@centreon/ui 24.11.2 → 24.11.4
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 +2 -3
- package/src/Dashboard/Dashboard.styles.ts +4 -3
- package/src/Dashboard/DashboardLayout.stories.tsx +1 -1
- package/src/Dashboard/Grid.tsx +17 -11
- package/src/Dashboard/Layout.tsx +56 -27
- package/src/FileDropZone/index.tsx +21 -23
- package/src/Form/CollapsibleGroup.tsx +3 -2
- package/src/Form/Form.cypress.spec.tsx +39 -0
- package/src/Form/Form.tsx +1 -0
- package/src/Form/Inputs/Autocomplete.tsx +27 -4
- package/src/Form/Inputs/ConnectedAutocomplete.tsx +20 -10
- package/src/Form/Inputs/File.tsx +69 -0
- package/src/Form/Inputs/Grid.tsx +30 -2
- package/src/Form/Inputs/Radio.tsx +12 -4
- package/src/Form/Inputs/Switch.tsx +10 -2
- package/src/Form/Inputs/Text.tsx +13 -4
- package/src/Form/Inputs/index.tsx +5 -2
- package/src/Form/Inputs/models.ts +18 -2
- package/src/Form/storiesData.tsx +15 -3
- package/src/Form/translatedLabels.ts +1 -0
- package/src/Graph/BarChart/BarChart.tsx +4 -1
- package/src/Graph/BarChart/ResponsiveBarChart.tsx +3 -2
- package/src/Graph/Chart/Chart.tsx +9 -2
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +2 -2
- package/src/Graph/Chart/InteractiveComponents/index.tsx +10 -2
- package/src/Graph/Chart/helpers/index.ts +5 -5
- package/src/Graph/Chart/index.tsx +7 -0
- package/src/Graph/Chart/models.ts +1 -0
- package/src/Graph/common/timeSeries/index.ts +15 -8
- package/src/InputField/Text/index.tsx +1 -1
- package/src/Listing/index.tsx +39 -27
- package/src/Listing/models.ts +8 -0
- package/src/MultiSelectEntries/index.tsx +0 -2
- package/src/PopoverMenu/index.tsx +9 -2
- package/src/SortableItems/index.tsx +1 -0
- package/src/ThemeProvider/index.tsx +1 -1
- package/src/ThemeProvider/palettes.ts +4 -4
- package/src/api/customFetch.ts +4 -1
- package/src/components/CrudPage/Actions/Actions.styles.ts +16 -0
- package/src/components/CrudPage/Actions/Actions.tsx +24 -0
- package/src/components/CrudPage/Actions/AddButton.tsx +23 -0
- package/src/components/CrudPage/Actions/Filters.tsx +25 -0
- package/src/components/CrudPage/Actions/Search.tsx +31 -0
- package/src/components/CrudPage/Actions/useSearch.tsx +24 -0
- package/src/components/CrudPage/Columns/Actions.tsx +88 -0
- package/src/components/CrudPage/CrudPage.cypress.spec.tsx +559 -0
- package/src/components/CrudPage/CrudPage.stories.tsx +278 -0
- package/src/components/CrudPage/CrudPageRoot.tsx +142 -0
- package/src/components/CrudPage/DeleteModal.tsx +77 -0
- package/src/components/CrudPage/Form/AddModal.tsx +35 -0
- package/src/components/CrudPage/Form/Buttons.tsx +98 -0
- package/src/components/CrudPage/Form/UpdateModal.tsx +60 -0
- package/src/components/CrudPage/Listing.tsx +63 -0
- package/src/components/CrudPage/atoms.ts +30 -0
- package/src/components/CrudPage/hooks/useDeleteItem.ts +53 -0
- package/src/components/CrudPage/hooks/useGetItem.ts +36 -0
- package/src/components/CrudPage/hooks/useGetItems.ts +67 -0
- package/src/components/CrudPage/hooks/useListingQueryKey.ts +31 -0
- package/src/components/CrudPage/index.tsx +7 -0
- package/src/components/CrudPage/models.ts +118 -0
- package/src/components/CrudPage/utils.ts +4 -0
- package/src/components/DataTable/DataTable.cypress.spec.tsx +2 -1
- package/src/components/DataTable/DataTable.stories.tsx +17 -0
- package/src/components/DataTable/DataTable.styles.ts +1 -1
- package/src/components/DataTable/EmptyState/DataTableEmptyState.styles.ts +3 -1
- package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +6 -0
- package/src/components/DataTable/Item/DataTableItem.styles.ts +28 -2
- package/src/components/DataTable/Item/DataTableItem.tsx +19 -4
- package/src/components/Layout/AreaIndicator.tsx +1 -1
- package/src/components/Layout/PageLayout/PageLayout.styles.ts +7 -2
- package/src/components/Layout/PageLayout/PageLayoutBody.tsx +1 -0
- package/src/components/Modal/Modal.styles.ts +1 -1
- package/src/components/Zoom/Zoom.tsx +2 -2
- package/src/components/Zoom/ZoomContent.tsx +2 -2
- package/src/components/index.ts +1 -0
|
@@ -261,7 +261,7 @@ export const getTheme = (mode: ThemeMode): ThemeOptions => ({
|
|
|
261
261
|
{
|
|
262
262
|
backgroundColor: theme.palette.background.default,
|
|
263
263
|
border: 'none',
|
|
264
|
-
borderRadius:
|
|
264
|
+
borderRadius: `${theme.shape.borderRadius}px`,
|
|
265
265
|
boxShadow: theme.shadows[3]
|
|
266
266
|
}
|
|
267
267
|
})
|
|
@@ -157,7 +157,7 @@ declare module '@mui/material/Badge' {
|
|
|
157
157
|
|
|
158
158
|
export const lightPalette: PaletteOptions = {
|
|
159
159
|
action: {
|
|
160
|
-
acknowledged: '#
|
|
160
|
+
acknowledged: '#745F35',
|
|
161
161
|
acknowledgedBackground: '#DFD2B9',
|
|
162
162
|
activatedOpacity: 0.12,
|
|
163
163
|
active: '#666666',
|
|
@@ -167,7 +167,7 @@ export const lightPalette: PaletteOptions = {
|
|
|
167
167
|
focusOpacity: 0.12,
|
|
168
168
|
hover: 'rgba(0, 0, 0, 0.06)',
|
|
169
169
|
hoverOpacity: 0.06,
|
|
170
|
-
inDowntime: '#
|
|
170
|
+
inDowntime: '#512980',
|
|
171
171
|
inDowntimeBackground: '#E5D8F3',
|
|
172
172
|
selected: 'rgba(102, 102, 102, 0.3)',
|
|
173
173
|
selectedOpacity: 0.3
|
|
@@ -297,7 +297,7 @@ export const lightPalette: PaletteOptions = {
|
|
|
297
297
|
|
|
298
298
|
export const darkPalette: PaletteOptions = {
|
|
299
299
|
action: {
|
|
300
|
-
acknowledged: '#
|
|
300
|
+
acknowledged: '#DFD2B9',
|
|
301
301
|
acknowledgedBackground: '#745F35',
|
|
302
302
|
activatedOpacity: 0.3,
|
|
303
303
|
active: '#B5B5B5',
|
|
@@ -307,7 +307,7 @@ export const darkPalette: PaletteOptions = {
|
|
|
307
307
|
focusOpacity: 0.3,
|
|
308
308
|
hover: 'rgba(255, 255, 255, 0.16)',
|
|
309
309
|
hoverOpacity: 0.16,
|
|
310
|
-
inDowntime: '#
|
|
310
|
+
inDowntime: '#E5D8F3',
|
|
311
311
|
inDowntimeBackground: '#512980',
|
|
312
312
|
selected: 'rgba(255, 255, 255, 0.5)',
|
|
313
313
|
selectedOpacity: 0.5
|
package/src/api/customFetch.ts
CHANGED
|
@@ -55,10 +55,13 @@ export const customFetch = <T>({
|
|
|
55
55
|
? `${baseEndpoint}${endpoint}`
|
|
56
56
|
: endpoint;
|
|
57
57
|
|
|
58
|
+
const isFormData = payload instanceof FormData;
|
|
59
|
+
|
|
58
60
|
const options = isMutation
|
|
59
61
|
? {
|
|
60
62
|
...defaultOptions,
|
|
61
|
-
body:
|
|
63
|
+
body: isFormData ? payload : JSON.stringify(payload),
|
|
64
|
+
headers: isFormData ? undefined : headers
|
|
62
65
|
}
|
|
63
66
|
: defaultOptions;
|
|
64
67
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { makeStyles } from 'tss-react/mui';
|
|
2
|
+
|
|
3
|
+
export const useActionsStyles = makeStyles()((theme) => ({
|
|
4
|
+
search: {
|
|
5
|
+
maxWidth: theme.spacing(50)
|
|
6
|
+
},
|
|
7
|
+
clearButton: {
|
|
8
|
+
alignSelf: 'flex-start'
|
|
9
|
+
},
|
|
10
|
+
tooltipFilters: {
|
|
11
|
+
padding: theme.spacing(2, 3),
|
|
12
|
+
display: 'flex',
|
|
13
|
+
flexDirection: 'column',
|
|
14
|
+
gap: theme.spacing(2)
|
|
15
|
+
}
|
|
16
|
+
}));
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Box } from '@mui/material';
|
|
2
|
+
import AddButton from './AddButton';
|
|
3
|
+
import Search from './Search';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
labels: {
|
|
7
|
+
search: string;
|
|
8
|
+
add: string;
|
|
9
|
+
};
|
|
10
|
+
filters: JSX.Element;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const Actions = ({ labels, filters }: Props): JSX.Element => {
|
|
14
|
+
return (
|
|
15
|
+
<Box
|
|
16
|
+
sx={{ display: 'grid', gridTemplateColumns: 'min-content auto', gap: 2 }}
|
|
17
|
+
>
|
|
18
|
+
<AddButton label={labels.add} />
|
|
19
|
+
<Search label={labels.search} filters={filters} />
|
|
20
|
+
</Box>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default Actions;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Add } from '@mui/icons-material';
|
|
2
|
+
import { useSetAtom } from 'jotai';
|
|
3
|
+
import { useCallback } from 'react';
|
|
4
|
+
import { Button } from '../../Button';
|
|
5
|
+
import { openFormModalAtom } from '../atoms';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
label: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const AddButton = ({ label }: Props): JSX.Element => {
|
|
12
|
+
const setOpenFormModal = useSetAtom(openFormModalAtom);
|
|
13
|
+
|
|
14
|
+
const add = useCallback(() => setOpenFormModal('add'), []);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Button size="small" icon={<Add />} iconVariant="start" onClick={add}>
|
|
18
|
+
{label}
|
|
19
|
+
</Button>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default AddButton;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Tune } from '@mui/icons-material';
|
|
2
|
+
import { isValidElement } from 'react';
|
|
3
|
+
import PopoverMenu from '../../../PopoverMenu';
|
|
4
|
+
import { useActionsStyles } from './Actions.styles';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
label: string;
|
|
8
|
+
filters: JSX.Element;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const Filters: React.FC<Props> = ({ label, filters }: Props): JSX.Element => {
|
|
12
|
+
const { classes } = useActionsStyles();
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<PopoverMenu
|
|
16
|
+
title={label}
|
|
17
|
+
icon={<Tune />}
|
|
18
|
+
tooltipClassName={classes.tooltipFilters}
|
|
19
|
+
>
|
|
20
|
+
{isValidElement(filters) ? filters : <div />}
|
|
21
|
+
</PopoverMenu>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default Filters;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { SearchField } from '@centreon/ui';
|
|
2
|
+
import { useActionsStyles } from './Actions.styles';
|
|
3
|
+
import Filters from './Filters';
|
|
4
|
+
import { useSearch } from './useSearch';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
label: string;
|
|
8
|
+
filters: JSX.Element;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const Search = ({ label, filters }: Props): JSX.Element => {
|
|
12
|
+
const { classes } = useActionsStyles();
|
|
13
|
+
|
|
14
|
+
const { change } = useSearch();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<SearchField
|
|
18
|
+
className={classes.search}
|
|
19
|
+
debounced
|
|
20
|
+
fullWidth
|
|
21
|
+
dataTestId={label}
|
|
22
|
+
placeholder={label}
|
|
23
|
+
onChange={change}
|
|
24
|
+
InputProps={{
|
|
25
|
+
endAdornment: <Filters label="filters" filters={filters} />
|
|
26
|
+
}}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default Search;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useAtom } from 'jotai';
|
|
2
|
+
import { ChangeEvent, useCallback, useRef } from 'react';
|
|
3
|
+
import { searchAtom } from '../atoms';
|
|
4
|
+
|
|
5
|
+
interface UseSearchState {
|
|
6
|
+
search: string;
|
|
7
|
+
change: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const useSearch = (): UseSearchState => {
|
|
11
|
+
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
12
|
+
|
|
13
|
+
const [search, setSearch] = useAtom(searchAtom);
|
|
14
|
+
|
|
15
|
+
const change = useCallback((event: ChangeEvent<HTMLInputElement>): void => {
|
|
16
|
+
if (timeoutRef.current) {
|
|
17
|
+
clearTimeout(timeoutRef.current);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
timeoutRef.current = setTimeout(() => setSearch(event.target.value), 500);
|
|
21
|
+
}, []);
|
|
22
|
+
|
|
23
|
+
return { search, change };
|
|
24
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { EditOutlined } from '@mui/icons-material';
|
|
2
|
+
import DeleteOutline from '@mui/icons-material/DeleteOutline';
|
|
3
|
+
import { Box } from '@mui/material';
|
|
4
|
+
import { useAtomValue, useSetAtom } from 'jotai';
|
|
5
|
+
import { isNil } from 'ramda';
|
|
6
|
+
import { useCallback } from 'react';
|
|
7
|
+
import { useTranslation } from 'react-i18next';
|
|
8
|
+
import { IconButton } from '../../Button';
|
|
9
|
+
import {
|
|
10
|
+
canDeleteSubItemsAtom,
|
|
11
|
+
itemToDeleteAtom,
|
|
12
|
+
openFormModalAtom
|
|
13
|
+
} from '../atoms';
|
|
14
|
+
|
|
15
|
+
interface Props<TData> {
|
|
16
|
+
row: TData & {
|
|
17
|
+
internalListingParentId?: number;
|
|
18
|
+
internalListingParentRow: TData;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const labelDelete = 'Delete';
|
|
23
|
+
const labelUpdate = 'Update';
|
|
24
|
+
|
|
25
|
+
const Actions = <TData extends { id: number; name: string }>({
|
|
26
|
+
row
|
|
27
|
+
}: Props<TData>): JSX.Element => {
|
|
28
|
+
const { t } = useTranslation();
|
|
29
|
+
const canDeleteSubItems = useAtomValue(canDeleteSubItemsAtom);
|
|
30
|
+
const setItemToDelete = useSetAtom(itemToDeleteAtom);
|
|
31
|
+
const setOpenFormModal = useSetAtom(openFormModalAtom);
|
|
32
|
+
|
|
33
|
+
const askBeforeDelete = (): void => {
|
|
34
|
+
setItemToDelete({
|
|
35
|
+
id: row.id,
|
|
36
|
+
name: row.name,
|
|
37
|
+
parent: isNil(row.internalListingParentRow)
|
|
38
|
+
? undefined
|
|
39
|
+
: {
|
|
40
|
+
id: row.internalListingParentRow.id,
|
|
41
|
+
name: row.internalListingParentRow.name
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const updateRow = useCallback(() => setOpenFormModal(row.id), [row.id]);
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Box
|
|
50
|
+
sx={{
|
|
51
|
+
display: 'flex',
|
|
52
|
+
flexDirection: 'row',
|
|
53
|
+
gap: 1,
|
|
54
|
+
width: '100%',
|
|
55
|
+
justifyContent: 'flex-end'
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
{isNil(row.internalListingParentRow) && (
|
|
59
|
+
<IconButton
|
|
60
|
+
size="small"
|
|
61
|
+
icon={<EditOutlined fontSize="small" color="primary" />}
|
|
62
|
+
onClick={updateRow}
|
|
63
|
+
title={t(labelUpdate)}
|
|
64
|
+
data-testid={
|
|
65
|
+
row.internalListingParentRow
|
|
66
|
+
? `edit-${row.internalListingParentRow.id}-${row.id}`
|
|
67
|
+
: `edit-${row.id}`
|
|
68
|
+
}
|
|
69
|
+
/>
|
|
70
|
+
)}
|
|
71
|
+
{(canDeleteSubItems || isNil(row.internalListingParentRow)) && (
|
|
72
|
+
<IconButton
|
|
73
|
+
size="small"
|
|
74
|
+
icon={<DeleteOutline fontSize="small" color="error" />}
|
|
75
|
+
onClick={askBeforeDelete}
|
|
76
|
+
title={t(labelDelete)}
|
|
77
|
+
data-testid={
|
|
78
|
+
row.internalListingParentRow
|
|
79
|
+
? `delete-${row.internalListingParentRow.id}-${row.id}`
|
|
80
|
+
: `delete-${row.id}`
|
|
81
|
+
}
|
|
82
|
+
/>
|
|
83
|
+
)}
|
|
84
|
+
</Box>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export default Actions;
|