@centreon/ui 24.4.10 → 24.4.12

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.10",
3
+ "version": "24.4.12",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -21,7 +21,7 @@ type Props = {
21
21
  ariaLabel?: string;
22
22
  className?: string;
23
23
  onClick: (event) => void;
24
- title?: string;
24
+ title?: string | JSX.Element;
25
25
  tooltipClassName?: string;
26
26
  tooltipPlacement?:
27
27
  | 'bottom'
@@ -77,9 +77,9 @@ const mountListing = (): void => {
77
77
  subItems={{
78
78
  canCheckSubItems: false,
79
79
  enable: true,
80
+ getRowProperty: () => 'subItems',
80
81
  labelCollapse: 'Collapse',
81
- labelExpand: 'Expand',
82
- rowProperty: 'subItems'
82
+ labelExpand: 'Expand'
83
83
  }}
84
84
  totalRows={10}
85
85
  />
@@ -387,9 +387,9 @@ export const ListingWithSubItems = {
387
387
  subItems: {
388
388
  canCheckSubItems: false,
389
389
  enable: true,
390
+ getRowProperty: () => 'subItems',
390
391
  labelCollapse: 'Collapse',
391
- labelExpand: 'Expand',
392
- rowProperty: 'subItems'
392
+ labelExpand: 'Expand'
393
393
  },
394
394
  totalRows: 10
395
395
  },
@@ -121,9 +121,9 @@ export interface Props<TRow> {
121
121
  subItems?: {
122
122
  canCheckSubItems: boolean;
123
123
  enable: boolean;
124
+ getRowProperty: (row?) => string;
124
125
  labelCollapse: string;
125
126
  labelExpand: string;
126
- rowProperty: string;
127
127
  };
128
128
  totalRows?: number;
129
129
  viewerModeConfiguration?: ViewerModeConfiguration;
@@ -176,9 +176,9 @@ const Listing = <TRow extends { id: RowId }>({
176
176
  subItems = {
177
177
  canCheckSubItems: false,
178
178
  enable: false,
179
+ getRowProperty: () => '',
179
180
  labelCollapse: 'Collapse',
180
- labelExpand: 'Expand',
181
- rowProperty: ''
181
+ labelExpand: 'Expand'
182
182
  }
183
183
  }: Props<TRow>): JSX.Element => {
184
184
  const currentVisibleColumns = getVisibleColumns({
@@ -211,10 +211,10 @@ const Listing = <TRow extends { id: RowId }>({
211
211
  ? reduce<TRow, Array<TRow>>(
212
212
  (acc, row): Array<TRow> => {
213
213
  if (
214
- row[subItems.rowProperty] &&
214
+ row[subItems.getRowProperty()] &&
215
215
  subItemsPivots.includes(row.id)
216
216
  ) {
217
- return [...acc, row, ...row[subItems.rowProperty]];
217
+ return [...acc, row, ...row[subItems.getRowProperty()]];
218
218
  }
219
219
 
220
220
  return [...acc, row];
@@ -449,7 +449,7 @@ const Listing = <TRow extends { id: RowId }>({
449
449
  reduce<TRow | number, Array<string | number>>(
450
450
  (acc, row) => [
451
451
  ...acc,
452
- ...pluck('id', row[subItems?.rowProperty || ''] || [])
452
+ ...pluck('id', row[subItems?.getRowProperty() || ''] || [])
453
453
  ],
454
454
  [],
455
455
  rows
@@ -620,7 +620,7 @@ const Listing = <TRow extends { id: RowId }>({
620
620
  listingVariant={listingVariant}
621
621
  row={row}
622
622
  rowColorConditions={rowColorConditions}
623
- subItemsRowProperty={subItems?.rowProperty}
623
+ subItemsRowProperty={subItems?.getRowProperty(row)}
624
624
  />
625
625
  ))}
626
626
  </ListingRow>
@@ -147,6 +147,30 @@ export const getTheme = (mode: ThemeMode): ThemeOptions => ({
147
147
  },
148
148
  MuiCssBaseline: {
149
149
  styleOverrides: (theme) => `
150
+ ::-webkit-scrollbar {
151
+ height: ${theme.spacing(1)};
152
+ width: ${theme.spacing(1)};
153
+ background-color: transparent;
154
+ }
155
+ ::-webkit-scrollbar-thumb {
156
+ background-color: ${
157
+ equals(mode, 'dark')
158
+ ? theme.palette.divider
159
+ : theme.palette.text.disabled
160
+ };
161
+ border-radius: ${theme.spacing(0.5)};
162
+ }
163
+ ::-webkit-scrollbar-thumb:hover {
164
+ background-color: ${theme.palette.primary.main};
165
+ }
166
+ * {
167
+ scrollbar-color: ${
168
+ equals(mode, 'dark')
169
+ ? theme.palette.divider
170
+ : theme.palette.text.disabled
171
+ } ${theme.palette.background.default};
172
+ scrollbar-width: thin;
173
+ }
150
174
  html {
151
175
  margin: 0;
152
176
  padding: 0;
@@ -1,6 +1,9 @@
1
1
  import React, { ReactElement, ReactNode } from 'react';
2
2
 
3
- import { IconButton as MuiIconButton } from '@mui/material';
3
+ import {
4
+ IconButton as MuiIconButton,
5
+ IconButtonProps as MuiIconButtonProps
6
+ } from '@mui/material';
4
7
 
5
8
  import { AriaLabelingAttributes } from '../../../@types/aria-attributes';
6
9
  import { DataTestAttributes } from '../../../@types/data-attributes';
@@ -23,7 +26,8 @@ type IconButtonProps = {
23
26
  size?: 'small' | 'medium' | 'large';
24
27
  variant?: 'primary' | 'secondary' | 'ghost';
25
28
  } & AriaLabelingAttributes &
26
- DataTestAttributes;
29
+ DataTestAttributes &
30
+ MuiIconButtonProps;
27
31
 
28
32
  /**
29
33
  * @todo re-factor as `iconVariant: 'icon-only'` Button variant, and remove IconButton component (reason: code duplication)
@@ -14,7 +14,7 @@ export const PageLayout = ({
14
14
  const { classes } = useStyles();
15
15
 
16
16
  return (
17
- <section className={classes.pageLayout} data-variant={variant}>
17
+ <section className={classes.pageLayout} data-variant={variant} id="page">
18
18
  {children}
19
19
  </section>
20
20
  );
@@ -17,6 +17,7 @@ export const PageLayoutActions = ({
17
17
  <section
18
18
  className={classes.pageLayoutActions}
19
19
  data-row-reverse={rowReverse}
20
+ id="actions"
20
21
  >
21
22
  {children}
22
23
  </section>
@@ -17,6 +17,7 @@ export const PageLayoutBody = ({
17
17
  <section
18
18
  className={classes.pageLayoutBody}
19
19
  data-has-background={hasBackground}
20
+ id="page-body"
20
21
  >
21
22
  {children}
22
23
  </section>
@@ -11,5 +11,9 @@ export const PageLayoutHeader = ({
11
11
  }: PageLayoutHeaderProps): JSX.Element => {
12
12
  const { classes } = useStyles();
13
13
 
14
- return <header className={classes.pageLayoutHeader}>{children}</header>;
14
+ return (
15
+ <header className={classes.pageLayoutHeader} id="header">
16
+ {children}
17
+ </header>
18
+ );
15
19
  };
@@ -0,0 +1,76 @@
1
+ import { useTranslation } from 'react-i18next';
2
+
3
+ import AddIcon from '@mui/icons-material/Add';
4
+ import ArrowBackIcon from '@mui/icons-material/ArrowBack';
5
+
6
+ import { Button, Menu } from '../..';
7
+
8
+ interface NamedEntity {
9
+ id: number | string;
10
+ name: string;
11
+ }
12
+
13
+ type Props = {
14
+ create: () => void;
15
+ elements: Array<NamedEntity>;
16
+ goBack: () => void;
17
+ isActive: (id: number | string) => boolean;
18
+ labels: {
19
+ create: string;
20
+ goBack: string;
21
+ };
22
+ navigateToElement: (id: number | string) => () => void;
23
+ };
24
+
25
+ export const PageQuickAccess = ({
26
+ elements,
27
+ isActive,
28
+ navigateToElement,
29
+ goBack,
30
+ create,
31
+ labels
32
+ }: Props): JSX.Element => {
33
+ const { t } = useTranslation();
34
+
35
+ return (
36
+ <Menu>
37
+ <Menu.Button data-testid="quickaccess" />
38
+ <Menu.Items>
39
+ {elements &&
40
+ elements.map((element) => (
41
+ <Menu.Item
42
+ key={`${element.id}`}
43
+ onClick={navigateToElement(element.id)}
44
+ {...(isActive(element.id) && {
45
+ isActive: true,
46
+ isDisabled: true
47
+ })}
48
+ >
49
+ {element.name}
50
+ </Menu.Item>
51
+ ))}
52
+ <Menu.Divider key="divider" />
53
+ <Menu.Item key="create">
54
+ <>
55
+ <Button
56
+ icon={<ArrowBackIcon />}
57
+ iconVariant="start"
58
+ variant="ghost"
59
+ onClick={goBack}
60
+ >
61
+ {t(labels.goBack)}
62
+ </Button>
63
+ <Button
64
+ icon={<AddIcon />}
65
+ iconVariant="start"
66
+ variant="secondary"
67
+ onClick={create}
68
+ >
69
+ {t(labels.create)}
70
+ </Button>
71
+ </>
72
+ </Menu.Item>
73
+ </Menu.Items>
74
+ </Menu>
75
+ );
76
+ };
@@ -2,9 +2,11 @@ import { PageLayout as PageLayoutRoot } from './PageLayout';
2
2
  import { PageLayoutHeader } from './PageLayoutHeader';
3
3
  import { PageLayoutBody } from './PageLayoutBody';
4
4
  import { PageLayoutActions } from './PageLayoutActions';
5
+ import { PageQuickAccess } from './PageQuickAccess';
5
6
 
6
7
  export const PageLayout = Object.assign(PageLayoutRoot, {
7
8
  Actions: PageLayoutActions,
8
9
  Body: PageLayoutBody,
9
- Header: PageLayoutHeader
10
+ Header: PageLayoutHeader,
11
+ QuickAccess: PageQuickAccess
10
12
  });
@@ -0,0 +1,66 @@
1
+ import { T } from 'ramda';
2
+
3
+ import { PageHeader } from '..';
4
+
5
+ import { AreaIndicator } from './AreaIndicator';
6
+
7
+ import { PageLayout } from '.';
8
+
9
+ const initialize = (): void => {
10
+ cy.mount({
11
+ Component: (
12
+ <PageLayout>
13
+ <PageLayout.Header>
14
+ <PageHeader>
15
+ <PageHeader.Menu>
16
+ <PageLayout.QuickAccess
17
+ create={cy.stub()}
18
+ elements={[
19
+ {
20
+ id: 1,
21
+ name: 'Entity'
22
+ }
23
+ ]}
24
+ goBack={cy.stub()}
25
+ isActive={T}
26
+ labels={{
27
+ create: 'Create',
28
+ goBack: 'Go back'
29
+ }}
30
+ navigateToElement={cy.stub()}
31
+ />
32
+ </PageHeader.Menu>
33
+ <PageHeader.Main>
34
+ <PageHeader.Title description="Description" title="Title" />
35
+ </PageHeader.Main>
36
+ <PageHeader.Actions>Actions</PageHeader.Actions>
37
+ </PageHeader>
38
+ </PageLayout.Header>
39
+ <PageLayout.Body>
40
+ <PageLayout.Actions>
41
+ <AreaIndicator name="Body actions" />
42
+ </PageLayout.Actions>
43
+ <h1>Content</h1>
44
+ </PageLayout.Body>
45
+ </PageLayout>
46
+ )
47
+ });
48
+ };
49
+
50
+ describe('Page layout', () => {
51
+ beforeEach(initialize);
52
+
53
+ it('displays the page layout', () => {
54
+ cy.makeSnapshot();
55
+ });
56
+
57
+ it('opens the quick access poppin when the corresponding logo is displayed', () => {
58
+ cy.findByTestId('quickaccess').click();
59
+
60
+ cy.contains('Entity').should('be.visible');
61
+ cy.contains('Create').should('be.visible');
62
+ cy.contains('Go back').should('be.visible');
63
+
64
+ cy.makeSnapshot();
65
+ });
66
+ });