@centreon/ui 23.10.21-MON-19322-dashboard-pages-layout-component.0 → 23.10.21

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "23.10.21-MON-19322-dashboard-pages-layout-component.0",
3
+ "version": "23.10.21",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -1,3 +1,5 @@
1
+ import { ReactElement } from 'react';
2
+
1
3
  import { ComponentMeta } from '@storybook/react';
2
4
  import { Layout } from 'react-grid-layout';
3
5
 
@@ -60,18 +62,18 @@ const generateLayout = (maxElements: number): Array<CustomLayout> => {
60
62
  };
61
63
 
62
64
  interface DashboardTemplateProps {
63
- header?: JSX.Element;
65
+ header?: ReactElement;
64
66
  layout?: Array<CustomLayout>;
65
67
  }
66
68
 
67
- const Header = (): JSX.Element => (
69
+ const Header = (): ReactElement => (
68
70
  <Typography variant="body2">The title</Typography>
69
71
  );
70
72
 
71
73
  const DashboardTemplate = ({
72
74
  header,
73
75
  layout = dashboardLayout
74
- }: DashboardTemplateProps): JSX.Element => (
76
+ }: DashboardTemplateProps): ReactElement => (
75
77
  <DashboardLayout.Layout<CustomLayout> layout={layout}>
76
78
  {layout.map(({ i, content, shouldUseFluidTypography }) => (
77
79
  <DashboardLayout.Item header={header} key={i}>
@@ -1,4 +1,4 @@
1
- import { useEffect, useState } from 'react';
1
+ import { ReactElement, useEffect, useState } from 'react';
2
2
 
3
3
  import { Responsive } from '@visx/visx';
4
4
  import GridLayout, { Layout, WidthProvider } from 'react-grid-layout';
@@ -14,7 +14,7 @@ const ReactGridLayout = WidthProvider(GridLayout);
14
14
 
15
15
  interface DashboardLayoutProps<T> {
16
16
  changeLayout?: (newLayout: Array<Layout>) => void;
17
- children: Array<JSX.Element>;
17
+ children: Array<ReactElement>;
18
18
  displayGrid?: boolean;
19
19
  layout: Array<T>;
20
20
  }
@@ -24,7 +24,7 @@ const Layout = <T extends Layout>({
24
24
  changeLayout,
25
25
  displayGrid,
26
26
  layout
27
- }: DashboardLayoutProps<T>): JSX.Element => {
27
+ }: DashboardLayoutProps<T>): ReactElement => {
28
28
  const { classes } = useDashboardLayoutStyles();
29
29
 
30
30
  const [columns, setColumns] = useState(getColumnsFromScreenSize());
@@ -45,7 +45,7 @@ const Layout = <T extends Layout>({
45
45
  Component: (
46
46
  <ResponsiveHeight>
47
47
  <Responsive.ParentSize>
48
- {({ width, height }): JSX.Element => (
48
+ {({ width, height }): ReactElement => (
49
49
  <div className={classes.container}>
50
50
  {displayGrid && (
51
51
  <Grid columns={columns} height={height} width={width} />
@@ -1,28 +1,28 @@
1
- import { lt } from 'ramda';
2
- import { Layout } from 'react-grid-layout';
3
-
4
- export const maxColumns = 12;
5
- const minColumns = 1;
6
- const breakpoint = 768;
7
-
8
- export const rowHeight = 64;
9
-
10
- export const getIsSmallScreenSize = (): boolean =>
11
- lt(window.innerWidth, breakpoint);
12
-
13
- export const getColumnsFromScreenSize = (): number =>
14
- getIsSmallScreenSize() ? minColumns : maxColumns;
15
-
16
- export const getLayout = <T extends Layout>(layout: Array<T>): Array<T> => {
17
- const isSmallScreenSize = getIsSmallScreenSize();
18
- if (!isSmallScreenSize) {
19
- return layout;
20
- }
21
-
22
- return layout
23
- .sort((a, b) => a.x + a.y - (b.x + b.y))
24
- .map((widget) => ({
25
- ...widget,
26
- w: 1
27
- }));
28
- };
1
+ import { lt } from 'ramda';
2
+ import { Layout } from 'react-grid-layout';
3
+
4
+ export const maxColumns = 12;
5
+ const minColumns = 1;
6
+ const breakpoint = 768;
7
+
8
+ export const rowHeight = 64;
9
+
10
+ export const getIsSmallScreenSize = (): boolean =>
11
+ lt(window.innerWidth, breakpoint);
12
+
13
+ export const getColumnsFromScreenSize = (): number =>
14
+ getIsSmallScreenSize() ? minColumns : maxColumns;
15
+
16
+ export const getLayout = <T extends Layout>(layout: Array<T>): Array<T> => {
17
+ const isSmallScreenSize = getIsSmallScreenSize();
18
+ if (!isSmallScreenSize) {
19
+ return layout;
20
+ }
21
+
22
+ return layout
23
+ .sort((a, b) => a.x + a.y - (b.x + b.y))
24
+ .map((widget) => ({
25
+ ...widget,
26
+ w: 1
27
+ }));
28
+ };
@@ -1,231 +1,201 @@
1
- import { equals } from 'ramda';
2
-
3
- import { alpha, PaletteOptions } from '@mui/material';
4
-
5
- import { ThemeMode } from '@centreon/ui-context';
6
-
7
- declare module '@mui/material/styles/createPalette' {
8
- interface TypeAction {
9
- acknowledged: string;
10
- acknowledgedBackground: string;
11
- inDowntime: string;
12
- inDowntimeBackground: string;
13
- }
14
- }
15
-
16
- declare module '@mui/material/styles' {
17
- interface Palette {
18
- background: {
19
- default: string;
20
- listingHeader: string;
21
- paper: string;
22
- };
23
- layout: TypeLayout;
24
- pending: {
25
- contrastText: string;
26
- main: string;
27
- };
28
- statusBackground: StatusBackground;
29
- }
30
- interface StatusBackground {
31
- error: string;
32
- none: string;
33
- pending: string;
34
- success: string;
35
- unknown: string;
36
- warning: string;
37
- }
38
- interface PaletteOptions {
39
- layout: TypeLayout;
40
- pending: {
41
- contrastText: string;
42
- main: string;
43
- };
44
- statusBackground: StatusBackground;
45
- }
46
-
47
- interface TypeBackground {
48
- listingHeader: string;
49
- }
50
-
51
- interface TypeLayout {
52
- body: {
53
- background: string;
54
- };
55
- header: {
56
- background: string;
57
- border: string;
58
- };
59
- }
60
- }
61
-
62
- declare module '@mui/material/Button' {
63
- interface ButtonPropsColorOverrides {
64
- pending: true;
65
- }
66
- }
67
-
68
- declare module '@mui/material/Badge' {
69
- interface BadgePropsColorOverrides {
70
- pending: true;
71
- }
72
- }
73
-
74
- export const lightPalette: PaletteOptions = {
75
- action: {
76
- acknowledged: '#67532C',
77
- acknowledgedBackground: '#F5F1E9',
78
- activatedOpacity: 0.12,
79
- active: '#666666',
80
- disabled: '#999999',
81
- disabledBackground: 'rgba(0, 0, 0, 0.12)',
82
- focus: 'rgba(0, 0, 0, 0.12)',
83
- focusOpacity: 0.12,
84
- hover: 'rgba(0, 0, 0, 0.06)',
85
- hoverOpacity: 0.06,
86
- inDowntime: '#4B2352',
87
- inDowntimeBackground: '#F0E9F8',
88
- selected: 'rgba(102, 102, 102, 0.3)',
89
- selectedOpacity: 0.3
90
- },
91
- background: {
92
- default: '#F4F4F4',
93
- listingHeader: '#666666',
94
- paper: '#FFFFFF'
95
- },
96
- divider: '#E3E3E3',
97
- error: {
98
- contrastText: '#000',
99
- main: '#FF4A4A'
100
- },
101
- info: {
102
- contrastText: '#000',
103
- main: '#1588D1'
104
- },
105
- layout: {
106
- body: {
107
- background: '#F6F6F6'
108
- },
109
- header: {
110
- background: '#FFFFFF',
111
- border: '#E3E3E3'
112
- }
113
- },
114
- mode: ThemeMode.light,
115
- pending: {
116
- contrastText: '#000',
117
- main: '#1EBEB3'
118
- },
119
- primary: {
120
- contrastText: '#fff',
121
- dark: '#255891',
122
- light: '#cde7fc',
123
- main: '#2E68AA'
124
- },
125
- secondary: {
126
- contrastText: '#fff',
127
- main: '#C772D6'
128
- },
129
- statusBackground: {
130
- error: '#FF6666',
131
- none: alpha('#2E68AA', 0.1),
132
- pending: '#1EBEB3',
133
- success: '#88B922',
134
- unknown: '#E3E3E3',
135
- warning: '#FD9B27'
136
- },
137
- success: {
138
- contrastText: '#000',
139
- main: '#88B922'
140
- },
141
- text: {
142
- disabled: '#999999',
143
- primary: '#000000',
144
- secondary: '#666666'
145
- },
146
- warning: {
147
- contrastText: '#000',
148
- main: '#FD9B27'
149
- }
150
- };
151
-
152
- export const darkPalette: PaletteOptions = {
153
- action: {
154
- acknowledged: '#67532C',
155
- acknowledgedBackground: '#67532C',
156
- activatedOpacity: 0.3,
157
- active: '#B5B5B5',
158
- disabled: '#999999',
159
- disabledBackground: '#555555',
160
- focus: 'rgba(255, 255, 255, 0.30)',
161
- focusOpacity: 0.3,
162
- hover: 'rgba(255, 255, 255, 0.16)',
163
- hoverOpacity: 0.16,
164
- inDowntime: '#4B2352',
165
- inDowntimeBackground: '#4B2352',
166
- selected: 'rgba(255, 255, 255, 0.5)',
167
- selectedOpacity: 0.5
168
- },
169
- background: {
170
- default: '#4a4a4a',
171
- listingHeader: '#666666',
172
- paper: '#212121'
173
- },
174
- divider: '#666666',
175
- error: {
176
- contrastText: '#fff',
177
- main: '#D60101'
178
- },
179
- info: {
180
- contrastText: '#fff',
181
- main: '#1CA9F4'
182
- },
183
- layout: {
184
- body: {
185
- background: '#F6F6F6'
186
- },
187
- header: {
188
- background: '#FFFFFF',
189
- border: '#E3E3E3'
190
- }
191
- },
192
- mode: ThemeMode.dark,
193
- pending: {
194
- contrastText: '#fff',
195
- main: '#118077'
196
- },
197
- primary: {
198
- contrastText: '#000',
199
- dark: '#4974A5',
200
- light: '#8bbff9',
201
- main: '#6eaff8'
202
- },
203
- secondary: {
204
- contrastText: '#fff',
205
- main: '#7C1FA2'
206
- },
207
- statusBackground: {
208
- error: '#D60101',
209
- none: alpha('#2E68AA', 0.1),
210
- pending: '#118077',
211
- success: '#5F8118',
212
- unknown: '#666666',
213
- warning: '#C55400'
214
- },
215
- success: {
216
- contrastText: '#fff',
217
- main: '#5F8118'
218
- },
219
- text: {
220
- disabled: '#666666',
221
- primary: '#FFFFFF',
222
- secondary: '#CCCCCC'
223
- },
224
- warning: {
225
- contrastText: '#fff',
226
- main: '#C55400'
227
- }
228
- };
229
-
230
- export const getPalette = (mode: ThemeMode): PaletteOptions =>
231
- equals(mode, ThemeMode.dark) ? darkPalette : lightPalette;
1
+ import { equals } from 'ramda';
2
+
3
+ import { alpha, PaletteOptions } from '@mui/material';
4
+
5
+ import { ThemeMode } from '@centreon/ui-context';
6
+
7
+ declare module '@mui/material/styles/createPalette' {
8
+ interface TypeAction {
9
+ acknowledged: string;
10
+ acknowledgedBackground: string;
11
+ inDowntime: string;
12
+ inDowntimeBackground: string;
13
+ }
14
+ }
15
+
16
+ declare module '@mui/material/styles' {
17
+ interface Palette {
18
+ background: {
19
+ default: string;
20
+ listingHeader: string;
21
+ paper: string;
22
+ };
23
+ pending: {
24
+ contrastText: string;
25
+ main: string;
26
+ };
27
+ statusBackground: StatusBackground;
28
+ }
29
+ interface StatusBackground {
30
+ error: string;
31
+ none: string;
32
+ pending: string;
33
+ success: string;
34
+ unknown: string;
35
+ warning: string;
36
+ }
37
+ interface PaletteOptions {
38
+ pending: {
39
+ contrastText: string;
40
+ main: string;
41
+ };
42
+ statusBackground: StatusBackground;
43
+ }
44
+
45
+ interface TypeBackground {
46
+ listingHeader: string;
47
+ }
48
+ }
49
+
50
+ declare module '@mui/material/Button' {
51
+ interface ButtonPropsColorOverrides {
52
+ pending: true;
53
+ }
54
+ }
55
+
56
+ declare module '@mui/material/Badge' {
57
+ interface BadgePropsColorOverrides {
58
+ pending: true;
59
+ }
60
+ }
61
+
62
+ export const lightPalette: PaletteOptions = {
63
+ action: {
64
+ acknowledged: '#67532C',
65
+ acknowledgedBackground: '#F5F1E9',
66
+ activatedOpacity: 0.12,
67
+ active: '#666666',
68
+ disabled: '#999999',
69
+ disabledBackground: 'rgba(0, 0, 0, 0.12)',
70
+ focus: 'rgba(0, 0, 0, 0.12)',
71
+ focusOpacity: 0.12,
72
+ hover: 'rgba(0, 0, 0, 0.06)',
73
+ hoverOpacity: 0.06,
74
+ inDowntime: '#4B2352',
75
+ inDowntimeBackground: '#F0E9F8',
76
+ selected: 'rgba(102, 102, 102, 0.3)',
77
+ selectedOpacity: 0.3
78
+ },
79
+ background: {
80
+ default: '#F4F4F4',
81
+ listingHeader: '#666666',
82
+ paper: '#FFFFFF'
83
+ },
84
+ divider: '#E3E3E3',
85
+ error: {
86
+ contrastText: '#000',
87
+ main: '#FF4A4A'
88
+ },
89
+ info: {
90
+ contrastText: '#000',
91
+ main: '#1588D1'
92
+ },
93
+ mode: ThemeMode.light,
94
+ pending: {
95
+ contrastText: '#000',
96
+ main: '#1EBEB3'
97
+ },
98
+ primary: {
99
+ contrastText: '#fff',
100
+ dark: '#255891',
101
+ light: '#cde7fc',
102
+ main: '#2E68AA'
103
+ },
104
+ secondary: {
105
+ contrastText: '#fff',
106
+ main: '#C772D6'
107
+ },
108
+ statusBackground: {
109
+ error: '#FF6666',
110
+ none: alpha('#2E68AA', 0.1),
111
+ pending: '#1EBEB3',
112
+ success: '#88B922',
113
+ unknown: '#E3E3E3',
114
+ warning: '#FD9B27'
115
+ },
116
+ success: {
117
+ contrastText: '#000',
118
+ main: '#88B922'
119
+ },
120
+ text: {
121
+ disabled: '#999999',
122
+ primary: '#000000',
123
+ secondary: '#666666'
124
+ },
125
+ warning: {
126
+ contrastText: '#000',
127
+ main: '#FD9B27'
128
+ }
129
+ };
130
+
131
+ export const darkPalette: PaletteOptions = {
132
+ action: {
133
+ acknowledged: '#67532C',
134
+ acknowledgedBackground: '#67532C',
135
+ activatedOpacity: 0.3,
136
+ active: '#B5B5B5',
137
+ disabled: '#999999',
138
+ disabledBackground: '#555555',
139
+ focus: 'rgba(255, 255, 255, 0.30)',
140
+ focusOpacity: 0.3,
141
+ hover: 'rgba(255, 255, 255, 0.16)',
142
+ hoverOpacity: 0.16,
143
+ inDowntime: '#4B2352',
144
+ inDowntimeBackground: '#4B2352',
145
+ selected: 'rgba(255, 255, 255, 0.5)',
146
+ selectedOpacity: 0.5
147
+ },
148
+ background: {
149
+ default: '#4a4a4a',
150
+ listingHeader: '#666666',
151
+ paper: '#212121'
152
+ },
153
+ divider: '#666666',
154
+ error: {
155
+ contrastText: '#fff',
156
+ main: '#D60101'
157
+ },
158
+ info: {
159
+ contrastText: '#fff',
160
+ main: '#1CA9F4'
161
+ },
162
+ mode: ThemeMode.dark,
163
+ pending: {
164
+ contrastText: '#fff',
165
+ main: '#118077'
166
+ },
167
+ primary: {
168
+ contrastText: '#000',
169
+ dark: '#4974A5',
170
+ light: '#8bbff9',
171
+ main: '#6eaff8'
172
+ },
173
+ secondary: {
174
+ contrastText: '#fff',
175
+ main: '#7C1FA2'
176
+ },
177
+ statusBackground: {
178
+ error: '#D60101',
179
+ none: alpha('#2E68AA', 0.1),
180
+ pending: '#118077',
181
+ success: '#5F8118',
182
+ unknown: '#666666',
183
+ warning: '#C55400'
184
+ },
185
+ success: {
186
+ contrastText: '#fff',
187
+ main: '#5F8118'
188
+ },
189
+ text: {
190
+ disabled: '#666666',
191
+ primary: '#FFFFFF',
192
+ secondary: '#CCCCCC'
193
+ },
194
+ warning: {
195
+ contrastText: '#fff',
196
+ main: '#C55400'
197
+ }
198
+ };
199
+
200
+ export const getPalette = (mode: ThemeMode): PaletteOptions =>
201
+ equals(mode, ThemeMode.dark) ? darkPalette : lightPalette;
@@ -12,6 +12,7 @@ const useStyles = makeStyles()((theme) => ({
12
12
  margin: theme.spacing(0, 0, 1.5, 0)
13
13
  },
14
14
  justifyContent: 'space-between',
15
+ marginBottom: theme.spacing(2.5),
15
16
 
16
17
  nav: {
17
18
  display: 'flex',
@@ -3,4 +3,3 @@ export * from './Modal';
3
3
  export * from './Form';
4
4
  export * from './Header';
5
5
  export * from './DataTable';
6
- export * from './Layout';
package/src/index.ts CHANGED
@@ -138,6 +138,8 @@ export { default as ActionsList } from './ActionsList';
138
138
 
139
139
  export type { ResponseError, CatchErrorProps } from './api/customFetch';
140
140
 
141
+ export * from './layout/TiledListingPage';
142
+
141
143
  export * from './utils';
142
144
  export { default as FluidTypography } from './Typography/FluidTypography';
143
145
  export * from './Dashboard';
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ import { useTiledListingActionsStyles } from './TiledListingPage.styles';
4
+
5
+ interface TiledListingActionsProps {
6
+ children: Array<ReactNode> | ReactNode;
7
+ }
8
+
9
+ export const TiledListingActions = ({
10
+ children
11
+ }: TiledListingActionsProps): JSX.Element => {
12
+ const { classes } = useTiledListingActionsStyles();
13
+
14
+ return <div className={classes.actions}>{children}</div>;
15
+ };
@@ -0,0 +1,21 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ import Responsive from '../../Responsive';
4
+
5
+ import { useTiledListingActionsStyles } from './TiledListingPage.styles';
6
+
7
+ interface TiledListingContentProps {
8
+ children: ReactNode;
9
+ }
10
+
11
+ export const TiledListingContent = ({
12
+ children
13
+ }: TiledListingContentProps): JSX.Element => {
14
+ const { classes } = useTiledListingActionsStyles();
15
+
16
+ return (
17
+ <Responsive>
18
+ <div className={classes.actions}>{children}</div>
19
+ </Responsive>
20
+ );
21
+ };
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ interface TiledListingListProps {
4
+ children: Array<ReactNode>;
5
+ }
6
+
7
+ export const TiledListingList = ({
8
+ children
9
+ }: TiledListingListProps): JSX.Element => {
10
+ return <div>{children}</div>;
11
+ };
@@ -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';
@@ -15,7 +15,12 @@ import {
15
15
  Modal
16
16
  } from '../../components';
17
17
  import { Default as DashboardFormDefaultStory } from '../../components/Form/Dashboard/DashboardForm.stories';
18
- import { PageLayout } from '../../components/Layout/PageLayout';
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,12 +134,10 @@ const DefaultView = (args): JSX.Element => {
132
134
  };
133
135
 
134
136
  return (
135
- <PageLayout>
136
- <PageLayout.Header>
137
- <Header title={title} />
138
- </PageLayout.Header>
139
- <PageLayout.Body>
140
- <PageLayout.Actions>
137
+ <TiledListingPage>
138
+ <Header title={title} />
139
+ <TiledListingList>
140
+ <TiledListingActions>
141
141
  {dataDashboards.length !== 0 && (
142
142
  <Button
143
143
  aria-label="add"
@@ -150,105 +150,101 @@ const DefaultView = (args): JSX.Element => {
150
150
  {actions.create.label}
151
151
  </Button>
152
152
  )}
153
- </PageLayout.Actions>
154
-
155
- <DataTable isEmpty={dataDashboards.length === 0}>
156
- {dataDashboards.length === 0 ? (
157
- <DataTable.EmptyState
158
- labels={list.emptyState.labels}
159
- 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={() =>
160
205
  setDialogState({
161
206
  item: null,
162
- open: true,
163
- variant: 'create'
207
+ open: false,
208
+ variant: dialogState.variant
164
209
  })
165
210
  }
211
+ onSubmit={(values) =>
212
+ dialogState.variant === 'create'
213
+ ? createDashboard(values)
214
+ : updateDashboard(values)
215
+ }
166
216
  />
167
- ) : (
168
- dataDashboards.map((dashboard) => (
169
- <DataTable.Item
170
- hasActions
171
- hasCardAction
172
- description={dashboard.description}
173
- key={dashboard.id}
174
- title={dashboard.name}
175
- onDelete={() =>
176
- setDeleteDialogState({ item: dashboard, open: true })
177
- }
178
- onEdit={() =>
179
- setDialogState({
180
- item: dashboard,
181
- open: true,
182
- variant: 'update'
183
- })
184
- }
185
- />
186
- ))
187
- )}
188
- </DataTable>
189
- </PageLayout.Body>
190
-
191
- <Modal
192
- open={dialogState.open}
193
- onClose={() =>
194
- setDialogState({
195
- item: null,
196
- open: false,
197
- variant: dialogState.variant
198
- })
199
- }
200
- >
201
- <Modal.Header>
202
- {form.labels.title[dialogState.variant ?? 'create']}
203
- </Modal.Header>
204
- <Modal.Body>
205
- <DashboardForm
206
- labels={DashboardFormDefaultStory!.args!.labels!}
207
- resource={dialogState.item || undefined}
208
- variant={dialogState.variant}
209
- onCancel={() =>
210
- setDialogState({
211
- item: null,
212
- open: false,
213
- variant: dialogState.variant
214
- })
215
- }
216
- onSubmit={(values) =>
217
- dialogState.variant === 'create'
218
- ? createDashboard(values)
219
- : updateDashboard(values)
220
- }
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
+ }}
221
244
  />
222
- </Modal.Body>
223
- </Modal>
224
- <Modal
225
- open={deleteDialogState.open}
226
- onClose={() =>
227
- setDeleteDialogState({
228
- ...deleteDialogState,
229
- open: false
230
- })
231
- }
232
- >
233
- <Modal.Header>{deleteConfirmation.labels.title}</Modal.Header>
234
- <Modal.Body>
235
- <p>
236
- {deleteConfirmation.labels.description(
237
- deleteDialogState.item?.name
238
- )}
239
- </p>
240
- </Modal.Body>
241
- <Modal.Actions
242
- isDanger
243
- labels={deleteConfirmation.labels.actions}
244
- onCancel={() => setDeleteDialogState({ item: null, open: false })}
245
- onConfirm={() => {
246
- deleteDashboard(deleteDialogState.item?.id);
247
- setDeleteDialogState({ item: null, open: false });
248
- }}
249
- />
250
- </Modal>
251
- </PageLayout>
245
+ </Modal>
246
+ </TiledListingList>
247
+ </TiledListingPage>
252
248
  );
253
249
  };
254
250
 
@@ -1,31 +0,0 @@
1
- import { makeStyles } from 'tss-react/mui';
2
-
3
- export const useStyles = makeStyles()((theme) => ({
4
- areaIndicator: {
5
- '& .areaIndicator': {
6
- left: theme.spacing(10)
7
- },
8
- '& label:first-of-type': {
9
- fontSize: '0.75rem',
10
- fontWeight: 500,
11
- left: theme.spacing(1),
12
- position: 'absolute',
13
- top: theme.spacing(0.75)
14
- },
15
- '&[data-depth="1"]': {
16
- '& label:first-of-type': {
17
- '&:before': {
18
- content: '"+ "'
19
- },
20
- left: theme.spacing(10)
21
- }
22
- },
23
-
24
- backgroundColor: '#9747FF19',
25
- borderRadius: '4px',
26
- color: '#9747FFFF',
27
- minHeight: theme.spacing(4),
28
-
29
- position: 'relative'
30
- }
31
- }));
@@ -1,35 +0,0 @@
1
- import { ReactElement, ReactNode } from 'react';
2
-
3
- import { useStyles } from './AreaIndicator.styles';
4
-
5
- type AreaIndicatorProps = {
6
- children?: ReactNode | Array<ReactNode>;
7
- depth?: number;
8
- height?: number | string;
9
- name: string;
10
- width?: number | string;
11
- };
12
-
13
- const AreaIndicator = ({
14
- children,
15
- name = 'area',
16
- width = '100%',
17
- height = '100%',
18
- depth = 0
19
- }: AreaIndicatorProps): ReactElement => {
20
- const { classes } = useStyles();
21
-
22
- return (
23
- <div
24
- className={classes.areaIndicator}
25
- data-depth={depth}
26
- style={{ height, width }}
27
- >
28
- {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
29
- <label>{name}</label>
30
- {children}
31
- </div>
32
- );
33
- };
34
-
35
- export { AreaIndicator };
@@ -1,62 +0,0 @@
1
- import { Meta, StoryObj } from '@storybook/react';
2
-
3
- import { AreaIndicator } from '../AreaIndicator';
4
-
5
- import { PageLayout } from './index';
6
-
7
- const meta: Meta<typeof PageLayout> = {
8
- argTypes: {
9
- variant: {
10
- control: {
11
- options: ['default', 'fixed-header']
12
- }
13
- }
14
- },
15
- component: PageLayout,
16
- parameters: {
17
- layout: 'fullscreen'
18
- }
19
- };
20
-
21
- export default meta;
22
- type Story = StoryObj<typeof PageLayout>;
23
-
24
- export const Default: Story = {
25
- args: {
26
- children: (
27
- <>
28
- <PageLayout.Header>
29
- <AreaIndicator name="header" />
30
- </PageLayout.Header>
31
- <PageLayout.Body>
32
- <AreaIndicator height="100vh" name="body">
33
- <PageLayout.Actions>
34
- <AreaIndicator depth={1} name="actions" />
35
- </PageLayout.Actions>
36
- </AreaIndicator>
37
- </PageLayout.Body>
38
- </>
39
- ),
40
- variant: 'default'
41
- }
42
- };
43
-
44
- export const FixedHeader: Story = {
45
- args: {
46
- children: (
47
- <>
48
- <PageLayout.Header>
49
- <AreaIndicator name="header" />
50
- </PageLayout.Header>
51
- <PageLayout.Body hasBackground>
52
- <AreaIndicator height="100vh" name="body">
53
- <PageLayout.Actions>
54
- <AreaIndicator depth={1} name="actions" />
55
- </PageLayout.Actions>
56
- </AreaIndicator>
57
- </PageLayout.Body>
58
- </>
59
- ),
60
- variant: 'fixed-header'
61
- }
62
- };
@@ -1,30 +0,0 @@
1
- import { makeStyles } from 'tss-react/mui';
2
-
3
- export const useStyles = makeStyles()((theme) => ({
4
- pageLayout: {
5
- display: 'flex',
6
- flexDirection: 'column',
7
- height: '100%'
8
- },
9
- pageLayoutActions: {
10
- paddingBottom: theme.spacing(2.5)
11
- },
12
- pageLayoutBody: {
13
- '&[data-has-background="true"]': {
14
- backgroundColor: theme.palette.layout.body.background
15
- },
16
- padding: theme.spacing(3, 4, 5)
17
- },
18
- pageLayoutHeader: {
19
- '[data-variant="fixed-header"] &': {
20
- backgroundColor: theme.palette.layout.header.background,
21
- borderBottom: `1px solid ${theme.palette.layout.header.border}`,
22
- padding: theme.spacing(5, 4, 2),
23
- position: 'sticky',
24
- top: 0,
25
- zIndex: `calc(${theme.zIndex.mobileStepper} - 100)`
26
- },
27
-
28
- padding: theme.spacing(5, 4, 0)
29
- }
30
- }));
@@ -1,21 +0,0 @@
1
- import { ReactElement, ReactNode } from 'react';
2
-
3
- import { useStyles } from './PageLayout.styles';
4
-
5
- type PageLayoutProps = {
6
- children: Array<ReactNode> | ReactNode;
7
- variant?: 'default' | 'fixed-header';
8
- };
9
-
10
- export const PageLayout = ({
11
- children,
12
- variant = 'default'
13
- }: PageLayoutProps): ReactElement => {
14
- const { classes } = useStyles();
15
-
16
- return (
17
- <section className={classes.pageLayout} data-variant={variant}>
18
- {children}
19
- </section>
20
- );
21
- };
@@ -1,15 +0,0 @@
1
- import { ReactElement, ReactNode } from 'react';
2
-
3
- import { useStyles } from './PageLayout.styles';
4
-
5
- type PageLayoutActionsProps = {
6
- children: Array<ReactNode> | ReactNode;
7
- };
8
-
9
- export const PageLayoutActions = ({
10
- children
11
- }: PageLayoutActionsProps): ReactElement => {
12
- const { classes } = useStyles();
13
-
14
- return <section className={classes.pageLayoutActions}>{children}</section>;
15
- };
@@ -1,24 +0,0 @@
1
- import { ReactElement, ReactNode } from 'react';
2
-
3
- import { useStyles } from './PageLayout.styles';
4
-
5
- type PageLayoutBodyProps = {
6
- children: Array<ReactNode> | ReactNode;
7
- hasBackground?: boolean;
8
- };
9
-
10
- export const PageLayoutBody = ({
11
- children,
12
- hasBackground = false
13
- }: PageLayoutBodyProps): ReactElement => {
14
- const { classes } = useStyles();
15
-
16
- return (
17
- <section
18
- className={classes.pageLayoutBody}
19
- data-has-background={hasBackground}
20
- >
21
- {children}
22
- </section>
23
- );
24
- };
@@ -1,15 +0,0 @@
1
- import { ReactNode } from 'react';
2
-
3
- import { useStyles } from './PageLayout.styles';
4
-
5
- type PageLayoutHeaderProps = {
6
- children: Array<ReactNode> | ReactNode;
7
- };
8
-
9
- export const PageLayoutHeader = ({
10
- children
11
- }: PageLayoutHeaderProps): JSX.Element => {
12
- const { classes } = useStyles();
13
-
14
- return <header className={classes.pageLayoutHeader}>{children}</header>;
15
- };
@@ -1,10 +0,0 @@
1
- import { PageLayout as PageLayoutRoot } from './PageLayout';
2
- import { PageLayoutHeader } from './PageLayoutHeader';
3
- import { PageLayoutBody } from './PageLayoutBody';
4
- import { PageLayoutActions } from './PageLayoutActions';
5
-
6
- export const PageLayout = Object.assign(PageLayoutRoot, {
7
- Actions: PageLayoutActions,
8
- Body: PageLayoutBody,
9
- Header: PageLayoutHeader
10
- });
@@ -1 +0,0 @@
1
- export * from './PageLayout';