@centreon/ui 25.10.28 → 25.10.30
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 +3 -3
- package/public/mockServiceWorker.js +8 -31
- package/src/Dashboard/Item.tsx +142 -149
- package/src/Form/Inputs/ConnectedAutocomplete.tsx +2 -0
- package/src/Form/Inputs/Grid.tsx +2 -3
- package/src/Form/Inputs/models.ts +2 -0
- package/src/Form/Section/navigateToSection.ts +6 -6
- package/src/Graph/BarChart/BarChart.cypress.spec.tsx +55 -102
- package/src/Graph/BarChart/BarChart.stories.tsx +1 -51
- package/src/Graph/BarChart/BarChart.tsx +1 -1
- package/src/Graph/BarChart/BarGroup.tsx +32 -22
- package/src/Graph/BarChart/BarStack.tsx +26 -15
- package/src/Graph/BarChart/MemoizedGroup.tsx +18 -14
- package/src/Graph/BarChart/ResponsiveBarChart.tsx +6 -7
- package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +2 -2
- package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +5 -4
- package/src/Graph/Chart/BasicComponents/Lines/StackedLines/useStackedLines.ts +45 -18
- package/src/Graph/Chart/BasicComponents/Lines/index.tsx +118 -124
- package/src/Graph/Chart/Chart.cypress.spec.tsx +6 -25
- package/src/Graph/Chart/Chart.stories.tsx +1 -43
- package/src/Graph/Chart/Chart.tsx +13 -9
- package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +4 -2
- package/src/Graph/Chart/Legend/index.tsx +2 -26
- package/src/Graph/Chart/index.tsx +45 -31
- package/src/Graph/Chart/models.ts +1 -6
- package/src/Graph/Chart/translatedLabels.ts +1 -0
- package/src/Graph/Chart/useChartData.ts +24 -3
- package/src/Graph/common/Axes/index.tsx +1 -1
- package/src/Graph/common/BaseChart/BaseChart.tsx +1 -6
- package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +23 -16
- package/src/Graph/common/Error/NoData.tsx +18 -0
- package/src/Graph/common/Grids/index.tsx +4 -4
- package/src/Graph/common/timeSeries/index.test.ts +4 -24
- package/src/Graph/common/timeSeries/index.ts +120 -184
- package/src/Graph/common/timeSeries/models.ts +1 -1
- package/src/Graph/common/utils.ts +4 -10
- package/src/Graph/index.ts +20 -20
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +9 -9
- package/src/InputField/Select/Autocomplete/Multi/Listbox.tsx +11 -3
- package/src/InputField/Select/Autocomplete/Multi/Multi.tsx +3 -2
- package/src/InputField/Select/Autocomplete/index.tsx +28 -17
- package/src/InputField/Select/Option.tsx +3 -3
- package/src/InputField/Select/index.tsx +2 -1
- package/src/Listing/ActionBar/Pagination.tsx +2 -1
- package/src/Listing/ActionBar/index.tsx +113 -8
- package/src/Listing/index.tsx +19 -2
- package/src/Listing/translatedLabels.ts +4 -0
- package/src/Module/index.tsx +2 -8
- package/src/ThemeProvider/index.tsx +21 -30
- package/src/ThemeProvider/tailwindcss.css +12 -10
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +8 -5
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +0 -1
- package/src/api/useGraphQuery/index.ts +7 -4
- package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +4 -3
- package/src/components/Form/AccessRights/ShareInput/useShareInput.tsx +15 -10
- package/src/components/Layout/PageLayout/PageLayout.tsx +3 -9
- package/src/components/Layout/PageLayout/PageLayoutActions.tsx +3 -5
- package/src/components/Layout/PageLayout/PageLayoutBody.tsx +3 -5
- package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +3 -5
- package/src/components/Layout/PageLayout/PageQuickAccess.tsx +44 -25
- package/src/components/Layout/PageLayout/translatedLabels.ts +1 -0
- package/src/components/Menu/Button/MenuButton.styles.ts +27 -0
- package/src/components/Menu/Button/MenuButton.tsx +5 -8
- package/src/components/Menu/Menu.styles.ts +68 -0
- package/src/components/Menu/MenuDivider.tsx +5 -1
- package/src/components/Menu/MenuItem.tsx +5 -1
- package/src/components/Menu/MenuItems.tsx +4 -5
- package/src/components/Modal/Modal.styles.ts +2 -1
- package/src/components/Modal/ModalHeader.tsx +1 -5
- package/src/utils/useInfiniteScrollListing.ts +11 -7
- package/src/utils/useViewportIntersection.ts +3 -4
- package/src/Graph/mockedData/dataWithMissingPoint.json +0 -74
- package/src/Graph/mockedData/pingServiceWithStackedKeys.json +0 -205
|
@@ -13,6 +13,7 @@ import { AutocompleteSlotsAndSlotProps } from '@mui/material/Autocomplete';
|
|
|
13
13
|
import { TextFieldSlotsAndSlotProps } from '@mui/material/TextField';
|
|
14
14
|
import { UseAutocompleteProps } from '@mui/material/useAutocomplete';
|
|
15
15
|
|
|
16
|
+
import type { AutocompleteRenderOptionState } from '@mui/material/Autocomplete';
|
|
16
17
|
import { ForwardedRef, HTMLAttributes, ReactElement, forwardRef } from 'react';
|
|
17
18
|
import { SelectEntry } from '..';
|
|
18
19
|
import { getNormalizedId } from '../../../utils';
|
|
@@ -33,6 +34,11 @@ export type Props = {
|
|
|
33
34
|
error?: string;
|
|
34
35
|
getOptionItemLabel?: (option) => string;
|
|
35
36
|
hideInput?: boolean;
|
|
37
|
+
renderOption?: (
|
|
38
|
+
renderProps: HTMLAttributes<HTMLLIElement>,
|
|
39
|
+
option: SelectEntry,
|
|
40
|
+
state: AutocompleteRenderOptionState
|
|
41
|
+
) => ReactElement;
|
|
36
42
|
label: string;
|
|
37
43
|
loading?: boolean;
|
|
38
44
|
onTextChange?;
|
|
@@ -52,7 +58,7 @@ export type Props = {
|
|
|
52
58
|
> &
|
|
53
59
|
UseAutocompleteProps<SelectEntry, Multiple, DisableClearable, FreeSolo>;
|
|
54
60
|
|
|
55
|
-
const LoadingIndicator = ():
|
|
61
|
+
const LoadingIndicator = (): ReactElement => {
|
|
56
62
|
const { classes } = useAutoCompleteStyles({});
|
|
57
63
|
|
|
58
64
|
return (
|
|
@@ -90,10 +96,11 @@ const AutocompleteField = forwardRef(
|
|
|
90
96
|
forceInputRenderValue = false,
|
|
91
97
|
textFieldSlotsAndSlotProps,
|
|
92
98
|
autocompleteSlotsAndSlotProps,
|
|
99
|
+
renderOption,
|
|
93
100
|
...autocompleteProps
|
|
94
101
|
}: Props,
|
|
95
102
|
ref?: ForwardedRef<HTMLDivElement>
|
|
96
|
-
):
|
|
103
|
+
): ReactElement => {
|
|
97
104
|
const { classes, cx } = useAutoCompleteStyles({ hideInput });
|
|
98
105
|
const { t } = useTranslation();
|
|
99
106
|
const theme = useTheme();
|
|
@@ -107,7 +114,24 @@ const AutocompleteField = forwardRef(
|
|
|
107
114
|
);
|
|
108
115
|
};
|
|
109
116
|
|
|
110
|
-
const
|
|
117
|
+
const renderOptions = renderOption
|
|
118
|
+
? renderOption
|
|
119
|
+
: (props, option): ReactElement => {
|
|
120
|
+
return (
|
|
121
|
+
<li
|
|
122
|
+
className={classes.options}
|
|
123
|
+
{...(props as HTMLAttributes<HTMLLIElement>)}
|
|
124
|
+
>
|
|
125
|
+
<Option
|
|
126
|
+
thumbnailUrl={displayOptionThumbnail ? option.url : undefined}
|
|
127
|
+
>
|
|
128
|
+
{getOptionItemLabel(option)}
|
|
129
|
+
</Option>
|
|
130
|
+
</li>
|
|
131
|
+
);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const renderInput = (params): ReactElement => {
|
|
111
135
|
return (
|
|
112
136
|
<TextField
|
|
113
137
|
{...params}
|
|
@@ -202,20 +226,7 @@ const AutocompleteField = forwardRef(
|
|
|
202
226
|
options={options}
|
|
203
227
|
ref={ref}
|
|
204
228
|
renderInput={renderInput}
|
|
205
|
-
renderOption={
|
|
206
|
-
return (
|
|
207
|
-
<li
|
|
208
|
-
className={classes.options}
|
|
209
|
-
{...(props as HTMLAttributes<HTMLLIElement>)}
|
|
210
|
-
>
|
|
211
|
-
<Option
|
|
212
|
-
thumbnailUrl={displayOptionThumbnail ? option.url : undefined}
|
|
213
|
-
>
|
|
214
|
-
{getOptionItemLabel(option)}
|
|
215
|
-
</Option>
|
|
216
|
-
</li>
|
|
217
|
-
);
|
|
218
|
-
}}
|
|
229
|
+
renderOption={renderOptions}
|
|
219
230
|
size="small"
|
|
220
231
|
slotProps={{
|
|
221
232
|
...autocompleteSlotsAndSlotProps?.slotProps,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RefObject, forwardRef } from 'react';
|
|
1
|
+
import { ReactElement, RefObject, forwardRef } from 'react';
|
|
2
2
|
|
|
3
3
|
import { equals, isNil } from 'ramda';
|
|
4
4
|
import { makeStyles } from 'tss-react/mui';
|
|
@@ -28,12 +28,12 @@ const useStyles = makeStyles()((theme) => ({
|
|
|
28
28
|
|
|
29
29
|
interface Props {
|
|
30
30
|
checkboxSelected?: boolean;
|
|
31
|
-
children: string;
|
|
31
|
+
children: string | ReactElement;
|
|
32
32
|
thumbnailUrl?: string;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const Option = forwardRef(
|
|
36
|
-
({ children, checkboxSelected, thumbnailUrl }: Props, ref):
|
|
36
|
+
({ children, checkboxSelected, thumbnailUrl }: Props, ref): ReactElement => {
|
|
37
37
|
const { classes } = useStyles();
|
|
38
38
|
|
|
39
39
|
return (
|
|
@@ -96,6 +96,7 @@ const SelectField = ({
|
|
|
96
96
|
fullWidth={fullWidth}
|
|
97
97
|
size="small"
|
|
98
98
|
{...formControlProps}
|
|
99
|
+
|
|
99
100
|
>
|
|
100
101
|
{label && <InputLabel>{label}</InputLabel>}
|
|
101
102
|
<Select
|
|
@@ -150,4 +151,4 @@ const SelectField = ({
|
|
|
150
151
|
);
|
|
151
152
|
};
|
|
152
153
|
|
|
153
|
-
export default SelectField;
|
|
154
|
+
export default SelectField;
|
|
@@ -22,7 +22,8 @@ const MemoizedPagination = memo(
|
|
|
22
22
|
equals(prevProps.page, nextProps.page) &&
|
|
23
23
|
equals(prevProps.count, nextProps.count) &&
|
|
24
24
|
equals(prevProps.labelRowsPerPage, nextProps.labelRowsPerPage) &&
|
|
25
|
-
equals(prevProps.className, nextProps.className)
|
|
25
|
+
equals(prevProps.className, nextProps.className) &&
|
|
26
|
+
prevProps.labelDisplayedRows === nextProps.labelDisplayedRows
|
|
26
27
|
);
|
|
27
28
|
|
|
28
29
|
export default MemoizedPagination;
|
|
@@ -5,13 +5,32 @@ import { makeStyles } from 'tss-react/mui';
|
|
|
5
5
|
|
|
6
6
|
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
|
|
7
7
|
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
|
|
8
|
+
import CircularProgress from '@mui/material/CircularProgress';
|
|
8
9
|
import Divider from '@mui/material/Divider';
|
|
10
|
+
import Tooltip from '@mui/material/Tooltip';
|
|
9
11
|
|
|
10
12
|
import { ListingVariant, userAtom } from '@centreon/ui-context';
|
|
11
13
|
|
|
12
|
-
import {
|
|
14
|
+
import { useAtomValue } from 'jotai';
|
|
15
|
+
import { equals, isEmpty, isNil, not, pick } from 'ramda';
|
|
16
|
+
import {
|
|
17
|
+
type ChangeEvent,
|
|
18
|
+
type MouseEvent,
|
|
19
|
+
type ReactNode,
|
|
20
|
+
useCallback
|
|
21
|
+
} from 'react';
|
|
22
|
+
import { useTranslation } from 'react-i18next';
|
|
23
|
+
import { makeStyles } from 'tss-react/mui';
|
|
24
|
+
|
|
25
|
+
import { IconButton, type ListingProps } from '../..';
|
|
13
26
|
import { useMemoComponent } from '../../utils';
|
|
14
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
labelApproximateCount,
|
|
29
|
+
labelApproximateCountTooltip,
|
|
30
|
+
labelComputingExactCount,
|
|
31
|
+
labelOf,
|
|
32
|
+
labelRowsPerPage
|
|
33
|
+
} from '../translatedLabels';
|
|
15
34
|
|
|
16
35
|
import ColumnMultiSelect from './ColumnMultiSelect';
|
|
17
36
|
import StyledPagination from './Pagination';
|
|
@@ -88,6 +107,9 @@ type Props = Pick<
|
|
|
88
107
|
| 'customPaginationClassName'
|
|
89
108
|
| 'listingVariant'
|
|
90
109
|
| 'viewerModeConfiguration'
|
|
110
|
+
| 'approximateTotalRows'
|
|
111
|
+
| 'onApproximateCountClick'
|
|
112
|
+
| 'isApproximateCountLoading'
|
|
91
113
|
>;
|
|
92
114
|
|
|
93
115
|
const MemoListingActionBar = ({
|
|
@@ -107,7 +129,10 @@ const MemoListingActionBar = ({
|
|
|
107
129
|
widthToMoveTablePagination = 550,
|
|
108
130
|
actionsBarMemoProps = [],
|
|
109
131
|
viewerModeConfiguration,
|
|
110
|
-
listingVariant
|
|
132
|
+
listingVariant,
|
|
133
|
+
approximateTotalRows = false,
|
|
134
|
+
onApproximateCountClick,
|
|
135
|
+
isApproximateCountLoading = false
|
|
111
136
|
}: Props): JSX.Element => {
|
|
112
137
|
const marginWidthTableListing = 30;
|
|
113
138
|
const { classes, cx } = useStyles({
|
|
@@ -118,17 +143,89 @@ const MemoListingActionBar = ({
|
|
|
118
143
|
|
|
119
144
|
const { themeMode } = useAtomValue(userAtom);
|
|
120
145
|
|
|
121
|
-
const changeRowPerPage = (
|
|
146
|
+
const changeRowPerPage = (
|
|
147
|
+
event: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
|
|
148
|
+
): void => {
|
|
122
149
|
onLimitChange?.(event.target.value);
|
|
123
150
|
onPaginate?.(0);
|
|
124
151
|
};
|
|
125
152
|
|
|
126
|
-
const changePage = (
|
|
153
|
+
const changePage = (
|
|
154
|
+
_: MouseEvent<HTMLButtonElement> | null,
|
|
155
|
+
value: number
|
|
156
|
+
): void => {
|
|
127
157
|
onPaginate?.(value);
|
|
128
158
|
};
|
|
129
159
|
|
|
130
|
-
const labelDisplayedRows = (
|
|
131
|
-
|
|
160
|
+
const labelDisplayedRows = useCallback(
|
|
161
|
+
({
|
|
162
|
+
from,
|
|
163
|
+
to,
|
|
164
|
+
count
|
|
165
|
+
}: {
|
|
166
|
+
count: number;
|
|
167
|
+
from: number;
|
|
168
|
+
to: number;
|
|
169
|
+
}): ReactNode => {
|
|
170
|
+
const range = `${from}-${to} ${t(labelOf)} `;
|
|
171
|
+
|
|
172
|
+
if (!approximateTotalRows) {
|
|
173
|
+
return `${range}${count}`;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (isApproximateCountLoading) {
|
|
177
|
+
return (
|
|
178
|
+
<span
|
|
179
|
+
style={{ alignItems: 'center', display: 'inline-flex', gap: 4 }}
|
|
180
|
+
>
|
|
181
|
+
{range}
|
|
182
|
+
<CircularProgress size={10} />
|
|
183
|
+
<span>{t(labelComputingExactCount)}</span>
|
|
184
|
+
</span>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const approximateLabel = (
|
|
189
|
+
<button
|
|
190
|
+
onClick={onApproximateCountClick}
|
|
191
|
+
style={{
|
|
192
|
+
background: 'none',
|
|
193
|
+
border: 'none',
|
|
194
|
+
color: 'inherit',
|
|
195
|
+
cursor: onApproximateCountClick ? 'pointer' : 'default',
|
|
196
|
+
font: 'inherit',
|
|
197
|
+
fontWeight: 600,
|
|
198
|
+
padding: 0,
|
|
199
|
+
textDecoration: onApproximateCountClick
|
|
200
|
+
? 'underline dotted'
|
|
201
|
+
: 'none'
|
|
202
|
+
}}
|
|
203
|
+
type="button"
|
|
204
|
+
>
|
|
205
|
+
{t(labelApproximateCount)}
|
|
206
|
+
</button>
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
<span>
|
|
211
|
+
{range}
|
|
212
|
+
{onApproximateCountClick ? (
|
|
213
|
+
<Tooltip title={t(labelApproximateCountTooltip)}>
|
|
214
|
+
{approximateLabel}
|
|
215
|
+
</Tooltip>
|
|
216
|
+
) : (
|
|
217
|
+
approximateLabel
|
|
218
|
+
)}
|
|
219
|
+
</span>
|
|
220
|
+
);
|
|
221
|
+
},
|
|
222
|
+
[
|
|
223
|
+
approximateTotalRows,
|
|
224
|
+
isApproximateCountLoading,
|
|
225
|
+
onApproximateCountClick,
|
|
226
|
+
t
|
|
227
|
+
]
|
|
228
|
+
);
|
|
132
229
|
|
|
133
230
|
return useMemoComponent({
|
|
134
231
|
Component: (
|
|
@@ -223,6 +320,8 @@ const MemoListingActionBar = ({
|
|
|
223
320
|
),
|
|
224
321
|
columnConfiguration,
|
|
225
322
|
customPaginationClassName,
|
|
323
|
+
approximateTotalRows,
|
|
324
|
+
isApproximateCountLoading,
|
|
226
325
|
...actionsBarMemoProps
|
|
227
326
|
]
|
|
228
327
|
});
|
|
@@ -245,7 +344,10 @@ const ListingActionBar = ({
|
|
|
245
344
|
widthToMoveTablePagination,
|
|
246
345
|
customPaginationClassName,
|
|
247
346
|
listingVariant,
|
|
248
|
-
viewerModeConfiguration
|
|
347
|
+
viewerModeConfiguration,
|
|
348
|
+
approximateTotalRows,
|
|
349
|
+
onApproximateCountClick,
|
|
350
|
+
isApproximateCountLoading
|
|
249
351
|
}: Props): JSX.Element | null => {
|
|
250
352
|
if (
|
|
251
353
|
not(paginated) &&
|
|
@@ -259,13 +361,16 @@ const ListingActionBar = ({
|
|
|
259
361
|
<MemoListingActionBar
|
|
260
362
|
actions={actions}
|
|
261
363
|
actionsBarMemoProps={actionsBarMemoProps}
|
|
364
|
+
approximateTotalRows={approximateTotalRows}
|
|
262
365
|
columnConfiguration={columnConfiguration}
|
|
263
366
|
columns={columns}
|
|
264
367
|
currentPage={currentPage}
|
|
265
368
|
customPaginationClassName={customPaginationClassName}
|
|
369
|
+
isApproximateCountLoading={isApproximateCountLoading}
|
|
266
370
|
limit={limit}
|
|
267
371
|
listingVariant={listingVariant}
|
|
268
372
|
moveTablePagination={moveTablePagination}
|
|
373
|
+
onApproximateCountClick={onApproximateCountClick}
|
|
269
374
|
paginated={paginated}
|
|
270
375
|
totalRows={totalRows}
|
|
271
376
|
viewerModeConfiguration={viewerModeConfiguration}
|
package/src/Listing/index.tsx
CHANGED
|
@@ -134,6 +134,9 @@ export interface Props<TRow> {
|
|
|
134
134
|
labelExpand: string;
|
|
135
135
|
};
|
|
136
136
|
totalRows?: number;
|
|
137
|
+
approximateTotalRows?: boolean;
|
|
138
|
+
onApproximateCountClick?: () => void;
|
|
139
|
+
isApproximateCountLoading?: boolean;
|
|
137
140
|
viewerModeConfiguration?: ViewerModeConfiguration;
|
|
138
141
|
widthToMoveTablePagination?: number;
|
|
139
142
|
isActionBarVisible: boolean;
|
|
@@ -198,7 +201,10 @@ const Listing = <
|
|
|
198
201
|
labelExpand: 'Expand'
|
|
199
202
|
},
|
|
200
203
|
isActionBarVisible = true,
|
|
201
|
-
labelNoResultFound = defaultLabelNoResultFound
|
|
204
|
+
labelNoResultFound = defaultLabelNoResultFound,
|
|
205
|
+
approximateTotalRows = false,
|
|
206
|
+
onApproximateCountClick,
|
|
207
|
+
isApproximateCountLoading = false
|
|
202
208
|
}: Props<TRow>): JSX.Element => {
|
|
203
209
|
const currentVisibleColumns = getVisibleColumns({
|
|
204
210
|
columnConfiguration,
|
|
@@ -527,13 +533,16 @@ const Listing = <
|
|
|
527
533
|
<ListingActionBar
|
|
528
534
|
actions={actions}
|
|
529
535
|
actionsBarMemoProps={actionsBarMemoProps}
|
|
536
|
+
approximateTotalRows={approximateTotalRows}
|
|
530
537
|
columnConfiguration={columnConfiguration}
|
|
531
538
|
columns={columns}
|
|
532
539
|
currentPage={currentPage}
|
|
533
540
|
customPaginationClassName={customPaginationClassName}
|
|
541
|
+
isApproximateCountLoading={isApproximateCountLoading}
|
|
534
542
|
limit={limit}
|
|
535
543
|
listingVariant={listingVariant}
|
|
536
544
|
moveTablePagination={moveTablePagination}
|
|
545
|
+
onApproximateCountClick={onApproximateCountClick}
|
|
537
546
|
paginated={paginated}
|
|
538
547
|
totalRows={totalRows}
|
|
539
548
|
viewerModeConfiguration={viewerModeConfiguration}
|
|
@@ -748,20 +757,26 @@ export const MemoizedListing = <TRow extends { id: string | number }>({
|
|
|
748
757
|
widthToMoveTablePagination,
|
|
749
758
|
listingVariant,
|
|
750
759
|
labelNoResultFound,
|
|
760
|
+
approximateTotalRows,
|
|
761
|
+
onApproximateCountClick,
|
|
762
|
+
isApproximateCountLoading,
|
|
751
763
|
...props
|
|
752
764
|
}: MemoizedListingProps<TRow>): JSX.Element =>
|
|
753
765
|
useMemoComponent({
|
|
754
766
|
Component: (
|
|
755
767
|
<Listing
|
|
768
|
+
approximateTotalRows={approximateTotalRows}
|
|
756
769
|
checkable={checkable}
|
|
757
770
|
columnConfiguration={columnConfiguration}
|
|
758
771
|
columns={columns}
|
|
759
772
|
currentPage={currentPage}
|
|
760
773
|
innerScrollDisabled={innerScrollDisabled}
|
|
774
|
+
isApproximateCountLoading={isApproximateCountLoading}
|
|
761
775
|
limit={limit}
|
|
762
776
|
listingVariant={listingVariant}
|
|
763
777
|
loading={loading}
|
|
764
778
|
moveTablePagination={moveTablePagination}
|
|
779
|
+
onApproximateCountClick={onApproximateCountClick}
|
|
765
780
|
paginated={paginated}
|
|
766
781
|
rowColorConditions={rowColorConditions}
|
|
767
782
|
rows={rows}
|
|
@@ -794,7 +809,9 @@ export const MemoizedListing = <TRow extends { id: string | number }>({
|
|
|
794
809
|
sortField,
|
|
795
810
|
innerScrollDisabled,
|
|
796
811
|
listingVariant,
|
|
797
|
-
labelNoResultFound
|
|
812
|
+
labelNoResultFound,
|
|
813
|
+
approximateTotalRows,
|
|
814
|
+
isApproximateCountLoading
|
|
798
815
|
]
|
|
799
816
|
});
|
|
800
817
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export const labelTo = 'to';
|
|
2
2
|
export const labelNoResultFound = 'No result found';
|
|
3
3
|
export const labelOf = 'of';
|
|
4
|
+
export const labelApproximateCount = '1,000+';
|
|
5
|
+
export const labelApproximateCountTooltip =
|
|
6
|
+
'More than 1,000 resources match your search. Click to continue.';
|
|
7
|
+
export const labelComputingExactCount = 'Loading...';
|
|
4
8
|
export const labelRowsPerPage = 'Rows per page';
|
|
5
9
|
export const labelFirstPage = 'First page';
|
|
6
10
|
export const labelLastPage = 'Last page';
|
package/src/Module/index.tsx
CHANGED
|
@@ -3,7 +3,6 @@ import { Provider as JotaiProvider, createStore } from 'jotai';
|
|
|
3
3
|
|
|
4
4
|
import { StylesProvider, createGenerateClassName } from '@mui/styles';
|
|
5
5
|
|
|
6
|
-
import { ThemeOptions } from '@mui/material';
|
|
7
6
|
import { QueryProvider, ThemeProvider } from '..';
|
|
8
7
|
import SnackbarProvider from '../Snackbar/SnackbarProvider';
|
|
9
8
|
|
|
@@ -13,10 +12,6 @@ export interface ModuleProps {
|
|
|
13
12
|
queryClient?: QueryClient;
|
|
14
13
|
seedName: string;
|
|
15
14
|
store: ReturnType<typeof createStore>;
|
|
16
|
-
overrideTheme?: {
|
|
17
|
-
light: Partial<ThemeOptions>;
|
|
18
|
-
dark: Partial<ThemeOptions>;
|
|
19
|
-
};
|
|
20
15
|
}
|
|
21
16
|
|
|
22
17
|
const Module = ({
|
|
@@ -24,8 +19,7 @@ const Module = ({
|
|
|
24
19
|
seedName,
|
|
25
20
|
maxSnackbars = 3,
|
|
26
21
|
store,
|
|
27
|
-
queryClient
|
|
28
|
-
overrideTheme
|
|
22
|
+
queryClient
|
|
29
23
|
}: ModuleProps): JSX.Element => {
|
|
30
24
|
const generateClassName = createGenerateClassName({
|
|
31
25
|
seed: seedName
|
|
@@ -35,7 +29,7 @@ const Module = ({
|
|
|
35
29
|
<QueryProvider queryClient={queryClient}>
|
|
36
30
|
<JotaiProvider store={store}>
|
|
37
31
|
<StylesProvider generateClassName={generateClassName}>
|
|
38
|
-
<ThemeProvider
|
|
32
|
+
<ThemeProvider>
|
|
39
33
|
<SnackbarProvider maxSnackbars={maxSnackbars}>
|
|
40
34
|
{children}
|
|
41
35
|
</SnackbarProvider>
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { useAtomValue } from 'jotai';
|
|
2
|
-
import { equals
|
|
2
|
+
import { equals } from 'ramda';
|
|
3
3
|
import { CSSInterpolation } from 'tss-react';
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
ButtonProps,
|
|
7
7
|
InputBaseProps,
|
|
8
8
|
ThemeProvider as MuiThemeProvider,
|
|
9
|
-
PaletteOptions,
|
|
10
9
|
StyledEngineProvider,
|
|
11
10
|
Theme,
|
|
12
11
|
createTheme
|
|
@@ -27,7 +26,7 @@ import { ReactNode, useMemo } from 'react';
|
|
|
27
26
|
import { getPalette } from './palettes';
|
|
28
27
|
|
|
29
28
|
declare module '@mui/styles/defaultTheme' {
|
|
30
|
-
interface DefaultTheme extends Theme {}
|
|
29
|
+
interface DefaultTheme extends Theme { }
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
declare module '@mui/material/TextField' {
|
|
@@ -199,14 +198,14 @@ export const getTheme = (mode: ThemeMode): ThemeOptions => ({
|
|
|
199
198
|
styleOverrides: {
|
|
200
199
|
root: ({ theme }) => ({
|
|
201
200
|
'&:hover, &.Mui-selected, &.Mui-selected:hover, &.Mui-selected:focus':
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
201
|
+
{
|
|
202
|
+
background: equals(theme.palette.mode, ThemeMode.dark)
|
|
203
|
+
? theme.palette.primary.dark
|
|
204
|
+
: theme.palette.primary.light,
|
|
205
|
+
color: equals(theme.palette.mode, ThemeMode.dark)
|
|
206
|
+
? theme.palette.common.white
|
|
207
|
+
: theme.palette.primary.main
|
|
208
|
+
},
|
|
210
209
|
fontSize: theme.typography.body2.fontSize
|
|
211
210
|
})
|
|
212
211
|
}
|
|
@@ -223,12 +222,12 @@ export const getTheme = (mode: ThemeMode): ThemeOptions => ({
|
|
|
223
222
|
styleOverrides: {
|
|
224
223
|
root: ({ theme }) => ({
|
|
225
224
|
[`[role="tooltip"] &, &.MuiMenu-paper, &.${autocompleteClasses.paper}`]:
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
225
|
+
{
|
|
226
|
+
backgroundColor: theme.palette.background.default,
|
|
227
|
+
border: 'none',
|
|
228
|
+
borderRadius: `${theme.shape.borderRadius}px`,
|
|
229
|
+
boxShadow: theme.shadows[3]
|
|
230
|
+
}
|
|
232
231
|
})
|
|
233
232
|
}
|
|
234
233
|
},
|
|
@@ -258,23 +257,15 @@ export const getTheme = (mode: ThemeMode): ThemeOptions => ({
|
|
|
258
257
|
|
|
259
258
|
interface Props {
|
|
260
259
|
children: ReactNode;
|
|
261
|
-
overrideTheme?: {
|
|
262
|
-
light: Partial<PaletteOptions>;
|
|
263
|
-
dark: Partial<PaletteOptions>;
|
|
264
|
-
};
|
|
265
260
|
}
|
|
266
261
|
|
|
267
|
-
const ThemeProvider = ({ children
|
|
262
|
+
const ThemeProvider = ({ children }: Props): JSX.Element => {
|
|
268
263
|
const { themeMode } = useAtomValue(userAtom);
|
|
269
264
|
|
|
270
|
-
const theme = useMemo(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
palette: overrideThemeByMode || {}
|
|
275
|
-
})
|
|
276
|
-
);
|
|
277
|
-
}, [themeMode, overrideTheme]);
|
|
265
|
+
const theme = useMemo(
|
|
266
|
+
() => createTheme(getTheme(themeMode || ThemeMode.light)),
|
|
267
|
+
[themeMode]
|
|
268
|
+
);
|
|
278
269
|
|
|
279
270
|
return (
|
|
280
271
|
<StyledEngineProvider injectFirst enableCssLayer>
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
/* =============
|
|
26
26
|
COLOR SYSTEM
|
|
27
27
|
============= */
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
/* Action colors */
|
|
30
30
|
--color-action-acknowledged: #745f35;
|
|
31
31
|
--color-action-acknowledged-background: #dfd2b9;
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
--color-action-in-downtime-background: #e5d8f3;
|
|
44
44
|
--color-action-selected: rgba(102, 102, 102, 0.3);
|
|
45
45
|
--color-action-selected-opacity: 0.3;
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
/* Background colors */
|
|
48
48
|
--color-background-default: #f4f4f4;
|
|
49
49
|
--color-background-listing-header: #666666;
|
|
@@ -52,18 +52,18 @@
|
|
|
52
52
|
--color-background-paper: #ffffff;
|
|
53
53
|
--color-background-tooltip: #434e58;
|
|
54
54
|
--color-background-widget: #f8f8f8;
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
/* Chip colors */
|
|
57
57
|
--color-chip-error: #ff6666;
|
|
58
58
|
--color-chip-info: #1588d1;
|
|
59
59
|
--color-chip-neutral: #6da4e4;
|
|
60
60
|
--color-chip-success: #88b922;
|
|
61
61
|
--color-chip-warning: #fd9b27;
|
|
62
|
-
|
|
62
|
+
|
|
63
63
|
/* Utility colors */
|
|
64
64
|
--color-divider: #e3e3e3;
|
|
65
65
|
--color-error-main: #ff4a4a;
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
/* Header colors */
|
|
68
68
|
--color-header-page-action-background-active: #1975d10f;
|
|
69
69
|
--color-header-page-action-background-default: #ffffff00;
|
|
@@ -90,18 +90,19 @@
|
|
|
90
90
|
--color-header-menu-item-color-active: #3e85d5;
|
|
91
91
|
--color-header-menu-item-color-default: #1b2127;
|
|
92
92
|
--color-header-menu-item-color-hover: #101418;
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
/* State colors */
|
|
95
95
|
--color-pending-main: #1ebeb3;
|
|
96
|
-
|
|
96
|
+
|
|
97
97
|
/* Primary & Secondary colors */
|
|
98
98
|
--color-primary-main: #2e68aa;
|
|
99
99
|
--color-primary-light: #cde7fc;
|
|
100
100
|
--color-primary-dark: #255891;
|
|
101
|
+
--color-primary-contrastText: #fff;
|
|
101
102
|
--color-secondary-main: #c772d6;
|
|
102
103
|
--color-secondary-light: #e5a5f0;
|
|
103
104
|
--color-secondary-dark: #ac28c1;
|
|
104
|
-
|
|
105
|
+
|
|
105
106
|
/* Status colors */
|
|
106
107
|
--color-status-background-error: #ff6666;
|
|
107
108
|
--color-status-background-none: --alpha(#2e68aa / 10%);
|
|
@@ -110,7 +111,7 @@
|
|
|
110
111
|
--color-stauts-background-unknown: #e3e3e3;
|
|
111
112
|
--color-status-background-warning: #fd9b27;
|
|
112
113
|
--color-success-main: #88b922;
|
|
113
|
-
|
|
114
|
+
|
|
114
115
|
/* Text colors */
|
|
115
116
|
--color-text-disabled: #999999;
|
|
116
117
|
--color-text-primary: #000000;
|
|
@@ -118,7 +119,7 @@
|
|
|
118
119
|
--color-warning-main: #fd9b27;
|
|
119
120
|
--color-warning-light: #fcc481;
|
|
120
121
|
--color-warning-dark: #fc7e00;
|
|
121
|
-
|
|
122
|
+
|
|
122
123
|
/* Base colors */
|
|
123
124
|
--color-white: #ffffff;
|
|
124
125
|
--color-black: #000000;
|
|
@@ -185,6 +186,7 @@
|
|
|
185
186
|
--color-primary-main: #6eaff8;
|
|
186
187
|
--color-primary-light: #8bbff9;
|
|
187
188
|
--color-primary-dark: #4974a5;
|
|
189
|
+
--color-primary-contrastText: #000;
|
|
188
190
|
--color-secondary-main: #7c1fa2;
|
|
189
191
|
--color-status-background-error: #d60101;
|
|
190
192
|
--color-status-background-none: --alpha(#2e68aa / 10%);
|
|
@@ -95,9 +95,10 @@ const PickersStartEndDate = ({
|
|
|
95
95
|
changeDate,
|
|
96
96
|
rangeStartDate,
|
|
97
97
|
rangeEndDate,
|
|
98
|
-
direction = PickersStartEndDateDirection.column
|
|
99
|
-
className
|
|
98
|
+
direction = PickersStartEndDateDirection.column
|
|
100
99
|
}: PickersStartEndDateProps): JSX.Element => {
|
|
100
|
+
const { classes } = useStyles();
|
|
101
|
+
|
|
101
102
|
const locale = useLocale();
|
|
102
103
|
const error = useAtomValue(errorTimePeriodAtom);
|
|
103
104
|
const isError = error || isInvalidDate({ endDate, startDate });
|
|
@@ -107,14 +108,16 @@ const PickersStartEndDate = ({
|
|
|
107
108
|
const maxEnd = rangeEndDate?.max;
|
|
108
109
|
const minEnd = rangeEndDate?.min || startDate;
|
|
109
110
|
|
|
110
|
-
const
|
|
111
|
+
const styleContainer = equals(direction, PickersStartEndDateDirection.column)
|
|
112
|
+
? classes.verticalDirection
|
|
113
|
+
: classes.horizontalDirection;
|
|
111
114
|
|
|
112
115
|
return (
|
|
113
116
|
<LocalizationProvider
|
|
114
117
|
adapterLocale={locale.substring(0, 2)}
|
|
115
118
|
dateAdapter={AdapterDayjs}
|
|
116
119
|
>
|
|
117
|
-
<div className={
|
|
120
|
+
<div className={styleContainer}>
|
|
118
121
|
<PickerDateWithLabel
|
|
119
122
|
changeDate={changeDate}
|
|
120
123
|
date={startDate}
|
|
@@ -140,7 +143,7 @@ const PickersStartEndDate = ({
|
|
|
140
143
|
{isError && (
|
|
141
144
|
<ErrorText
|
|
142
145
|
message="The end date must be greater than the start date"
|
|
143
|
-
style=
|
|
146
|
+
style={classes.error}
|
|
144
147
|
/>
|
|
145
148
|
)}
|
|
146
149
|
</LocalizationProvider>
|