@centreon/ui 24.4.1-MON-24235-Filter-App-token.14 → 24.4.1-MON-develop-dashboard.0
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 -1
- package/src/Dialog/Confirm/index.tsx +2 -10
- package/src/Dialog/index.tsx +1 -8
- package/src/Graph/Gauge/Gauge.cypress.spec.tsx +102 -0
- package/src/Graph/Gauge/Gauge.tsx +1 -1
- package/src/Graph/HeatMap/HeatMap.cypress.spec.tsx +145 -0
- package/src/Graph/HeatMap/HeatMap.stories.tsx +0 -25
- package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +8 -2
- package/src/Graph/LineChart/Legend/Legend.styles.ts +1 -1
- package/src/Graph/LineChart/Legend/LegendHeader.tsx +1 -1
- package/src/Graph/LineChart/Legend/useInteractiveValues.ts +2 -2
- package/src/Graph/LineChart/index.tsx +1 -1
- package/src/Graph/SingleBar/SingleBar.cypress.spec.tsx +121 -0
- package/src/Graph/Text/Text.cypress.spec.tsx +101 -0
- package/src/Graph/Text/Text.tsx +1 -1
- package/src/Graph/common/testUtils.ts +71 -0
- package/src/Graph/common/timeSeries/index.ts +19 -11
- package/src/Graph/index.ts +1 -0
- package/src/InputField/Select/Autocomplete/Multi/index.tsx +2 -4
- package/src/InputField/Select/Autocomplete/index.tsx +1 -2
- package/src/Listing/ActionBar/index.tsx +9 -8
- package/src/Listing/Cell/DataCell.styles.ts +3 -0
- package/src/Listing/Cell/DataCell.tsx +8 -4
- package/src/Listing/Listing.cypress.spec.tsx +80 -4
- package/src/Listing/Listing.styles.ts +3 -5
- package/src/Listing/index.stories.tsx +25 -2
- package/src/Listing/index.test.tsx +1 -1
- package/src/Listing/index.tsx +3 -1
- package/src/Listing/models.ts +1 -0
- package/src/api/useMutationQuery/index.test.ts +4 -4
- package/src/api/useMutationQuery/index.ts +24 -13
- package/src/components/Form/AccessRights/ShareInput/ContactSwitch.tsx +3 -3
- package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +1 -0
- package/src/components/List/Item/ListItem.tsx +3 -3
package/src/Graph/Text/Text.tsx
CHANGED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export const successThresholds = {
|
|
2
|
+
critical: [
|
|
3
|
+
{
|
|
4
|
+
label: 'Critical',
|
|
5
|
+
value: 1.5
|
|
6
|
+
}
|
|
7
|
+
],
|
|
8
|
+
enabled: true,
|
|
9
|
+
warning: [
|
|
10
|
+
{
|
|
11
|
+
label: 'Warning',
|
|
12
|
+
value: 0.5
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const warningThresholds = {
|
|
18
|
+
critical: [
|
|
19
|
+
{
|
|
20
|
+
label: 'Critical',
|
|
21
|
+
value: 1.5
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
enabled: true,
|
|
25
|
+
warning: [
|
|
26
|
+
{
|
|
27
|
+
label: 'Warning',
|
|
28
|
+
value: 0.4
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const criticalThresholds = {
|
|
34
|
+
critical: [
|
|
35
|
+
{
|
|
36
|
+
label: 'Critical',
|
|
37
|
+
value: 0.3
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
enabled: true,
|
|
41
|
+
warning: [
|
|
42
|
+
{
|
|
43
|
+
label: 'Warning',
|
|
44
|
+
value: 0.2
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const rangedThresholds = {
|
|
50
|
+
critical: [
|
|
51
|
+
{
|
|
52
|
+
label: 'Critical',
|
|
53
|
+
value: 0.55
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
label: 'Critical',
|
|
57
|
+
value: 0.65
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
enabled: true,
|
|
61
|
+
warning: [
|
|
62
|
+
{
|
|
63
|
+
label: 'Warning',
|
|
64
|
+
value: 0.13
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
label: 'Warning',
|
|
68
|
+
value: 0.5
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
};
|
|
@@ -476,15 +476,7 @@ const registerMsUnitToNumeral = (): null => {
|
|
|
476
476
|
|
|
477
477
|
registerMsUnitToNumeral();
|
|
478
478
|
|
|
479
|
-
const
|
|
480
|
-
value,
|
|
481
|
-
unit,
|
|
482
|
-
base = 1000
|
|
483
|
-
}: FormatMetricValueProps): string | null => {
|
|
484
|
-
if (isNil(value)) {
|
|
485
|
-
return null;
|
|
486
|
-
}
|
|
487
|
-
|
|
479
|
+
const getBase1024 = ({ unit, base }): boolean => {
|
|
488
480
|
const base2Units = [
|
|
489
481
|
'B',
|
|
490
482
|
'bytes',
|
|
@@ -497,7 +489,19 @@ const formatMetricValue = ({
|
|
|
497
489
|
'b'
|
|
498
490
|
];
|
|
499
491
|
|
|
500
|
-
|
|
492
|
+
return base2Units.includes(unit) || Number(base) === 1024;
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
const formatMetricValue = ({
|
|
496
|
+
value,
|
|
497
|
+
unit,
|
|
498
|
+
base = 1000
|
|
499
|
+
}: FormatMetricValueProps): string | null => {
|
|
500
|
+
if (isNil(value)) {
|
|
501
|
+
return null;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
const base1024 = getBase1024({ base, unit });
|
|
501
505
|
|
|
502
506
|
const formatSuffix = cond([
|
|
503
507
|
[equals('ms'), always(' ms')],
|
|
@@ -525,6 +529,8 @@ const formatMetricValueWithUnit = ({
|
|
|
525
529
|
return null;
|
|
526
530
|
}
|
|
527
531
|
|
|
532
|
+
const base1024 = getBase1024({ base, unit });
|
|
533
|
+
|
|
528
534
|
if (isRaw) {
|
|
529
535
|
const unitText = equals('%', unit) ? unit : ` ${unit}`;
|
|
530
536
|
|
|
@@ -537,7 +543,9 @@ const formatMetricValueWithUnit = ({
|
|
|
537
543
|
|
|
538
544
|
const formattedMetricValue = formatMetricValue({ base, unit, value });
|
|
539
545
|
|
|
540
|
-
return
|
|
546
|
+
return base1024 || !unit || equals(unit, 'ms')
|
|
547
|
+
? formattedMetricValue
|
|
548
|
+
: `${formattedMetricValue} ${unit}`;
|
|
541
549
|
};
|
|
542
550
|
|
|
543
551
|
const getStackedYScale = ({
|
package/src/Graph/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { includes, map, prop, reject
|
|
1
|
+
import { includes, map, prop, reject } from 'ramda';
|
|
2
2
|
import { makeStyles } from 'tss-react/mui';
|
|
3
3
|
|
|
4
4
|
import { Chip, ChipProps, Tooltip } from '@mui/material';
|
|
@@ -85,11 +85,9 @@ const MultiAutocompleteField = ({
|
|
|
85
85
|
return includes(id, valueIds);
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
const sortByName = sortBy(compose(toLower, prop('name')));
|
|
89
|
-
|
|
90
88
|
const autocompleteOptions = disableSortedOptions
|
|
91
89
|
? options
|
|
92
|
-
:
|
|
90
|
+
: [...values, ...reject(isOptionSelected, options)];
|
|
93
91
|
|
|
94
92
|
return (
|
|
95
93
|
<Autocomplete
|
|
@@ -216,8 +216,7 @@ const AutocompleteField = React.forwardRef(
|
|
|
216
216
|
...params.inputProps,
|
|
217
217
|
'aria-label': label,
|
|
218
218
|
'data-testid': dataTestId || label,
|
|
219
|
-
id: getNormalizedId(label || '')
|
|
220
|
-
...autocompleteProps?.inputProps
|
|
219
|
+
id: getNormalizedId(label || '')
|
|
221
220
|
}}
|
|
222
221
|
label={label}
|
|
223
222
|
placeholder={isNil(placeholder) ? t(searchLabel) : placeholder}
|
|
@@ -174,14 +174,15 @@ const MemoListingActionBar = ({
|
|
|
174
174
|
</IconButton>
|
|
175
175
|
)}
|
|
176
176
|
<div className={classes.ModeViewer} />
|
|
177
|
-
{columnConfiguration?.selectedColumnIds &&
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
177
|
+
{columnConfiguration?.selectedColumnIds &&
|
|
178
|
+
columnConfiguration?.sortable && (
|
|
179
|
+
<ColumnMultiSelect
|
|
180
|
+
columnConfiguration={columnConfiguration}
|
|
181
|
+
columns={columns}
|
|
182
|
+
onResetColumns={onResetColumns}
|
|
183
|
+
onSelectColumns={onSelectColumns}
|
|
184
|
+
/>
|
|
185
|
+
)}
|
|
185
186
|
{paginated && (
|
|
186
187
|
<StyledPagination
|
|
187
188
|
ActionsComponent={PaginationActions}
|
|
@@ -46,7 +46,7 @@ const DataCell = ({
|
|
|
46
46
|
labelCollapse,
|
|
47
47
|
labelExpand
|
|
48
48
|
}: Props): JSX.Element | null => {
|
|
49
|
-
const { classes } = useStyles();
|
|
49
|
+
const { classes, cx } = useStyles();
|
|
50
50
|
const { dataStyle } = useStyleTable({ listingVariant });
|
|
51
51
|
|
|
52
52
|
const commonCellProps = {
|
|
@@ -64,7 +64,7 @@ const DataCell = ({
|
|
|
64
64
|
|
|
65
65
|
const cellByColumnType = {
|
|
66
66
|
[ColumnType.string]: (): JSX.Element => {
|
|
67
|
-
const { getFormattedString, isTruncated, getColSpan } = column;
|
|
67
|
+
const { getFormattedString, isTruncated, getColSpan, align } = column;
|
|
68
68
|
|
|
69
69
|
const colSpan = getColSpan?.(isRowSelected);
|
|
70
70
|
|
|
@@ -87,6 +87,7 @@ const DataCell = ({
|
|
|
87
87
|
isRowHighlighted={isRowHighlighted}
|
|
88
88
|
listingVariant={listingVariant}
|
|
89
89
|
style={{
|
|
90
|
+
alignItems: align,
|
|
90
91
|
gridColumn
|
|
91
92
|
}}
|
|
92
93
|
{...commonCellProps}
|
|
@@ -99,7 +100,7 @@ const DataCell = ({
|
|
|
99
100
|
);
|
|
100
101
|
},
|
|
101
102
|
[ColumnType.component]: (): JSX.Element | null => {
|
|
102
|
-
const { getHiddenCondition, clickable } = column;
|
|
103
|
+
const { getHiddenCondition, clickable, align } = column;
|
|
103
104
|
const Component = column.Component as (
|
|
104
105
|
props: ComponentColumnProps
|
|
105
106
|
) => JSX.Element;
|
|
@@ -126,9 +127,12 @@ const DataCell = ({
|
|
|
126
127
|
|
|
127
128
|
return (
|
|
128
129
|
<Cell
|
|
129
|
-
className={classes.cell}
|
|
130
|
+
className={cx(classes.cell, clickable && classes.clickable)}
|
|
130
131
|
isRowHighlighted={isRowHighlighted}
|
|
131
132
|
listingVariant={listingVariant}
|
|
133
|
+
style={{
|
|
134
|
+
alignItems: align
|
|
135
|
+
}}
|
|
132
136
|
onClick={(e): void => {
|
|
133
137
|
if (!clickable) {
|
|
134
138
|
return;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { Button } from '@mui/material';
|
|
1
|
+
import { Button, Typography } from '@mui/material';
|
|
2
|
+
|
|
3
|
+
import { ListingVariant } from '@centreon/ui-context';
|
|
2
4
|
|
|
3
5
|
import { ColumnType } from './models';
|
|
4
6
|
|
|
@@ -12,6 +14,12 @@ const ButtonColumn = ({ row }: Props): JSX.Element => (
|
|
|
12
14
|
<Button size="small">Click to reveal details about {row.name}</Button>
|
|
13
15
|
);
|
|
14
16
|
|
|
17
|
+
const LargeText = (): JSX.Element => (
|
|
18
|
+
<Typography sx={{ whiteSpace: 'normal' }}>
|
|
19
|
+
This is a large text that fills the content
|
|
20
|
+
</Typography>
|
|
21
|
+
);
|
|
22
|
+
|
|
15
23
|
const generateSubItems = (parentIndex: number): Array<unknown> => {
|
|
16
24
|
return tenElements.map((__, subIndex) => ({
|
|
17
25
|
active: false,
|
|
@@ -37,6 +45,28 @@ const listingWithSubItems = tenElements.map((_, index) => ({
|
|
|
37
45
|
subItems: index % 2 === 0 ? generateSubItems(index) : undefined
|
|
38
46
|
}));
|
|
39
47
|
|
|
48
|
+
const defaultColumn = [
|
|
49
|
+
{
|
|
50
|
+
getFormattedString: ({ name }): string => name,
|
|
51
|
+
id: 'name',
|
|
52
|
+
label: 'Name',
|
|
53
|
+
type: ColumnType.string
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
getFormattedString: ({ description }): string => description,
|
|
57
|
+
id: 'description',
|
|
58
|
+
label: 'Description',
|
|
59
|
+
type: ColumnType.string
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
Component: LargeText,
|
|
63
|
+
id: '#',
|
|
64
|
+
label: 'Custom',
|
|
65
|
+
type: ColumnType.component,
|
|
66
|
+
width: '100px'
|
|
67
|
+
}
|
|
68
|
+
];
|
|
69
|
+
|
|
40
70
|
const columnsWithSubItems = [
|
|
41
71
|
{
|
|
42
72
|
getFormattedString: ({ name }): string => name,
|
|
@@ -62,7 +92,27 @@ const columnsWithSubItems = [
|
|
|
62
92
|
|
|
63
93
|
const expandedItems = [0, 8];
|
|
64
94
|
|
|
65
|
-
const
|
|
95
|
+
const mountListingResponsive = (listingVariant: ListingVariant): void => {
|
|
96
|
+
cy.viewport('macbook-13');
|
|
97
|
+
|
|
98
|
+
cy.mount({
|
|
99
|
+
Component: (
|
|
100
|
+
<div style={{ height: '100vh' }}>
|
|
101
|
+
<Listing
|
|
102
|
+
isResponsive
|
|
103
|
+
columns={defaultColumn}
|
|
104
|
+
currentPage={1}
|
|
105
|
+
limit={10}
|
|
106
|
+
listingVariant={listingVariant}
|
|
107
|
+
rows={listingWithSubItems}
|
|
108
|
+
totalRows={10}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
)
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const mountListingForSubItems = (): void => {
|
|
66
116
|
cy.viewport('macbook-13');
|
|
67
117
|
|
|
68
118
|
cy.mount({
|
|
@@ -89,9 +139,9 @@ const mountListing = (): void => {
|
|
|
89
139
|
};
|
|
90
140
|
|
|
91
141
|
describe('Listing', () => {
|
|
92
|
-
beforeEach(mountListing);
|
|
93
|
-
|
|
94
142
|
it('expands the row when the corresponding icon si clicked', () => {
|
|
143
|
+
mountListingForSubItems();
|
|
144
|
+
|
|
95
145
|
cy.contains('E0').should('be.visible');
|
|
96
146
|
|
|
97
147
|
expandedItems.forEach((index) => {
|
|
@@ -111,6 +161,8 @@ describe('Listing', () => {
|
|
|
111
161
|
});
|
|
112
162
|
|
|
113
163
|
it('collapses the row when the corresponding icon si clicked', () => {
|
|
164
|
+
mountListingForSubItems();
|
|
165
|
+
|
|
114
166
|
cy.contains('Sub item 100').should('be.visible');
|
|
115
167
|
|
|
116
168
|
cy.findByLabelText('Collapse 0').click();
|
|
@@ -119,4 +171,28 @@ describe('Listing', () => {
|
|
|
119
171
|
|
|
120
172
|
cy.makeSnapshot();
|
|
121
173
|
});
|
|
174
|
+
|
|
175
|
+
it('displays the last column on several lines in compact mode when the isResponsive prop is set', () => {
|
|
176
|
+
mountListingResponsive(ListingVariant.compact);
|
|
177
|
+
|
|
178
|
+
cy.get('.MuiTable-root').should(
|
|
179
|
+
'have.css',
|
|
180
|
+
'grid-template-rows',
|
|
181
|
+
'30px 85px 85px 85px 85px 85px 85px 85px 85px 85px 85px'
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
cy.makeSnapshot();
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('displays the last column on several lines in extended mode when the isResponsive prop is set', () => {
|
|
188
|
+
mountListingResponsive(ListingVariant.extended);
|
|
189
|
+
|
|
190
|
+
cy.get('.MuiTable-root').should(
|
|
191
|
+
'have.css',
|
|
192
|
+
'grid-template-rows',
|
|
193
|
+
'38px 85px 85px 85px 85px 85px 85px 85px 85px 85px 85px'
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
cy.makeSnapshot();
|
|
197
|
+
});
|
|
122
198
|
});
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { makeStyles } from 'tss-react/mui';
|
|
2
2
|
|
|
3
|
-
import { ListingVariant } from '@centreon/ui-context';
|
|
4
|
-
|
|
5
3
|
import { TableStyleAtom as TableStyle } from './models';
|
|
6
4
|
|
|
7
5
|
const loadingIndicatorHeight = 3;
|
|
@@ -9,12 +7,12 @@ const loadingIndicatorHeight = 3;
|
|
|
9
7
|
interface StylesProps {
|
|
10
8
|
dataStyle: TableStyle;
|
|
11
9
|
getGridTemplateColumn: string;
|
|
12
|
-
|
|
10
|
+
isResponsive: string;
|
|
13
11
|
rows: Array<unknown>;
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
const useListingStyles = makeStyles<StylesProps>()(
|
|
17
|
-
(theme, { dataStyle, getGridTemplateColumn, rows }) => ({
|
|
15
|
+
(theme, { dataStyle, getGridTemplateColumn, rows, isResponsive }) => ({
|
|
18
16
|
actionBar: {
|
|
19
17
|
alignItems: 'center',
|
|
20
18
|
display: 'flex'
|
|
@@ -56,7 +54,7 @@ const useListingStyles = makeStyles<StylesProps>()(
|
|
|
56
54
|
gridTemplateColumns: getGridTemplateColumn,
|
|
57
55
|
gridTemplateRows: `${theme.spacing(dataStyle.header.height / 8)} repeat(${
|
|
58
56
|
rows?.length || 1
|
|
59
|
-
}, ${dataStyle.body.height}px)`,
|
|
57
|
+
}, ${isResponsive ? 'auto' : `${dataStyle.body.height}px`})`,
|
|
60
58
|
position: 'relative'
|
|
61
59
|
},
|
|
62
60
|
tableBody: {
|
|
@@ -40,7 +40,7 @@ const useStyles = makeStyles()((theme) => ({
|
|
|
40
40
|
}));
|
|
41
41
|
|
|
42
42
|
const ComponentColumn = ({ row, isSelected }): JSX.Element => (
|
|
43
|
-
|
|
43
|
+
<div style={{ display: 'flex', flexDirection: 'row', flexWrap: 'wrap' }}>
|
|
44
44
|
<span>
|
|
45
45
|
{'I am '}
|
|
46
46
|
<b>{`${isSelected ? 'selected' : 'not selected'}`}</b>
|
|
@@ -50,7 +50,7 @@ const ComponentColumn = ({ row, isSelected }): JSX.Element => (
|
|
|
50
50
|
{'I am '}
|
|
51
51
|
<b>{`${row.active ? 'active' : 'not active'}`}</b>
|
|
52
52
|
</span>
|
|
53
|
-
|
|
53
|
+
</div>
|
|
54
54
|
);
|
|
55
55
|
|
|
56
56
|
const ButtonColumn = ({ row }): JSX.Element => (
|
|
@@ -395,3 +395,26 @@ export const ListingWithSubItems = {
|
|
|
395
395
|
},
|
|
396
396
|
render: TemplateSubItems
|
|
397
397
|
};
|
|
398
|
+
|
|
399
|
+
export const ListingWithResponsive = {
|
|
400
|
+
args: {
|
|
401
|
+
checkable: true,
|
|
402
|
+
columns: [
|
|
403
|
+
...defaultColumns,
|
|
404
|
+
{
|
|
405
|
+
Component: ComponentColumn,
|
|
406
|
+
id: '##',
|
|
407
|
+
label: 'Responsive',
|
|
408
|
+
type: ColumnType.component,
|
|
409
|
+
width: '140px'
|
|
410
|
+
}
|
|
411
|
+
],
|
|
412
|
+
currentPage: 1,
|
|
413
|
+
isResponsive: true,
|
|
414
|
+
limit: 10,
|
|
415
|
+
loading: false,
|
|
416
|
+
rows: listingWithSubItems,
|
|
417
|
+
totalRows: 10
|
|
418
|
+
},
|
|
419
|
+
render: TemplateSubItems
|
|
420
|
+
};
|
package/src/Listing/index.tsx
CHANGED
|
@@ -102,6 +102,7 @@ export interface Props<TRow> {
|
|
|
102
102
|
getId?: (row: TRow) => RowId;
|
|
103
103
|
headerMemoProps?: Array<unknown>;
|
|
104
104
|
innerScrollDisabled?: boolean;
|
|
105
|
+
isResponsive?: boolean;
|
|
105
106
|
limit?: number;
|
|
106
107
|
listingVariant?: ListingVariant;
|
|
107
108
|
loading?: boolean;
|
|
@@ -147,6 +148,7 @@ const Listing = <TRow extends { id: RowId }>({
|
|
|
147
148
|
columns,
|
|
148
149
|
columnConfiguration = defaultColumnConfiguration,
|
|
149
150
|
customPaginationClassName,
|
|
151
|
+
isResponsive = false,
|
|
150
152
|
onResetColumns,
|
|
151
153
|
onSelectColumns,
|
|
152
154
|
rows = [],
|
|
@@ -233,7 +235,7 @@ const Listing = <TRow extends { id: RowId }>({
|
|
|
233
235
|
const { classes } = useListingStyles({
|
|
234
236
|
dataStyle,
|
|
235
237
|
getGridTemplateColumn,
|
|
236
|
-
|
|
238
|
+
isResponsive,
|
|
237
239
|
rows: rowsToDisplay
|
|
238
240
|
});
|
|
239
241
|
|
package/src/Listing/models.ts
CHANGED
|
@@ -48,7 +48,7 @@ describe('useFetchQuery', () => {
|
|
|
48
48
|
method: Method.POST
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
result.current.mutate(user);
|
|
51
|
+
result.current.mutate({ payload: 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(user);
|
|
67
|
+
result.current.mutate({ payload: 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(user);
|
|
88
|
+
result.current.mutate({ payload: 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(user);
|
|
112
|
+
result.current.mutate({ payload: user });
|
|
113
113
|
|
|
114
114
|
await waitFor(() => {
|
|
115
115
|
expect(mockedShowErrorMessage).not.toHaveBeenCalled();
|
|
@@ -22,6 +22,11 @@ export enum Method {
|
|
|
22
22
|
PUT = 'PUT'
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
interface Variables<TMeta, T> {
|
|
26
|
+
_meta?: TMeta;
|
|
27
|
+
payload?: T;
|
|
28
|
+
}
|
|
29
|
+
|
|
25
30
|
export type UseMutationQueryProps<T, TMeta> = {
|
|
26
31
|
baseEndpoint?: string;
|
|
27
32
|
catchError?: (props: CatchErrorProps) => void;
|
|
@@ -33,30 +38,36 @@ export type UseMutationQueryProps<T, TMeta> = {
|
|
|
33
38
|
method: Method;
|
|
34
39
|
onError?: (
|
|
35
40
|
error: ResponseError,
|
|
36
|
-
variables:
|
|
41
|
+
variables: Variables<TMeta, T>,
|
|
37
42
|
context: unknown
|
|
38
43
|
) => unknown;
|
|
39
|
-
onMutate?: (variables:
|
|
44
|
+
onMutate?: (variables: Variables<TMeta, T>) => Promise<unknown> | unknown;
|
|
40
45
|
onSuccess?: (
|
|
41
46
|
data: ResponseError | T,
|
|
42
|
-
variables: T
|
|
43
|
-
_meta: TMeta;
|
|
44
|
-
},
|
|
47
|
+
variables: Variables<TMeta, T>,
|
|
45
48
|
context: unknown
|
|
46
49
|
) => unknown;
|
|
47
50
|
} & Omit<
|
|
48
|
-
UseMutationOptions<
|
|
49
|
-
'mutationFn' | 'onError' | 'onMutate' | 'onSuccess'
|
|
51
|
+
UseMutationOptions<{ _meta?: TMeta; payload: T }>,
|
|
52
|
+
'mutationFn' | 'onError' | 'onMutate' | 'onSuccess' | 'mutateAsync' | 'mutate'
|
|
50
53
|
>;
|
|
51
54
|
|
|
52
55
|
const log = anylogger('API Request');
|
|
53
56
|
|
|
54
|
-
export type UseMutationQueryState<T> = Omit<
|
|
57
|
+
export type UseMutationQueryState<T, TMeta> = Omit<
|
|
55
58
|
UseMutationResult<T | ResponseError>,
|
|
56
|
-
'isError'
|
|
59
|
+
'isError' | 'mutate' | 'mutateAsync'
|
|
57
60
|
> & {
|
|
58
61
|
isError: boolean;
|
|
59
62
|
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>;
|
|
60
71
|
};
|
|
61
72
|
|
|
62
73
|
const useMutationQuery = <T extends object, TMeta>({
|
|
@@ -72,18 +83,18 @@ const useMutationQuery = <T extends object, TMeta>({
|
|
|
72
83
|
onSuccess,
|
|
73
84
|
onSettled,
|
|
74
85
|
baseEndpoint
|
|
75
|
-
}: UseMutationQueryProps<T, TMeta>): UseMutationQueryState<T> => {
|
|
86
|
+
}: UseMutationQueryProps<T, TMeta>): UseMutationQueryState<T, TMeta> => {
|
|
76
87
|
const { showErrorMessage } = useSnackbar();
|
|
77
88
|
|
|
78
89
|
const queryData = useMutation<
|
|
79
90
|
T | ResponseError,
|
|
80
91
|
ResponseError,
|
|
81
|
-
|
|
92
|
+
Variables<TMeta, T>
|
|
82
93
|
>({
|
|
83
94
|
mutationFn: (
|
|
84
|
-
|
|
95
|
+
variables: Variables<TMeta, T>
|
|
85
96
|
): Promise<T | ResponseError> => {
|
|
86
|
-
const { _meta,
|
|
97
|
+
const { _meta, payload } = variables || {};
|
|
87
98
|
|
|
88
99
|
return customFetch<T>({
|
|
89
100
|
baseEndpoint,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useAtom } from 'jotai';
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
3
|
|
|
4
4
|
import { FormControlLabel, Radio, RadioGroup } from '@mui/material';
|
|
@@ -17,7 +17,7 @@ const ContactSwitch = ({ labels }: Props): JSX.Element => {
|
|
|
17
17
|
const { classes } = useContactSwitchStyles();
|
|
18
18
|
const { t } = useTranslation();
|
|
19
19
|
|
|
20
|
-
const setContactType =
|
|
20
|
+
const [contactType, setContactType] = useAtom(contactTypeAtom);
|
|
21
21
|
|
|
22
22
|
const change = (event: React.ChangeEvent<HTMLInputElement>): void => {
|
|
23
23
|
setContactType(event.target.value as ContactType);
|
|
@@ -29,7 +29,7 @@ const ContactSwitch = ({ labels }: Props): JSX.Element => {
|
|
|
29
29
|
<RadioGroup
|
|
30
30
|
row
|
|
31
31
|
className={classes.inputs}
|
|
32
|
-
|
|
32
|
+
value={contactType}
|
|
33
33
|
onChange={change}
|
|
34
34
|
>
|
|
35
35
|
<FormControlLabel
|
|
@@ -52,6 +52,7 @@ const ShareInput = ({ labels, endpoints, roles }: Props): JSX.Element => {
|
|
|
52
52
|
? t(labels.autocompleteContactGroup)
|
|
53
53
|
: t(labels.autocompleteContact)
|
|
54
54
|
)}
|
|
55
|
+
queryKey={isContactGroup ? labels.contactGroup : labels.contact}
|
|
55
56
|
renderOption={renderOption}
|
|
56
57
|
value={selectedContact}
|
|
57
58
|
onChange={selectContact}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ForwardedRef, forwardRef, ReactElement, ReactNode } from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { ListItem as MuiListItem } from '@mui/material';
|
|
4
4
|
|
|
5
5
|
import { useStyles } from './ListItem.styles';
|
|
6
6
|
|
|
7
|
-
type
|
|
7
|
+
type ListItemProps = {
|
|
8
8
|
action?: ReactElement;
|
|
9
9
|
children: ReactNode | Array<ReactNode>;
|
|
10
10
|
className?: string;
|
|
@@ -12,7 +12,7 @@ type Props = {
|
|
|
12
12
|
|
|
13
13
|
export const ListItem = forwardRef(
|
|
14
14
|
(
|
|
15
|
-
{ action, children, className, ...attr }:
|
|
15
|
+
{ action, children, className, ...attr }: ListItemProps,
|
|
16
16
|
ref?: ForwardedRef<HTMLLIElement>
|
|
17
17
|
) => {
|
|
18
18
|
const { classes, cx } = useStyles();
|