@qoretechnologies/reqore 0.35.3 → 0.36.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 (198) hide show
  1. package/__tests__/collection.test.tsx +1 -22
  2. package/__tests__/table.test.tsx +1 -1
  3. package/__tests__/tree.test.tsx +0 -18
  4. package/dist/components/Breadcrumbs/index.js +1 -1
  5. package/dist/components/Breadcrumbs/index.js.map +1 -1
  6. package/dist/components/Button/index.d.ts +1 -4
  7. package/dist/components/Button/index.d.ts.map +1 -1
  8. package/dist/components/Button/index.js +11 -26
  9. package/dist/components/Button/index.js.map +1 -1
  10. package/dist/components/Collection/index.d.ts +2 -2
  11. package/dist/components/Collection/index.d.ts.map +1 -1
  12. package/dist/components/Collection/index.js +10 -10
  13. package/dist/components/Collection/index.js.map +1 -1
  14. package/dist/components/Collection/item.d.ts +3 -3
  15. package/dist/components/Collection/item.d.ts.map +1 -1
  16. package/dist/components/Collection/item.js.map +1 -1
  17. package/dist/components/Columns/index.d.ts +1 -1
  18. package/dist/components/Columns/index.d.ts.map +1 -1
  19. package/dist/components/Comment/index.d.ts +1 -1
  20. package/dist/components/Comment/index.d.ts.map +1 -1
  21. package/dist/components/CommentFeed/index.d.ts +1 -1
  22. package/dist/components/CommentFeed/index.d.ts.map +1 -1
  23. package/dist/components/ControlGroup/index.d.ts +1 -1
  24. package/dist/components/ControlGroup/index.d.ts.map +1 -1
  25. package/dist/components/Dropdown/index.d.ts +1 -1
  26. package/dist/components/Dropdown/index.d.ts.map +1 -1
  27. package/dist/components/Dropdown/item.d.ts +2 -2
  28. package/dist/components/Dropdown/item.d.ts.map +1 -1
  29. package/dist/components/Dropdown/list.d.ts +1 -1
  30. package/dist/components/Dropdown/list.d.ts.map +1 -1
  31. package/dist/components/Effect/index.d.ts +2 -2
  32. package/dist/components/Effect/index.d.ts.map +1 -1
  33. package/dist/components/ExportModal/index.d.ts +11 -0
  34. package/dist/components/ExportModal/index.d.ts.map +1 -0
  35. package/dist/components/ExportModal/index.js +91 -0
  36. package/dist/components/ExportModal/index.js.map +1 -0
  37. package/dist/components/Header/index.d.ts +7 -7
  38. package/dist/components/Header/index.d.ts.map +1 -1
  39. package/dist/components/InputClearButton/index.d.ts +1 -0
  40. package/dist/components/InputClearButton/index.d.ts.map +1 -1
  41. package/dist/components/KeyValueTable/index.d.ts +27 -0
  42. package/dist/components/KeyValueTable/index.d.ts.map +1 -0
  43. package/dist/components/KeyValueTable/index.js +87 -0
  44. package/dist/components/KeyValueTable/index.js.map +1 -0
  45. package/dist/components/Layout/content.d.ts +1 -1
  46. package/dist/components/Layout/content.d.ts.map +1 -1
  47. package/dist/components/Layout/index.d.ts +1 -1
  48. package/dist/components/Layout/index.d.ts.map +1 -1
  49. package/dist/components/Menu/item.d.ts +1 -1
  50. package/dist/components/Menu/item.d.ts.map +1 -1
  51. package/dist/components/Menu/item.js +3 -3
  52. package/dist/components/Menu/item.js.map +1 -1
  53. package/dist/components/Modal/index.d.ts +1 -1
  54. package/dist/components/Modal/index.d.ts.map +1 -1
  55. package/dist/components/MultiSelect/index.d.ts +2 -2
  56. package/dist/components/MultiSelect/index.d.ts.map +1 -1
  57. package/dist/components/Notifications/notification.js +3 -3
  58. package/dist/components/Notifications/notification.js.map +1 -1
  59. package/dist/components/Paging/index.d.ts +1 -1
  60. package/dist/components/Paging/index.d.ts.map +1 -1
  61. package/dist/components/Panel/NonResponsiveActions.d.ts +1 -1
  62. package/dist/components/Panel/NonResponsiveActions.d.ts.map +1 -1
  63. package/dist/components/Panel/index.js +1 -1
  64. package/dist/components/Panel/index.js.map +1 -1
  65. package/dist/components/Panel/panel.screenshot.d.ts +1 -1
  66. package/dist/components/Panel/panel.screenshot.d.ts.map +1 -1
  67. package/dist/components/Paragraph/index.d.ts +1 -1
  68. package/dist/components/Paragraph/index.d.ts.map +1 -1
  69. package/dist/components/Popover/index.d.ts +1 -1
  70. package/dist/components/Popover/index.d.ts.map +1 -1
  71. package/dist/components/RadioGroup/index.d.ts +1 -1
  72. package/dist/components/RadioGroup/index.d.ts.map +1 -1
  73. package/dist/components/Sidebar/item.d.ts +1 -1
  74. package/dist/components/Sidebar/item.d.ts.map +1 -1
  75. package/dist/components/Spacer/index.d.ts +3 -3
  76. package/dist/components/Spacer/index.d.ts.map +1 -1
  77. package/dist/components/Spinner/index.d.ts +1 -1
  78. package/dist/components/Spinner/index.d.ts.map +1 -1
  79. package/dist/components/Table/body.d.ts +1 -1
  80. package/dist/components/Table/body.d.ts.map +1 -1
  81. package/dist/components/Table/body.js +4 -2
  82. package/dist/components/Table/body.js.map +1 -1
  83. package/dist/components/Table/cell.d.ts +1 -1
  84. package/dist/components/Table/cell.d.ts.map +1 -1
  85. package/dist/components/Table/headerCell.d.ts +1 -1
  86. package/dist/components/Table/headerCell.d.ts.map +1 -1
  87. package/dist/components/Table/helpers.d.ts +8 -6
  88. package/dist/components/Table/helpers.d.ts.map +1 -1
  89. package/dist/components/Table/helpers.js +49 -16
  90. package/dist/components/Table/helpers.js.map +1 -1
  91. package/dist/components/Table/index.d.ts +5 -4
  92. package/dist/components/Table/index.d.ts.map +1 -1
  93. package/dist/components/Table/index.js +63 -53
  94. package/dist/components/Table/index.js.map +1 -1
  95. package/dist/components/Table/row.d.ts +7 -5
  96. package/dist/components/Table/row.d.ts.map +1 -1
  97. package/dist/components/Table/row.js +12 -5
  98. package/dist/components/Table/row.js.map +1 -1
  99. package/dist/components/Table/value.d.ts +7 -0
  100. package/dist/components/Table/value.d.ts.map +1 -0
  101. package/dist/components/Table/value.js +37 -0
  102. package/dist/components/Table/value.js.map +1 -0
  103. package/dist/components/Tabs/content.d.ts +1 -1
  104. package/dist/components/Tabs/content.d.ts.map +1 -1
  105. package/dist/components/Tabs/index.d.ts +1 -1
  106. package/dist/components/Tabs/index.d.ts.map +1 -1
  107. package/dist/components/Tabs/list.d.ts +1 -1
  108. package/dist/components/Tabs/list.d.ts.map +1 -1
  109. package/dist/components/Tabs/list.js +1 -1
  110. package/dist/components/Tabs/list.js.map +1 -1
  111. package/dist/components/Tag/group.d.ts +1 -1
  112. package/dist/components/Tag/group.d.ts.map +1 -1
  113. package/dist/components/Tree/index.d.ts +2 -1
  114. package/dist/components/Tree/index.d.ts.map +1 -1
  115. package/dist/components/Tree/index.js +35 -31
  116. package/dist/components/Tree/index.js.map +1 -1
  117. package/dist/containers/Paging.d.ts +1 -1
  118. package/dist/containers/Paging.d.ts.map +1 -1
  119. package/dist/containers/ThemeProvider.d.ts +1 -1
  120. package/dist/containers/ThemeProvider.d.ts.map +1 -1
  121. package/dist/helpers/utils.d.ts +2 -1
  122. package/dist/helpers/utils.d.ts.map +1 -1
  123. package/dist/helpers/utils.js +20 -2
  124. package/dist/helpers/utils.js.map +1 -1
  125. package/dist/hooks/useAutoFocus.d.ts +1 -1
  126. package/dist/hooks/useAutoFocus.d.ts.map +1 -1
  127. package/dist/hooks/usePopover.d.ts +1 -0
  128. package/dist/hooks/usePopover.d.ts.map +1 -1
  129. package/dist/index.d.ts +2 -0
  130. package/dist/index.d.ts.map +1 -1
  131. package/dist/index.js +6 -2
  132. package/dist/index.js.map +1 -1
  133. package/dist/styles.d.ts +3 -0
  134. package/dist/styles.d.ts.map +1 -1
  135. package/dist/styles.js +49 -11
  136. package/dist/styles.js.map +1 -1
  137. package/migration-storybook.log +88 -0
  138. package/package.json +26 -20
  139. package/src/components/Breadcrumbs/index.tsx +1 -1
  140. package/src/components/Button/index.tsx +3 -54
  141. package/src/components/Collection/index.tsx +18 -15
  142. package/src/components/Collection/item.tsx +2 -1
  143. package/src/components/ExportModal/index.tsx +98 -0
  144. package/src/components/KeyValueTable/index.tsx +129 -0
  145. package/src/components/Menu/item.tsx +4 -4
  146. package/src/components/Notifications/notification.tsx +2 -2
  147. package/src/components/Panel/index.tsx +2 -2
  148. package/src/components/Table/body.tsx +6 -3
  149. package/src/components/Table/helpers.ts +52 -21
  150. package/src/components/Table/index.tsx +127 -90
  151. package/src/components/Table/row.tsx +21 -10
  152. package/src/components/Table/value.tsx +27 -0
  153. package/src/components/Tabs/list.tsx +1 -1
  154. package/src/components/Tree/index.tsx +82 -75
  155. package/src/helpers/utils.ts +10 -2
  156. package/src/hooks/useAutoFocus.ts +1 -1
  157. package/src/index.tsx +2 -0
  158. package/src/mock/tableData.ts +12 -0
  159. package/src/stories/Breadcrumbs/Breadcrumbs.stories.tsx +11 -23
  160. package/src/stories/Button/Button.stories.tsx +83 -47
  161. package/src/stories/Checkbox/Checkbox.stories.tsx +19 -9
  162. package/src/stories/Collection/Collection.stories.tsx +195 -171
  163. package/src/stories/Columns/Columns.stories.tsx +38 -24
  164. package/src/stories/Comment/Comment.stories.tsx +15 -6
  165. package/src/stories/ControlGroup/ControlGroup.stories.tsx +102 -48
  166. package/src/stories/Drawer/Drawer.stories.tsx +52 -17
  167. package/src/stories/Dropdown/Dropdown.stories.tsx +184 -152
  168. package/src/stories/ExportModal/ExportModal.stories.tsx +18 -0
  169. package/src/stories/Header/Header.stories.tsx +65 -31
  170. package/src/stories/Icon/Icon.stories.tsx +139 -133
  171. package/src/stories/Input/Input.stories.tsx +68 -31
  172. package/src/stories/KeyValueTable/KeyValueTable.stories.tsx +224 -0
  173. package/src/stories/Menu/Menu.stories.tsx +56 -20
  174. package/src/stories/Message/Message.stories.tsx +71 -37
  175. package/src/stories/Modal/Modal.stories.tsx +28 -8
  176. package/src/stories/MultiSelect/MultiSelect.stories.tsx +66 -35
  177. package/src/stories/Navbar/Navbar.stories.tsx +15 -5
  178. package/src/stories/Notifications/Interactive.stories.tsx +40 -28
  179. package/src/stories/Notifications/Notification.stories.tsx +55 -41
  180. package/src/stories/Notifications/Notifications.stories.tsx +45 -29
  181. package/src/stories/Paging/Paging.stories.tsx +206 -177
  182. package/src/stories/Panel/Panel.stories.tsx +238 -168
  183. package/src/stories/Paragraph/Paragraph.stories.tsx +66 -31
  184. package/src/stories/Popover/Popover.stories.tsx +62 -40
  185. package/src/stories/RadioGroup/RadioGroup.stories.tsx +41 -19
  186. package/src/stories/Sidebar/Sidebar.stories.tsx +29 -10
  187. package/src/stories/Spacer/Spacer.stories.tsx +13 -5
  188. package/src/stories/Spinner/Spinner.stories.tsx +26 -12
  189. package/src/stories/Table/Table.stories.tsx +200 -144
  190. package/src/stories/Table/Tests.stories.tsx +9 -0
  191. package/src/stories/Tabs/Tabs.stories.tsx +82 -46
  192. package/src/stories/Tag/Tag.stories.tsx +56 -37
  193. package/src/stories/Tag/TagGroup.stories.tsx +297 -0
  194. package/src/stories/TextArea/TextArea.stories.tsx +82 -40
  195. package/src/stories/Tree/Tree.stories.tsx +84 -22
  196. package/src/stories/utils.ts +22 -1
  197. package/src/styles.ts +55 -2
  198. package/tests.json +1 -1
@@ -1,15 +1,15 @@
1
1
  import { size } from 'lodash';
2
2
  import { firstBy } from 'thenby';
3
- import { IReqoreTableColumn, IReqoreTableSort } from '.';
3
+ import { IReqoreTableColumn, IReqoreTableData, IReqoreTableSort } from '.';
4
4
  import { ICON_FROM_SIZE, SIZE_TO_MODIFIER, SIZE_TO_PX, TSizes } from '../../constants/sizes';
5
5
  import { IReqoreIconName } from '../../types/icons';
6
- import { IReqorePanelAction } from '../Panel';
6
+ import { IReqorePanelSubAction } from '../Panel';
7
7
 
8
8
  export const flipSortDirection = (direction: 'asc' | 'desc'): 'asc' | 'desc' =>
9
9
  direction === 'asc' ? 'desc' : 'asc';
10
10
 
11
- export const fixSort = (sort?: IReqoreTableSort) => {
12
- return { ...(sort || {}), direction: sort?.direction || 'desc' };
11
+ export const fixSort = (sort: IReqoreTableSort) => {
12
+ return { ...sort, direction: sort?.direction || 'desc' };
13
13
  };
14
14
 
15
15
  export const sortTableData = (data: any[], sort: IReqoreTableSort) => {
@@ -81,20 +81,38 @@ export const zoomToWidth = {
81
81
 
82
82
  // This code converts a zoom level to a label.
83
83
  export const zoomToLabel = {
84
- 0: '0.6x',
85
- 0.5: '0.8x',
86
- 1: '1x',
87
- 1.5: '1.2x',
88
- 2: '1.4x',
84
+ 0: '30%',
85
+ 0.5: '60%',
86
+ 1: '100%',
87
+ 1.5: '130%',
88
+ 2: '160%',
89
89
  };
90
90
 
91
+ export const getExportActions = (
92
+ onClick: (type: 'current' | 'full') => void,
93
+ withLabels: boolean = true
94
+ ): IReqorePanelSubAction[] => [
95
+ {
96
+ label: withLabels ? 'Export current view' : undefined,
97
+ icon: 'Download2Line',
98
+ onClick: () => onClick('current'),
99
+ },
100
+ {
101
+ label: withLabels ? 'Export full data' : undefined,
102
+ icon: 'DownloadLine',
103
+ onClick: () => onClick('full'),
104
+ },
105
+ ];
106
+
91
107
  export const getZoomActions = (
92
108
  type: string,
93
109
  zoom: number,
94
- setter: (zoom: number) => void
95
- ): IReqorePanelAction[] => [
110
+ setter: (zoom: number) => void,
111
+ withLabels?: boolean
112
+ ): IReqorePanelSubAction[] => [
96
113
  {
97
114
  icon: 'ZoomInLine',
115
+ label: withLabels ? 'Zoom in' : undefined,
98
116
  tooltip: 'Zoom in',
99
117
  disabled: zoom === 2,
100
118
  className: `${type}-zoom-in`,
@@ -104,7 +122,7 @@ export const getZoomActions = (
104
122
  },
105
123
  {
106
124
  icon: 'RestartLine',
107
- label: zoomToLabel[zoom],
125
+ label: `${zoomToLabel[zoom]}${withLabels ? ' (reset)' : ''}`,
108
126
  tooltip: 'Reset zoom',
109
127
  disabled: zoom === 1,
110
128
  className: `${type}-zoom-reset`,
@@ -115,6 +133,7 @@ export const getZoomActions = (
115
133
  {
116
134
  icon: 'ZoomOutLine',
117
135
  tooltip: 'Zoom out',
136
+ label: withLabels ? 'Zoom out' : undefined,
118
137
  disabled: zoom === 0,
119
138
  className: `${type}-zoom-out`,
120
139
  onClick: () => {
@@ -127,7 +146,7 @@ export const getColumnsCount = (columns: IReqoreTableColumn[]): number => {
127
146
  let count = 0;
128
147
 
129
148
  columns.forEach((column) => {
130
- if (column.header.columns) {
149
+ if (column.header?.columns) {
131
150
  count += getColumnsCount(column.header.columns);
132
151
  } else {
133
152
  count += 1;
@@ -145,7 +164,7 @@ export const hasGroupedColumns = (columns: IReqoreTableColumn[]): boolean => {
145
164
 
146
165
  export const hasHiddenColumns = (columns: IReqoreTableColumn[]): boolean => {
147
166
  return columns.some((column) => {
148
- if (column.header.columns) {
167
+ if (column.header?.columns) {
149
168
  return column.header.columns.some((subColumn) => subColumn.show === false);
150
169
  }
151
170
 
@@ -157,8 +176,8 @@ export const getColumnsByPinType = (
157
176
  columns: IReqoreTableColumn[],
158
177
  type: 'left' | 'right' | 'main'
159
178
  ): IReqoreTableColumn[] => {
160
- return columns.reduce((newColumns, column) => {
161
- if (column.header.columns) {
179
+ return columns.reduce((newColumns: IReqoreTableColumn[], column): IReqoreTableColumn[] => {
180
+ if (column.header?.columns) {
162
181
  const subColumns: IReqoreTableColumn[] = getColumnsByPinType(column.header.columns, type);
163
182
 
164
183
  if (!size(subColumns)) {
@@ -188,8 +207,8 @@ export const getColumnsByPinType = (
188
207
  };
189
208
 
190
209
  export const getOnlyShownColumns = (columns: IReqoreTableColumn[]): IReqoreTableColumn[] => {
191
- return columns.reduce((newColumns, column) => {
192
- if (column.header.columns) {
210
+ return columns.reduce((newColumns: IReqoreTableColumn[], column) => {
211
+ if (column.header?.columns) {
193
212
  const subColumns = getOnlyShownColumns(column.header.columns);
194
213
 
195
214
  if (size(subColumns)) {
@@ -220,7 +239,7 @@ export const prepareColumns = (
220
239
  ): IReqoreTableColumn[] => {
221
240
  // We need to set the width of each column
222
241
  return columns.map((column) => {
223
- if (column.header.columns) {
242
+ if (column.header?.columns) {
224
243
  return {
225
244
  ...column,
226
245
  header: {
@@ -233,7 +252,7 @@ export const prepareColumns = (
233
252
  let newWidth = calculateMinimumCellWidth(
234
253
  column.width || 50,
235
254
  size,
236
- column.header.icon,
255
+ column.header?.icon,
237
256
  column.sortable,
238
257
  column.filterable,
239
258
  column.hideable,
@@ -250,7 +269,7 @@ export const prepareColumns = (
250
269
 
251
270
  export const calculateMinimumCellWidth = (
252
271
  currentWidth: number = 50,
253
- size?: TSizes,
272
+ size: TSizes,
254
273
  icon?: IReqoreIconName,
255
274
  sortable?: boolean,
256
275
  filterable?: boolean,
@@ -273,3 +292,15 @@ export const calculateMinimumCellWidth = (
273
292
 
274
293
  return width;
275
294
  };
295
+
296
+ export const removeInternalData = (data: IReqoreTableData): any[] => {
297
+ return data.map((item) => {
298
+ const newItem = { ...item };
299
+
300
+ delete newItem._selectId;
301
+ delete newItem._disabled;
302
+ delete newItem._intent;
303
+
304
+ return newItem;
305
+ });
306
+ };
@@ -11,6 +11,7 @@ import { useQueryWithDelay } from '../../hooks/useQueryWithDelay';
11
11
  import { IReqoreIntent, IReqoreTooltip } from '../../types/global';
12
12
  import { IReqoreButtonProps, TReqoreBadge } from '../Button';
13
13
  import { IReqoreDropdownItem } from '../Dropdown/list';
14
+ import { ReqoreExportModal } from '../ExportModal';
14
15
  import ReqoreInput, { IReqoreInputProps } from '../Input';
15
16
  import { IReqorePanelAction, IReqorePanelProps, IReqorePanelSubAction } from '../Panel';
16
17
  import ReqoreTableBody from './body';
@@ -21,11 +22,13 @@ import {
21
22
  flipSortDirection,
22
23
  getColumnsByPinType,
23
24
  getColumnsCount,
25
+ getExportActions,
24
26
  getOnlyShownColumns,
25
27
  getZoomActions,
26
28
  hasGroupedColumns,
27
29
  hasHiddenColumns,
28
30
  prepareColumns,
31
+ removeInternalData,
29
32
  sizeToZoom,
30
33
  sortTableData,
31
34
  zoomToSize,
@@ -104,8 +107,10 @@ export interface IReqoreTableProps extends IReqorePanelProps {
104
107
 
105
108
  filterable?: boolean;
106
109
  filterProps?: (data: IReqoreTableData) => IReqoreInputProps;
107
- filter?: string;
108
- onFilterChange?: (query: string) => void;
110
+ filter?: string | number;
111
+ onFilterChange?: (query: string | number) => void;
112
+
113
+ exportable?: boolean;
109
114
 
110
115
  zoomable?: boolean;
111
116
  defaultZoom?: number;
@@ -137,7 +142,7 @@ export interface IReqoreTableStyle {
137
142
  }
138
143
 
139
144
  export interface IReqoreTableSort {
140
- by?: string;
145
+ by: string;
141
146
  thenBy?: string;
142
147
  direction?: 'asc' | 'desc';
143
148
  }
@@ -188,7 +193,7 @@ const ReqoreTable = ({
188
193
  fill,
189
194
  filterable,
190
195
  zoomable,
191
- filter,
196
+ filter = '',
192
197
  actions = [],
193
198
  onFilterChange,
194
199
  filterProps,
@@ -198,16 +203,17 @@ const ReqoreTable = ({
198
203
  bodyCellComponent,
199
204
  onSelectClick,
200
205
  paging,
206
+ exportable,
201
207
  ...rest
202
208
  }: IReqoreTableProps) => {
203
- const leftTableRef = useRef<HTMLDivElement>(undefined);
204
- const rightTableRef = useRef<HTMLDivElement>(undefined);
205
- const mainTableRef = useRef<HTMLDivElement>(undefined);
206
- const mainHeaderRef = useRef<HTMLDivElement>(undefined);
209
+ const leftTableRef = useRef<HTMLDivElement>(null);
210
+ const rightTableRef = useRef<HTMLDivElement>(null);
211
+ const mainTableRef = useRef<HTMLDivElement>(null);
212
+ const mainHeaderRef = useRef<HTMLDivElement>(null);
207
213
 
208
214
  const [isScrolled, setIsScrolled] = useState<boolean>(false);
209
215
  const [_data, setData] = useState<IReqoreTableData>(data || []);
210
- const [_sort, setSort] = useState<IReqoreTableSort>(fixSort(sort));
216
+ const [_sort, setSort] = useState<IReqoreTableSort | undefined>(fixSort(sort));
211
217
  const [_selected, setSelected] = useState<(string | number)[]>(selected || []);
212
218
  const [_selectedQuant, setSelectedQuant] = useState<'all' | 'none' | 'some'>('none');
213
219
  const [columnModifiers, setColumnModifiers] = useState<{
@@ -215,9 +221,14 @@ const ReqoreTable = ({
215
221
  }>({});
216
222
  const [_internalColumns, setColumns] = useState<IReqoreTableColumn[]>(columns);
217
223
  const [zoom, setZoom] = useState<number>(sizeToZoom[size]);
224
+ const [showExportModal, setShowExportModal] = useState<'full' | 'current' | undefined>(undefined);
218
225
 
219
226
  const [wrapperRef, sizes] = useMeasure();
220
- const { query, preQuery, setQuery, setPreQuery } = useQueryWithDelay(filter, 300, onFilterChange);
227
+ const { query, preQuery, setQuery, setPreQuery } = useQueryWithDelay(
228
+ filter.toString(),
229
+ 300,
230
+ onFilterChange
231
+ );
221
232
 
222
233
  const selectedIcon = useMemo(() => {
223
234
  switch (_selectedQuant) {
@@ -260,15 +271,15 @@ const ReqoreTable = ({
260
271
  tooltip: selectToggleTooltip,
261
272
  icon: !_selectId
262
273
  ? 'Forbid2Line'
263
- : _selected?.find((s) => s === _selectId)
274
+ : _selected?.find((s) => s.toString() === _selectId.toString())
264
275
  ? 'CheckboxCircleLine'
265
276
  : 'CheckboxBlankCircleLine',
266
277
  intent: !_selectId
267
278
  ? 'muted'
268
- : _selected?.find((s) => s === _selectId)
279
+ : _selected?.find((s) => s.toString() === _selectId.toString())
269
280
  ? selectedRowIntent
270
281
  : undefined,
271
- onClick: () => handleSelectClick(_selectId),
282
+ onClick: _selectId ? () => handleSelectClick(_selectId) : undefined,
272
283
  },
273
284
  ],
274
285
  },
@@ -314,7 +325,7 @@ const ReqoreTable = ({
314
325
  const transformedData = useMemo(() => {
315
326
  // Filter by global query
316
327
  let filteredData = _data.filter((datum) =>
317
- JSON.stringify(datum).toLowerCase().includes(query.toLowerCase())
328
+ JSON.stringify(datum).toLowerCase().includes(query.toString().toLowerCase())
318
329
  );
319
330
 
320
331
  // Filter by column filters
@@ -345,7 +356,7 @@ const ReqoreTable = ({
345
356
  }, [data]);
346
357
 
347
358
  useUpdateEffect(() => {
348
- if (selectable) {
359
+ if (selectable && selected) {
349
360
  setSelected(selected);
350
361
  }
351
362
  }, [selected]);
@@ -370,7 +381,7 @@ const ReqoreTable = ({
370
381
  }
371
382
  }, [_selected]);
372
383
 
373
- const handleSortChange = (by?: string) => {
384
+ const handleSortChange = (by: string) => {
374
385
  setSort((currentSort: IReqoreTableSort) => {
375
386
  const newSort: IReqoreTableSort = { ...currentSort };
376
387
 
@@ -440,16 +451,11 @@ const ReqoreTable = ({
440
451
  }, []);
441
452
 
442
453
  const columnsList = useMemo(() => {
443
- const _columnsList: IReqorePanelSubAction[] = [
444
- {
445
- divider: true,
446
- label: 'Show / hide columns',
447
- },
448
- ];
454
+ const _columnsList: IReqorePanelSubAction[] = [];
449
455
 
450
456
  const addColumn = (column: IReqoreTableColumn) => {
451
457
  _columnsList.push({
452
- label: typeof column.header.label === 'string' ? column.header.label : column.dataId,
458
+ label: typeof column.header?.label === 'string' ? column.header.label : column.dataId,
453
459
  selected: column.show !== false,
454
460
  onClick: () =>
455
461
  handleColumnsUpdate(column.dataId, 'show', column.show !== false ? false : true),
@@ -471,6 +477,13 @@ const ReqoreTable = ({
471
477
  }
472
478
  });
473
479
 
480
+ if (count(_columnsList)) {
481
+ _columnsList.unshift({
482
+ divider: true,
483
+ label: 'Show / hide columns',
484
+ });
485
+ }
486
+
474
487
  return _columnsList;
475
488
  }, [finalColumns]);
476
489
 
@@ -494,15 +507,16 @@ const ReqoreTable = ({
494
507
  const tableActions = useMemo<IReqorePanelAction[]>(() => {
495
508
  const finalActions: IReqorePanelAction[] = [...actions];
496
509
 
497
- finalActions.push({
498
- label: 'Columns',
499
- icon: 'LayoutColumnLine',
500
- className: 'reqore-table-columns-options',
501
- badge: getColumnsCount(getOnlyShownColumns(finalColumns)),
502
- intent: hasHiddenColumns(finalColumns) ? 'info' : undefined,
503
- multiSelect: true,
504
- actions: columnsList,
505
- });
510
+ if (count(columnsList)) {
511
+ finalActions.push({
512
+ icon: 'LayoutColumnLine',
513
+ className: 'reqore-table-columns-options',
514
+ badge: getColumnsCount(getOnlyShownColumns(finalColumns)),
515
+ intent: hasHiddenColumns(finalColumns) ? 'info' : undefined,
516
+ multiSelect: true,
517
+ actions: columnsList,
518
+ });
519
+ }
506
520
 
507
521
  if (filterable) {
508
522
  finalActions.push({
@@ -525,13 +539,6 @@ const ReqoreTable = ({
525
539
  });
526
540
  }
527
541
 
528
- if (zoomable) {
529
- finalActions.push({
530
- fluid: false,
531
- group: getZoomActions('reqore-table', zoom, setZoom),
532
- });
533
- }
534
-
535
542
  if (isScrolled) {
536
543
  finalActions.push({
537
544
  icon: 'ArrowUpSFill',
@@ -542,11 +549,28 @@ const ReqoreTable = ({
542
549
  });
543
550
  }
544
551
 
545
- if (count(columnModifiers) || zoomable || filterable) {
552
+ if (count(columnModifiers) || zoomable || filterable || exportable) {
553
+ let moreActions: IReqorePanelSubAction[] = [];
554
+
555
+ if (exportable) {
556
+ moreActions = [
557
+ ...getExportActions((type) => setShowExportModal(type)),
558
+ { divider: true, line: true },
559
+ ];
560
+ }
561
+
562
+ if (zoomable) {
563
+ moreActions = [
564
+ ...getZoomActions('reqore-table', zoom, setZoom, true),
565
+ { divider: true, line: true },
566
+ ];
567
+ }
568
+
546
569
  finalActions.push({
547
570
  icon: 'MoreLine',
548
571
  className: 'reqore-table-more',
549
572
  actions: [
573
+ ...moreActions,
550
574
  {
551
575
  label: 'Reset table',
552
576
  icon: 'RestartLine',
@@ -577,7 +601,7 @@ const ReqoreTable = ({
577
601
  ]);
578
602
 
579
603
  const badge = useMemo(() => {
580
- const badgeList: TReqoreBadge[] = rest.label ? [count(transformedData)] : undefined;
604
+ const badgeList: TReqoreBadge[] = rest.label ? [count(transformedData)] : [];
581
605
 
582
606
  if (rest.badge) {
583
607
  if (isArray(rest.badge)) {
@@ -657,58 +681,71 @@ const ReqoreTable = ({
657
681
  );
658
682
  };
659
683
 
660
- const pagingOptions = useMemo(() => getPagingObjectFromType(paging), [paging]);
684
+ const pagingOptions = useMemo(
685
+ () => (paging ? getPagingObjectFromType(paging) : undefined),
686
+ [paging]
687
+ );
661
688
 
662
689
  return (
663
- <ReqorePanel
664
- transparent
665
- flat
666
- padded={false}
667
- contentStyle={{ display: 'flex', flexFlow: 'column', overflow: 'hidden' }}
668
- responsiveActions={false}
669
- {...rest}
670
- size={wrapperSize}
671
- actions={tableActions}
672
- fill={fill}
673
- className={`${className || ''} reqore-table`}
674
- style={{ width, ...(rest.style || {}) }}
675
- getContentRef={wrapperRef}
676
- badge={badge}
677
- >
678
- <ReqorePaginationContainer<IReqoreTableRowData>
679
- items={transformedData}
680
- type={
681
- paging
682
- ? {
683
- ...pagingOptions,
684
- onPageChange: () => {
685
- if (!pagingOptions.infinite) {
686
- handleScrollToTop();
687
- }
688
- },
689
- }
690
- : undefined
691
- }
690
+ <>
691
+ <ReqorePanel
692
+ transparent
693
+ flat
694
+ padded={false}
695
+ contentStyle={{ display: 'flex', flexFlow: 'column', overflow: 'hidden' }}
696
+ responsiveActions={false}
697
+ {...rest}
698
+ size={wrapperSize}
699
+ actions={tableActions}
700
+ fill={fill}
701
+ className={`${className || ''} reqore-table`}
702
+ style={{ width, ...(rest.style || {}) }}
703
+ getContentRef={wrapperRef}
704
+ badge={badge}
692
705
  >
693
- {(pagedData) => (
694
- <>
695
- <StyledTablesWrapper className='reqore-table-wrapper'>
696
- {renderTable('left', pagedData)}
697
- {renderTable('main', pagedData)}
698
- {renderTable('right', pagedData)}
699
- </StyledTablesWrapper>
700
- {count(pagedData) === 0 ? (
701
- <>
702
- <ReqoreVerticalSpacer height={10} />
703
- <ReqoreMessage flat size={size} icon='Search2Line'>
704
- {emptyMessage}
705
- </ReqoreMessage>
706
- </>
707
- ) : null}
708
- </>
709
- )}
710
- </ReqorePaginationContainer>
711
- </ReqorePanel>
706
+ <ReqorePaginationContainer<IReqoreTableRowData>
707
+ items={transformedData}
708
+ type={
709
+ pagingOptions
710
+ ? {
711
+ ...pagingOptions,
712
+ onPageChange: () => {
713
+ if (!pagingOptions.infinite) {
714
+ handleScrollToTop();
715
+ }
716
+ },
717
+ }
718
+ : undefined
719
+ }
720
+ >
721
+ {(pagedData) => (
722
+ <>
723
+ {showExportModal && (
724
+ <ReqoreExportModal
725
+ data={removeInternalData(
726
+ showExportModal === 'current' ? pagedData : transformedData
727
+ )}
728
+ onClose={() => setShowExportModal(undefined)}
729
+ />
730
+ )}
731
+ <StyledTablesWrapper className='reqore-table-wrapper'>
732
+ {renderTable('left', pagedData)}
733
+ {renderTable('main', pagedData)}
734
+ {renderTable('right', pagedData)}
735
+ </StyledTablesWrapper>
736
+ {count(pagedData) === 0 ? (
737
+ <>
738
+ <ReqoreVerticalSpacer height={10} />
739
+ <ReqoreMessage flat size={size} icon='Search2Line'>
740
+ {emptyMessage}
741
+ </ReqoreMessage>
742
+ </>
743
+ ) : null}
744
+ </>
745
+ )}
746
+ </ReqorePaginationContainer>
747
+ </ReqorePanel>
748
+ </>
712
749
  );
713
750
  };
714
751
 
@@ -17,10 +17,10 @@ import { getOnlyShownColumns } from './helpers';
17
17
 
18
18
  export interface IReqoreTableRowOptions {
19
19
  columns: IReqoreTableColumn[];
20
- data?: IReqoreTableData;
20
+ data: IReqoreTableData;
21
21
  selectable?: boolean;
22
- onSelectClick?: (selectId: string | number) => void;
23
- selected?: (string | number)[];
22
+ onSelectClick: (selectId: string | number) => void;
23
+ selected: (string | number)[];
24
24
  onRowClick?: IReqoreTableRowClick;
25
25
  striped?: boolean;
26
26
  selectedRowIntent?: TReqoreIntent;
@@ -29,7 +29,10 @@ export interface IReqoreTableRowOptions {
29
29
  cellComponent?: IReqoreCustomTableBodyCell;
30
30
  rowComponent?: IReqoreCustomTableRow;
31
31
  }
32
- export interface IReqoreCustomTableRowProps extends IReqoreTableRowOptions {}
32
+ export interface IReqoreCustomTableRowProps extends IReqoreTableRowOptions {
33
+ style?: React.CSSProperties;
34
+ children?: ReactElement;
35
+ }
33
36
  export interface IReqoreCustomTableRow extends React.FC<IReqoreCustomTableRowProps> {}
34
37
  export interface IReqoreTableRowProps extends React.HTMLAttributes<HTMLDivElement> {
35
38
  data: IReqoreTableRowOptions;
@@ -92,7 +95,9 @@ const ReqoreTableRow = ({
92
95
  index,
93
96
  }: IReqoreTableRowProps) => {
94
97
  const [isHovered, setIsHovered] = useState<boolean>(false);
95
- const isSelected = selected.find((selectId) => selectId === data[index]._selectId);
98
+ const isSelected =
99
+ data[index]._selectId &&
100
+ selected.find((selectId) => selectId.toString() === data[index]._selectId.toString());
96
101
 
97
102
  const CellComponent = cellComponent || ReqoreTableBodyCell;
98
103
  const RowComponent = rowComponent || StyledTableRow;
@@ -124,12 +129,18 @@ const ReqoreTableRow = ({
124
129
  );
125
130
  }
126
131
 
127
- const content = cell?.content;
132
+ let content = cell?.content;
128
133
 
129
134
  if (isFunction(content)) {
130
- const Content = content;
135
+ // Check what type does the content function return
136
+ if (React.isValidElement(content(data))) {
137
+ const Content = content;
138
+ // If it's a react element, return it
139
+ return <Content {...data} _size={size} _dataId={dataId} />;
140
+ }
131
141
 
132
- return <Content {...data} _size={size} _dataId={dataId} />;
142
+ // If it's a function, call it and return the result
143
+ content = content(data) as any;
133
144
  }
134
145
 
135
146
  if (isString(content)) {
@@ -175,7 +186,7 @@ const ReqoreTableRow = ({
175
186
  const renderCells = (columns: IReqoreTableColumn[], data: IReqoreTableData) =>
176
187
  getOnlyShownColumns(columns).map(
177
188
  ({ width, minWidth, maxWidth, resizedWidth, grow, dataId, cell, header, align, intent }) => {
178
- if (header.columns) {
189
+ if (header?.columns) {
179
190
  return renderCells(header.columns, data);
180
191
  }
181
192
 
@@ -221,7 +232,7 @@ const ReqoreTableRow = ({
221
232
  onRowClick(data[index]);
222
233
  } else if (selectable && data[index]._selectId) {
223
234
  // Otherwise select the row if selectable
224
- onSelectClick(data[index]._selectId);
235
+ onSelectClick(data[index]._selectId!);
225
236
  }
226
237
  },
227
238
  className: 'reqore-table-cell',
@@ -0,0 +1,27 @@
1
+ import ReqoreIcon from '../Icon';
2
+ import { ReqoreP } from '../Paragraph';
3
+
4
+ export interface IReqoreTableValueProps {
5
+ value?: string | number | boolean | any[] | { [key: string]: any };
6
+ }
7
+
8
+ export const ReqoreTableValue = ({ value }: IReqoreTableValueProps) => {
9
+ if (value === undefined || value === null) {
10
+ return <>-</>;
11
+ }
12
+
13
+ switch (typeof value) {
14
+ case 'string':
15
+ case 'number':
16
+ return <ReqoreP className='reqore-table-text'>{value}</ReqoreP>;
17
+ case 'boolean':
18
+ return (
19
+ <ReqoreIcon
20
+ icon={value ? 'CheckLine' : 'CloseLine'}
21
+ intent={value ? 'success' : 'danger'}
22
+ />
23
+ );
24
+ default:
25
+ return <ReqoreP className='reqore-table-text'>{JSON.stringify(value)}</ReqoreP>;
26
+ }
27
+ };
@@ -252,7 +252,7 @@ const ReqoreTabsList = ({
252
252
  }
253
253
  : undefined,
254
254
  selected: activeTab === id,
255
- onClick: (_id, event: React.MouseEvent<any>) => {
255
+ onClick: (event: React.MouseEvent<any>) => {
256
256
  if (!disabled) {
257
257
  onTabChange?.(id);
258
258