@centreon/ui 23.10.25-feature-MON-19319.0 → 23.10.25

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.
Files changed (54) hide show
  1. package/package.json +1 -8
  2. package/src/Button/Save/index.stories.tsx +10 -5
  3. package/src/Dashboard/DashboardLayout.stories.tsx +5 -3
  4. package/src/Dashboard/Layout.tsx +4 -4
  5. package/src/Dashboard/utils.ts +28 -28
  6. package/src/ThemeProvider/index.tsx +5 -6
  7. package/src/ThemeProvider/palettes.ts +208 -234
  8. package/src/components/Button/Button.styles.ts +2 -7
  9. package/src/components/Button/Button.tsx +1 -1
  10. package/src/components/Form/Dashboard/Dashboard.resource.ts +1 -1
  11. package/src/components/Form/Dashboard/DashboardForm.tsx +10 -6
  12. package/src/components/Form/Dashboard/translatedLabels.ts +1 -0
  13. package/src/components/Header/Header.stories.tsx +27 -0
  14. package/src/components/Header/Header.styles.ts +27 -0
  15. package/src/components/Header/Header.tsx +23 -0
  16. package/src/components/Header/index.ts +1 -1
  17. package/src/components/index.ts +0 -2
  18. package/src/index.ts +2 -0
  19. package/src/layout/TiledListingPage/TiledListingActions.tsx +15 -0
  20. package/src/layout/TiledListingPage/TiledListingContent.tsx +21 -0
  21. package/src/layout/TiledListingPage/TiledListingList.tsx +11 -0
  22. package/src/layout/TiledListingPage/TiledListingPage.styles.ts +16 -0
  23. package/src/layout/TiledListingPage/TiledListingPage.tsx +15 -0
  24. package/src/layout/TiledListingPage/index.ts +4 -0
  25. package/src/screens/dashboard/DashboardsOverview.stories.tsx +101 -109
  26. package/test/setupTests.js +20 -23
  27. package/src/components/Header/PageHeader/PageHeader.stories.tsx +0 -83
  28. package/src/components/Header/PageHeader/PageHeader.styles.ts +0 -105
  29. package/src/components/Header/PageHeader/PageHeader.tsx +0 -15
  30. package/src/components/Header/PageHeader/PageHeaderActions.tsx +0 -17
  31. package/src/components/Header/PageHeader/PageHeaderMain.tsx +0 -15
  32. package/src/components/Header/PageHeader/PageHeaderMenu.tsx +0 -15
  33. package/src/components/Header/PageHeader/PageHeaderTitle.tsx +0 -44
  34. package/src/components/Header/PageHeader/index.ts +0 -12
  35. package/src/components/Layout/AreaIndicator.styles.ts +0 -33
  36. package/src/components/Layout/AreaIndicator.tsx +0 -35
  37. package/src/components/Layout/PageLayout/PageLayout.stories.tsx +0 -81
  38. package/src/components/Layout/PageLayout/PageLayout.styles.ts +0 -30
  39. package/src/components/Layout/PageLayout/PageLayout.tsx +0 -21
  40. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +0 -15
  41. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +0 -24
  42. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +0 -15
  43. package/src/components/Layout/PageLayout/index.ts +0 -10
  44. package/src/components/Layout/index.ts +0 -1
  45. package/src/components/Menu/Menu.tsx +0 -0
  46. package/src/components/Tooltip/TextOverflowTooltip/TextOverflowTooltip.stories.tsx +0 -71
  47. package/src/components/Tooltip/TextOverflowTooltip/TextOverflowTooltip.styles.ts +0 -5
  48. package/src/components/Tooltip/TextOverflowTooltip/TextOverflowTooltip.tsx +0 -115
  49. package/src/components/Tooltip/TextOverflowTooltip/index.tsx +0 -1
  50. package/src/components/Tooltip/Tooltip.stories.tsx +0 -41
  51. package/src/components/Tooltip/Tooltip.styles.ts +0 -5
  52. package/src/components/Tooltip/Tooltip.tsx +0 -46
  53. package/src/components/Tooltip/index.ts +0 -1
  54. package/src/utils/useResizeObserver.ts +0 -6
@@ -0,0 +1,16 @@
1
+ import { makeStyles } from 'tss-react/mui';
2
+
3
+ export const useTiledListPageStyles = makeStyles()((theme) => ({
4
+ listPage: {
5
+ display: 'flex',
6
+ flexDirection: 'column',
7
+ height: '100%',
8
+ padding: theme.spacing(1.5)
9
+ }
10
+ }));
11
+
12
+ export const useTiledListingActionsStyles = makeStyles()((theme) => ({
13
+ actions: {
14
+ paddingBottom: theme.spacing(2.5)
15
+ }
16
+ }));
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ import { useTiledListPageStyles } from './TiledListingPage.styles';
4
+
5
+ interface TiledListingPageProps {
6
+ children: Array<ReactNode>;
7
+ }
8
+
9
+ export const TiledListingPage = ({
10
+ children
11
+ }: TiledListingPageProps): JSX.Element => {
12
+ const { classes } = useTiledListPageStyles();
13
+
14
+ return <div className={classes.listPage}>{children}</div>;
15
+ };
@@ -0,0 +1,4 @@
1
+ export * from './TiledListingPage';
2
+ export * from './TiledListingActions';
3
+ export * from './TiledListingList';
4
+ export * from './TiledListingContent';
@@ -11,11 +11,16 @@ import {
11
11
  DashboardForm,
12
12
  DashboardFormProps,
13
13
  DataTable,
14
- Modal,
15
- PageHeader,
16
- PageLayout
14
+ Header,
15
+ Modal
17
16
  } from '../../components';
18
17
  import { Default as DashboardFormDefaultStory } from '../../components/Form/Dashboard/DashboardForm.stories';
18
+ import {
19
+ TiledListingActions,
20
+ TiledListingContent,
21
+ TiledListingList,
22
+ TiledListingPage
23
+ } from '../../layout/TiledListingPage';
19
24
 
20
25
  const meta: Meta = {
21
26
  args: {
@@ -59,9 +64,6 @@ const meta: Meta = {
59
64
  },
60
65
  title: 'Dashboards overview'
61
66
  },
62
- parameters: {
63
- layout: 'fullscreen'
64
- },
65
67
  title: 'screens/Dashboards'
66
68
  };
67
69
 
@@ -132,16 +134,10 @@ const DefaultView = (args): JSX.Element => {
132
134
  };
133
135
 
134
136
  return (
135
- <PageLayout>
136
- <PageLayout.Header>
137
- <PageHeader>
138
- <PageHeader.Main>
139
- <PageHeader.Title title={title} />
140
- </PageHeader.Main>
141
- </PageHeader>
142
- </PageLayout.Header>
143
- <PageLayout.Body>
144
- <PageLayout.Actions>
137
+ <TiledListingPage>
138
+ <Header title={title} />
139
+ <TiledListingList>
140
+ <TiledListingActions>
145
141
  {dataDashboards.length !== 0 && (
146
142
  <Button
147
143
  aria-label="add"
@@ -154,105 +150,101 @@ const DefaultView = (args): JSX.Element => {
154
150
  {actions.create.label}
155
151
  </Button>
156
152
  )}
157
- </PageLayout.Actions>
158
-
159
- <DataTable isEmpty={dataDashboards.length === 0}>
160
- {dataDashboards.length === 0 ? (
161
- <DataTable.EmptyState
162
- labels={list.emptyState.labels}
163
- onCreate={() =>
153
+ </TiledListingActions>
154
+ <TiledListingContent>
155
+ <DataTable isEmpty={dataDashboards.length === 0}>
156
+ {dataDashboards.length === 0 ? (
157
+ <DataTable.EmptyState
158
+ labels={list.emptyState.labels}
159
+ onCreate={() =>
160
+ setDialogState({ item: null, open: true, variant: 'create' })
161
+ }
162
+ />
163
+ ) : (
164
+ dataDashboards.map((dashboard) => (
165
+ <DataTable.Item
166
+ hasActions
167
+ hasCardAction
168
+ description={dashboard.description}
169
+ key={dashboard.id}
170
+ title={dashboard.name}
171
+ onDelete={() =>
172
+ setDeleteDialogState({ item: dashboard, open: true })
173
+ }
174
+ onEdit={() =>
175
+ setDialogState({
176
+ item: dashboard,
177
+ open: true,
178
+ variant: 'update'
179
+ })
180
+ }
181
+ />
182
+ ))
183
+ )}
184
+ </DataTable>
185
+ </TiledListingContent>
186
+ <Modal
187
+ open={dialogState.open}
188
+ onClose={() =>
189
+ setDialogState({
190
+ item: null,
191
+ open: false,
192
+ variant: dialogState.variant
193
+ })
194
+ }
195
+ >
196
+ <Modal.Header>
197
+ {form.labels.title[dialogState.variant ?? 'create']}
198
+ </Modal.Header>
199
+ <Modal.Body>
200
+ <DashboardForm
201
+ labels={DashboardFormDefaultStory!.args!.labels!}
202
+ resource={dialogState.item || undefined}
203
+ variant={dialogState.variant}
204
+ onCancel={() =>
164
205
  setDialogState({
165
206
  item: null,
166
- open: true,
167
- variant: 'create'
207
+ open: false,
208
+ variant: dialogState.variant
168
209
  })
169
210
  }
211
+ onSubmit={(values) =>
212
+ dialogState.variant === 'create'
213
+ ? createDashboard(values)
214
+ : updateDashboard(values)
215
+ }
170
216
  />
171
- ) : (
172
- dataDashboards.map((dashboard) => (
173
- <DataTable.Item
174
- hasActions
175
- hasCardAction
176
- description={dashboard.description}
177
- key={dashboard.id}
178
- title={dashboard.name}
179
- onDelete={() =>
180
- setDeleteDialogState({ item: dashboard, open: true })
181
- }
182
- onEdit={() =>
183
- setDialogState({
184
- item: dashboard,
185
- open: true,
186
- variant: 'update'
187
- })
188
- }
189
- />
190
- ))
191
- )}
192
- </DataTable>
193
- </PageLayout.Body>
194
-
195
- <Modal
196
- open={dialogState.open}
197
- onClose={() =>
198
- setDialogState({
199
- item: null,
200
- open: false,
201
- variant: dialogState.variant
202
- })
203
- }
204
- >
205
- <Modal.Header>
206
- {form.labels.title[dialogState.variant ?? 'create']}
207
- </Modal.Header>
208
- <Modal.Body>
209
- <DashboardForm
210
- labels={DashboardFormDefaultStory!.args!.labels!}
211
- resource={dialogState.item || undefined}
212
- variant={dialogState.variant}
213
- onCancel={() =>
214
- setDialogState({
215
- item: null,
216
- open: false,
217
- variant: dialogState.variant
218
- })
219
- }
220
- onSubmit={(values) =>
221
- dialogState.variant === 'create'
222
- ? createDashboard(values)
223
- : updateDashboard(values)
224
- }
217
+ </Modal.Body>
218
+ </Modal>
219
+ <Modal
220
+ open={deleteDialogState.open}
221
+ onClose={() =>
222
+ setDeleteDialogState({
223
+ ...deleteDialogState,
224
+ open: false
225
+ })
226
+ }
227
+ >
228
+ <Modal.Header>{deleteConfirmation.labels.title}</Modal.Header>
229
+ <Modal.Body>
230
+ <p>
231
+ {deleteConfirmation.labels.description(
232
+ deleteDialogState.item?.name
233
+ )}
234
+ </p>
235
+ </Modal.Body>
236
+ <Modal.Actions
237
+ isDanger
238
+ labels={deleteConfirmation.labels.actions}
239
+ onCancel={() => setDeleteDialogState({ item: null, open: false })}
240
+ onConfirm={() => {
241
+ deleteDashboard(deleteDialogState.item?.id);
242
+ setDeleteDialogState({ item: null, open: false });
243
+ }}
225
244
  />
226
- </Modal.Body>
227
- </Modal>
228
- <Modal
229
- open={deleteDialogState.open}
230
- onClose={() =>
231
- setDeleteDialogState({
232
- ...deleteDialogState,
233
- open: false
234
- })
235
- }
236
- >
237
- <Modal.Header>{deleteConfirmation.labels.title}</Modal.Header>
238
- <Modal.Body>
239
- <p>
240
- {deleteConfirmation.labels.description(
241
- deleteDialogState.item?.name
242
- )}
243
- </p>
244
- </Modal.Body>
245
- <Modal.Actions
246
- isDanger
247
- labels={deleteConfirmation.labels.actions}
248
- onCancel={() => setDeleteDialogState({ item: null, open: false })}
249
- onConfirm={() => {
250
- deleteDashboard(deleteDialogState.item?.id);
251
- setDeleteDialogState({ item: null, open: false });
252
- }}
253
- />
254
- </Modal>
255
- </PageLayout>
245
+ </Modal>
246
+ </TiledListingList>
247
+ </TiledListingPage>
256
248
  );
257
249
  };
258
250
 
@@ -1,45 +1,42 @@
1
1
  /* eslint-disable no-underscore-dangle */
2
2
  /* eslint-disable no-undef */
3
- // FIXME: testing library setup
4
- // import '@testing-library/jest-dom';
5
- // import '@testing-library/react';
6
3
  // import '@testing-library/jest-dom/extend-expect';
7
- import i18n from "i18next";
8
- import { initReactI18next } from "react-i18next";
9
- import fetchMock from "jest-fetch-mock";
4
+ import i18n from 'i18next';
5
+ import { initReactI18next } from 'react-i18next';
6
+ import fetchMock from 'jest-fetch-mock';
10
7
 
11
8
  const mockedMatchMedia = () => ({
12
9
  addListener: () => {},
13
10
  matches: false,
14
- removeListener: () => {},
11
+ removeListener: () => {}
15
12
  });
16
13
 
17
14
  window.matchMedia = window.matchMedia || mockedMatchMedia;
18
15
 
19
16
  document.createRange = () => ({
20
17
  commonAncestorContainer: {
21
- nodeName: "BODY",
22
- ownerDocument: document,
18
+ nodeName: 'BODY',
19
+ ownerDocument: document
23
20
  },
24
21
  setEnd: () => {},
25
- setStart: () => {},
22
+ setStart: () => {}
26
23
  });
27
24
 
28
25
  global.IntersectionObserver = class IntersectionObserver {
29
26
  observe() {
30
- this.a = "";
27
+ this.a = '';
31
28
 
32
29
  return null;
33
30
  }
34
31
 
35
32
  disconnect() {
36
- this.a = "";
33
+ this.a = '';
37
34
 
38
35
  return null;
39
36
  }
40
37
  };
41
38
 
42
- Object.defineProperty(window, "matchMedia", {
39
+ Object.defineProperty(window, 'matchMedia', {
43
40
  value: jest.fn().mockImplementation((query) => ({
44
41
  addEventListener: jest.fn(),
45
42
  addListener: jest.fn(),
@@ -48,42 +45,42 @@ Object.defineProperty(window, "matchMedia", {
48
45
  media: query,
49
46
  onchange: null,
50
47
  removeEventListener: jest.fn(),
51
- removeListener: jest.fn(),
48
+ removeListener: jest.fn()
52
49
  })),
53
- writable: true,
50
+ writable: true
54
51
  });
55
52
 
56
- Object.defineProperty(Image.prototype, "onload", {
53
+ Object.defineProperty(Image.prototype, 'onload', {
57
54
  get() {
58
55
  return this._onload;
59
56
  },
60
57
  set(onload) {
61
58
  onloadRef = onload;
62
59
  this._onload = onload;
63
- },
60
+ }
64
61
  });
65
- Object.defineProperty(Image.prototype, "onerror", {
62
+ Object.defineProperty(Image.prototype, 'onerror', {
66
63
  get() {
67
64
  return this._onerror;
68
65
  },
69
66
  set(onerror) {
70
67
  onerrorRef = onerror;
71
68
  this._onerror = onerror;
72
- },
69
+ }
73
70
  });
74
71
 
75
72
  i18n.use(initReactI18next).init({
76
- fallbackLng: "en",
73
+ fallbackLng: 'en',
77
74
  keySeparator: false,
78
- lng: "en",
75
+ lng: 'en',
79
76
  nsSeparator: false,
80
- resources: {},
77
+ resources: {}
81
78
  });
82
79
 
83
80
  window.Image = () => ({
84
81
  onerror: () => {},
85
82
  onload: () => {},
86
- src: null,
83
+ src: null
87
84
  });
88
85
 
89
86
  fetchMock.enableMocks();
@@ -1,83 +0,0 @@
1
- import { Meta, StoryObj } from '@storybook/react';
2
-
3
- import {
4
- ArrowDropDown as ArrowDropDownIcon,
5
- Menu as MenuIcon,
6
- Settings as SettingsIcon,
7
- StarOutline as StarOutlineIcon
8
- } from '@mui/icons-material';
9
-
10
- import { Button, IconButton } from '../../Button';
11
-
12
- import { PageHeader } from './index';
13
-
14
- type PageHeaderComponent = typeof PageHeader & typeof PageHeader.Title;
15
-
16
- const meta: Meta<typeof PageHeader> = {
17
- component: PageHeader
18
- };
19
-
20
- export default meta;
21
- type Story = StoryObj<PageHeaderComponent>;
22
-
23
- export const Default: Story = {
24
- args: {
25
- title: 'Page header'
26
- },
27
- render: (args) => (
28
- <PageHeader>
29
- <PageHeader.Main>
30
- <PageHeader.Title {...args} />
31
- </PageHeader.Main>
32
- <PageHeader.Actions>
33
- <Button
34
- icon={<SettingsIcon />}
35
- iconVariant="start"
36
- size="small"
37
- variant="ghost"
38
- >
39
- Manage
40
- </Button>
41
- </PageHeader.Actions>
42
- </PageHeader>
43
- )
44
- };
45
-
46
- export const WithDescription: Story = {
47
- args: {
48
- description:
49
- 'Eu aliquip quis in minim laboris occaecat quis nostrud occaecat. Cupidatat consectetur non Lorem eiusmod ut cupidatat dolor enim cillum ex enim irure velit. ',
50
- title: 'Nulla ex dolore tempor magna ex'
51
- },
52
- render: Default.render
53
- };
54
-
55
- export const WithMenu: Story = {
56
- args: {
57
- ...WithDescription.args,
58
- actions: (
59
- <IconButton icon={<StarOutlineIcon />} size="small" variant="ghost" />
60
- )
61
- },
62
- render: (args) => (
63
- <PageHeader>
64
- <PageHeader.Main>
65
- <PageHeader.Menu>
66
- <MenuIcon />
67
- <ArrowDropDownIcon data-size="small" />
68
- </PageHeader.Menu>
69
- <PageHeader.Title {...args} />
70
- </PageHeader.Main>
71
- <PageHeader.Actions>
72
- <Button
73
- icon={<SettingsIcon />}
74
- iconVariant="start"
75
- size="small"
76
- variant="ghost"
77
- >
78
- Manage
79
- </Button>
80
- </PageHeader.Actions>
81
- </PageHeader>
82
- )
83
- };
@@ -1,105 +0,0 @@
1
- import { makeStyles } from 'tss-react/mui';
2
-
3
- const useStyles = makeStyles()((theme) => ({
4
- header: {
5
- alignItems: 'flex-start',
6
- borderBottom: `1px solid ${theme.palette.primary.main}`,
7
- display: 'flex',
8
- flexDirection: 'row',
9
- h1: {
10
- font: 'normal normal 600 24px/24px Roboto',
11
- letterSpacing: '0.18px',
12
- margin: theme.spacing(0, 0, 1.5, 0)
13
- },
14
- justifyContent: 'space-between',
15
-
16
- nav: {
17
- display: 'flex',
18
- gap: theme.spacing(1),
19
- justifyContent: 'flex-end'
20
- },
21
-
22
- padding: theme.spacing(0, 0, 1.5, 0)
23
- },
24
- pageHeader: {
25
- alignItems: 'flex-start',
26
- borderBottom: `1px solid ${theme.palette.header.page.border}`,
27
- display: 'flex',
28
- gap: theme.spacing(4),
29
- paddingBottom: theme.spacing(2)
30
- },
31
- pageHeaderActions: {
32
- '& > button': {
33
- '&:hover': {
34
- backgroundColor: theme.palette.header.page.action.background.active,
35
- color: theme.palette.header.page.action.color.active
36
- },
37
- backgroundColor: theme.palette.header.page.action.background.default,
38
-
39
- color: theme.palette.header.page.action.color.default
40
- },
41
- display: 'flex',
42
-
43
- gap: theme.spacing(2)
44
- },
45
- pageHeaderMain: {
46
- display: 'flex',
47
- flexGrow: 1,
48
- gap: theme.spacing(1.5)
49
- },
50
- pageHeaderMenu: {
51
- // TEMP
52
- '& [data-size="small"]': {
53
- height: '20px',
54
- marginTop: theme.spacing(0.25),
55
- width: '20px'
56
- },
57
- alignItems: 'top',
58
- display: 'flex',
59
- opacity: 0.5,
60
- padding: theme.spacing(0.25, 0)
61
- },
62
- pageHeaderTitle: {
63
- '& > *': {
64
- display: 'grid'
65
- },
66
- '& > span': {
67
- display: 'flex',
68
- flexDirection: 'row',
69
-
70
- gap: theme.spacing(2)
71
- },
72
- display: 'flex',
73
-
74
- flexDirection: 'column',
75
-
76
- gap: theme.spacing(1),
77
-
78
- h1: {
79
- color: theme.palette.header.page.title,
80
- font: 'normal normal 700 24px/100% Roboto',
81
- letterSpacing: '0.15px',
82
- margin: theme.spacing(0)
83
- }
84
- },
85
- pageHeaderTitleActions: {
86
- '& > button': {
87
- opacity: 0.2,
88
- padding: 0
89
- },
90
- alignItems: 'bottom',
91
- display: 'flex',
92
- gap: theme.spacing(1)
93
- },
94
- pageHeaderTitleDescription: {
95
- color: theme.palette.header.page.description,
96
- font: 'normal normal 400 12px/16px Roboto',
97
- letterSpacing: '0.15px',
98
- maxWidth: '560px',
99
- overflow: 'hidden',
100
- textOverflow: 'ellipsis',
101
- whiteSpace: 'nowrap'
102
- }
103
- }));
104
-
105
- export { useStyles };
@@ -1,15 +0,0 @@
1
- import React, { ReactElement, ReactNode } from 'react';
2
-
3
- import { useStyles } from './PageHeader.styles';
4
-
5
- type PageHeaderProps = {
6
- children?: ReactNode;
7
- };
8
-
9
- const PageHeader = ({ children }: PageHeaderProps): ReactElement => {
10
- const { classes } = useStyles();
11
-
12
- return <section className={classes.pageHeader}>{children}</section>;
13
- };
14
-
15
- export { PageHeader };
@@ -1,17 +0,0 @@
1
- import React, { ReactElement, ReactNode } from 'react';
2
-
3
- import { useStyles } from './PageHeader.styles';
4
-
5
- type PageHeaderActionsProps = {
6
- children?: ReactNode;
7
- };
8
-
9
- const PageHeaderActions = ({
10
- children
11
- }: PageHeaderActionsProps): ReactElement => {
12
- const { classes } = useStyles();
13
-
14
- return <header className={classes.pageHeaderActions}>{children}</header>;
15
- };
16
-
17
- export { PageHeaderActions };
@@ -1,15 +0,0 @@
1
- import React, { ReactElement, ReactNode } from 'react';
2
-
3
- import { useStyles } from './PageHeader.styles';
4
-
5
- type PageHeaderMainProps = {
6
- children?: ReactNode;
7
- };
8
-
9
- const PageHeaderMain = ({ children }: PageHeaderMainProps): ReactElement => {
10
- const { classes } = useStyles();
11
-
12
- return <div className={classes.pageHeaderMain}>{children}</div>;
13
- };
14
-
15
- export { PageHeaderMain };
@@ -1,15 +0,0 @@
1
- import React, { ReactElement, ReactNode } from 'react';
2
-
3
- import { useStyles } from './PageHeader.styles';
4
-
5
- type PageHeaderMenuProps = {
6
- children?: ReactNode;
7
- };
8
-
9
- const PageHeaderMenu = ({ children }: PageHeaderMenuProps): ReactElement => {
10
- const { classes } = useStyles();
11
-
12
- return <nav className={classes.pageHeaderMenu}>{children}</nav>;
13
- };
14
-
15
- export { PageHeaderMenu };
@@ -1,44 +0,0 @@
1
- import React, { ReactElement, ReactNode } from 'react';
2
-
3
- import { Typography as MuiTypography } from '@mui/material';
4
-
5
- import { TextOverflowTooltip } from '../../Tooltip/TextOverflowTooltip';
6
-
7
- import { useStyles } from './PageHeader.styles';
8
-
9
- type PageHeaderTitleProps = {
10
- actions?: ReactNode;
11
- description?: string;
12
- title: string;
13
- };
14
-
15
- const PageHeaderTitle = ({
16
- actions,
17
- title,
18
- description
19
- }: PageHeaderTitleProps): ReactElement => {
20
- const { classes } = useStyles();
21
-
22
- return (
23
- <div className={classes.pageHeaderTitle}>
24
- <span>
25
- <MuiTypography variant="h1">{title}</MuiTypography>
26
- {actions && (
27
- <div className={classes.pageHeaderTitleActions}>{actions}</div>
28
- )}
29
- </span>
30
- {description && (
31
- <TextOverflowTooltip label={description}>
32
- <MuiTypography
33
- className={classes.pageHeaderTitleDescription}
34
- variant="body2"
35
- >
36
- {description}
37
- </MuiTypography>
38
- </TextOverflowTooltip>
39
- )}
40
- </div>
41
- );
42
- };
43
-
44
- export { PageHeaderTitle };