@imposium-hub/components 2.5.11-1 → 2.5.11-11

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 (98) hide show
  1. package/dist/cjs/components/app-wrapper/AppWrapper.js +5 -2
  2. package/dist/cjs/components/app-wrapper/AppWrapper.js.map +1 -1
  3. package/dist/cjs/components/assets/AssetsTableNameCell.js +1 -2
  4. package/dist/cjs/components/assets/AssetsTableNameCell.js.map +1 -1
  5. package/dist/cjs/components/assets/StoryTableNameFilter.d.ts +2 -0
  6. package/dist/cjs/components/assets/StoryTableNameFilter.js +94 -0
  7. package/dist/cjs/components/assets/StoryTableNameFilter.js.map +1 -0
  8. package/dist/cjs/components/color-field/ColorField.js +9 -14
  9. package/dist/cjs/components/color-field/ColorField.js.map +1 -1
  10. package/dist/cjs/components/confirm-modal/ConfirmModal.d.ts +8 -0
  11. package/dist/cjs/components/confirm-modal/ConfirmModal.js +21 -8
  12. package/dist/cjs/components/confirm-modal/ConfirmModal.js.map +1 -1
  13. package/dist/cjs/components/data-table/DataTable.d.ts +1 -0
  14. package/dist/cjs/components/data-table/DataTable.js +75 -5
  15. package/dist/cjs/components/data-table/DataTable.js.map +1 -1
  16. package/dist/cjs/components/data-table/Paginator.js +35 -14
  17. package/dist/cjs/components/data-table/Paginator.js.map +1 -1
  18. package/dist/cjs/components/header/Header.d.ts +1 -0
  19. package/dist/cjs/components/header/Header.js +22 -2
  20. package/dist/cjs/components/header/Header.js.map +1 -1
  21. package/dist/cjs/components/story-previewer/StoryPreviewer.js +11 -1
  22. package/dist/cjs/components/story-previewer/StoryPreviewer.js.map +1 -1
  23. package/dist/cjs/constants/variables.d.ts +3 -0
  24. package/dist/cjs/constants/variables.js +27 -2
  25. package/dist/cjs/constants/variables.js.map +1 -1
  26. package/dist/cjs/index.d.ts +5 -1
  27. package/dist/cjs/index.js +12 -2
  28. package/dist/cjs/index.js.map +1 -1
  29. package/dist/cjs/redux/actions/asset-list.js +33 -42
  30. package/dist/cjs/redux/actions/asset-list.js.map +1 -1
  31. package/dist/cjs/redux/actions/asset-uploads.js +10 -0
  32. package/dist/cjs/redux/actions/asset-uploads.js.map +1 -1
  33. package/dist/cjs/redux/actions/story-filter.d.ts +4 -0
  34. package/dist/cjs/redux/actions/story-filter.js +18 -0
  35. package/dist/cjs/redux/actions/story-filter.js.map +1 -0
  36. package/dist/cjs/redux/reducers/asset-uploads.js.map +1 -1
  37. package/dist/cjs/redux/reducers/story-filter.d.ts +2 -0
  38. package/dist/cjs/redux/reducers/story-filter.js +33 -0
  39. package/dist/cjs/redux/reducers/story-filter.js.map +1 -0
  40. package/dist/esm/components/app-wrapper/AppWrapper.js +5 -2
  41. package/dist/esm/components/app-wrapper/AppWrapper.js.map +1 -1
  42. package/dist/esm/components/assets/AssetsTableNameCell.js +1 -2
  43. package/dist/esm/components/assets/AssetsTableNameCell.js.map +1 -1
  44. package/dist/esm/components/assets/StoryTableNameFilter.d.ts +2 -0
  45. package/dist/esm/components/assets/StoryTableNameFilter.js +20 -0
  46. package/dist/esm/components/assets/StoryTableNameFilter.js.map +1 -0
  47. package/dist/esm/components/color-field/ColorField.js +9 -14
  48. package/dist/esm/components/color-field/ColorField.js.map +1 -1
  49. package/dist/esm/components/confirm-modal/ConfirmModal.d.ts +8 -0
  50. package/dist/esm/components/confirm-modal/ConfirmModal.js +21 -8
  51. package/dist/esm/components/confirm-modal/ConfirmModal.js.map +1 -1
  52. package/dist/esm/components/data-table/DataTable.d.ts +1 -0
  53. package/dist/esm/components/data-table/DataTable.js +73 -3
  54. package/dist/esm/components/data-table/DataTable.js.map +1 -1
  55. package/dist/esm/components/data-table/Paginator.js +35 -14
  56. package/dist/esm/components/data-table/Paginator.js.map +1 -1
  57. package/dist/esm/components/header/Header.d.ts +1 -0
  58. package/dist/esm/components/header/Header.js +19 -3
  59. package/dist/esm/components/header/Header.js.map +1 -1
  60. package/dist/esm/components/story-previewer/StoryPreviewer.js +12 -2
  61. package/dist/esm/components/story-previewer/StoryPreviewer.js.map +1 -1
  62. package/dist/esm/constants/variables.d.ts +3 -0
  63. package/dist/esm/constants/variables.js +25 -1
  64. package/dist/esm/constants/variables.js.map +1 -1
  65. package/dist/esm/index.d.ts +5 -1
  66. package/dist/esm/index.js +5 -1
  67. package/dist/esm/index.js.map +1 -1
  68. package/dist/esm/redux/actions/asset-list.js +33 -42
  69. package/dist/esm/redux/actions/asset-list.js.map +1 -1
  70. package/dist/esm/redux/actions/asset-uploads.js +10 -0
  71. package/dist/esm/redux/actions/asset-uploads.js.map +1 -1
  72. package/dist/esm/redux/actions/story-filter.d.ts +4 -0
  73. package/dist/esm/redux/actions/story-filter.js +13 -0
  74. package/dist/esm/redux/actions/story-filter.js.map +1 -0
  75. package/dist/esm/redux/reducers/asset-uploads.js.map +1 -1
  76. package/dist/esm/redux/reducers/story-filter.d.ts +2 -0
  77. package/dist/esm/redux/reducers/story-filter.js +16 -0
  78. package/dist/esm/redux/reducers/story-filter.js.map +1 -0
  79. package/dist/styles.css +0 -3
  80. package/dist/styles.less +0 -5
  81. package/less/components/header.less +0 -5
  82. package/package.json +1 -1
  83. package/src/components/app-wrapper/AppWrapper.tsx +3 -4
  84. package/src/components/assets/AssetsTableNameCell.tsx +1 -10
  85. package/src/components/assets/StoryTableNameFilter.tsx +40 -0
  86. package/src/components/color-field/ColorField.tsx +16 -17
  87. package/src/components/confirm-modal/ConfirmModal.tsx +131 -0
  88. package/src/components/data-table/DataTable.tsx +90 -5
  89. package/src/components/data-table/Paginator.tsx +37 -15
  90. package/src/components/header/Header.tsx +25 -2
  91. package/src/components/story-previewer/StoryPreviewer.tsx +28 -4
  92. package/src/constants/variables.ts +27 -1
  93. package/src/index.ts +11 -1
  94. package/src/redux/actions/asset-list.ts +36 -44
  95. package/src/redux/actions/asset-uploads.ts +9 -0
  96. package/src/redux/actions/story-filter.ts +15 -0
  97. package/src/redux/reducers/asset-uploads.ts +0 -2
  98. package/src/redux/reducers/story-filter.ts +18 -0
@@ -0,0 +1,131 @@
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import Modal from '../modal/Modal';
4
+ import Button from '../button/Button';
5
+ import { confirm as copy } from '../../constants/copy';
6
+ import Section from '../section/Section';
7
+
8
+ export interface IConfirmModalProps {
9
+ onYes: () => void;
10
+ onNo?: () => void;
11
+ title: string;
12
+ yesLabel?: string;
13
+ noLabel?: string;
14
+ showCancel?: boolean;
15
+ }
16
+
17
+ export const ConfirmModal = () => {
18
+ const [props, setProps] = useState<IConfirmModalProps>(null);
19
+ const [isOpen, setIsOpen] = useState<boolean>(false);
20
+
21
+ const onOpen = (event) => {
22
+ setProps({
23
+ ...event.detail
24
+ });
25
+ setIsOpen(true);
26
+ };
27
+
28
+ const onClose = () => setIsOpen(false);
29
+
30
+ const onYesHandler = () => {
31
+ props.onYes();
32
+ setIsOpen(false);
33
+ };
34
+
35
+ const onNoHandler = () => {
36
+ props.onNo();
37
+ setIsOpen(false);
38
+ };
39
+
40
+ const onYes = useCallback(() => onYesHandler(), [isOpen]);
41
+
42
+ const onNo = useCallback(() => {
43
+ if (props.onNo) {
44
+ onNoHandler();
45
+ } else {
46
+ onClose();
47
+ }
48
+ }, [isOpen]);
49
+
50
+ const onKeyDown = useCallback(
51
+ (e) => {
52
+ if (e.key === 'Enter') {
53
+ e.preventDefault();
54
+ onYesHandler();
55
+ }
56
+ },
57
+ [isOpen]
58
+ );
59
+
60
+ useEffect(() => {
61
+ window.addEventListener('openconfirmmodal', onOpen);
62
+ return () => {
63
+ window.removeEventListener('openconfirmmodal', onOpen);
64
+ };
65
+ }, []);
66
+
67
+ useEffect(() => {
68
+ if (isOpen) {
69
+ document.addEventListener('keypress', onKeyDown);
70
+ } else {
71
+ document.removeEventListener('keypress', onKeyDown);
72
+ }
73
+ return () => {
74
+ document.removeEventListener('keypress', onKeyDown);
75
+ };
76
+ }, [isOpen, onKeyDown]);
77
+
78
+ const { cancel, yes, no } = copy;
79
+ const noLabel = props?.noLabel ? props.noLabel : no;
80
+ const yesLabel = props?.yesLabel ? props.yesLabel : yes;
81
+
82
+ const modal = isOpen && (
83
+ <Modal
84
+ onRequestClose={onClose}
85
+ wrapperStyle={{
86
+ left: '0px',
87
+ width: '100%'
88
+ }}
89
+ style={{
90
+ width: '400px',
91
+ height: '14%',
92
+ top: 'calc(50% - 150px)',
93
+ left: 'calc((100% - 400px) / 2)'
94
+ }}
95
+ isOpen={true}>
96
+ <Section>
97
+ <div className='confirm-modal'>
98
+ <p>{props.title}</p>
99
+ <div className='confirm-buttons'>
100
+ {props.showCancel ? (
101
+ <Button
102
+ onClick={onClose}
103
+ size='large'
104
+ color='default'>
105
+ {cancel}
106
+ </Button>
107
+ ) : null}
108
+ <Button
109
+ onClick={onNo}
110
+ size='large'
111
+ color='default'>
112
+ {noLabel}
113
+ </Button>
114
+ <Button
115
+ onClick={onYes}
116
+ size='large'
117
+ style='bold'
118
+ color='primary'>
119
+ {yesLabel}
120
+ </Button>
121
+ </div>
122
+ </div>
123
+ </Section>
124
+ </Modal>
125
+ );
126
+
127
+ const PortalContextComponent = () =>
128
+ ReactDOM.createPortal(modal, document.querySelector('#react-root'));
129
+
130
+ return <PortalContextComponent />;
131
+ };
@@ -90,6 +90,8 @@ interface IDataTableProps {
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]);
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,8 +427,14 @@ 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
439
  const onClick = () => {
358
440
  if (typeof props.onRowClick === 'function') {
@@ -375,6 +457,10 @@ const DataTable: React.FC<IDataTableProps> = (props: IDataTableProps) => {
375
457
  }
376
458
  };
377
459
 
460
+ rowProps.onMouseMove = () => {
461
+ setSelectedRowId(i);
462
+ };
463
+
378
464
  const rowContent = row.cells.map((cell) => (
379
465
  <td
380
466
  {...cell.getCellProps()}
@@ -386,7 +472,6 @@ const DataTable: React.FC<IDataTableProps> = (props: IDataTableProps) => {
386
472
  ));
387
473
  const rowId = row?.original?.id || i;
388
474
  const rowKey = `row-${rowId}`;
389
-
390
475
  const expanded = props.expandTags ? props.expandTags : row.isExpanded;
391
476
  return (
392
477
  <React.Fragment key={rowKey}>
@@ -29,34 +29,55 @@ const Paginator: React.FC<any> = ({
29
29
  }) => {
30
30
  const [getPageIndex, setPageIndex] = React.useState<number>(pageIndex);
31
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]);
32
43
 
33
44
  React.useEffect(() => {
34
45
  if (pageIndex !== getPageIndex) {
35
46
  setPageIndex(pageIndex);
47
+ setInputPageIndex('');
48
+ }
49
+
50
+ if (itemsPerPage !== getItemsPerPage) {
51
+ setItemsPerPage(itemsPerPage);
52
+ setInputItemsPerPage('');
36
53
  }
37
- }, [pageIndex]);
54
+ }, [pageIndex, itemsPerPage]);
38
55
 
39
56
  const onItemsPerPageBlur = () => {
40
57
  clearTimeout(textInputTimeout);
41
- onItemsPerPage(getItemsPerPage);
58
+ if (inputItemsPerPage !== '') {
59
+ onItemsPerPage(inputItemsPerPage);
60
+ }
42
61
  };
43
62
 
44
63
  const onGoToPageBlur = () => {
45
64
  clearTimeout(textInputTimeout);
46
- gotoPage(getPageIndex, pageSize);
65
+ if (inputPageIndex !== '') {
66
+ gotoPage(inputPageIndex, pageSize);
67
+ }
47
68
  };
48
69
 
49
70
  const onItemsPerPageKeyDown = (e) => {
50
- if (e.key === 'Enter') {
71
+ if (e.key === 'Enter' && inputItemsPerPage !== '') {
51
72
  clearTimeout(textInputTimeout);
52
- onItemsPerPage(getItemsPerPage);
73
+ onItemsPerPage(inputItemsPerPage);
53
74
  }
54
75
  };
55
76
 
56
77
  const onGoToPageKeyDown = (e) => {
57
- if (e.key === 'Enter') {
78
+ if (e.key === 'Enter' && inputPageIndex !== '') {
58
79
  clearTimeout(textInputTimeout);
59
- gotoPage(getPageIndex, pageSize);
80
+ gotoPage(inputPageIndex, pageSize);
60
81
  }
61
82
  };
62
83
 
@@ -92,14 +113,14 @@ const Paginator: React.FC<any> = ({
92
113
  size='small'
93
114
  tooltip='Go to last page'
94
115
  disabled={!canNextPage}
95
- onClick={() => gotoPage(pageCount, pageSize)}>
116
+ onClick={() => gotoPage(getPageCount, pageSize)}>
96
117
  {ICON_ANGLE_DOUBLE_RIGHT}
97
118
  </Button>
98
119
  &nbsp;&nbsp;
99
120
  <span>
100
121
  {copy.table.page}&nbsp;&nbsp;
101
122
  <strong>
102
- {getPageIndex} of {pageCount}
123
+ {getPageIndex} of {getPageCount}
103
124
  </strong>
104
125
  &nbsp;&nbsp;
105
126
  </span>
@@ -109,18 +130,19 @@ const Paginator: React.FC<any> = ({
109
130
  className='paginator-input'
110
131
  type='number'
111
132
  placeholder={getPageIndex.toString()}
133
+ value={inputPageIndex}
112
134
  onChange={(e) => {
113
135
  const input = e.target.value;
114
136
  const inputNum = Number(input);
115
137
  let next: number;
116
138
 
117
139
  clearTimeout(textInputTimeout);
118
-
119
- if (!input || inputNum < 1 || inputNum > pageCount) {
140
+ setInputPageIndex(input);
141
+ if (!input || inputNum < 1 || inputNum > getPageCount) {
120
142
  return;
121
143
  }
122
144
 
123
- if (inputNum >= 1 && inputNum <= pageCount) {
145
+ if (inputNum >= 1 && inputNum <= getPageCount) {
124
146
  next = inputNum;
125
147
  }
126
148
 
@@ -140,19 +162,19 @@ const Paginator: React.FC<any> = ({
140
162
  className='paginator-input'
141
163
  type='number'
142
164
  placeholder={getItemsPerPage.toString()}
143
- min={1}
165
+ value={inputItemsPerPage}
144
166
  onChange={(e) => {
145
167
  const input = e.target.value;
146
168
  const inputNum = Number(input);
147
169
 
148
170
  clearTimeout(textInputTimeout);
149
171
 
172
+ setInputItemsPerPage(input);
173
+
150
174
  if (!input || inputNum < 1) {
151
175
  return;
152
176
  }
153
177
 
154
- setItemsPerPage(inputNum);
155
-
156
178
  textInputTimeout = window.setTimeout(
157
179
  () => onItemsPerPage(inputNum),
158
180
  1000
@@ -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: string;
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) {
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.name
686
709
  };
687
710
  };
688
711
 
@@ -1,6 +1,11 @@
1
1
  import * as React from 'react';
2
2
  import { IImposiumAPI } from '../../services/API';
3
- import { VARIABLE_TYPES, BOOLEAN_DEFAULT_OPTIONS } from '../../constants/variables';
3
+ import {
4
+ VARIABLE_TYPES,
5
+ BOOLEAN_DEFAULT_OPTIONS,
6
+ colorPresets,
7
+ formatColor
8
+ } from '../../constants/variables';
4
9
  import { OUTPUT_TYPES } from '../../constants/previewer';
5
10
  import TextField from '../text-field/TextField';
6
11
  import Button from '../button/Button';
@@ -23,6 +28,7 @@ import LogViewer from '../log-viewer/LogViewer';
23
28
  import { connect } from 'react-redux';
24
29
  import { ICON_DOWNLOAD, ICON_CLIPBOARD } from '../../constants/icons';
25
30
  import AudioPlayer from '../players/AudioPlayer';
31
+ import ColorField from '../color-field/ColorField';
26
32
 
27
33
  interface IStoryPreviewerProps {
28
34
  api: IImposiumAPI;
@@ -137,15 +143,14 @@ class StoryPreviewer extends React.PureComponent<IStoryPreviewerProps, IStoryPre
137
143
  const { variables } = this.props;
138
144
  const inventoryOverrides = this.props.editor?.inventoryOverrides;
139
145
  const newInv = {};
140
-
141
146
  for (const i in variables) {
142
147
  if (variables.hasOwnProperty(i)) {
143
148
  const override = inventoryOverrides ? inventoryOverrides[i] : null;
144
149
  const inv = variables[i];
145
- newInv[inv.id] = override ? override : this.getVariableValue(inv.previewItem);
150
+ newInv[inv.id] =
151
+ override !== null ? override : this.getVariableValue(inv.previewItem);
146
152
  }
147
153
  }
148
-
149
154
  return newInv;
150
155
  }
151
156
 
@@ -230,6 +235,11 @@ class StoryPreviewer extends React.PureComponent<IStoryPreviewerProps, IStoryPre
230
235
  }
231
236
  }
232
237
 
238
+ private colorInputChanged(key, value) {
239
+ const color = formatColor(value);
240
+ this.variableInputChanged(key, color);
241
+ }
242
+
233
243
  private variableInputChanged(key, value) {
234
244
  const inventory = { ...this.state.inventory };
235
245
  inventory[key] = value;
@@ -397,6 +407,20 @@ class StoryPreviewer extends React.PureComponent<IStoryPreviewerProps, IStoryPre
397
407
  </FieldWrapper>
398
408
  );
399
409
  break;
410
+ case VARIABLE_TYPES.COLOR:
411
+ const value = inventory[inv.id] ? inventory[inv.id] : 'rgba(0,0,0,1)';
412
+ fields.push(
413
+ <ColorField
414
+ label={inv.name}
415
+ labelPosition='top'
416
+ enableAlpha={true}
417
+ presetColors={colorPresets}
418
+ value={value}
419
+ pickerPosition='bottom'
420
+ onChange={(v) => this.colorInputChanged(inv.id, v)}
421
+ />
422
+ );
423
+ break;
400
424
  }
401
425
  }
402
426
  }
@@ -5,7 +5,8 @@ export const VARIABLE_TYPES = {
5
5
  ENUM: 'enum',
6
6
  IMAGE: 'image',
7
7
  VIDEO: 'video',
8
- AUDIO: 'audio'
8
+ AUDIO: 'audio',
9
+ COLOR: 'color'
9
10
  };
10
11
 
11
12
  export const BOOLEAN_DEFAULT_OPTIONS = [
@@ -18,3 +19,28 @@ export const BOOLEAN_DEFAULT_OPTIONS = [
18
19
  label: 'False'
19
20
  }
20
21
  ];
22
+
23
+ export const colorPresets = [
24
+ '#D0021B',
25
+ '#F5A623',
26
+ '#F8E71C',
27
+ '#8B572A',
28
+ '#7ED321',
29
+ '#417505',
30
+ '#BD10E0',
31
+ '#9013FE',
32
+ '#4A90E2',
33
+ '#50E3C2',
34
+ '#B8E986',
35
+ '#000000',
36
+ '#4A4A4A',
37
+ '#9B9B9B',
38
+ '#FFFFFF',
39
+ 'transparent'
40
+ ];
41
+
42
+ export const formatColor = (color) => {
43
+ const { r, g, b, a } = color.rgb;
44
+ const alpha = color.source === 'hsv' ? 1 : a;
45
+ return `rgba(${r},${g},${b},${alpha})`;
46
+ };
package/src/index.ts CHANGED
@@ -159,7 +159,11 @@ import ContextMenuItem from './components/context-menu/ContextMenuItem';
159
159
  import ContextMenuTrigger from './components/context-menu/ContextMenuTrigger';
160
160
  import CopyPropIdButton from './components/copy-prop-id-button/CopyPropIdButton';
161
161
  import Submenu from './components/context-menu/SubMenu';
162
+ import { ConfirmModal, IConfirmModalProps } from './components/confirm-modal/ConfirmModal';
162
163
  import AssetsTableAssetIdCell from './components/assets/AssetsTableAssetIdCell';
164
+ import { resetStoryFilter, updateStoryFilter } from './redux/actions/story-filter';
165
+ import storyFilter from './redux/reducers/story-filter';
166
+ import StoryTableNameFilter from './components/assets/StoryTableNameFilter';
163
167
 
164
168
  export {
165
169
  AppWrapper,
@@ -218,6 +222,7 @@ export {
218
222
  AssetsTableGlobalCell,
219
223
  AssetsTableStatusCell,
220
224
  AssetsTableNameFilter,
225
+ StoryTableNameFilter,
221
226
  AssetsTableAssetIdFilter,
222
227
  AssetsTableAssetIdCell,
223
228
  AssetsTableNameCell,
@@ -245,6 +250,8 @@ export {
245
250
  storyDeleted,
246
251
  updateFilters,
247
252
  resetFilters,
253
+ updateStoryFilter,
254
+ resetStoryFilter,
248
255
  getAssets,
249
256
  deleteAssets,
250
257
  downloadAssets,
@@ -259,6 +266,7 @@ export {
259
266
  deselectAsset,
260
267
  resetSelection,
261
268
  assetFilters,
269
+ storyFilter,
262
270
  assetList,
263
271
  assetUploads,
264
272
  selectedAssets,
@@ -315,5 +323,7 @@ export {
315
323
  ContextMenuItem,
316
324
  ContextMenuTrigger,
317
325
  Submenu,
318
- CopyPropIdButton
326
+ CopyPropIdButton,
327
+ ConfirmModal,
328
+ IConfirmModalProps
319
329
  };