@centreon/ui 26.12.1 → 26.12.3
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 +6 -3
- package/public/mockServiceWorker.js +31 -8
- package/src/Dashboard/Dashboard.browser.test.tsx +107 -0
- package/src/Form/CollapsibleGroup.tsx +6 -33
- package/src/Form/Form.browser.test.tsx +553 -0
- package/src/Form/Inputs/ExclusiveCheckboxGroup.browser.test.tsx +304 -0
- package/src/Form/Inputs/Grid.tsx +1 -2
- package/src/Form/Inputs/SegmentedButtons.browser.test.tsx +113 -0
- package/src/Form/Inputs/index.tsx +10 -52
- package/src/InputField/Number/Number.browser.test.tsx +109 -0
- package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.browser.test.tsx +250 -0
- package/src/Listing/Listing.browser.test.tsx +476 -0
- package/src/Module/Module.browser.test.tsx +145 -0
- package/src/Pagination/Pagination.browser.test.tsx +184 -0
- package/src/RichTextEditor/RichTextEditor.browser.test.tsx +567 -0
- package/src/RichTextEditor/plugins/FloatingLinkEditorPlugin.tsx +3 -1
- package/src/TimePeriods/ResolutionTimePeriod.browser.test.tsx +143 -0
- package/src/TimePeriods/TimePeriods.browser.test.tsx +468 -0
- package/src/Typography/FluidTypography/FluidTypography.browser.test.tsx +54 -0
- package/src/api/useMutationQuery/useMutationQuery.browser.test.tsx +154 -0
- package/src/components/CollapsibleItem/CollapsibleItem.browser.test.tsx +120 -0
- package/src/components/CopyCommand/CopyCommand.browser.test.tsx +287 -0
- package/src/components/CrudPage/CrudPage.browser.test.tsx +659 -0
- package/src/components/DataTable/DataTable.browser.test.tsx +257 -0
- package/src/components/Form/AccessRights/AccessRights.browser.test.tsx +527 -0
- package/src/components/ItemComposition/ItemComposition.browser.test.tsx +172 -0
- package/src/components/Layout/PageLayout.browser.test.tsx +114 -0
- package/src/components/Modal/ConfirmationModal/ConfirmationModal.browser.test.tsx +237 -0
- package/src/components/SortableEntriesList/SortableEntriesList.browser.test.tsx +981 -0
- package/src/components/Tabs/Tabs.browser.test.tsx +115 -0
- package/src/utils/useFullscreen/Fullscreen.browser.test.tsx +176 -0
- package/src/utils/useLocale/useLocale.browser.test.tsx +49 -0
- package/src/utils/useLocaleTimezoneDate/{LocaleTimezoneDate.cypress.spec.tsx → LocaleTimezoneDate.browser.test.tsx} +24 -11
- package/src/Dashboard/Dashboard.cypress.spec.tsx +0 -71
- package/src/Form/Form.cypress.spec.tsx +0 -306
- package/src/Form/Inputs/ExclusiveCheckboxGroup.cypress.spec.tsx +0 -236
- package/src/Form/Inputs/SegmentedButtons.cypress.spec.tsx +0 -101
- package/src/InputField/Number/Number.cypress.spec.tsx +0 -89
- package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.cypress.spec.tsx +0 -182
- package/src/Listing/Listing.cypress.spec.tsx +0 -349
- package/src/Module/Module.cypress.spec.tsx +0 -127
- package/src/Pagination/Pagination.cypress.spec.tsx +0 -140
- package/src/RichTextEditor/RichTextEditor.cypress.spec.tsx +0 -408
- package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +0 -74
- package/src/TimePeriods/TimePeriods.cypress.spec.tsx +0 -488
- package/src/Typography/FluidTypography/FluidTypography.cypress.spec.tsx +0 -27
- package/src/api/useMutationQuery/useMutationQuery.cypress.spec.tsx +0 -93
- package/src/components/CollapsibleItem/CollapsibleItem.cypress.spec.tsx +0 -76
- package/src/components/CopyCommand/CopyCommand.cypress.spec.tsx +0 -167
- package/src/components/CrudPage/CrudPage.cypress.spec.tsx +0 -561
- package/src/components/DataTable/DataTable.cypress.spec.tsx +0 -174
- package/src/components/Form/AccessRights/AccessRights.cypress.spec.tsx +0 -376
- package/src/components/ItemComposition/ItemComposition.cypress.spec.tsx +0 -112
- package/src/components/Layout/PageLayout.cypress.spec.tsx +0 -64
- package/src/components/Modal/ConfirmationModal/ConfirmationModal.cypress.spec.tsx +0 -171
- package/src/components/SortableEntriesList/SortableEntriesList.cypress.spec.tsx +0 -792
- package/src/components/Tabs/Tabs.cypress.spec.tsx +0 -69
- package/src/utils/useFullscreen/Fullscreen.cypress.spec.tsx +0 -130
- package/src/utils/useLocale/useLocale.cypress.spec.tsx +0 -40
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@centreon/ui",
|
|
3
|
-
"version": "26.12.
|
|
3
|
+
"version": "26.12.3",
|
|
4
4
|
"description": "Centreon UI Components",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"update:deps": "pnpx npm-check-updates -i --format group",
|
|
7
|
-
"type-check": "tsc --project tsconfig.typecheck.json",
|
|
7
|
+
"type-check": "tsc --project tsconfig.typecheck.json && tsc --project tsconfig.rstest.json",
|
|
8
8
|
"type-check:staged": "node typecheck-staged.mjs",
|
|
9
9
|
"lint": "biome check ./src/ --error-on-warnings",
|
|
10
10
|
"lint:fix": "pnpm lint --fix",
|
|
@@ -21,7 +21,10 @@
|
|
|
21
21
|
"cypress:install": "cypress install",
|
|
22
22
|
"cypress:cli": "./cypress/scripts/cypress-cli.sh",
|
|
23
23
|
"tokens:transform": "TS_NODE_PROJECT=tsconfig.node.json ts-node style-dictionary.transform.ts",
|
|
24
|
-
"install:arm:binaries": "pnpm i -D @swc/core-linux-arm64-gnu@1.6.6 @rspack/binding-linux-arm64-gnu@1.1.6 -w && pnpm remove @swc/core-linux-arm64-gnu @rspack/binding-linux-arm64-gnu"
|
|
24
|
+
"install:arm:binaries": "pnpm i -D @swc/core-linux-arm64-gnu@1.6.6 @rspack/binding-linux-arm64-gnu@1.1.6 -w && pnpm remove @swc/core-linux-arm64-gnu @rspack/binding-linux-arm64-gnu",
|
|
25
|
+
"rstest:run": "TZ=Etc/UTC rstest run",
|
|
26
|
+
"rstest:ui": "TZ=Etc/UTC rstest run --browser.headless=false --pool.maxWorkers=1",
|
|
27
|
+
"rstest:install": "playwright install --with-deps --only-shell chromium"
|
|
25
28
|
},
|
|
26
29
|
"type": "module",
|
|
27
30
|
"sideEffects": false,
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* - Please do NOT serve this file on production.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const PACKAGE_VERSION = '2.
|
|
12
|
-
const INTEGRITY_CHECKSUM = '
|
|
11
|
+
const PACKAGE_VERSION = '2.7.3'
|
|
12
|
+
const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
|
|
13
13
|
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
|
|
14
14
|
const activeClientIds = new Set()
|
|
15
15
|
|
|
@@ -62,7 +62,12 @@ self.addEventListener('message', async function (event) {
|
|
|
62
62
|
|
|
63
63
|
sendToClient(client, {
|
|
64
64
|
type: 'MOCKING_ENABLED',
|
|
65
|
-
payload:
|
|
65
|
+
payload: {
|
|
66
|
+
client: {
|
|
67
|
+
id: client.id,
|
|
68
|
+
frameType: client.frameType,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
66
71
|
})
|
|
67
72
|
break
|
|
68
73
|
}
|
|
@@ -155,6 +160,10 @@ async function handleRequest(event, requestId) {
|
|
|
155
160
|
async function resolveMainClient(event) {
|
|
156
161
|
const client = await self.clients.get(event.clientId)
|
|
157
162
|
|
|
163
|
+
if (activeClientIds.has(event.clientId)) {
|
|
164
|
+
return client
|
|
165
|
+
}
|
|
166
|
+
|
|
158
167
|
if (client?.frameType === 'top-level') {
|
|
159
168
|
return client
|
|
160
169
|
}
|
|
@@ -183,12 +192,26 @@ async function getResponse(event, client, requestId) {
|
|
|
183
192
|
const requestClone = request.clone()
|
|
184
193
|
|
|
185
194
|
function passthrough() {
|
|
186
|
-
|
|
195
|
+
// Cast the request headers to a new Headers instance
|
|
196
|
+
// so the headers can be manipulated with.
|
|
197
|
+
const headers = new Headers(requestClone.headers)
|
|
198
|
+
|
|
199
|
+
// Remove the "accept" header value that marked this request as passthrough.
|
|
200
|
+
// This prevents request alteration and also keeps it compliant with the
|
|
201
|
+
// user-defined CORS policies.
|
|
202
|
+
const acceptHeader = headers.get('accept')
|
|
203
|
+
if (acceptHeader) {
|
|
204
|
+
const values = acceptHeader.split(',').map((value) => value.trim())
|
|
205
|
+
const filteredValues = values.filter(
|
|
206
|
+
(value) => value !== 'msw/passthrough',
|
|
207
|
+
)
|
|
187
208
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
209
|
+
if (filteredValues.length > 0) {
|
|
210
|
+
headers.set('accept', filteredValues.join(', '))
|
|
211
|
+
} else {
|
|
212
|
+
headers.delete('accept')
|
|
213
|
+
}
|
|
214
|
+
}
|
|
192
215
|
|
|
193
216
|
return fetch(requestClone, { headers })
|
|
194
217
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Typography } from '@mui/material';
|
|
2
|
+
|
|
3
|
+
import { render } from '@test-setup/render';
|
|
4
|
+
import { screen, waitFor } from '@testing-library/react';
|
|
5
|
+
import type { LayoutItem } from 'react-grid-layout';
|
|
6
|
+
|
|
7
|
+
import { DashboardLayout } from '.';
|
|
8
|
+
|
|
9
|
+
interface CustomLayout extends LayoutItem {
|
|
10
|
+
content: string;
|
|
11
|
+
shouldUseFluidTypography?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const dashboardLayout: Array<CustomLayout> = [
|
|
15
|
+
{
|
|
16
|
+
content: 'Panel 1',
|
|
17
|
+
h: 4,
|
|
18
|
+
i: 'a',
|
|
19
|
+
shouldUseFluidTypography: false,
|
|
20
|
+
w: 6,
|
|
21
|
+
x: 0,
|
|
22
|
+
y: 0
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
content: 'Panel 2',
|
|
26
|
+
h: 3,
|
|
27
|
+
i: 'b',
|
|
28
|
+
minW: 2,
|
|
29
|
+
w: 7,
|
|
30
|
+
x: 1,
|
|
31
|
+
y: 7
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
content: 'Panel 3',
|
|
35
|
+
h: 7,
|
|
36
|
+
i: 'c',
|
|
37
|
+
w: 6,
|
|
38
|
+
x: 6,
|
|
39
|
+
y: 6
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
content: 'Panel 4',
|
|
43
|
+
h: 3,
|
|
44
|
+
i: 'd',
|
|
45
|
+
minW: 2,
|
|
46
|
+
w: 5,
|
|
47
|
+
x: 4,
|
|
48
|
+
y: 10
|
|
49
|
+
}
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const initialize = (): void => {
|
|
53
|
+
render(
|
|
54
|
+
<DashboardLayout.Layout layout={dashboardLayout}>
|
|
55
|
+
{dashboardLayout.map(({ i, content }) => (
|
|
56
|
+
<DashboardLayout.Item header={<div>header</div>} id={i} key={i}>
|
|
57
|
+
{[<Typography key="content">{content}</Typography>]}
|
|
58
|
+
</DashboardLayout.Item>
|
|
59
|
+
))}
|
|
60
|
+
</DashboardLayout.Layout>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const panelBox = (content: string): DOMRect =>
|
|
65
|
+
(
|
|
66
|
+
screen.getByText(content).closest('.react-grid-item') as HTMLElement
|
|
67
|
+
).getBoundingClientRect();
|
|
68
|
+
|
|
69
|
+
describe('Dashboard', () => {
|
|
70
|
+
beforeEach(() => {
|
|
71
|
+
expect.hasAssertions();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('displays placeholder when panels is out of viewport', async () => {
|
|
75
|
+
initialize();
|
|
76
|
+
|
|
77
|
+
// The four panels render with their header. Panels 1 and 3 share the
|
|
78
|
+
// first row (Panel 3 taller), Panel 2 sits below Panel 3 starting within
|
|
79
|
+
// Panel 1's width, and Panel 4 is below Panel 2.
|
|
80
|
+
expect(await screen.findByText('Panel 1')).toBeVisible();
|
|
81
|
+
expect(screen.getByText('Panel 2')).toBeVisible();
|
|
82
|
+
expect(screen.getByText('Panel 3')).toBeVisible();
|
|
83
|
+
expect(screen.getByText('Panel 4')).toBeInTheDocument();
|
|
84
|
+
expect(screen.getAllByText('header')).toHaveLength(4);
|
|
85
|
+
|
|
86
|
+
await waitFor(() => {
|
|
87
|
+
const panel1 = panelBox('Panel 1');
|
|
88
|
+
const panel3 = panelBox('Panel 3');
|
|
89
|
+
|
|
90
|
+
expect(panel1.width).toBeGreaterThan(0);
|
|
91
|
+
expect(panel3.top).toBe(panel1.top);
|
|
92
|
+
expect(panel3.left).toBeGreaterThan(panel1.right);
|
|
93
|
+
expect(panel3.width).toBe(panel1.width);
|
|
94
|
+
expect(panel3.height).toBeGreaterThan(panel1.height);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const panel1 = panelBox('Panel 1');
|
|
98
|
+
const panel2 = panelBox('Panel 2');
|
|
99
|
+
const panel3 = panelBox('Panel 3');
|
|
100
|
+
const panel4 = panelBox('Panel 4');
|
|
101
|
+
|
|
102
|
+
expect(panel2.top).toBeGreaterThan(panel3.bottom);
|
|
103
|
+
expect(panel2.left).toBeGreaterThan(panel1.left);
|
|
104
|
+
expect(panel2.left).toBeLessThan(panel1.right);
|
|
105
|
+
expect(panel4.top).toBeGreaterThan(panel2.bottom);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
|
|
11
11
|
import { useCallback, useState } from 'react';
|
|
12
12
|
import { useTranslation } from 'react-i18next';
|
|
13
|
-
import { makeStyles } from 'tss-react/mui';
|
|
14
13
|
|
|
15
14
|
import type { Group } from './Inputs/models';
|
|
16
15
|
|
|
@@ -23,22 +22,6 @@ interface Props {
|
|
|
23
22
|
isCollapsible: boolean;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
const useStyles = makeStyles()((theme) => ({
|
|
27
|
-
expandCollapseIcon: {
|
|
28
|
-
justifySelf: 'flex-end'
|
|
29
|
-
},
|
|
30
|
-
groupTitleContainer: {
|
|
31
|
-
alignItems: 'center',
|
|
32
|
-
columnGap: theme.spacing(1),
|
|
33
|
-
display: 'flex',
|
|
34
|
-
flexDirection: 'row'
|
|
35
|
-
},
|
|
36
|
-
title: {},
|
|
37
|
-
tooltip: {
|
|
38
|
-
maxWidth: theme.spacing(60)
|
|
39
|
-
}
|
|
40
|
-
}));
|
|
41
|
-
|
|
42
25
|
const CollapsibleGroup = ({
|
|
43
26
|
children,
|
|
44
27
|
isCollapsible,
|
|
@@ -47,7 +30,6 @@ const CollapsibleGroup = ({
|
|
|
47
30
|
defaultIsOpen = false,
|
|
48
31
|
className
|
|
49
32
|
}: Props): JSX.Element => {
|
|
50
|
-
const { classes, cx } = useStyles();
|
|
51
33
|
const { t } = useTranslation();
|
|
52
34
|
|
|
53
35
|
const [isOpen, setIsOpen] = useState(isCollapsible && defaultIsOpen);
|
|
@@ -56,7 +38,7 @@ const CollapsibleGroup = ({
|
|
|
56
38
|
setIsOpen((currentIsOpen) => !currentIsOpen);
|
|
57
39
|
};
|
|
58
40
|
|
|
59
|
-
const containerClassName = className || ''
|
|
41
|
+
const containerClassName = `flex items-center gap-x-2 ${className || ''}`;
|
|
60
42
|
|
|
61
43
|
const CollapseIcon = isOpen ? ExpandLess : ExpandMore;
|
|
62
44
|
const ContainerComponent = useCallback(
|
|
@@ -66,7 +48,7 @@ const CollapsibleGroup = ({
|
|
|
66
48
|
isCollapsible ? (
|
|
67
49
|
<ListItemButton
|
|
68
50
|
aria-label={group?.name}
|
|
69
|
-
className={`${
|
|
51
|
+
className={`${containerClassName} bg-background-listing-header rounded-lg`}
|
|
70
52
|
dense
|
|
71
53
|
disableGutters
|
|
72
54
|
disableRipple
|
|
@@ -75,18 +57,9 @@ const CollapsibleGroup = ({
|
|
|
75
57
|
{containerComponentChildren}
|
|
76
58
|
</ListItemButton>
|
|
77
59
|
) : (
|
|
78
|
-
<Box className={
|
|
79
|
-
{containerComponentChildren}
|
|
80
|
-
</Box>
|
|
60
|
+
<Box className={containerClassName}>{containerComponentChildren}</Box>
|
|
81
61
|
),
|
|
82
|
-
[
|
|
83
|
-
isCollapsible,
|
|
84
|
-
classes.groupTitleContainer,
|
|
85
|
-
containerClassName,
|
|
86
|
-
cx,
|
|
87
|
-
group?.name,
|
|
88
|
-
toggle
|
|
89
|
-
]
|
|
62
|
+
[isCollapsible, containerClassName, group?.name, toggle]
|
|
90
63
|
);
|
|
91
64
|
|
|
92
65
|
return (
|
|
@@ -100,7 +73,7 @@ const CollapsibleGroup = ({
|
|
|
100
73
|
data-testid={`${group?.name}-header`}
|
|
101
74
|
>
|
|
102
75
|
<Typography
|
|
103
|
-
className="groupText scroll-m-12 snap-start"
|
|
76
|
+
className="groupText scroll-m-12 snap-start text-base font-medium"
|
|
104
77
|
variant="h6"
|
|
105
78
|
{...group?.titleAttributes}
|
|
106
79
|
data-section-group-form-id={group?.name}
|
|
@@ -110,7 +83,7 @@ const CollapsibleGroup = ({
|
|
|
110
83
|
{group?.EndIcon && (
|
|
111
84
|
<Tooltip
|
|
112
85
|
classes={{
|
|
113
|
-
tooltip:
|
|
86
|
+
tooltip: 'max-w-120'
|
|
114
87
|
}}
|
|
115
88
|
placement="top"
|
|
116
89
|
title={group?.TooltipContent ? <group.TooltipContent /> : ''}
|