@centreon/ui 26.5.9 → 26.5.11

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 (142) hide show
  1. package/package.json +3 -1
  2. package/src/@types/globals.d.ts +21 -0
  3. package/src/Colors/index.tsx +1 -1
  4. package/src/Dashboard/Item.tsx +11 -14
  5. package/src/Dialog/Duplicate/index.tsx +1 -1
  6. package/src/FileDropZone/useDropzone.test.ts +18 -15
  7. package/src/Form/Inputs/Checkbox.tsx +6 -3
  8. package/src/Form/Inputs/CheckboxGroup.tsx +8 -8
  9. package/src/Form/Inputs/ConnectedAutocomplete.tsx +9 -3
  10. package/src/Form/Inputs/FieldsTable/FieldsTable.tsx +1 -1
  11. package/src/Form/Inputs/File.tsx +3 -1
  12. package/src/Form/Inputs/Grid.tsx +1 -1
  13. package/src/Form/Inputs/List/List.tsx +8 -7
  14. package/src/Form/Inputs/List/useList.ts +12 -6
  15. package/src/Form/Inputs/Radio.tsx +7 -1
  16. package/src/Form/Inputs/Text.tsx +1 -1
  17. package/src/Form/Inputs/index.tsx +7 -2
  18. package/src/Form/storiesData.tsx +5 -2
  19. package/src/Graph/BarChart/Bar.tsx +2 -2
  20. package/src/Graph/BarChart/BarChart.tsx +2 -0
  21. package/src/Graph/BarChart/BarGroup.tsx +3 -0
  22. package/src/Graph/BarChart/BarStack.tsx +1 -0
  23. package/src/Graph/BarChart/MemoizedGroup.tsx +3 -1
  24. package/src/Graph/BarChart/ResponsiveBarChart.tsx +5 -0
  25. package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +4 -0
  26. package/src/Graph/BarStack/Graph.tsx +3 -0
  27. package/src/Graph/Chart/BasicComponents/Lines/RegularLines/index.tsx +4 -1
  28. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +7 -1
  29. package/src/Graph/Chart/BasicComponents/Lines/Threshold/BasicThreshold.tsx +1 -0
  30. package/src/Graph/Chart/BasicComponents/Lines/index.tsx +11 -1
  31. package/src/Graph/Chart/Chart.tsx +9 -0
  32. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +2 -0
  33. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +2 -0
  34. package/src/Graph/Chart/InteractiveComponents/Annotations/annotationsAtoms.ts +5 -0
  35. package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/GraphValueTooltip.tsx +3 -0
  36. package/src/Graph/Chart/Legend/LegendHeader.tsx +1 -0
  37. package/src/Graph/Chart/Legend/index.tsx +6 -1
  38. package/src/Graph/Chart/useChartData.ts +6 -0
  39. package/src/Graph/Gauge/AnimatedPie.tsx +3 -0
  40. package/src/Graph/Gauge/PieData.tsx +5 -0
  41. package/src/Graph/Gauge/ResponsiveGauge.tsx +2 -0
  42. package/src/Graph/Gauge/Thresholds.tsx +1 -0
  43. package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +1 -0
  44. package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +2 -0
  45. package/src/Graph/Timeline/ResponsiveTimeline.tsx +1 -0
  46. package/src/Graph/Tree/Links.tsx +1 -0
  47. package/src/Graph/Tree/Tree.tsx +1 -0
  48. package/src/Graph/Tree/stories/datas.ts +2 -0
  49. package/src/Graph/common/Axes/index.tsx +3 -3
  50. package/src/Graph/common/BaseChart/BaseChart.tsx +3 -0
  51. package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +1 -0
  52. package/src/Graph/common/BaseChart/Header/models.ts +1 -0
  53. package/src/Graph/common/timeSeries/index.test.ts +17 -1
  54. package/src/Graph/common/timeSeries/index.ts +12 -0
  55. package/src/Graph/common/utils.ts +6 -2
  56. package/src/InputField/Number/Number.tsx +10 -4
  57. package/src/InputField/Search/PersistentTooltip.tsx +6 -5
  58. package/src/InputField/Select/Autocomplete/Connected/Single.tsx +3 -1
  59. package/src/InputField/Select/Autocomplete/Connected/index.test.tsx +1 -1
  60. package/src/InputField/Select/Autocomplete/Connected/index.tsx +5 -1
  61. package/src/InputField/Select/Autocomplete/Draggable/SortableList.tsx +4 -5
  62. package/src/InputField/Select/Autocomplete/Draggable/index.tsx +4 -5
  63. package/src/InputField/Select/Autocomplete/Multi/Listbox.tsx +16 -1
  64. package/src/InputField/Select/Autocomplete/Multi/Multi.tsx +44 -30
  65. package/src/InputField/Select/Autocomplete/Multi/index.tsx +1 -0
  66. package/src/InputField/Select/Autocomplete/index.tsx +7 -1
  67. package/src/InputField/Select/IconPopover/index.tsx +0 -3
  68. package/src/InputField/Select/Option.tsx +6 -1
  69. package/src/InputField/Select/index.tsx +3 -3
  70. package/src/InputField/Text/index.tsx +11 -3
  71. package/src/InputField/Text/useAutoSize.ts +2 -2
  72. package/src/Listing/ActionBar/index.tsx +2 -3
  73. package/src/Listing/Cell/index.tsx +24 -22
  74. package/src/Listing/Header/Cell/ListingHeaderCell.styles.ts +7 -0
  75. package/src/Listing/Header/ListingHeader.tsx +2 -2
  76. package/src/Listing/Header/_internals/PredefinedSelectionList.tsx +3 -3
  77. package/src/Listing/index.tsx +29 -34
  78. package/src/Listing/useStyleTable.ts +1 -1
  79. package/src/Module/index.tsx +3 -3
  80. package/src/MultiSelectEntries/index.tsx +1 -1
  81. package/src/Pagination/Pagination.tsx +1 -1
  82. package/src/ParentSize/ParentSize.tsx +2 -1
  83. package/src/PopoverMenu/index.tsx +1 -7
  84. package/src/RichTextEditor/ContentEditable.tsx +2 -0
  85. package/src/RichTextEditor/RichTextEditor.tsx +1 -0
  86. package/src/RichTextEditor/plugins/FloatingLinkEditorPlugin.tsx +1 -0
  87. package/src/RichTextEditor/plugins/ToolbarPlugin/BlockButtons.tsx +1 -0
  88. package/src/RichTextEditor/plugins/ToolbarPlugin/ListButton.tsx +2 -0
  89. package/src/Snackbar/index.tsx +3 -1
  90. package/src/SortableItems/Item.tsx +8 -7
  91. package/src/SortableItems/index.tsx +1 -1
  92. package/src/ThemeProvider/index.tsx +5 -3
  93. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +3 -2
  94. package/src/TimePeriods/SelectedTimePeriod.tsx +1 -1
  95. package/src/TimePeriods/timePeriodsAtoms.ts +1 -1
  96. package/src/TimePeriods/useSortTimePeriods.ts +1 -1
  97. package/src/Typography/Subtitle.tsx +3 -1
  98. package/src/Typography/story.utils.tsx +3 -2
  99. package/src/Wizard/ActionsBar.tsx +2 -2
  100. package/src/api/QueryProvider.tsx +1 -2
  101. package/src/api/buildListingEndpoint/getSearchQueryParameterValue.ts +4 -2
  102. package/src/api/useGraphQuery/index.ts +11 -6
  103. package/src/api/useMutationQuery/index.ts +11 -7
  104. package/src/api/useMutationQuery/useOptimisticMutation.ts +34 -16
  105. package/src/api/useRequest/index.test.ts +1 -1
  106. package/src/api/useRequest/index.ts +1 -1
  107. package/src/components/Button/Button.tsx +2 -2
  108. package/src/components/CrudPage/Actions/Filters.tsx +1 -1
  109. package/src/components/CrudPage/Actions/useSearch.tsx +1 -1
  110. package/src/components/CrudPage/Columns/Actions.tsx +2 -2
  111. package/src/components/CrudPage/CrudPageRoot.tsx +1 -1
  112. package/src/components/CrudPage/DeleteModal.tsx +14 -6
  113. package/src/components/CrudPage/Form/AddModal.tsx +16 -4
  114. package/src/components/CrudPage/Form/UpdateModal.tsx +2 -2
  115. package/src/components/CrudPage/Listing.tsx +2 -1
  116. package/src/components/CrudPage/hooks/useDeleteItem.ts +5 -1
  117. package/src/components/CrudPage/hooks/useGetItem.ts +3 -3
  118. package/src/components/DataTable/DataListing.tsx +1 -1
  119. package/src/components/ExpandableContainer/ExpandableContainer.tsx +1 -0
  120. package/src/components/Form/AccessRights/Actions/Actions.tsx +1 -1
  121. package/src/components/Form/AccessRights/Actions/useActions.ts +1 -4
  122. package/src/components/Form/AccessRights/List/StateChip.tsx +1 -1
  123. package/src/components/Form/AccessRights/Stats/Stats.tsx +1 -1
  124. package/src/components/Form/AccessRights/common/RoleSelectField.tsx +4 -6
  125. package/src/components/Form/Dashboard/DashboardForm.tsx +2 -2
  126. package/src/components/Header/PageHeader/PageHeader.styles.ts +26 -20
  127. package/src/components/Menu/useMenu.tsx +3 -3
  128. package/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +14 -9
  129. package/src/components/Modal/Modal.tsx +5 -3
  130. package/src/components/Modal/ModalActions.tsx +1 -1
  131. package/src/components/Modal/ModalBody.tsx +2 -2
  132. package/src/components/Modal/ModalHeader.tsx +2 -2
  133. package/src/components/Tooltip/TextOverflowTooltip/TextOverflowTooltip.tsx +8 -2
  134. package/src/index.ts +1 -1
  135. package/src/utils/sanitizedHTML.ts +1 -1
  136. package/src/utils/useDebounce.ts +3 -1
  137. package/src/utils/useLicenseExpirationWarning.ts +11 -6
  138. package/src/utils/useLocaleDateTimeFormat/index.test.tsx +3 -1
  139. package/src/utils/useLocaleDateTimeFormat/localeFallback.test.tsx +3 -1
  140. package/src/utils/useMemoComponent.ts +1 -1
  141. package/src/utils/usePluralizedTranslation.test.ts +2 -0
  142. package/src/utils/useViewportIntersection.ts +3 -4
@@ -5,8 +5,8 @@ import { Method } from '.';
5
5
 
6
6
  interface GetOptimisticMutationListingProps<T, TMeta> {
7
7
  method: Method;
8
- payload: T;
9
- _meta: TMeta;
8
+ payload: T | undefined;
9
+ _meta: TMeta | undefined;
10
10
  }
11
11
 
12
12
  export interface OptimisticListing {
@@ -39,7 +39,7 @@ export const useOptimisticMutation = <T, TMeta>({
39
39
  ? optimisticListing?.queryKey
40
40
  : [optimisticListing?.queryKey];
41
41
 
42
- return listingQueryKey;
42
+ return listingQueryKey as Array<string>;
43
43
  };
44
44
 
45
45
  const getPreviousListing = (): unknown => {
@@ -62,9 +62,12 @@ export const useOptimisticMutation = <T, TMeta>({
62
62
  const listingQueryKey = getListingQueryKey();
63
63
 
64
64
  const updatedPayload =
65
- payload && 'id' in payload
65
+ payload && 'id' in (payload as Record<string, unknown>)
66
66
  ? payload
67
- : { ...payload, id: (optimisticListing?.total ?? 0) + 1 };
67
+ : {
68
+ ...(payload as Record<string, unknown>),
69
+ id: (optimisticListing?.total ?? 0) + 1
70
+ };
68
71
 
69
72
  const hasOnlyOnePage =
70
73
  (optimisticListing?.total || 0) <= (optimisticListing?.limit || 0);
@@ -74,19 +77,22 @@ export const useOptimisticMutation = <T, TMeta>({
74
77
  queryClient.getQueriesData({
75
78
  queryKey: listingQueryKey
76
79
  })
77
- )?.[1];
80
+ )?.[1] as { result: Array<Record<string, unknown>> } | undefined;
78
81
 
79
82
  if (equals(Method.POST, method) && !isFormDataPayload && hasOnlyOnePage) {
80
- const newItems = append(updatedPayload, items.result);
83
+ const newItems = append(
84
+ updatedPayload as Record<string, unknown>,
85
+ items?.result ?? []
86
+ );
81
87
 
82
88
  return { ...items, result: newItems };
83
89
  }
84
90
 
85
91
  if (equals(Method.DELETE, method) && hasOnlyOnePage) {
86
- const itemIndex = items.result.findIndex(({ id }) =>
87
- equals(id, _meta.id)
92
+ const itemIndex = items?.result.findIndex(({ id }) =>
93
+ equals(id, (_meta as Record<string, unknown>)?.id)
88
94
  );
89
- const newItems = remove(itemIndex, 1, items.result);
95
+ const newItems = remove(itemIndex ?? 0, 1, items?.result ?? []);
90
96
 
91
97
  return { ...items, result: newItems };
92
98
  }
@@ -97,24 +103,36 @@ export const useOptimisticMutation = <T, TMeta>({
97
103
  (equals(Method.POST, method) && isFormDataPayload)) &&
98
104
  hasOnlyOnePage
99
105
  ) {
100
- const itemIndex = items.result.findIndex(({ id }) =>
101
- equals(id, _meta.id)
106
+ const itemIndex = items?.result.findIndex(({ id }) =>
107
+ equals(id, (_meta as Record<string, unknown>)?.id)
108
+ );
109
+ const item = items?.result.find(({ id }) =>
110
+ equals(id, (_meta as Record<string, unknown>)?.id)
102
111
  );
103
- const item = items.result.find(({ id }) => equals(id, _meta.id));
104
112
  const updatedItem = equals(Method.PUT, method)
105
113
  ? updatedPayload
106
114
  : {
107
115
  ...item,
108
116
  ...(isFormDataPayload
109
- ? Object.fromEntries(updatedPayload.entries())
117
+ ? (
118
+ Object as unknown as {
119
+ fromEntries: (
120
+ entries: IterableIterator<[string, FormDataEntryValue]>
121
+ ) => Record<string, unknown>;
122
+ }
123
+ ).fromEntries((updatedPayload as unknown as FormData).entries())
110
124
  : updatedPayload)
111
125
  };
112
- const newItems = update(itemIndex, updatedItem, items.result);
126
+ const newItems = update(
127
+ itemIndex ?? 0,
128
+ updatedItem as Record<string, unknown>,
129
+ items?.result ?? []
130
+ );
113
131
 
114
132
  return { ...items, result: newItems };
115
133
  }
116
134
 
117
- return items;
135
+ return items as object;
118
136
  };
119
137
  return { getListingQueryKey, getOptimisticMutationItems, getPreviousListing };
120
138
  };
@@ -22,7 +22,7 @@ const request = jest.fn();
22
22
 
23
23
  const renderUseRequest = (
24
24
  requestParams: RequestParams<Result>
25
- ): RenderHookResult<unknown, RequestResult<Result>> =>
25
+ ): RenderHookResult<RequestResult<Result>, unknown> =>
26
26
  renderHook(() => useRequest(requestParams));
27
27
 
28
28
  describe(useRequest, () => {
@@ -64,7 +64,7 @@ const useRequest = <TResult>({
64
64
  .catch((error) => {
65
65
  setSending(false);
66
66
  if (axios.isCancel(error)) {
67
- warnLog(error);
67
+ warnLog(error as unknown as string);
68
68
 
69
69
  throw error;
70
70
  }
@@ -7,7 +7,7 @@ import { type ReactElement, type ReactNode, useMemo } from 'react';
7
7
 
8
8
  import type { AriaLabelingAttributes } from '../../@types/aria-attributes';
9
9
  import type { DataTestAttributes } from '../../@types/data-attributes';
10
- import { button } from './Button.module.css';
10
+ import styles from './Button.module.css';
11
11
 
12
12
  const muiVariantMap: Record<
13
13
  Required<ButtonProps>['variant'],
@@ -58,7 +58,7 @@ const Button = ({
58
58
 
59
59
  return (
60
60
  <MuiButton
61
- className={`${button} ${className}`}
61
+ className={`${styles.button} ${className}`}
62
62
  data-icon-variant={iconVariant}
63
63
  data-is-danger={isDanger}
64
64
  data-size={size}
@@ -19,7 +19,7 @@ const Filters: React.FC<Props> = ({ label, filters }: Props): JSX.Element => {
19
19
  title={label}
20
20
  tooltipClassName={classes.tooltipFilters}
21
21
  >
22
- {isValidElement(filters) ? filters : <div />}
22
+ {isValidElement(filters) ? () => filters : () => <div />}
23
23
  </PopoverMenu>
24
24
  );
25
25
  };
@@ -9,7 +9,7 @@ interface UseSearchState {
9
9
  }
10
10
 
11
11
  export const useSearch = (): UseSearchState => {
12
- const timeoutRef = useRef<NodeJS.Timeout | null>(null);
12
+ const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
13
13
 
14
14
  const [search, setSearch] = useAtom(searchAtom);
15
15
 
@@ -17,7 +17,7 @@ import {
17
17
  interface Props<TData> {
18
18
  row: TData & {
19
19
  internalListingParentId?: number;
20
- internalListingParentRow: TData;
20
+ internalListingParentRow: TData & { id: number };
21
21
  };
22
22
  }
23
23
 
@@ -64,7 +64,7 @@ const Actions = <TData extends { id: number; name: string }>({
64
64
  <IconButton
65
65
  data-testid={
66
66
  row.internalListingParentRow
67
- ? `edit-${row.internalListingParentRow.id}-${row.id}`
67
+ ? `edit-${(row.internalListingParentRow as TData & { id: number }).id}-${row.id}`
68
68
  : `edit-${row.id}`
69
69
  }
70
70
  icon={<EditOutlined color="primary" fontSize="small" />}
@@ -36,7 +36,7 @@ export const CrudPageRoot = <
36
36
  deleteItem,
37
37
  form
38
38
  }: CrudPageRootProps<TData, TFilters, TItem, TItemForm>): JSX.Element => {
39
- const previousCanDeleteSubItemRef = useRef<boolean | undefined>();
39
+ const previousCanDeleteSubItemRef = useRef<boolean | undefined>(undefined);
40
40
  const previousFormLabelButtonsRef = useRef<unknown | null>(null);
41
41
  const { isDataEmpty, hasItems, isLoading, items, total } = useGetItems<
42
42
  TData,
@@ -1,7 +1,7 @@
1
1
  import { Box, CircularProgress, Typography } from '@mui/material';
2
2
 
3
3
  import { useAtom } from 'jotai';
4
- import { useCallback, useRef } from 'react';
4
+ import { type ReactElement, useCallback, useRef } from 'react';
5
5
 
6
6
  import { Button } from '../Button';
7
7
  import { Modal } from '../Modal';
@@ -35,7 +35,9 @@ const DeleteModal = <TData extends { id: number; name: string }>({
35
35
  }, [setItemToDelete]);
36
36
 
37
37
  const confirm = useCallback(() => {
38
- deleteItem(itemToDeleteRef.current).then(close);
38
+ if (itemToDeleteRef.current) {
39
+ deleteItem(itemToDeleteRef.current).then(close);
40
+ }
39
41
  }, [close, deleteItem]);
40
42
 
41
43
  if (isOpen) {
@@ -46,14 +48,20 @@ const DeleteModal = <TData extends { id: number; name: string }>({
46
48
  <Modal onClose={close} open={isOpen} size={modalSize}>
47
49
  <Modal.Header>
48
50
  {isAFunction(labels.title)
49
- ? labels.title(itemToDeleteRef.current as TData)
50
- : labels.title}
51
+ ? (labels.title as (item: ItemToDelete) => string | ReactElement)(
52
+ itemToDeleteRef.current as TData
53
+ )
54
+ : (labels.title as string | ReactElement)}
51
55
  </Modal.Header>
52
56
  <Modal.Body>
53
57
  <Typography>
54
58
  {isAFunction(labels.description)
55
- ? labels.description(itemToDeleteRef.current as TData)
56
- : labels.description}
59
+ ? (
60
+ labels.description as (
61
+ item: ItemToDelete
62
+ ) => string | ReactElement
63
+ )(itemToDeleteRef.current as TData)
64
+ : (labels.description as string | ReactElement)}
57
65
  </Typography>
58
66
  </Modal.Body>
59
67
  <Box
@@ -1,18 +1,26 @@
1
1
  import { useAtomValue, useSetAtom } from 'jotai';
2
- import { equals, isNotNil } from 'ramda';
2
+ import { isNotNil } from 'ramda';
3
3
  import { useCallback, useMemo } from 'react';
4
4
 
5
5
  import { Modal } from '../../Modal';
6
6
  import { askBeforeCloseFormModalAtom, openFormModalAtom } from '../atoms';
7
7
  import Buttons from './Buttons';
8
8
 
9
- const AddModal = ({ title, Form, modalSize = 'medium' }): JSX.Element => {
9
+ const AddModal = ({
10
+ title,
11
+ Form,
12
+ modalSize = 'medium'
13
+ }: {
14
+ title: string;
15
+ Form: (props: { Buttons: () => JSX.Element }) => JSX.Element;
16
+ modalSize?: 'small' | 'medium' | 'large' | 'xlarge' | 'fullscreen';
17
+ }): JSX.Element => {
10
18
  const setAskBeforeCloseFormModal = useSetAtom(askBeforeCloseFormModalAtom);
11
19
 
12
20
  const openFormModal = useAtomValue(openFormModalAtom);
13
21
 
14
22
  const isModalOpen = useMemo(
15
- () => isNotNil(openFormModal) && equals('add', openFormModal),
23
+ () => isNotNil(openFormModal) && openFormModal === 'add',
16
24
  [openFormModal]
17
25
  );
18
26
 
@@ -22,7 +30,11 @@ const AddModal = ({ title, Form, modalSize = 'medium' }): JSX.Element => {
22
30
  );
23
31
 
24
32
  return (
25
- <Modal onClose={openAskBeforeClose} open={isModalOpen} size={modalSize}>
33
+ <Modal
34
+ onClose={openAskBeforeClose}
35
+ open={isModalOpen}
36
+ size={modalSize as 'small' | 'medium' | 'large' | 'xlarge' | 'fullscreen'}
37
+ >
26
38
  <Modal.Header>{title}</Modal.Header>
27
39
  <Modal.Body>
28
40
  <Form Buttons={Buttons} />
@@ -1,5 +1,5 @@
1
1
  import { useAtomValue, useSetAtom } from 'jotai';
2
- import { equals, isNotNil } from 'ramda';
2
+ import { isNotNil } from 'ramda';
3
3
  import { useCallback, useMemo } from 'react';
4
4
 
5
5
  import { Modal } from '../..';
@@ -33,7 +33,7 @@ const UpdateModal = <TItem extends { id: number; name: string }, TItemForm>({
33
33
  });
34
34
 
35
35
  const isModalOpen = useMemo(
36
- () => isNotNil(openFormModal) && !equals('add', openFormModal),
36
+ () => isNotNil(openFormModal) && openFormModal !== 'add',
37
37
  [openFormModal]
38
38
  );
39
39
 
@@ -47,6 +47,7 @@ const Listing = <TData extends { id: number; name: string }>({
47
47
  actions={<Actions filters={filters} labels={labels} />}
48
48
  columns={listingColumns}
49
49
  currentPage={page}
50
+ isActionBarVisible
50
51
  limit={limit}
51
52
  loading={isLoading}
52
53
  onLimitChange={setLimit}
@@ -54,7 +55,7 @@ const Listing = <TData extends { id: number; name: string }>({
54
55
  onSort={changeSort}
55
56
  rows={rows}
56
57
  sortField={sortField}
57
- sortOrder={sortOrder}
58
+ sortOrder={sortOrder as 'asc' | 'desc' | undefined}
58
59
  subItems={subItems}
59
60
  totalRows={total}
60
61
  />
@@ -40,7 +40,11 @@ export const useDeleteItem = ({
40
40
  onSuccess: (_data, { _meta }) => {
41
41
  queryClient.invalidateQueries({ queryKey: [listingQueryKey] });
42
42
  showSuccessMessage(
43
- isAFunction(successMessage) ? successMessage(_meta) : successMessage
43
+ (isAFunction(successMessage)
44
+ ? (successMessage as (item: ItemToDelete) => string | ReactElement)(
45
+ _meta as ItemToDelete
46
+ )
47
+ : successMessage) as string
44
48
  );
45
49
  }
46
50
  });
@@ -1,4 +1,4 @@
1
- import { equals, isNotNil } from 'ramda';
1
+ import { isNotNil } from 'ramda';
2
2
 
3
3
  import { useFetchQuery } from '../../..';
4
4
  import type { GetItem } from '../models';
@@ -22,10 +22,10 @@ export const useGetItem = <
22
22
  }): UseGetItem<TItemForm> => {
23
23
  const { data, isLoading } = useFetchQuery<TItem>({
24
24
  decoder,
25
- getEndpoint: () => baseEndpoint(id),
25
+ getEndpoint: () => baseEndpoint(id as number),
26
26
  getQueryKey: () => [itemQueryKey, id],
27
27
  queryOptions: {
28
- enabled: isNotNil(id) && !equals('add', id),
28
+ enabled: isNotNil(id) && id !== 'add',
29
29
  suspense: false
30
30
  }
31
31
  });
@@ -3,4 +3,4 @@ import type { RowId } from '../../Listing/models';
3
3
 
4
4
  export const DataListing = <TRow extends { id: RowId }>(
5
5
  props: ListingProps<TRow>
6
- ): JSX.Element => <Listing<TRow> {...props} />;
6
+ ): JSX.Element => <Listing {...(props as ListingProps<TRow>)} />;
@@ -42,6 +42,7 @@ const ExpandableContainer = ({ children }: Props) => {
42
42
  {children(reducedChildrenData)}
43
43
  {isExpanded && (
44
44
  <Modal
45
+ // @ts-expect-error - MUI Dialog classes prop passed through spread but not in ModalProps
45
46
  classes={{
46
47
  paper: classes.papper
47
48
  }}
@@ -32,7 +32,7 @@ const Actions = ({
32
32
  });
33
33
 
34
34
  const onCancel = (): void => {
35
- cancel({ dirty, values: formattedValues });
35
+ cancel?.({ dirty, values: formattedValues });
36
36
  };
37
37
 
38
38
  return (
@@ -30,10 +30,7 @@ export const useActions = ({ submit, clear }: Props): UseActionsState => {
30
30
  const save = (): void => {
31
31
  submit(
32
32
  values.filter(({ isRemoved }) => !isRemoved).map(formatValueForSubmition)
33
- )?.then((isError) => {
34
- if (isError) {
35
- return;
36
- }
33
+ )?.then(() => {
37
34
  clear();
38
35
  });
39
36
  };
@@ -12,7 +12,7 @@ const StateChip = ({ label, state }: Props): JSX.Element => {
12
12
  const { classes, cx } = useListStyles();
13
13
 
14
14
  return (
15
- <div className={cx(classes.state)}>
15
+ <div className={cx((classes as Record<string, string>).state)}>
16
16
  <Chip
17
17
  className={classes.stateChip}
18
18
  data-state={state}
@@ -11,7 +11,7 @@ interface Props {
11
11
  labels: Labels['list'];
12
12
  }
13
13
 
14
- const Stats = ({ labels }: Props): JSX.Element => {
14
+ const Stats = ({ labels }: Props): JSX.Element | null => {
15
15
  const { t } = useTranslation();
16
16
  const { hasStats, addedItems, updatedItems, removedItems } =
17
17
  useAtomValue(statsDerivedAtom);
@@ -1,5 +1,3 @@
1
- import type { SelectChangeEvent } from '@mui/material';
2
-
3
1
  import SelectField, { type SelectEntry } from '../../../../InputField/Select';
4
2
  import { useRoleSelectField } from './RoleSelectField.styles';
5
3
 
@@ -21,18 +19,18 @@ const RoleSelectField = ({
21
19
  disabled
22
20
  }: Props): JSX.Element => {
23
21
  const { classes } = useRoleSelectField();
24
- const change = (event: SelectChangeEvent): void => {
25
- onChange(event.target.value as string);
26
- };
27
22
 
28
23
  return (
29
24
  <div className={classes.roleContainer}>
30
25
  <SelectField
31
26
  dataTestId={testId}
32
27
  disabled={disabled}
28
+ formControlProps={{}}
33
29
  fullWidth
34
30
  label={label}
35
- onChange={change}
31
+ onChange={(event) => {
32
+ onChange(event.target.value);
33
+ }}
36
34
  options={roles}
37
35
  selectedOptionId={value}
38
36
  size="small"
@@ -1,7 +1,7 @@
1
1
  import { equals } from 'ramda';
2
2
  import { type ReactElement, useCallback, useMemo } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
- import { number, object, string } from 'yup';
4
+ import { number, object, type Schema, string } from 'yup';
5
5
 
6
6
  import { Form, type FormProps } from '../../../Form';
7
7
  import { InputType } from '../../../Form/Inputs/models';
@@ -109,7 +109,7 @@ const DashboardForm = ({
109
109
  .min(3, ({ min, label }) => t(labelMustBeAtLeast, { label, min }))
110
110
  .max(50, ({ max, label }) => t(labelMustBeMost, { label, max }))
111
111
  .required(t(labelRequired) as string)
112
- })
112
+ }) as unknown as Schema<DashboardResource>
113
113
  }),
114
114
  [resource, labels, onSubmit, showRefreshIntervalFields, t]
115
115
  );
@@ -1,25 +1,29 @@
1
1
  import { alpha } from '@mui/system';
2
2
 
3
+ import type { CSSObject } from 'tss-react';
3
4
  import { makeStyles } from 'tss-react/mui';
4
5
 
5
6
  const useStyles = makeStyles()((theme) => ({
6
7
  header: {
7
- alignItems: 'flex-start',
8
- borderBottom: `1px solid ${theme.palette.primary.main}`,
9
- display: 'flex',
10
- flexDirection: 'row',
11
- h1: {
12
- ...theme.typography.h5,
8
+ '& h1': {
9
+ fontFamily: theme.typography.h5.fontFamily,
10
+ fontSize: theme.typography.h5.fontSize,
13
11
  fontWeight: theme.typography.fontWeightMedium,
12
+ letterSpacing: theme.typography.h5.letterSpacing,
13
+ lineHeight: theme.typography.h5.lineHeight,
14
14
  margin: theme.spacing(0, 0, 1.5, 0)
15
- },
16
- justifyContent: 'space-between',
15
+ } as CSSObject,
17
16
 
18
- nav: {
17
+ '& nav': {
19
18
  display: 'flex',
20
19
  gap: theme.spacing(1),
21
20
  justifyContent: 'flex-end'
22
- },
21
+ } as CSSObject,
22
+ alignItems: 'flex-start',
23
+ borderBottom: `1px solid ${theme.palette.primary.main}`,
24
+ display: 'flex',
25
+ flexDirection: 'row',
26
+ justifyContent: 'space-between',
23
27
 
24
28
  padding: theme.spacing(0, 0, 1.5, 0)
25
29
  },
@@ -39,7 +43,7 @@ const useStyles = makeStyles()((theme) => ({
39
43
  backgroundColor: theme.palette.header.page.action.background.default,
40
44
 
41
45
  color: theme.palette.header.page.action.color.default
42
- },
46
+ } as CSSObject,
43
47
  display: 'flex',
44
48
 
45
49
  gap: theme.spacing(2)
@@ -84,28 +88,30 @@ const useStyles = makeStyles()((theme) => ({
84
88
  pageHeaderTitle: {
85
89
  '& > *': {
86
90
  display: 'grid'
87
- },
91
+ } as CSSObject,
88
92
  '& > span': {
89
93
  alignItems: 'center',
90
94
  display: 'flex',
91
95
  flexDirection: 'row',
92
96
  gap: theme.spacing(2)
93
- },
94
- alignSelf: 'flex-start',
95
- display: 'flex',
96
- flexDirection: 'column',
97
- h1: {
98
- ...theme.typography.h5,
97
+ } as CSSObject,
98
+ '& h1': {
99
+ fontFamily: theme.typography.h5.fontFamily,
100
+ fontSize: theme.typography.h5.fontSize,
99
101
  fontWeight: theme.typography.fontWeightBold,
102
+ letterSpacing: theme.typography.h5.letterSpacing,
100
103
  lineHeight: '1',
101
104
  margin: theme.spacing(0)
102
- }
105
+ } as CSSObject,
106
+ alignSelf: 'flex-start',
107
+ display: 'flex',
108
+ flexDirection: 'column'
103
109
  },
104
110
  pageHeaderTitleActions: {
105
111
  '& > button': {
106
112
  opacity: 0.2,
107
113
  padding: 0
108
- },
114
+ } as CSSObject,
109
115
  alignItems: 'bottom',
110
116
  display: 'flex',
111
117
  gap: theme.spacing(1),
@@ -37,9 +37,9 @@ const MenuProvider = ({
37
37
  [
38
38
  [isMenuOpenAtom, initialIsOpen ?? false],
39
39
  [anchorElAtom, null],
40
- [onOpenAtom, onOpen],
41
- [onCloseAtom, onClose]
42
- ],
40
+ [onOpenAtom, onOpen ?? null],
41
+ [onCloseAtom, onClose ?? null]
42
+ ] as unknown as Parameters<typeof useHydrateAtoms>[0],
43
43
  { store: menuStore }
44
44
  );
45
45
 
@@ -42,29 +42,34 @@ export const ConfirmationModal = <TAtom,>({
42
42
  disabled,
43
43
  size
44
44
  }: ConfirmationModalProps<TAtom>): JSX.Element => {
45
- const [atomData, setAtomData] = useAtom<TAtom | null>(atom);
45
+ const [atomData, setAtomData] = useAtom(atom);
46
+
47
+ const typedAtomData = atomData as Awaited<TAtom> | null;
46
48
 
47
49
  const closeModal = (): void => {
48
- onClose?.(atomData);
50
+ onClose?.(typedAtomData);
49
51
  setAtomData(null);
50
52
  };
51
53
 
52
54
  const formattedLabels = useMemo(() => {
53
55
  return {
54
- cancel: getLabel({ atomData, label: labels.cancel }),
55
- confirm: getLabel({ atomData, label: labels.confirm }),
56
- description: getLabel({ atomData, label: labels.description }),
57
- title: getLabel({ atomData, label: labels.title })
56
+ cancel: getLabel({ atomData: typedAtomData, label: labels.cancel }),
57
+ confirm: getLabel({ atomData: typedAtomData, label: labels.confirm }),
58
+ description: getLabel({
59
+ atomData: typedAtomData,
60
+ label: labels.description
61
+ }),
62
+ title: getLabel({ atomData: typedAtomData, label: labels.title })
58
63
  };
59
- }, [labels, atomData]);
64
+ }, [labels, typedAtomData]);
60
65
 
61
66
  const confirm = (): void => {
62
- onConfirm?.(atomData);
67
+ onConfirm?.(typedAtomData);
63
68
  setAtomData(null);
64
69
  };
65
70
 
66
71
  const cancel = (): void => {
67
- onCancel?.(atomData);
72
+ onCancel?.(typedAtomData);
68
73
  setAtomData(null);
69
74
  };
70
75
 
@@ -54,9 +54,11 @@ const Modal = ({
54
54
  onClose={onClose}
55
55
  open={open}
56
56
  TransitionComponent={isFullscreen ? Slide : undefined}
57
- TransitionProps={{
58
- direction: 'up'
59
- }}
57
+ TransitionProps={
58
+ {
59
+ direction: 'up'
60
+ } as Record<string, unknown>
61
+ }
60
62
  {...attr}
61
63
  >
62
64
  {hasCloseButton && (
@@ -28,7 +28,7 @@ const ModalActions = ({
28
28
  disabled,
29
29
  isFixed
30
30
  }: ModalActionsProps): ReactElement => {
31
- const { classes } = useStyles();
31
+ const { classes } = useStyles({});
32
32
 
33
33
  return (
34
34
  <div className={classes.modalActions} data-fixed={isFixed}>
@@ -1,6 +1,6 @@
1
1
  import type { ReactElement, ReactNode } from 'react';
2
2
 
3
- import { modalBody } from './modal.module.css';
3
+ import styles from './modal.module.css';
4
4
 
5
5
  export type ModalHeaderProps = {
6
6
  children?: ReactNode;
@@ -8,7 +8,7 @@ export type ModalHeaderProps = {
8
8
 
9
9
  const ModalBody = ({ children }: ModalHeaderProps): ReactElement => {
10
10
  return (
11
- <div className={modalBody} data-testid="modal-body">
11
+ <div className={styles.modalBody} data-testid="modal-body">
12
12
  {children}
13
13
  </div>
14
14
  );