@patternfly/react-table 5.2.0-prerelease.9 → 6.0.0-alpha.10

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 (175) hide show
  1. package/CHANGELOG.md +242 -0
  2. package/components/package.json +1 -1
  3. package/deprecated/package.json +1 -1
  4. package/dist/dynamic/components/Table/package.json +1 -1
  5. package/dist/dynamic/components/Table/utils/decorators/package.json +1 -1
  6. package/dist/dynamic/components/Table/utils/package.json +1 -1
  7. package/dist/dynamic/deprecated/components/Table/base/package.json +1 -1
  8. package/dist/dynamic/deprecated/components/Table/package.json +1 -1
  9. package/dist/dynamic/deprecated/components/package.json +1 -1
  10. package/dist/esm/components/Table/Caption.js +1 -1
  11. package/dist/esm/components/Table/Caption.js.map +1 -1
  12. package/dist/esm/components/Table/CollapseColumn.js +1 -1
  13. package/dist/esm/components/Table/CollapseColumn.js.map +1 -1
  14. package/dist/esm/components/Table/DraggableRowWrapper.js +2 -2
  15. package/dist/esm/components/Table/DraggableRowWrapper.js.map +1 -1
  16. package/dist/esm/components/Table/EditColumn.js +1 -1
  17. package/dist/esm/components/Table/EditColumn.js.map +1 -1
  18. package/dist/esm/components/Table/EditableSelectInputCell.js +3 -3
  19. package/dist/esm/components/Table/EditableSelectInputCell.js.map +1 -1
  20. package/dist/esm/components/Table/EditableTextCell.js +3 -3
  21. package/dist/esm/components/Table/EditableTextCell.js.map +1 -1
  22. package/dist/esm/components/Table/ExpandableRowContent.js +1 -1
  23. package/dist/esm/components/Table/ExpandableRowContent.js.map +1 -1
  24. package/dist/esm/components/Table/HeaderCellInfoWrapper.js +1 -1
  25. package/dist/esm/components/Table/HeaderCellInfoWrapper.js.map +1 -1
  26. package/dist/esm/components/Table/InnerScrollContainer.js +1 -1
  27. package/dist/esm/components/Table/InnerScrollContainer.js.map +1 -1
  28. package/dist/esm/components/Table/OuterScrollContainer.js +1 -1
  29. package/dist/esm/components/Table/OuterScrollContainer.js.map +1 -1
  30. package/dist/esm/components/Table/SelectColumn.d.ts +5 -0
  31. package/dist/esm/components/Table/SelectColumn.d.ts.map +1 -1
  32. package/dist/esm/components/Table/SelectColumn.js +6 -3
  33. package/dist/esm/components/Table/SelectColumn.js.map +1 -1
  34. package/dist/esm/components/Table/SortColumn.d.ts +4 -0
  35. package/dist/esm/components/Table/SortColumn.d.ts.map +1 -1
  36. package/dist/esm/components/Table/SortColumn.js +3 -3
  37. package/dist/esm/components/Table/SortColumn.js.map +1 -1
  38. package/dist/esm/components/Table/Table.js +3 -3
  39. package/dist/esm/components/Table/Table.js.map +1 -1
  40. package/dist/esm/components/Table/TableText.d.ts +3 -1
  41. package/dist/esm/components/Table/TableText.d.ts.map +1 -1
  42. package/dist/esm/components/Table/TableText.js +13 -11
  43. package/dist/esm/components/Table/TableText.js.map +1 -1
  44. package/dist/esm/components/Table/TableTypes.d.ts +3 -0
  45. package/dist/esm/components/Table/TableTypes.d.ts.map +1 -1
  46. package/dist/esm/components/Table/Tbody.js +1 -1
  47. package/dist/esm/components/Table/Tbody.js.map +1 -1
  48. package/dist/esm/components/Table/Td.js +3 -3
  49. package/dist/esm/components/Table/Td.js.map +1 -1
  50. package/dist/esm/components/Table/Th.d.ts +3 -0
  51. package/dist/esm/components/Table/Th.d.ts.map +1 -1
  52. package/dist/esm/components/Table/Th.js +16 -9
  53. package/dist/esm/components/Table/Th.js.map +1 -1
  54. package/dist/esm/components/Table/Thead.js +1 -1
  55. package/dist/esm/components/Table/Thead.js.map +1 -1
  56. package/dist/esm/components/Table/Tr.js +2 -2
  57. package/dist/esm/components/Table/Tr.js.map +1 -1
  58. package/dist/esm/components/Table/TreeRowWrapper.js +2 -2
  59. package/dist/esm/components/Table/TreeRowWrapper.js.map +1 -1
  60. package/dist/esm/components/Table/utils/decorators/cellActions.js +1 -1
  61. package/dist/esm/components/Table/utils/decorators/cellActions.js.map +1 -1
  62. package/dist/esm/components/Table/utils/decorators/cellWidth.js +1 -1
  63. package/dist/esm/components/Table/utils/decorators/cellWidth.js.map +1 -1
  64. package/dist/esm/components/Table/utils/decorators/classNames.js +1 -1
  65. package/dist/esm/components/Table/utils/decorators/classNames.js.map +1 -1
  66. package/dist/esm/components/Table/utils/decorators/collapsible.js +1 -1
  67. package/dist/esm/components/Table/utils/decorators/collapsible.js.map +1 -1
  68. package/dist/esm/components/Table/utils/decorators/compoundExpand.js +1 -1
  69. package/dist/esm/components/Table/utils/decorators/compoundExpand.js.map +1 -1
  70. package/dist/esm/components/Table/utils/decorators/editable.js +1 -1
  71. package/dist/esm/components/Table/utils/decorators/editable.js.map +1 -1
  72. package/dist/esm/components/Table/utils/decorators/favoritable.js +1 -1
  73. package/dist/esm/components/Table/utils/decorators/favoritable.js.map +1 -1
  74. package/dist/esm/components/Table/utils/decorators/info.js +1 -1
  75. package/dist/esm/components/Table/utils/decorators/info.js.map +1 -1
  76. package/dist/esm/components/Table/utils/decorators/selectable.d.ts.map +1 -1
  77. package/dist/esm/components/Table/utils/decorators/selectable.js +4 -4
  78. package/dist/esm/components/Table/utils/decorators/selectable.js.map +1 -1
  79. package/dist/esm/components/Table/utils/decorators/sortable.d.ts.map +1 -1
  80. package/dist/esm/components/Table/utils/decorators/sortable.js +7 -4
  81. package/dist/esm/components/Table/utils/decorators/sortable.js.map +1 -1
  82. package/dist/esm/components/Table/utils/decorators/treeRow.js +2 -2
  83. package/dist/esm/components/Table/utils/decorators/treeRow.js.map +1 -1
  84. package/dist/esm/components/Table/utils/decorators/wrappable.js +1 -1
  85. package/dist/esm/components/Table/utils/decorators/wrappable.js.map +1 -1
  86. package/dist/esm/demos/index.d.ts +2 -0
  87. package/dist/esm/demos/index.d.ts.map +1 -0
  88. package/dist/esm/demos/index.js +2 -0
  89. package/dist/esm/demos/index.js.map +1 -0
  90. package/dist/esm/demos/sampleData.d.ts +13 -0
  91. package/dist/esm/demos/sampleData.d.ts.map +1 -0
  92. package/dist/esm/demos/sampleData.js +764 -0
  93. package/dist/esm/demos/sampleData.js.map +1 -0
  94. package/dist/esm/deprecated/components/Table/Table.js +1 -1
  95. package/dist/esm/deprecated/components/Table/Table.js.map +1 -1
  96. package/dist/esm/index.d.ts +1 -0
  97. package/dist/esm/index.d.ts.map +1 -1
  98. package/dist/esm/index.js +1 -0
  99. package/dist/esm/index.js.map +1 -1
  100. package/dist/js/components/Table/EditableSelectInputCell.js +1 -1
  101. package/dist/js/components/Table/EditableSelectInputCell.js.map +1 -1
  102. package/dist/js/components/Table/EditableTextCell.js +1 -1
  103. package/dist/js/components/Table/EditableTextCell.js.map +1 -1
  104. package/dist/js/components/Table/SelectColumn.d.ts +5 -0
  105. package/dist/js/components/Table/SelectColumn.d.ts.map +1 -1
  106. package/dist/js/components/Table/SelectColumn.js +6 -3
  107. package/dist/js/components/Table/SelectColumn.js.map +1 -1
  108. package/dist/js/components/Table/SortColumn.d.ts +4 -0
  109. package/dist/js/components/Table/SortColumn.d.ts.map +1 -1
  110. package/dist/js/components/Table/SortColumn.js +3 -2
  111. package/dist/js/components/Table/SortColumn.js.map +1 -1
  112. package/dist/js/components/Table/TableText.d.ts +3 -1
  113. package/dist/js/components/Table/TableText.d.ts.map +1 -1
  114. package/dist/js/components/Table/TableText.js +12 -10
  115. package/dist/js/components/Table/TableText.js.map +1 -1
  116. package/dist/js/components/Table/TableTypes.d.ts +3 -0
  117. package/dist/js/components/Table/TableTypes.d.ts.map +1 -1
  118. package/dist/js/components/Table/Th.d.ts +3 -0
  119. package/dist/js/components/Table/Th.d.ts.map +1 -1
  120. package/dist/js/components/Table/Th.js +14 -7
  121. package/dist/js/components/Table/Th.js.map +1 -1
  122. package/dist/js/components/Table/utils/decorators/selectable.d.ts.map +1 -1
  123. package/dist/js/components/Table/utils/decorators/selectable.js +2 -2
  124. package/dist/js/components/Table/utils/decorators/selectable.js.map +1 -1
  125. package/dist/js/components/Table/utils/decorators/sortable.d.ts.map +1 -1
  126. package/dist/js/components/Table/utils/decorators/sortable.js +6 -3
  127. package/dist/js/components/Table/utils/decorators/sortable.js.map +1 -1
  128. package/dist/js/demos/index.d.ts +2 -0
  129. package/dist/js/demos/index.d.ts.map +1 -0
  130. package/dist/js/demos/index.js +5 -0
  131. package/dist/js/demos/index.js.map +1 -0
  132. package/dist/js/demos/sampleData.d.ts +13 -0
  133. package/dist/js/demos/sampleData.d.ts.map +1 -0
  134. package/dist/js/demos/sampleData.js +767 -0
  135. package/dist/js/demos/sampleData.js.map +1 -0
  136. package/dist/js/index.d.ts +1 -0
  137. package/dist/js/index.d.ts.map +1 -1
  138. package/dist/js/index.js +1 -0
  139. package/dist/js/index.js.map +1 -1
  140. package/dist/umd/react-table.min.js +3 -3
  141. package/package.json +8 -7
  142. package/src/components/Table/EditableSelectInputCell.tsx +1 -1
  143. package/src/components/Table/EditableTextCell.tsx +1 -1
  144. package/src/components/Table/SelectColumn.tsx +27 -8
  145. package/src/components/Table/SortColumn.tsx +15 -1
  146. package/src/components/Table/TableText.tsx +19 -9
  147. package/src/components/Table/TableTypes.tsx +3 -0
  148. package/src/components/Table/Th.tsx +16 -5
  149. package/src/components/Table/examples/TableStickyColumnsAndHeader.tsx +5 -4
  150. package/src/components/Table/utils/decorators/selectable.tsx +2 -1
  151. package/src/components/Table/utils/decorators/sortable.tsx +8 -2
  152. package/src/components/Table/utils/transformers.test.tsx +1 -0
  153. package/src/demos/Table.md +159 -0
  154. package/src/demos/examples/TableAutomaticPagination.tsx +101 -0
  155. package/src/{docs/demos/table-demos/BulkSelect.jsx → demos/examples/TableBulkSelect.tsx} +41 -20
  156. package/src/demos/examples/TableColumnManagement.tsx +486 -0
  157. package/src/demos/examples/TableColumnManagementWithDraggable.tsx +641 -0
  158. package/src/{docs/demos/table-demos/Compact.jsx → demos/examples/TableCompact.tsx} +32 -16
  159. package/src/{docs/demos/table-demos/CompoundExpansion.jsx → demos/examples/TableCompoundExpansion.tsx} +25 -12
  160. package/src/demos/examples/TableEmptyStateDefault.tsx +60 -0
  161. package/src/demos/examples/TableEmptyStateError.tsx +53 -0
  162. package/src/demos/examples/TableEmptyStateLoading.tsx +43 -0
  163. package/src/{docs/demos/table-demos/ExpandCollapseAll.jsx → demos/examples/TableExpandCollapseAll.tsx} +17 -10
  164. package/src/demos/examples/TableFilterable.tsx +394 -0
  165. package/src/{docs/demos/table-demos/SortableResponsive.jsx → demos/examples/TableSortableResponsive.tsx} +30 -28
  166. package/src/{docs/demos/table-demos/StaticBottomPagination.jsx → demos/examples/TableStaticBottomPagination.tsx} +22 -9
  167. package/src/{docs/demos/table-demos/StickyFirstColumn.jsx → demos/examples/TableStickyFirstColumn.tsx} +31 -9
  168. package/src/{docs/demos/table-demos/StickyHeader.jsx → demos/examples/TableStickyHeader.tsx} +3 -3
  169. package/src/demos/index.ts +1 -0
  170. package/src/{docs/demos/table-demos/sampleData.js → demos/sampleData.tsx} +88 -77
  171. package/src/deprecated/components/Table/__tests__/Table.test.tsx +4 -9
  172. package/src/deprecated/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +8 -8
  173. package/src/index.ts +1 -0
  174. package/src/docs/demos/Table.md +0 -1621
  175. package/src/docs/demos/table-demos/ColumnManagement.jsx +0 -471
@@ -1,1621 +0,0 @@
1
- ---
2
- id: Table
3
- section: components
4
- ---
5
-
6
- import {
7
- Checkbox,
8
- Label,
9
- PageSection,
10
- ToolbarExpandIconWrapper,
11
- ToolbarContent,
12
- Toolbar,
13
- ToolbarItem,
14
- SearchInput,
15
- Masthead,
16
- MastheadToggle,
17
- MastheadMain,
18
- MastheadContent,
19
- SkipToContent,
20
- Breadcrumb,
21
- BreadcrumbItem,
22
- Page,
23
- PageSectionVariants,
24
- TextContent,
25
- Text,
26
- Divider } from '@patternfly/react-core';
27
- import { Table as TableDeprecated, TableHeader, TableBody } from '@patternfly/react-table/deprecated';
28
-
29
- import CheckIcon from '@patternfly/react-icons/dist/esm/icons/check-icon';
30
- import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon';
31
- import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon';
32
- import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';
33
- import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
34
- import EditIcon from '@patternfly/react-icons/dist/esm/icons/edit-icon';
35
- import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
36
- import SortAmountDownIcon from '@patternfly/react-icons/dist/esm/icons/sort-amount-down-icon';
37
- import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
38
- import SyncIcon from '@patternfly/react-icons/dist/esm/icons/sync-icon';
39
- import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon';
40
- import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
41
- import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon';
42
- import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon';
43
- import globalDangerColor200 from '@patternfly/react-tokens/dist/esm/global_danger_color_200';
44
- import imgBrand from '@patternfly/react-core/src/components/assets/pfLogo.svg';
45
- import imgAvatar from '@patternfly/react-core/src/components/assets/avatarImg.svg';
46
- import AngleDownIcon from '@patternfly/react-icons/dist/esm/icons/angle-down-icon';
47
- import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon';
48
- import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';
49
- import AttentionBellIcon from '@patternfly/react-icons/dist/esm/icons/attention-bell-icon';
50
- import BlueprintIcon from '@patternfly/react-icons/dist/esm/icons/blueprint-icon';
51
- import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
52
- import { rows, columns } from '@patternfly/react-table/src/docs/demos/table-demos/sampleData';
53
-
54
- ## Demos
55
-
56
- ### Bulk select
57
-
58
- ```js isFullscreen file="./table-demos/BulkSelect.jsx"
59
-
60
- ```
61
-
62
- ### Expand/collapse all
63
-
64
- ```js isFullscreen file="./table-demos/ExpandCollapseAll.jsx"
65
-
66
- ```
67
-
68
- ### Compact
69
-
70
- ```js isFullscreen file="./table-demos/Compact.jsx"
71
-
72
- ```
73
-
74
- ### Compound expansion
75
-
76
- ```js isFullscreen file="./table-demos/CompoundExpansion.jsx"
77
-
78
- ```
79
-
80
- ### Column management
81
-
82
- ```js isFullscreen file="./table-demos/ColumnManagement.jsx"
83
-
84
- ```
85
-
86
- ### Column management with draggable
87
-
88
- ```js
89
- import React from 'react';
90
- import {
91
- Button,
92
- DataList,
93
- DataListCheck,
94
- DataListControl,
95
- DataListDragButton,
96
- DataListItem,
97
- DataListItemRow,
98
- DataListCell,
99
- DataListItemCells,
100
- Toolbar,
101
- ToolbarContent,
102
- ToolbarItem,
103
- Modal,
104
- OverflowMenu,
105
- OverflowMenuGroup,
106
- OverflowMenuItem,
107
- Pagination,
108
- PaginationVariant,
109
- Text,
110
- TextContent,
111
- TextVariants,
112
- MenuToggle
113
- } from '@patternfly/react-core';
114
- import { Table as TableDeprecated, TableHeader, TableBody, TableText } from '@patternfly/react-table/deprecated';
115
- import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon';
116
- import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';
117
- import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
118
- import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
119
- import SortAmountDownIcon from '@patternfly/react-icons/dist/esm/icons/sort-amount-down-icon';
120
-
121
- class ColumnManagementAction extends React.Component {
122
- constructor(props) {
123
- super(props);
124
- this.actions = [
125
- {
126
- title: <a href="#">Link</a>
127
- },
128
- {
129
- title: 'Action'
130
- },
131
- {
132
- isSeparator: true
133
- },
134
- {
135
- title: <a href="#">Separated link</a>
136
- }
137
- ];
138
- this.defaultColumns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit', ''];
139
- this.defaultRows = [
140
- {
141
- cells: [
142
- {
143
- title: (
144
- <React.Fragment>
145
- <div>Node 1</div>
146
- <a href="#">siemur/test-space</a>
147
- </React.Fragment>
148
- ),
149
- props: { column: 'Repositories' }
150
- },
151
- {
152
- title: (
153
- <React.Fragment>
154
- <CodeBranchIcon key="icon" /> 10
155
- </React.Fragment>
156
- ),
157
- props: { column: 'Branches' }
158
- },
159
- {
160
- title: (
161
- <React.Fragment>
162
- <CodeIcon key="icon" /> 25
163
- </React.Fragment>
164
- ),
165
- props: { column: 'Pull requests' }
166
- },
167
- {
168
- title: (
169
- <React.Fragment>
170
- <CubeIcon key="icon" /> 5
171
- </React.Fragment>
172
- ),
173
- props: { column: 'Workspaces' }
174
- },
175
- {
176
- title: '2 days ago',
177
- props: { column: 'Last commit' }
178
- },
179
- {
180
- title: (
181
- <React.Fragment>
182
- <a href="#">Action link</a>
183
- </React.Fragment>
184
- ),
185
- props: { column: '' }
186
- }
187
- ]
188
- },
189
- {
190
- cells: [
191
- {
192
- title: (
193
- <React.Fragment>
194
- <div>Node 2</div>
195
- <a href="#">siemur/test-space</a>
196
- </React.Fragment>
197
- ),
198
- props: { column: 'Repositories' }
199
- },
200
- {
201
- title: (
202
- <React.Fragment>
203
- <CodeBranchIcon key="icon" /> 8
204
- </React.Fragment>
205
- ),
206
- props: { column: 'Branches' }
207
- },
208
- {
209
- title: (
210
- <React.Fragment>
211
- <CodeIcon key="icon" /> 30
212
- </React.Fragment>
213
- ),
214
- props: { column: 'Pull requests' }
215
- },
216
- {
217
- title: (
218
- <React.Fragment>
219
- <CubeIcon key="icon" /> 2
220
- </React.Fragment>
221
- ),
222
- props: { column: 'Workspaces' }
223
- },
224
- {
225
- title: '2 days ago',
226
- props: { column: 'Last commit' }
227
- },
228
- {
229
- title: (
230
- <React.Fragment>
231
- <a href="#">Action link</a>
232
- </React.Fragment>
233
- ),
234
- props: { column: '' }
235
- }
236
- ]
237
- },
238
- {
239
- cells: [
240
- {
241
- title: (
242
- <React.Fragment>
243
- <div>Node 3</div>
244
- <a href="#">siemur/test-space</a>
245
- </React.Fragment>
246
- ),
247
- props: { column: 'Repositories' }
248
- },
249
- {
250
- title: (
251
- <React.Fragment>
252
- <CodeBranchIcon key="icon" /> 12
253
- </React.Fragment>
254
- ),
255
- props: { column: 'Branches' }
256
- },
257
- {
258
- title: (
259
- <React.Fragment>
260
- <CodeIcon key="icon" /> 48
261
- </React.Fragment>
262
- ),
263
- props: { column: 'Pull requests' }
264
- },
265
- {
266
- title: (
267
- <React.Fragment>
268
- <CubeIcon key="icon" /> 13
269
- </React.Fragment>
270
- ),
271
- props: { column: 'Workspaces' }
272
- },
273
- {
274
- title: '30 days ago',
275
- props: { column: 'Last commit' }
276
- },
277
- {
278
- title: (
279
- <React.Fragment>
280
- <a href="#">Action link</a>
281
- </React.Fragment>
282
- ),
283
- props: { column: '' }
284
- }
285
- ]
286
- },
287
- {
288
- cells: [
289
- {
290
- title: (
291
- <React.Fragment>
292
- <div>Node 4</div>
293
- <a href="#">siemur/test-space</a>
294
- </React.Fragment>
295
- ),
296
- props: { column: 'Repositories' }
297
- },
298
- {
299
- title: (
300
- <React.Fragment>
301
- <CodeBranchIcon key="icon" /> 3
302
- </React.Fragment>
303
- ),
304
- props: { column: 'Branches' }
305
- },
306
- {
307
- title: (
308
- <React.Fragment>
309
- <CodeIcon key="icon" /> 8
310
- </React.Fragment>
311
- ),
312
- props: { column: 'Pull requests' }
313
- },
314
- {
315
- title: (
316
- <React.Fragment>
317
- <CubeIcon key="icon" /> 20
318
- </React.Fragment>
319
- ),
320
- props: { column: 'Workspaces' }
321
- },
322
- {
323
- title: '8 days ago',
324
- props: { column: 'Last commit' }
325
- },
326
- {
327
- title: (
328
- <React.Fragment>
329
- <a href="#">Action link</a>
330
- </React.Fragment>
331
- ),
332
- props: { column: '' }
333
- }
334
- ]
335
- },
336
- {
337
- cells: [
338
- {
339
- title: (
340
- <React.Fragment>
341
- <div>Node 5</div>
342
- <a href="#">siemur/test-space</a>
343
- </React.Fragment>
344
- ),
345
- props: { column: 'Repositories' }
346
- },
347
- {
348
- title: (
349
- <React.Fragment>
350
- <CodeBranchIcon key="icon" /> 34
351
- </React.Fragment>
352
- ),
353
- props: { column: 'Branches' }
354
- },
355
- {
356
- title: (
357
- <React.Fragment>
358
- <CodeIcon key="icon" /> 21
359
- </React.Fragment>
360
- ),
361
- props: { column: 'Pull requests' }
362
- },
363
- {
364
- title: (
365
- <React.Fragment>
366
- <CubeIcon key="icon" /> 26
367
- </React.Fragment>
368
- ),
369
- props: { column: 'Workspaces' }
370
- },
371
- {
372
- title: '2 days ago',
373
- props: { column: 'Last commit' }
374
- },
375
- {
376
- title: (
377
- <React.Fragment>
378
- <a href="#">Action link</a>
379
- </React.Fragment>
380
- ),
381
- props: { column: '' }
382
- }
383
- ]
384
- }
385
- ];
386
- this.state = {
387
- filters: [],
388
- filteredColumns: [],
389
- columns: this.defaultColumns,
390
- rows: this.defaultRows,
391
- canSelectAll: true,
392
- isModalOpen: false,
393
- check1: true,
394
- check2: true,
395
- check3: true,
396
- check4: true,
397
- check5: true,
398
- liveText: '',
399
- id: '',
400
- itemOrder: ['data1', 'data2', 'data3', 'data4', 'data5']
401
- };
402
- this.onSelect = this.onSelect.bind(this);
403
- this.toggleSelect = this.toggleSelect.bind(this);
404
- this.renderModal = this.renderModal.bind(this);
405
- this.matchCheckboxNameToColumn = (name) => {
406
- switch (name) {
407
- case 'check1':
408
- return 'Repositories';
409
- case 'check2':
410
- return 'Branches';
411
- case 'check3':
412
- return 'Pull requests';
413
- case 'check4':
414
- return 'Workspaces';
415
- case 'check5':
416
- return 'Last commit';
417
- }
418
- };
419
- this.matchDataListNameToColumn = (name) => {
420
- switch (name) {
421
- case 'data1':
422
- return 'Repositories';
423
- case 'data2':
424
- return 'Branches';
425
- case 'data3':
426
- return 'Pull requests';
427
- case 'data4':
428
- return 'Workspaces';
429
- case 'data5':
430
- return 'Last commit';
431
- }
432
- };
433
- this.filterData = (checked, name) => {
434
- const { rows, columns, filters } = this.state;
435
- if (checked) {
436
- const updatedFilters = filters.filter((item) => item !== name);
437
- const filteredColumns = this.defaultColumns.filter((column) => !updatedFilters.includes(column));
438
- this.setState({
439
- filters: updatedFilters,
440
- filteredColumns: filteredColumns
441
- });
442
- } else {
443
- let updatedFilters = filters;
444
- updatedFilters.push(name);
445
- const filteredColumns = columns.filter((column) => !filters.includes(column));
446
- this.setState({
447
- filters: updatedFilters,
448
- filteredColumns: filteredColumns
449
- });
450
- }
451
- };
452
- this.unfilterAllData = () => {
453
- this.setState({
454
- filters: [],
455
- filteredColumns: this.defaultColumns
456
- });
457
- };
458
- this.handleChange = (event, checked) => {
459
- const target = event.target;
460
- const value = target.type === 'checkbox' ? target.checked : target.value;
461
- this.filterData(checked, this.matchCheckboxNameToColumn(target.name));
462
- this.setState({
463
- [target.name]: value
464
- });
465
- };
466
- this.handleModalToggle = (_event: KeyboardEvent | React.MouseEvent) => {
467
- this.setState(({ isModalOpen }) => ({
468
- isModalOpen: !isModalOpen
469
- }));
470
- };
471
- this.onSave = () => {
472
- const orderedColumns = this.state.itemOrder.map((item) => this.matchDataListNameToColumn(item));
473
- // concat empty string at the end for actions column
474
- const filteredOrderedColumns = orderedColumns
475
- .filter((col) => this.state.filteredColumns.length === 0 || this.state.filteredColumns.indexOf(col) > -1)
476
- .concat(['']);
477
- const orderedRows = [];
478
- this.defaultRows.forEach((row) => {
479
- const updatedCells = row.cells
480
- .filter((cell) => filteredOrderedColumns.indexOf(cell.props.column) > -1)
481
- .sort((cellA, cellB) => {
482
- const indexA = filteredOrderedColumns.indexOf(cellA.props.column);
483
- const indexB = filteredOrderedColumns.indexOf(cellB.props.column);
484
- if (indexA < indexB) {
485
- return -1;
486
- }
487
- if (indexA > indexB) {
488
- return 1;
489
- }
490
- // a must be equal to b
491
- return 0;
492
- });
493
- orderedRows.push({
494
- cells: updatedCells
495
- });
496
- });
497
- this.setState(({ isModalOpen }) => ({
498
- columns: filteredOrderedColumns,
499
- rows: orderedRows,
500
- isModalOpen: !isModalOpen
501
- }));
502
- };
503
-
504
- this.selectAllColumns = () => {
505
- this.unfilterAllData();
506
- this.setState({
507
- check1: true,
508
- check2: true,
509
- check3: true,
510
- check4: true,
511
- check5: true
512
- });
513
- };
514
-
515
- this.onDragStart = (id) => {
516
- this.setState({
517
- id: id,
518
- liveText: `Dragging started for item id: ${id}.`
519
- });
520
- };
521
-
522
- this.onDragMove = (oldIndex, newIndex) => {
523
- const { id } = this.state;
524
- this.setState({
525
- liveText: `Dragging item ${id}.`
526
- });
527
- };
528
-
529
- this.onDragCancel = () => {
530
- this.setState({
531
- liveText: `Dragging cancelled. List is unchanged.`
532
- });
533
- };
534
-
535
- this.onDragFinish = (itemOrder) => {
536
- this.setState({
537
- liveText: `Dragging finished`,
538
- itemOrder
539
- });
540
- };
541
- }
542
-
543
- onSelect(event, isSelected, rowId) {
544
- let rows;
545
- if (rowId === -1) {
546
- rows = this.state.rows.map((oneRow) => {
547
- oneRow.selected = isSelected;
548
- return oneRow;
549
- });
550
- } else {
551
- rows = [...this.state.rows];
552
- rows[rowId] = { ...rows[rowId], selected: isSelected };
553
- }
554
- this.setState({
555
- rows
556
- });
557
- }
558
-
559
- toggleSelect(checked) {
560
- this.setState({
561
- canSelectAll: checked
562
- });
563
- }
564
-
565
- renderModal() {
566
- const { isModalOpen } = this.state;
567
- return (
568
- <Modal
569
- title="Manage columns"
570
- isOpen={isModalOpen}
571
- variant="small"
572
- description={
573
- <TextContent>
574
- <Text component={TextVariants.p}>Selected categories will be displayed in the table.</Text>
575
- <Button isInline onClick={this.selectAllColumns} variant="link">
576
- Select all
577
- </Button>
578
- </TextContent>
579
- }
580
- onClose={this.handleModalToggle}
581
- actions={[
582
- <Button key="save" variant="primary" onClick={this.onSave}>
583
- Save
584
- </Button>,
585
- <Button key="cancel" variant="secondary" onClick={this.handleModalToggle}>
586
- Cancel
587
- </Button>
588
- ]}
589
- >
590
- <DataList
591
- aria-label="Table column management"
592
- id="table-column-management"
593
- isCompact
594
- onDragFinish={this.onDragFinish}
595
- onDragStart={this.onDragStart}
596
- onDragMove={this.onDragMove}
597
- onDragCancel={this.onDragCancel}
598
- itemOrder={this.state.itemOrder}
599
- >
600
- <DataListItem aria-labelledby="table-column-management-item1" id="data1">
601
- <DataListItemRow>
602
- <DataListControl>
603
- <DataListDragButton
604
- aria-label="Reorder"
605
- aria-labelledby="table-column-management-item1"
606
- aria-describedby="Press space or enter to begin dragging, and use the arrow keys to navigate up or down. Press enter to confirm the drag, or any other key to cancel the drag operation."
607
- aria-pressed="false"
608
- />
609
- <DataListCheck
610
- aria-labelledby="table-column-management-item1"
611
- checked={this.state.check1}
612
- name="check1"
613
- id="check1"
614
- onChange={this.handleChange}
615
- otherControls
616
- />
617
- </DataListControl>
618
- <DataListItemCells
619
- dataListCells={[
620
- <DataListCell id="table-column-management-item1" key="table-column-management-item1">
621
- <label htmlFor="check1">Repositories</label>
622
- </DataListCell>
623
- ]}
624
- />
625
- </DataListItemRow>
626
- </DataListItem>
627
- <DataListItem aria-labelledby="table-column-management-item2" id="data2">
628
- <DataListItemRow>
629
- <DataListControl>
630
- <DataListDragButton
631
- aria-label="Reorder"
632
- aria-labelledby="table-column-management-item2"
633
- aria-describedby="Press space or enter to begin dragging, and use the arrow keys to navigate up or down. Press enter to confirm the drag, or any other key to cancel the drag operation."
634
- aria-pressed="false"
635
- />
636
- <DataListCheck
637
- aria-labelledby="table-column-management-item2"
638
- checked={this.state.check2}
639
- name="check2"
640
- id="check2"
641
- onChange={this.handleChange}
642
- otherControls
643
- />
644
- </DataListControl>
645
- <DataListItemCells
646
- dataListCells={[
647
- <DataListCell id="table-column-management-item2" key="table-column-management-item2">
648
- <label htmlFor="check2">Branches</label>
649
- </DataListCell>
650
- ]}
651
- />
652
- </DataListItemRow>
653
- </DataListItem>
654
- <DataListItem aria-labelledby="table-column-management-item3" id="data3">
655
- <DataListItemRow>
656
- <DataListControl>
657
- <DataListDragButton
658
- aria-label="Reorder"
659
- aria-labelledby="table-column-management-item3"
660
- aria-describedby="Press space or enter to begin dragging, and use the arrow keys to navigate up or down. Press enter to confirm the drag, or any other key to cancel the drag operation."
661
- aria-pressed="false"
662
- />
663
- <DataListCheck
664
- aria-labelledby="table-column-management-item3"
665
- checked={this.state.check3}
666
- name="check3"
667
- id="check3"
668
- onChange={this.handleChange}
669
- otherControls
670
- />
671
- </DataListControl>
672
- <DataListItemCells
673
- dataListCells={[
674
- <DataListCell id="table-column-management-item3" key="table-column-management-item3">
675
- <label htmlFor="check3">Pull requests</label>
676
- </DataListCell>
677
- ]}
678
- />
679
- </DataListItemRow>
680
- </DataListItem>
681
- <DataListItem aria-labelledby="table-column-management-item4" id="data4">
682
- <DataListItemRow>
683
- <DataListControl>
684
- <DataListDragButton
685
- aria-label="Reorder"
686
- aria-labelledby="table-column-management-item4"
687
- aria-describedby="Press space or enter to begin dragging, and use the arrow keys to navigate up or down. Press enter to confirm the drag, or any other key to cancel the drag operation."
688
- aria-pressed="false"
689
- />
690
- <DataListCheck
691
- aria-labelledby="table-column-management-item4"
692
- checked={this.state.check4}
693
- name="check4"
694
- id="check4"
695
- onChange={this.handleChange}
696
- otherControls
697
- />
698
- </DataListControl>
699
- <DataListItemCells
700
- dataListCells={[
701
- <DataListCell id="table-column-management-item4" key="table-column-management-item4">
702
- <label htmlFor="check4">Workspaces</label>
703
- </DataListCell>
704
- ]}
705
- />
706
- </DataListItemRow>
707
- </DataListItem>
708
- <DataListItem aria-labelledby="table-column-management-item5" id="data5">
709
- <DataListItemRow>
710
- <DataListControl>
711
- <DataListDragButton
712
- aria-label="Reorder"
713
- aria-labelledby="table-column-management-item5"
714
- aria-describedby="Press space or enter to begin dragging, and use the arrow keys to navigate up or down. Press enter to confirm the drag, or any other key to cancel the drag operation."
715
- aria-pressed="false"
716
- />
717
- <DataListCheck
718
- aria-labelledby="table-column-management-item5"
719
- checked={this.state.check5}
720
- name="check5"
721
- id="check5"
722
- onChange={this.handleChange}
723
- otherControls
724
- />
725
- </DataListControl>
726
- <DataListItemCells
727
- dataListCells={[
728
- <DataListCell id="table-column-management-item5" key="table-column-management-item5">
729
- <label htmlFor="check5">Last commit</label>
730
- </DataListCell>
731
- ]}
732
- />
733
- </DataListItemRow>
734
- </DataListItem>
735
- </DataList>
736
- </Modal>
737
- );
738
- }
739
-
740
- render() {
741
- const { canSelectAll, columns, rows } = this.state;
742
-
743
- const toolbarItems = (
744
- <React.Fragment>
745
- <span id="page-layout-table-draggable-column-management-action-toolbar-top-select-checkbox-label" hidden>
746
- Choose one
747
- </span>
748
- <ToolbarContent>
749
- <ToolbarItem variant="overflow-menu">
750
- <OverflowMenu breakpoint="md">
751
- <OverflowMenuItem isPersistent>
752
- <MenuToggle>
753
- <FilterIcon /> Name
754
- </MenuToggle>
755
- </OverflowMenuItem>
756
- <OverflowMenuItem>
757
- <MenuToggle variant="plain" aria-label="Sort columns">
758
- <SortAmountDownIcon aria-hidden="true" />
759
- </MenuToggle>
760
- </OverflowMenuItem>
761
- <OverflowMenuGroup groupType="button" isPersistent>
762
- <OverflowMenuItem>
763
- <Button variant="primary">Action</Button>
764
- </OverflowMenuItem>
765
- <OverflowMenuItem>
766
- <Button variant="link" onClick={this.handleModalToggle}>
767
- Manage columns
768
- </Button>
769
- </OverflowMenuItem>
770
- </OverflowMenuGroup>
771
- </OverflowMenu>
772
- </ToolbarItem>
773
- <ToolbarItem variant="pagination">
774
- <Pagination
775
- itemCount={37}
776
- widgetId="pagination-options-menu"
777
- page={1}
778
- variant={PaginationVariant.top}
779
- isCompact
780
- titles={{
781
- paginationAriaLabel: `Draggable column management top pagination`
782
- }}
783
- />
784
- </ToolbarItem>
785
- </ToolbarContent>
786
- </React.Fragment>
787
- );
788
-
789
- return (
790
- <React.Fragment>
791
- <TableDeprecated
792
- gridBreakPoint="grid-xl"
793
- header={
794
- <React.Fragment>
795
- <Toolbar id="page-layout-table-draggable-column-management-action-toolbar-top">{toolbarItems}</Toolbar>
796
- </React.Fragment>
797
- }
798
- aria-label="This is a table with checkboxes"
799
- id="page-layout-table-draggable-column-management-action-table"
800
- onSelect={this.onSelect}
801
- cells={columns}
802
- rows={rows}
803
- actions={this.actions}
804
- canSelectAll={canSelectAll}
805
- >
806
- <TableHeader />
807
- <TableBody />
808
- </TableDeprecated>
809
- <Pagination
810
- isCompact
811
- id="page-layout-table-draggable-column-management-action-toolbar-bottom"
812
- itemCount={37}
813
- widgetId="pagination-options-menu-bottom"
814
- page={1}
815
- variant={PaginationVariant.bottom}
816
- titles={{
817
- paginationAriaLabel: `Draggable column management bottom pagination`
818
- }}
819
- />
820
- {this.renderModal()}
821
- </React.Fragment>
822
- );
823
- }
824
- }
825
- ```
826
-
827
- ### Filterable
828
-
829
- ```js isFullscreen
830
- import React from 'react';
831
- import {
832
- Badge,
833
- Button,
834
- Bullseye,
835
- EmptyState,
836
- EmptyStateActions,
837
- EmptyStateBody,
838
- EmptyStateIcon,
839
- EmptyStateHeader,
840
- EmptyStateFooter,
841
- Label,
842
- MenuToggle,
843
- MenuToggleElement,
844
- Toolbar,
845
- ToolbarItem,
846
- ToolbarContent,
847
- ToolbarFilter,
848
- ToolbarToggleGroup,
849
- ToolbarGroup,
850
- Title,
851
- Select,
852
- SelectOption,
853
- SearchInput
854
- } from '@patternfly/react-core';
855
- import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
856
- import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
857
- import { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
858
- import { rows, columns } from '@patternfly/react-table/src/docs/demos/table-demos/sampleData';
859
-
860
- class FilterTableDemo extends React.Component {
861
- constructor(props) {
862
- super(props);
863
- this.state = {
864
- filters: {
865
- location: [],
866
- name: [],
867
- status: []
868
- },
869
- currentCategory: 'Status',
870
- isFilterDropdownOpen: false,
871
- isCategoryDropdownOpen: false,
872
- nameInput: '',
873
- inputValue: '',
874
- rows: rows.slice(0, 10)
875
- };
876
-
877
- this.onDelete = (type = '', id = '') => {
878
- if (type) {
879
- this.setState((prevState) => {
880
- prevState.filters[type.toLowerCase()] = prevState.filters[type.toLowerCase()].filter((s) => s !== id);
881
- return {
882
- filters: prevState.filters
883
- };
884
- });
885
- } else {
886
- this.setState({
887
- filters: {
888
- location: [],
889
- name: [],
890
- status: []
891
- }
892
- });
893
- }
894
- };
895
-
896
- this.onCategoryToggle = () => {
897
- this.setState({
898
- isCategoryDropdownOpen: !this.state.isCategoryDropdownOpen
899
- });
900
- };
901
-
902
- this.onCategorySelect = (event) => {
903
- this.setState({
904
- currentCategory: event.target.innerText,
905
- isCategoryDropdownOpen: false
906
- });
907
- };
908
-
909
- this.onFilterToggle = () => {
910
- this.setState({
911
- isFilterDropdownOpen: !this.state.isFilterDropdownOpen
912
- });
913
- };
914
-
915
- this.onFilterSelect = (event) => {
916
- this.setState({
917
- isFilterDropdownOpen: !this.state.isFilterDropdownOpen
918
- });
919
- };
920
-
921
- this.onInputChange = (newValue) => {
922
- this.setState({ inputValue: newValue });
923
- };
924
-
925
- this.onStatusSelect = (event, selection) => {
926
- const checked = event.target.checked;
927
- this.setState((prevState) => {
928
- const prevSelections = prevState.filters['status'];
929
- return {
930
- filters: {
931
- ...prevState.filters,
932
- status: checked ? [...prevSelections, selection] : prevSelections.filter((value) => value !== selection)
933
- },
934
- isFilterDropdownOpen: false
935
- };
936
- });
937
- };
938
-
939
- this.onNameInput = (event) => {
940
- if (event.key && event.key !== 'Enter') {
941
- return;
942
- }
943
-
944
- const { inputValue } = this.state;
945
- this.setState((prevState) => {
946
- const prevFilters = prevState.filters['name'];
947
- return {
948
- filters: {
949
- ...prevState.filters,
950
- ['name']: prevFilters.includes(inputValue) ? prevFilters : [...prevFilters, inputValue]
951
- },
952
- inputValue: ''
953
- };
954
- });
955
- };
956
-
957
- this.onLocationSelect = (event, selection) => {
958
- this.setState((prevState) => {
959
- return {
960
- filters: {
961
- ...prevState.filters,
962
- ['location']: [selection]
963
- },
964
- isFilterDropdownOpen: false
965
- };
966
- });
967
- this.onFilterSelect();
968
- };
969
- }
970
-
971
- buildCategoryDropdown() {
972
- const { isCategoryDropdownOpen, currentCategory } = this.state;
973
-
974
- const categoryMenuItems = [
975
- <SelectOption key="cat1" value="Location">Location</SelectOption>,
976
- <SelectOption key="cat2" value="Name">Name</SelectOption>,
977
- <SelectOption key="cat3" value="Status">Status</SelectOption>
978
- ];
979
-
980
- return (
981
- <ToolbarItem>
982
- <Select
983
- onSelect={this.onCategorySelect}
984
- selected={currentCategory}
985
- toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
986
- <MenuToggle
987
- ref={toggleRef}
988
- onClick={this.onCategoryToggle}
989
- isExpanded={isCategoryDropdownOpen}
990
- icon={<FilterIcon />}
991
- style={
992
- {
993
- width: '100%',
994
- verticalAlign: 'text-bottom'
995
- } as React.CSSProperties
996
- }
997
- >
998
- {currentCategory}
999
- </MenuToggle>
1000
- )}
1001
- isOpen={isCategoryDropdownOpen}
1002
- >
1003
- {categoryMenuItems}
1004
- </Select>
1005
- </ToolbarItem>
1006
- );
1007
- }
1008
-
1009
- buildFilterDropdown() {
1010
- const { currentCategory, isFilterDropdownOpen, inputValue, filters } = this.state;
1011
-
1012
- const locationMenuItems = [
1013
- <SelectOption key="raleigh" value="Raleigh">Raleigh</SelectOption>,
1014
- <SelectOption key="san francisco" value="San Francisco">San Francisco</SelectOption>,
1015
- <SelectOption key="boston" value="Boston">Boston</SelectOption>,
1016
- <SelectOption key="atlanta" value="Atlanta">Atlanta</SelectOption>,
1017
- ];
1018
-
1019
- const statusMenuItems = [
1020
- <SelectOption
1021
- hasCheckbox
1022
- key="statusRunning"
1023
- value="Running"
1024
- isSelected={filters.status.includes("Running")}
1025
- >
1026
- Running
1027
- </SelectOption>,
1028
- <SelectOption
1029
- hasCheckbox
1030
- key="statusStopped"
1031
- value="Stopped"
1032
- isSelected={filters.status.includes("Stopped")}
1033
- >
1034
- Stopped
1035
- </SelectOption>,
1036
- <SelectOption
1037
- hasCheckbox
1038
- key="statusDown"
1039
- value="Down"
1040
- isSelected={filters.status.includes("Down")}
1041
- >
1042
- Down
1043
- </SelectOption>,
1044
- <SelectOption
1045
- hasCheckbox
1046
- key="statusDegraded"
1047
- value="Degraded"
1048
- isSelected={filters.status.includes("Degraded")}
1049
- >
1050
- Degraded
1051
- </SelectOption>,
1052
- <SelectOption
1053
- hasCheckbox
1054
- key="statusMaint"
1055
- value="Needs maintenance"
1056
- isSelected={filters.status.includes("Needs maintenance")}
1057
- >
1058
- Needs maintenance
1059
- </SelectOption>
1060
- ];
1061
-
1062
- return (
1063
- <React.Fragment>
1064
- <ToolbarFilter
1065
- chips={filters.location}
1066
- deleteChip={this.onDelete}
1067
- categoryName="Location"
1068
- showToolbarItem={currentCategory === 'Location'}
1069
- >
1070
- <Select
1071
- aria-label="Location"
1072
- onSelect={this.onLocationSelect}
1073
- selected={filters.location[0]}
1074
- isOpen={isFilterDropdownOpen}
1075
- minWidth="100px"
1076
- toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
1077
- <MenuToggle
1078
- ref={toggleRef}
1079
- onClick={this.onFilterToggle}
1080
- isExpanded={isFilterDropdownOpen}
1081
- style={
1082
- {
1083
- width: '100%',
1084
- verticalAlign: 'text-bottom'
1085
- } as React.CSSProperties
1086
- }
1087
- >
1088
- {filters.location[0] || `Any`}
1089
- </MenuToggle>
1090
- )}
1091
- >
1092
- {locationMenuItems}
1093
- </Select>
1094
- </ToolbarFilter>
1095
- <ToolbarFilter
1096
- chips={filters.name}
1097
- deleteChip={this.onDelete}
1098
- categoryName="Name"
1099
- showToolbarItem={currentCategory === 'Name'}
1100
- >
1101
- <SearchInput
1102
- aria-label="name filter"
1103
- placeholder="Filter by name..."
1104
- onChange={(_event, value) => this.onInputChange(value)}
1105
- value={inputValue}
1106
- onClear={() => {
1107
- this.onInputChange('');
1108
- }}
1109
- onSearch={this.onNameInput}
1110
- />
1111
- </ToolbarFilter>
1112
- <ToolbarFilter
1113
- chips={filters.status}
1114
- deleteChip={this.onDelete}
1115
- categoryName="Status"
1116
- showToolbarItem={currentCategory === 'Status'}
1117
- >
1118
- <Select
1119
- aria-label="Status"
1120
- isOpen={isFilterDropdownOpen}
1121
- minWidth="100px"
1122
- onSelect={this.onStatusSelect}
1123
- selected={filters.status}
1124
- toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
1125
- <MenuToggle
1126
- ref={toggleRef}
1127
- onClick={this.onFilterToggle}
1128
- isExpanded={isFilterDropdownOpen}
1129
- style={
1130
- {
1131
- width: '100%',
1132
- verticalAlign: 'text-bottom'
1133
- } as React.CSSProperties
1134
- }
1135
- >
1136
- Filter by status
1137
- {filters.status.length > 0 && <Badge isRead>{filters.status.length}</Badge>}
1138
- </MenuToggle>
1139
- )}
1140
- >
1141
- {statusMenuItems}
1142
- </Select>
1143
- </ToolbarFilter>
1144
- </React.Fragment>
1145
- );
1146
- }
1147
-
1148
- renderToolbar() {
1149
- return (
1150
- <Toolbar id="toolbar-with-chip-groups" clearAllFilters={this.onDelete} collapseListedFiltersBreakpoint="xl">
1151
- <ToolbarContent>
1152
- <ToolbarToggleGroup toggleIcon={<FilterIcon />} breakpoint="xl">
1153
- <ToolbarGroup
1154
- variant="filter-group"
1155
- style={{
1156
- lineHeight: '22px',
1157
- alignItems: 'center'
1158
- } as React.CSSProperties}
1159
- >
1160
- {this.buildCategoryDropdown()}
1161
- {this.buildFilterDropdown()}
1162
- </ToolbarGroup>
1163
- </ToolbarToggleGroup>
1164
- </ToolbarContent>
1165
- </Toolbar>
1166
- );
1167
- }
1168
-
1169
- render() {
1170
- const { loading, filters, rows } = this.state;
1171
-
1172
- const filteredRows =
1173
- filters.name.length > 0 || filters.location.length > 0 || filters.status.length > 0
1174
- ? rows.filter((row) => {
1175
- return (
1176
- (filters.name.length === 0 ||
1177
- filters.name.some((name) => row.name.toLowerCase().includes(name.toLowerCase()))) &&
1178
- (filters.location.length === 0 || filters.location.includes(row.location)) &&
1179
- (filters.status.length === 0 || filters.status.includes(row.status))
1180
- );
1181
- })
1182
- : rows;
1183
-
1184
- let tableRows = filteredRows;
1185
- if (!loading && filteredRows.length === 0) {
1186
- tableRows = [
1187
- {
1188
- heightAuto: true,
1189
- cells: [
1190
- {
1191
- props: { colSpan: 8 },
1192
- title: (
1193
- <Bullseye>
1194
- <EmptyState>
1195
- <EmptyStateHeader
1196
- titleText="Clear all filters and try again."
1197
- headingLevel="h5"
1198
- icon={<EmptyStateIcon icon={SearchIcon} />}
1199
- />
1200
- <EmptyStateBody>
1201
- No results match this filter criteria. Remove all filters or clear all filters to show results.
1202
- </EmptyStateBody>
1203
- <EmptyStateFooter>
1204
- <EmptyStateActions>
1205
- <Button
1206
- variant="link"
1207
- onClick={() => {
1208
- this.onDelete(null);
1209
- }}
1210
- >
1211
- Clear all filters
1212
- </Button>
1213
- </EmptyStateActions>
1214
- </EmptyStateFooter>
1215
- </EmptyState>
1216
- </Bullseye>
1217
- )
1218
- }
1219
- ]
1220
- }
1221
- ];
1222
- } else if (loading) {
1223
- tableRows = [
1224
- {
1225
- heightAuto: true,
1226
- cells: [
1227
- {
1228
- props: { colSpan: 8 },
1229
- title: (
1230
- <Title headingLevel="h2" size="3xl">
1231
- Please wait while loading data
1232
- </Title>
1233
- )
1234
- }
1235
- ]
1236
- }
1237
- ];
1238
- }
1239
-
1240
- const renderLabel = labelText => {
1241
- switch (labelText) {
1242
- case 'Running':
1243
- return <Label color="green">{labelText}</Label>;
1244
- case 'Stopped':
1245
- return <Label color="orange">{labelText}</Label>;
1246
- case 'Needs maintenance':
1247
- return <Label color="blue">{labelText}</Label>;
1248
- case 'Down':
1249
- return <Label color="red">{labelText}</Label>;
1250
- }
1251
- };
1252
-
1253
- return (
1254
- <React.Fragment>
1255
- {this.renderToolbar()}
1256
- <Table aria-label="Filterable Table Demo">
1257
- <Thead>
1258
- <Tr>
1259
- <Th key={0}>{columns[0]}</Th>
1260
- <Th key={1}>{columns[1]}</Th>
1261
- <Th key={2}>{columns[2]}</Th>
1262
- <Th key={3}>{columns[3]}</Th>
1263
- <Th key={4}>{columns[4]}</Th>
1264
- <Th key={5}>{columns[5]}</Th>
1265
- <Th key={6}>{columns[6]}</Th>
1266
- <Th key={7} width={10}>
1267
- {columns[7]}
1268
- </Th>
1269
- </Tr>
1270
- </Thead>
1271
- <Tbody>
1272
- {filteredRows.slice(0, 10).map((row, rowIndex) => (
1273
- <Tr key={rowIndex}>
1274
- <>
1275
- <Td dataLabel={columns[0]}>{row.name}</Td>
1276
- <Td dataLabel={columns[1]}>{row.threads}</Td>
1277
- <Td dataLabel={columns[2]}>{row.applications}</Td>
1278
- <Td dataLabel={columns[3]}>{row.workspaces}</Td>
1279
- <Td dataLabel={columns[4]}>{renderLabel(row.status)}</Td>
1280
- <Td dataLabel={columns[5]}>{row.location}</Td>
1281
- <Td dataLabel={columns[6]}>{row.lastModified}</Td>
1282
- <Td dataLabel={columns[7]} modifier="truncate">
1283
- <TableText>
1284
- <a href="#">{row.url}</a>
1285
- </TableText>
1286
- </Td>
1287
- </>
1288
- </Tr>
1289
- ))}
1290
- </Tbody>
1291
- </Table>
1292
- </React.Fragment>
1293
- );
1294
- }
1295
- }
1296
- ```
1297
-
1298
- ### Sortable - responsive
1299
-
1300
- ```js isFullscreen file="./table-demos/SortableResponsive.jsx"
1301
-
1302
- ```
1303
-
1304
- ### Automatic pagination
1305
-
1306
- The below example illustrates the `isLastFullPageShown` prop, which makes the following changes when the user sets the number of items to display per page to an amount that exceeds the remaining amount of data:
1307
-
1308
- - The component automatically changes the page back to the last full page of results, rather than defaulting to the final page of results.
1309
-
1310
- To demonstrate this, navigate to the last page of data below using the `>>` navigation arrows, then use the dropdown selector to change the view to 5 per page.
1311
-
1312
- - The default behavior would show the last page of results, which would only contain the last two rows (rows 11 - 12).
1313
- - The `isLastFullPageShown` prop navigates you back to the previous page which does contain a full page of 5 rows (rows 6 - 10).
1314
-
1315
- ```js isFullscreen
1316
- import React from 'react';
1317
- import { Pagination } from '@patternfly/react-core';
1318
- import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
1319
-
1320
- class ComplexPaginationTableDemo extends React.Component {
1321
- constructor(props) {
1322
- super(props);
1323
- (this.columns = {
1324
- firstColumn: 'First column',
1325
- secondColumn: 'Second column',
1326
- thirdColumn: 'Third column'
1327
- }),
1328
- (this.defaultRows = [
1329
- { firstColumn: 'Row 1 column 1', secondColumn: 'Row 1 column 2', thirdColumn: 'Row 1 column 3' },
1330
- { firstColumn: 'Row 2 column 1', secondColumn: 'Row 2 column 2', thirdColumn: 'Row 2 column 3' },
1331
- { firstColumn: 'Row 3 column 1', secondColumn: 'Row 3 column 2', thirdColumn: 'Row 3 column 3' },
1332
- { firstColumn: 'Row 4 column 1', secondColumn: 'Row 4 column 2', thirdColumn: 'Row 4 column 3' },
1333
- { firstColumn: 'Row 5 column 1', secondColumn: 'Row 5 column 2', thirdColumn: 'Row 5 column 3' },
1334
- { firstColumn: 'Row 6 column 1', secondColumn: 'Row 6 column 2', thirdColumn: 'Row 6 column 3' },
1335
- { firstColumn: 'Row 7 column 1', secondColumn: 'Row 7 column 2', thirdColumn: 'Row 7 column 3' },
1336
- { firstColumn: 'Row 8 column 1', secondColumn: 'Row 8 column 2', thirdColumn: 'Row 8 column 3' },
1337
- { firstColumn: 'Row 9 column 1', secondColumn: 'Row 9 column 2', thirdColumn: 'Row 9 column 3' },
1338
- { firstColumn: 'Row 10 column 1', secondColumn: 'Row 10 column 2', thirdColumn: 'Row 10 column 3' },
1339
- { firstColumn: 'Row 11 column 1', secondColumn: 'Row 11 column 2', thirdColumn: 'Row 11 column 3' },
1340
- { firstColumn: 'Row 12 column 1', secondColumn: 'Row 12 column 2', thirdColumn: 'Row 12 column 3' }
1341
- ]);
1342
- this.defaultPerPage = 10;
1343
- this.state = {
1344
- perPage: this.defaultPerPage,
1345
- page: 1,
1346
- rows: this.defaultRows.slice(0, this.defaultPerPage)
1347
- };
1348
- this.handleSetPage = this.handleSetPage.bind(this);
1349
- this.handlePerPageSelect = this.handlePerPageSelect.bind(this);
1350
- }
1351
-
1352
- handleSetPage(_evt, newPage, perPage, startIdx, endIdx) {
1353
- this.setState({
1354
- page: newPage,
1355
- rows: this.defaultRows.slice(startIdx, endIdx)
1356
- });
1357
- }
1358
-
1359
- handlePerPageSelect(_evt, newPerPage, newPage, startIdx, endIdx) {
1360
- this.setState({
1361
- perPage: newPerPage,
1362
- page: newPage,
1363
- rows: this.defaultRows.slice(startIdx, endIdx)
1364
- });
1365
- }
1366
-
1367
- renderPagination(variant = 'top') {
1368
- const { page, perPage } = this.state;
1369
- return (
1370
- <Pagination
1371
- isCompact
1372
- itemCount={this.defaultRows.length}
1373
- page={page}
1374
- perPage={perPage}
1375
- isLastFullPageShown
1376
- onSetPage={this.handleSetPage}
1377
- onPerPageSelect={this.handlePerPageSelect}
1378
- perPageOptions={[
1379
- { title: '3', value: 3 },
1380
- { title: '5', value: 5 },
1381
- { title: '12', value: 12 },
1382
- { title: '20', value: 20 }
1383
- ]}
1384
- titles={{
1385
- paginationAriaLabel: `${variant} pagination`
1386
- }}
1387
- />
1388
- );
1389
- }
1390
-
1391
- render() {
1392
- return (
1393
- <React.Fragment>
1394
- {this.renderPagination()}
1395
- <Table aria-label="Automated Pagination Table Demo">
1396
- <Thead>
1397
- <Tr>
1398
- <Th>{this.columns.firstColumn}</Th>
1399
- <Th>{this.columns.secondColumn}</Th>
1400
- <Th>{this.columns.thirdColumn}</Th>
1401
- </Tr>
1402
- </Thead>
1403
- <Tbody>
1404
- {this.state.rows.map((row, rowIndex) => (
1405
- <Tr key={rowIndex}>
1406
- <>
1407
- <Td dataLabel={this.columns.firstColumn}>{row.firstColumn}</Td>
1408
- <Td dataLabel={this.columns.secondColumn}>{row.secondColumn}</Td>
1409
- <Td dataLabel={this.columns.thirdColumn}>{row.thirdColumn}</Td>
1410
- </>
1411
- </Tr>
1412
- ))}
1413
- </Tbody>
1414
- </Table>
1415
- </React.Fragment>
1416
- );
1417
- }
1418
- }
1419
- ```
1420
-
1421
- ### Static bottom pagination on mobile
1422
-
1423
- ```js isFullscreen file="table-demos/StaticBottomPagination.jsx"
1424
-
1425
- ```
1426
-
1427
- ### Sticky header
1428
-
1429
- ```js isFullscreen file="./table-demos/StickyHeader.jsx"
1430
-
1431
- ```
1432
-
1433
- ### Sticky first column
1434
-
1435
- ```js isFullscreen file="./table-demos/StickyFirstColumn.jsx"
1436
-
1437
- ```
1438
-
1439
- ### Sticky columns and header with toolbar
1440
-
1441
- A toolbar may be added above a sticky table either inside or outside the `OuterScrollContainer`.
1442
-
1443
- ```ts isFullscreen file="../../components/Table/examples/TableStickyColumnsAndHeader.tsx"
1444
-
1445
- ```
1446
-
1447
- ## Empty states
1448
-
1449
- These examples demonstrate the use of an [Empty State component](/components/empty-state) inside of a [Table](/components/table). Empty states are useful in a table when a filter returns no results, while data is loading, or when any type of error or exception condition occurs.
1450
-
1451
- ### Empty
1452
-
1453
- ```js isFullscreen
1454
- import React from 'react';
1455
- import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
1456
- import {
1457
- Bullseye,
1458
- Button,
1459
- Card,
1460
- EmptyState,
1461
- EmptyStateVariant,
1462
- EmptyStateIcon,
1463
- EmptyStateBody,
1464
- EmptyStateHeader,
1465
- EmptyStateFooter,
1466
- EmptyStateActions,
1467
- PageSection
1468
- } from '@patternfly/react-core';
1469
- import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
1470
- import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper';
1471
-
1472
- export const TableEmptyState: React.FunctionComponent = () => (
1473
- <DashboardWrapper hasPageTemplateTitle>
1474
- <PageSection padding={{ default: 'noPadding', xl: 'padding' }}>
1475
- <Card component="div">
1476
- <Table aria-label="Empty state table">
1477
- <Thead>
1478
- <Tr>
1479
- <Th>Repositories</Th>
1480
- <Th>Branches</Th>
1481
- <Th>Pull requests</Th>
1482
- <Th>Workspaces</Th>
1483
- <Th>Last commit</Th>
1484
- </Tr>
1485
- </Thead>
1486
- <Tbody>
1487
- <Tr>
1488
- <Td colSpan={8}>
1489
- <Bullseye>
1490
- <EmptyState variant={EmptyStateVariant.sm}>
1491
- <EmptyStateHeader
1492
- icon={<EmptyStateIcon icon={SearchIcon} />}
1493
- titleText="No results found"
1494
- headingLevel="h2"
1495
- />
1496
- <EmptyStateBody>
1497
- No results match this filter criteria. Clear all filters and try again.
1498
- </EmptyStateBody>
1499
- <EmptyStateFooter>
1500
- <EmptyStateActions>
1501
- <Button variant="link">Clear all filters</Button>
1502
- </EmptyStateActions>
1503
- </EmptyStateFooter>
1504
- </EmptyState>
1505
- </Bullseye>
1506
- </Td>
1507
- </Tr>
1508
- </Tbody>
1509
- </Table>
1510
- </Card>
1511
- </PageSection>
1512
- </DashboardWrapper>
1513
- );
1514
- ```
1515
-
1516
- ### Loading
1517
-
1518
- ```js isFullscreen
1519
- import React from 'react';
1520
- import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
1521
- import {
1522
- Bullseye,
1523
- Card,
1524
- EmptyState,
1525
- EmptyStateIcon,
1526
- EmptyStateBody,
1527
- EmptyStateHeader,
1528
- PageSection,
1529
- Spinner
1530
- } from '@patternfly/react-core';
1531
- import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper';
1532
-
1533
- export const LoadingStateDemo: React.FunctionComponent = () => (
1534
- <DashboardWrapper hasPageTemplateTitle>
1535
- <PageSection padding={{ default: 'noPadding', xl: 'padding' }}>
1536
- <Card component="div">
1537
- <Table aria-label="Loading table demo">
1538
- <Thead>
1539
- <Tr>
1540
- <Th>Repositories</Th>
1541
- <Th>Branches</Th>
1542
- <Th>Pull requests</Th>
1543
- <Th>Workspaces</Th>
1544
- <Th>Last commit</Th>
1545
- </Tr>
1546
- </Thead>
1547
- <Tbody>
1548
- <Tr>
1549
- <Td colSpan={8}>
1550
- <Bullseye>
1551
- <EmptyState>
1552
- <EmptyStateHeader titleText="Loading" headingLevel="h2" icon={<EmptyStateIcon icon={Spinner} />} />
1553
- </EmptyState>
1554
- </Bullseye>
1555
- </Td>
1556
- </Tr>
1557
- </Tbody>
1558
- </Table>
1559
- </Card>
1560
- </PageSection>
1561
- </DashboardWrapper>
1562
- );
1563
- ```
1564
-
1565
- ### Error
1566
-
1567
- ```js isFullscreen
1568
- import React from 'react';
1569
- import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
1570
- import {
1571
- Bullseye,
1572
- Card,
1573
- EmptyState,
1574
- EmptyStateVariant,
1575
- EmptyStateIcon,
1576
- EmptyStateBody,
1577
- EmptyStateHeader,
1578
- PageSection
1579
- } from '@patternfly/react-core';
1580
- import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon';
1581
- import globalDangerColor200 from '@patternfly/react-tokens/dist/esm/global_danger_color_200';
1582
- import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper';
1583
-
1584
- export const ErrorStateDemo: React.FunctionComponent = () => (
1585
- <DashboardWrapper hasPageTemplateTitle>
1586
- <PageSection padding={{ default: 'noPadding', xl: 'padding' }}>
1587
- <Card component="div">
1588
- <Table aria-label="Loading table demo">
1589
- <Thead>
1590
- <Tr>
1591
- <Th>Repositories</Th>
1592
- <Th>Branches</Th>
1593
- <Th>Pull requests</Th>
1594
- <Th>Workspaces</Th>
1595
- <Th>Last commit</Th>
1596
- </Tr>
1597
- </Thead>
1598
- <Tbody>
1599
- <Tr>
1600
- <Td colSpan={8}>
1601
- <Bullseye>
1602
- <EmptyState variant={EmptyStateVariant.sm}>
1603
- <EmptyStateHeader
1604
- titleText="Unable to connect"
1605
- icon={<EmptyStateIcon icon={ExclamationCircleIcon} color={globalDangerColor200.value} />}
1606
- headingLevel="h2"
1607
- />
1608
- <EmptyStateBody>
1609
- There was an error retrieving data. Check your connection and reload the page.
1610
- </EmptyStateBody>
1611
- </EmptyState>
1612
- </Bullseye>
1613
- </Td>
1614
- </Tr>
1615
- </Tbody>
1616
- </Table>
1617
- </Card>
1618
- </PageSection>
1619
- </DashboardWrapper>
1620
- );
1621
- ```