@centreon/ui 24.4.1-sync-release-34022.1 → 24.4.1-sync-dev-2404.0

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.
Files changed (221) hide show
  1. package/package.json +48 -40
  2. package/src/ActionsList/ActionsList.styles.ts +40 -71
  3. package/src/Button/Icon/index.stories.tsx +1 -1
  4. package/src/Button/Icon/index.tsx +1 -1
  5. package/src/Dashboard/Dashboard.styles.ts +6 -5
  6. package/src/Dialog/Confirm/index.tsx +10 -2
  7. package/src/Dialog/UnsavedChanges/index.tsx +21 -20
  8. package/src/Dialog/UnsavedChanges/translatedLabels.ts +4 -6
  9. package/src/Dialog/index.tsx +8 -1
  10. package/src/Form/Inputs/CheckboxGroup.tsx +4 -1
  11. package/src/Form/Inputs/Text.tsx +3 -1
  12. package/src/Form/Inputs/models.ts +1 -0
  13. package/src/Graph/BarStack/BarStack.cypress.spec.tsx +139 -0
  14. package/src/Graph/BarStack/BarStack.stories.tsx +123 -0
  15. package/src/Graph/BarStack/BarStack.styles.ts +37 -0
  16. package/src/Graph/BarStack/BarStack.tsx +14 -0
  17. package/src/Graph/BarStack/ResponsiveBarStack.tsx +209 -0
  18. package/src/Graph/BarStack/index.ts +1 -0
  19. package/src/Graph/BarStack/models.ts +19 -0
  20. package/src/Graph/BarStack/useResponsiveBarStack.ts +131 -0
  21. package/src/Graph/Gauge/Gauge.cypress.spec.tsx +102 -0
  22. package/src/Graph/Gauge/Gauge.tsx +1 -1
  23. package/src/Graph/HeatMap/HeatMap.cypress.spec.tsx +145 -0
  24. package/src/Graph/HeatMap/HeatMap.stories.tsx +0 -25
  25. package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +8 -2
  26. package/src/Graph/Legend/Legend.tsx +21 -0
  27. package/src/Graph/Legend/index.ts +1 -0
  28. package/src/Graph/Legend/models.ts +11 -0
  29. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/index.tsx +4 -5
  30. package/src/Graph/LineChart/BasicComponents/ThresholdLine.tsx +3 -1
  31. package/src/Graph/LineChart/Header/index.tsx +3 -31
  32. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/useTickGraph.ts +9 -11
  33. package/src/Graph/LineChart/InteractiveComponents/Annotations/Annotation/index.tsx +3 -2
  34. package/src/Graph/LineChart/InteractiveComponents/GraphValueTooltip/GraphValueTooltip.tsx +68 -0
  35. package/src/Graph/LineChart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +27 -0
  36. package/src/Graph/LineChart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltipStyles.ts +31 -0
  37. package/src/Graph/LineChart/InteractiveComponents/index.tsx +132 -17
  38. package/src/Graph/LineChart/InteractiveComponents/interactionWithGraphAtoms.ts +7 -27
  39. package/src/Graph/LineChart/Legend/Legend.styles.ts +5 -9
  40. package/src/Graph/LineChart/Legend/LegendHeader.tsx +10 -22
  41. package/src/Graph/LineChart/Legend/index.tsx +17 -55
  42. package/src/Graph/LineChart/LineChart.cypress.spec.tsx +91 -0
  43. package/src/Graph/LineChart/LineChart.styles.ts +8 -0
  44. package/src/Graph/LineChart/LineChart.tsx +106 -116
  45. package/src/Graph/LineChart/LoadingSkeleton.tsx +2 -2
  46. package/src/Graph/LineChart/index.tsx +6 -7
  47. package/src/Graph/LineChart/mockedData/lastDayWithIncompleteValues.json +1320 -0
  48. package/src/Graph/LineChart/mockedData/lastDayWithNullValues.json +1314 -0
  49. package/src/Graph/LineChart/models.ts +12 -1
  50. package/src/Graph/PieChart/PieChart.cypress.spec.tsx +154 -0
  51. package/src/Graph/PieChart/PieChart.stories.tsx +194 -0
  52. package/src/Graph/PieChart/PieChart.styles.ts +39 -0
  53. package/src/Graph/PieChart/PieChart.tsx +14 -0
  54. package/src/Graph/PieChart/ResponsivePie.tsx +243 -0
  55. package/src/Graph/PieChart/index.ts +1 -0
  56. package/src/Graph/PieChart/models.ts +19 -0
  57. package/src/Graph/PieChart/useResponsivePie.ts +81 -0
  58. package/src/Graph/SingleBar/SingleBar.cypress.spec.tsx +121 -0
  59. package/src/Graph/Text/Text.cypress.spec.tsx +101 -0
  60. package/src/Graph/Text/Text.styles.ts +12 -1
  61. package/src/Graph/Text/Text.tsx +17 -12
  62. package/src/Graph/Tree/DescendantNodes.tsx +88 -0
  63. package/src/Graph/Tree/Links.tsx +64 -0
  64. package/src/Graph/Tree/StandaloneTree.tsx +32 -0
  65. package/src/Graph/Tree/Tree.cypress.spec.tsx +171 -0
  66. package/src/Graph/Tree/Tree.stories.tsx +144 -0
  67. package/src/Graph/Tree/Tree.tsx +116 -0
  68. package/src/Graph/Tree/constants.ts +2 -0
  69. package/src/Graph/Tree/index.ts +4 -0
  70. package/src/Graph/Tree/models.ts +52 -0
  71. package/src/Graph/Tree/stories/contents.tsx +164 -0
  72. package/src/Graph/Tree/stories/datas.ts +305 -0
  73. package/src/Graph/Tree/utils.ts +49 -0
  74. package/src/Graph/common/testUtils.ts +71 -0
  75. package/src/Graph/common/timeSeries/index.ts +50 -12
  76. package/src/Graph/common/utils.ts +19 -0
  77. package/src/Graph/index.ts +4 -0
  78. package/src/InputField/Number/Number.cypress.spec.tsx +85 -0
  79. package/src/InputField/Number/Number.stories.tsx +66 -0
  80. package/src/InputField/Number/Number.tsx +74 -0
  81. package/src/InputField/Search/index.tsx +2 -2
  82. package/src/InputField/Select/Autocomplete/Multi/index.tsx +4 -2
  83. package/src/InputField/Select/Autocomplete/index.tsx +10 -3
  84. package/src/InputField/Select/IconPopover/index.tsx +1 -1
  85. package/src/InputField/Select/index.tsx +14 -1
  86. package/src/InputField/Text/index.tsx +38 -38
  87. package/src/Listing/ActionBar/index.tsx +10 -10
  88. package/src/Listing/Cell/DataCell.styles.ts +3 -0
  89. package/src/Listing/Cell/DataCell.tsx +8 -4
  90. package/src/Listing/Listing.cypress.spec.tsx +218 -33
  91. package/src/Listing/Listing.styles.ts +3 -5
  92. package/src/Listing/Row/Row.tsx +7 -3
  93. package/src/Listing/index.stories.tsx +25 -2
  94. package/src/Listing/index.test.tsx +1 -1
  95. package/src/Listing/index.tsx +202 -143
  96. package/src/Listing/models.ts +1 -0
  97. package/src/Listing/useStyleTable.ts +1 -0
  98. package/src/Panel/index.tsx +1 -1
  99. package/src/PopoverMenu/index.tsx +6 -5
  100. package/src/ThemeProvider/index.tsx +3 -0
  101. package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.styles.ts +6 -7
  102. package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +12 -9
  103. package/src/TopCounterElements/TopCounterLayout.tsx +3 -0
  104. package/src/TopCounterElements/useCloseOnLegacyPage.tsx +42 -0
  105. package/src/Typography/FluidTypography/FluidTypography.cypress.spec.tsx +27 -0
  106. package/src/Typography/FluidTypography/index.stories.tsx +2 -2
  107. package/src/Typography/FluidTypography/index.tsx +21 -28
  108. package/src/api/index.ts +3 -3
  109. package/src/api/useGraphQuery/index.ts +26 -5
  110. package/src/api/useGraphQuery/models.ts +5 -0
  111. package/src/api/useMutationQuery/index.test.ts +4 -4
  112. package/src/api/useMutationQuery/index.ts +24 -13
  113. package/src/components/CollapsibleItem/CollapsibleItem.cypress.spec.tsx +76 -0
  114. package/src/components/CollapsibleItem/CollapsibleItem.stories.tsx +26 -0
  115. package/src/components/CollapsibleItem/CollapsibleItem.tsx +43 -14
  116. package/src/components/CollapsibleItem/useCollapsibleItemStyles.ts +24 -1
  117. package/src/components/DataTable/DataTable.cypress.spec.tsx +14 -33
  118. package/src/components/DataTable/Item/DataTableItem.tsx +4 -60
  119. package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.cypress.spec.tsx +36 -13
  120. package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/ContactSwitch.tsx +11 -3
  121. package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/ShareInput.styles.ts +8 -0
  122. package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/ShareInput.tsx +1 -0
  123. package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/useShareInput.tsx +4 -0
  124. package/src/components/Form/{AccessRightsV2 → AccessRights}/models.ts +1 -0
  125. package/src/components/Form/{AccessRightsV2 → AccessRights}/storiesData.ts +23 -22
  126. package/src/components/Form/Dashboard/DashboardDuplicationForm.tsx +85 -0
  127. package/src/components/Form/Dashboard/index.ts +1 -0
  128. package/src/components/Form/FormActions.tsx +7 -2
  129. package/src/components/Form/index.ts +2 -2
  130. package/src/components/ItemComposition/Item.tsx +1 -1
  131. package/src/components/ItemComposition/ItemComposition.cypress.spec.tsx +113 -0
  132. package/src/components/ItemComposition/ItemComposition.stories.tsx +14 -0
  133. package/src/components/ItemComposition/ItemComposition.styles.ts +36 -3
  134. package/src/components/ItemComposition/ItemComposition.tsx +41 -17
  135. package/src/components/List/Item/ListItem.tsx +3 -3
  136. package/src/components/Modal/ConfirmationModal/ConfirmationModal.cypress.spec.tsx +168 -0
  137. package/src/components/Modal/ConfirmationModal/ConfirmationModal.stories.tsx +62 -0
  138. package/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +87 -0
  139. package/src/components/Modal/Modal.styles.ts +8 -3
  140. package/src/components/Modal/index.ts +2 -0
  141. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.stories.tsx +3 -3
  142. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.tsx +1 -1
  143. package/src/components/Tooltip/ConfirmationTooltip/models.ts +1 -1
  144. package/src/components/Zoom/Minimap.tsx +127 -0
  145. package/src/components/Zoom/Zoom.cypress.spec.tsx +246 -0
  146. package/src/components/Zoom/Zoom.stories.tsx +115 -0
  147. package/src/components/Zoom/Zoom.styles.tsx +68 -0
  148. package/src/components/Zoom/Zoom.tsx +61 -0
  149. package/src/components/Zoom/ZoomContent.tsx +167 -0
  150. package/src/components/Zoom/constants.ts +2 -0
  151. package/src/components/Zoom/localPoint.ts +51 -0
  152. package/src/components/Zoom/models.ts +25 -0
  153. package/src/components/Zoom/useMinimap.ts +156 -0
  154. package/src/components/Zoom/useZoom.ts +70 -0
  155. package/src/components/Zoom/utils.ts +55 -0
  156. package/src/components/index.ts +1 -0
  157. package/src/index.ts +1 -0
  158. package/src/utils/index.ts +2 -0
  159. package/src/utils/useFullscreen/Fullscreen.cypress.spec.tsx +130 -0
  160. package/src/utils/useFullscreen/atoms.ts +3 -0
  161. package/src/utils/useFullscreen/index.ts +2 -0
  162. package/src/utils/useFullscreen/translatedLabels.ts +1 -0
  163. package/src/utils/useFullscreen/useFullscreen.ts +73 -0
  164. package/src/utils/useFullscreen/useFullscreenListener.ts +62 -0
  165. package/src/utils/useInfiniteScrollListing.ts +4 -1
  166. package/src/Graph/LineChart/BasicComponents/LoadingProgress.tsx +0 -46
  167. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/TooltipAnchorPoint.tsx +0 -96
  168. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/useTooltipAnchorPoint.ts +0 -107
  169. package/src/Graph/LineChart/Legend/InteractiveValue.tsx +0 -22
  170. package/src/Graph/LineChart/Legend/useInteractiveValues.ts +0 -99
  171. package/src/Typography/FluidTypography/useFluidResizeObserver.ts +0 -56
  172. package/src/components/Form/AccessRights/AccessRights.resource.ts +0 -45
  173. package/src/components/Form/AccessRights/AccessRightsForm.stories.tsx +0 -59
  174. package/src/components/Form/AccessRights/AccessRightsForm.styles.ts +0 -21
  175. package/src/components/Form/AccessRights/AccessRightsForm.tsx +0 -67
  176. package/src/components/Form/AccessRights/AccessRightsFormActions.tsx +0 -80
  177. package/src/components/Form/AccessRights/Input/AddAction.tsx +0 -31
  178. package/src/components/Form/AccessRights/Input/ContactAccessRightInput.stories.tsx +0 -54
  179. package/src/components/Form/AccessRights/Input/ContactAccessRightInput.tsx +0 -72
  180. package/src/components/Form/AccessRights/Input/ContactAccessRightsInput.styles.ts +0 -22
  181. package/src/components/Form/AccessRights/Input/ContactInputField.tsx +0 -105
  182. package/src/components/Form/AccessRights/Input/RoleInputField.tsx +0 -29
  183. package/src/components/Form/AccessRights/List/ContactAccessRightsList.stories.tsx +0 -97
  184. package/src/components/Form/AccessRights/List/ContactAccessRightsList.styles.ts +0 -71
  185. package/src/components/Form/AccessRights/List/ContactAccessRightsList.tsx +0 -51
  186. package/src/components/Form/AccessRights/List/ContactAccessRightsListItem.stories.tsx +0 -116
  187. package/src/components/Form/AccessRights/List/ContactAccessRightsListItem.tsx +0 -118
  188. package/src/components/Form/AccessRights/List/ContactAccessRightsListItemSkeleton.tsx +0 -26
  189. package/src/components/Form/AccessRights/List/ContactAccessRightsListSkeleton.tsx +0 -28
  190. package/src/components/Form/AccessRights/Stats/AccessRightsStats.styles.ts +0 -18
  191. package/src/components/Form/AccessRights/Stats/AccessRightsStats.tsx +0 -41
  192. package/src/components/Form/AccessRights/__fixtures__/contactAccessRight.mock.ts +0 -54
  193. package/src/components/Form/AccessRights/common/GroupLabel.styles.ts +0 -18
  194. package/src/components/Form/AccessRights/common/GroupLabel.tsx +0 -15
  195. package/src/components/Form/AccessRights/common/Input.styles.ts +0 -48
  196. package/src/components/Form/AccessRights/common/RoleInputSelect.styles.ts +0 -11
  197. package/src/components/Form/AccessRights/common/RoleInputSelect.tsx +0 -57
  198. package/src/components/Form/AccessRights/index.ts +0 -3
  199. package/src/components/Form/AccessRights/useAccessRightsForm.test.tsx +0 -531
  200. package/src/components/Form/AccessRights/useAccessRightsForm.tsx +0 -282
  201. package/src/components/Form/AccessRights/useAccessRightsForm.utils.ts +0 -41
  202. /package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.stories.tsx +0 -0
  203. /package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.styles.ts +0 -0
  204. /package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.tsx +0 -0
  205. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Actions/Actions.styles.ts +0 -0
  206. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Actions/Actions.tsx +0 -0
  207. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Actions/useActions.ts +0 -0
  208. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/Item.tsx +0 -0
  209. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/List.styles.tsx +0 -0
  210. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/List.tsx +0 -0
  211. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/ListItemSkeleton.tsx +0 -0
  212. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/ListSkeleton.tsx +0 -0
  213. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/RemoveAccessRight.tsx +0 -0
  214. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/StateChip.tsx +0 -0
  215. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/useItem.ts +0 -0
  216. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Provider.tsx +0 -0
  217. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Stats/Stats.tsx +0 -0
  218. /package/src/components/Form/{AccessRightsV2 → AccessRights}/atoms.ts +0 -0
  219. /package/src/components/Form/{AccessRightsV2 → AccessRights}/common/RoleSelectField.styles.tsx +0 -0
  220. /package/src/components/Form/{AccessRightsV2 → AccessRights}/common/RoleSelectField.tsx +0 -0
  221. /package/src/components/Form/{AccessRightsV2 → AccessRights}/useAccessRightsInitValues.ts +0 -0
@@ -1,5 +1,7 @@
1
1
  import { Box } from '@mui/material';
2
+ import Delete from '@mui/icons-material/Delete';
2
3
 
4
+ import { IconButton } from '../..';
3
5
  import { ColumnType } from '../../Listing/models';
4
6
 
5
7
  import { DataTable } from '.';
@@ -12,29 +14,27 @@ const data = Array(5)
12
14
  title: `Entity ${idx}`
13
15
  }));
14
16
 
15
- const initializeDataTableGrid = ({
16
- hasActions,
17
- hasCardAction,
18
- canDelete
19
- }): void => {
17
+ const CardActions = (): JSX.Element => {
18
+ return (
19
+ <IconButton ariaLabel="Delete" title="Delete" onClick={cy.stub()}>
20
+ <Delete fontSize="small" />
21
+ </IconButton>
22
+ );
23
+ };
24
+
25
+ const initializeDataTableGrid = ({ hasActions, hasCardAction }): void => {
20
26
  cy.viewport(1200, 590);
21
27
  cy.mount({
22
28
  Component: (
23
29
  <DataTable variant="grid">
24
30
  {data.map(({ title, description }) => (
25
31
  <DataTable.Item
32
+ Actions={<CardActions />}
26
33
  description={description}
27
34
  hasActions={hasActions}
28
35
  hasCardAction={hasCardAction}
29
36
  key={title}
30
- labelsDelete={{
31
- cancel: 'Cancel',
32
- confirm: {
33
- label: 'Delete'
34
- }
35
- }}
36
37
  title={title}
37
- onDelete={canDelete ? cy.stub() : undefined}
38
38
  />
39
39
  ))}
40
40
  </DataTable>
@@ -94,7 +94,6 @@ const initializeDataTableListing = (): void => {
94
94
  describe('DataTable: Grid', () => {
95
95
  it('displays items with title and description only', () => {
96
96
  initializeDataTableGrid({
97
- canDelete: false,
98
97
  hasActions: false,
99
98
  hasCardAction: false
100
99
  });
@@ -109,32 +108,17 @@ describe('DataTable: Grid', () => {
109
108
 
110
109
  it('displays items with actions', () => {
111
110
  initializeDataTableGrid({
112
- canDelete: false,
113
- hasActions: true,
114
- hasCardAction: false
115
- });
116
-
117
- cy.findAllByLabelText('edit access rights').should('have.length', 5);
118
- cy.findAllByLabelText('edit').should('have.length', 5);
119
-
120
- cy.makeSnapshot();
121
- });
122
-
123
- it('displays items with delete action', () => {
124
- initializeDataTableGrid({
125
- canDelete: true,
126
111
  hasActions: true,
127
112
  hasCardAction: false
128
113
  });
129
114
 
130
- cy.findAllByLabelText('delete').should('have.length', 5);
115
+ cy.findAllByLabelText('Delete').should('have.length', 5);
131
116
 
132
117
  cy.makeSnapshot();
133
118
  });
134
119
 
135
120
  it('displays items with card action only', () => {
136
121
  initializeDataTableGrid({
137
- canDelete: false,
138
122
  hasActions: false,
139
123
  hasCardAction: true
140
124
  });
@@ -146,15 +130,12 @@ describe('DataTable: Grid', () => {
146
130
 
147
131
  it('displays items with card action and bottom actions', () => {
148
132
  initializeDataTableGrid({
149
- canDelete: true,
150
133
  hasActions: true,
151
134
  hasCardAction: true
152
135
  });
153
136
 
154
137
  cy.findAllByLabelText('view').should('have.length', 5);
155
- cy.findAllByLabelText('delete').should('have.length', 5);
156
- cy.findAllByLabelText('edit access rights').should('have.length', 5);
157
- cy.findAllByLabelText('edit').should('have.length', 5);
138
+ cy.findAllByLabelText('Delete').should('have.length', 5);
158
139
 
159
140
  cy.makeSnapshot();
160
141
  });
@@ -7,32 +7,15 @@ import {
7
7
  CardContent as MuiCardContent,
8
8
  Typography as MuiTypography
9
9
  } from '@mui/material';
10
- import {
11
- Delete as DeleteIcon,
12
- Settings as SettingsIcon,
13
- Share as ShareIcon
14
- } from '@mui/icons-material';
15
-
16
- import { IconButton } from '../../Button';
17
- import { ConfirmationTooltip } from '../../Tooltip/ConfirmationTooltip';
18
10
 
19
11
  import { useStyles } from './DataTableItem.styles';
20
12
 
21
13
  export interface DataTableItemProps {
14
+ Actions?: JSX.Element;
22
15
  description?: string;
23
16
  hasActions?: boolean;
24
17
  hasCardAction?: boolean;
25
- labelsDelete?: {
26
- cancel: string;
27
- confirm: {
28
- label: string;
29
- secondaryLabel?: string;
30
- };
31
- };
32
18
  onClick?: () => void;
33
- onDelete?: () => void;
34
- onEdit?: () => void;
35
- onEditAccessRights?: () => void;
36
19
  title: string;
37
20
  }
38
21
 
@@ -44,10 +27,7 @@ const DataTableItem = forwardRef(
44
27
  hasCardAction = false,
45
28
  hasActions = false,
46
29
  onClick,
47
- onEdit,
48
- onDelete,
49
- onEditAccessRights,
50
- labelsDelete
30
+ Actions
51
31
  }: DataTableItemProps,
52
32
  ref
53
33
  ): ReactElement => {
@@ -75,44 +55,8 @@ const DataTableItem = forwardRef(
75
55
  </ActionArea>
76
56
  {hasActions && (
77
57
  <MuiCardActions>
78
- <span>
79
- {onDelete && labelsDelete && (
80
- <ConfirmationTooltip
81
- confirmVariant="error"
82
- labels={labelsDelete}
83
- onConfirm={onDelete}
84
- >
85
- {(openTooltip) => (
86
- <IconButton
87
- aria-label="delete"
88
- data-testid="delete"
89
- icon={<DeleteIcon />}
90
- size="small"
91
- variant="ghost"
92
- onClick={openTooltip}
93
- />
94
- )}
95
- </ConfirmationTooltip>
96
- )}
97
- </span>
98
- <span>
99
- <IconButton
100
- aria-label="edit access rights"
101
- data-testid="edit-access-rights"
102
- icon={<ShareIcon />}
103
- size="small"
104
- variant="primary"
105
- onClick={() => onEditAccessRights?.()}
106
- />
107
- <IconButton
108
- aria-label="edit"
109
- data-testid="edit"
110
- icon={<SettingsIcon />}
111
- size="small"
112
- variant="primary"
113
- onClick={() => onEdit?.()}
114
- />
115
- </span>
58
+ <span />
59
+ <span>{Actions}</span>
116
60
  </MuiCardActions>
117
61
  )}
118
62
  </MuiCard>
@@ -116,15 +116,15 @@ describe('Access rights', () => {
116
116
  it('displays a removed chip when the corresponding icon is clicked', () => {
117
117
  initialize({});
118
118
 
119
- cy.findByTestId(`remove-Leah McGlynn`).should(
119
+ cy.findByTestId(`remove-Kathy Schmitt`).should(
120
120
  'have.attr',
121
121
  'data-removed',
122
122
  'false'
123
123
  );
124
124
 
125
- cy.findByTestId(`remove-Leah McGlynn`).click();
125
+ cy.findByTestId(`remove-Kathy Schmitt`).click();
126
126
 
127
- cy.findByTestId(`remove-Leah McGlynn`).should(
127
+ cy.findByTestId(`remove-Kathy Schmitt`).should(
128
128
  'have.attr',
129
129
  'data-removed',
130
130
  'true'
@@ -137,18 +137,18 @@ describe('Access rights', () => {
137
137
  it('restores the contact when the contact is removed and the corresponding icon is clicked', () => {
138
138
  initialize({});
139
139
 
140
- cy.findByTestId(`remove-Leah McGlynn`).click();
140
+ cy.findByTestId(`remove-Kathy Schmitt`).click();
141
141
 
142
- cy.findByTestId(`remove-Leah McGlynn`).should(
142
+ cy.findByTestId(`remove-Kathy Schmitt`).should(
143
143
  'have.attr',
144
144
  'data-removed',
145
145
  'true'
146
146
  );
147
147
  cy.contains(labels.list.removed).should('be.visible');
148
148
 
149
- cy.findByTestId(`remove-Leah McGlynn`).click();
149
+ cy.findByTestId(`remove-Kathy Schmitt`).click();
150
150
 
151
- cy.findByTestId(`remove-Leah McGlynn`).should(
151
+ cy.findByTestId(`remove-Kathy Schmitt`).should(
152
152
  'have.attr',
153
153
  'data-removed',
154
154
  'false'
@@ -161,9 +161,9 @@ describe('Access rights', () => {
161
161
  it('submits the new acces rights list without the removed contact', () => {
162
162
  const { save } = initialize({});
163
163
 
164
- cy.findByTestId(`remove-Leah McGlynn`).click();
164
+ cy.findByTestId(`remove-Kathy Schmitt`).click();
165
165
 
166
- cy.findByTestId(`remove-Leah McGlynn`).should(
166
+ cy.findByTestId(`remove-Kathy Schmitt`).should(
167
167
  'have.attr',
168
168
  'data-removed',
169
169
  'true'
@@ -183,7 +183,7 @@ describe('Access rights', () => {
183
183
  it('submits the new acces rights list with the updated contact', () => {
184
184
  const { save } = initialize({});
185
185
 
186
- cy.findByTestId(`role-Leah McGlynn`).parent().click();
186
+ cy.findByTestId(`role-Kathy Schmitt`).parent().click();
187
187
 
188
188
  cy.get('li[data-value="editor"]').click();
189
189
  cy.contains(labels.list.updated).should('be.visible');
@@ -201,7 +201,7 @@ describe('Access rights', () => {
201
201
  it('removes the updated chip when the contact role is updated and its initial role is assigned back', () => {
202
202
  initialize({});
203
203
 
204
- cy.findByTestId(`role-Leah McGlynn`).parent().click();
204
+ cy.findByTestId(`role-Kathy Schmitt`).parent().click();
205
205
 
206
206
  cy.get('li[data-value="editor"]').click();
207
207
  cy.contains(labels.list.updated).should('be.visible');
@@ -291,10 +291,10 @@ describe('Access rights', () => {
291
291
 
292
292
  cy.contains('Entity Group 10').should('be.visible');
293
293
 
294
- cy.findByTestId(`role-Leah McGlynn`).parent().click();
294
+ cy.findByTestId(`role-Kathy Schmitt`).parent().click();
295
295
  cy.get('li[data-value="editor"]').click();
296
296
 
297
- cy.findByTestId('remove-Jody Blanda').click();
297
+ cy.findByTestId('remove-Linda Schultz').click();
298
298
 
299
299
  cy.contains('1 added | 1 updated | 1 removed').should('be.visible');
300
300
 
@@ -347,4 +347,27 @@ describe('Access rights', () => {
347
347
 
348
348
  cy.makeSnapshot();
349
349
  });
350
+
351
+ it('resets the role to "viewer" when the "editor" role is selected and a contact with "viewer" right is selected', () => {
352
+ initialize({});
353
+
354
+ cy.findByLabelText(labels.add.autocompleteContact).click();
355
+
356
+ cy.waitForRequest('@getContacts');
357
+
358
+ cy.contains('Entity 10').click();
359
+
360
+ cy.findByTestId('add_role').parent().click();
361
+ cy.get('li[data-value="editor"]').click();
362
+
363
+ cy.findByLabelText(labels.add.autocompleteContact).click();
364
+
365
+ cy.waitForRequest('@getContacts');
366
+
367
+ cy.contains('Entity 11').click();
368
+
369
+ cy.findByTestId('add_role').should('have.value', 'viewer');
370
+
371
+ cy.makeSnapshot();
372
+ });
350
373
  });
@@ -1,4 +1,4 @@
1
- import { useSetAtom } from 'jotai';
1
+ import { useAtom } from 'jotai';
2
2
  import { useTranslation } from 'react-i18next';
3
3
 
4
4
  import { FormControlLabel, Radio, RadioGroup } from '@mui/material';
@@ -7,14 +7,17 @@ import { ContactType, Labels } from '../models';
7
7
  import { contactTypeAtom } from '../atoms';
8
8
  import { Subtitle } from '../../../..';
9
9
 
10
+ import { useContactSwitchStyles } from './ShareInput.styles';
11
+
10
12
  interface Props {
11
13
  labels: Labels['add'];
12
14
  }
13
15
 
14
16
  const ContactSwitch = ({ labels }: Props): JSX.Element => {
17
+ const { classes } = useContactSwitchStyles();
15
18
  const { t } = useTranslation();
16
19
 
17
- const setContactType = useSetAtom(contactTypeAtom);
20
+ const [contactType, setContactType] = useAtom(contactTypeAtom);
18
21
 
19
22
  const change = (event: React.ChangeEvent<HTMLInputElement>): void => {
20
23
  setContactType(event.target.value as ContactType);
@@ -23,7 +26,12 @@ const ContactSwitch = ({ labels }: Props): JSX.Element => {
23
26
  return (
24
27
  <>
25
28
  <Subtitle>{t(labels.title)}</Subtitle>
26
- <RadioGroup row defaultValue={ContactType.Contact} onChange={change}>
29
+ <RadioGroup
30
+ row
31
+ className={classes.inputs}
32
+ value={contactType}
33
+ onChange={change}
34
+ >
27
35
  <FormControlLabel
28
36
  control={<Radio />}
29
37
  label={labels.contact}
@@ -7,3 +7,11 @@ export const useShareInputStyles = makeStyles()((theme) => ({
7
7
  gridTemplateColumns: `1fr min-content min-content`
8
8
  }
9
9
  }));
10
+
11
+ export const useContactSwitchStyles = makeStyles()((theme) => ({
12
+ inputs: {
13
+ display: 'flex',
14
+ flexDirection: 'row',
15
+ gap: theme.spacing(2)
16
+ }
17
+ }));
@@ -52,6 +52,7 @@ const ShareInput = ({ labels, endpoints, roles }: Props): JSX.Element => {
52
52
  ? t(labels.autocompleteContactGroup)
53
53
  : t(labels.autocompleteContact)
54
54
  )}
55
+ queryKey={isContactGroup ? labels.contactGroup : labels.contact}
55
56
  renderOption={renderOption}
56
57
  value={selectedContact}
57
58
  onChange={selectContact}
@@ -40,6 +40,10 @@ const useShareInput = (endpoints: Endpoints): UseShareInputState => {
40
40
 
41
41
  const selectContact = (_, entry): void => {
42
42
  setSelectedContact(entry);
43
+ if (equals('editor', entry.most_permissive_role)) {
44
+ return;
45
+ }
46
+ setSelectedRole('viewer');
43
47
  };
44
48
 
45
49
  const add = (): void => {
@@ -2,6 +2,7 @@ export interface AccessRightInitialValues {
2
2
  email?: string;
3
3
  id: number | string;
4
4
  isContactGroup: boolean;
5
+ most_permissive_role?: 'editor' | 'viewer';
5
6
  name: string;
6
7
  role: string;
7
8
  }
@@ -88,6 +88,7 @@ const buildEntities = (from, isGroup): Array<SelectEntry> => {
88
88
  .map((_, index) => ({
89
89
  email: isGroup ? undefined : faker.internet.email(),
90
90
  id: 1000 + index,
91
+ most_permissive_role: index % 3 === 0 ? 'editor' : 'viewer',
91
92
  name: `Entity ${isGroup ? 'Group' : ''} ${from + index}`
92
93
  }));
93
94
  };
@@ -139,83 +140,83 @@ export const roles = [
139
140
 
140
141
  export const removedAccessRights = [
141
142
  {
142
- email: 'Virgie14@yahoo.com',
143
+ email: 'Adrienne.Kassulke-Rutherford@gmail.com',
143
144
  id: 1,
144
145
  isContactGroup: false,
145
- name: 'Jody Blanda',
146
+ name: 'Linda Schultz',
146
147
  role: 'editor'
147
148
  },
148
149
  {
149
- email: 'Wyman29@yahoo.com',
150
+ email: 'Merle7@hotmail.com',
150
151
  id: 2,
151
152
  isContactGroup: false,
152
- name: 'Susan Dooley',
153
+ name: 'Lewis Buckridge PhD',
153
154
  role: 'viewer'
154
155
  },
155
156
  {
156
- email: 'Merle.Schamberger@hotmail.com',
157
+ email: 'Linda.Harris37@hotmail.com',
157
158
  id: 3,
158
159
  isContactGroup: false,
159
- name: 'Lewis Buckridge PhD',
160
+ name: "Jodi O'Reilly",
160
161
  role: 'editor'
161
162
  },
162
163
  {
163
- email: 'Rossie6@gmail.com',
164
+ email: 'Louvenia.Torphy@yahoo.com',
164
165
  id: 4,
165
166
  isContactGroup: false,
166
- name: 'Bertha Hane',
167
+ name: 'Mildred Ratke-Stanton',
167
168
  role: 'viewer'
168
169
  },
169
170
  {
170
- email: 'Monty_Nienow47@gmail.com',
171
+ email: 'Kelli.Russel4@hotmail.com',
171
172
  id: 5,
172
173
  isContactGroup: true,
173
- name: 'Mildred Ratke-Stanton',
174
+ name: 'Rudolph Brown',
174
175
  role: 'editor'
175
176
  }
176
177
  ];
177
178
 
178
179
  export const updatedAccessRights = [
179
180
  {
180
- email: 'Jovani.Willms74@gmail.com',
181
+ email: 'Kylie_Wintheiser54@hotmail.com',
181
182
  id: 0,
182
183
  isContactGroup: true,
183
- name: 'Leah McGlynn',
184
+ name: 'Kathy Schmitt',
184
185
  role: 'editor'
185
186
  },
186
187
  {
187
- email: 'Virgie14@yahoo.com',
188
+ email: 'Adrienne.Kassulke-Rutherford@gmail.com',
188
189
  id: 1,
189
190
  isContactGroup: false,
190
- name: 'Jody Blanda',
191
+ name: 'Linda Schultz',
191
192
  role: 'editor'
192
193
  },
193
194
  {
194
- email: 'Wyman29@yahoo.com',
195
+ email: 'Merle7@hotmail.com',
195
196
  id: 2,
196
197
  isContactGroup: false,
197
- name: 'Susan Dooley',
198
+ name: 'Lewis Buckridge PhD',
198
199
  role: 'viewer'
199
200
  },
200
201
  {
201
- email: 'Merle.Schamberger@hotmail.com',
202
+ email: 'Linda.Harris37@hotmail.com',
202
203
  id: 3,
203
204
  isContactGroup: false,
204
- name: 'Lewis Buckridge PhD',
205
+ name: "Jodi O'Reilly",
205
206
  role: 'editor'
206
207
  },
207
208
  {
208
- email: 'Rossie6@gmail.com',
209
+ email: 'Louvenia.Torphy@yahoo.com',
209
210
  id: 4,
210
211
  isContactGroup: false,
211
- name: 'Bertha Hane',
212
+ name: 'Mildred Ratke-Stanton',
212
213
  role: 'viewer'
213
214
  },
214
215
  {
215
- email: 'Monty_Nienow47@gmail.com',
216
+ email: 'Kelli.Russel4@hotmail.com',
216
217
  id: 5,
217
218
  isContactGroup: true,
218
- name: 'Mildred Ratke-Stanton',
219
+ name: 'Rudolph Brown',
219
220
  role: 'editor'
220
221
  }
221
222
  ];
@@ -0,0 +1,85 @@
1
+ import { ReactElement, useCallback, useMemo } from 'react';
2
+
3
+ import { string, object } from 'yup';
4
+ import { useTranslation } from 'react-i18next';
5
+
6
+ import { InputType } from '../../../Form/Inputs/models';
7
+ import { Form, FormProps } from '../../../Form';
8
+ import { FormVariant } from '../Form.models';
9
+ import { FormActions, FormActionsProps } from '../FormActions';
10
+
11
+ import { useStyles } from './DashboardForm.styles';
12
+ import {
13
+ labelMustBeAtLeast,
14
+ labelMustBeMost,
15
+ labelRequired
16
+ } from './translatedLabels';
17
+ import { DashboardResource } from './Dashboard.resource';
18
+
19
+ type DashboardFormProps = {
20
+ labels: DashboardFormLabels;
21
+ name: string;
22
+ onSubmit?: FormProps<DashboardResource>['submit'];
23
+ variant?: FormVariant;
24
+ } & Pick<FormActionsProps, 'onCancel'>;
25
+
26
+ type DashboardFormLabels = {
27
+ actions: FormActionsProps['labels'];
28
+ entity: Required<DashboardResource>;
29
+ };
30
+
31
+ const DashboardDuplicationForm = ({
32
+ variant = 'create',
33
+ labels,
34
+ onSubmit,
35
+ onCancel,
36
+ name
37
+ }: DashboardFormProps): ReactElement => {
38
+ const { classes } = useStyles();
39
+ const { t } = useTranslation();
40
+
41
+ const formProps = useMemo<FormProps<DashboardResource>>(
42
+ () => ({
43
+ initialValues: { name },
44
+ inputs: [
45
+ {
46
+ autoFocus: true,
47
+ fieldName: 'name',
48
+ group: 'main',
49
+ label: labels?.entity?.name,
50
+ required: true,
51
+ type: InputType.Text
52
+ }
53
+ ],
54
+ submit: (values, bag) => onSubmit?.(values, bag),
55
+ validationSchema: object({
56
+ name: string()
57
+ .label(labels?.entity?.name)
58
+ .min(3, ({ min, label }) => t(labelMustBeAtLeast, { label, min }))
59
+ .max(50, ({ max, label }) => t(labelMustBeMost, { label, max }))
60
+ .required(t(labelRequired) as string)
61
+ })
62
+ }),
63
+ [labels, onSubmit]
64
+ );
65
+
66
+ const Actions = useCallback(
67
+ () => (
68
+ <FormActions<DashboardResource>
69
+ enableSubmitWhenNotDirty
70
+ labels={labels?.actions}
71
+ variant={variant}
72
+ onCancel={onCancel}
73
+ />
74
+ ),
75
+ [labels, onCancel, variant]
76
+ );
77
+
78
+ return (
79
+ <div className={classes.dashboardForm}>
80
+ <Form<DashboardResource> {...formProps} Buttons={Actions} />
81
+ </div>
82
+ );
83
+ };
84
+
85
+ export { DashboardDuplicationForm };
@@ -1,2 +1,3 @@
1
1
  export * from './DashboardForm';
2
2
  export * from './Dashboard.resource';
3
+ export * from './DashboardDuplicationForm';
@@ -8,6 +8,7 @@ import { FormVariant } from './Form.models';
8
8
  import { useStyles } from './Form.styles';
9
9
 
10
10
  export type FormActionsProps = {
11
+ enableSubmitWhenNotDirty?: boolean;
11
12
  labels: FormActionsLabels;
12
13
  onCancel: () => void;
13
14
  variant: FormVariant;
@@ -21,12 +22,16 @@ export type FormActionsLabels = {
21
22
  const FormActions = <TResource extends object>({
22
23
  labels,
23
24
  onCancel,
24
- variant
25
+ variant,
26
+ enableSubmitWhenNotDirty
25
27
  }: FormActionsProps): ReactElement => {
26
28
  const { classes } = useStyles();
27
29
  const { isSubmitting, dirty, isValid, submitForm } =
28
30
  useFormikContext<TResource>();
29
31
 
32
+ const isSubmitDisabled =
33
+ isSubmitting || (!dirty && !enableSubmitWhenNotDirty) || !isValid;
34
+
30
35
  return (
31
36
  <div className={classes.actions}>
32
37
  <Button
@@ -42,7 +47,7 @@ const FormActions = <TResource extends object>({
42
47
  <Button
43
48
  aria-label={labels.submit[variant]}
44
49
  data-testid="submit"
45
- disabled={isSubmitting || !dirty || !isValid}
50
+ disabled={isSubmitDisabled}
46
51
  size="medium"
47
52
  type="submit"
48
53
  variant="primary"
@@ -1,4 +1,4 @@
1
1
  export * from './Form.models';
2
2
  export * from './Dashboard';
3
- export * from './AccessRights';
4
- export { default as AccessRightsV2 } from './AccessRightsV2/AccessRights';
3
+ export { default as AccessRights } from './AccessRights/AccessRights';
4
+ export { default as AccessRightsV2 } from './AccessRights/AccessRights';
@@ -7,7 +7,7 @@ import { IconButton } from '..';
7
7
  import { useItemStyles } from './ItemComposition.styles';
8
8
 
9
9
  type Props = {
10
- children: Array<ReactElement>;
10
+ children: ReactElement | Array<ReactElement>;
11
11
  className?: string;
12
12
  deleteButtonHidden?: boolean;
13
13
  labelDelete: string;