@centreon/ui 24.7.7 → 24.7.9

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "24.7.7",
3
+ "version": "24.7.9",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "update:deps": "pnpx npm-check-updates -i --format group",
@@ -12,7 +12,7 @@
12
12
  "test:storybook:local": "test-storybook --url http://127.0.0.1:9001",
13
13
  "test:ci": "jest --silent --reporter=jest-junit",
14
14
  "cypress:ui": "cypress open --component --browser=chrome",
15
- "cypress:run:updateSnapshot": "pnpm cypress:cli --env updateSnapshots=true",
15
+ "cypress:run:updateSnapshot": "cypress run --component --browser=electron --env updateSnapshots=true",
16
16
  "cypress:run:coverage": "cypress run --component --browser=chrome --env codeCoverageTasksRegistered=true",
17
17
  "cypress:run": "cypress run --component --browser=chrome",
18
18
  "tokens:transform": "TS_NODE_PROJECT=tsconfig.node.json ts-node style-dictionary.transform.ts"
@@ -53,55 +53,55 @@
53
53
  "@cypress/webpack-dev-server": "^3.10.0",
54
54
  "@faker-js/faker": "^8.4.1",
55
55
  "@mdx-js/react": "^3.0.1",
56
- "@modern-js/prod-server": "^2.54.5",
57
- "@modern-js/storybook": "^2.54.5",
58
- "@simonsmith/cypress-image-snapshot": "^9.0.3",
59
- "@storybook/addon-a11y": "^8.1.11",
60
- "@storybook/addon-docs": "^8.1.11",
61
- "@storybook/addon-essentials": "^8.1.11",
62
- "@storybook/addon-interactions": "^8.1.11",
63
- "@storybook/addon-themes": "^8.1.11",
64
- "@storybook/blocks": "^8.1.11",
65
- "@storybook/manager-api": "^8.1.11",
56
+ "@modern-js/prod-server": "^2.56.0",
57
+ "@modern-js/storybook": "^2.56.0",
58
+ "@simonsmith/cypress-image-snapshot": "^9.1.0",
59
+ "@storybook/addon-a11y": "^8.2.5",
60
+ "@storybook/addon-docs": "^8.2.5",
61
+ "@storybook/addon-essentials": "^8.2.5",
62
+ "@storybook/addon-interactions": "^8.2.5",
63
+ "@storybook/addon-themes": "^8.2.5",
64
+ "@storybook/blocks": "^8.2.5",
65
+ "@storybook/manager-api": "^8.2.5",
66
66
  "@storybook/mdx2-csf": "^1.1.0",
67
- "@storybook/preview-api": "^8.1.11",
68
- "@storybook/react": "^8.1.11",
69
- "@storybook/react-vite": "^8.1.11",
70
- "@storybook/test": "^8.1.11",
71
- "@storybook/test-runner": "^0.19.0",
72
- "@storybook/theming": "^8.1.11",
67
+ "@storybook/preview-api": "^8.2.5",
68
+ "@storybook/react": "^8.2.5",
69
+ "@storybook/react-vite": "^8.2.5",
70
+ "@storybook/test": "^8.2.5",
71
+ "@storybook/test-runner": "^0.19.1",
72
+ "@storybook/theming": "^8.2.5",
73
73
  "@testing-library/cypress": "^10.0.2",
74
74
  "@testing-library/jest-dom": "^6.4.6",
75
75
  "@testing-library/react": "^16.0.0",
76
76
  "@testing-library/react-hooks": "^8.0.1",
77
77
  "@types/jest": "^29.5.12",
78
78
  "@types/mocha": "^10.0.7",
79
- "@types/ramda": "^0.30.0",
79
+ "@types/ramda": "^0.30.1",
80
80
  "@types/react": "^18.3.3",
81
81
  "@types/testing-library__jest-dom": "^6.0.0",
82
82
  "@vitejs/plugin-react": "^4.3.1",
83
83
  "@vitejs/plugin-react-swc": "^3.7.0",
84
84
  "axios-mock-adapter": "^1.22.0",
85
85
  "chai": "^5.1.1",
86
- "cypress": "^13.13.0",
86
+ "cypress": "^13.13.1",
87
87
  "identity-obj-proxy": "^3.0.0",
88
88
  "jest-transform-stub": "^2.0.0",
89
89
  "mochawesome": "^7.1.3",
90
- "msw": "2.3.1",
91
- "msw-storybook-addon": "^2.0.2",
92
- "puppeteer": "^22.12.1",
90
+ "msw": "2.3.2",
91
+ "msw-storybook-addon": "^2.0.3",
92
+ "puppeteer": "^22.13.1",
93
93
  "react": "^18.3.1",
94
94
  "react-dom": "^18.3.1",
95
95
  "react-test-renderer": "^18.3.1",
96
96
  "remark-gfm": "^4.0.0",
97
97
  "speed-measure-vite-plugin": "^1.0.1",
98
- "storybook": "^8.1.11",
98
+ "storybook": "^8.2.5",
99
99
  "storybook-addon-mock": "^5.0.0",
100
100
  "storybook-dark-mode": "^4.0.2",
101
- "style-dictionary": "^4.0.0",
101
+ "style-dictionary": "^4.0.1",
102
102
  "ts-node": "^10.9.2",
103
103
  "use-resize-observer": "^9.1.0",
104
- "vite": "^5.3.3",
104
+ "vite": "^5.3.4",
105
105
  "vite-plugin-istanbul": "^6.0.2",
106
106
  "vite-plugin-svgr": "^4.2.0",
107
107
  "vite-plugin-turbosnap": "^1.0.3"
@@ -115,8 +115,8 @@
115
115
  "@lexical/rich-text": "^0.16.1",
116
116
  "@lexical/selection": "^0.16.1",
117
117
  "@lexical/utils": "^0.16.1",
118
- "@mui/material": "^5.15.21",
119
- "@react-spring/web": "^9.7.3",
118
+ "@mui/material": "^5.16.4",
119
+ "@react-spring/web": "^9.7.4",
120
120
  "@visx/clip-path": "^3.3.0",
121
121
  "@visx/curve": "^3.3.0",
122
122
  "@visx/event": "^3.3.0",
@@ -133,7 +133,7 @@
133
133
  "@visx/zoom": "^3.3.0",
134
134
  "anylogger": "^1.0.11",
135
135
  "d3-array": "3.2.4",
136
- "dayjs": "^1.11.11",
136
+ "dayjs": "^1.11.12",
137
137
  "humanize-duration": "^3.32.1",
138
138
  "lexical": "^0.16.1",
139
139
  "notistack": "^3.0.1",
@@ -142,7 +142,7 @@
142
142
  "react-grid-layout": "^1.4.4",
143
143
  "react-html-parser": "^2.0.2",
144
144
  "react-resizable": "^3.0.5",
145
- "react-router-dom": "^6.24.0",
145
+ "react-router-dom": "^6.25.1",
146
146
  "react-transition-group": "^4.4.5",
147
147
  "sanitize-html": "^2.13.0",
148
148
  "ulog": "^2.0.0-beta.19"
@@ -8,7 +8,7 @@
8
8
  * - Please do NOT serve this file on production.
9
9
  */
10
10
 
11
- const PACKAGE_VERSION = '2.3.1'
11
+ const PACKAGE_VERSION = '2.3.2'
12
12
  const INTEGRITY_CHECKSUM = '26357c79639bfa20d64c0efca2a87423'
13
13
  const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
14
14
  const activeClientIds = new Set()
@@ -41,6 +41,8 @@ const dashboardLayout: Array<CustomLayout> = [
41
41
  ];
42
42
 
43
43
  const initialize = (): void => {
44
+ cy.adjustViewport();
45
+
44
46
  cy.mount({
45
47
  Component: (
46
48
  <DashboardLayout.Layout layout={dashboardLayout}>
@@ -63,7 +65,6 @@ describe('Dashboard', () => {
63
65
  cy.get('[data-widget-skeleton="a"]').should('not.exist');
64
66
  cy.get('[data-widget-skeleton="b"]').should('not.exist');
65
67
  cy.get('[data-widget-skeleton="c"]').should('not.exist');
66
- cy.get('[data-widget-skeleton="d"]').should('exist');
67
68
 
68
69
  cy.makeSnapshot();
69
70
  });
@@ -1,9 +1,13 @@
1
+ import { renderHook } from '@testing-library/react';
1
2
  import dayjs from 'dayjs';
3
+ import { useAtomValue } from 'jotai';
2
4
  import { equals } from 'ramda';
3
5
 
6
+ import { userAtom } from '@centreon/ui-context';
7
+
4
8
  import dataPingService from '../mockedData/pingService.json';
5
- import dataPingServiceStacked from '../mockedData/pingServiceStacked.json';
6
9
  import dataPingServiceMixedStacked from '../mockedData/pingServiceMixedStacked.json';
10
+ import dataPingServiceStacked from '../mockedData/pingServiceStacked.json';
7
11
 
8
12
  import BarChart, { BarChartProps } from './BarChart';
9
13
 
@@ -31,6 +35,8 @@ const initialize = ({
31
35
  BarChartProps,
32
36
  'data' | 'legend' | 'axis' | 'barStyle' | 'orientation' | 'tooltip'
33
37
  >): void => {
38
+ cy.adjustViewport();
39
+
34
40
  cy.mount({
35
41
  Component: (
36
42
  <div style={{ height: '100%', width: '100%' }}>
@@ -54,6 +60,8 @@ describe('Bar chart', () => {
54
60
  ['horizontal', 'vertical'].forEach((orientation) => {
55
61
  it(`displays the bar chart ${orientation}ly`, () => {
56
62
  initialize({ orientation });
63
+ const userData = renderHook(() => useAtomValue(userAtom));
64
+ userData.result.current.locale = 'en';
57
65
 
58
66
  cy.contains('0 ms').should('be.visible');
59
67
  cy.contains('20').should('be.visible');
@@ -55,17 +55,10 @@ const Template = (args): JSX.Element => {
55
55
  return <HeatMap {...args} arrowClassName={classes.arrow} />;
56
56
  };
57
57
 
58
- const TileContent = ({
59
- data,
60
- backgroundColor
61
- }: {
62
- backgroundColor: string;
63
- data: Data;
64
- }): JSX.Element => (
58
+ const TileContent = ({ data }: { data: Data }): JSX.Element => (
65
59
  <div
66
60
  style={{
67
61
  alignItems: 'center',
68
- backgroundColor,
69
62
  display: 'flex',
70
63
  height: '100%',
71
64
  justifyContent: 'center'
@@ -13,8 +13,9 @@ export const useHeatMapStyles = makeStyles()((theme) => ({
13
13
  width: '100%'
14
14
  },
15
15
  heatMapTileContent: {
16
- height: `calc(100% - ${theme.spacing(1)})`,
17
- width: `calc(100% - ${theme.spacing(1)})`
16
+ height: '100%',
17
+ position: 'relative',
18
+ width: '100%'
18
19
  },
19
20
  heatMapTooltip: {
20
21
  backgroundColor: theme.palette.background.paper,
@@ -2,10 +2,10 @@ import { useTranslation } from 'react-i18next';
2
2
 
3
3
  import { useTheme } from '@mui/material';
4
4
 
5
- import IconDowntime from '../../../Icons/Downtime';
6
5
  import { labelDowntime } from '../../../translatedLabels';
7
6
  import EventAnnotations from '../EventAnnotations';
8
7
  import { Args } from '../models';
8
+ import { DowntimeIcon } from '../../../../../Icon';
9
9
 
10
10
  const DowntimeAnnotations = (props: Args): JSX.Element => {
11
11
  const { t } = useTranslation();
@@ -15,7 +15,7 @@ const DowntimeAnnotations = (props: Args): JSX.Element => {
15
15
 
16
16
  return (
17
17
  <EventAnnotations
18
- Icon={IconDowntime}
18
+ Icon={DowntimeIcon}
19
19
  ariaLabel={t(labelDowntime)}
20
20
  color={color}
21
21
  type="downtime"
@@ -1,3 +1,7 @@
1
+ import { createStore, Provider } from 'jotai';
2
+
3
+ import { userAtom } from '@centreon/ui-context';
4
+
1
5
  import { LineChartData } from '../common/models';
2
6
  import dataLastDay from '../mockedData/lastDay.json';
3
7
  import dataLastDayWithNullValues from '../mockedData/lastDayWithNullValues.json';
@@ -14,6 +18,20 @@ interface Props
14
18
  data?: LineChartData;
15
19
  }
16
20
 
21
+ const checkLegendInformation = (): void => {
22
+ cy.contains('hitratio').should('be.visible');
23
+ cy.contains('querytime').should('be.visible');
24
+ cy.contains('connTime').should('be.visible');
25
+ cy.contains('Min: 70.31').should('be.visible');
26
+ cy.contains('Min: 0.03').should('be.visible');
27
+ cy.contains('Max: 88.03').should('be.visible');
28
+ cy.contains('Max: 0.98').should('be.visible');
29
+ cy.contains('Max: 0.97').should('be.visible');
30
+ cy.contains('Avg: 78.07').should('be.visible');
31
+ cy.contains('Avg: 0.5').should('be.visible');
32
+ cy.contains('Avg: 0.51').should('be.visible');
33
+ };
34
+
17
35
  const initialize = ({
18
36
  data = dataLastDay,
19
37
  tooltip,
@@ -21,16 +39,28 @@ const initialize = ({
21
39
  axis,
22
40
  lineStyle
23
41
  }: Props): void => {
42
+ cy.adjustViewport();
43
+
44
+ const store = createStore();
45
+ store.set(userAtom, {
46
+ alias: 'admin',
47
+ locale: 'en',
48
+ name: 'admin',
49
+ timezone: 'Europe/Paris'
50
+ });
51
+
24
52
  cy.mount({
25
53
  Component: (
26
- <WrapperLineChart
27
- {...argumentsData}
28
- axis={axis}
29
- data={data as unknown as LineChartData}
30
- legend={legend}
31
- lineStyle={lineStyle}
32
- tooltip={tooltip}
33
- />
54
+ <Provider store={store}>
55
+ <WrapperLineChart
56
+ {...argumentsData}
57
+ axis={axis}
58
+ data={data as unknown as LineChartData}
59
+ legend={legend}
60
+ lineStyle={lineStyle}
61
+ tooltip={tooltip}
62
+ />
63
+ </Provider>
34
64
  )
35
65
  });
36
66
 
@@ -227,18 +257,20 @@ describe('Line chart', () => {
227
257
  cy.get('[data-display-side="false"]').should('exist');
228
258
  cy.get('[data-as-list="true"]').should('exist');
229
259
 
230
- cy.contains('9:00 AM').should('be.visible');
260
+ cy.contains('8:00 AM').should('be.visible');
231
261
 
232
262
  cy.makeSnapshot();
233
263
  });
234
264
 
235
265
  it('displays the legend on the left side of the graph when the corresponding prop is set', () => {
236
- initialize({ legend: { mode: 'grid', placement: 'left' } });
266
+ initialize({
267
+ legend: { mode: 'grid', placement: 'left' }
268
+ });
237
269
 
238
270
  cy.get('[data-display-side="true"]').should('exist');
239
271
  cy.get('[data-as-list="true"]').should('exist');
240
272
 
241
- cy.contains('9:00 AM').should('be.visible');
273
+ cy.contains('8:00 AM').should('be.visible');
242
274
 
243
275
  cy.makeSnapshot();
244
276
  });
@@ -249,7 +281,7 @@ describe('Line chart', () => {
249
281
  cy.get('[data-display-side="true"]').should('exist');
250
282
  cy.get('[data-as-list="true"]').should('exist');
251
283
 
252
- cy.contains('9:00 AM').should('be.visible');
284
+ cy.contains('8:00 AM').should('be.visible');
253
285
 
254
286
  cy.makeSnapshot();
255
287
  });
@@ -259,7 +291,7 @@ describe('Line chart', () => {
259
291
  it('does not display axis borders when the prop is set', () => {
260
292
  initialize({ axis: { showBorder: false } });
261
293
 
262
- cy.contains('9:00 AM').should('be.visible');
294
+ cy.contains('8:00 AM').should('be.visible');
263
295
 
264
296
  cy.get('line[class*="visx-axis-line"]')
265
297
  .eq(0)
@@ -280,7 +312,7 @@ describe('Line chart', () => {
280
312
  it('does not display grids when the prop is set', () => {
281
313
  initialize({ axis: { showGridLines: false } });
282
314
 
283
- cy.contains('9:00 AM').should('be.visible');
315
+ cy.contains('8:00 AM').should('be.visible');
284
316
 
285
317
  cy.get('g[class="visx-group visx-rows"]').should('not.exist');
286
318
  cy.get('g[class="visx-group visx-columns"]').should('not.exist');
@@ -291,7 +323,7 @@ describe('Line chart', () => {
291
323
  it('displays only horizontal lines when the prop is set', () => {
292
324
  initialize({ axis: { gridLinesType: 'horizontal' } });
293
325
 
294
- cy.contains('9:00 AM').should('be.visible');
326
+ cy.contains('8:00 AM').should('be.visible');
295
327
 
296
328
  cy.get('g[class="visx-group visx-rows"]').should('be.visible');
297
329
  cy.get('g[class="visx-group visx-columns"]').should('not.exist');
@@ -302,7 +334,7 @@ describe('Line chart', () => {
302
334
  it('displays only vertical lines when the prop is set', () => {
303
335
  initialize({ axis: { gridLinesType: 'vertical' } });
304
336
 
305
- cy.contains('9:00 AM').should('be.visible');
337
+ cy.contains('8:00 AM').should('be.visible');
306
338
 
307
339
  cy.get('g[class="visx-group visx-rows"]').should('not.exist');
308
340
  cy.get('g[class="visx-group visx-columns"]').should('be.visible');
@@ -313,7 +345,7 @@ describe('Line chart', () => {
313
345
  it('rotates the tick label when the props is set', () => {
314
346
  initialize({ axis: { yAxisTickLabelRotation: -35 } });
315
347
 
316
- cy.contains('9:00 AM').should('be.visible');
348
+ cy.contains('8:00 AM').should('be.visible');
317
349
 
318
350
  cy.get('text[transform="rotate(-35, -2, 388)"]').should('be.visible');
319
351
 
@@ -323,7 +355,7 @@ describe('Line chart', () => {
323
355
  it('displays as centered to zero when the prop is set', () => {
324
356
  initialize({ axis: { isCenteredZero: true } });
325
357
 
326
- cy.contains('9:00 AM').should('be.visible');
358
+ cy.contains('8:00 AM').should('be.visible');
327
359
 
328
360
  cy.contains('0.9').should('be.visible');
329
361
  cy.contains('-0.9').should('be.visible');
@@ -336,7 +368,10 @@ describe('Line chart', () => {
336
368
  it('displays the curve in a natural style when the prop is set', () => {
337
369
  initialize({ lineStyle: { curve: 'natural' } });
338
370
 
339
- cy.contains('9:00 AM').should('be.visible');
371
+ cy.contains('8:00 AM').should('be.visible');
372
+ cy.get('[data-metric="13536"]').should('be.visible');
373
+ cy.get('[data-metric="13534"]').should('be.visible');
374
+ cy.get('[data-metric="13535"]').should('be.visible');
340
375
 
341
376
  cy.makeSnapshot();
342
377
  });
@@ -344,7 +379,11 @@ describe('Line chart', () => {
344
379
  it('displays the curve in a step style when the prop is set', () => {
345
380
  initialize({ lineStyle: { curve: 'step' } });
346
381
 
347
- cy.contains('9:00 AM').should('be.visible');
382
+ cy.contains('8:00 AM').should('be.visible');
383
+ cy.get('[data-metric="13536"]').should('be.visible');
384
+ cy.get('[data-metric="13534"]').should('be.visible');
385
+ cy.get('[data-metric="13535"]').should('be.visible');
386
+ checkLegendInformation();
348
387
 
349
388
  cy.makeSnapshot();
350
389
  });
@@ -352,27 +391,31 @@ describe('Line chart', () => {
352
391
  it('shows the area when the prop is set', () => {
353
392
  initialize({ lineStyle: { showArea: true } });
354
393
 
355
- cy.contains('9:00 AM').should('be.visible');
394
+ cy.contains('8:00 AM').should('be.visible');
356
395
  cy.get('path[fill="rgba(102, 153, 204, 0.19999999999999996)"]').should(
357
396
  'be.visible'
358
397
  );
359
398
 
399
+ cy.get('[data-metric="13536"]').should('be.visible');
400
+ cy.get('[data-metric="13534"]').should('be.visible');
401
+ cy.get('[data-metric="13535"]').should('be.visible');
402
+
403
+ checkLegendInformation();
404
+
360
405
  cy.makeSnapshot();
361
406
  });
362
407
 
363
408
  it('shows the area with a custom transparency when props are set', () => {
364
409
  initialize({ lineStyle: { areaTransparency: 20, showArea: true } });
365
410
 
366
- cy.contains('9:00 AM').should('be.visible');
411
+ cy.contains('8:00 AM').should('be.visible');
367
412
  cy.get('path[fill="rgba(102, 153, 204, 0.8)"]').should('be.visible');
368
-
369
- cy.makeSnapshot();
370
413
  });
371
414
 
372
415
  it('shows points when the prop is set', () => {
373
416
  initialize({ lineStyle: { showPoints: true } });
374
417
 
375
- cy.contains('9:00 AM').should('be.visible');
418
+ cy.contains('8:00 AM').should('be.visible');
376
419
  cy.get('circle[cx="4.0625"]').should('be.visible');
377
420
  cy.get('circle[cy="163.69430856642046"]').should('be.visible');
378
421
 
@@ -382,7 +425,7 @@ describe('Line chart', () => {
382
425
  it('displays lines with a custom line width when the prop is set', () => {
383
426
  initialize({ lineStyle: { lineWidth: 6 } });
384
427
 
385
- cy.contains('9:00 AM').should('be.visible');
428
+ cy.contains('8:00 AM').should('be.visible');
386
429
  cy.get('path[stroke-width="6"]').should('have.length', 3);
387
430
 
388
431
  cy.makeSnapshot();
@@ -391,7 +434,7 @@ describe('Line chart', () => {
391
434
  it('displays lines with dots width when the prop is set', () => {
392
435
  initialize({ lineStyle: { dotOffset: 10, lineWidth: 4 } });
393
436
 
394
- cy.contains('9:00 AM').should('be.visible');
437
+ cy.contains('8:00 AM').should('be.visible');
395
438
  cy.get('path[stroke-width="4"]')
396
439
  .should('have.attr', 'stroke-dasharray')
397
440
  .and('equals', '4 10');
@@ -400,7 +443,7 @@ describe('Line chart', () => {
400
443
  it('displays lines with dots width when the prop is set', () => {
401
444
  initialize({ lineStyle: { dashLength: 5, dashOffset: 8 } });
402
445
 
403
- cy.contains('9:00 AM').should('be.visible');
446
+ cy.contains('8:00 AM').should('be.visible');
404
447
  cy.get('path[stroke-width="2"]')
405
448
  .should('have.attr', 'stroke-dasharray')
406
449
  .and('equals', '5 8');
@@ -142,6 +142,7 @@ export interface VariationThreshold {
142
142
  }
143
143
 
144
144
  export interface BasicThreshold {
145
+ id?: string;
145
146
  type: ThresholdType.basic;
146
147
  }
147
148
 
@@ -35,6 +35,8 @@ const initializeStandaloneTree = ({
35
35
  treeLink,
36
36
  children = SimpleContent
37
37
  }: InitializeProps): void => {
38
+ cy.adjustViewport();
39
+
38
40
  cy.mount({
39
41
  Component: (
40
42
  <div style={{ height: '99vh' }}>
@@ -0,0 +1,8 @@
1
+ import { Person } from '@mui/icons-material';
2
+ import { SvgIconProps } from '@mui/material';
3
+
4
+ import BaseIcon from './BaseIcon';
5
+
6
+ export const AcknowledgementIcon = (props: SvgIconProps): JSX.Element => (
7
+ <BaseIcon Icon={Person} dataTestId="AcknowledgementIcon" {...props} />
8
+ );
@@ -0,0 +1,32 @@
1
+ import { has } from 'ramda';
2
+
3
+ import { SvgIcon, SvgIconProps, SvgIconTypeMap } from '@mui/material';
4
+ import { OverridableComponent } from '@mui/material/OverridableComponent';
5
+
6
+ interface Props extends SvgIconProps {
7
+ Icon: JSX.Element | OverridableComponent<SvgIconTypeMap>;
8
+ dataTestId?: string;
9
+ }
10
+
11
+ const BaseIcon = ({ Icon, dataTestId, ...props }: Props): JSX.Element => {
12
+ if (!has('key', Icon)) {
13
+ const Component = Icon as (props: SvgIconProps) => JSX.Element;
14
+
15
+ return (
16
+ <SvgIcon
17
+ data-testid={dataTestId || (Icon as () => JSX.Element).name}
18
+ {...props}
19
+ >
20
+ <Component />
21
+ </SvgIcon>
22
+ );
23
+ }
24
+
25
+ return (
26
+ <SvgIcon data-testid={dataTestId} {...props}>
27
+ {Icon as JSX.Element}
28
+ </SvgIcon>
29
+ );
30
+ };
31
+
32
+ export default BaseIcon;
@@ -0,0 +1,14 @@
1
+ import { SvgIconProps } from '@mui/material';
2
+
3
+ import BaseIcon from './BaseIcon';
4
+
5
+ const icon = (
6
+ <g>
7
+ <path d="M7.6215 5.243C7.9422 5.243 8.2557 5.1479 8.52236 4.96972C8.78901 4.79155 8.99685 4.53831 9.11958 4.24202C9.2423 3.94573 9.27441 3.6197 9.21185 3.30516C9.14928 2.99062 8.99485 2.70169 8.76808 2.47492C8.54131 2.24815 8.25238 2.09372 7.93784 2.03116C7.6233 1.96859 7.29727 2.0007 7.00098 2.12343C6.70469 2.24616 6.45145 2.45399 6.27327 2.72065C6.0951 2.9873 6 3.30079 6 3.6215C6 4.05155 6.17084 4.46398 6.47493 4.76807C6.77902 5.07216 7.19145 5.243 7.6215 5.243Z" />
8
+ <path d="M17.8192 12.3739C17.743 12.1905 17.6143 12.0338 17.4492 11.9235C17.2841 11.8132 17.0901 11.7541 16.8915 11.7538C16.8915 11.7538 14.9107 11.4903 14.3232 11.8736C14.0659 12.083 13.8556 12.3442 13.706 12.6403L10.396 12.1161C10.142 11.2785 9.05429 8.10738 9.05429 8.10738L8.24354 6.81076C8.09994 6.57117 7.89855 6.37142 7.6578 6.22979C7.41705 6.08815 7.14463 6.00914 6.86545 6C6.64749 6.01064 6.43062 6.03754 6.21666 6.0805L2 7.86971V11.68H2.23096L4.36037 12.0174L2.81746 19.7866H4.52041L5.979 13.3006L7.68196 14.9221V19.7866H9.30345V13.706L8.16304 12.6183L13.3649 13.4415L10.4094 19.9725L20.928 19.8671L17.8192 12.3739ZM8.03845 9.87167C8.03845 9.87167 8.59142 11.1712 8.88179 11.8736L7.67525 11.682L8.03845 9.87167ZM3.62437 11.0408V8.921L5.08295 8.35368L4.52137 11.1827L3.62437 11.0408Z" />
9
+ </g>
10
+ );
11
+
12
+ export const DowntimeIcon = (props: SvgIconProps): JSX.Element => (
13
+ <BaseIcon {...props} Icon={icon} height="24" viewBox="0 0 24 24" width="24" />
14
+ );
@@ -0,0 +1,8 @@
1
+ import { Dns } from '@mui/icons-material';
2
+ import { SvgIconProps } from '@mui/material';
3
+
4
+ import BaseIcon from './BaseIcon';
5
+
6
+ export const HostIcon = (props: SvgIconProps): JSX.Element => (
7
+ <BaseIcon Icon={Dns} dataTestId="HostIcon" {...props} />
8
+ );
@@ -0,0 +1,8 @@
1
+ import { Grain } from '@mui/icons-material';
2
+ import { SvgIconProps } from '@mui/material';
3
+
4
+ import BaseIcon from './BaseIcon';
5
+
6
+ export const ServiceIcon = (props: SvgIconProps): JSX.Element => (
7
+ <BaseIcon Icon={Grain} dataTestId="ServiceIcon" {...props} />
8
+ );
@@ -0,0 +1,4 @@
1
+ export { HostIcon } from './HostIcon';
2
+ export { ServiceIcon } from './ServiceIcon';
3
+ export { DowntimeIcon } from './DowntimeIcon';
4
+ export { AcknowledgementIcon } from './AcnowledgementIcon';
@@ -1,17 +1,18 @@
1
+ import dayjs from 'dayjs';
2
+ import timezone from 'dayjs/plugin/timezone';
3
+ import utc from 'dayjs/plugin/utc';
1
4
  import { useAtomValue } from 'jotai';
2
- import { makeStyles } from 'tss-react/mui';
3
5
  import { equals } from 'ramda';
4
6
  import { useTranslation } from 'react-i18next';
5
- import dayjs from 'dayjs';
6
- import utc from 'dayjs/plugin/utc';
7
- import timezone from 'dayjs/plugin/timezone';
7
+ import { makeStyles } from 'tss-react/mui';
8
8
 
9
- import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
10
9
  import { Typography } from '@mui/material';
11
10
  import { LocalizationProvider } from '@mui/x-date-pickers';
11
+ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
12
12
 
13
13
  import { userAtom } from '@centreon/ui-context';
14
14
 
15
+ import { isInvalidDate } from '../../helpers';
15
16
  import DateTimePickerInput from '../../DateTimePickerInput';
16
17
  import {
17
18
  CustomTimePeriodProperty,
@@ -20,8 +21,10 @@ import {
20
21
  import { errorTimePeriodAtom } from '../../timePeriodsAtoms';
21
22
 
22
23
  import ErrorText from './ErrorText';
23
- import { PickersData, PickersStartEndDateDirection } from './models';
24
- import { PickersStartEndDateModel } from './usePickersStartEndDate';
24
+ import {
25
+ PickersStartEndDateDirection,
26
+ PickersStartEndDateProps
27
+ } from './models';
25
28
 
26
29
  dayjs.extend(utc);
27
30
  dayjs.extend(timezone);
@@ -37,9 +40,6 @@ const useStyles = makeStyles()((theme) => ({
37
40
  justifyItems: 'center',
38
41
  padding: 0
39
42
  },
40
- horizontalError: {
41
- textAlign: 'left'
42
- },
43
43
  row: {
44
44
  alignItems: 'center',
45
45
  display: 'flex',
@@ -89,17 +89,6 @@ const PickerDateWithLabel = ({
89
89
  );
90
90
  };
91
91
 
92
- interface DisabledPicker {
93
- isDisabledEndPicker?: boolean;
94
- isDisabledStartPicker?: boolean;
95
- }
96
- type PickersDate = Pick<PickersData, 'rangeEndDate' | 'rangeStartDate'>;
97
-
98
- interface Props extends PickersDate, PickersStartEndDateModel {
99
- direction?: PickersStartEndDateDirection;
100
- disabled?: DisabledPicker;
101
- }
102
-
103
92
  const PickersStartEndDate = ({
104
93
  startDate,
105
94
  endDate,
@@ -108,11 +97,12 @@ const PickersStartEndDate = ({
108
97
  rangeStartDate,
109
98
  rangeEndDate,
110
99
  direction = PickersStartEndDateDirection.column
111
- }: Props): JSX.Element => {
112
- const { classes, cx } = useStyles();
100
+ }: PickersStartEndDateProps): JSX.Element => {
101
+ const { classes } = useStyles();
113
102
 
114
103
  const { locale } = useAtomValue(userAtom);
115
104
  const error = useAtomValue(errorTimePeriodAtom);
105
+ const isError = error || isInvalidDate({ endDate, startDate });
116
106
 
117
107
  const maxStart = rangeStartDate?.max || endDate;
118
108
  const minStart = rangeStartDate?.min;
@@ -123,11 +113,6 @@ const PickersStartEndDate = ({
123
113
  ? classes.verticalDirection
124
114
  : classes.horizontalDirection;
125
115
 
126
- const isHorizontalDirection = equals(
127
- direction,
128
- PickersStartEndDateDirection.row
129
- );
130
-
131
116
  return (
132
117
  <LocalizationProvider
133
118
  adapterLocale={locale.substring(0, 2)}
@@ -156,12 +141,10 @@ const PickersStartEndDate = ({
156
141
  />
157
142
  </div>
158
143
 
159
- {error && (
144
+ {isError && (
160
145
  <ErrorText
161
146
  message="The end date must be greater than the start date"
162
- style={cx(classes.error, {
163
- [classes.horizontalError]: isHorizontalDirection
164
- })}
147
+ style={classes.error}
165
148
  />
166
149
  )}
167
150
  </LocalizationProvider>
@@ -2,6 +2,8 @@ import { PopoverOrigin, PopoverPosition } from '@mui/material';
2
2
 
3
3
  import { CustomTimePeriod, CustomTimePeriodProperty } from '../../models';
4
4
 
5
+ import { PickersStartEndDateModel } from './usePickersStartEndDate';
6
+
5
7
  interface RangeDate {
6
8
  max?: Date;
7
9
  min?: Date;
@@ -57,3 +59,16 @@ export enum PickersStartEndDateDirection {
57
59
  column = 'column',
58
60
  row = 'row'
59
61
  }
62
+
63
+ interface DisabledPicker {
64
+ isDisabledEndPicker?: boolean;
65
+ isDisabledStartPicker?: boolean;
66
+ }
67
+ type PickersDate = Pick<PickersData, 'rangeEndDate' | 'rangeStartDate'>;
68
+
69
+ export interface PickersStartEndDateProps
70
+ extends PickersDate,
71
+ PickersStartEndDateModel {
72
+ direction?: PickersStartEndDateDirection;
73
+ disabled?: DisabledPicker;
74
+ }
@@ -4,6 +4,7 @@ import dayjs from 'dayjs';
4
4
  import { useSetAtom } from 'jotai';
5
5
  import { and, cond, equals, isNil } from 'ramda';
6
6
 
7
+ import { isInvalidDate } from '../../helpers';
7
8
  import { CustomTimePeriod, CustomTimePeriodProperty } from '../../models';
8
9
  import { errorTimePeriodAtom } from '../../timePeriodsAtoms';
9
10
 
@@ -32,9 +33,6 @@ const usePickersStartEndDate = ({
32
33
 
33
34
  const setError = useSetAtom(errorTimePeriodAtom);
34
35
 
35
- const isInvalidDate = ({ startDate, endDate }): boolean =>
36
- dayjs(startDate).isSameOrAfter(dayjs(endDate), 'minute');
37
-
38
36
  const changeDate = ({ property, date }): void => {
39
37
  const currentDate = customTimePeriod[property];
40
38
  cond([
@@ -1,7 +1,8 @@
1
1
  import PickersStartEndDate from './PopoverCustomTimePeriod/PickersStartEndDate';
2
2
  import {
3
3
  AcceptDateProps,
4
- PickersStartEndDateDirection
4
+ PickersStartEndDateDirection,
5
+ PickersStartEndDateProps
5
6
  } from './PopoverCustomTimePeriod/models';
6
7
 
7
8
  interface Props {
@@ -13,14 +14,19 @@ interface Props {
13
14
  const SimpleCustomTimePeriod = ({
14
15
  startDate,
15
16
  endDate,
16
- changeDate
17
- }: Props): JSX.Element => {
17
+ changeDate,
18
+ ...rest
19
+ }: Props &
20
+ Partial<
21
+ Omit<PickersStartEndDateProps, 'startDate' | 'endDate' | 'changeDate'>
22
+ >): JSX.Element => {
18
23
  return (
19
24
  <PickersStartEndDate
20
25
  changeDate={changeDate}
21
26
  direction={PickersStartEndDateDirection.row}
22
27
  endDate={endDate}
23
28
  startDate={startDate}
29
+ {...rest}
24
30
  />
25
31
  );
26
32
  };
@@ -1,4 +1,5 @@
1
1
  import { find, propEq } from 'ramda';
2
+ import dayjs from 'dayjs';
2
3
 
3
4
  import {
4
5
  CustomTimePeriod,
@@ -24,3 +25,6 @@ export const getTimePeriodById = ({
24
25
  timePeriods
25
26
  }: TimePeriodById): TimePeriod =>
26
27
  find<TimePeriod>(propEq(id, 'id'))(timePeriods) as TimePeriod;
28
+
29
+ export const isInvalidDate = ({ startDate, endDate }): boolean =>
30
+ dayjs(startDate).isSameOrAfter(dayjs(endDate), 'minute');
@@ -1,6 +1,6 @@
1
1
  import React, { ReactElement, ReactNode } from 'react';
2
2
 
3
- import { DialogTitle as MuiDialogTitle } from '@mui/material';
3
+ import { DialogTitleProps, DialogTitle as MuiDialogTitle } from '@mui/material';
4
4
 
5
5
  import { useStyles } from './Modal.styles';
6
6
 
@@ -8,12 +8,17 @@ export type ModalHeaderProps = {
8
8
  children?: ReactNode;
9
9
  };
10
10
 
11
- const ModalHeader = ({ children }: ModalHeaderProps): ReactElement => {
11
+ const ModalHeader = ({
12
+ children,
13
+ ...rest
14
+ }: ModalHeaderProps & DialogTitleProps): ReactElement => {
12
15
  const { classes } = useStyles();
13
16
 
14
17
  return (
15
18
  <div className={classes.modalHeader}>
16
- <MuiDialogTitle color="primary">{children}</MuiDialogTitle>
19
+ <MuiDialogTitle color="primary" {...rest}>
20
+ {children}
21
+ </MuiDialogTitle>
17
22
  </div>
18
23
  );
19
24
  };
package/src/index.ts CHANGED
@@ -166,3 +166,4 @@ export * from './ParentSize';
166
166
  export { default as Subtitle } from './Typography/Subtitle';
167
167
  export { default as TablePagination } from './Listing/ActionBar/Pagination';
168
168
  export { default as PaginationActions } from './Listing/ActionBar/PaginationActions';
169
+ export * from './Icon';
@@ -25,3 +25,4 @@ export * from './useFullscreen';
25
25
  export * from './resourcesStatusURL';
26
26
  export * from '../Graph/LineChart/helpers';
27
27
  export * from '../Graph/LineChart/InteractiveComponents/TimeShiftZones/useTimeShiftZones';
28
+ export * from '../TimePeriods/helpers';
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><defs><style>.a{fill:none;}.b{opacity:1;}</style></defs><g transform="translate(-94.852 -137.365)"><rect class="a" width="24" height="24" transform="translate(94.852 137.365)"/><g class="b" transform="translate(97.108 140.129)"><path d="M103.476,143.64a1.692,1.692,0,1,0-1.692-1.692A1.692,1.692,0,0,0,103.476,143.64Z" transform="translate(-97.132 -140.255)"/><path d="M114.266,150.2a1.05,1.05,0,0,0-.968-.647s-2.067-.275-2.68.125a2.464,2.464,0,0,0-.644.8l-3.454-.547c-.265-.874-1.4-4.183-1.4-4.183l-.846-1.353a1.743,1.743,0,0,0-1.438-.846,4.571,4.571,0,0,0-.677.084l-4.4,1.867v3.976H98l2.222.352-1.61,8.107h1.777l1.522-6.768,1.777,1.692v5.076h1.692v-6.345l-1.19-1.135,5.428.859-3.084,6.815,10.976-.11Zm-10.206-2.611s.577,1.356.88,2.089l-1.259-.2Zm-4.606,1.22v-2.212l1.522-.592-.586,2.952Z" transform="translate(-97.762 -139.74)"/></g></g></svg>
@@ -1,9 +0,0 @@
1
- import { SvgIcon, SvgIconProps } from '@mui/material';
2
-
3
- import IconDowntime from '../../../@assets/icons/downtime.icon.svg';
4
-
5
- const Downtime = (props: SvgIconProps): JSX.Element => (
6
- <SvgIcon component={IconDowntime} {...props} />
7
- );
8
-
9
- export default Downtime;