@onehat/ui 0.4.77 → 0.4.79
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.
- package/package.json +1 -1
- package/src/Components/Editor/AttachmentDirectoriesEditor.js +51 -0
- package/src/Components/Editor/AttachmentsEditor.js +81 -0
- package/src/Components/Form/Field/Combo/AttachmentDirectoriesCombo.js +20 -0
- package/src/Components/Form/Field/Combo/AttachmentDirectoriesComboEditor.js +22 -0
- package/src/Components/Form/Field/Combo/AttachmentsCombo.js +20 -0
- package/src/Components/Form/Field/Combo/AttachmentsComboEditor.js +22 -0
- package/src/Components/Form/Field/Tag/AttachmentDirectoriesTag.js +22 -0
- package/src/Components/Form/Field/Tag/AttachmentDirectoriesTagEditor.js +22 -0
- package/src/Components/Form/Field/Tag/AttachmentsTag.js +22 -0
- package/src/Components/Form/Field/Tag/AttachmentsTagEditor.js +22 -0
- package/src/Components/Form/Form.js +17 -17
- package/src/Components/Grid/AttachmentDirectoriesFilteredGrid.js +17 -0
- package/src/Components/Grid/AttachmentDirectoriesFilteredGridEditor.js +17 -0
- package/src/Components/Grid/AttachmentDirectoriesFilteredInlineGridEditor.js +17 -0
- package/src/Components/Grid/AttachmentDirectoriesFilteredSideGridEditor.js +17 -0
- package/src/Components/Grid/AttachmentDirectoriesGrid.js +20 -0
- package/src/Components/Grid/AttachmentDirectoriesGridEditor.js +27 -0
- package/src/Components/Grid/AttachmentDirectoriesInlineGridEditor.js +25 -0
- package/src/Components/Grid/AttachmentDirectoriesSideGridEditor.js +24 -0
- package/src/Components/Grid/AttachmentsFilteredGrid.js +17 -0
- package/src/Components/Grid/AttachmentsFilteredGridEditor.js +17 -0
- package/src/Components/Grid/AttachmentsFilteredInlineGridEditor.js +17 -0
- package/src/Components/Grid/AttachmentsFilteredSideGridEditor.js +17 -0
- package/src/Components/Grid/AttachmentsGrid.js +20 -0
- package/src/Components/Grid/AttachmentsGridEditor.js +27 -0
- package/src/Components/Grid/AttachmentsInlineGridEditor.js +25 -0
- package/src/Components/Grid/AttachmentsSideGridEditor.js +24 -0
- package/src/Components/Grid/Columns/AttachmentDirectoriesGridColumns.js +32 -0
- package/src/Components/Grid/Columns/AttachmentsGridColumns.js +133 -0
- package/src/Components/Grid/Grid.js +194 -21
- package/src/Components/Grid/GridHeaderRow.js +10 -17
- package/src/Components/Grid/GridRow.js +49 -22
- package/src/Components/Grid/RowHandle.js +8 -6
- package/src/Components/Hoc/withEditor.js +18 -1
- package/src/Components/Hoc/withModal.js +4 -0
- package/src/Components/Hoc/withPdfButtons.js +1 -1
- package/src/Components/Hoc/withSelection.js +26 -4
- package/src/Components/Layout/AsyncOperation.js +299 -195
- package/src/Components/Messages/GlobalModals.js +1 -2
- package/src/Components/Panel/Panel.js +14 -2
- package/src/Components/Panel/TabPanel.js +1 -1
- package/src/Components/Panel/TreePanel.js +1 -1
- package/src/Components/Report/Report.js +106 -17
- package/src/Components/Toolbar/PaginationToolbar.js +4 -3
- package/src/Components/Toolbar/Toolbar.js +6 -3
- package/src/Components/Tree/Tree.js +219 -148
- package/src/Components/Tree/TreeNode.js +20 -13
- package/src/Components/Window/AttachmentDirectoriesEditorWindow.js +34 -0
- package/src/Components/Window/AttachmentsEditorWindow.js +34 -0
- package/src/Components/index.js +92 -1
- package/src/Constants/Attachments.js +2 -0
- package/src/Constants/Dates.js +2 -2
- package/src/Constants/Progress.js +5 -1
- package/src/Models/Schemas/AttachmentDirectories.js +66 -0
- package/src/Models/Schemas/Attachments.js +88 -0
- package/src/Models/Slices/SystemSlice.js +220 -0
- package/src/PlatformImports/Web/Attachments.js +855 -161
- package/src/Styles/Global.css +7 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useMemo, useState, useEffect, } from 'react';
|
|
1
|
+
import { useMemo, useState, useEffect, forwardRef, isValidElement, cloneElement, } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
4
|
HStack,
|
|
@@ -25,25 +25,20 @@ import useAsyncRenderers from './useAsyncRenderers.js';
|
|
|
25
25
|
import _ from 'lodash';
|
|
26
26
|
|
|
27
27
|
// Conditional import for web only
|
|
28
|
-
let getEmptyImage;
|
|
29
|
-
if (CURRENT_MODE === UI_MODE_WEB) {
|
|
30
|
-
import('react-dnd-html5-backend').then((module) => {
|
|
31
|
-
getEmptyImage = module.getEmptyImage;
|
|
32
|
-
}).catch(() => {
|
|
33
|
-
getEmptyImage = null;
|
|
34
|
-
});
|
|
35
|
-
}
|
|
28
|
+
let getEmptyImage = null;
|
|
36
29
|
|
|
37
30
|
// This was broken out from Grid simply so we can memoize it
|
|
38
31
|
|
|
39
|
-
function GridRow(props) {
|
|
32
|
+
const GridRow = forwardRef(function GridRow(props, ref) {
|
|
40
33
|
const {
|
|
41
34
|
columnsConfig,
|
|
42
35
|
columnProps,
|
|
43
36
|
fields,
|
|
44
37
|
rowProps,
|
|
45
38
|
hideNavColumn,
|
|
46
|
-
|
|
39
|
+
showRowHandle,
|
|
40
|
+
rowCanSelect,
|
|
41
|
+
rowCanDrag,
|
|
47
42
|
isRowHoverable,
|
|
48
43
|
isSelected,
|
|
49
44
|
isHovered,
|
|
@@ -79,8 +74,15 @@ function GridRow(props) {
|
|
|
79
74
|
// Hide the default drag preview only when using custom drag proxy (and only on web)
|
|
80
75
|
useEffect(() => {
|
|
81
76
|
if (dragPreviewRef && typeof dragPreviewRef === 'function' && getDragProxy && CURRENT_MODE === UI_MODE_WEB) {
|
|
82
|
-
//
|
|
83
|
-
|
|
77
|
+
// Load getEmptyImage dynamically and apply it
|
|
78
|
+
import('react-dnd-html5-backend').then((module) => {
|
|
79
|
+
const getEmptyImage = module.getEmptyImage;
|
|
80
|
+
if (getEmptyImage) {
|
|
81
|
+
dragPreviewRef(getEmptyImage(), { captureDraggingState: true });
|
|
82
|
+
}
|
|
83
|
+
}).catch((error) => {
|
|
84
|
+
console.warn('Failed to load react-dnd-html5-backend:', error);
|
|
85
|
+
});
|
|
84
86
|
}
|
|
85
87
|
}, [dragPreviewRef, getDragProxy]);
|
|
86
88
|
|
|
@@ -126,12 +128,13 @@ function GridRow(props) {
|
|
|
126
128
|
if (_.isArray(columnsConfig)) {
|
|
127
129
|
return _.map(columnsConfig, (config, key, all) => {
|
|
128
130
|
if (config.isHidden) {
|
|
129
|
-
return
|
|
131
|
+
// every element needs a key, so return an empty element with a key
|
|
132
|
+
return <Box key={key} style={{ display: 'none' }} />;
|
|
130
133
|
}
|
|
131
134
|
const
|
|
132
135
|
propsToPass = columnProps[key] || {},
|
|
133
136
|
colStyle = {},
|
|
134
|
-
whichCursor =
|
|
137
|
+
whichCursor = showRowHandle ? 'cursor-text' : 'cursor-pointer'; // when using rowSelectHandle, indicate that the row text is selectable, otherwise indicate that the row itself is selectable
|
|
135
138
|
let colClassName = clsx(
|
|
136
139
|
'GridRow-column',
|
|
137
140
|
'p-1',
|
|
@@ -161,7 +164,12 @@ function GridRow(props) {
|
|
|
161
164
|
|
|
162
165
|
let value;
|
|
163
166
|
if (_.isFunction(config)) {
|
|
164
|
-
|
|
167
|
+
const element = config(item, key);
|
|
168
|
+
if (isValidElement(element)) {
|
|
169
|
+
// ensure element has a key
|
|
170
|
+
return element.key != null ? element : cloneElement(element, { key });
|
|
171
|
+
}
|
|
172
|
+
return <Box key={key}>{element}</Box>; // create a box (with key) to wrap non-elements
|
|
165
173
|
}
|
|
166
174
|
if (_.isPlainObject(config)) {
|
|
167
175
|
if (config.renderer) {
|
|
@@ -219,7 +227,7 @@ function GridRow(props) {
|
|
|
219
227
|
throw Error('Not yet working correctly!');
|
|
220
228
|
// Async renderer
|
|
221
229
|
if (isLoading) {
|
|
222
|
-
content = <Loading />;
|
|
230
|
+
content = <Loading key={key} />;
|
|
223
231
|
} else if (asyncResult) {
|
|
224
232
|
if (asyncResult.error) {
|
|
225
233
|
content = <Text key={key}>Render Error: {asyncResult.error.message || String(asyncResult.error)}</Text>;
|
|
@@ -240,7 +248,15 @@ function GridRow(props) {
|
|
|
240
248
|
content = <Text key={key}>Render Error: {error}</Text>;
|
|
241
249
|
}
|
|
242
250
|
}
|
|
243
|
-
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
// Ensure content has a key prop
|
|
255
|
+
if (isValidElement(content)) {
|
|
256
|
+
// ensure element has a key
|
|
257
|
+
return content.key != null ? content : cloneElement(content, { key });
|
|
258
|
+
}
|
|
259
|
+
return <Box key={key}>{content}</Box>; // create a box (with key) to wrap non-elements
|
|
244
260
|
}
|
|
245
261
|
if (config.fieldName) {
|
|
246
262
|
|
|
@@ -315,7 +331,13 @@ function GridRow(props) {
|
|
|
315
331
|
}
|
|
316
332
|
}
|
|
317
333
|
if (_.isFunction(value)) {
|
|
318
|
-
|
|
334
|
+
const result = value(key);
|
|
335
|
+
// Ensure the result has a key prop
|
|
336
|
+
if (isValidElement(result)) {
|
|
337
|
+
// Only clone if the result doesn't already have a key
|
|
338
|
+
return result.key != null ? result : cloneElement(result, { key });
|
|
339
|
+
}
|
|
340
|
+
return <Box key={key}>{result}</Box>;
|
|
319
341
|
}
|
|
320
342
|
const elementProps = {};
|
|
321
343
|
if (config.getCellProps) {
|
|
@@ -353,12 +375,13 @@ function GridRow(props) {
|
|
|
353
375
|
};
|
|
354
376
|
|
|
355
377
|
let rowContents = <>
|
|
356
|
-
{
|
|
378
|
+
{showRowHandle &&
|
|
357
379
|
<RowHandle
|
|
358
380
|
ref={dragSourceRef}
|
|
359
381
|
isDragSource={isDragSource}
|
|
360
382
|
isDraggable={isDraggable}
|
|
361
|
-
|
|
383
|
+
canSelect={rowCanSelect}
|
|
384
|
+
canDrag={rowCanDrag}
|
|
362
385
|
/>}
|
|
363
386
|
|
|
364
387
|
{isPhantom &&
|
|
@@ -418,6 +441,7 @@ function GridRow(props) {
|
|
|
418
441
|
rowClassName += ' border-4 border-[#0ff]';
|
|
419
442
|
}
|
|
420
443
|
return <HStackNative
|
|
444
|
+
ref={ref}
|
|
421
445
|
{...testProps('Row ' + (isSelected ? 'row-selected' : ''))}
|
|
422
446
|
{...rowProps}
|
|
423
447
|
key={hash}
|
|
@@ -449,8 +473,11 @@ function GridRow(props) {
|
|
|
449
473
|
dragSourceRef,
|
|
450
474
|
dragPreviewRef,
|
|
451
475
|
dropTargetRef,
|
|
476
|
+
showRowHandle,
|
|
477
|
+
rowCanSelect,
|
|
478
|
+
rowCanDrag,
|
|
452
479
|
]);
|
|
453
|
-
}
|
|
480
|
+
});
|
|
454
481
|
|
|
455
482
|
// export default withDraggable(withDragSource(withDropTarget(GridRow)));
|
|
456
483
|
export default GridRow;
|
|
@@ -7,7 +7,7 @@ import withTooltip from '@onehat/ui/src/Components/Hoc/withTooltip';
|
|
|
7
7
|
import clsx from 'clsx';
|
|
8
8
|
import Arcs from '../Icons/Arcs.js';
|
|
9
9
|
|
|
10
|
-
const RowHandle = forwardRef(
|
|
10
|
+
const RowHandle = forwardRef((props, ref) => {
|
|
11
11
|
const {
|
|
12
12
|
isDragSource,
|
|
13
13
|
isDraggable
|
|
@@ -31,25 +31,27 @@ const RowHandle = forwardRef(function RowHandle(props, ref) {
|
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
function withAdditionalProps(WrappedComponent) {
|
|
34
|
-
return (props) => {
|
|
34
|
+
return forwardRef((props, ref) => {
|
|
35
35
|
const {
|
|
36
|
-
|
|
36
|
+
canSelect,
|
|
37
|
+
canDrag,
|
|
37
38
|
isDragSource,
|
|
38
39
|
isDraggable
|
|
39
40
|
} = props;
|
|
40
41
|
let tooltipParts = [];
|
|
41
|
-
if (
|
|
42
|
+
if (canSelect) {
|
|
42
43
|
tooltipParts.push('Select');
|
|
43
44
|
}
|
|
44
|
-
if (
|
|
45
|
+
if (canDrag) {
|
|
45
46
|
tooltipParts.push('Drag');
|
|
46
47
|
}
|
|
47
48
|
const tooltip = tooltipParts.length === 2 ? tooltipParts.join(' or ') : tooltipParts[0];
|
|
48
49
|
return <WrappedComponent
|
|
49
50
|
tooltip={tooltip}
|
|
50
51
|
{...props}
|
|
52
|
+
ref={ref}
|
|
51
53
|
/>;
|
|
52
|
-
};
|
|
54
|
+
});
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
export default withAdditionalProps(withTooltip(RowHandle));
|
|
@@ -45,6 +45,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
45
45
|
editorType,
|
|
46
46
|
onAdd,
|
|
47
47
|
onChange, // any kind of crud change
|
|
48
|
+
onBeforeDelete,
|
|
48
49
|
onDelete,
|
|
49
50
|
onSave, // this could also be called 'onEdit'
|
|
50
51
|
onEditorClose,
|
|
@@ -106,7 +107,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
106
107
|
setIsWaitModalShown = (bool) => {
|
|
107
108
|
const
|
|
108
109
|
dispatch = UiGlobals.redux?.dispatch,
|
|
109
|
-
setIsWaitModalShownAction = UiGlobals.
|
|
110
|
+
setIsWaitModalShownAction = UiGlobals.systemReducer?.setIsWaitModalShownAction;
|
|
110
111
|
if (setIsWaitModalShownAction) {
|
|
111
112
|
console.log('withEditor:setIsWaitModalShownAction', bool);
|
|
112
113
|
dispatch(setIsWaitModalShownAction(bool));
|
|
@@ -289,7 +290,15 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
289
290
|
if (_.isEmpty(selection) || (_.isArray(selection) && (selection.length > 1 || selection[0]?.isDestroyed))) {
|
|
290
291
|
return;
|
|
291
292
|
}
|
|
293
|
+
if (onBeforeDelete) {
|
|
294
|
+
// This listener is set by parent components using a prop
|
|
295
|
+
const listenerResult = await onBeforeDelete(selection);
|
|
296
|
+
if (listenerResult === false) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
292
300
|
if (getListeners().onBeforeDelete) {
|
|
301
|
+
// This listener is set by child components using setWithEditListeners()
|
|
293
302
|
const listenerResult = await getListeners().onBeforeDelete();
|
|
294
303
|
if (listenerResult === false) {
|
|
295
304
|
return;
|
|
@@ -345,7 +354,15 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
345
354
|
return;
|
|
346
355
|
}
|
|
347
356
|
const selection = getSelection();
|
|
357
|
+
if (onBeforeDelete) {
|
|
358
|
+
// This listener is set by parent components using a prop
|
|
359
|
+
const listenerResult = await onBeforeDelete(selection);
|
|
360
|
+
if (listenerResult === false) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
348
364
|
if (getListeners().onBeforeDelete) {
|
|
365
|
+
// This listener is set by child components using setWithEditListeners()
|
|
349
366
|
const listenerResult = await getListeners().onBeforeDelete(selection);
|
|
350
367
|
if (listenerResult === false) {
|
|
351
368
|
return;
|
|
@@ -332,7 +332,7 @@ export default function withPdfButtons(WrappedComponent) {
|
|
|
332
332
|
|
|
333
333
|
const
|
|
334
334
|
dispatch = UiGlobals.redux.dispatch,
|
|
335
|
-
setIsWaitModalShownAction = UiGlobals.
|
|
335
|
+
setIsWaitModalShownAction = UiGlobals.systemReducer.setIsWaitModalShownAction;
|
|
336
336
|
|
|
337
337
|
dispatch(setIsWaitModalShownAction(true));
|
|
338
338
|
|
|
@@ -42,8 +42,24 @@ export default function withSelection(WrappedComponent) {
|
|
|
42
42
|
forceUpdate = useForceUpdate(),
|
|
43
43
|
selectionRef = useRef(initialSelection),
|
|
44
44
|
RepositoryRef = useRef(Repository),
|
|
45
|
+
isSelectionChangesEnabledRef = useRef(true),
|
|
45
46
|
[isReady, setIsReady] = useState(selection || false), // if selection is already defined, or value is not null and we don't need to load repository, it's ready
|
|
47
|
+
getIsSelectionChangesEnabled = () => {
|
|
48
|
+
return isSelectionChangesEnabledRef.current;
|
|
49
|
+
},
|
|
50
|
+
setIsSelectionChangesEnabled = (bool) => {
|
|
51
|
+
isSelectionChangesEnabledRef.current = bool;
|
|
52
|
+
},
|
|
53
|
+
disableSelectionChanges = () => {
|
|
54
|
+
setIsSelectionChangesEnabled(false);
|
|
55
|
+
},
|
|
56
|
+
enableSelectionChanges = () => {
|
|
57
|
+
setIsSelectionChangesEnabled(true);
|
|
58
|
+
},
|
|
46
59
|
setSelection = (selection) => {
|
|
60
|
+
if (!getIsSelectionChangesEnabled()) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
47
63
|
if (_.isEqual(selection, getSelection())) {
|
|
48
64
|
return;
|
|
49
65
|
}
|
|
@@ -195,13 +211,16 @@ export default function withSelection(WrappedComponent) {
|
|
|
195
211
|
},
|
|
196
212
|
isInSelection = (item) => {
|
|
197
213
|
const Repository = getRepository();
|
|
214
|
+
let found = null;
|
|
198
215
|
if (Repository) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
216
|
+
found = _.find(getSelection(), (selectedItem) => {
|
|
217
|
+
return selectedItem.id === item.id;
|
|
218
|
+
});
|
|
219
|
+
} else {
|
|
220
|
+
found = _.find(getSelection(), (selectedItem) => {
|
|
203
221
|
return selectedItem[idIx] === item[idIx];
|
|
204
222
|
});
|
|
223
|
+
}
|
|
205
224
|
return !!found;
|
|
206
225
|
},
|
|
207
226
|
getIndexOfSelectedItem = (item) => {
|
|
@@ -436,6 +455,9 @@ export default function withSelection(WrappedComponent) {
|
|
|
436
455
|
isInSelection={isInSelection}
|
|
437
456
|
getIdsFromSelection={getIdsFromLocalSelection}
|
|
438
457
|
getDisplayValuesFromSelection={getDisplayValuesFromSelection}
|
|
458
|
+
disableSelectionChanges={disableSelectionChanges}
|
|
459
|
+
enableSelectionChanges={enableSelectionChanges}
|
|
460
|
+
refreshSelection={refreshSelection}
|
|
439
461
|
/>;
|
|
440
462
|
});
|
|
441
463
|
}
|