@centreon/ui 24.4.46 → 24.4.48

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 (139) hide show
  1. package/package.json +14 -23
  2. package/public/mockServiceWorker.js +1 -1
  3. package/src/Button/Icon/index.tsx +1 -1
  4. package/src/Button/Save/StartIcon.tsx +3 -3
  5. package/src/Button/Save/index.tsx +5 -9
  6. package/src/Checkbox/Checkbox.tsx +2 -2
  7. package/src/Checkbox/CheckboxGroup/index.tsx +2 -2
  8. package/src/Dashboard/Item.tsx +1 -1
  9. package/src/Dashboard/Layout.tsx +2 -2
  10. package/src/Dialog/index.tsx +1 -1
  11. package/src/FallbackPage/FallbackPage.tsx +3 -3
  12. package/src/FileDropZone/index.tsx +1 -3
  13. package/src/Form/Inputs/CheckboxGroup.tsx +4 -1
  14. package/src/Form/Inputs/index.tsx +1 -3
  15. package/src/Form/Inputs/models.ts +1 -9
  16. package/src/Graph/Gauge/Gauge.tsx +1 -1
  17. package/src/Graph/HeatMap/HeatMap.stories.tsx +25 -0
  18. package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +2 -8
  19. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/Circle.tsx +2 -2
  20. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/index.tsx +4 -5
  21. package/src/Graph/LineChart/BasicComponents/Thresholds.tsx +2 -2
  22. package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +1 -1
  23. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/GuidingLines.tsx +2 -2
  24. package/src/Graph/LineChart/InteractiveComponents/Annotations/Annotation/index.tsx +3 -2
  25. package/src/Graph/LineChart/InteractiveComponents/Annotations/EventAnnotations.tsx +1 -1
  26. package/src/Graph/LineChart/Legend/Legend.styles.ts +1 -1
  27. package/src/Graph/LineChart/Legend/LegendHeader.tsx +1 -1
  28. package/src/Graph/LineChart/Legend/useInteractiveValues.ts +2 -2
  29. package/src/Graph/LineChart/Legend/useLegend.ts +3 -3
  30. package/src/Graph/LineChart/helpers/doc.ts +13 -16
  31. package/src/Graph/LineChart/helpers/index.ts +1 -1
  32. package/src/Graph/LineChart/index.stories.tsx +2 -4
  33. package/src/Graph/LineChart/index.tsx +1 -1
  34. package/src/Graph/SingleBar/Thresholds.tsx +2 -2
  35. package/src/Graph/Text/Text.stories.tsx +4 -60
  36. package/src/Graph/Text/Text.tsx +1 -1
  37. package/src/Graph/common/timeSeries/index.ts +14 -22
  38. package/src/Graph/common/utils.ts +0 -19
  39. package/src/Graph/index.ts +0 -3
  40. package/src/InputField/Select/Autocomplete/Connected/index.tsx +7 -10
  41. package/src/InputField/Select/Autocomplete/Draggable/SortableList.tsx +1 -1
  42. package/src/InputField/Select/Autocomplete/Draggable/SortableListContent.tsx +1 -1
  43. package/src/InputField/Select/Autocomplete/Draggable/index.tsx +1 -1
  44. package/src/InputField/Select/Autocomplete/index.tsx +115 -121
  45. package/src/InputField/Select/IconPopover/index.tsx +2 -2
  46. package/src/InputField/Select/index.tsx +1 -1
  47. package/src/InputField/Text/index.tsx +2 -2
  48. package/src/Listing/ActionBar/index.tsx +8 -9
  49. package/src/Listing/Cell/DataCell.styles.ts +0 -3
  50. package/src/Listing/Cell/DataCell.tsx +5 -23
  51. package/src/Listing/Header/ListingHeader.tsx +1 -1
  52. package/src/Listing/Listing.cypress.spec.tsx +4 -80
  53. package/src/Listing/Listing.styles.ts +7 -4
  54. package/src/Listing/index.stories.tsx +3 -37
  55. package/src/Listing/index.test.tsx +1 -1
  56. package/src/Listing/index.tsx +3 -4
  57. package/src/Listing/models.ts +0 -1
  58. package/src/Module/index.tsx +4 -2
  59. package/src/RichTextEditor/RichTextEditor.tsx +1 -12
  60. package/src/SortableItems/index.tsx +7 -2
  61. package/src/ThemeProvider/index.tsx +0 -24
  62. package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.styles.ts +7 -6
  63. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +3 -8
  64. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +2 -0
  65. package/src/TimePeriods/DateTimePickerInput.tsx +19 -56
  66. package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +9 -12
  67. package/src/TimePeriods/TimePeriods.cypress.spec.tsx +33 -9
  68. package/src/TimePeriods/helpers/index.ts +1 -1
  69. package/src/TimePeriods/index.stories.tsx +4 -12
  70. package/src/TimePeriods/index.tsx +2 -2
  71. package/src/api/QueryProvider.tsx +1 -1
  72. package/src/api/TestQueryProvider.tsx +1 -1
  73. package/src/api/useFetchQuery/index.ts +23 -27
  74. package/src/api/useMutationQuery/index.test.ts +4 -4
  75. package/src/api/useMutationQuery/index.ts +25 -60
  76. package/src/components/Button/Icon/IconButton.tsx +2 -6
  77. package/src/components/DataTable/DataTable.stories.tsx +0 -40
  78. package/src/components/DataTable/DataTable.styles.ts +0 -3
  79. package/src/components/DataTable/DataTable.tsx +3 -3
  80. package/src/components/DataTable/Item/DataTableItem.styles.ts +2 -7
  81. package/src/components/DataTable/Item/DataTableItem.tsx +4 -4
  82. package/src/components/DataTable/index.ts +1 -3
  83. package/src/components/Form/AccessRights/ShareInput/ContactSwitch.tsx +3 -3
  84. package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +0 -1
  85. package/src/components/Form/Dashboard/DashboardForm.tsx +12 -15
  86. package/src/components/Layout/PageLayout/PageLayout.tsx +1 -1
  87. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +0 -1
  88. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +0 -1
  89. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +1 -5
  90. package/src/components/Layout/PageLayout/index.ts +1 -3
  91. package/src/components/Modal/Modal.styles.ts +1 -1
  92. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.stories.tsx +3 -3
  93. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.tsx +1 -1
  94. package/src/components/Tooltip/ConfirmationTooltip/models.ts +1 -1
  95. package/src/index.ts +2 -2
  96. package/src/queryParameters/url/index.ts +1 -5
  97. package/src/screens/dashboard/DashboardsDetail.stories.tsx +108 -0
  98. package/src/screens/dashboard/DashboardsOverview.stories.tsx +281 -0
  99. package/src/utils/index.ts +1 -1
  100. package/src/utils/useDateTimePickerAdapter.ts +309 -0
  101. package/src/utils/useFullscreen/useFullscreenListener.ts +7 -10
  102. package/src/utils/{useLicenseExpirationWarning.test.tsx → useLicenseExpirationWarning.cypress.spec.tsx} +37 -48
  103. package/src/utils/useLicenseExpirationWarning.ts +18 -18
  104. package/src/Form/Form.cypress.spec.tsx +0 -133
  105. package/src/Form/Inputs/List/Content.tsx +0 -62
  106. package/src/Form/Inputs/List/List.styles.ts +0 -29
  107. package/src/Form/Inputs/List/List.tsx +0 -58
  108. package/src/Form/Inputs/List/useList.ts +0 -81
  109. package/src/Graph/BarStack/BarStack.cypress.spec.tsx +0 -154
  110. package/src/Graph/BarStack/BarStack.stories.tsx +0 -123
  111. package/src/Graph/BarStack/BarStack.styles.ts +0 -36
  112. package/src/Graph/BarStack/BarStack.tsx +0 -14
  113. package/src/Graph/BarStack/ResponsiveBarStack.tsx +0 -208
  114. package/src/Graph/BarStack/index.ts +0 -1
  115. package/src/Graph/BarStack/models.ts +0 -19
  116. package/src/Graph/BarStack/useResponsiveBarStack.ts +0 -139
  117. package/src/Graph/Gauge/Gauge.cypress.spec.tsx +0 -102
  118. package/src/Graph/HeatMap/HeatMap.cypress.spec.tsx +0 -145
  119. package/src/Graph/Legend/Legend.tsx +0 -21
  120. package/src/Graph/Legend/index.ts +0 -1
  121. package/src/Graph/Legend/models.ts +0 -11
  122. package/src/Graph/PieChart/PieChart.cypress.spec.tsx +0 -169
  123. package/src/Graph/PieChart/PieChart.stories.tsx +0 -194
  124. package/src/Graph/PieChart/PieChart.styles.ts +0 -39
  125. package/src/Graph/PieChart/PieChart.tsx +0 -14
  126. package/src/Graph/PieChart/ResponsivePie.tsx +0 -251
  127. package/src/Graph/PieChart/index.ts +0 -1
  128. package/src/Graph/PieChart/models.ts +0 -19
  129. package/src/Graph/PieChart/useResponsivePie.ts +0 -86
  130. package/src/Graph/SingleBar/SingleBar.cypress.spec.tsx +0 -121
  131. package/src/Graph/Text/Text.cypress.spec.tsx +0 -101
  132. package/src/Graph/common/testUtils.ts +0 -71
  133. package/src/Graph/translatedLabels.ts +0 -1
  134. package/src/Module/Module.cypress.spec.tsx +0 -129
  135. package/src/components/DataTable/DataListing.tsx +0 -6
  136. package/src/components/DataTable/DataTable.cypress.spec.tsx +0 -193
  137. package/src/components/Layout/PageLayout/PageQuickAccess.tsx +0 -76
  138. package/src/components/Layout/PageLayout.cypress.spec.tsx +0 -66
  139. package/src/utils/usePluralizedTranslation.ts +0 -21
@@ -1,85 +1,48 @@
1
- import { useCallback } from 'react';
1
+ import dayjs from 'dayjs';
2
2
 
3
- import dayjs, { Dayjs } from 'dayjs';
4
- import { useAtomValue } from 'jotai';
5
- import { equals } from 'ramda';
3
+ import { DateTimePicker } from '@mui/x-date-pickers';
6
4
 
7
- import {
8
- DateTimePicker,
9
- DateTimePickerProps,
10
- LocalizationProvider
11
- } from '@mui/x-date-pickers';
12
- import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
13
-
14
- import { userAtom } from '@centreon/ui-context';
5
+ import { useDateTimePickerAdapter } from '@centreon/ui';
15
6
 
16
7
  import { CustomTimePeriodProperty } from './models';
17
8
 
18
- interface ChangeDateProps {
19
- date: Date;
20
- property: CustomTimePeriodProperty | string;
21
- }
22
-
23
9
  interface Props {
24
- changeDate: (props: ChangeDateProps) => void;
10
+ changeDate: (props) => void;
25
11
  date: Date | null;
26
12
  desktopMediaQuery?: string;
27
13
  disabled?: boolean;
28
14
  maxDate?: Date;
29
15
  minDate?: Date;
30
- minDateTime?: Date;
31
- property: CustomTimePeriodProperty | string;
16
+ property: CustomTimePeriodProperty;
32
17
  }
33
18
 
34
19
  const DateTimePickerInput = ({
35
20
  date,
36
21
  maxDate,
37
22
  minDate,
38
- minDateTime,
39
23
  property,
40
24
  changeDate,
41
25
  disabled = false,
42
- desktopMediaQuery,
43
- ...rest
44
- }: Props & DateTimePickerProps<dayjs.Dayjs>): JSX.Element => {
45
- const desktopPickerMediaQuery =
46
- '@media (min-width: 1024px) or (pointer: fine)';
47
-
48
- const { timezone, locale } = useAtomValue(userAtom);
49
-
50
- const isUTC = equals(timezone, 'UTC');
26
+ desktopMediaQuery
27
+ }: Props): JSX.Element => {
28
+ const { desktopPickerMediaQuery } = useDateTimePickerAdapter();
51
29
 
52
30
  const changeTime = (newValue: dayjs.Dayjs | null): void => {
53
31
  changeDate({ date: dayjs(newValue).toDate(), property });
54
32
  };
55
33
 
56
- const formatDate = useCallback(
57
- (currentDate: Date | null): Dayjs => {
58
- return isUTC ? dayjs.utc(currentDate) : dayjs.tz(currentDate, timezone);
59
- },
60
- [isUTC, timezone]
61
- );
62
-
63
34
  return (
64
- <LocalizationProvider
65
- adapterLocale={locale.substring(0, 2)}
66
- dateAdapter={AdapterDayjs}
67
- dateLibInstance={dayjs}
68
- >
69
- <DateTimePicker<dayjs.Dayjs>
70
- dayOfWeekFormatter={(dayOfWeek) =>
71
- dayOfWeek.substring(0, 2).toLocaleUpperCase()
72
- }
73
- desktopModeMediaQuery={desktopMediaQuery ?? desktopPickerMediaQuery}
74
- disabled={disabled}
75
- maxDate={maxDate && formatDate(maxDate)}
76
- minDate={minDate && formatDate(minDate)}
77
- minDateTime={minDateTime && formatDate(minDateTime)}
78
- value={formatDate(date)}
79
- onChange={changeTime}
80
- {...rest}
81
- />
82
- </LocalizationProvider>
35
+ <DateTimePicker<dayjs.Dayjs>
36
+ dayOfWeekFormatter={(day: string): string =>
37
+ day.substring(0, 2).toUpperCase()
38
+ }
39
+ desktopModeMediaQuery={desktopMediaQuery ?? desktopPickerMediaQuery}
40
+ disabled={disabled}
41
+ maxDate={maxDate && dayjs(maxDate)}
42
+ minDate={minDate && dayjs(minDate)}
43
+ value={dayjs(date)}
44
+ onChange={changeTime}
45
+ />
83
46
  );
84
47
  };
85
48
 
@@ -1,5 +1,5 @@
1
1
  import dayjs from 'dayjs';
2
- import 'dayjs/locale/en';
2
+ import 'dayjs/locale/fr';
3
3
  import localizedFormatPlugin from 'dayjs/plugin/localizedFormat';
4
4
  import timezonePlugin from 'dayjs/plugin/timezone';
5
5
  import utcPlugin from 'dayjs/plugin/utc';
@@ -19,18 +19,18 @@ dayjs.extend(localizedFormatPlugin);
19
19
 
20
20
  const data = [
21
21
  {
22
- locale: 'en_US',
23
- resolution: { height: 590, width: 500 },
22
+ locale: 'fr_FR',
23
+ resolution: { height: 720, width: 500 },
24
24
  timezone: 'Europe/Paris'
25
25
  },
26
26
  {
27
- locale: 'en_US',
28
- resolution: { height: 590, width: 200 },
27
+ locale: 'fr_FR',
28
+ resolution: { height: 720, width: 200 },
29
29
  timezone: 'Europe/Paris'
30
30
  },
31
31
  {
32
- locale: 'en_US',
33
- resolution: { height: 590, width: 1024 },
32
+ locale: 'fr_FR',
33
+ resolution: { height: 720, width: 1024 },
34
34
  timezone: 'Europe/Paris'
35
35
  }
36
36
  ];
@@ -45,7 +45,7 @@ data.forEach((item) =>
45
45
 
46
46
  store.set(userAtom, {
47
47
  ...retrievedUser,
48
- locale: 'en_US',
48
+ locale: 'fr_FR',
49
49
  timezone: 'Europe/Paris'
50
50
  });
51
51
 
@@ -59,10 +59,7 @@ data.forEach((item) =>
59
59
  });
60
60
 
61
61
  it(`displays correctly the dates design when screen resolution is ${width}px`, () => {
62
- cy.makeSnapshotWithCustomResolution({
63
- resolution: { height, width },
64
- title: `${width}px`
65
- });
62
+ cy.makeSnapshot(`${width}px`);
66
63
  });
67
64
  })
68
65
  );
@@ -3,10 +3,15 @@ import localizedFormatPlugin from 'dayjs/plugin/localizedFormat';
3
3
  import timezonePlugin from 'dayjs/plugin/timezone';
4
4
  import utcPlugin from 'dayjs/plugin/utc';
5
5
  import { Provider, createStore } from 'jotai';
6
- import { equals } from 'ramda';
6
+ import { equals, inc } from 'ramda';
7
7
  import { renderHook } from '@testing-library/react';
8
8
 
9
- import { useLocaleDateTimeFormat } from '@centreon/ui';
9
+ import { LocalizationProvider } from '@mui/x-date-pickers';
10
+
11
+ import {
12
+ useLocaleDateTimeFormat,
13
+ useDateTimePickerAdapter
14
+ } from '@centreon/ui';
10
15
  import { ListingVariant, userAtom } from '@centreon/ui-context';
11
16
 
12
17
  import { CustomTimePeriodProperty } from './models';
@@ -292,6 +297,10 @@ testData.forEach((item) =>
292
297
  beforeEach(() => {
293
298
  cy.viewport('macbook-13');
294
299
 
300
+ const { result } = renderHook(() => useDateTimePickerAdapter());
301
+
302
+ const { Adapter } = result.current;
303
+
295
304
  const store = createStore();
296
305
  store.set(userAtom, {
297
306
  ...retrievedUser,
@@ -302,16 +311,31 @@ testData.forEach((item) =>
302
311
  cy.mount({
303
312
  Component: (
304
313
  <Provider store={store}>
305
- <DateTimePickerInput
306
- changeDate={cy.stub()}
307
- date={new Date(item.initialDate)}
308
- property={CustomTimePeriodProperty.start}
309
- />
314
+ <LocalizationProvider adapterLocale="en" dateAdapter={Adapter}>
315
+ <DateTimePickerInput
316
+ changeDate={cy.stub()}
317
+ date={new Date(item.initialDate)}
318
+ desktopMediaQuery="@media (min-width: 1024px)"
319
+ property={CustomTimePeriodProperty.start}
320
+ />
321
+ </LocalizationProvider>
310
322
  </Provider>
311
323
  )
312
324
  });
313
325
  });
314
326
 
327
+ it('checks input calendar value contains correct date', () => {
328
+ const { result } = renderHook(() => useLocaleDateTimeFormat());
329
+ const { format } = result.current;
330
+
331
+ const dateInput = format({
332
+ date: dayjs(item.initialDate).tz(item.timezone),
333
+ formatString: 'L hh:mm A'
334
+ });
335
+
336
+ cy.get('input').should('have.value', dateInput);
337
+ });
338
+
315
339
  it(`displays the correct number of days for the current month when the ${item.button} button is clicked`, () => {
316
340
  cy.get('button').click();
317
341
  item.data.forEach((element) => {
@@ -365,7 +389,7 @@ testData.forEach((item) =>
365
389
 
366
390
  cy.get('[role="rowgroup"]').children().as('listWeeks');
367
391
 
368
- cy.get('@listWeeks').should('have.length', numberWeeks);
392
+ cy.get('@listWeeks').should('have.length', inc(numberWeeks));
369
393
  cy.get('@listWeeks').eq(0).as('firstWeek');
370
394
  cy.get('@firstWeek').children().as('listDaysInFirstWeek');
371
395
 
@@ -392,7 +416,7 @@ testData.forEach((item) =>
392
416
 
393
417
  cy.get('[role="rowgroup"]').children().as('listWeeks');
394
418
 
395
- cy.get('@listWeeks').should('have.length', numberWeeks);
419
+ cy.get('@listWeeks').should('have.length', inc(numberWeeks));
396
420
 
397
421
  cy.get('@listWeeks')
398
422
  .eq(numberWeeks - 1)
@@ -23,4 +23,4 @@ export const getTimePeriodById = ({
23
23
  id,
24
24
  timePeriods
25
25
  }: TimePeriodById): TimePeriod =>
26
- find<TimePeriod>(propEq(id, 'id'))(timePeriods) as TimePeriod;
26
+ find<TimePeriod>(propEq('id', id))(timePeriods) as TimePeriod;
@@ -88,27 +88,20 @@ const args = {
88
88
  ]
89
89
  };
90
90
 
91
- const parameters = {
92
- chromatic: { diffThreshold: 0.1 }
93
- };
94
-
95
91
  export const BasicTimePeriod: Story = {
96
92
  ...Template,
97
- argTypes,
98
- parameters
93
+ argTypes
99
94
  };
100
95
 
101
96
  export const WithExtraTimePeriods: Story = {
102
97
  ...Template,
103
98
  argTypes,
104
- args,
105
- parameters
99
+ args
106
100
  };
107
101
 
108
102
  export const WithExternalComponent: Story = {
109
103
  ...TemplateWithExternalComponent,
110
- argTypes,
111
- parameters
104
+ argTypes
112
105
  };
113
106
 
114
107
  export const SimpleTimePeriod: StorySimpleTimePeriod = {
@@ -116,6 +109,5 @@ export const SimpleTimePeriod: StorySimpleTimePeriod = {
116
109
  args: {
117
110
  endDate: dayjs(Date.now()).toDate(),
118
111
  startDate: dayjs(Date.now()).subtract(29, 'day').toDate()
119
- },
120
- parameters
112
+ }
121
113
  };
@@ -20,7 +20,7 @@ import { useStyles } from './TimePeriods.styles';
20
20
  import {
21
21
  CustomTimePeriod as CustomTimePeriodModel,
22
22
  EndStartInterval,
23
- TimePeriod as TimePeriodModel
23
+ TimePeriod
24
24
  } from './models';
25
25
  import useTimePeriod from './useTimePeriod';
26
26
 
@@ -34,7 +34,7 @@ interface Parameters extends EndStartInterval {
34
34
  export interface Props {
35
35
  adjustTimePeriodData?: Omit<CustomTimePeriodModel, 'timelineEventsLimit'>;
36
36
  disabled?: boolean;
37
- extraTimePeriods?: Array<Omit<TimePeriodModel, 'timelineEventsLimit'>>;
37
+ extraTimePeriods?: Array<Omit<TimePeriod, 'timelineEventsLimit'>>;
38
38
  getIsError?: (value: boolean) => void;
39
39
  getParameters?: ({ start, end, timelineEventsLimit }: Parameters) => void;
40
40
  renderExternalComponent?: ReactNode;
@@ -7,7 +7,7 @@ const defaultCacheTime = 5 * 1_000;
7
7
  const client = new QueryClient({
8
8
  defaultOptions: {
9
9
  queries: {
10
- gcTime: defaultCacheTime,
10
+ cacheTime: defaultCacheTime,
11
11
  refetchOnWindowFocus: false,
12
12
  staleTime: defaultCacheTime,
13
13
  suspense: true
@@ -5,7 +5,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
5
5
  const client = new QueryClient({
6
6
  defaultOptions: {
7
7
  queries: {
8
- gcTime: 0,
8
+ cacheTime: 0,
9
9
  retry: false
10
10
  }
11
11
  }
@@ -27,9 +27,7 @@ export interface UseFetchQueryProps<T> {
27
27
  getQueryKey: () => QueryKey;
28
28
  httpCodesBypassErrorSnackbar?: Array<number>;
29
29
  isPaginated?: boolean;
30
- queryOptions?: {
31
- suspense?: boolean;
32
- } & Omit<
30
+ queryOptions?: Omit<
33
31
  UseQueryOptions<T | ResponseError, Error, T | ResponseError, QueryKey>,
34
32
  'queryKey' | 'queryFn'
35
33
  >;
@@ -37,12 +35,11 @@ export interface UseFetchQueryProps<T> {
37
35
 
38
36
  export type UseFetchQueryState<T> = {
39
37
  data?: T;
40
- error: Omit<ResponseError, 'isError'> | null;
41
38
  fetchQuery: () => Promise<T | ResponseError>;
42
39
  prefetchNextPage: ({ page, getPrefetchQueryKey }) => void;
43
40
  prefetchPreviousPage: ({ page, getPrefetchQueryKey }) => void;
44
41
  prefetchQuery: ({ endpointParams, queryKey }) => void;
45
- } & Omit<QueryObserverBaseResult, 'data' | 'error'>;
42
+ } & Omit<QueryObserverBaseResult, 'data'>;
46
43
 
47
44
  export interface PrefetchEndpointParams {
48
45
  page: number;
@@ -67,8 +64,9 @@ const useFetchQuery = <T extends object>({
67
64
 
68
65
  const { showErrorMessage } = useSnackbar();
69
66
 
70
- const queryData = useQuery<T | ResponseError, Error>({
71
- queryFn: ({ signal }): Promise<T | ResponseError> =>
67
+ const queryData = useQuery<T | ResponseError, Error>(
68
+ getQueryKey(),
69
+ ({ signal }): Promise<T | ResponseError> =>
72
70
  customFetch<T>({
73
71
  baseEndpoint,
74
72
  catchError,
@@ -78,9 +76,10 @@ const useFetchQuery = <T extends object>({
78
76
  headers: new Headers(fetchHeaders),
79
77
  signal
80
78
  }),
81
- queryKey: getQueryKey(),
82
- ...queryOptions
83
- });
79
+ {
80
+ ...queryOptions
81
+ }
82
+ );
84
83
 
85
84
  const queryClient = useQueryClient();
86
85
 
@@ -100,8 +99,9 @@ const useFetchQuery = <T extends object>({
100
99
  };
101
100
 
102
101
  const prefetchQuery = ({ endpointParams, queryKey }): void => {
103
- queryClient.prefetchQuery({
104
- queryFn: ({ signal }): Promise<T | ResponseError> =>
102
+ queryClient.prefetchQuery(
103
+ queryKey,
104
+ ({ signal }): Promise<T | ResponseError> =>
105
105
  customFetch<T>({
106
106
  baseEndpoint,
107
107
  catchError,
@@ -110,9 +110,8 @@ const useFetchQuery = <T extends object>({
110
110
  endpoint: getEndpoint(endpointParams),
111
111
  headers: new Headers(fetchHeaders),
112
112
  signal
113
- }),
114
- queryKey
115
- });
113
+ })
114
+ );
116
115
  };
117
116
 
118
117
  const prefetchNextPage = ({ page, getPrefetchQueryKey }): void => {
@@ -142,8 +141,9 @@ const useFetchQuery = <T extends object>({
142
141
  };
143
142
 
144
143
  const fetchQuery = (): Promise<T | ResponseError> => {
145
- return queryClient.fetchQuery({
146
- queryFn: ({ signal }): Promise<T | ResponseError> =>
144
+ return queryClient.fetchQuery(
145
+ getQueryKey(),
146
+ ({ signal }): Promise<T | ResponseError> =>
147
147
  customFetch<T>({
148
148
  baseEndpoint,
149
149
  catchError,
@@ -152,9 +152,8 @@ const useFetchQuery = <T extends object>({
152
152
  endpoint: getEndpoint(),
153
153
  headers: new Headers(fetchHeaders),
154
154
  signal
155
- }),
156
- queryKey: getQueryKey()
157
- });
155
+ })
156
+ );
158
157
  };
159
158
 
160
159
  const data = useMemo(
@@ -175,16 +174,13 @@ const useFetchQuery = <T extends object>({
175
174
  return;
176
175
  }
177
176
 
178
- queryClient.cancelQueries({ queryKey: getQueryKey() });
177
+ queryClient.cancelQueries(getQueryKey());
179
178
  };
180
179
  }, []);
181
180
 
182
- useEffect(
183
- () => {
184
- manageError();
185
- },
186
- useDeepCompare([queryData.data])
187
- );
181
+ useEffect(() => {
182
+ manageError();
183
+ }, useDeepCompare([queryData.data]));
188
184
 
189
185
  return {
190
186
  ...omit(['data', 'error'], queryData),
@@ -48,7 +48,7 @@ describe('useFetchQuery', () => {
48
48
  method: Method.POST
49
49
  });
50
50
 
51
- result.current.mutate({ payload: user });
51
+ result.current.mutate(user);
52
52
 
53
53
  await waitFor(() => {
54
54
  expect(result.current?.isError).toEqual(false);
@@ -64,7 +64,7 @@ describe('useFetchQuery', () => {
64
64
  method: Method.POST
65
65
  });
66
66
 
67
- result.current.mutate({ payload: user });
67
+ result.current.mutate(user);
68
68
 
69
69
  await waitFor(() => {
70
70
  expect(result.current?.isError).toEqual(true);
@@ -85,7 +85,7 @@ describe('useFetchQuery', () => {
85
85
  method: Method.POST
86
86
  });
87
87
 
88
- result.current.mutate({ payload: user });
88
+ result.current.mutate(user);
89
89
 
90
90
  await waitFor(() => {
91
91
  expect(result.current?.isError).toEqual(true);
@@ -109,7 +109,7 @@ describe('useFetchQuery', () => {
109
109
  method: Method.POST
110
110
  });
111
111
 
112
- result.current.mutate({ payload: user });
112
+ result.current.mutate(user);
113
113
 
114
114
  await waitFor(() => {
115
115
  expect(mockedShowErrorMessage).not.toHaveBeenCalled();
@@ -8,7 +8,7 @@ import {
8
8
  } from '@tanstack/react-query';
9
9
  import { JsonDecoder } from 'ts.data.json';
10
10
  import anylogger from 'anylogger';
11
- import { includes, omit } from 'ramda';
11
+ import { includes } from 'ramda';
12
12
 
13
13
  import { CatchErrorProps, customFetch, ResponseError } from '../customFetch';
14
14
  import useSnackbar from '../../Snackbar/useSnackbar';
@@ -22,11 +22,6 @@ export enum Method {
22
22
  PUT = 'PUT'
23
23
  }
24
24
 
25
- interface Variables<TMeta, T> {
26
- _meta?: TMeta;
27
- payload?: T;
28
- }
29
-
30
25
  export type UseMutationQueryProps<T, TMeta> = {
31
26
  baseEndpoint?: string;
32
27
  catchError?: (props: CatchErrorProps) => void;
@@ -36,39 +31,14 @@ export type UseMutationQueryProps<T, TMeta> = {
36
31
  getEndpoint: (_meta: TMeta) => string;
37
32
  httpCodesBypassErrorSnackbar?: Array<number>;
38
33
  method: Method;
39
- onError?: (
40
- error: ResponseError,
41
- variables: Variables<TMeta, T>,
42
- context: unknown
43
- ) => unknown;
44
- onMutate?: (variables: Variables<TMeta, T>) => Promise<unknown> | unknown;
45
- onSuccess?: (
46
- data: ResponseError | T,
47
- variables: Variables<TMeta, T>,
48
- context: unknown
49
- ) => unknown;
50
- } & Omit<
51
- UseMutationOptions<{ _meta?: TMeta; payload: T }>,
52
- 'mutationFn' | 'onError' | 'onMutate' | 'onSuccess' | 'mutateAsync' | 'mutate'
53
- >;
34
+ } & Omit<UseMutationOptions<T & { _meta?: TMeta }>, 'mutationFn'>;
54
35
 
55
36
  const log = anylogger('API Request');
56
37
 
57
- export type UseMutationQueryState<T, TMeta> = Omit<
58
- UseMutationResult<T | ResponseError>,
59
- 'isError' | 'mutate' | 'mutateAsync'
60
- > & {
38
+ export type UseMutationQueryState<T> = {
61
39
  isError: boolean;
62
40
  isMutating: boolean;
63
- mutate: (variables: Variables<TMeta, T>) => ResponseError | T;
64
- mutateAsync: (
65
- variables: Variables<TMeta, T>,
66
- rest?: Pick<
67
- UseMutationQueryProps<T, TMeta>,
68
- 'onError' | 'onMutate' | 'onSettled' | 'onSuccess'
69
- >
70
- ) => Promise<ResponseError | T>;
71
- };
41
+ } & UseMutationResult<T | ResponseError>;
72
42
 
73
43
  const useMutationQuery = <T extends object, TMeta>({
74
44
  getEndpoint,
@@ -81,20 +51,17 @@ const useMutationQuery = <T extends object, TMeta>({
81
51
  onMutate,
82
52
  onError,
83
53
  onSuccess,
84
- onSettled,
85
54
  baseEndpoint
86
- }: UseMutationQueryProps<T, TMeta>): UseMutationQueryState<T, TMeta> => {
55
+ }: UseMutationQueryProps<T, TMeta>): UseMutationQueryState<T> => {
87
56
  const { showErrorMessage } = useSnackbar();
88
57
 
89
58
  const queryData = useMutation<
90
59
  T | ResponseError,
91
60
  ResponseError,
92
- Variables<TMeta, T>
93
- >({
94
- mutationFn: (
95
- variables: Variables<TMeta, T>
96
- ): Promise<T | ResponseError> => {
97
- const { _meta, payload } = variables || {};
61
+ T & { _meta: TMeta }
62
+ >(
63
+ (_payload: T & { _meta: TMeta }): Promise<T | ResponseError> => {
64
+ const { _meta, ...payload } = _payload || {};
98
65
 
99
66
  return customFetch<T>({
100
67
  baseEndpoint,
@@ -111,18 +78,19 @@ const useMutationQuery = <T extends object, TMeta>({
111
78
  payload
112
79
  });
113
80
  },
114
- onError,
115
- onMutate,
116
- onSettled,
117
- onSuccess: (data, variables, context) => {
118
- if (data?.isError) {
119
- onError?.(data, variables, context);
120
-
121
- return;
81
+ {
82
+ onError,
83
+ onMutate,
84
+ onSuccess: (data, variables, context) => {
85
+ if (data?.isError) {
86
+ onError?.(data, variables, context);
87
+
88
+ return;
89
+ }
90
+ onSuccess?.(data, variables, context);
122
91
  }
123
- onSuccess?.(data, variables, context);
124
92
  }
125
- });
93
+ );
126
94
 
127
95
  const manageError = (): void => {
128
96
  const data = queryData.data as ResponseError | undefined;
@@ -139,17 +107,14 @@ const useMutationQuery = <T extends object, TMeta>({
139
107
  }
140
108
  };
141
109
 
142
- useEffect(
143
- () => {
144
- manageError();
145
- },
146
- useDeepCompare([queryData.data])
147
- );
110
+ useEffect(() => {
111
+ manageError();
112
+ }, useDeepCompare([queryData.data]));
148
113
 
149
114
  return {
150
- ...omit(['isError'], queryData),
115
+ ...queryData,
151
116
  isError: (queryData.data as ResponseError | undefined)?.isError || false,
152
- isMutating: queryData.isPending
117
+ isMutating: queryData.isLoading
153
118
  };
154
119
  };
155
120
 
@@ -1,9 +1,6 @@
1
1
  import React, { ReactElement, ReactNode } from 'react';
2
2
 
3
- import {
4
- IconButton as MuiIconButton,
5
- IconButtonProps as MuiIconButtonProps
6
- } from '@mui/material';
3
+ import { IconButton as MuiIconButton } from '@mui/material';
7
4
 
8
5
  import { AriaLabelingAttributes } from '../../../@types/aria-attributes';
9
6
  import { DataTestAttributes } from '../../../@types/data-attributes';
@@ -26,8 +23,7 @@ type IconButtonProps = {
26
23
  size?: 'small' | 'medium' | 'large';
27
24
  variant?: 'primary' | 'secondary' | 'ghost';
28
25
  } & AriaLabelingAttributes &
29
- DataTestAttributes &
30
- MuiIconButtonProps;
26
+ DataTestAttributes;
31
27
 
32
28
  /**
33
29
  * @todo re-factor as `iconVariant: 'icon-only'` Button variant, and remove IconButton component (reason: code duplication)