@centreon/ui 24.4.1-MON-23368-containers.80 → 24.4.1-MON-34459-fullscreen-mode.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "24.4.1-MON-23368-containers.80",
3
+ "version": "24.4.1-MON-34459-fullscreen-mode.3",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -48,11 +48,11 @@
48
48
  "test/*"
49
49
  ],
50
50
  "devDependencies": {
51
- "@cypress/react": "^8.0.0",
52
- "@cypress/webpack-dev-server": "^3.7.3",
51
+ "@cypress/react": "^7.0.2",
52
+ "@cypress/webpack-dev-server": "^3.2.3",
53
53
  "@faker-js/faker": "^8.0.2",
54
- "@mdx-js/react": "^3.0.0",
55
- "@simonsmith/cypress-image-snapshot": "^9.0.1",
54
+ "@mdx-js/react": "^2.1.4",
55
+ "@simonsmith/cypress-image-snapshot": "^6.1.0",
56
56
  "@storybook/addon-a11y": "^7.0.9",
57
57
  "@storybook/addon-docs": "^7.0.9",
58
58
  "@storybook/addon-essentials": "^7.0.9",
@@ -73,15 +73,16 @@
73
73
  "@testing-library/jest-dom": "^5.16.5",
74
74
  "@testing-library/react": "^13.4.0",
75
75
  "@testing-library/react-hooks": "^8.0.1",
76
- "@types/jest": "^29.5.11",
76
+ "@types/cypress": "^1.1.3",
77
+ "@types/jest": "^27.5.0",
77
78
  "@types/mocha": "^10.0.6",
78
- "@types/ramda": "^0.29.9",
79
- "@types/react": "^18.2.48",
80
- "@types/testing-library__jest-dom": "^6.0.0",
79
+ "@types/ramda": "^0.29.6",
80
+ "@types/react": "^18.0.26",
81
+ "@types/testing-library__jest-dom": "^5.14.6",
81
82
  "@vitejs/plugin-react": "^4.0.0",
82
83
  "@vitejs/plugin-react-swc": "^3.3.0",
83
- "axios-mock-adapter": "^1.22.0",
84
- "cypress": "^13.6.2",
84
+ "axios-mock-adapter": "^1.21.4",
85
+ "cypress": "^13.3.1",
85
86
  "identity-obj-proxy": "^3.0.0",
86
87
  "jest-transform-stub": "^2.0.0",
87
88
  "mochawesome": "^7.1.3",
@@ -92,26 +93,27 @@
92
93
  "react-dom": "^18.2.0",
93
94
  "react-test-renderer": "^18.2.0",
94
95
  "remark-gfm": "^3.0.1",
96
+ "sass": "^1.62.1",
95
97
  "speed-measure-vite-plugin": "^0.1.2",
96
- "storybook": "^7.6.8",
98
+ "storybook": "^7.0.9",
97
99
  "storybook-addon-mock": "^4.0.0",
98
- "storybook-dark-mode": "^3.0.3",
100
+ "storybook-dark-mode": "^3.0.0",
99
101
  "style-dictionary": "^3.8.0",
100
- "ts-node": "^10.9.2",
102
+ "ts-node": "^10.9.1",
101
103
  "use-resize-observer": "^9.1.0",
102
104
  "vite": "^4.3.5",
103
105
  "vite-plugin-istanbul": "^5.0.0",
104
106
  "vite-plugin-svgr": "^3.2.0",
105
- "vite-plugin-turbosnap": "^1.0.3"
107
+ "vite-plugin-turbosnap": "^1.0.2"
106
108
  },
107
109
  "dependencies": {
108
- "@lexical/html": "^0.12.6",
109
- "@lexical/link": "^0.12.6",
110
- "@lexical/list": "^0.12.6",
111
- "@lexical/react": "^0.12.6",
112
- "@lexical/rich-text": "^0.12.6",
113
- "@lexical/selection": "^0.12.6",
114
- "@lexical/utils": "^0.12.6",
110
+ "@lexical/html": "^0.12.2",
111
+ "@lexical/link": "^0.12.2",
112
+ "@lexical/list": "^0.12.2",
113
+ "@lexical/react": "^0.12.2",
114
+ "@lexical/rich-text": "^0.12.2",
115
+ "@lexical/selection": "^0.12.2",
116
+ "@lexical/utils": "^0.12.2",
115
117
  "@react-spring/web": "^9.7.3",
116
118
  "@visx/curve": "^2.1.0",
117
119
  "@visx/group": "^3.3.0",
@@ -123,9 +125,9 @@
123
125
  "@visx/threshold": "^2.12.2",
124
126
  "@visx/visx": "2.16.0",
125
127
  "anylogger": "^1.0.11",
126
- "d3-array": "3.2.4",
128
+ "d3-array": "3.2.0",
127
129
  "humanize-duration": "^3.27.3",
128
- "lexical": "^0.12.6",
130
+ "lexical": "^0.12.2",
129
131
  "notistack": "^3.0.1",
130
132
  "numeral": "^2.0.6",
131
133
  "ramda": "0.29.1",
@@ -46,10 +46,7 @@ const CheckboxGroup = ({
46
46
  return;
47
47
  }
48
48
 
49
- setFieldValue(
50
- fieldName,
51
- value?.filter((elm) => !equals(elm, label))
52
- );
49
+ setFieldValue(fieldName, value?.filter((elm) => !equals(elm, label)));
53
50
  };
54
51
 
55
52
  return useMemoComponent({
@@ -130,10 +130,11 @@ const WrapperThresholdLines = ({
130
130
 
131
131
  return (
132
132
  <g>
133
- {filteredThresholdLines.map((element) =>
134
- element?.map(({ Component, props, key }) => (
135
- <Component {...props} id={key} key={key} />
136
- ))
133
+ {filteredThresholdLines.map(
134
+ (element) =>
135
+ element?.map(({ Component, props, key }) => (
136
+ <Component {...props} id={key} key={key} />
137
+ ))
137
138
  )}
138
139
  </g>
139
140
  );
@@ -43,9 +43,8 @@ const Annotation = ({
43
43
 
44
44
  const setAnnotationHovered = useSetAtom(annotationHoveredAtom);
45
45
 
46
- const content = `${truncate(event.content)} (${t(labelBy)} ${
47
- event.contact?.name
48
- })`;
46
+ const content = `${truncate(event.content)} (${t(labelBy)} ${event.contact
47
+ ?.name})`;
49
48
 
50
49
  return (
51
50
  <g>
@@ -21,3 +21,4 @@ export * from './useRefreshInterval';
21
21
  export * from './centreonBaseURL';
22
22
  export * from './usePluralizedTranslation';
23
23
  export * from './useResizeObserver';
24
+ export * from './useFullscreen';
@@ -0,0 +1,109 @@
1
+ import { Provider, createStore } from 'jotai';
2
+ import { BrowserRouter } from 'react-router-dom';
3
+
4
+ import { Button } from '@mui/material';
5
+
6
+ import { useFullscreen } from './useFullscreen';
7
+ import { router, useFullscreenListener } from './useFullscreenListener';
8
+
9
+ const labelEnterFullscreen = 'Enter fullscreen';
10
+ const labelExitFullscreen = 'Exit fullscreen';
11
+
12
+ const ChildComponent = (): JSX.Element => {
13
+ const { toggleFullscreen, fullscreenEnabled, isFullscreenActivated } =
14
+ useFullscreen();
15
+
16
+ return (
17
+ <div
18
+ data-fullscreenActivated={isFullscreenActivated}
19
+ data-fullscreenEnabled={fullscreenEnabled}
20
+ id="test"
21
+ >
22
+ <Button onClick={() => toggleFullscreen(document.body)}>
23
+ {isFullscreenActivated ? labelExitFullscreen : labelEnterFullscreen}
24
+ </Button>
25
+ </div>
26
+ );
27
+ };
28
+
29
+ const TestComponent = (): JSX.Element => {
30
+ useFullscreenListener();
31
+
32
+ return <ChildComponent />;
33
+ };
34
+
35
+ const initialize = (): void => {
36
+ const store = createStore();
37
+
38
+ const queryParameters = new Map();
39
+
40
+ cy.stub(router, 'useSearchParams', () => queryParameters);
41
+
42
+ cy.mount({
43
+ Component: (
44
+ <BrowserRouter>
45
+ <Provider store={store}>
46
+ <TestComponent />
47
+ </Provider>
48
+ </BrowserRouter>
49
+ )
50
+ });
51
+ };
52
+
53
+ describe('Fullscreen', () => {
54
+ it('enters fullscreen mode when the button is clicked', () => {
55
+ initialize();
56
+
57
+ cy.get('#test')
58
+ .should('have.attr', 'data-fullscreenActivated', 'false')
59
+ .should('have.attr', 'data-fullscreenEnabled', 'true');
60
+
61
+ cy.contains(labelEnterFullscreen).realClick();
62
+
63
+ cy.get('#test')
64
+ .should('have.attr', 'data-fullscreenActivated', 'true')
65
+ .should('have.attr', 'data-fullscreenEnabled', 'true');
66
+
67
+ cy.contains(labelExitFullscreen).realClick();
68
+ });
69
+
70
+ it('exits fullscreen mode when the button is clicked', () => {
71
+ initialize();
72
+
73
+ cy.get('#test')
74
+ .should('have.attr', 'data-fullscreenActivated', 'false')
75
+ .should('have.attr', 'data-fullscreenEnabled', 'true');
76
+
77
+ cy.contains(labelEnterFullscreen).realClick();
78
+
79
+ cy.get('#test')
80
+ .should('have.attr', 'data-fullscreenActivated', 'true')
81
+ .should('have.attr', 'data-fullscreenEnabled', 'true');
82
+
83
+ cy.contains(labelExitFullscreen).realClick();
84
+
85
+ cy.get('#test')
86
+ .should('have.attr', 'data-fullscreenActivated', 'false')
87
+ .should('have.attr', 'data-fullscreenEnabled', 'true');
88
+ });
89
+
90
+ it('toggles fullscreen mode when the corresponding shortcut is clicked', () => {
91
+ initialize();
92
+
93
+ cy.get('#test')
94
+ .should('have.attr', 'data-fullscreenActivated', 'false')
95
+ .should('have.attr', 'data-fullscreenEnabled', 'true');
96
+
97
+ cy.get('#test').realPress(['Alt', 'F']);
98
+
99
+ cy.get('#test')
100
+ .should('have.attr', 'data-fullscreenActivated', 'true')
101
+ .should('have.attr', 'data-fullscreenEnabled', 'true');
102
+
103
+ cy.get('#test').realPress(['Alt', 'F']);
104
+
105
+ cy.get('#test')
106
+ .should('have.attr', 'data-fullscreenActivated', 'false')
107
+ .should('have.attr', 'data-fullscreenEnabled', 'true');
108
+ });
109
+ });
@@ -0,0 +1,3 @@
1
+ import { atom } from 'jotai';
2
+
3
+ export const isFullscreenActivatedAtom = atom(false);
@@ -0,0 +1,2 @@
1
+ export * from './useFullscreen';
2
+ export * from './useFullscreenListener';
@@ -0,0 +1 @@
1
+ export const labelCannotEnterInFullscreen = 'Cannot enter fullscreen mode';
@@ -0,0 +1,73 @@
1
+ import { useTranslation } from 'react-i18next';
2
+ import { useAtom } from 'jotai';
3
+
4
+ import { useSnackbar } from '../..';
5
+
6
+ import { labelCannotEnterInFullscreen } from './translatedLabels';
7
+ import { isFullscreenActivatedAtom } from './atoms';
8
+
9
+ interface UseFullscreenState {
10
+ enterInFullscreen: (element: HTMLElement | null) => void;
11
+ exitFullscreen: () => void;
12
+ fullscreenEnabled: boolean;
13
+ isFullscreenActivated: boolean;
14
+ resetVariables: () => void;
15
+ toggleFullscreen: (element: HTMLElement | null) => void;
16
+ }
17
+
18
+ export const useFullscreen = (): UseFullscreenState => {
19
+ const { t } = useTranslation();
20
+
21
+ const { showErrorMessage } = useSnackbar();
22
+
23
+ const [isFullscreenActivated, setIsFullscreenActivated] = useAtom(
24
+ isFullscreenActivatedAtom
25
+ );
26
+
27
+ const resetVariables = (): void => {
28
+ setIsFullscreenActivated(false);
29
+ };
30
+
31
+ const enterInFullscreen = (element: HTMLElement | null): void => {
32
+ if (!document.fullscreenEnabled) {
33
+ return;
34
+ }
35
+
36
+ if (!element) {
37
+ showErrorMessage(t(labelCannotEnterInFullscreen));
38
+ }
39
+
40
+ element
41
+ ?.requestFullscreen({ navigationUI: 'show' })
42
+ .then(() => {
43
+ setIsFullscreenActivated(true);
44
+ })
45
+ .catch(() => {
46
+ showErrorMessage(t(labelCannotEnterInFullscreen));
47
+ setIsFullscreenActivated(false);
48
+ });
49
+ };
50
+
51
+ const exitFullscreen = (): void => {
52
+ document.exitFullscreen().then(resetVariables);
53
+ };
54
+
55
+ const toggleFullscreen = (element: HTMLElement | null): void => {
56
+ if (isFullscreenActivated) {
57
+ exitFullscreen();
58
+
59
+ return;
60
+ }
61
+
62
+ enterInFullscreen(element);
63
+ };
64
+
65
+ return {
66
+ enterInFullscreen,
67
+ exitFullscreen,
68
+ fullscreenEnabled: document.fullscreenEnabled,
69
+ isFullscreenActivated,
70
+ resetVariables,
71
+ toggleFullscreen
72
+ };
73
+ };
@@ -0,0 +1,54 @@
1
+ import { useEffect } from 'react';
2
+
3
+ import { equals } from 'ramda';
4
+ import { useSearchParams } from 'react-router-dom';
5
+
6
+ import { useDeepCompare } from '../useMemoComponent';
7
+
8
+ import { useFullscreen } from './useFullscreen';
9
+
10
+ export const router = {
11
+ useSearchParams
12
+ };
13
+
14
+ export const useFullscreenListener = (): boolean => {
15
+ const { toggleFullscreen, resetVariables, isFullscreenActivated } =
16
+ useFullscreen();
17
+
18
+ const toggle = (event: KeyboardEvent): void => {
19
+ if (!event.altKey || !equals(event.code, 'KeyF')) {
20
+ return;
21
+ }
22
+
23
+ toggleFullscreen(document.querySelector('body'));
24
+ };
25
+
26
+ const changeFullscreen = (): void => {
27
+ if (document.fullscreenElement) {
28
+ return;
29
+ }
30
+
31
+ resetVariables();
32
+ };
33
+
34
+ useEffect(
35
+ () => {
36
+ document.addEventListener('fullscreenchange', changeFullscreen);
37
+
38
+ return () => {
39
+ document.removeEventListener('fullscreenchange', changeFullscreen);
40
+ };
41
+ },
42
+ useDeepCompare([document.fullscreenElement])
43
+ );
44
+
45
+ useEffect(() => {
46
+ window.addEventListener('keypress', toggle);
47
+
48
+ return () => {
49
+ window.removeEventListener('keypress', toggle);
50
+ };
51
+ }, [isFullscreenActivated]);
52
+
53
+ return isFullscreenActivated;
54
+ };