@centreon/ui 24.4.8 → 24.4.10

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 (73) hide show
  1. package/package.json +17 -12
  2. package/src/Button/Save/StartIcon.tsx +3 -3
  3. package/src/Dashboard/Item.tsx +1 -1
  4. package/src/Dashboard/Layout.tsx +2 -2
  5. package/src/FileDropZone/index.tsx +3 -1
  6. package/src/Form/Form.cypress.spec.tsx +133 -0
  7. package/src/Form/Inputs/CheckboxGroup.tsx +1 -4
  8. package/src/Form/Inputs/List/Content.tsx +62 -0
  9. package/src/Form/Inputs/List/List.styles.ts +29 -0
  10. package/src/Form/Inputs/List/List.tsx +58 -0
  11. package/src/Form/Inputs/List/useList.ts +81 -0
  12. package/src/Form/Inputs/index.tsx +3 -1
  13. package/src/Form/Inputs/models.ts +9 -1
  14. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/Circle.tsx +2 -2
  15. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/index.tsx +5 -4
  16. package/src/Graph/LineChart/BasicComponents/Thresholds.tsx +2 -2
  17. package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +1 -1
  18. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/GuidingLines.tsx +2 -2
  19. package/src/Graph/LineChart/InteractiveComponents/Annotations/Annotation/index.tsx +2 -3
  20. package/src/Graph/LineChart/InteractiveComponents/Annotations/EventAnnotations.tsx +1 -1
  21. package/src/Graph/LineChart/Legend/useLegend.ts +3 -3
  22. package/src/Graph/LineChart/helpers/doc.ts +16 -13
  23. package/src/Graph/LineChart/helpers/index.ts +1 -1
  24. package/src/Graph/LineChart/index.stories.tsx +4 -2
  25. package/src/Graph/SingleBar/Thresholds.tsx +2 -2
  26. package/src/Graph/Text/Text.stories.tsx +60 -4
  27. package/src/Graph/common/timeSeries/index.ts +3 -3
  28. package/src/InputField/Select/Autocomplete/Connected/index.tsx +10 -7
  29. package/src/InputField/Select/Autocomplete/Draggable/SortableList.tsx +1 -1
  30. package/src/InputField/Select/Autocomplete/Draggable/SortableListContent.tsx +1 -1
  31. package/src/InputField/Select/Autocomplete/Draggable/index.tsx +1 -1
  32. package/src/InputField/Select/IconPopover/index.tsx +2 -2
  33. package/src/InputField/Select/index.tsx +1 -1
  34. package/src/Listing/Header/ListingHeader.tsx +1 -1
  35. package/src/Listing/Listing.styles.ts +2 -3
  36. package/src/Listing/index.stories.tsx +12 -1
  37. package/src/Listing/index.tsx +1 -2
  38. package/src/RichTextEditor/RichTextEditor.tsx +12 -1
  39. package/src/SortableItems/index.tsx +2 -7
  40. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +8 -3
  41. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +0 -2
  42. package/src/TimePeriods/DateTimePickerInput.tsx +45 -17
  43. package/src/TimePeriods/TimePeriods.cypress.spec.tsx +9 -33
  44. package/src/TimePeriods/helpers/index.ts +1 -1
  45. package/src/TimePeriods/index.stories.tsx +12 -4
  46. package/src/TimePeriods/index.tsx +2 -2
  47. package/src/Typography/Subtitle.tsx +55 -0
  48. package/src/api/QueryProvider.tsx +1 -1
  49. package/src/api/TestQueryProvider.tsx +1 -1
  50. package/src/api/useFetchQuery/index.ts +27 -23
  51. package/src/api/useMutationQuery/index.ts +41 -17
  52. package/src/components/DataTable/DataListing.tsx +6 -0
  53. package/src/components/DataTable/DataTable.cypress.spec.tsx +193 -0
  54. package/src/components/DataTable/DataTable.stories.tsx +40 -0
  55. package/src/components/DataTable/DataTable.styles.ts +3 -0
  56. package/src/components/DataTable/DataTable.tsx +3 -3
  57. package/src/components/DataTable/Item/DataTableItem.styles.ts +7 -2
  58. package/src/components/DataTable/Item/DataTableItem.tsx +2 -2
  59. package/src/components/DataTable/index.ts +3 -1
  60. package/src/components/Form/AccessRights/__fixtures__/contactAccessRight.mock.ts +2 -0
  61. package/src/components/Form/AccessRights/useAccessRightsForm.utils.ts +1 -1
  62. package/src/components/Form/Dashboard/DashboardForm.tsx +15 -12
  63. package/src/components/Modal/Modal.styles.ts +4 -3
  64. package/src/components/Modal/ModalActions.tsx +4 -2
  65. package/src/index.ts +2 -0
  66. package/src/queryParameters/url/index.ts +5 -1
  67. package/src/utils/index.ts +1 -1
  68. package/src/utils/{useLicenseExpirationWarning.cypress.spec.tsx → useLicenseExpirationWarning.test.tsx} +48 -37
  69. package/src/utils/useLicenseExpirationWarning.ts +18 -18
  70. package/src/utils/usePluralizedTranslation.ts +21 -0
  71. package/src/screens/dashboard/DashboardsDetail.stories.tsx +0 -108
  72. package/src/screens/dashboard/DashboardsOverview.stories.tsx +0 -281
  73. package/src/utils/useDateTimePickerAdapter.ts +0 -309
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "24.4.8",
3
+ "version": "24.4.10",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -12,6 +12,7 @@
12
12
  "test:ci": "jest --silent --reporter=jest-junit",
13
13
  "cypress:ui": "cypress open --component --browser=chrome",
14
14
  "cypress:cli:updateSnapshot": "pnpm cypress:cli --env updateSnapshots=true",
15
+ "cypress:run:coverage": "cypress run --component --browser=chrome --env codeCoverageTasksRegistered=true",
15
16
  "cypress:cli": "cypress run --component --browser=chrome",
16
17
  "tokens:transform": "TS_NODE_PROJECT=tsconfig.node.json ts-node style-dictionary.transform.ts"
17
18
  },
@@ -73,13 +74,14 @@
73
74
  "@testing-library/react-hooks": "^8.0.1",
74
75
  "@types/cypress": "^1.1.3",
75
76
  "@types/jest": "^27.5.0",
76
- "@types/ramda": "^0.28.12",
77
+ "@types/mocha": "^10.0.6",
78
+ "@types/ramda": "^0.29.6",
77
79
  "@types/react": "^18.0.26",
78
80
  "@types/testing-library__jest-dom": "^5.14.6",
79
81
  "@vitejs/plugin-react": "^4.0.0",
80
82
  "@vitejs/plugin-react-swc": "^3.3.0",
81
83
  "axios-mock-adapter": "^1.21.4",
82
- "cypress": "^12.8.0",
84
+ "cypress": "^13.3.1",
83
85
  "identity-obj-proxy": "^3.0.0",
84
86
  "jest-transform-stub": "^2.0.0",
85
87
  "mochawesome": "^7.1.3",
@@ -97,16 +99,18 @@
97
99
  "ts-node": "^10.9.1",
98
100
  "use-resize-observer": "^9.1.0",
99
101
  "vite": "^4.3.5",
102
+ "vite-plugin-istanbul": "^5.0.0",
100
103
  "vite-plugin-svgr": "^3.2.0",
101
104
  "vite-plugin-turbosnap": "^1.0.2"
102
105
  },
103
106
  "dependencies": {
104
- "@lexical/link": "0.11.3",
105
- "@lexical/list": "^0.11.3",
106
- "@lexical/react": "0.11.3",
107
- "@lexical/rich-text": "^0.11.3",
108
- "@lexical/selection": "0.11.3",
109
- "@lexical/utils": "0.11.3",
107
+ "@lexical/html": "^0.12.2",
108
+ "@lexical/link": "^0.12.2",
109
+ "@lexical/list": "^0.12.2",
110
+ "@lexical/react": "^0.12.2",
111
+ "@lexical/rich-text": "^0.12.2",
112
+ "@lexical/selection": "^0.12.2",
113
+ "@lexical/utils": "^0.12.2",
110
114
  "@react-spring/web": "^9.7.3",
111
115
  "@visx/curve": "^2.1.0",
112
116
  "@visx/group": "^3.3.0",
@@ -118,8 +122,9 @@
118
122
  "anylogger": "^1.0.11",
119
123
  "d3-array": "3.2.0",
120
124
  "humanize-duration": "^3.27.3",
121
- "lexical": "0.11.3",
122
- "notistack": "^2.0.8",
125
+ "lexical": "^0.12.2",
126
+ "notistack": "^3.0.1",
127
+ "ramda": "0.29.1",
123
128
  "react-grid-layout": "^1.3.4",
124
129
  "react-html-parser": "^2.0.2",
125
130
  "react-resizable": "^3.0.5",
@@ -135,7 +140,7 @@
135
140
  "@mui/icons-material": "5.x",
136
141
  "@mui/material": "5.x",
137
142
  "@mui/styles": "5.x",
138
- "@tanstack/react-query": "4.x",
143
+ "@tanstack/react-query": "5.x",
139
144
  "axios": "0.x",
140
145
  "dayjs": "1.x",
141
146
  "formik": "2.x",
@@ -15,9 +15,9 @@ interface Props {
15
15
 
16
16
  const StartIcon = ({ startIconConfig }: Props): JSX.Element | null =>
17
17
  cond<Array<StartIconConfigProps>, JSX.Element | null>([
18
- [pipe(propEq('hasLabel', true), not), always(null)],
19
- [propEq('succeeded', true), always(<CheckIcon />)],
20
- [propEq('loading', true), always(<SaveIcon />)],
18
+ [pipe(propEq(true, 'hasLabel'), not), always(null)],
19
+ [propEq(true, 'succeeded'), always(<CheckIcon />)],
20
+ [propEq(true, 'loading'), always(<SaveIcon />)],
21
21
  [T, always(<SaveIcon />)]
22
22
  ])(startIconConfig);
23
23
 
@@ -27,7 +27,7 @@ interface DashboardItemProps {
27
27
  style?: CSSProperties;
28
28
  }
29
29
 
30
- const Item = forwardRef(
30
+ const Item = forwardRef<HTMLDivElement, DashboardItemProps>(
31
31
  (
32
32
  {
33
33
  children,
@@ -23,7 +23,7 @@ interface DashboardLayoutProps<T> {
23
23
  layout: Array<T>;
24
24
  }
25
25
 
26
- const Layout = <T extends Layout>({
26
+ const DashboardLayout = <T extends Layout>({
27
27
  children,
28
28
  changeLayout,
29
29
  displayGrid,
@@ -76,4 +76,4 @@ const Layout = <T extends Layout>({
76
76
  });
77
77
  };
78
78
 
79
- export default Layout;
79
+ export default DashboardLayout;
@@ -98,7 +98,9 @@ const getExtensions = cond([
98
98
  [T, identity]
99
99
  ]) as (accept: string) => Array<string>;
100
100
 
101
- export const transformFileListToArray = (files: FileList | null): Array<File> =>
101
+ export const transformFileListToArray = (
102
+ files: FileList | null
103
+ ): Array<File> =>
102
104
  isNil(files)
103
105
  ? []
104
106
  : (Array(files.length)
@@ -0,0 +1,133 @@
1
+ import { object } from 'yup';
2
+ import { faker } from '@faker-js/faker';
3
+ import { useFormikContext } from 'formik';
4
+
5
+ import { Typography } from '@mui/material';
6
+
7
+ import { Button } from '../components';
8
+
9
+ import { Form } from './Form';
10
+ import { InputType } from './Inputs/models';
11
+
12
+ faker.seed(42);
13
+
14
+ const AddItem = ({ addItem }: { addItem: (item) => void }): JSX.Element => {
15
+ const { values } = useFormikContext();
16
+ const add = (): void => {
17
+ addItem({
18
+ alias: faker.company.name(),
19
+ id: values.list.length,
20
+ name: faker.person.firstName()
21
+ });
22
+ };
23
+
24
+ return (
25
+ <Button variant="ghost" onClick={add}>
26
+ Add item
27
+ </Button>
28
+ );
29
+ };
30
+
31
+ const SortContent = ({
32
+ name,
33
+ alias
34
+ }: {
35
+ alias: string;
36
+ name: string;
37
+ }): JSX.Element => (
38
+ <Typography>
39
+ {name} ({alias})
40
+ </Typography>
41
+ );
42
+
43
+ const initializeFormList = (): void => {
44
+ cy.mount({
45
+ Component: (
46
+ <Form
47
+ initialValues={{
48
+ list: []
49
+ }}
50
+ inputs={[
51
+ {
52
+ fieldName: 'list',
53
+ group: '',
54
+ label: '',
55
+ list: {
56
+ AddItem,
57
+ SortContent,
58
+ addItemLabel: 'Add an item to the list',
59
+ itemProps: ['id', 'name', 'alias'],
60
+ sortLabel: 'Sort items'
61
+ },
62
+ type: InputType.List
63
+ }
64
+ ]}
65
+ submit={cy.stub()}
66
+ validationSchema={object()}
67
+ />
68
+ )
69
+ });
70
+ };
71
+
72
+ describe('Form list', () => {
73
+ beforeEach(initializeFormList);
74
+
75
+ it('adds an element to the list', () => {
76
+ cy.contains('Add an item to the list').should('be.visible');
77
+ cy.contains('Sort items').should('be.visible');
78
+
79
+ cy.contains('Add item').click();
80
+
81
+ cy.findByLabelText('sort-0').should('be.visible');
82
+ cy.findByLabelText('delete-0').should('be.visible');
83
+ cy.contains('Christelle (Schinner - Wiegand)').should('be.visible');
84
+
85
+ cy.makeSnapshot();
86
+ });
87
+
88
+ it('sorts elements in the list', () => {
89
+ cy.contains('Add an item to the list').should('be.visible');
90
+ cy.contains('Sort items').should('be.visible');
91
+
92
+ cy.contains('Add item').click();
93
+ cy.contains('Add item').click();
94
+
95
+ cy.findByLabelText('sort-0').should('be.visible');
96
+ cy.findByLabelText('delete-0').should('be.visible');
97
+ cy.contains('Carley (Satterfield, Miller and Metz)').should('be.visible');
98
+ cy.findByLabelText('sort-1').should('be.visible');
99
+ cy.findByLabelText('delete-1').should('be.visible');
100
+ cy.contains('Anderson (Crist - Bradtke)').should('be.visible');
101
+
102
+ cy.moveSortableElementUsingAriaLabel({
103
+ ariaLabel: 'sort-0',
104
+ direction: 'down'
105
+ });
106
+
107
+ cy.contains('Carley (Satterfield, Miller and Metz)').should('be.visible');
108
+ cy.contains('Anderson (Crist - Bradtke)').should('be.visible');
109
+
110
+ cy.makeSnapshot();
111
+ });
112
+
113
+ it('removes an element from the list', () => {
114
+ cy.contains('Add an item to the list').should('be.visible');
115
+ cy.contains('Sort items').should('be.visible');
116
+
117
+ cy.contains('Add item').click();
118
+ cy.contains('Add item').click();
119
+
120
+ cy.findByLabelText('sort-0').should('be.visible');
121
+ cy.findByLabelText('delete-0').should('be.visible');
122
+ cy.contains('Lea (Streich - Hartmann)').should('be.visible');
123
+ cy.findByLabelText('sort-1').should('be.visible');
124
+ cy.findByLabelText('delete-1').should('be.visible');
125
+ cy.contains('Akeem (Quigley LLC)').should('be.visible');
126
+
127
+ cy.findByLabelText('delete-0').click();
128
+
129
+ cy.contains('Lea (Streich - Hartmann)').should('not.exist');
130
+
131
+ cy.makeSnapshot();
132
+ });
133
+ });
@@ -46,10 +46,7 @@ const CheckboxGroup = ({
46
46
  return;
47
47
  }
48
48
 
49
- setFieldValue(
50
- fieldName,
51
- value?.filter((elm) => !equals(elm, label))
52
- );
49
+ setFieldValue(fieldName, value?.filter((elm) => !equals(elm, label)));
53
50
  };
54
51
 
55
52
  return useMemoComponent({
@@ -0,0 +1,62 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ import { DraggableSyntheticListeners } from '@dnd-kit/core';
4
+
5
+ import KrilinIndicatorIcon from '@mui/icons-material/DragIndicator';
6
+ import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
7
+
8
+ import { IconButton } from '../../../components';
9
+
10
+ import { useListStyles } from './List.styles';
11
+
12
+ export interface ContentProps {
13
+ attributes;
14
+ children: ReactNode;
15
+ deleteItem: (id: string) => () => void;
16
+ id: string;
17
+ isDragging: boolean;
18
+ isInDragOverlay?: boolean;
19
+ itemRef: React.RefObject<HTMLDivElement>;
20
+ listeners: DraggableSyntheticListeners;
21
+ name: string;
22
+ style;
23
+ }
24
+
25
+ const Content = ({
26
+ listeners,
27
+ itemRef,
28
+ attributes,
29
+ style,
30
+ isDragging,
31
+ id,
32
+ children,
33
+ deleteItem
34
+ }: ContentProps): JSX.Element => {
35
+ const { classes } = useListStyles();
36
+
37
+ return (
38
+ <div
39
+ className={classes.content}
40
+ ref={itemRef}
41
+ {...attributes}
42
+ style={style}
43
+ >
44
+ <IconButton
45
+ data-dragging={isDragging}
46
+ size="small"
47
+ {...listeners}
48
+ aria-label={`sort-${id}`}
49
+ icon={<KrilinIndicatorIcon fontSize="small" />}
50
+ />
51
+ <div className={classes.innerContent}>{children}</div>
52
+ <IconButton
53
+ aria-label={`delete-${id}`}
54
+ icon={<DeleteOutlineIcon color="error" fontSize="small" />}
55
+ size="small"
56
+ onClick={deleteItem(id)}
57
+ />
58
+ </div>
59
+ );
60
+ };
61
+
62
+ export default Content;
@@ -0,0 +1,29 @@
1
+ import { makeStyles } from 'tss-react/mui';
2
+
3
+ export const useListStyles = makeStyles()((theme) => ({
4
+ content: {
5
+ '& [data-dragging="false"]': {
6
+ cursor: 'grab'
7
+ },
8
+ '& [data-dragging="true"]': {
9
+ cursor: 'grabbing'
10
+ },
11
+ alignItems: 'center',
12
+ borderBottom: `1px dashed ${theme.palette.action.disabledBackground}`,
13
+ display: 'flex',
14
+ flexDirection: 'row',
15
+ padding: theme.spacing(1, 0)
16
+ },
17
+ innerContent: {
18
+ flexGrow: 1
19
+ },
20
+ items: {
21
+ maxHeight: theme.spacing(16),
22
+ overflowY: 'auto'
23
+ },
24
+ list: {
25
+ display: 'flex',
26
+ flexDirection: 'column',
27
+ gap: theme.spacing(1)
28
+ }
29
+ }));
@@ -0,0 +1,58 @@
1
+ import { ComponentType } from 'react';
2
+
3
+ import { closestCenter } from '@dnd-kit/core';
4
+ import { verticalListSortingStrategy } from '@dnd-kit/sortable';
5
+ import { useTranslation } from 'react-i18next';
6
+
7
+ import { InputPropsWithoutGroup } from '../models';
8
+ import { SortableItems, Subtitle } from '../../..';
9
+
10
+ import { useList } from './useList';
11
+ import { useListStyles } from './List.styles';
12
+ import Content, { ContentProps } from './Content';
13
+
14
+ const List = ({
15
+ list,
16
+ fieldName
17
+ }: InputPropsWithoutGroup): JSX.Element | null => {
18
+ const { t } = useTranslation();
19
+ const { classes } = useListStyles();
20
+
21
+ const { addItem, sortList, sortedList, deleteItem } = useList({ fieldName });
22
+
23
+ const { AddItem, addItemLabel, sortLabel, SortContent, itemProps } = list as {
24
+ AddItem: ComponentType<{ addItem }>;
25
+ SortContent: ComponentType;
26
+ addItemLabel?: string;
27
+ itemProps: Array<string>;
28
+ sortLabel?: string;
29
+ };
30
+
31
+ return (
32
+ <div className={classes.list}>
33
+ {addItemLabel && <Subtitle>{t(addItemLabel)}</Subtitle>}
34
+ <AddItem addItem={addItem} />
35
+ {sortLabel && <Subtitle>{t(sortLabel)}</Subtitle>}
36
+ <div className={classes.items}>
37
+ <SortableItems
38
+ updateSortableItemsOnItemsChange
39
+ // eslint-disable-next-line react/no-unstable-nested-components
40
+ Content={(props: Omit<ContentProps, 'children' | 'deleteItem'>) => (
41
+ <Content {...props} deleteItem={deleteItem}>
42
+ <SortContent {...props} />
43
+ </Content>
44
+ )}
45
+ collisionDetection={closestCenter}
46
+ itemProps={itemProps}
47
+ items={sortedList}
48
+ sortingStrategy={verticalListSortingStrategy}
49
+ onDragEnd={({ items }): void => {
50
+ sortList(items);
51
+ }}
52
+ />
53
+ </div>
54
+ </div>
55
+ );
56
+ };
57
+
58
+ export default List;
@@ -0,0 +1,81 @@
1
+ import { useMemo, useRef } from 'react';
2
+
3
+ import { FormikValues, useFormikContext } from 'formik';
4
+ import {
5
+ append,
6
+ equals,
7
+ inc,
8
+ isEmpty,
9
+ pluck,
10
+ prop,
11
+ reject,
12
+ sortBy
13
+ } from 'ramda';
14
+
15
+ import { SelectEntry } from '../../..';
16
+
17
+ interface UseListState {
18
+ addItem: (newItem: SelectEntry) => void;
19
+ deleteItem: (id: string) => () => void;
20
+ sortList: (items: Array<string>) => void;
21
+ sortedList: Array<unknown>;
22
+ }
23
+
24
+ export const useList = ({ fieldName }): UseListState => {
25
+ const { values, setFieldValue } = useFormikContext<FormikValues>();
26
+ const maxOrder = useRef(0);
27
+
28
+ const list = values[fieldName];
29
+
30
+ const sortedList = useMemo(
31
+ () =>
32
+ sortBy(prop('order'), list).map(({ id, ...props }) => ({
33
+ id: `${id}`,
34
+ ...props
35
+ })),
36
+ [list]
37
+ );
38
+
39
+ const addItem = (newItem: SelectEntry): void => {
40
+ setFieldValue(
41
+ fieldName,
42
+ append(
43
+ {
44
+ ...newItem,
45
+ id: (newItem as SelectEntry).id as number,
46
+ order: inc(maxOrder.current)
47
+ },
48
+ list
49
+ )
50
+ );
51
+ };
52
+
53
+ const deleteItem = (id: string) => (): void => {
54
+ const newItems = reject((item) => equals(Number(id), item.id))(list);
55
+
56
+ setFieldValue(fieldName, newItems);
57
+ };
58
+
59
+ const sortList = (items: Array<string>): void => {
60
+ const newOrderedList = items.map((itemId, idx) => {
61
+ const item = sortedList.find(({ id }) => equals(id, itemId));
62
+
63
+ return {
64
+ ...item,
65
+ id: Number(item?.id),
66
+ order: inc(idx)
67
+ };
68
+ });
69
+
70
+ setFieldValue(fieldName, newOrderedList);
71
+ };
72
+
73
+ maxOrder.current = isEmpty(list) ? 0 : Math.max(...pluck('order', list));
74
+
75
+ return {
76
+ addItem,
77
+ deleteItem,
78
+ sortList,
79
+ sortedList
80
+ };
81
+ };
@@ -21,6 +21,7 @@ import CheckboxGroup from './CheckboxGroup';
21
21
  import Checkbox from './Checkbox';
22
22
  import Custom from './Custom';
23
23
  import LoadingSkeleton from './LoadingSkeleton';
24
+ import List from './List/List';
24
25
 
25
26
  export const getInput = R.cond<
26
27
  Array<InputType>,
@@ -66,6 +67,7 @@ export const getInput = R.cond<
66
67
  R.equals(InputType.CheckboxGroup) as (b: InputType) => boolean,
67
68
  R.always(CheckboxGroup)
68
69
  ],
70
+ [R.equals(InputType.List) as (b: InputType) => boolean, R.always(List)],
69
71
  [R.T, R.always(TextInput)]
70
72
  ]);
71
73
 
@@ -185,7 +187,7 @@ const Inputs = ({
185
187
  const hasGroupTitle = R.not(R.isNil(groupName));
186
188
 
187
189
  const groupProps = hasGroupTitle
188
- ? R.find(R.propEq('name', groupName), groups)
190
+ ? R.find(R.propEq(groupName, 'name'), groups)
189
191
  : ({} as Group);
190
192
 
191
193
  const isFirstElement = areGroupsOpen || R.equals(index, 0);
@@ -18,7 +18,8 @@ export enum InputType {
18
18
  Grid,
19
19
  Custom,
20
20
  Checkbox,
21
- CheckboxGroup
21
+ CheckboxGroup,
22
+ List
22
23
  }
23
24
 
24
25
  interface FieldsTableGetRequiredProps {
@@ -76,6 +77,13 @@ export interface InputProps {
76
77
  hideInput?: (values: FormikValues) => boolean;
77
78
  inputClassName?: string;
78
79
  label: string;
80
+ list?: {
81
+ AddItem: React.ComponentType<{ addItem }>;
82
+ SortContent: React.ComponentType<object>;
83
+ addItemLabel?: string;
84
+ itemProps: Array<string>;
85
+ sortLabel?: string;
86
+ };
79
87
  radio?: {
80
88
  options?: Array<{
81
89
  label: string | JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import { Shape } from '@visx/visx';
2
2
  import { isEmpty, isNil } from 'ramda';
3
3
 
4
- import { Circle } from './models';
4
+ import { Circle as CircleModel } from './models';
5
5
  import useCoordinateCircle from './useCoordinateCircle';
6
6
 
7
7
  const Circle = ({
@@ -11,7 +11,7 @@ const Circle = ({
11
11
  timeSeries,
12
12
  getX,
13
13
  getCountDisplayedCircles
14
- }: Circle): JSX.Element | null => {
14
+ }: CircleModel): JSX.Element | null => {
15
15
  const coordinates = useCoordinateCircle({
16
16
  getCountDisplayedCircles,
17
17
  getX,
@@ -130,10 +130,11 @@ const WrapperThresholdLines = ({
130
130
 
131
131
  return (
132
132
  <g>
133
- {filteredThresholdLines.map((element) =>
134
- element?.map(({ Component, props, key }) => (
135
- <Component {...props} id={key} key={key} />
136
- ))
133
+ {filteredThresholdLines.map(
134
+ (element) =>
135
+ element?.map(({ Component, props, key }) => (
136
+ <Component {...props} id={key} key={key} />
137
+ ))
137
138
  )}
138
139
  </g>
139
140
  );
@@ -2,7 +2,7 @@ import { equals, isNil } from 'ramda';
2
2
 
3
3
  import { getUnits, getYScale } from '../../common/timeSeries';
4
4
  import { Line } from '../../common/timeSeries/models';
5
- import { Thresholds } from '../../common/models';
5
+ import { Thresholds as ThresholdsModel } from '../../common/models';
6
6
 
7
7
  import { ThresholdLine } from './ThresholdLine';
8
8
 
@@ -13,7 +13,7 @@ interface Props {
13
13
  rightScale: (value: number) => number;
14
14
  showTooltip: (props) => void;
15
15
  thresholdUnit?: string;
16
- thresholds: Thresholds;
16
+ thresholds: ThresholdsModel;
17
17
  width: number;
18
18
  }
19
19
 
@@ -28,7 +28,7 @@ const useFilterLines = ({
28
28
  linesGraph,
29
29
  setLinesGraph
30
30
  }: UseFilterLines): Result => {
31
- const displayedLines = reject(propEq('display', false), linesGraph ?? lines);
31
+ const displayedLines = reject(propEq(false, 'display'), linesGraph ?? lines);
32
32
  const filterLines = (): Array<Line> => {
33
33
  const lineOriginMetric = findLineOfOriginMetricThreshold(lines);
34
34
 
@@ -2,7 +2,7 @@ import { Shape } from '@visx/visx';
2
2
 
3
3
  import { grey } from '@mui/material/colors';
4
4
 
5
- import { GuidingLines } from './models';
5
+ import { GuidingLines as GuidingLinesModel } from './models';
6
6
  import useTickGraph from './useTickGraph';
7
7
 
8
8
  const GuidingLines = ({
@@ -10,7 +10,7 @@ const GuidingLines = ({
10
10
  xScale,
11
11
  graphHeight,
12
12
  graphWidth
13
- }: GuidingLines): JSX.Element | null => {
13
+ }: GuidingLinesModel): JSX.Element | null => {
14
14
  const { positionX, positionY } = useTickGraph({
15
15
  timeSeries,
16
16
  xScale
@@ -43,9 +43,8 @@ const Annotation = ({
43
43
 
44
44
  const setAnnotationHovered = useSetAtom(annotationHoveredAtom);
45
45
 
46
- const content = `${truncate(event.content)} (${t(labelBy)} ${
47
- event.contact?.name
48
- })`;
46
+ const content = `${truncate(event.content)} (${t(labelBy)} ${event.contact
47
+ ?.name})`;
49
48
 
50
49
  return (
51
50
  <g>
@@ -26,7 +26,7 @@ const EventAnnotations = ({
26
26
  color,
27
27
  annotationHoveredId
28
28
  }: Props): JSX.Element => {
29
- const events = filter(propEq('type', type), data);
29
+ const events = filter(propEq(type, 'type'), data);
30
30
 
31
31
  return (
32
32
  <>