@cccsaurora/howler-ui 2.13.1 → 2.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -78,7 +78,7 @@ const HitSearchProvider = ({ children }) => {
78
78
  fullQuery = `(howler.bundles:${bundle}) AND (${fullQuery})`;
79
79
  }
80
80
  else if (viewId) {
81
- fullQuery = `(${(await getCurrentView())?.query || 'howler.id:*'}) AND (${fullQuery})`;
81
+ fullQuery = `(${(await getCurrentView({ viewId }))?.query || 'howler.id:*'}) AND (${fullQuery})`;
82
82
  }
83
83
  const _response = await dispatchApi(api.search.hit.post({
84
84
  offset: appendResults ? response.rows : offset,
@@ -132,7 +132,6 @@ const HitSearchProvider = ({ children }) => {
132
132
  trackTotalHits,
133
133
  loadHits,
134
134
  getCurrentView,
135
- defaultView,
136
135
  setOffset
137
136
  ]);
138
137
  // We only run this when ancillary properties (i.e. filters, sorting) change
@@ -147,7 +146,7 @@ const HitSearchProvider = ({ children }) => {
147
146
  setResponse(null);
148
147
  }
149
148
  // eslint-disable-next-line react-hooks/exhaustive-deps
150
- }, [filter, offset, pageCount, sort, span, bundleId, location.pathname, startDate, endDate]);
149
+ }, [filter, offset, pageCount, sort, span, bundleId, location.pathname, startDate, endDate, viewId]);
151
150
  return (_jsx(HitSearchContext.Provider, { value: {
152
151
  layout,
153
152
  displayType,
@@ -12,7 +12,10 @@ export interface ViewContextType {
12
12
  addView: (v: View) => Promise<View>;
13
13
  editView: (id: string, newView: Partial<Omit<View, 'view_id' | 'owner'>>) => Promise<View>;
14
14
  removeView: (id: string) => Promise<void>;
15
- getCurrentView: (lazy?: boolean) => Promise<View>;
15
+ getCurrentView: (config?: {
16
+ viewId?: string;
17
+ lazy?: boolean;
18
+ }) => Promise<View>;
16
19
  }
17
20
  export declare const ViewContext: import("use-context-selector").Context<ViewContextType>;
18
21
  declare const ViewProvider: FC<PropsWithChildren>;
@@ -59,15 +59,17 @@ const ViewProvider = ({ children }) => {
59
59
  }
60
60
  })();
61
61
  }, [defaultView, fetchViews, setDefaultView, views]);
62
- const getCurrentView = useCallback(async (lazy = false) => {
63
- const id = location.pathname.startsWith('/views') ? routeParams.id : defaultView;
64
- if (!id) {
62
+ const getCurrentView = useCallback(async ({ viewId, lazy = false } = {}) => {
63
+ if (!viewId) {
64
+ viewId = location.pathname.startsWith('/views') ? routeParams.id : defaultView;
65
+ }
66
+ if (!viewId) {
65
67
  return null;
66
68
  }
67
- if (!has(views, id) && !lazy) {
68
- return (await fetchViews([id]))[0];
69
+ if (!has(views, viewId) && !lazy) {
70
+ return (await fetchViews([viewId]))[0];
69
71
  }
70
- return views[id];
72
+ return views[viewId];
71
73
  }, [defaultView, fetchViews, location.pathname, routeParams.id, views]);
72
74
  const editView = useCallback(async (id, partialView) => {
73
75
  const result = await dispatchApi(api.view.put(id, partialView));
@@ -117,17 +117,23 @@ describe('ViewContext', () => {
117
117
  });
118
118
  describe('getCurrentView', () => {
119
119
  let hook;
120
- beforeAll(async () => {
120
+ beforeEach(async () => {
121
121
  hook = await act(async () => {
122
122
  return renderHook(() => useContextSelector(ViewContext, ctx => ctx.getCurrentView), { wrapper: Wrapper });
123
123
  });
124
124
  });
125
125
  it('should allow the user to fetch their current view based on the location', async () => {
126
126
  // lazy load should return nothing
127
- await expect(hook.result.current(true)).resolves.toBeFalsy();
127
+ await expect(hook.result.current({ lazy: true })).resolves.toBeFalsy();
128
128
  const result = await act(async () => hook.result.current());
129
129
  expect(result).toEqual(MOCK_RESPONSES['/api/v1/search/view'].items[0]);
130
130
  });
131
+ it('should allow the user to fetch their current view based on the view ID', async () => {
132
+ // lazy load should return nothing
133
+ await expect(hook.result.current({ lazy: true })).resolves.toBeFalsy();
134
+ const result = await act(async () => hook.result.current({ viewId: 'searched_view_id' }));
135
+ expect(result).toEqual(MOCK_RESPONSES['/api/v1/search/view'].items[0]);
136
+ });
131
137
  });
132
138
  describe('editView', () => {
133
139
  let hook;
@@ -29,7 +29,7 @@ const HitBanner = ({ hit, layout = HitLayout.NORMAL, showAssigned = true }) => {
29
29
  if (!hit?.howler.analytic) {
30
30
  return;
31
31
  }
32
- getMatchingAnalytic(hit).then(analytic => setAnalyticId(analytic.analytic_id));
32
+ getMatchingAnalytic(hit).then(analytic => setAnalyticId(analytic?.analytic_id));
33
33
  // eslint-disable-next-line react-hooks/exhaustive-deps
34
34
  }, [hit?.howler.analytic]);
35
35
  const providerColor = useMemo(() => PROVIDER_COLORS[hit.event?.provider ?? 'unknown'] ?? stringToColor(hit.event.provider), [hit.event?.provider]);
@@ -42,6 +42,7 @@ const HitGraph = ({ query }) => {
42
42
  const removeHitFromSelection = useContextSelector(HitContext, ctx => ctx.removeHitFromSelection);
43
43
  const viewId = useContextSelector(HitSearchContext, ctx => ctx.viewId);
44
44
  const error = useContextSelector(HitSearchContext, ctx => ctx.error);
45
+ const response = useContextSelector(HitSearchContext, ctx => ctx.response);
45
46
  const chartRef = useRef();
46
47
  const [loading, setLoading] = useState(false);
47
48
  const [filterField, setFilterField] = useState(FILTER_FIELDS[0]);
@@ -113,12 +114,12 @@ const HitGraph = ({ query }) => {
113
114
  }
114
115
  }, [dispatchApi, endDate, escalationFilter, filterField, override, query, span, startDate]);
115
116
  useEffect(() => {
116
- if ((!query && !viewId) || error) {
117
+ if ((!query && !viewId) || error || !response) {
117
118
  return;
118
119
  }
119
120
  performQuery();
120
121
  // eslint-disable-next-line react-hooks/exhaustive-deps
121
- }, [query, viewId, error, span]);
122
+ }, [query, viewId, error, span, response]);
122
123
  const options = useMemo(() => {
123
124
  const parentOptions = scatter('hit.summary.title', 'hit.summary.subtitle');
124
125
  return {
@@ -53,7 +53,7 @@ const HitSort = ({ size = 'small' }) => {
53
53
  return;
54
54
  }
55
55
  (async () => {
56
- const selectedView = await getCurrentView(true);
56
+ const selectedView = await getCurrentView({ lazy: true });
57
57
  if (selectedView?.sort && !location.search.includes('sort')) {
58
58
  setSavedSort(selectedView.sort);
59
59
  }
@@ -26,7 +26,7 @@ const SearchSpan = ({ omitCustom = false, size }) => {
26
26
  return;
27
27
  }
28
28
  (async () => {
29
- const viewSpan = (await getCurrentView(true))?.span;
29
+ const viewSpan = (await getCurrentView({ lazy: true }))?.span;
30
30
  if (!viewSpan) {
31
31
  return;
32
32
  }
@@ -104,7 +104,7 @@ const HitViewer = () => {
104
104
  hit_worklog: () => _jsx(HitWorklog, { hit: hit, users: users }),
105
105
  hit_related: () => _jsx(HitRelated, { hit: hit }),
106
106
  ...Object.fromEntries(hit?.howler.dossier?.map((lead, index) => ['lead:' + index, () => _jsx(LeadRenderer, { lead: lead })]) ?? []),
107
- ...Object.fromEntries(dossiers.flatMap((_dossier, dossierIndex) => _dossier.leads?.map((_lead, leadIndex) => [
107
+ ...Object.fromEntries(dossiers.flatMap((_dossier, dossierIndex) => (_dossier.leads ?? []).map((_lead, leadIndex) => [
108
108
  `external-lead:${dossierIndex}:${leadIndex}`,
109
109
  () => _jsx(LeadRenderer, { lead: _lead, hit: hit })
110
110
  ])))
@@ -15,7 +15,7 @@ const TYPES = {
15
15
  const VISUALIZATIONS = ['assessment', 'created', 'escalation', 'status', 'detection'];
16
16
  const AddNewCard = ({ dashboard, addCard }) => {
17
17
  const { t } = useTranslation();
18
- const views = useContextSelector(ViewContext, ctx => ctx.views ?? []);
18
+ const views = useContextSelector(ViewContext, ctx => ctx.views ?? {});
19
19
  const fetchViews = useContextSelector(ViewContext, ctx => ctx.fetchViews);
20
20
  const [selectedType, setSelectedType] = useState('');
21
21
  const [analytics, setAnalytics] = useState([]);
@@ -58,7 +58,8 @@ const AddNewCard = ({ dashboard, addCard }) => {
58
58
  }, [fetchViews]);
59
59
  return (_jsx(Grid, { item: true, xs: 12, md: 6, children: _jsxs(Card, { variant: "outlined", sx: { height: '100%' }, children: [_jsx(CardHeader, { title: t('route.home.add'), subheader: _jsx(Typography, { variant: "body2", color: "text.secondary", children: t('route.home.add.description') }) }), _jsx(CardContent, { children: _jsxs(Stack, { spacing: 1, children: [_jsxs(FormControl, { sx: theme => ({ mt: `${theme.spacing(2)} !important` }), children: [_jsx(InputLabel, { children: t('route.home.add.type') }), _jsx(Select, { value: selectedType, onChange: event => setSelectedType(event.target.value), label: t('route.home.add.type'), children: Object.keys(TYPES).map(type => (_jsx(MenuItem, { value: type, children: _jsxs(Stack, { children: [_jsx(Typography, { variant: "body1", children: t(`route.home.add.type.${type}`) }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: t(`route.home.add.type.${type}.description`) })] }) }, type))) })] }), selectedType && _jsx(Divider, { flexItem: true }), selectedType === 'analytic' && (_jsxs(_Fragment, { children: [_jsx(Typography, { variant: "body1", children: t('route.home.add.analytic.title') }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: t('route.home.add.analytic.description') }), _jsx(Autocomplete, { sx: { pt: 1 }, onChange: (__, opt) => setConfig('analyticId', opt.analytic_id), options: analytics, filterOptions: (options, state) => options.filter(opt => opt.name.toLowerCase().includes(state.inputValue.toLowerCase()) ||
60
60
  opt.description?.split('\n')[0]?.toLowerCase().includes(state.inputValue.toLowerCase())), renderOption: (props, option) => (_createElement("li", { ...props, key: option.analytic_id },
61
- _jsxs(Stack, { children: [_jsx(Typography, { variant: "body1", children: option.name }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: option.description?.split('\n')[0] })] }))), getOptionLabel: option => option.name, renderInput: params => _jsx(TextField, { ...params, label: t('route.home.add.analytic') }) }), _jsxs(FormControl, { sx: theme => ({ mt: `${theme.spacing(2)} !important` }), children: [_jsx(InputLabel, { children: t('route.home.add.visualization') }), _jsx(Select, { value: config.type ?? '', onChange: event => setConfig('type', event.target.value), label: t('route.home.add.visualization'), children: VISUALIZATIONS.map(viz => (_jsx(MenuItem, { value: viz, children: _jsxs(Stack, { children: [_jsx(Typography, { variant: "body1", children: t(`route.home.add.visualization.${viz}`) }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: t(`route.home.add.visualization.${viz}.description`) })] }) }, viz))) })] })] })), selectedType === 'view' && (_jsxs(_Fragment, { children: [_jsx(Autocomplete, { sx: { pt: 1 }, onChange: (__, opt) => setConfig('viewId', opt.view_id), onOpen: onViewOpen, onClose: () => setViewOpen(false), open: viewOpen, loading: viewLoading, options: Object.values(views), filterOptions: (options, state) => options.filter(opt => !dashboard?.find(entry => entry.type === 'view' && JSON.parse(entry.config).viewId === opt.view_id) &&
61
+ _jsxs(Stack, { children: [_jsx(Typography, { variant: "body1", children: option.name }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: option.description?.split('\n')[0] })] }))), getOptionLabel: option => option.name, renderInput: params => _jsx(TextField, { ...params, label: t('route.home.add.analytic') }) }), _jsxs(FormControl, { sx: theme => ({ mt: `${theme.spacing(2)} !important` }), children: [_jsx(InputLabel, { children: t('route.home.add.visualization') }), _jsx(Select, { value: config.type ?? '', onChange: event => setConfig('type', event.target.value), label: t('route.home.add.visualization'), children: VISUALIZATIONS.map(viz => (_jsx(MenuItem, { value: viz, children: _jsxs(Stack, { children: [_jsx(Typography, { variant: "body1", children: t(`route.home.add.visualization.${viz}`) }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: t(`route.home.add.visualization.${viz}.description`) })] }) }, viz))) })] })] })), selectedType === 'view' && (_jsxs(_Fragment, { children: [_jsx(Autocomplete, { sx: { pt: 1 }, onChange: (__, opt) => setConfig('viewId', opt.view_id), onOpen: onViewOpen, onClose: () => setViewOpen(false), open: viewOpen, loading: viewLoading, options: Object.values(views), filterOptions: (options, state) => options.filter(opt => !!opt &&
62
+ !dashboard?.find(entry => entry.type === 'view' && JSON.parse(entry.config).viewId === opt.view_id) &&
62
63
  (opt.title.toLowerCase().includes(state.inputValue.toLowerCase()) ||
63
64
  opt.query.toLowerCase().includes(state.inputValue.toLowerCase()))), renderOption: (props, option) => (_createElement("li", { ...props, key: option.view_id },
64
65
  _jsxs(Stack, { children: [_jsx(Typography, { variant: "body1", children: t(option.title) }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: option.query })] }))), getOptionLabel: option => t(option.title), renderInput: params => _jsx(TextField, { ...params, label: t('route.home.add.view') }) }), _jsx(Typography, { variant: "body1", sx: { pt: 1 }, children: t('route.home.add.limit') }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: t('route.home.add.limit.description') }), _jsx(Box, { sx: { px: 0.5 }, children: _jsx(Slider, { value: config.limit ?? 3, valueLabelDisplay: "auto", onChange: (_, value) => setConfig('limit', value), min: 1, max: 10, step: 1, marks: true }) })] })), _jsx(Stack, { direction: "row", justifyContent: "end", children: _jsx(CustomButton, { variant: "outlined", size: "small", color: "primary", startIcon: _jsx(Check, {}), disabled: !selectedType || TYPES[selectedType]?.filter(field => !config[field])?.length > 0, onClick: _addCard, children: t('create') }) })] }) })] }) }));
@@ -16,6 +16,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
16
16
  import { useTranslation } from 'react-i18next';
17
17
  import { Link } from 'react-router-dom';
18
18
  import { StorageKey } from '@cccsaurora/howler-ui/utils/constants';
19
+ import ErrorBoundary from '../ErrorBoundary';
19
20
  import AddNewCard from './AddNewCard';
20
21
  import AnalyticCard, {} from './AnalyticCard';
21
22
  import EntryWrapper from './EntryWrapper';
@@ -81,41 +82,41 @@ const Home = () => {
81
82
  })
82
83
  .then(result => setUpdatedHitTotal(result.total));
83
84
  }, [updateQuery]);
84
- return (_jsx(PageCenter, { maxWidth: "1800px", textAlign: "left", height: "100%", children: _jsxs(Stack, { direction: "column", spacing: 1, sx: { height: '100%' }, children: [_jsxs(Stack, { direction: "row", justifyContent: "end", spacing: 1, children: [isEditing && (_jsx(CustomButton, { variant: "outlined", size: "small", color: "error", startIcon: _jsx(Cancel, {}), onClick: discardChanges, children: t('cancel') })), _jsx(CustomButton, { variant: "outlined", size: "small", disabled: isEditing && isEqual(dashboard, user.dashboard), color: isEditing ? 'success' : 'primary', startIcon: isEditing ? loading ? _jsx(CircularProgress, { size: 20 }) : _jsx(Check, {}) : _jsx(Edit, {}), onClick: () => (!isEditing ? setIsEditing(true) : saveChanges()), children: t(isEditing ? 'save' : 'edit') })] }), updatedHitTotal > 0 && (_jsxs(Alert, { severity: "info", variant: "outlined", action: _jsxs(Stack, { spacing: 1, direction: "row", children: [_jsx(IconButton, { color: "info", component: Link, to: `/hits?query=${encodeURIComponent(updateQuery)}`, onClick: () => setLastViewed(dayjs().utc().format(LUCENE_DATE_FMT)), children: _jsx(OpenInNew, {}) }), _jsx(IconButton, { color: "info", onClick: () => {
85
- setLastViewed(dayjs().utc().format(LUCENE_DATE_FMT));
86
- setUpdatedHitTotal(0);
87
- }, children: _jsx(Close, {}) })] }), children: [_jsx(AlertTitle, { children: t('route.home.alert.updated.title') }), t('route.home.alert.updated.description', { count: updatedHitTotal })] })), _jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: _jsx(SortableContext, { items: (dashboard ?? []).map(entry => getIdFromEntry(entry)), children: _jsxs(Grid, { container: true, spacing: 1, alignItems: "stretch", sx: [
88
- theme => ({
89
- marginLeft: `${theme.spacing(-1)} !important`
90
- }),
91
- !dashboard?.length &&
92
- !isEditing && {
93
- height: '100%',
94
- display: 'flex',
95
- alignItems: 'center'
96
- }
97
- ], children: [(dashboard ?? []).map(entry => {
98
- if (entry.type === 'view') {
99
- const settings = JSON.parse(entry.config);
100
- return (_jsx(EntryWrapper, { editing: isEditing, id: settings.viewId, onDelete: () => setLocalDashboard((dashboard ?? []).filter(_entry => _entry.entry_id !== getIdFromEntry(entry))), children: _jsx(ViewCard, { ...settings }, entry.config) }, entry.entry_id));
85
+ return (_jsx(PageCenter, { maxWidth: "1800px", textAlign: "left", height: "100%", children: _jsx(ErrorBoundary, { children: _jsxs(Stack, { direction: "column", spacing: 1, sx: { height: '100%' }, children: [_jsxs(Stack, { direction: "row", justifyContent: "end", spacing: 1, children: [isEditing && (_jsx(CustomButton, { variant: "outlined", size: "small", color: "error", startIcon: _jsx(Cancel, {}), onClick: discardChanges, children: t('cancel') })), _jsx(CustomButton, { variant: "outlined", size: "small", disabled: isEditing && isEqual(dashboard, user.dashboard), color: isEditing ? 'success' : 'primary', startIcon: isEditing ? loading ? _jsx(CircularProgress, { size: 20 }) : _jsx(Check, {}) : _jsx(Edit, {}), onClick: () => (!isEditing ? setIsEditing(true) : saveChanges()), children: t(isEditing ? 'save' : 'edit') })] }), updatedHitTotal > 0 && (_jsxs(Alert, { severity: "info", variant: "outlined", action: _jsxs(Stack, { spacing: 1, direction: "row", children: [_jsx(IconButton, { color: "info", component: Link, to: `/hits?query=${encodeURIComponent(updateQuery)}`, onClick: () => setLastViewed(dayjs().utc().format(LUCENE_DATE_FMT)), children: _jsx(OpenInNew, {}) }), _jsx(IconButton, { color: "info", onClick: () => {
86
+ setLastViewed(dayjs().utc().format(LUCENE_DATE_FMT));
87
+ setUpdatedHitTotal(0);
88
+ }, children: _jsx(Close, {}) })] }), children: [_jsx(AlertTitle, { children: t('route.home.alert.updated.title') }), t('route.home.alert.updated.description', { count: updatedHitTotal })] })), _jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: _jsx(SortableContext, { items: (dashboard ?? []).map(entry => getIdFromEntry(entry)), children: _jsxs(Grid, { container: true, spacing: 1, alignItems: "stretch", sx: [
89
+ theme => ({
90
+ marginLeft: `${theme.spacing(-1)} !important`
91
+ }),
92
+ !dashboard?.length &&
93
+ !isEditing && {
94
+ height: '100%',
95
+ display: 'flex',
96
+ alignItems: 'center'
101
97
  }
102
- else if (entry.type === 'analytic') {
103
- const settings = JSON.parse(entry.config);
104
- return (_jsx(EntryWrapper, { editing: isEditing, id: getIdFromEntry(entry), onDelete: () => setLocalDashboard((dashboard ?? []).filter(_entry => _entry.entry_id !== getIdFromEntry(entry))), children: _jsx(AnalyticCard, { ...settings }, entry.config) }, entry.entry_id));
105
- }
106
- else {
107
- return null;
108
- }
109
- }), isEditing && (_jsx(AddNewCard, { dashboard: dashboard, addCard: newCard => setStateDashboard(_dashboard => [...(_dashboard ?? []), newCard]) })), !dashboard?.length && !isEditing && (_jsx(Grid, { item: true, xs: 12, children: _jsxs(Stack, { direction: "column", spacing: 2, sx: theme => ({
110
- height: '60vh',
111
- borderStyle: 'dashed',
112
- borderColor: theme.palette.text.secondary,
113
- borderWidth: '1rem',
114
- borderRadius: '1rem',
115
- opacity: 0.3,
116
- justifyContent: 'center',
117
- alignItems: 'center',
118
- padding: 3
119
- }), children: [_jsx(Typography, { variant: "h1", sx: { display: 'flex', alignItems: 'center' }, children: _jsxs(Stack, { direction: "row", spacing: 2.5, children: [_jsx(AppBrand, { application: "howler", variant: "logo", size: "large" }), _jsx("span", { children: t('route.home.title') })] }) }), _jsx(Typography, { variant: "h4", sx: { textAlign: 'center' }, children: t('route.home.description') })] }) }))] }) }) })] }) }));
98
+ ], children: [(dashboard ?? []).map(entry => {
99
+ if (entry.type === 'view') {
100
+ const settings = JSON.parse(entry.config);
101
+ return (_jsx(EntryWrapper, { editing: isEditing, id: settings.viewId, onDelete: () => setLocalDashboard((dashboard ?? []).filter(_entry => _entry.entry_id !== getIdFromEntry(entry))), children: _jsx(ViewCard, { ...settings }, entry.config) }, entry.entry_id));
102
+ }
103
+ else if (entry.type === 'analytic') {
104
+ const settings = JSON.parse(entry.config);
105
+ return (_jsx(EntryWrapper, { editing: isEditing, id: getIdFromEntry(entry), onDelete: () => setLocalDashboard((dashboard ?? []).filter(_entry => _entry.entry_id !== getIdFromEntry(entry))), children: _jsx(AnalyticCard, { ...settings }, entry.config) }, entry.entry_id));
106
+ }
107
+ else {
108
+ return null;
109
+ }
110
+ }), isEditing && (_jsx(AddNewCard, { dashboard: dashboard, addCard: newCard => setStateDashboard(_dashboard => [...(_dashboard ?? []), newCard]) })), !dashboard?.length && !isEditing && (_jsx(Grid, { item: true, xs: 12, children: _jsxs(Stack, { direction: "column", spacing: 2, sx: theme => ({
111
+ height: '60vh',
112
+ borderStyle: 'dashed',
113
+ borderColor: theme.palette.text.secondary,
114
+ borderWidth: '1rem',
115
+ borderRadius: '1rem',
116
+ opacity: 0.3,
117
+ justifyContent: 'center',
118
+ alignItems: 'center',
119
+ padding: 3
120
+ }), children: [_jsx(Typography, { variant: "h1", sx: { display: 'flex', alignItems: 'center' }, children: _jsxs(Stack, { direction: "row", spacing: 2.5, children: [_jsx(AppBrand, { application: "howler", variant: "logo", size: "large" }), _jsx("span", { children: t('route.home.title') })] }) }), _jsx(Typography, { variant: "h4", sx: { textAlign: 'center' }, children: t('route.home.description') })] }) }))] }) }) })] }) }) }));
120
121
  };
121
122
  export default Home;
package/package.json CHANGED
@@ -96,7 +96,7 @@
96
96
  "internal-slot": "1.0.7"
97
97
  },
98
98
  "type": "module",
99
- "version": "2.13.1",
99
+ "version": "2.13.2",
100
100
  "exports": {
101
101
  "./i18n": "./i18n.js",
102
102
  "./index.css": "./index.css",