@scality/core-ui 0.122.0 → 0.123.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 (80) hide show
  1. package/.storybook/preview.js +28 -8
  2. package/dist/components/constrainedtext/Constrainedtext.component.d.ts.map +1 -1
  3. package/dist/components/constrainedtext/Constrainedtext.component.js +1 -4
  4. package/dist/components/emptystate/Emptystate.component.d.ts +11 -1
  5. package/dist/components/emptystate/Emptystate.component.d.ts.map +1 -1
  6. package/dist/components/emptystate/Emptystate.component.js +9 -4
  7. package/dist/components/icon/Icon.component.d.ts +2 -2
  8. package/dist/components/icon/Icon.component.d.ts.map +1 -1
  9. package/dist/components/infomessage/InfoMessageUtils.d.ts +1 -1
  10. package/dist/components/infomessage/InfoMessageUtils.d.ts.map +1 -1
  11. package/dist/components/infomessage/InfoMessageUtils.js +5 -4
  12. package/dist/components/navbar/Navbar.component.d.ts.map +1 -1
  13. package/dist/components/navbar/Navbar.component.js +1 -0
  14. package/dist/components/searchinput/SearchInput.component.d.ts +2 -1
  15. package/dist/components/searchinput/SearchInput.component.d.ts.map +1 -1
  16. package/dist/components/selectv2/Selectv2.component.d.ts +1 -1
  17. package/dist/components/selectv2/Selectv2.component.d.ts.map +1 -1
  18. package/dist/components/sidebar/Sidebar.component.d.ts.map +1 -1
  19. package/dist/components/sidebar/Sidebar.component.js +2 -1
  20. package/dist/components/tablev2/MultiSelectableContent.d.ts +1 -2
  21. package/dist/components/tablev2/MultiSelectableContent.d.ts.map +1 -1
  22. package/dist/components/tablev2/MultiSelectableContent.js +9 -24
  23. package/dist/components/tablev2/Search.d.ts +0 -6
  24. package/dist/components/tablev2/Search.d.ts.map +1 -1
  25. package/dist/components/tablev2/Search.js +3 -4
  26. package/dist/components/tablev2/SingleSelectableContent.d.ts +4 -5
  27. package/dist/components/tablev2/SingleSelectableContent.d.ts.map +1 -1
  28. package/dist/components/tablev2/SingleSelectableContent.js +9 -23
  29. package/dist/components/tablev2/TableCommon.d.ts +15 -3
  30. package/dist/components/tablev2/TableCommon.d.ts.map +1 -1
  31. package/dist/components/tablev2/TableCommon.js +37 -2
  32. package/dist/components/tablev2/TableUtils.d.ts +11 -0
  33. package/dist/components/tablev2/TableUtils.d.ts.map +1 -1
  34. package/dist/components/tablev2/TableUtils.js +23 -0
  35. package/dist/components/tablev2/Tablestyle.d.ts +6 -3
  36. package/dist/components/tablev2/Tablestyle.d.ts.map +1 -1
  37. package/dist/components/tablev2/Tablestyle.js +29 -36
  38. package/dist/components/tablev2/Tablev2.component.d.ts +24 -3
  39. package/dist/components/tablev2/Tablev2.component.d.ts.map +1 -1
  40. package/dist/components/tablev2/Tablev2.component.js +3 -1
  41. package/dist/components/tabsv2/StyledTabs.d.ts.map +1 -1
  42. package/dist/components/tabsv2/StyledTabs.js +14 -14
  43. package/dist/components/toast/Toast.component.d.ts.map +1 -1
  44. package/dist/components/toast/Toast.component.js +1 -1
  45. package/dist/components/toast/useMutationsHandler.d.ts +1 -1
  46. package/dist/components/toast/useMutationsHandler.d.ts.map +1 -1
  47. package/dist/components/toast/useMutationsHandler.js +8 -6
  48. package/dist/organisms/attachments/AttachmentConfirmationModal.d.ts.map +1 -1
  49. package/dist/organisms/attachments/AttachmentConfirmationModal.js +1 -1
  50. package/dist/organisms/attachments/AttachmentTable.d.ts.map +1 -1
  51. package/dist/organisms/attachments/AttachmentTable.js +15 -12
  52. package/package.json +1 -1
  53. package/src/lib/components/constrainedtext/Constrainedtext.component.tsx +1 -4
  54. package/src/lib/components/emptystate/Emptystate.component.tsx +34 -10
  55. package/src/lib/components/icon/Icon.component.tsx +2 -2
  56. package/src/lib/components/infomessage/InfoMessageUtils.ts +39 -33
  57. package/src/lib/components/navbar/Navbar.component.tsx +1 -0
  58. package/src/lib/components/searchinput/SearchInput.component.tsx +1 -0
  59. package/src/lib/components/selectv2/Selectv2.component.tsx +1 -1
  60. package/src/lib/components/sidebar/Sidebar.component.tsx +3 -2
  61. package/src/lib/components/tablev2/MultiSelectableContent.tsx +13 -63
  62. package/src/lib/components/tablev2/Search.tsx +13 -24
  63. package/src/lib/components/tablev2/SingleSelectableContent.tsx +18 -71
  64. package/src/lib/components/tablev2/TableCommon.tsx +100 -1
  65. package/src/lib/components/tablev2/TableUtils.ts +37 -0
  66. package/src/lib/components/tablev2/Tablestyle.tsx +30 -37
  67. package/src/lib/components/tablev2/Tablev2.component.tsx +14 -0
  68. package/src/lib/components/tablev2/Tablev2.test.tsx +0 -3
  69. package/src/lib/components/tabsv2/StyledTabs.ts +16 -14
  70. package/src/lib/components/toast/Toast.component.tsx +1 -0
  71. package/src/lib/components/toast/useMutationsHandler.ts +4 -2
  72. package/src/lib/organisms/attachments/AttachmentConfirmationModal.tsx +0 -1
  73. package/src/lib/organisms/attachments/AttachmentTable.tsx +25 -16
  74. package/stories/Hooks/useMutationsHandler.mdx +121 -0
  75. package/stories/attachment.stories.tsx +78 -0
  76. package/stories/common.tsx +12 -6
  77. package/stories/emptystate.stories.tsx +1 -2
  78. package/stories/form.stories.tsx +1 -3
  79. package/stories/modal.stories.tsx +0 -2
  80. package/stories/tablev2.stories.tsx +131 -52
@@ -32,6 +32,7 @@ import {
32
32
  } from './AttachmentTypes';
33
33
  import { useQuery, UseQueryOptions } from 'react-query';
34
34
  import { EmptyCell } from '../../components/tablev2/Tablev2.component';
35
+ import { tableRowHeight } from '../../components/tablev2/TableUtils';
35
36
 
36
37
  type AttachableEntityWithPendingStatus<ENTITY_TYPE> = {
37
38
  isPending?: boolean;
@@ -104,11 +105,7 @@ const MenuContainer = styled.ul<{
104
105
  `;
105
106
 
106
107
  const SearchBoxContainer = styled.div`
107
- margin-bottom: ${spacing.r24};
108
- width: 78%;
109
- .sc-tooltip {
110
- width: 100%;
111
- }
108
+ padding: ${spacing.r16};
112
109
  `;
113
110
 
114
111
  const StyledSearchInput = styled(SearchInput)`
@@ -134,6 +131,7 @@ const StyledTable = styled.div`
134
131
  const CenterredSecondaryText = styled(SecondaryText)`
135
132
  display: block;
136
133
  text-align: center;
134
+ line-height: ${tableRowHeight[rowHeight]}rem;
137
135
  `;
138
136
 
139
137
  const PrivateAttachmentContext = createContext<{
@@ -477,8 +475,12 @@ export const AttachmentTable = <ENTITY_TYPE,>({
477
475
  <SearchBoxContainer
478
476
  {...{
479
477
  ref: (element) => {
480
- if (element) {
481
- setSearchWidth(element.getBoundingClientRect().width - 2 + 'px');
478
+ if (element?.firstElementChild) {
479
+ setSearchWidth(
480
+ element.firstElementChild.getBoundingClientRect().width -
481
+ 2 +
482
+ 'px',
483
+ );
482
484
  }
483
485
  },
484
486
  }}
@@ -489,7 +491,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
489
491
  <>We failed to load the entities, hence search is disabled</>
490
492
  }
491
493
  >
492
- <Box display="flex" alignItems="center" width="100%" gap={8}>
494
+ <Stack>
493
495
  <StyledSearchInput
494
496
  placeholder={searchEntityPlaceholder}
495
497
  {...getInputProps({
@@ -508,7 +510,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
508
510
  disabled={filteredEntities.status === 'error'}
509
511
  />
510
512
  <Loader />
511
- </Box>
513
+ </Stack>
512
514
  </Tooltip>
513
515
  ) : (
514
516
  <StyledSearchInput
@@ -595,7 +597,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
595
597
  <Table
596
598
  columns={[
597
599
  {
598
- Header: <Box flex={1.5}>Name</Box>,
600
+ Header: 'Name',
599
601
  accessor: 'name',
600
602
  cellStyle: {
601
603
  flex: 1.5,
@@ -639,7 +641,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
639
641
  },
640
642
  },
641
643
  {
642
- Header: <Box flex={0.5}>Attachment status</Box>,
644
+ Header: 'Attachment',
643
645
  accessor: 'isPending',
644
646
  cellStyle: {
645
647
  flex: 0.5,
@@ -690,7 +692,6 @@ export const AttachmentTable = <ENTITY_TYPE,>({
690
692
  defaultSortingKey="name"
691
693
  >
692
694
  <Table.SingleSelectableContent
693
- backgroundVariant="backgroundLevel4"
694
695
  rowHeight={rowHeight}
695
696
  separationLineVariant="backgroundLevel2"
696
697
  >
@@ -698,7 +699,7 @@ export const AttachmentTable = <ENTITY_TYPE,>({
698
699
  <>
699
700
  {initiallyAttachedEntitiesStatus === 'idle' ||
700
701
  initiallyAttachedEntitiesStatus === 'loading' ? (
701
- <Wrap>
702
+ <Wrap style={{ height: `${tableRowHeight[rowHeight]}rem` }}>
702
703
  <p></p>
703
704
  <Stack>
704
705
  <Loader />
@@ -707,9 +708,17 @@ export const AttachmentTable = <ENTITY_TYPE,>({
707
708
  <p></p>
708
709
  </Wrap>
709
710
  ) : initiallyAttachedEntitiesStatus === 'error' ? (
710
- <CenterredSecondaryText>
711
- Failed to load {entityName.plural}
712
- </CenterredSecondaryText>
711
+ <Stack
712
+ style={{
713
+ justifyContent: 'center',
714
+ height: `${tableRowHeight[rowHeight]}rem`,
715
+ }}
716
+ >
717
+ <Icon name="Exclamation-circle" color="statusWarning" />
718
+ <Text color="textSecondary">
719
+ Failed to load attached {entityName.plural}.
720
+ </Text>
721
+ </Stack>
713
722
  ) : (
714
723
  desiredAttachedEntities.length === 0 && (
715
724
  <CenterredSecondaryText>
@@ -0,0 +1,121 @@
1
+ # useMutationsHandler
2
+
3
+ The `useMutationsHandler` hook is a powerful utility designed to manage and handle the results of multiple mutations using `react-query`.
4
+ It provides a unified way to handle success and error states, display toast notifications,
5
+ and manage side effects after mutation completions.
6
+
7
+ ## Usage
8
+
9
+ ```jsx
10
+ import { useMutationsHandler } from '@scality/core-ui';
11
+ import { Button } from '@scality/core-ui/dist/next';
12
+ import { useMutation } from 'react-query';
13
+
14
+ function useMainMutation() {
15
+ return useMutation({
16
+ mutationFn: () => {
17
+ return Promise.resolve('mainMutation');
18
+ },
19
+ });
20
+ }
21
+
22
+ function useDependantMutation() {
23
+ return useMutation({
24
+ mutationFn: () => {
25
+ return Promise.resolve('dependantMutation');
26
+ },
27
+ });
28
+ }
29
+
30
+ export const ExampleComponent = () => {
31
+ const useMainM = useMainMutation();
32
+ const useDependantM = useDependantMutation();
33
+ const { mutate: mainMutate } = useMainM;
34
+ const { mutate: dependantMutate } = useDependantM;
35
+
36
+ const mainMutation = {
37
+ mutation: useMainM,
38
+ name: 'mainMutation',
39
+ };
40
+
41
+ const dependantMutations = [
42
+ {
43
+ mutation: useDependantM,
44
+ name: 'depandantMutation',
45
+ },
46
+ ];
47
+
48
+ useMutationsHandler({
49
+ mainMutation,
50
+ dependantMutations,
51
+ messageDescriptionBuilder: (mutations) => {
52
+ const mutationsStatus = mutations.map(({ status }) => status);
53
+ const mutationsAllSuccess = mutationsStatus.every(
54
+ (status) => status === 'success',
55
+ );
56
+
57
+ if (mutationsAllSuccess) {
58
+ return `All mutations were successful`;
59
+ } else {
60
+ return `Some mutations failed`;
61
+ }
62
+ },
63
+ onAllMutationsSuccess: () => {
64
+ // do something after success of all mutations
65
+ },
66
+ });
67
+
68
+ const handleClick = () => {
69
+ mainMutate(null, {
70
+ onSuccess: () => dependantMutate(),
71
+ });
72
+ };
73
+
74
+ return (
75
+ <Button label={'Click me'} onClick={() => handleClick()} type="button" />
76
+ );
77
+ };
78
+ ```
79
+
80
+ ## Props
81
+
82
+ ### `mainMutation`
83
+
84
+ - Type: MutationConfig
85
+ - Description: The primary mutation that needs to be executed and monitored
86
+
87
+ For more information on useMutation, see [here](https://tanstack.com/query/latest/docs/framework/react/reference/useMutation)
88
+
89
+ ### `messageDescriptionBuilder`
90
+
91
+ - Type: () => React Node
92
+ - Description: Define the element that will be rendered inside the toast
93
+
94
+ ### `dependentMutations`
95
+
96
+ - Type: MutationConfig[]
97
+ - Description: The secondary mutations that need to be executed and monitored after the success of the main mutation
98
+ - Optional
99
+
100
+ ### `toastProps`
101
+
102
+ - Type: Pick<
103
+ ToastContextState,
104
+ 'style' | 'autoDismiss' | 'position' | 'duration' | 'withProgressBar'
105
+ >
106
+ - Description: Props from the `Toast` component, allow the customization of the toast displayed by `useMutationsHandler`
107
+ - Optional
108
+
109
+ For more information on toastProps, see [here](?path=/docs/components-feedback-toast--stories)
110
+
111
+ ### onMainMutationSuccess
112
+
113
+ - Type: () => void
114
+ - Description: The callback to call after the main mutation succeeded
115
+ - Optional
116
+
117
+ ### onAllMutationsSuccess
118
+
119
+ - Type: () => void
120
+ - Description: The callback to call after all the mutations succeeded
121
+ - Optional
@@ -0,0 +1,78 @@
1
+ import { action } from '@storybook/addon-actions';
2
+ import React from 'react';
3
+ import {
4
+ AttachmentProvider,
5
+ AttachmentTable,
6
+ } from '../src/lib/organisms/attachments/AttachmentTable';
7
+
8
+ import { Box } from '../src/lib/next';
9
+ import { useTheme } from 'styled-components';
10
+
11
+ export default {
12
+ title: 'Components/AttachmentTable',
13
+ component: AttachmentTable,
14
+ };
15
+
16
+ export const Playground = {
17
+ render: () => {
18
+ const theme = useTheme();
19
+ return (
20
+ <Box
21
+ style={{ height: '100%', backgroundColor: theme.backgroundLevel4 }}
22
+ p={'2rem'}
23
+ >
24
+ <AttachmentProvider>
25
+ <AttachmentTable
26
+ entityName={{ plural: 'users', singular: 'user' }}
27
+ filteredEntities={{
28
+ status: 'success',
29
+ data: {
30
+ number: 1,
31
+ entities: [{ name: 'User A', id: 'test', type: 'USER' }],
32
+ },
33
+ }}
34
+ initialAttachmentOperations={[]}
35
+ onEntitySearchChange={action('onEntitySearchChange')}
36
+ searchEntityPlaceholder="Search user by name"
37
+ initiallyAttachedEntities={[
38
+ { name: 'User A', id: 'test', type: 'USER' },
39
+ ]}
40
+ initiallyAttachedEntitiesStatus={'success'}
41
+ onAttachmentsOperationsChanged={() => {
42
+ console.log('changed');
43
+ }}
44
+ />
45
+ </AttachmentProvider>
46
+ </Box>
47
+ );
48
+ },
49
+ };
50
+
51
+ export const FailToLoad = {
52
+ render: () => {
53
+ const theme = useTheme();
54
+ return (
55
+ <Box
56
+ style={{ height: '100%', backgroundColor: theme.backgroundLevel4 }}
57
+ p={'2rem'}
58
+ >
59
+ <AttachmentProvider>
60
+ <AttachmentTable
61
+ entityName={{ plural: 'users', singular: 'user' }}
62
+ filteredEntities={{
63
+ status: 'error',
64
+ }}
65
+ initialAttachmentOperations={[]}
66
+ onEntitySearchChange={action('onEntitySearchChange')}
67
+ searchEntityPlaceholder="Search user by name"
68
+ initiallyAttachedEntities={[]}
69
+ initiallyAttachedEntitiesStatus={'error'}
70
+ onAttachmentsOperationsChanged={() => {
71
+ console.log('changed');
72
+ }}
73
+ />
74
+ </AttachmentProvider>
75
+ </Box>
76
+ );
77
+ },
78
+ };
@@ -1,12 +1,18 @@
1
1
  import React from 'react';
2
- import styled from 'styled-components';
2
+ import styled, { css } from 'styled-components';
3
3
  import { getThemePropSelector } from '../src/lib/utils';
4
4
  const StyledWrapper = styled.div`
5
- padding: 3rem;
6
- height: 100%;
7
- background-color: ${(props) => props.theme.backgroundLevel1};
8
- color: ${(props) => props.theme.textPrimary};
9
- box-sizing: border-box;
5
+ ${(props) => {
6
+ const { style, theme } = props;
7
+ return css`
8
+ padding: 3rem;
9
+ height: 100%;
10
+ background-color: ${theme[style?.backgroundColor || 'backgroundLevel3']};
11
+ color: ${theme.textPrimary};
12
+ box-sizing: border-box;
13
+ overflow: scroll;
14
+ `;
15
+ }}
10
16
  `;
11
17
  const StyledTitle = styled.h3`
12
18
  color: ${getThemePropSelector('textPrimary')};
@@ -1,6 +1,5 @@
1
- import React from 'react';
2
1
  import { EmptyState } from '../src/lib/components/emptystate/Emptystate.component';
3
- import { Wrapper } from './common';
2
+
4
3
  export default {
5
4
  title: 'Components/Data Display/EmptyState',
6
5
  component: EmptyState,
@@ -236,9 +236,7 @@ export const AllRequiredPageForm = {
236
236
  export const TabForm = {
237
237
  ...PageForm,
238
238
  args: {
239
- layout: {
240
- kind: 'tab',
241
- },
239
+ kind: 'tab',
242
240
  },
243
241
  };
244
242
 
@@ -1,4 +1,3 @@
1
- import React, { useState } from 'react';
2
1
  import { Modal } from '../src/lib/components/modal/Modal.component';
3
2
  import { action } from '@storybook/addon-actions';
4
3
  import { Wrapper } from './common';
@@ -164,7 +163,6 @@ export const WithinTable = {
164
163
  <Table.SingleSelectableContent
165
164
  rowHeight="h32"
166
165
  separationLineVariant="backgroundLevel3"
167
- backgroundVariant="backgroundLevel1"
168
166
  />
169
167
  </Table>
170
168
  </div>
@@ -5,7 +5,7 @@ import {
5
5
  EmptyCell,
6
6
  Table,
7
7
  } from '../src/lib/components/tablev2/Tablev2.component';
8
- import { Wrapper, Title } from './common';
8
+ import { Title } from './common';
9
9
  import {
10
10
  BrowserRouter,
11
11
  BrowserRouter as Router,
@@ -65,51 +65,49 @@ type Entry = {
65
65
  health: string;
66
66
  };
67
67
 
68
+ const columns: Column<Entry>[] = [
69
+ {
70
+ Header: 'First Name',
71
+ accessor: 'firstName',
72
+ cellStyle: {
73
+ textAlign: 'left',
74
+ },
75
+ Cell: ({ value }) => {
76
+ if (value) return <>{value}</>;
77
+ return <EmptyCell />;
78
+ },
79
+ },
80
+ {
81
+ Header: 'Last Name',
82
+ accessor: 'lastName',
83
+ cellStyle: {
84
+ textAlign: 'left',
85
+ },
86
+ // disable the sorting on this column
87
+ disableSortBy: true,
88
+ },
89
+ {
90
+ Header: 'Age',
91
+ accessor: 'age',
92
+ cellStyle: {
93
+ width: '50px',
94
+ textAlign: 'left',
95
+ },
96
+ },
97
+ {
98
+ Header: 'Health',
99
+ accessor: 'health',
100
+ sortType: 'health',
101
+ cellStyle: {
102
+ textAlign: 'left',
103
+ },
104
+ },
105
+ ];
106
+ const getRowId = (row: Entry, relativeIndex: number) => {
107
+ return row.lastName + ' ' + row.firstName;
108
+ };
68
109
  export const SimpleContentTable = {
69
110
  render: ({}) => {
70
- const columns: Column<Entry>[] = [
71
- {
72
- Header: 'First Name',
73
- accessor: 'firstName',
74
- cellStyle: {
75
- textAlign: 'left',
76
- },
77
- Cell: ({ value }) => {
78
- if (value) return <>{value}</>;
79
- return <EmptyCell />;
80
- },
81
- },
82
- {
83
- Header: 'Last Name',
84
- accessor: 'lastName',
85
- cellStyle: {
86
- textAlign: 'left',
87
- },
88
- // disable the sorting on this column
89
- disableSortBy: true,
90
- },
91
- {
92
- Header: 'Age',
93
- accessor: 'age',
94
- cellStyle: {
95
- width: '50px',
96
- textAlign: 'left',
97
- },
98
- },
99
- {
100
- Header: 'Health',
101
- accessor: 'health',
102
- sortType: 'health',
103
- cellStyle: {
104
- textAlign: 'left',
105
- },
106
- },
107
- ];
108
-
109
- const getRowId = (row: Entry, relativeIndex: number) => {
110
- return row.lastName + ' ' + row.firstName;
111
- };
112
-
113
111
  const TableWithQueryParams = ({}) => {
114
112
  const location = useLocation();
115
113
  return (
@@ -148,7 +146,7 @@ export const SimpleContentTable = {
148
146
  };
149
147
 
150
148
  return (
151
- <Wrapper>
149
+ <>
152
150
  <Title>Non Selectable Table</Title>
153
151
  <div
154
152
  style={{
@@ -230,6 +228,7 @@ export const SimpleContentTable = {
230
228
  data={data}
231
229
  defaultSortingKey={'health'}
232
230
  getRowId={getRowId}
231
+ status="loading"
233
232
  >
234
233
  <Table.MultiSelectableContent
235
234
  rowHeight="h40"
@@ -241,7 +240,7 @@ export const SimpleContentTable = {
241
240
  />
242
241
  </Table>
243
242
  </div>
244
- </Wrapper>
243
+ </>
245
244
  );
246
245
  },
247
246
  };
@@ -320,7 +319,7 @@ export const asyncTable = {
320
319
  ];
321
320
 
322
321
  return (
323
- <Wrapper>
322
+ <>
324
323
  <Title>async cell Table</Title>
325
324
  <div
326
325
  style={{
@@ -347,7 +346,7 @@ export const asyncTable = {
347
346
  </Table>
348
347
  </BrowserRouter>
349
348
  </div>
350
- </Wrapper>
349
+ </>
351
350
  );
352
351
  },
353
352
  };
@@ -384,7 +383,7 @@ export const OnBottomCallback = {
384
383
  };
385
384
 
386
385
  return (
387
- <Wrapper>
386
+ <>
388
387
  <Title>async cell Table</Title>
389
388
  <div
390
389
  style={{
@@ -406,7 +405,7 @@ export const OnBottomCallback = {
406
405
  />
407
406
  </Table>
408
407
  </div>
409
- </Wrapper>
408
+ </>
410
409
  );
411
410
  },
412
411
  };
@@ -492,7 +491,7 @@ export const MultiTable = {
492
491
  };
493
492
 
494
493
  return (
495
- <Wrapper>
494
+ <>
496
495
  <Title>Several Multiselect</Title>
497
496
  <Flex justifyContent="center" gap="2rem">
498
497
  <Box width="500px" height="200px">
@@ -546,7 +545,87 @@ export const MultiTable = {
546
545
  </Table>
547
546
  </Box>
548
547
  </Flex>
549
- </Wrapper>
548
+ </>
549
+ );
550
+ },
551
+ };
552
+
553
+ export const EmptyTable = {
554
+ render: (args) => {
555
+ const { background } = args;
556
+ return (
557
+ <Table columns={columns} data={[]} defaultSortingKey={'firstName'}>
558
+ <Table.SingleSelectableContent
559
+ rowHeight="h40"
560
+ separationLineVariant={background}
561
+ backgroundVariant="backgroundLevel1"
562
+ onRowSelected={action('Table Row Clicked')}
563
+ />
564
+ </Table>
565
+ );
566
+ },
567
+ argTypes: {
568
+ background: {
569
+ control: {
570
+ type: 'select',
571
+ description: 'Background color',
572
+ defaultValue: 'backgroundLevel3',
573
+ },
574
+ options: [
575
+ 'backgroundLevel1',
576
+ 'backgroundLevel2',
577
+ 'backgroundLevel3',
578
+ 'backgroundLevel4',
579
+ ],
580
+ },
581
+ },
582
+ };
583
+
584
+ export const LoadingTable = {
585
+ render: ({}) => {
586
+ return (
587
+ <Box width="500px" height="200px">
588
+ <Table
589
+ columns={columns}
590
+ data={data}
591
+ defaultSortingKey={'health'}
592
+ getRowId={getRowId}
593
+ status="loading"
594
+ >
595
+ <Table.SingleSelectableContent
596
+ rowHeight="h40"
597
+ separationLineVariant="backgroundLevel3"
598
+ backgroundVariant="backgroundLevel1"
599
+ />
600
+ </Table>
601
+ </Box>
602
+ );
603
+ },
604
+ };
605
+
606
+ export const ErrorTable = {
607
+ render: ({}) => {
608
+ return (
609
+ <Box width="50rem" height="200px">
610
+ <Table
611
+ columns={columns}
612
+ data={data}
613
+ defaultSortingKey={'health'}
614
+ getRowId={getRowId}
615
+ status="error"
616
+ entityName={{
617
+ en: { singular: 'user', plural: 'users' },
618
+ fr: { singular: 'utilisateur', plural: 'utilisateurs' },
619
+ }}
620
+ >
621
+ <Table.SingleSelectableContent
622
+ rowHeight="h40"
623
+ separationLineVariant="backgroundLevel4"
624
+ backgroundVariant="backgroundLevel1"
625
+ locale="en"
626
+ />
627
+ </Table>
628
+ </Box>
550
629
  );
551
630
  },
552
631
  };