@imposium-hub/components 2.5.11 → 2.5.12-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/dist/cjs/components/assets/AssetsTableAssetIdCell.d.ts +2 -0
  2. package/dist/cjs/components/assets/AssetsTableAssetIdCell.js +54 -0
  3. package/dist/cjs/components/assets/AssetsTableAssetIdCell.js.map +1 -0
  4. package/dist/cjs/components/assets/AssetsTableAssetIdFilter.d.ts +2 -0
  5. package/dist/cjs/components/assets/AssetsTableAssetIdFilter.js +94 -0
  6. package/dist/cjs/components/assets/AssetsTableAssetIdFilter.js.map +1 -0
  7. package/dist/cjs/components/assets/AssetsTableGlobalCell.js +2 -1
  8. package/dist/cjs/components/assets/AssetsTableGlobalCell.js.map +1 -1
  9. package/dist/cjs/components/assets/StoryTableNameFilter.d.ts +2 -0
  10. package/dist/cjs/components/{error-message-preview/ErrorMessagePreview.js → assets/StoryTableNameFilter.js} +46 -43
  11. package/dist/cjs/components/assets/StoryTableNameFilter.js.map +1 -0
  12. package/dist/cjs/components/card/Card.d.ts +1 -0
  13. package/dist/cjs/components/card/Card.js +17 -4
  14. package/dist/cjs/components/card/Card.js.map +1 -1
  15. package/dist/cjs/components/color-field/ColorField.js +9 -14
  16. package/dist/cjs/components/color-field/ColorField.js.map +1 -1
  17. package/dist/cjs/components/data-table/DataTable.d.ts +3 -2
  18. package/dist/cjs/components/data-table/DataTable.js +80 -10
  19. package/dist/cjs/components/data-table/DataTable.js.map +1 -1
  20. package/dist/cjs/components/data-table/Paginator.js +76 -11
  21. package/dist/cjs/components/data-table/Paginator.js.map +1 -1
  22. package/dist/cjs/components/header/Header.d.ts +1 -0
  23. package/dist/cjs/components/header/Header.js +25 -4
  24. package/dist/cjs/components/header/Header.js.map +1 -1
  25. package/dist/cjs/components/smpte-field/SMPTEField.d.ts +2 -1
  26. package/dist/cjs/components/smpte-field/SMPTEField.js +9 -3
  27. package/dist/cjs/components/smpte-field/SMPTEField.js.map +1 -1
  28. package/dist/cjs/components/story-previewer/StoryPreviewer.js +1 -1
  29. package/dist/cjs/components/story-previewer/StoryPreviewer.js.map +1 -1
  30. package/dist/cjs/constants/variables.d.ts +1 -2
  31. package/dist/cjs/constants/variables.js +3 -24
  32. package/dist/cjs/constants/variables.js.map +1 -1
  33. package/dist/cjs/index.d.ts +6 -1
  34. package/dist/cjs/index.js +14 -2
  35. package/dist/cjs/index.js.map +1 -1
  36. package/dist/cjs/redux/actions/story-filter.d.ts +4 -0
  37. package/dist/cjs/redux/actions/story-filter.js +18 -0
  38. package/dist/cjs/redux/actions/story-filter.js.map +1 -0
  39. package/dist/cjs/redux/reducers/story-filter.d.ts +2 -0
  40. package/dist/cjs/redux/reducers/story-filter.js +33 -0
  41. package/dist/cjs/redux/reducers/story-filter.js.map +1 -0
  42. package/dist/esm/components/assets/AssetsTableAssetIdCell.d.ts +2 -0
  43. package/dist/esm/components/assets/AssetsTableAssetIdCell.js +29 -0
  44. package/dist/esm/components/assets/AssetsTableAssetIdCell.js.map +1 -0
  45. package/dist/esm/components/assets/AssetsTableAssetIdFilter.d.ts +2 -0
  46. package/dist/esm/components/assets/AssetsTableAssetIdFilter.js +20 -0
  47. package/dist/esm/components/assets/AssetsTableAssetIdFilter.js.map +1 -0
  48. package/dist/esm/components/assets/AssetsTableGlobalCell.js +2 -1
  49. package/dist/esm/components/assets/AssetsTableGlobalCell.js.map +1 -1
  50. package/dist/esm/components/assets/StoryTableNameFilter.d.ts +2 -0
  51. package/dist/esm/components/assets/StoryTableNameFilter.js +20 -0
  52. package/dist/esm/components/assets/StoryTableNameFilter.js.map +1 -0
  53. package/dist/esm/components/card/Card.d.ts +1 -0
  54. package/dist/esm/components/card/Card.js +16 -4
  55. package/dist/esm/components/card/Card.js.map +1 -1
  56. package/dist/esm/components/color-field/ColorField.js +9 -14
  57. package/dist/esm/components/color-field/ColorField.js.map +1 -1
  58. package/dist/esm/components/data-table/DataTable.d.ts +3 -2
  59. package/dist/esm/components/data-table/DataTable.js +78 -8
  60. package/dist/esm/components/data-table/DataTable.js.map +1 -1
  61. package/dist/esm/components/data-table/Paginator.js +95 -44
  62. package/dist/esm/components/data-table/Paginator.js.map +1 -1
  63. package/dist/esm/components/header/Header.d.ts +1 -0
  64. package/dist/esm/components/header/Header.js +19 -3
  65. package/dist/esm/components/header/Header.js.map +1 -1
  66. package/dist/esm/components/smpte-field/SMPTEField.d.ts +2 -1
  67. package/dist/esm/components/smpte-field/SMPTEField.js +9 -3
  68. package/dist/esm/components/smpte-field/SMPTEField.js.map +1 -1
  69. package/dist/esm/components/story-previewer/StoryPreviewer.js +1 -1
  70. package/dist/esm/components/story-previewer/StoryPreviewer.js.map +1 -1
  71. package/dist/esm/constants/variables.d.ts +1 -2
  72. package/dist/esm/constants/variables.js +2 -22
  73. package/dist/esm/constants/variables.js.map +1 -1
  74. package/dist/esm/index.d.ts +6 -1
  75. package/dist/esm/index.js +6 -1
  76. package/dist/esm/index.js.map +1 -1
  77. package/dist/esm/redux/actions/story-filter.d.ts +4 -0
  78. package/dist/esm/redux/actions/story-filter.js +13 -0
  79. package/dist/esm/redux/actions/story-filter.js.map +1 -0
  80. package/dist/esm/redux/reducers/story-filter.d.ts +2 -0
  81. package/dist/esm/redux/reducers/story-filter.js +16 -0
  82. package/dist/esm/redux/reducers/story-filter.js.map +1 -0
  83. package/dist/styles.css +13 -5
  84. package/dist/styles.less +16 -8
  85. package/less/components/data-table.less +4 -0
  86. package/less/components/form-field.less +7 -3
  87. package/less/components/header.less +0 -5
  88. package/less/components/tag.less +5 -0
  89. package/package.json +1 -1
  90. package/src/components/assets/AssetsTableAssetIdCell.tsx +64 -0
  91. package/src/components/assets/AssetsTableAssetIdFilter.tsx +41 -0
  92. package/src/components/assets/AssetsTableGlobalCell.tsx +11 -1
  93. package/src/components/assets/StoryTableNameFilter.tsx +40 -0
  94. package/src/components/card/Card.tsx +27 -13
  95. package/src/components/color-field/ColorField.tsx +16 -17
  96. package/src/components/data-table/DataTable.tsx +100 -12
  97. package/src/components/data-table/Paginator.tsx +162 -93
  98. package/src/components/header/Header.tsx +25 -2
  99. package/src/components/smpte-field/SMPTEField.tsx +8 -3
  100. package/src/components/story-previewer/StoryPreviewer.tsx +1 -1
  101. package/src/constants/variables.ts +2 -20
  102. package/src/index.ts +11 -0
  103. package/src/redux/actions/story-filter.ts +15 -0
  104. package/src/redux/reducers/story-filter.ts +18 -0
  105. package/dist/cjs/components/app-wrapper/AppWrapper_BACKUP_73190.d.ts +0 -27
  106. package/dist/cjs/components/app-wrapper/AppWrapper_BACKUP_73190.js +0 -243
  107. package/dist/cjs/components/app-wrapper/AppWrapper_BACKUP_73190.js.map +0 -1
  108. package/dist/cjs/components/app-wrapper/AppWrapper_BASE_73190.d.ts +0 -28
  109. package/dist/cjs/components/app-wrapper/AppWrapper_BASE_73190.js +0 -255
  110. package/dist/cjs/components/app-wrapper/AppWrapper_BASE_73190.js.map +0 -1
  111. package/dist/cjs/components/app-wrapper/AppWrapper_LOCAL_73190.d.ts +0 -27
  112. package/dist/cjs/components/app-wrapper/AppWrapper_LOCAL_73190.js +0 -243
  113. package/dist/cjs/components/app-wrapper/AppWrapper_LOCAL_73190.js.map +0 -1
  114. package/dist/cjs/components/app-wrapper/AppWrapper_REMOTE_73190.d.ts +0 -28
  115. package/dist/cjs/components/app-wrapper/AppWrapper_REMOTE_73190.js +0 -251
  116. package/dist/cjs/components/app-wrapper/AppWrapper_REMOTE_73190.js.map +0 -1
  117. package/dist/cjs/components/error-message-preview/ErrorMessagePreview.d.ts +0 -15
  118. package/dist/cjs/components/error-message-preview/ErrorMessagePreview.js.map +0 -1
  119. package/dist/cjs/components/header/Header_BACKUP_73021.d.ts +0 -33
  120. package/dist/cjs/components/header/Header_BACKUP_73021.js +0 -393
  121. package/dist/cjs/components/header/Header_BACKUP_73021.js.map +0 -1
  122. package/dist/cjs/components/header/Header_BASE_73021.d.ts +0 -29
  123. package/dist/cjs/components/header/Header_BASE_73021.js +0 -376
  124. package/dist/cjs/components/header/Header_BASE_73021.js.map +0 -1
  125. package/dist/cjs/components/header/Header_LOCAL_73021.d.ts +0 -33
  126. package/dist/cjs/components/header/Header_LOCAL_73021.js +0 -382
  127. package/dist/cjs/components/header/Header_LOCAL_73021.js.map +0 -1
  128. package/dist/cjs/components/header/Header_REMOTE_73021.d.ts +0 -30
  129. package/dist/cjs/components/header/Header_REMOTE_73021.js +0 -386
  130. package/dist/cjs/components/header/Header_REMOTE_73021.js.map +0 -1
  131. package/dist/esm/components/app-wrapper/AppWrapper_BACKUP_73190.d.ts +0 -27
  132. package/dist/esm/components/app-wrapper/AppWrapper_BACKUP_73190.js +0 -194
  133. package/dist/esm/components/app-wrapper/AppWrapper_BACKUP_73190.js.map +0 -1
  134. package/dist/esm/components/app-wrapper/AppWrapper_BASE_73190.d.ts +0 -28
  135. package/dist/esm/components/app-wrapper/AppWrapper_BASE_73190.js +0 -208
  136. package/dist/esm/components/app-wrapper/AppWrapper_BASE_73190.js.map +0 -1
  137. package/dist/esm/components/app-wrapper/AppWrapper_LOCAL_73190.d.ts +0 -27
  138. package/dist/esm/components/app-wrapper/AppWrapper_LOCAL_73190.js +0 -194
  139. package/dist/esm/components/app-wrapper/AppWrapper_LOCAL_73190.js.map +0 -1
  140. package/dist/esm/components/app-wrapper/AppWrapper_REMOTE_73190.d.ts +0 -28
  141. package/dist/esm/components/app-wrapper/AppWrapper_REMOTE_73190.js +0 -204
  142. package/dist/esm/components/app-wrapper/AppWrapper_REMOTE_73190.js.map +0 -1
  143. package/dist/esm/components/error-message-preview/ErrorMessagePreview.d.ts +0 -15
  144. package/dist/esm/components/error-message-preview/ErrorMessagePreview.js +0 -35
  145. package/dist/esm/components/error-message-preview/ErrorMessagePreview.js.map +0 -1
  146. package/dist/esm/components/header/Header_BACKUP_73021.d.ts +0 -33
  147. package/dist/esm/components/header/Header_BACKUP_73021.js +0 -336
  148. package/dist/esm/components/header/Header_BACKUP_73021.js.map +0 -1
  149. package/dist/esm/components/header/Header_BASE_73021.d.ts +0 -29
  150. package/dist/esm/components/header/Header_BASE_73021.js +0 -322
  151. package/dist/esm/components/header/Header_BASE_73021.js.map +0 -1
  152. package/dist/esm/components/header/Header_LOCAL_73021.d.ts +0 -33
  153. package/dist/esm/components/header/Header_LOCAL_73021.js +0 -328
  154. package/dist/esm/components/header/Header_LOCAL_73021.js.map +0 -1
  155. package/dist/esm/components/header/Header_REMOTE_73021.d.ts +0 -30
  156. package/dist/esm/components/header/Header_REMOTE_73021.js +0 -329
  157. package/dist/esm/components/header/Header_REMOTE_73021.js.map +0 -1
@@ -0,0 +1,40 @@
1
+ import * as React from 'react';
2
+ import TextField from '../text-field/TextField';
3
+ import { connect } from 'react-redux';
4
+ import { bindActionCreators } from 'redux';
5
+ import { updateStoryFilter } from '../../redux/actions/story-filter';
6
+
7
+ interface IStoryTableNameFilterProps {
8
+ storyFilter: any;
9
+ updateStoryFilter: (filters: any) => any;
10
+ }
11
+
12
+ class StoryTableNameFilter extends React.PureComponent<IStoryTableNameFilterProps> {
13
+ public render = (): JSX.Element => {
14
+ const { storyFilter } = this.props;
15
+
16
+ return (
17
+ <TextField
18
+ className='story-name'
19
+ focusOnMount
20
+ value={storyFilter}
21
+ onChange={(n) => this.props.updateStoryFilter({ name: n })}
22
+ />
23
+ );
24
+ };
25
+ }
26
+
27
+ const mapDispatchToProps = (dispatch): any => {
28
+ return bindActionCreators({ updateStoryFilter }, dispatch);
29
+ };
30
+
31
+ const mapStateToProps = (state): any => {
32
+ return { storyFilter: state.storyFilter.name };
33
+ };
34
+
35
+ const StoryTableNameFilterMemoized = connect(
36
+ mapStateToProps,
37
+ mapDispatchToProps
38
+ )(React.memo(StoryTableNameFilter));
39
+
40
+ export default StoryTableNameFilterMemoized;
@@ -11,6 +11,7 @@ interface ICardProps {
11
11
  onOpen?: (e: any) => any;
12
12
  onClose?: (e: any) => any;
13
13
  onToggle?: (toggle: boolean) => any;
14
+ buttons?: any[];
14
15
  }
15
16
 
16
17
  interface ICardState {
@@ -97,9 +98,7 @@ class Card extends React.PureComponent<ICardProps, ICardState> {
97
98
 
98
99
  return (
99
100
  <div className={`card ${openClass} ${collapsableClass} ${styleClass}`}>
100
- <div
101
- className='card-header'
102
- onClick={this.evtHandlers.toggleOpen}>
101
+ <div className='card-header'>
103
102
  {this.renderTitle(styleClass)}
104
103
  {this.renderButtons()}
105
104
  </div>
@@ -109,21 +108,36 @@ class Card extends React.PureComponent<ICardProps, ICardState> {
109
108
  }
110
109
 
111
110
  public renderButtons() {
112
- const { collapsable } = this.props;
111
+ const { collapsable, buttons } = this.props;
113
112
  const { open } = this.state;
114
113
  const buttonIcon = open ? ICON_CARET_UP : ICON_CARET_DOWN;
115
114
 
115
+ let buttonArray: JSX.Element[];
116
+
117
+ const toggleBtn = (
118
+ <Button
119
+ key='toggleOpen'
120
+ style='subtle'
121
+ onClick={(e) => this.toggleOpen(e)}>
122
+ {buttonIcon}
123
+ </Button>
124
+ );
125
+
126
+ if (buttons && buttons.length > 0) {
127
+ buttonArray = buttons.map((button) => {
128
+ return button;
129
+ });
130
+ }
131
+
116
132
  if (collapsable) {
117
- return (
118
- <div className='header-buttons'>
119
- <Button
120
- style='subtle'
121
- onClick={this.evtHandlers.toggleOpen}>
122
- {buttonIcon}
123
- </Button>
124
- </div>
125
- );
133
+ if (buttonArray && buttonArray.length > 0) {
134
+ buttonArray.push(toggleBtn);
135
+ } else {
136
+ buttonArray = [toggleBtn];
137
+ }
126
138
  }
139
+
140
+ return <div className='header-buttons'>{buttonArray}</div>;
127
141
  }
128
142
  }
129
143
 
@@ -127,18 +127,14 @@ class ColorField extends React.PureComponent<IColorFieldProps, IColorFieldState>
127
127
  />
128
128
  ) : null;
129
129
 
130
- let swatchStyle;
131
- if (value === 'transparent' || value === 'rgba(0,0,0,0)') {
132
- swatchStyle = {
133
- background: this.transparentBg,
134
- border: '1px solid #1d1d1d',
135
- boxSizing: 'border-box'
136
- };
137
- } else {
138
- swatchStyle = {
139
- backgroundColor: value
140
- };
141
- }
130
+ const swatchStyle = {
131
+ backgroundColor: value
132
+ };
133
+
134
+ const transparentBg = {
135
+ background: this.transparentBg,
136
+ height: '20px'
137
+ };
142
138
 
143
139
  return (
144
140
  <FieldWrapper
@@ -150,11 +146,14 @@ class ColorField extends React.PureComponent<IColorFieldProps, IColorFieldState>
150
146
  labelPosition={labelPosition}
151
147
  labelWidth={labelWidth}
152
148
  width={width}>
153
- <div
154
- className='swatch'
155
- style={swatchStyle}
156
- onClick={(e) => this.togglePicker(e)}
157
- />
149
+ <div style={transparentBg}>
150
+ <div
151
+ className='swatch'
152
+ style={swatchStyle}
153
+ onClick={(e) => this.togglePicker(e)}
154
+ />
155
+ </div>
156
+
158
157
  <div
159
158
  className={`picker picker-${pickerPos}`}
160
159
  ref={this.picker}>
@@ -82,14 +82,16 @@ interface IDataTableProps {
82
82
 
83
83
  // controlled selection props
84
84
  highlightBy?: any;
85
- onRowClick?: (row) => void;
86
- onRowDoubleClick?: (row) => void;
85
+ onRowClick?: (row, shiftKey?) => void;
86
+ onRowDoubleClick?: (row, shiftKey?) => void;
87
87
 
88
88
  renderPivotComponent?: (row) => JSX.Element;
89
89
 
90
90
  disableKeyScroll?: boolean;
91
91
 
92
92
  expandTags?: boolean;
93
+
94
+ keyboardNav?: boolean;
93
95
  }
94
96
 
95
97
  const processColumnData = (freshColumns): any[] => {
@@ -119,7 +121,7 @@ const DataTable: React.FC<IDataTableProps> = (props: IDataTableProps) => {
119
121
  const [didMount, setDidMount] = React.useState(false);
120
122
  const [data, setData] = React.useState([]);
121
123
  const [columns, setColumns] = React.useState([]);
122
-
124
+ const [selectedRowId, setSelectedRowId] = React.useState<number>(null);
123
125
  const manualPagination: boolean =
124
126
  Number.isInteger(props.currentPage) && typeof props.onPage === 'function';
125
127
  const manualSortBy: boolean =
@@ -205,6 +207,8 @@ const DataTable: React.FC<IDataTableProps> = (props: IDataTableProps) => {
205
207
  React.useEffect(() => {
206
208
  if (Array.isArray(props.data)) {
207
209
  setData(props.data);
210
+ setSelectedRowId(null);
211
+ scrollToTop();
208
212
  }
209
213
  }, [props.data]);
210
214
 
@@ -226,6 +230,68 @@ const DataTable: React.FC<IDataTableProps> = (props: IDataTableProps) => {
226
230
  }
227
231
  }, [sortBy]);
228
232
 
233
+ const getRowElem = () => {
234
+ return document.getElementsByClassName('ip-table-row selected keyboardNav')[0];
235
+ };
236
+
237
+ const getBodyEle = () => {
238
+ return document.querySelector('tbody.ip-table-body.keyboardNav');
239
+ };
240
+
241
+ const scrollIntoView = () => {
242
+ getRowElem().scrollIntoView({ behavior: 'smooth', block: 'center' });
243
+ };
244
+
245
+ const scrollToTop = () => {
246
+ if (getBodyEle()) {
247
+ getBodyEle().scrollTo({ top: 0, behavior: 'smooth' });
248
+ }
249
+ };
250
+
251
+ const scrollToBottom = () => {
252
+ const y = getRowElem().scrollHeight * rowData.length;
253
+ getBodyEle().scrollTo({ top: y, behavior: 'smooth' });
254
+ };
255
+
256
+ const rowSelector = (e) => {
257
+ e.preventDefault();
258
+ e.stopPropagation();
259
+ let rowId = 0;
260
+ const maxRowId = rowData.length - 1;
261
+ if (e.code === 'ArrowUp') {
262
+ if (selectedRowId === 0 || selectedRowId === null) {
263
+ setSelectedRowId(maxRowId);
264
+ scrollToBottom();
265
+ }
266
+ if (selectedRowId !== 0 && selectedRowId !== null) {
267
+ setSelectedRowId(selectedRowId - 1);
268
+ scrollIntoView();
269
+ }
270
+ }
271
+
272
+ if (e.code === 'ArrowDown') {
273
+ if (selectedRowId === null) {
274
+ setSelectedRowId(0);
275
+ } else {
276
+ rowId = selectedRowId === maxRowId ? 0 : selectedRowId + 1;
277
+ setSelectedRowId(rowId);
278
+ if (rowId === 0) {
279
+ scrollToTop();
280
+ } else {
281
+ scrollIntoView();
282
+ }
283
+ }
284
+ }
285
+
286
+ if (
287
+ e.code === 'Enter' &&
288
+ typeof props.onRowClick === 'function' &&
289
+ selectedRowId !== null
290
+ ) {
291
+ props.onRowClick(rows[selectedRowId], e.shiftKey);
292
+ }
293
+ };
294
+
229
295
  return (
230
296
  <section
231
297
  ref={wrapperRef}
@@ -246,7 +312,17 @@ const DataTable: React.FC<IDataTableProps> = (props: IDataTableProps) => {
246
312
  <React.Fragment key='head-fragment'>
247
313
  <tr
248
314
  {...headerGroup.getHeaderGroupProps()}
249
- className='ip-table-head-row'>
315
+ className='ip-table-head-row'
316
+ onKeyDown={(e) => {
317
+ if (
318
+ (e.code === 'ArrowUp' ||
319
+ e.code === 'ArrowDown' ||
320
+ e.code === 'Enter') &&
321
+ props.keyboardNav
322
+ ) {
323
+ rowSelector(e);
324
+ }
325
+ }}>
250
326
  {headerGroup.headers.map((column) => {
251
327
  const searchable: boolean = column.hasOwnProperty('Search');
252
328
  const toggleProps: any = column.getSortByToggleProps();
@@ -326,7 +402,7 @@ const DataTable: React.FC<IDataTableProps> = (props: IDataTableProps) => {
326
402
 
327
403
  <tbody
328
404
  {...getTableBodyProps()}
329
- className='ip-table-body'>
405
+ className={`ip-table-body ${props.keyboardNav ? 'keyboardNav' : ''}`}>
330
406
  {rowData.map((row, i) => {
331
407
  let selectedClass: string = '';
332
408
  let activeRef: any;
@@ -351,30 +427,43 @@ const DataTable: React.FC<IDataTableProps> = (props: IDataTableProps) => {
351
427
 
352
428
  prepareRow(row);
353
429
 
430
+ if (i === selectedRowId) {
431
+ selectedClass = 'selected';
432
+ }
433
+
354
434
  const rowProps = row.getRowProps();
355
- rowProps.className = `ip-table-row ${selectedClass}`;
435
+ rowProps.className = `ip-table-row ${selectedClass} ${
436
+ props.keyboardNav ? 'keyboardNav' : ''
437
+ }`;
356
438
  rowProps.onClick = (e) => {
357
- const onClick = () => {
439
+ const onClick = (shift: boolean) => {
358
440
  if (typeof props.onRowClick === 'function') {
359
- props.onRowClick(row);
441
+ props.onRowClick(row, shift);
360
442
  }
361
443
  };
362
444
 
363
445
  if (!doubleClickEnabled) {
364
- onClick();
446
+ onClick(e.shiftKey);
365
447
  }
366
448
 
367
449
  if (e.detail === 1 && doubleClickEnabled) {
368
- doubleClickTimeout = window.setTimeout(onClick, 200);
450
+ doubleClickTimeout = window.setTimeout(
451
+ () => onClick(e.shiftKey),
452
+ 200
453
+ );
369
454
  }
370
455
  };
371
456
  rowProps.onDoubleClick = (e) => {
372
457
  clearTimeout(doubleClickTimeout);
373
458
  if (doubleClickEnabled) {
374
- props.onRowDoubleClick(row);
459
+ props.onRowDoubleClick(row, e.shiftKey);
375
460
  }
376
461
  };
377
462
 
463
+ rowProps.onMouseMove = () => {
464
+ setSelectedRowId(i);
465
+ };
466
+
378
467
  const rowContent = row.cells.map((cell) => (
379
468
  <td
380
469
  {...cell.getCellProps()}
@@ -386,7 +475,6 @@ const DataTable: React.FC<IDataTableProps> = (props: IDataTableProps) => {
386
475
  ));
387
476
  const rowId = row?.original?.id || i;
388
477
  const rowKey = `row-${rowId}`;
389
-
390
478
  const expanded = props.expandTags ? props.expandTags : row.isExpanded;
391
479
  return (
392
480
  <React.Fragment key={rowKey}>
@@ -26,102 +26,171 @@ const Paginator: React.FC<any> = ({
26
26
  setPageSize,
27
27
  itemsPerPage,
28
28
  onItemsPerPage
29
- }) => (
30
- <section className='ip-table-pagination'>
31
- <span>
32
- <Button
33
- style='subtle'
34
- size='small'
35
- tooltip='Go to first page'
36
- disabled={!canPreviousPage}
37
- onClick={() => gotoPage(1, pageSize)}>
38
- {ICON_ANGLE_DOUBLE_LEFT}
39
- </Button>
40
- <Button
41
- style='subtle'
42
- size='small'
43
- tooltip='Go to previous page'
44
- disabled={!canPreviousPage}
45
- onClick={() => previousPage()}>
46
- {ICON_ANGLE_LEFT}
47
- </Button>
48
- <Button
49
- style='subtle'
50
- size='small'
51
- tooltip='Go to next page'
52
- disabled={!canNextPage}
53
- onClick={() => nextPage()}>
54
- {ICON_ANGLE_RIGHT}
55
- </Button>
56
- <Button
57
- style='subtle'
58
- size='small'
59
- tooltip='Go to last page'
60
- disabled={!canNextPage}
61
- onClick={() => gotoPage(pageCount, pageSize)}>
62
- {ICON_ANGLE_DOUBLE_RIGHT}
63
- </Button>
64
- &nbsp;&nbsp;
29
+ }) => {
30
+ const [getPageIndex, setPageIndex] = React.useState<number>(pageIndex);
31
+ const [getItemsPerPage, setItemsPerPage] = React.useState<number>(itemsPerPage);
32
+ const [getPageCount, setPageCount] = React.useState<number>(pageCount);
33
+ const [inputPageIndex, setInputPageIndex] = React.useState<string>('');
34
+ const [inputItemsPerPage, setInputItemsPerPage] = React.useState<string>('');
35
+
36
+ React.useEffect(() => {
37
+ if (pageCount === 0) {
38
+ setPageCount(1);
39
+ } else {
40
+ setPageCount(pageCount);
41
+ }
42
+ }, [pageCount]);
43
+
44
+ React.useEffect(() => {
45
+ if (pageIndex !== getPageIndex) {
46
+ setPageIndex(pageIndex);
47
+ setInputPageIndex('');
48
+ }
49
+
50
+ if (itemsPerPage !== getItemsPerPage) {
51
+ setItemsPerPage(itemsPerPage);
52
+ setInputItemsPerPage('');
53
+ }
54
+ }, [pageIndex, itemsPerPage]);
55
+
56
+ const onItemsPerPageBlur = () => {
57
+ clearTimeout(textInputTimeout);
58
+ if (inputItemsPerPage !== '') {
59
+ onItemsPerPage(inputItemsPerPage);
60
+ }
61
+ };
62
+
63
+ const onGoToPageBlur = () => {
64
+ clearTimeout(textInputTimeout);
65
+ if (inputPageIndex !== '') {
66
+ gotoPage(inputPageIndex, pageSize);
67
+ }
68
+ };
69
+
70
+ const onItemsPerPageKeyDown = (e) => {
71
+ if (e.key === 'Enter' && inputItemsPerPage !== '') {
72
+ clearTimeout(textInputTimeout);
73
+ onItemsPerPage(inputItemsPerPage);
74
+ }
75
+ };
76
+
77
+ const onGoToPageKeyDown = (e) => {
78
+ if (e.key === 'Enter' && inputPageIndex !== '') {
79
+ clearTimeout(textInputTimeout);
80
+ gotoPage(inputPageIndex, pageSize);
81
+ }
82
+ };
83
+
84
+ return (
85
+ <section className='ip-table-pagination'>
65
86
  <span>
66
- {copy.table.page}&nbsp;&nbsp;
67
- <strong>
68
- {pageIndex} of {pageCount}
69
- </strong>
87
+ <Button
88
+ style='subtle'
89
+ size='small'
90
+ tooltip='Go to first page'
91
+ disabled={!canPreviousPage}
92
+ onClick={() => gotoPage(1, pageSize)}>
93
+ {ICON_ANGLE_DOUBLE_LEFT}
94
+ </Button>
95
+ <Button
96
+ style='subtle'
97
+ size='small'
98
+ tooltip='Go to previous page'
99
+ disabled={!canPreviousPage}
100
+ onClick={() => previousPage()}>
101
+ {ICON_ANGLE_LEFT}
102
+ </Button>
103
+ <Button
104
+ style='subtle'
105
+ size='small'
106
+ tooltip='Go to next page'
107
+ disabled={!canNextPage}
108
+ onClick={() => nextPage()}>
109
+ {ICON_ANGLE_RIGHT}
110
+ </Button>
111
+ <Button
112
+ style='subtle'
113
+ size='small'
114
+ tooltip='Go to last page'
115
+ disabled={!canNextPage}
116
+ onClick={() => gotoPage(getPageCount, pageSize)}>
117
+ {ICON_ANGLE_DOUBLE_RIGHT}
118
+ </Button>
70
119
  &nbsp;&nbsp;
120
+ <span>
121
+ {copy.table.page}&nbsp;&nbsp;
122
+ <strong>
123
+ {getPageIndex} of {getPageCount}
124
+ </strong>
125
+ &nbsp;&nbsp;
126
+ </span>
127
+ <span>
128
+ {copy.table.goToPage}&nbsp;&nbsp;
129
+ <input
130
+ className='paginator-input'
131
+ type='number'
132
+ placeholder={getPageIndex.toString()}
133
+ value={inputPageIndex}
134
+ onChange={(e) => {
135
+ const input = e.target.value;
136
+ const inputNum = Number(input);
137
+ let next: number;
138
+
139
+ clearTimeout(textInputTimeout);
140
+ setInputPageIndex(input);
141
+ if (!input || inputNum < 1 || inputNum > getPageCount) {
142
+ return;
143
+ }
144
+
145
+ if (inputNum >= 1 && inputNum <= getPageCount) {
146
+ next = inputNum;
147
+ }
148
+
149
+ textInputTimeout = window.setTimeout(
150
+ () => gotoPage(next, pageSize),
151
+ 1000
152
+ );
153
+ }}
154
+ onBlur={() => onGoToPageBlur()}
155
+ onKeyDown={(e) => onGoToPageKeyDown(e)}
156
+ />
157
+ </span>
158
+ &nbsp;&nbsp;
159
+ <span>
160
+ {copy.table.itemsPerPage}&nbsp;&nbsp;
161
+ <input
162
+ className='paginator-input'
163
+ type='number'
164
+ placeholder={getItemsPerPage.toString()}
165
+ value={inputItemsPerPage}
166
+ onChange={(e) => {
167
+ const input = e.target.value;
168
+ const inputNum = Number(input);
169
+
170
+ clearTimeout(textInputTimeout);
171
+
172
+ setInputItemsPerPage(input);
173
+
174
+ if (!input || inputNum < 1) {
175
+ return;
176
+ }
177
+
178
+ textInputTimeout = window.setTimeout(
179
+ () => onItemsPerPage(inputNum),
180
+ 1000
181
+ );
182
+ }}
183
+ onBlur={() => onItemsPerPageBlur()}
184
+ onKeyDown={(e) => onItemsPerPageKeyDown(e)}
185
+ />
186
+ </span>
71
187
  </span>
72
- <span>
73
- {copy.table.goToPage}&nbsp;&nbsp;
74
- <input
75
- className='paginator-input'
76
- type='number'
77
- placeholder={pageIndex}
78
- onChange={(e) => {
79
- const input = e.target.value;
80
- const inputNum = Number(input);
81
- let next: number;
82
-
83
- clearTimeout(textInputTimeout);
84
-
85
- if (!input || inputNum < 1 || inputNum > pageCount) {
86
- return;
87
- }
88
-
89
- if (inputNum >= 1 && inputNum <= pageCount) {
90
- next = inputNum;
91
- }
92
-
93
- textInputTimeout = window.setTimeout(() => gotoPage(next, pageSize), 300);
94
- }}
95
- />
96
- </span>
97
- &nbsp;&nbsp;
98
- <span>
99
- {copy.table.itemsPerPage}&nbsp;&nbsp;
100
- <input
101
- className='paginator-input'
102
- type='number'
103
- placeholder={itemsPerPage}
104
- min={1}
105
- onChange={(e) => {
106
- const input = e.target.value;
107
- const inputNum = Number(input);
108
-
109
- clearTimeout(textInputTimeout);
110
-
111
- if (!input || inputNum < 1) {
112
- return;
113
- }
114
-
115
- textInputTimeout = window.setTimeout(() => onItemsPerPage(inputNum), 300);
116
- }}
117
- />
118
- </span>
119
- </span>
120
188
 
121
- <span className='total-assets'>
122
- {copy.table.total}&nbsp;&nbsp;<strong>{totalItems || 0}</strong>
123
- </span>
124
- </section>
125
- );
189
+ <span className='total-assets'>
190
+ {copy.table.total}&nbsp;&nbsp;<strong>{totalItems || 0}</strong>
191
+ </span>
192
+ </section>
193
+ );
194
+ };
126
195
 
127
196
  export default Paginator;
@@ -19,6 +19,7 @@ import Select, { createFilter } from 'react-select';
19
19
  import { setAccessData } from '../../redux/actions/access';
20
20
  import { bindActionCreators } from 'redux';
21
21
  import { StoryTableTotalRendersCell } from '../assets/StoryTableTotalRendersCell';
22
+ import StoryTableNameFilter from '../assets/StoryTableNameFilter';
22
23
 
23
24
  export interface IHeaderProps {
24
25
  email?: string;
@@ -38,6 +39,7 @@ export interface IHeaderProps {
38
39
  hideDocs?: boolean;
39
40
  showFTLogo?: boolean;
40
41
  access: any;
42
+ storyFilter: any;
41
43
  }
42
44
 
43
45
  export interface IHeaderState {
@@ -290,6 +292,7 @@ class ImposiumHeader extends React.PureComponent<IHeaderProps, IHeaderState> {
290
292
  Header: 'Name',
291
293
  width: 115,
292
294
  minWidth: 115,
295
+ Search: () => <StoryTableNameFilter />,
293
296
  disableSortBy: false
294
297
  },
295
298
  {
@@ -533,12 +536,30 @@ class ImposiumHeader extends React.PureComponent<IHeaderProps, IHeaderState> {
533
536
  ? [{ id: order, desc: orderDirection === 'desc' }]
534
537
  : undefined;
535
538
 
536
- const sortedStories = _.orderBy(
539
+ let sortedStories = _.orderBy(
537
540
  activeOrganizationBlob.stories,
538
541
  ['date_modified'],
539
542
  ['desc']
540
543
  );
541
544
 
545
+ if (this.props.storyFilter && this.props.storyFilter?.name) {
546
+ const storyFilter = this.props.storyFilter.toLowerCase();
547
+
548
+ const sortByName = sortedStories.filter((stories) =>
549
+ stories.name.toLowerCase().includes(storyFilter)
550
+ );
551
+ if (sortByName.length > 0) {
552
+ sortedStories = sortByName;
553
+ } else {
554
+ const sortById = sortedStories.filter((stories) =>
555
+ stories.id.includes(storyFilter)
556
+ );
557
+ if (sortById.length > 0) {
558
+ sortedStories = sortById;
559
+ }
560
+ }
561
+ }
562
+
542
563
  storyMenuInner = (
543
564
  <DataTable
544
565
  columns={this.getStoriesColumns()}
@@ -548,6 +569,7 @@ class ImposiumHeader extends React.PureComponent<IHeaderProps, IHeaderState> {
548
569
  itemsPerPage={activeOrganizationBlob.stories.length}
549
570
  hidePaginator={true}
550
571
  onRowClick={this.changeStory}
572
+ keyboardNav={true}
551
573
  />
552
574
  );
553
575
  }
@@ -682,7 +704,8 @@ const mapStateToProps = (state): any => {
682
704
  return {
683
705
  auth: state.auth,
684
706
  story: state.story,
685
- access: state.access
707
+ access: state.access,
708
+ storyFilter: state.storyFilter
686
709
  };
687
710
  };
688
711