@indico-data/design-system 1.0.1

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 (161) hide show
  1. package/.babelrc +27 -0
  2. package/.eslintignore +6 -0
  3. package/.eslintrc.js +63 -0
  4. package/.husky/pre-commit +4 -0
  5. package/.prettierignore +3 -0
  6. package/.prettierrc +6 -0
  7. package/.stackblitzrc +4 -0
  8. package/.storybook/indico-data-logo.svg +1 -0
  9. package/.storybook/main.ts +36 -0
  10. package/.storybook/preview-head.html +19 -0
  11. package/.storybook/preview.ts +24 -0
  12. package/.storybook/themes.js +24 -0
  13. package/.yarn/releases/yarn-classic.cjs +179386 -0
  14. package/.yarnrc.yml +1 -0
  15. package/README.md +30 -0
  16. package/package.json +79 -0
  17. package/src/components/Accordion/Accordion.stories.tsx +47 -0
  18. package/src/components/Accordion/Accordion.styles.ts +35 -0
  19. package/src/components/Accordion/Accordion.tsx +30 -0
  20. package/src/components/Accordion/index.ts +1 -0
  21. package/src/components/Icon/Icon.stories.tsx +60 -0
  22. package/src/components/Icon/Icon.tsx +75 -0
  23. package/src/components/Icon/faIcons.tsx +168 -0
  24. package/src/components/Icon/index.ts +2 -0
  25. package/src/components/Icon/indicons.tsx +699 -0
  26. package/src/components/Icon/storyHelpers.tsx +87 -0
  27. package/src/components/ListTable/Header/Header.styles.ts +62 -0
  28. package/src/components/ListTable/Header/Header.tsx +67 -0
  29. package/src/components/ListTable/Header/index.ts +1 -0
  30. package/src/components/ListTable/ListTable.stories.tsx +301 -0
  31. package/src/components/ListTable/ListTable.styles.ts +76 -0
  32. package/src/components/ListTable/ListTable.tsx +135 -0
  33. package/src/components/ListTable/index.ts +1 -0
  34. package/src/components/ListTable/mock-data/index.ts +1 -0
  35. package/src/components/ListTable/mock-data/mock-data.ts +291 -0
  36. package/src/components/Pagination/Pagination.stories.tsx +45 -0
  37. package/src/components/Pagination/Pagination.styles.ts +51 -0
  38. package/src/components/Pagination/Pagination.tsx +118 -0
  39. package/src/components/Pagination/index.ts +1 -0
  40. package/src/components/basic-section/Section/Section.stories.tsx +14 -0
  41. package/src/components/basic-section/Section/Section.styles.ts +8 -0
  42. package/src/components/basic-section/Section/Section.tsx +30 -0
  43. package/src/components/basic-section/Section/index.ts +1 -0
  44. package/src/components/basic-section/SectionBlock/SectionBlock.styles.ts +15 -0
  45. package/src/components/basic-section/SectionBlock/SectionBlock.tsx +37 -0
  46. package/src/components/basic-section/SectionBlock/index.ts +1 -0
  47. package/src/components/basic-section/SectionBody/SectionBody.stories.tsx +16 -0
  48. package/src/components/basic-section/SectionBody/SectionBody.styles.ts +18 -0
  49. package/src/components/basic-section/SectionBody/SectionBody.tsx +30 -0
  50. package/src/components/basic-section/SectionBody/index.ts +1 -0
  51. package/src/components/basic-section/SectionHeader/SectionHeader.stories.tsx +17 -0
  52. package/src/components/basic-section/SectionHeader/SectionHeader.styles.ts +5 -0
  53. package/src/components/basic-section/SectionHeader/SectionHeader.tsx +35 -0
  54. package/src/components/basic-section/SectionHeader/index.ts +1 -0
  55. package/src/components/basic-section/SectionTable/SectionTable.styles.ts +237 -0
  56. package/src/components/basic-section/SectionTable/SectionTable.tsx +229 -0
  57. package/src/components/basic-section/SectionTable/index.ts +1 -0
  58. package/src/components/basic-section/index.ts +5 -0
  59. package/src/components/buttons/Button/Button.stories.tsx +80 -0
  60. package/src/components/buttons/Button/Button.styles.ts +99 -0
  61. package/src/components/buttons/Button/Button.tsx +74 -0
  62. package/src/components/buttons/Button/index.ts +1 -0
  63. package/src/components/buttons/IconButton/IconButton.stories.tsx +96 -0
  64. package/src/components/buttons/IconButton/IconButton.styles.ts +78 -0
  65. package/src/components/buttons/IconButton/IconButton.tsx +109 -0
  66. package/src/components/buttons/IconButton/index.ts +1 -0
  67. package/src/components/buttons/commonStyles.ts +108 -0
  68. package/src/components/buttons/index.ts +2 -0
  69. package/src/components/buttons/types.ts +2 -0
  70. package/src/components/dropdowns/BorderSelect/BorderSelect.stories.tsx +22 -0
  71. package/src/components/dropdowns/BorderSelect/BorderSelect.styles.ts +73 -0
  72. package/src/components/dropdowns/BorderSelect/BorderSelect.tsx +85 -0
  73. package/src/components/dropdowns/BorderSelect/index.ts +1 -0
  74. package/src/components/dropdowns/MultiCombobox/MultiCombobox.stories.tsx +146 -0
  75. package/src/components/dropdowns/MultiCombobox/MultiCombobox.styles.ts +89 -0
  76. package/src/components/dropdowns/MultiCombobox/MultiCombobox.tsx +123 -0
  77. package/src/components/dropdowns/MultiCombobox/index.ts +1 -0
  78. package/src/components/dropdowns/Select/Select.stories.tsx +54 -0
  79. package/src/components/dropdowns/Select/Select.styles.ts +73 -0
  80. package/src/components/dropdowns/Select/Select.tsx +69 -0
  81. package/src/components/dropdowns/Select/index.ts +1 -0
  82. package/src/components/dropdowns/SingleCombobox/SingleCombobox.stories.tsx +61 -0
  83. package/src/components/dropdowns/SingleCombobox/SingleCombobox.styles.ts +56 -0
  84. package/src/components/dropdowns/SingleCombobox/SingleCombobox.tsx +103 -0
  85. package/src/components/dropdowns/SingleCombobox/index.ts +1 -0
  86. package/src/components/dropdowns/commonStyles.ts +65 -0
  87. package/src/components/dropdowns/index.ts +4 -0
  88. package/src/components/dropdowns/types.ts +45 -0
  89. package/src/components/dropdowns/useCombobox.ts +32 -0
  90. package/src/components/dropdowns/utils.tsx +25 -0
  91. package/src/components/index.ts +9 -0
  92. package/src/components/inputs/EditableInput/EditableInput.stories.tsx +26 -0
  93. package/src/components/inputs/EditableInput/EditableInput.styles.ts +21 -0
  94. package/src/components/inputs/EditableInput/EditableInput.tsx +103 -0
  95. package/src/components/inputs/EditableInput/index.ts +1 -0
  96. package/src/components/inputs/NumberInput/NumberInput.stories.tsx +72 -0
  97. package/src/components/inputs/NumberInput/NumberInput.styles.ts +66 -0
  98. package/src/components/inputs/NumberInput/NumberInput.tsx +153 -0
  99. package/src/components/inputs/NumberInput/index.ts +1 -0
  100. package/src/components/inputs/SearchInput/SearchInput.stories.tsx +17 -0
  101. package/src/components/inputs/SearchInput/SearchInput.styles.ts +25 -0
  102. package/src/components/inputs/SearchInput/SearchInput.tsx +47 -0
  103. package/src/components/inputs/SearchInput/index.ts +1 -0
  104. package/src/components/inputs/TextInput/TextInput.stories.tsx +104 -0
  105. package/src/components/inputs/TextInput/TextInput.styles.ts +74 -0
  106. package/src/components/inputs/TextInput/TextInput.tsx +116 -0
  107. package/src/components/inputs/TextInput/index.ts +1 -0
  108. package/src/components/inputs/index.ts +4 -0
  109. package/src/components/inputs/inputsCommon.styles.ts +61 -0
  110. package/src/components/loading-indicators/BarSpinner/BarSpinner.stories.tsx +14 -0
  111. package/src/components/loading-indicators/BarSpinner/BarSpinner.styles.ts +53 -0
  112. package/src/components/loading-indicators/BarSpinner/BarSpinner.tsx +21 -0
  113. package/src/components/loading-indicators/BarSpinner/index.ts +1 -0
  114. package/src/components/loading-indicators/CirclePulse/CirclePulse.stories.tsx +22 -0
  115. package/src/components/loading-indicators/CirclePulse/CirclePulse.styles.ts +81 -0
  116. package/src/components/loading-indicators/CirclePulse/CirclePulse.tsx +61 -0
  117. package/src/components/loading-indicators/CirclePulse/index.ts +1 -0
  118. package/src/components/loading-indicators/CircleSpinner/CircleSpinner.stories.tsx +16 -0
  119. package/src/components/loading-indicators/CircleSpinner/CircleSpinner.tsx +37 -0
  120. package/src/components/loading-indicators/CircleSpinner/index.ts +1 -0
  121. package/src/components/loading-indicators/LoadingList/LoadingList.stories.tsx +14 -0
  122. package/src/components/loading-indicators/LoadingList/LoadingList.styles.ts +42 -0
  123. package/src/components/loading-indicators/LoadingList/LoadingList.tsx +9 -0
  124. package/src/components/loading-indicators/LoadingList/index.ts +1 -0
  125. package/src/components/loading-indicators/PercentageRing/PercentageRing.stories.tsx +18 -0
  126. package/src/components/loading-indicators/PercentageRing/PercentageRing.styles.ts +27 -0
  127. package/src/components/loading-indicators/PercentageRing/PercentageRing.tsx +76 -0
  128. package/src/components/loading-indicators/PercentageRing/index.ts +1 -0
  129. package/src/components/loading-indicators/RandomLoadingMessage/RandomLoadingMessage.stories.tsx +16 -0
  130. package/src/components/loading-indicators/RandomLoadingMessage/RandomLoadingMessage.tsx +18 -0
  131. package/src/components/loading-indicators/RandomLoadingMessage/index.ts +1 -0
  132. package/src/components/loading-indicators/RandomLoadingMessage/random-messages.js +67 -0
  133. package/src/components/loading-indicators/index.ts +6 -0
  134. package/src/components/user-feedback/Shrug/Shrug.stories.tsx +38 -0
  135. package/src/components/user-feedback/Shrug/Shrug.styles.ts +23 -0
  136. package/src/components/user-feedback/Shrug/Shrug.tsx +44 -0
  137. package/src/components/user-feedback/Shrug/index.ts +1 -0
  138. package/src/components/user-feedback/index.ts +1 -0
  139. package/src/index.tsx +18 -0
  140. package/src/styles/globals/buttons.ts +154 -0
  141. package/src/styles/globals/forms.ts +103 -0
  142. package/src/styles/globals/index.tsx +25 -0
  143. package/src/styles/globals/layout.ts +25 -0
  144. package/src/styles/globals/lists.ts +23 -0
  145. package/src/styles/globals/margin-padding.ts +33 -0
  146. package/src/styles/globals/media.ts +13 -0
  147. package/src/styles/globals/tables.ts +34 -0
  148. package/src/styles/globals/typography.ts +95 -0
  149. package/src/styles/globals/utility-classes.ts +76 -0
  150. package/src/tokens/animation.ts +6 -0
  151. package/src/tokens/breakpoints.ts +11 -0
  152. package/src/tokens/colors.ts +279 -0
  153. package/src/tokens/index.ts +20 -0
  154. package/src/tokens/margin.ts +5 -0
  155. package/src/tokens/numbers.js +41 -0
  156. package/src/tokens/padding.ts +5 -0
  157. package/src/tokens/spacings.ts +5 -0
  158. package/src/tokens/typography.ts +37 -0
  159. package/src/types.ts +6 -0
  160. package/tsconfig.json +13 -0
  161. package/webpack.config.js +35 -0
@@ -0,0 +1,135 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React from 'react';
4
+ import { v4 as uuid } from 'uuid';
5
+
6
+ import { Pagination, Accordion, LoadingList, Shrug, SectionBody } from '@/components';
7
+ import { PermafrostComponent } from '@/types';
8
+
9
+ import { Header } from './Header';
10
+ import { StyledListTable } from './ListTable.styles';
11
+
12
+ type Props = PermafrostComponent & {
13
+ accordion?: boolean;
14
+ accordionDefaultOpen?: boolean;
15
+ emptyListMessage?: string;
16
+ error?: any;
17
+ errorMessage?: any;
18
+ headerComponent?: React.ReactNode;
19
+ listHeader: React.ReactNode;
20
+ listItems: React.ReactNode[];
21
+ loading?: any;
22
+ pagination?: {
23
+ currentPage: number;
24
+ limit: number;
25
+ pageInfo: {
26
+ startCursor: number;
27
+ endCursor: number;
28
+ hasNextPage: boolean;
29
+ aggregateCount: number;
30
+ };
31
+ getNextPage: (before: number) => void;
32
+ getPage: (after: number, pageOffset: number) => void;
33
+ getPreviousPage: (after: number) => void;
34
+ };
35
+ sortBy?: {
36
+ descending: boolean;
37
+ items: { name: string; value: string }[];
38
+ value: string;
39
+ onSort: (value: string) => void;
40
+ updateDescending: () => void;
41
+ };
42
+ subTitle?: string | React.ReactNode;
43
+ title: string;
44
+ totalCount?: number;
45
+ };
46
+
47
+ export const ListTable = (props: Props) => {
48
+ const header = (
49
+ <Header
50
+ selectProps={{ 'data-cy': 'dataset--sort-by-select' }}
51
+ title={props.title}
52
+ headerComponent={props.headerComponent}
53
+ sortBy={props.sortBy}
54
+ aggregateCount={props?.pagination?.pageInfo?.aggregateCount || props.totalCount}
55
+ />
56
+ );
57
+
58
+ const RenderList = () => {
59
+ if (props.loading) {
60
+ return <LoadingList />;
61
+ }
62
+ if (props.error) {
63
+ return (
64
+ <SectionBody className="error-shrug">
65
+ <Shrug message={props.errorMessage || 'Sorry, there was an error retrieving this data'} />
66
+ </SectionBody>
67
+ );
68
+ }
69
+
70
+ return (
71
+ <>
72
+ {props.listItems.length === 0 ? (
73
+ <SectionBody className="error-shrug">
74
+ <Shrug message={props.emptyListMessage || 'No results found'} />
75
+ </SectionBody>
76
+ ) : (
77
+ <ul className="list-container">
78
+ {props.listItems.map((li) => {
79
+ const key = uuid();
80
+ return (
81
+ <li className="list-item" key={key}>
82
+ {li}
83
+ </li>
84
+ );
85
+ })}
86
+ </ul>
87
+ )}
88
+ {props.pagination ? (
89
+ <Pagination
90
+ limit={props.pagination.limit}
91
+ pageInfo={props.pagination.pageInfo}
92
+ currentPage={props.pagination.currentPage}
93
+ getPage={props.pagination.getPage}
94
+ getPreviousPage={props.pagination.getPreviousPage}
95
+ getNextPage={props.pagination.getNextPage}
96
+ quantity={props.listItems.length}
97
+ />
98
+ ) : null}
99
+ </>
100
+ );
101
+ };
102
+
103
+ const list = (
104
+ <StyledListTable>
105
+ {props.subTitle ? (
106
+ <div className="sub-title">
107
+ {typeof props.subTitle === 'string' ? (
108
+ <p style={{ maxWidth: '75%' }}>{props.subTitle}</p>
109
+ ) : (
110
+ props.subTitle
111
+ )}
112
+ </div>
113
+ ) : null}
114
+ <div className="list">
115
+ {!props.error ? <div className="list-header-container">{props.listHeader}</div> : null}
116
+ <RenderList />
117
+ </div>
118
+ </StyledListTable>
119
+ );
120
+
121
+ return (
122
+ <StyledListTable className={props.className} data-cy={props['data-cy']} id={props.id}>
123
+ {props.accordion ? (
124
+ <Accordion header={header} content={list} open={props.accordionDefaultOpen} />
125
+ ) : (
126
+ <>
127
+ {header}
128
+ {list}
129
+ </>
130
+ )}
131
+ </StyledListTable>
132
+ );
133
+ };
134
+
135
+ export default ListTable;
@@ -0,0 +1 @@
1
+ export { ListTable } from './ListTable';
@@ -0,0 +1 @@
1
+ export { mockUserHeaders, mockDocProcHeaders, mockAllUsers, mockDocProcReport } from './mock-data';
@@ -0,0 +1,291 @@
1
+ export const mockUserHeaders = [
2
+ { name: 'ID', value: 'ID' },
3
+ { name: 'Name', value: 'NAME' },
4
+ { name: 'Email', value: 'EMAIL' },
5
+ { name: 'Created', value: 'REGISTERED_AT' },
6
+ ];
7
+
8
+ export const mockDocProcHeaders = [
9
+ { name: 'Date', value: 'CREATED_ON' },
10
+ { name: 'Name', value: 'NAME' },
11
+ { name: 'Status', value: 'STATUS' },
12
+ ];
13
+
14
+ export const mockAllUsers = {
15
+ users: [
16
+ {
17
+ id: 240,
18
+ name: 'other user@email.com',
19
+ email: 'other user@email.com',
20
+ registeredAt: '1612905437.021334',
21
+ active: true,
22
+ scopes: [{ scope: 'APP_ACCESS', __typename: 'ScopeAccess' }],
23
+ __typename: 'User',
24
+ },
25
+ {
26
+ id: 239,
27
+ name: 'jay',
28
+ email: 'jay@email.com',
29
+ registeredAt: '1612385431.071407',
30
+ active: true,
31
+ scopes: [
32
+ { scope: 'CELERY_FLOWER', __typename: 'ScopeAccess' },
33
+ { scope: 'MANAGE_USERS', __typename: 'ScopeAccess' },
34
+ { scope: 'APP_ACCESS', __typename: 'ScopeAccess' },
35
+ { scope: 'GRAPHIQL', __typename: 'ScopeAccess' },
36
+ ],
37
+ __typename: 'User',
38
+ },
39
+ {
40
+ id: 238,
41
+ name: 'ryan no accesss',
42
+ email: 'ryan+123@email.com',
43
+ registeredAt: '1611954642.254328',
44
+ active: true,
45
+ scopes: [{ scope: 'APP_ACCESS', __typename: 'ScopeAccess' }],
46
+ __typename: 'User',
47
+ },
48
+ {
49
+ id: 237,
50
+ name: 'Kazmer Test',
51
+ email: 'mike+123@email.com',
52
+ registeredAt: '1611883365.793202',
53
+ active: true,
54
+ scopes: [{ scope: 'APP_ACCESS', __typename: 'ScopeAccess' }],
55
+ __typename: 'User',
56
+ },
57
+ {
58
+ id: 236,
59
+ name: 'andy+012621a@email.com',
60
+ email: 'andy+012621a@email.com',
61
+ registeredAt: '1611708023.136021',
62
+ active: true,
63
+ scopes: [],
64
+ __typename: 'User',
65
+ },
66
+ {
67
+ id: 235,
68
+ name: 'other_user@email.com',
69
+ email: 'other_user@email.com',
70
+ registeredAt: '1611588266.058129',
71
+ active: true,
72
+ scopes: [{ scope: 'APP_ACCESS', __typename: 'ScopeAccess' }],
73
+ __typename: 'User',
74
+ },
75
+ {
76
+ id: 234,
77
+ name: 'Matthew',
78
+ email: 'matthew@bayers.org',
79
+ registeredAt: '1611267047.427759',
80
+ active: true,
81
+ scopes: [
82
+ { scope: 'CELERY_FLOWER', __typename: 'ScopeAccess' },
83
+ { scope: 'APP_ACCESS', __typename: 'ScopeAccess' },
84
+ { scope: 'GRAPHIQL', __typename: 'ScopeAccess' },
85
+ ],
86
+ __typename: 'User',
87
+ },
88
+ {
89
+ id: 233,
90
+ name: 'Kazmer Test',
91
+ email: 'mike.test@email.com',
92
+ registeredAt: '1611256056.678655',
93
+ active: null,
94
+ scopes: [],
95
+ __typename: 'User',
96
+ },
97
+ {
98
+ id: 232,
99
+ name: 'meg',
100
+ email: 'meg@email.com',
101
+ registeredAt: '1611157563.220335',
102
+ active: true,
103
+ scopes: [
104
+ { scope: 'MANAGE_USERS', __typename: 'ScopeAccess' },
105
+ { scope: 'APP_ACCESS', __typename: 'ScopeAccess' },
106
+ { scope: 'GRAPHIQL', __typename: 'ScopeAccess' },
107
+ ],
108
+ __typename: 'User',
109
+ },
110
+ {
111
+ id: 231,
112
+ name: 'Ryan',
113
+ email: 'ryan@email.com',
114
+ registeredAt: '1611069234.797305',
115
+ active: true,
116
+ scopes: [
117
+ { scope: 'CELERY_FLOWER', __typename: 'ScopeAccess' },
118
+ { scope: 'MANAGE_USERS', __typename: 'ScopeAccess' },
119
+ { scope: 'APP_ACCESS', __typename: 'ScopeAccess' },
120
+ { scope: 'GRAPHIQL', __typename: 'ScopeAccess' },
121
+ ],
122
+ __typename: 'User',
123
+ },
124
+ {
125
+ id: 230,
126
+ name: 'dataset2_permissions@email.com',
127
+ email: 'dataset2_permissions@email.com',
128
+ registeredAt: '1611009197.841298',
129
+ active: true,
130
+ scopes: [{ scope: 'APP_ACCESS', __typename: 'ScopeAccess' }],
131
+ __typename: 'User',
132
+ },
133
+ {
134
+ id: 229,
135
+ name: 'dataset1_permissions@email.com',
136
+ email: 'dataset1_permissions@email.com',
137
+ registeredAt: '1611009196.388319',
138
+ active: true,
139
+ scopes: [{ scope: 'APP_ACCESS', __typename: 'ScopeAccess' }],
140
+ __typename: 'User',
141
+ },
142
+ {
143
+ id: 228,
144
+ name: 'rafal@email.com',
145
+ email: 'rafal@email.com',
146
+ registeredAt: '1610614811.580037',
147
+ active: true,
148
+ scopes: [],
149
+ __typename: 'User',
150
+ },
151
+ {
152
+ id: 227,
153
+ name: 'Jonas',
154
+ email: 'jonas@email.com',
155
+ registeredAt: '1610544934.971219',
156
+ active: true,
157
+ scopes: [
158
+ { scope: 'CELERY_FLOWER', __typename: 'ScopeAccess' },
159
+ { scope: 'APP_ACCESS', __typename: 'ScopeAccess' },
160
+ { scope: 'GRAPHIQL', __typename: 'ScopeAccess' },
161
+ ],
162
+ __typename: 'User',
163
+ },
164
+ {
165
+ id: 226,
166
+ name: 'Elias',
167
+ email: 'elias@email.com',
168
+ registeredAt: '1610378674.648602',
169
+ active: true,
170
+ scopes: [
171
+ { scope: 'CELERY_FLOWER', __typename: 'ScopeAccess' },
172
+ { scope: 'MANAGE_USERS', __typename: 'ScopeAccess' },
173
+ { scope: 'APP_ACCESS', __typename: 'ScopeAccess' },
174
+ { scope: 'GRAPHIQL', __typename: 'ScopeAccess' },
175
+ ],
176
+ __typename: 'User',
177
+ },
178
+ {
179
+ id: 225,
180
+ name: 'Michael',
181
+ email: 'michael@email.com',
182
+ registeredAt: '1610377784.876469',
183
+ active: true,
184
+ scopes: [
185
+ { scope: 'CELERY_FLOWER', __typename: 'ScopeAccess' },
186
+ { scope: 'MANAGE_USERS', __typename: 'ScopeAccess' },
187
+ { scope: 'APP_ACCESS', __typename: 'ScopeAccess' },
188
+ { scope: 'GRAPHIQL', __typename: 'ScopeAccess' },
189
+ ],
190
+ __typename: 'User',
191
+ },
192
+ {
193
+ id: 224,
194
+ name: 'Automated Testing',
195
+ email: 'test+platform@email.com',
196
+ registeredAt: '1609428969.611241',
197
+ active: true,
198
+ scopes: [
199
+ { scope: 'CELERY_FLOWER', __typename: 'ScopeAccess' },
200
+ { scope: 'MANAGE_USERS', __typename: 'ScopeAccess' },
201
+ { scope: 'APP_ACCESS', __typename: 'ScopeAccess' },
202
+ { scope: 'GRAPHIQL', __typename: 'ScopeAccess' },
203
+ ],
204
+ __typename: 'User',
205
+ },
206
+ {
207
+ id: 223,
208
+ name: 'admin_permissions2@email.com',
209
+ email: 'admin_permissions2@email.com',
210
+ registeredAt: '1609428428.431605',
211
+ active: true,
212
+ scopes: [
213
+ { scope: 'APP_ACCESS', __typename: 'ScopeAccess' },
214
+ { scope: 'GRAPHIQL', __typename: 'ScopeAccess' },
215
+ ],
216
+ __typename: 'User',
217
+ },
218
+ {
219
+ id: 222,
220
+ name: 'admin_permissions@email.com',
221
+ email: 'admin_permissions@email.com',
222
+ registeredAt: '1609428416.321584',
223
+ active: true,
224
+ scopes: [{ scope: 'APP_ACCESS', __typename: 'ScopeAccess' }],
225
+ __typename: 'User',
226
+ },
227
+ {
228
+ id: 221,
229
+ name: 'test+small3@email.com',
230
+ email: 'test+small3@email.com',
231
+ registeredAt: '1607885687.72808',
232
+ active: true,
233
+ scopes: [
234
+ { scope: 'APP_ACCESS', __typename: 'ScopeAccess' },
235
+ { scope: 'GRAPHIQL', __typename: 'ScopeAccess' },
236
+ ],
237
+ __typename: 'User',
238
+ },
239
+ ],
240
+ pageInfo: {
241
+ startCursor: 240,
242
+ endCursor: 221,
243
+ hasNextPage: true,
244
+ aggregateCount: 149,
245
+ __typename: 'PageInfo',
246
+ },
247
+ __typename: 'UserPage',
248
+ };
249
+
250
+ export const mockDocProcReport = {
251
+ reports: [
252
+ {
253
+ id: 1,
254
+ name: 'Doc_Processing_Report1_01_02_2021',
255
+ status: 'Complete',
256
+ createdOn: '1607885687.72808',
257
+ },
258
+ {
259
+ id: 2,
260
+ name: 'Doc_Processing_Report2_01_02_2021',
261
+ status: 'Complete',
262
+ createdOn: '1607885687.72808',
263
+ },
264
+ {
265
+ id: 3,
266
+ name: 'Doc_Processing_Report3_01_02_2021',
267
+ status: 'Complete',
268
+ createdOn: '1607885687.72808',
269
+ },
270
+ {
271
+ id: 4,
272
+ name: 'Doc_Processing_Report4_01_02_2021',
273
+ status: 'Complete',
274
+ createdOn: '1607885687.72808',
275
+ },
276
+ {
277
+ id: 5,
278
+ name: 'Doc_Processing_Report5_01_02_2021',
279
+ status: 'Complete',
280
+ createdOn: '1607885687.72808',
281
+ },
282
+ ],
283
+ pageInfo: {
284
+ startCursor: 240,
285
+ endCursor: 221,
286
+ hasNextPage: true,
287
+ aggregateCount: 15,
288
+ __typename: 'PageInfo',
289
+ },
290
+ __typename: 'UserPage',
291
+ };
@@ -0,0 +1,45 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+
3
+ import { Pagination } from './Pagination';
4
+
5
+ const meta = {
6
+ component: Pagination,
7
+ title: 'Pagination',
8
+ argTypes: {},
9
+ args: {
10
+ skip: 0,
11
+ limit: 10,
12
+ getPage: () => {},
13
+ getNextPage: () => {},
14
+ getPreviousPage: () => {},
15
+ },
16
+ } satisfies Meta<typeof Pagination>;
17
+
18
+ export default meta;
19
+ type Story = StoryObj<typeof Pagination>;
20
+
21
+ export const Normal: Story = {
22
+ args: {
23
+ currentPage: 3,
24
+ pageInfo: {
25
+ aggregateCount: 60,
26
+ endCursor: 51,
27
+ hasNextPage: true,
28
+ startCursor: 60,
29
+ },
30
+ quantity: 10,
31
+ },
32
+ };
33
+
34
+ export const WithoutPages: Story = {
35
+ args: {
36
+ currentPage: 1,
37
+ pageInfo: {
38
+ aggregateCount: 9,
39
+ endCursor: 1,
40
+ hasNextPage: false,
41
+ startCursor: 9,
42
+ },
43
+ quantity: 9,
44
+ },
45
+ };
@@ -0,0 +1,51 @@
1
+ import styled from 'styled-components';
2
+
3
+ import { COLORS } from '@/tokens';
4
+
5
+ const paddingRight = '30px';
6
+
7
+ export const StyledPagination = styled.div`
8
+ width: 100%;
9
+ position: relative;
10
+
11
+ .Pagination--stats {
12
+ display: inline-block;
13
+ padding: 10px 0;
14
+ line-height: 1.6;
15
+ }
16
+
17
+ .Pagination--button-group {
18
+ display: flex;
19
+ justify-content: flex-end;
20
+ width: calc(25% + ${paddingRight});
21
+ padding: 10px ${paddingRight} 10px 0;
22
+ position: absolute;
23
+ top: 0;
24
+ right: 0;
25
+
26
+ > * {
27
+ display: inline-block;
28
+ font-size: 18px;
29
+ vertical-align: middle;
30
+ margin-right: 8px;
31
+ }
32
+
33
+ button {
34
+ width: auto;
35
+ padding: 0;
36
+ display: inline-block;
37
+ background: none;
38
+ box-shadow: none;
39
+ text-decoration: underline;
40
+ color: ${COLORS.midFontColor};
41
+
42
+ &:hover {
43
+ color: ${COLORS.defaultFontColor};
44
+ }
45
+
46
+ &.Pagination--non-click {
47
+ text-decoration: none;
48
+ }
49
+ }
50
+ }
51
+ `;
@@ -0,0 +1,118 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React from 'react';
4
+
5
+ import { numberUtils } from '@indico-data/utils';
6
+
7
+ import { PermafrostComponent } from '@/types';
8
+
9
+ import { StyledPagination } from './Pagination.styles';
10
+
11
+ type Props = PermafrostComponent & {
12
+ currentPage: number;
13
+ limit: number;
14
+ pageInfo: {
15
+ aggregateCount: number;
16
+ endCursor: number;
17
+ hasNextPage: boolean;
18
+ startCursor: number;
19
+ };
20
+ quantity: number;
21
+ skip?: number;
22
+ getPage(startCursor: number, endCursor: number): void;
23
+ getNextPage(cursor: number): void;
24
+ getPreviousPage(cursor: number): void;
25
+ };
26
+
27
+ export function Pagination(props: Props) {
28
+ // renderPreviousPages = (currentPage, lastPage) => {
29
+ // if (currentPage === lastPage - 2) {
30
+ // return null
31
+ // }
32
+ // // this.props.getPage(endCursor, 1)
33
+ // if (currentPage === lastPage - 1) {
34
+ // return <>{lastPage - 2 >= 1 && <button onClick={() => this.props.getBeforePage(startCursor, )}>{lastPage - 2}</button>}</>
35
+ // }
36
+
37
+ // if (currentPage === lastPage) {
38
+ // return (
39
+ // <>
40
+ // {lastPage - 2 >= 1 && <button>{lastPage - 2}</button>}
41
+ // {lastPage - 1 >= 1 && <button>{lastPage - 1}</button>}
42
+ // </>
43
+ // )
44
+ // }
45
+ // }
46
+
47
+ const { aggregateCount, hasNextPage, endCursor, startCursor } = props.pageInfo;
48
+ const { currentPage, limit, quantity } = props;
49
+ const lastPage = Math.ceil(aggregateCount / limit);
50
+ const currentItemNumber = (currentPage - 1) * limit + 1;
51
+
52
+ return (
53
+ <StyledPagination className={props.className} data-cy={props['data-cy']} id={props.id}>
54
+ <div className="Pagination--stats">
55
+ <p>
56
+ Showing{' '}
57
+ {aggregateCount === 0 ? (
58
+ <></>
59
+ ) : (
60
+ <>
61
+ {currentItemNumber} - {currentItemNumber + quantity - 1} of{' '}
62
+ </>
63
+ )}
64
+ {numberUtils.numberWithCommas(aggregateCount)} entries
65
+ </p>
66
+ </div>
67
+ {aggregateCount > limit && (
68
+ <div className="Pagination--button-group" data-cy="Pagination--button-group">
69
+ <p data-cy="pagination--label">Page:&nbsp;</p>
70
+ {currentPage > 1 && (
71
+ <button onClick={() => props.getPreviousPage(startCursor)}>Prev</button>
72
+ )}
73
+ {/* {currentPage >= lastPage - 2 && this.renderPreviousPages(currentPage, lastPage)} */}
74
+ <p data-cy="pagination--current-page">{currentPage}</p>
75
+ {lastPage > currentPage + 1 && (
76
+ <button
77
+ onClick={() => props.getPage(endCursor, 1)}
78
+ data-cy="pagination--second-page-number"
79
+ >
80
+ {currentPage + 1}
81
+ </button>
82
+ )}
83
+ {lastPage > currentPage + 2 && (
84
+ <button
85
+ onClick={() => props.getPage(endCursor, 2)}
86
+ data-cy="pagination--third-page-number"
87
+ >
88
+ {currentPage + 2}
89
+ </button>
90
+ )}
91
+ {lastPage > currentPage + 3 && (
92
+ <button onClick={() => props.getPage(endCursor, 3)}>{currentPage + 3}</button>
93
+ )}
94
+ {lastPage - (currentPage + 2) === 3 && (
95
+ <button onClick={() => props.getPage(endCursor, 4)}>{currentPage + 4}</button>
96
+ )}
97
+ {lastPage - (currentPage + 2) > 2 && lastPage - (currentPage + 2) !== 3 && <p>...</p>}
98
+ {lastPage !== currentPage && (
99
+ <button
100
+ onClick={() => props.getPage(endCursor, lastPage - currentPage)}
101
+ data-cy="pagination--last-page"
102
+ >
103
+ {lastPage}
104
+ </button>
105
+ )}
106
+ {hasNextPage && (
107
+ <button
108
+ onClick={() => props.getNextPage(endCursor)}
109
+ data-cy="pagination--next-page-number"
110
+ >
111
+ Next
112
+ </button>
113
+ )}
114
+ </div>
115
+ )}
116
+ </StyledPagination>
117
+ );
118
+ }
@@ -0,0 +1 @@
1
+ export { Pagination } from './Pagination';
@@ -0,0 +1,14 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+
3
+ import { Section } from './Section';
4
+
5
+ const meta = {
6
+ component: Section,
7
+ title: 'Basic Section/Section',
8
+ argTypes: {},
9
+ } satisfies Meta<typeof Section>;
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof Section>;
13
+
14
+ export const Normal: Story = {};
@@ -0,0 +1,8 @@
1
+ import styled from 'styled-components';
2
+
3
+ export const StyledSection = styled.article`
4
+ position: relative;
5
+ float: left;
6
+ margin-bottom: 20px;
7
+ width: 100%;
8
+ `;