@centreon/ui 24.5.3 → 24.5.5
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
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Typography } from '@mui/material';
|
|
2
|
+
|
|
3
|
+
import { DashboardLayout } from '.';
|
|
4
|
+
|
|
5
|
+
const dashboardLayout: Array<CustomLayout> = [
|
|
6
|
+
{
|
|
7
|
+
content: 'Panel 1',
|
|
8
|
+
h: 4,
|
|
9
|
+
i: 'a',
|
|
10
|
+
shouldUseFluidTypography: false,
|
|
11
|
+
w: 6,
|
|
12
|
+
x: 0,
|
|
13
|
+
y: 0
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
content: 'Panel 2',
|
|
17
|
+
h: 3,
|
|
18
|
+
i: 'b',
|
|
19
|
+
minW: 2,
|
|
20
|
+
w: 7,
|
|
21
|
+
x: 1,
|
|
22
|
+
y: 7
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
content: 'Panel 3',
|
|
26
|
+
h: 7,
|
|
27
|
+
i: 'c',
|
|
28
|
+
w: 6,
|
|
29
|
+
x: 6,
|
|
30
|
+
y: 6
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
content: 'Panel 4',
|
|
34
|
+
h: 3,
|
|
35
|
+
i: 'd',
|
|
36
|
+
minW: 2,
|
|
37
|
+
w: 5,
|
|
38
|
+
x: 4,
|
|
39
|
+
y: 10
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const initialize = (): void => {
|
|
44
|
+
cy.mount({
|
|
45
|
+
Component: (
|
|
46
|
+
<DashboardLayout.Layout layout={dashboardLayout}>
|
|
47
|
+
{dashboardLayout.map(({ i, content }) => (
|
|
48
|
+
<DashboardLayout.Item header={<div>header</div>} id={i} key={i}>
|
|
49
|
+
<Typography>{content}</Typography>
|
|
50
|
+
</DashboardLayout.Item>
|
|
51
|
+
))}
|
|
52
|
+
</DashboardLayout.Layout>
|
|
53
|
+
)
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
describe('Dashboard', () => {
|
|
58
|
+
it('displays placeholder when panels is out of viewport', () => {
|
|
59
|
+
initialize();
|
|
60
|
+
|
|
61
|
+
cy.get('[data-widget-skeleton="a"]').should('not.exist');
|
|
62
|
+
cy.get('[data-widget-skeleton="b"]').should('not.exist');
|
|
63
|
+
cy.get('[data-widget-skeleton="c"]').should('not.exist');
|
|
64
|
+
cy.get('[data-widget-skeleton="d"]').should('exist');
|
|
65
|
+
|
|
66
|
+
cy.makeSnapshot();
|
|
67
|
+
});
|
|
68
|
+
});
|
package/src/Dashboard/Item.tsx
CHANGED
|
@@ -3,14 +3,16 @@ import {
|
|
|
3
3
|
ForwardedRef,
|
|
4
4
|
forwardRef,
|
|
5
5
|
MouseEvent,
|
|
6
|
-
ReactElement
|
|
6
|
+
ReactElement,
|
|
7
|
+
useEffect
|
|
7
8
|
} from 'react';
|
|
8
9
|
|
|
9
10
|
import { isNil, prop } from 'ramda';
|
|
10
11
|
|
|
11
12
|
import { Card, useTheme } from '@mui/material';
|
|
12
13
|
|
|
13
|
-
import { useMemoComponent } from '../utils';
|
|
14
|
+
import { useMemoComponent, useViewportIntersection } from '../utils';
|
|
15
|
+
import LoadingSkeleton from '../LoadingSkeleton';
|
|
14
16
|
|
|
15
17
|
import { useDashboardItemStyles } from './Dashboard.styles';
|
|
16
18
|
|
|
@@ -45,6 +47,9 @@ const Item = forwardRef<HTMLDivElement, DashboardItemProps>(
|
|
|
45
47
|
}: DashboardItemProps,
|
|
46
48
|
ref: ForwardedRef<HTMLDivElement>
|
|
47
49
|
): ReactElement => {
|
|
50
|
+
const { isInViewport, setElement } = useViewportIntersection({
|
|
51
|
+
rootMargin: '140px 0px 140px 0px'
|
|
52
|
+
});
|
|
48
53
|
const hasHeader = !isNil(header);
|
|
49
54
|
|
|
50
55
|
const { classes, cx } = useDashboardItemStyles({ hasHeader });
|
|
@@ -58,6 +63,14 @@ const Item = forwardRef<HTMLDivElement, DashboardItemProps>(
|
|
|
58
63
|
|
|
59
64
|
const cardContainerListeners = !hasHeader ? listeners : {};
|
|
60
65
|
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (isNil(ref)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
setElement(ref.current);
|
|
72
|
+
}, [ref]);
|
|
73
|
+
|
|
61
74
|
return useMemoComponent({
|
|
62
75
|
Component: (
|
|
63
76
|
<div
|
|
@@ -89,19 +102,31 @@ const Item = forwardRef<HTMLDivElement, DashboardItemProps>(
|
|
|
89
102
|
!disablePadding && classes.widgetPadding
|
|
90
103
|
)}
|
|
91
104
|
>
|
|
92
|
-
{
|
|
105
|
+
{!isInViewport ? (
|
|
106
|
+
<LoadingSkeleton
|
|
107
|
+
animation={false}
|
|
108
|
+
data-widget-skeleton={id}
|
|
109
|
+
height="100%"
|
|
110
|
+
width="100%"
|
|
111
|
+
/>
|
|
112
|
+
) : (
|
|
113
|
+
children
|
|
114
|
+
)}
|
|
93
115
|
</div>
|
|
94
116
|
</Card>
|
|
95
117
|
</div>
|
|
96
118
|
),
|
|
97
|
-
memoProps:
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
119
|
+
memoProps: isInViewport
|
|
120
|
+
? [
|
|
121
|
+
style,
|
|
122
|
+
className,
|
|
123
|
+
header,
|
|
124
|
+
theme.palette.mode,
|
|
125
|
+
canMove,
|
|
126
|
+
isInViewport,
|
|
127
|
+
...additionalMemoProps
|
|
128
|
+
]
|
|
129
|
+
: [isInViewport, theme.palette.mode, style]
|
|
105
130
|
});
|
|
106
131
|
}
|
|
107
132
|
);
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
UseQueryOptions
|
|
9
9
|
} from '@tanstack/react-query';
|
|
10
10
|
import { JsonDecoder } from 'ts.data.json';
|
|
11
|
-
import { has, includes, isNil, not, omit } from 'ramda';
|
|
11
|
+
import { equals, has, includes, isNil, not, omit } from 'ramda';
|
|
12
12
|
|
|
13
13
|
import { CatchErrorProps, customFetch, ResponseError } from '../customFetch';
|
|
14
14
|
import useSnackbar from '../../Snackbar/useSnackbar';
|
|
@@ -32,6 +32,7 @@ export interface UseFetchQueryProps<T> {
|
|
|
32
32
|
UseQueryOptions<T | ResponseError, Error, T | ResponseError, QueryKey>,
|
|
33
33
|
'queryKey' | 'queryFn'
|
|
34
34
|
>;
|
|
35
|
+
useLongCache?: boolean;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
export type UseFetchQueryState<T> = {
|
|
@@ -58,12 +59,18 @@ const useFetchQuery = <T extends object>({
|
|
|
58
59
|
queryOptions,
|
|
59
60
|
httpCodesBypassErrorSnackbar = [],
|
|
60
61
|
baseEndpoint,
|
|
61
|
-
doNotCancelCallsOnUnmount = false
|
|
62
|
+
doNotCancelCallsOnUnmount = false,
|
|
63
|
+
useLongCache
|
|
62
64
|
}: UseFetchQueryProps<T>): UseFetchQueryState<T> => {
|
|
63
65
|
const dataRef = useRef<T | undefined>(undefined);
|
|
64
66
|
|
|
65
67
|
const { showErrorMessage } = useSnackbar();
|
|
66
68
|
|
|
69
|
+
const isCypressTest = equals(window.Cypress?.testingType, 'component');
|
|
70
|
+
|
|
71
|
+
const cacheOptions =
|
|
72
|
+
!isCypressTest && useLongCache ? { gcTime: 60 * 1000 } : {};
|
|
73
|
+
|
|
67
74
|
const queryData = useQuery<T | ResponseError, Error>({
|
|
68
75
|
queryFn: ({ signal }): Promise<T | ResponseError> =>
|
|
69
76
|
customFetch<T>({
|
|
@@ -76,6 +83,7 @@ const useFetchQuery = <T extends object>({
|
|
|
76
83
|
signal
|
|
77
84
|
}),
|
|
78
85
|
queryKey: getQueryKey(),
|
|
86
|
+
...cacheOptions,
|
|
79
87
|
...queryOptions
|
|
80
88
|
});
|
|
81
89
|
|
|
@@ -149,7 +149,8 @@ const useGraphQuery = ({
|
|
|
149
149
|
enabled: areResourcesFullfilled(resources) && !isEmpty(definedMetrics),
|
|
150
150
|
refetchInterval: refreshInterval,
|
|
151
151
|
suspense: false
|
|
152
|
-
}
|
|
152
|
+
},
|
|
153
|
+
useLongCache: true
|
|
153
154
|
});
|
|
154
155
|
|
|
155
156
|
const data = useRef<PerformanceGraphData | undefined>(undefined);
|