@onehat/ui 0.4.107 → 0.4.109
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/Container/Container.js +23 -1
- package/src/Components/Form/Field/Tag/Tag.js +1 -1
- package/src/Components/Form/Form.js +31 -12
- package/src/Components/Grid/GridRow.js +13 -6
- package/src/Components/Hoc/withEditor.js +13 -4
- package/src/Components/Hoc/withFilters.js +6 -3
- package/src/Components/Hoc/withPdfButtons.js +4 -3
- package/src/Components/Hoc/withPresetButtons.js +8 -3
- package/src/Components/Layout/ScreenHeader.js +2 -0
- package/src/Components/Viewer/Viewer.js +20 -12
- package/src/Components/Window/UploadsDownloadsWindow.js +30 -12
- package/src/Components/Form/Field/FormikForm.js +0 -1019
package/package.json
CHANGED
|
@@ -424,6 +424,8 @@ function Container(props) {
|
|
|
424
424
|
|
|
425
425
|
componentProps._panel.isCollapsible = false;
|
|
426
426
|
componentProps._panel.isDisabled = isDisabled || isComponentsDisabled;
|
|
427
|
+
componentProps.isCollapsible = false;
|
|
428
|
+
componentProps.isDisabled = isDisabled || isComponentsDisabled;
|
|
427
429
|
componentProps.onLayout = debouncedOnLayout;
|
|
428
430
|
centerComponent = cloneElement(center, componentProps);
|
|
429
431
|
if (north) {
|
|
@@ -432,9 +434,11 @@ function Container(props) {
|
|
|
432
434
|
|
|
433
435
|
componentProps._panel.isDisabled = isDisabled || isComponentsDisabled;
|
|
434
436
|
componentProps._panel.className = 'h-full w-full ' + (north.props.className || '');
|
|
437
|
+
componentProps.isDisabled = !!north.props?.isDisabled || isDisabled || isComponentsDisabled;
|
|
438
|
+
componentProps.className = 'h-full w-full ' + (north.props.className || '');
|
|
435
439
|
wrapperProps.onLayout = (e) => {
|
|
436
440
|
const height = parseFloat(e.nativeEvent.layout.height);
|
|
437
|
-
if (height && height !==
|
|
441
|
+
if (height && height !== getNorthHeight()) {
|
|
438
442
|
setNorthHeight(height);
|
|
439
443
|
}
|
|
440
444
|
};
|
|
@@ -453,6 +457,9 @@ function Container(props) {
|
|
|
453
457
|
componentProps._panel.collapseDirection = VERTICAL;
|
|
454
458
|
componentProps._panel.isCollapsed = getNorthIsCollapsed();
|
|
455
459
|
componentProps._panel.setIsCollapsed = setNorthIsCollapsed;
|
|
460
|
+
componentProps.collapseDirection = VERTICAL;
|
|
461
|
+
componentProps.isCollapsed = getNorthIsCollapsed();
|
|
462
|
+
componentProps.setIsCollapsed = setNorthIsCollapsed;
|
|
456
463
|
if (isWeb && northIsResizable) {
|
|
457
464
|
northSplitter = <Splitter
|
|
458
465
|
mode={VERTICAL}
|
|
@@ -470,6 +477,8 @@ function Container(props) {
|
|
|
470
477
|
|
|
471
478
|
componentProps._panel.isDisabled = isDisabled || isComponentsDisabled;
|
|
472
479
|
componentProps._panel.className = 'h-full w-full ' + (south.props.className || '');
|
|
480
|
+
componentProps.isDisabled = !!south.props?.isDisabled || isDisabled || isComponentsDisabled;
|
|
481
|
+
componentProps.className = 'h-full w-full ' + (south.props.className || '');
|
|
473
482
|
wrapperProps.onLayout = (e) => {
|
|
474
483
|
const height = parseFloat(e.nativeEvent.layout.height);
|
|
475
484
|
if (height && height !== getSouthHeight()) {
|
|
@@ -491,6 +500,9 @@ function Container(props) {
|
|
|
491
500
|
componentProps._panel.collapseDirection = VERTICAL;
|
|
492
501
|
componentProps._panel.isCollapsed = getSouthIsCollapsed();
|
|
493
502
|
componentProps._panel.setIsCollapsed = setSouthIsCollapsed;
|
|
503
|
+
componentProps.collapseDirection = VERTICAL;
|
|
504
|
+
componentProps.isCollapsed = getSouthIsCollapsed();
|
|
505
|
+
componentProps.setIsCollapsed = setSouthIsCollapsed;
|
|
494
506
|
if (isWeb && southIsResizable) {
|
|
495
507
|
southSplitter = <Splitter
|
|
496
508
|
mode={VERTICAL}
|
|
@@ -508,6 +520,8 @@ function Container(props) {
|
|
|
508
520
|
|
|
509
521
|
componentProps._panel.isDisabled = isDisabled || isComponentsDisabled;
|
|
510
522
|
componentProps._panel.className = 'h-full w-full ' + (east.props.className || '');
|
|
523
|
+
componentProps.isDisabled = !!east.props?.isDisabled || isDisabled || isComponentsDisabled;
|
|
524
|
+
componentProps.className = 'h-full w-full ' + (east.props.className || '');
|
|
511
525
|
wrapperProps.onLayout = (e) => {
|
|
512
526
|
const width = parseFloat(e.nativeEvent.layout.width);
|
|
513
527
|
if (width && width !== getEastWidth()) {
|
|
@@ -529,6 +543,9 @@ function Container(props) {
|
|
|
529
543
|
componentProps._panel.collapseDirection = HORIZONTAL;
|
|
530
544
|
componentProps._panel.isCollapsed = getEastIsCollapsed();
|
|
531
545
|
componentProps._panel.setIsCollapsed = setEastIsCollapsed;
|
|
546
|
+
componentProps.collapseDirection = HORIZONTAL;
|
|
547
|
+
componentProps.isCollapsed = getEastIsCollapsed();
|
|
548
|
+
componentProps.setIsCollapsed = setEastIsCollapsed;
|
|
532
549
|
if (isWeb && eastIsResizable) {
|
|
533
550
|
eastSplitter = <Splitter
|
|
534
551
|
mode={HORIZONTAL}
|
|
@@ -546,6 +563,8 @@ function Container(props) {
|
|
|
546
563
|
|
|
547
564
|
componentProps._panel.isDisabled = isDisabled || isComponentsDisabled;
|
|
548
565
|
componentProps._panel.className = 'h-full w-full ' + (west.props.className || '');
|
|
566
|
+
componentProps.isDisabled = !!west.props?.isDisabled || isDisabled || isComponentsDisabled;
|
|
567
|
+
componentProps.className = 'h-full w-full ' + (west.props.className || '');
|
|
549
568
|
wrapperProps.onLayout = (e) => {
|
|
550
569
|
const width = parseFloat(e.nativeEvent.layout.width);
|
|
551
570
|
if (width && width !== getWestWidth()) {
|
|
@@ -567,6 +586,9 @@ function Container(props) {
|
|
|
567
586
|
componentProps._panel.collapseDirection = HORIZONTAL;
|
|
568
587
|
componentProps._panel.isCollapsed = getWestIsCollapsed();
|
|
569
588
|
componentProps._panel.setIsCollapsed = setWestIsCollapsed;
|
|
589
|
+
componentProps.collapseDirection = HORIZONTAL;
|
|
590
|
+
componentProps.isCollapsed = getWestIsCollapsed();
|
|
591
|
+
componentProps.setIsCollapsed = setWestIsCollapsed;
|
|
570
592
|
if (isWeb && westIsResizable) {
|
|
571
593
|
westSplitter = <Splitter
|
|
572
594
|
mode={HORIZONTAL}
|
|
@@ -321,7 +321,11 @@ function Form(props) {
|
|
|
321
321
|
type = 'Text';
|
|
322
322
|
}
|
|
323
323
|
}
|
|
324
|
-
const
|
|
324
|
+
const
|
|
325
|
+
Element = getComponentFromType(type),
|
|
326
|
+
shouldHideFieldUi = type === 'Hidden',
|
|
327
|
+
isCombo = type?.match && type.match(/Combo/);
|
|
328
|
+
|
|
325
329
|
if (config.hasOwnProperty('autoLoad')) {
|
|
326
330
|
editorTypeProps.autoLoad = config.autoLoad;
|
|
327
331
|
} else {
|
|
@@ -335,9 +339,8 @@ function Form(props) {
|
|
|
335
339
|
editorTypeProps.showXButton = true;
|
|
336
340
|
}
|
|
337
341
|
}
|
|
338
|
-
const Element = getComponentFromType(type);
|
|
339
342
|
|
|
340
|
-
if (isEditorViewOnly || !isEditable) {
|
|
343
|
+
if ((isEditorViewOnly || !isEditable) && !shouldHideFieldUi) {
|
|
341
344
|
let value = null;
|
|
342
345
|
if (renderer) {
|
|
343
346
|
value = renderer(record);
|
|
@@ -483,6 +486,9 @@ function Form(props) {
|
|
|
483
486
|
{...dynamicProps}
|
|
484
487
|
className={elementClassName}
|
|
485
488
|
/>;
|
|
489
|
+
if (shouldHideFieldUi) {
|
|
490
|
+
return element;
|
|
491
|
+
}
|
|
486
492
|
|
|
487
493
|
const dirtyIcon = isDirty && !disableDirtyIcon ?
|
|
488
494
|
<Icon
|
|
@@ -532,6 +538,7 @@ function Form(props) {
|
|
|
532
538
|
isEditable = true,
|
|
533
539
|
isEditingEnabledInPlainEditor,
|
|
534
540
|
label,
|
|
541
|
+
disableLabel = false,
|
|
535
542
|
labelWidth,
|
|
536
543
|
items,
|
|
537
544
|
onChange: onEditorChange,
|
|
@@ -588,7 +595,11 @@ function Form(props) {
|
|
|
588
595
|
type = 'Text';
|
|
589
596
|
}
|
|
590
597
|
}
|
|
591
|
-
const
|
|
598
|
+
const
|
|
599
|
+
Element = getComponentFromType(type),
|
|
600
|
+
shouldHideFieldUi = type === 'Hidden',
|
|
601
|
+
isCombo = type?.match && type.match(/Combo/);
|
|
602
|
+
|
|
592
603
|
if (item.hasOwnProperty('autoLoad')) {
|
|
593
604
|
editorTypeProps.autoLoad = item.autoLoad;
|
|
594
605
|
} else {
|
|
@@ -602,7 +613,6 @@ function Form(props) {
|
|
|
602
613
|
editorTypeProps.showXButton = true;
|
|
603
614
|
}
|
|
604
615
|
}
|
|
605
|
-
const Element = getComponentFromType(type);
|
|
606
616
|
|
|
607
617
|
if (inArray(type, ['Column', 'Row', 'FieldSet'])) {
|
|
608
618
|
if (_.isEmpty(items)) {
|
|
@@ -676,7 +686,7 @@ function Form(props) {
|
|
|
676
686
|
label = propertyDef.title;
|
|
677
687
|
}
|
|
678
688
|
|
|
679
|
-
if (isEditorViewOnly || !isEditable) {
|
|
689
|
+
if ((isEditorViewOnly || !isEditable) && !shouldHideFieldUi) {
|
|
680
690
|
let value = null;
|
|
681
691
|
if (isSingle) {
|
|
682
692
|
value = record?.properties?.[name]?.displayValue || null;
|
|
@@ -713,7 +723,10 @@ function Form(props) {
|
|
|
713
723
|
{...viewerTypeProps}
|
|
714
724
|
className={elementClassName}
|
|
715
725
|
/>;
|
|
716
|
-
if (
|
|
726
|
+
if (shouldHideFieldUi) {
|
|
727
|
+
return null;
|
|
728
|
+
}
|
|
729
|
+
if (!disableLabels && !disableLabel && label) {
|
|
717
730
|
const style = {};
|
|
718
731
|
if (defaults?.labelWidth) {
|
|
719
732
|
style.width = defaults.labelWidth;
|
|
@@ -846,6 +859,9 @@ function Form(props) {
|
|
|
846
859
|
{...dynamicProps}
|
|
847
860
|
className={elementClassName}
|
|
848
861
|
/>;
|
|
862
|
+
if (shouldHideFieldUi) {
|
|
863
|
+
return element;
|
|
864
|
+
}
|
|
849
865
|
let message = null;
|
|
850
866
|
if (error) {
|
|
851
867
|
message = error.message;
|
|
@@ -905,7 +921,7 @@ function Form(props) {
|
|
|
905
921
|
}
|
|
906
922
|
}
|
|
907
923
|
const labelToUse = dynamicProps.label || label;
|
|
908
|
-
if (!disableLabels && labelToUse && editorType !== EDITOR_TYPE__INLINE) {
|
|
924
|
+
if (!disableLabels && !disableLabel && labelToUse && editorType !== EDITOR_TYPE__INLINE) {
|
|
909
925
|
const style = {};
|
|
910
926
|
if (defaults?.labelWidth) {
|
|
911
927
|
style.width = defaults.labelWidth;
|
|
@@ -933,7 +949,7 @@ function Form(props) {
|
|
|
933
949
|
{element}
|
|
934
950
|
</VStack>;
|
|
935
951
|
}
|
|
936
|
-
} else if (disableLabels && requiredIndicator) {
|
|
952
|
+
} else if ((disableLabels || disableLabel) && requiredIndicator) {
|
|
937
953
|
element = <HStack className="Form-HStack10 w-full">
|
|
938
954
|
{requiredIndicator}
|
|
939
955
|
{element}
|
|
@@ -1274,7 +1290,10 @@ function Form(props) {
|
|
|
1274
1290
|
showCancelBtn = false,
|
|
1275
1291
|
showSaveBtn = false,
|
|
1276
1292
|
showSubmitBtn = false,
|
|
1277
|
-
isAddMode = getEditorMode() === EDITOR_MODE__ADD
|
|
1293
|
+
isAddMode = getEditorMode() === EDITOR_MODE__ADD,
|
|
1294
|
+
isEditableMode =
|
|
1295
|
+
getEditorMode() === EDITOR_MODE__ADD ||
|
|
1296
|
+
getEditorMode() === EDITOR_MODE__EDIT;
|
|
1278
1297
|
if (containerWidth) { // we need to render this component twice in order to get the container width. Skip this on first render
|
|
1279
1298
|
|
|
1280
1299
|
// create editor
|
|
@@ -1363,7 +1382,7 @@ function Form(props) {
|
|
|
1363
1382
|
if (onDelete && getEditorMode() === EDITOR_MODE__EDIT && isSingle) {
|
|
1364
1383
|
showDeleteBtn = true;
|
|
1365
1384
|
}
|
|
1366
|
-
if (!isEditorViewOnly && !hideResetButton) {
|
|
1385
|
+
if (!isEditorViewOnly && isEditableMode && !hideResetButton) {
|
|
1367
1386
|
showResetBtn = true;
|
|
1368
1387
|
}
|
|
1369
1388
|
// determine whether we should show the close or cancel button
|
|
@@ -1394,7 +1413,7 @@ function Form(props) {
|
|
|
1394
1413
|
}
|
|
1395
1414
|
}
|
|
1396
1415
|
}
|
|
1397
|
-
if (!isEditorViewOnly && onSave) {
|
|
1416
|
+
if (!isEditorViewOnly && isEditableMode && onSave) {
|
|
1398
1417
|
showSaveBtn = true;
|
|
1399
1418
|
}
|
|
1400
1419
|
if (!!onSubmit) {
|
|
@@ -375,9 +375,11 @@ const GridRow = forwardRef((props, ref) => {
|
|
|
375
375
|
// TODO: incorporate better scrollbar formatting with
|
|
376
376
|
// tailwind plugin 'tailwind-scrollbar' (already installed, just not yet used here)
|
|
377
377
|
|
|
378
|
+
const isEmptyCellValue = _.isNil(value) || value === '';
|
|
379
|
+
|
|
378
380
|
let textClassName = clsx(
|
|
379
381
|
'GridRow-TextNative',
|
|
380
|
-
'self-center',
|
|
382
|
+
isEmptyCellValue ? 'self-stretch' : 'self-center', // if the cell value is empty, stretch the cell to be full height
|
|
381
383
|
areCellsScrollable ? 'overflow-auto' : 'overflow-hidden',
|
|
382
384
|
'[&::-webkit-scrollbar]:h-2',
|
|
383
385
|
'[&::-webkit-scrollbar-thumb]:bg-gray-300',
|
|
@@ -386,6 +388,14 @@ const GridRow = forwardRef((props, ref) => {
|
|
|
386
388
|
styles.GRID_CELL_CLASSNAME,
|
|
387
389
|
styles.GRID_ROW_MAX_HEIGHT_EXTRA,
|
|
388
390
|
);
|
|
391
|
+
const textStyle = {
|
|
392
|
+
// userSelect: 'none',
|
|
393
|
+
...colStyle,
|
|
394
|
+
...(isEmptyCellValue ? { // if the cell value is empty, stretch the cell to be full height
|
|
395
|
+
height: '100%',
|
|
396
|
+
display: 'block',
|
|
397
|
+
} : {}),
|
|
398
|
+
};
|
|
389
399
|
if (rowProps?._cell?.className) {
|
|
390
400
|
textClassName += ' ' + rowProps._cell.className;
|
|
391
401
|
}
|
|
@@ -395,16 +405,13 @@ const GridRow = forwardRef((props, ref) => {
|
|
|
395
405
|
return <TextNative
|
|
396
406
|
{...testProps('cell-' + config.fieldName)}
|
|
397
407
|
key={key}
|
|
398
|
-
style={
|
|
399
|
-
// userSelect: 'none',
|
|
400
|
-
...colStyle,
|
|
401
|
-
}}
|
|
408
|
+
style={textStyle}
|
|
402
409
|
numberOfLines={1}
|
|
403
410
|
ellipsizeMode="head"
|
|
404
411
|
className={textClassName}
|
|
405
412
|
{...elementProps}
|
|
406
413
|
{...propsToPass}
|
|
407
|
-
>{value}</TextNative>;
|
|
414
|
+
>{isEmptyCellValue ? ' ' : value}</TextNative>;
|
|
408
415
|
});
|
|
409
416
|
} else {
|
|
410
417
|
// TODO: if 'columnsConfig' is an object, parse its contents
|
|
@@ -36,6 +36,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
36
36
|
disableAdd = false,
|
|
37
37
|
disableEdit = false,
|
|
38
38
|
disableDelete = false,
|
|
39
|
+
enableMultiDelete = false, // deleting multiple records at once is opt-in only
|
|
39
40
|
disableDuplicate = false,
|
|
40
41
|
disableView = false,
|
|
41
42
|
useRemoteDuplicate = false, // call specific copyToNew function on server, rather than simple duplicate on client
|
|
@@ -441,7 +442,14 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
441
442
|
cb = args;
|
|
442
443
|
}
|
|
443
444
|
const selection = getSelection();
|
|
444
|
-
|
|
445
|
+
const hasTreeSelection = isTree || _.some(selection, (selected) => !!selected?.isTree);
|
|
446
|
+
if (
|
|
447
|
+
_.isEmpty(selection) ||
|
|
448
|
+
(_.isArray(selection) && (
|
|
449
|
+
selection[0]?.isDestroyed ||
|
|
450
|
+
(selection.length > 1 && (!enableMultiDelete || hasTreeSelection))
|
|
451
|
+
))
|
|
452
|
+
) {
|
|
445
453
|
return;
|
|
446
454
|
}
|
|
447
455
|
if (onBeforeDelete) {
|
|
@@ -461,11 +469,11 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
461
469
|
const
|
|
462
470
|
isSingle = selection.length === 1,
|
|
463
471
|
firstSelection = selection[0],
|
|
464
|
-
|
|
465
|
-
hasChildren =
|
|
472
|
+
isTreeNode = firstSelection?.isTree,
|
|
473
|
+
hasChildren = isTreeNode ? firstSelection?.hasChildren : false,
|
|
466
474
|
isPhantom = firstSelection?.isPhantom;
|
|
467
475
|
|
|
468
|
-
if (isSingle &&
|
|
476
|
+
if (isSingle && isTreeNode && hasChildren) {
|
|
469
477
|
alert({
|
|
470
478
|
title: 'Move up children?',
|
|
471
479
|
message: 'The node you have selected for deletion has children. ' +
|
|
@@ -1022,6 +1030,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
1022
1030
|
isEditor={true}
|
|
1023
1031
|
userCanEdit={userCanEdit}
|
|
1024
1032
|
userCanView={userCanView}
|
|
1033
|
+
enableMultiDelete={enableMultiDelete}
|
|
1025
1034
|
disableAdd={disableAdd || isEditorDisabledByParent || isCrudBlockedByInheritedView}
|
|
1026
1035
|
disableEdit={disableEdit || isEditorDisabledByParent || isCrudBlockedByInheritedView}
|
|
1027
1036
|
disableDelete={disableDelete || isEditorDisabledByParent || isCrudBlockedByInheritedView}
|
|
@@ -97,7 +97,7 @@ export default function withFilters(WrappedComponent) {
|
|
|
97
97
|
|
|
98
98
|
let title, type;
|
|
99
99
|
if (propertyDef) {
|
|
100
|
-
title = propertyDef.title;
|
|
100
|
+
title = propertyDef.filterTitle || propertyDef.title;
|
|
101
101
|
type = propertyDef.filterType;
|
|
102
102
|
} else if (modelAncillaryFilters[field]) {
|
|
103
103
|
const ancillaryFilter = modelFilterTypes[field];
|
|
@@ -262,7 +262,7 @@ export default function withFilters(WrappedComponent) {
|
|
|
262
262
|
|
|
263
263
|
if (!title) {
|
|
264
264
|
const propertyDef = Repository.getSchema().getPropertyDefinition(field);
|
|
265
|
-
title = propertyDef?.title;
|
|
265
|
+
title = propertyDef?.filterTitle || propertyDef?.title;
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
if (_.isString(filterType)) {
|
|
@@ -398,7 +398,10 @@ export default function withFilters(WrappedComponent) {
|
|
|
398
398
|
|
|
399
399
|
// basic property filter
|
|
400
400
|
const propertyDef = Repository.getSchema().getPropertyDefinition(filterField);
|
|
401
|
-
|
|
401
|
+
if (propertyDef?.isFilteringDisabled) {
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
data.push([ filterField, propertyDef?.filterTitle || propertyDef?.title ]);
|
|
402
405
|
});
|
|
403
406
|
|
|
404
407
|
// sort by title
|
|
@@ -62,9 +62,9 @@ export default function withPdfButtons(WrappedComponent) {
|
|
|
62
62
|
buildModalItems = () => {
|
|
63
63
|
// Build a cloned PDF item tree so we never mutate source items by reference.
|
|
64
64
|
const
|
|
65
|
-
|
|
65
|
+
itemsToUse = pdfItems || _.filter(items, (item) => item?.type !== 'Hidden'),
|
|
66
66
|
ancillaryItemsToUse = pdfAncillaryItems || ancillaryItems,
|
|
67
|
-
modalItems = _.compact(_.map(
|
|
67
|
+
modalItems = _.compact(_.map(itemsToUse, (item, ix) => buildNextLayer(item, ix, columnDefaults)));
|
|
68
68
|
|
|
69
69
|
if (!_.isEmpty(ancillaryItemsToUse)) {
|
|
70
70
|
const
|
|
@@ -179,7 +179,7 @@ export default function withPdfButtons(WrappedComponent) {
|
|
|
179
179
|
type: 'Checkbox',
|
|
180
180
|
name,
|
|
181
181
|
title: resolvedTitle,
|
|
182
|
-
|
|
182
|
+
label: resolvedTitle,
|
|
183
183
|
};
|
|
184
184
|
},
|
|
185
185
|
buildValidator = () => {
|
|
@@ -228,6 +228,7 @@ export default function withPdfButtons(WrappedComponent) {
|
|
|
228
228
|
parent={self}
|
|
229
229
|
reference="chooseFieldsForm"
|
|
230
230
|
editorType={EDITOR_TYPE__PLAIN}
|
|
231
|
+
checkIsEditingDisabled={false /* hack so layout looks right */}
|
|
231
232
|
alert={alert}
|
|
232
233
|
columnDefaults={{
|
|
233
234
|
labelWidth: '100px',
|
|
@@ -75,6 +75,7 @@ export default function withPresetButtons(WrappedComponent) {
|
|
|
75
75
|
disableAdd = !isEditor,
|
|
76
76
|
disableEdit = !isEditor,
|
|
77
77
|
disableDelete = !isEditor,
|
|
78
|
+
enableMultiDelete = false,
|
|
78
79
|
disableView = isTree,
|
|
79
80
|
disableCopy = isTree,
|
|
80
81
|
disableDuplicate = !isEditor,
|
|
@@ -300,7 +301,7 @@ export default function withPresetButtons(WrappedComponent) {
|
|
|
300
301
|
icon = Trash;
|
|
301
302
|
if (isNoSelectorSelected() ||
|
|
302
303
|
isEmptySelection() ||
|
|
303
|
-
isMultiSelection() ||
|
|
304
|
+
(isMultiSelection() && (!enableMultiDelete || isTree)) ||
|
|
304
305
|
isProtectedValue() ||
|
|
305
306
|
(canRecordBeDeleted && !canRecordBeDeleted(selection))
|
|
306
307
|
) {
|
|
@@ -435,6 +436,10 @@ export default function withPresetButtons(WrappedComponent) {
|
|
|
435
436
|
showInfo('Copied to clipboard!');
|
|
436
437
|
}
|
|
437
438
|
},
|
|
439
|
+
getColumnsConfigForDownload = () => {
|
|
440
|
+
const activeColumnsConfig = localColumnsConfig.length ? localColumnsConfig : props.columnsConfig;
|
|
441
|
+
return _.filter(activeColumnsConfig, (config) => !config.isHidden);
|
|
442
|
+
},
|
|
438
443
|
onUploadDownload = () => {
|
|
439
444
|
const onUploadDecorator = async () => {
|
|
440
445
|
if (onUpload) {
|
|
@@ -453,7 +458,7 @@ export default function withPresetButtons(WrappedComponent) {
|
|
|
453
458
|
reference="uploadsDownloads"
|
|
454
459
|
onClose={hideModal}
|
|
455
460
|
Repository={Repository}
|
|
456
|
-
columnsConfig={
|
|
461
|
+
columnsConfig={getColumnsConfigForDownload()}
|
|
457
462
|
uploadHeaders={uploadHeaders}
|
|
458
463
|
uploadParams={uploadParams}
|
|
459
464
|
onUpload={onUploadDecorator}
|
|
@@ -470,7 +475,7 @@ export default function withPresetButtons(WrappedComponent) {
|
|
|
470
475
|
onClose={hideModal}
|
|
471
476
|
isDownloadOnly={true}
|
|
472
477
|
Repository={Repository}
|
|
473
|
-
columnsConfig={
|
|
478
|
+
columnsConfig={getColumnsConfigForDownload()}
|
|
474
479
|
downloadHeaders={downloadHeaders}
|
|
475
480
|
downloadParams={downloadParams}
|
|
476
481
|
/>,
|
|
@@ -22,6 +22,7 @@ function ScreenHeader(props) {
|
|
|
22
22
|
const {
|
|
23
23
|
title,
|
|
24
24
|
icon,
|
|
25
|
+
additionalButtons,
|
|
25
26
|
info,
|
|
26
27
|
_info = {},
|
|
27
28
|
useModeIcons = false,
|
|
@@ -88,6 +89,7 @@ function ScreenHeader(props) {
|
|
|
88
89
|
tooltip="To side editor"
|
|
89
90
|
/>
|
|
90
91
|
</>}
|
|
92
|
+
{additionalButtons}
|
|
91
93
|
{info &&
|
|
92
94
|
<IconButton
|
|
93
95
|
{...testProps('infoBtn')}
|
|
@@ -107,6 +107,14 @@ function Viewer(props) {
|
|
|
107
107
|
}),
|
|
108
108
|
isSideEditor = editorType === EDITOR_TYPE__SIDE,
|
|
109
109
|
isSmartEditor = editorType === EDITOR_TYPE__SMART,
|
|
110
|
+
parentEditorModeRaw = (getEditorMode && getEditorMode()) || editorMode || null,
|
|
111
|
+
parentEditorMode = parentEditorModeRaw === EDITOR_MODE__ADD
|
|
112
|
+
? EDITOR_MODE__EDIT
|
|
113
|
+
: parentEditorModeRaw,
|
|
114
|
+
normalizedParentEditorMode =
|
|
115
|
+
parentEditorMode === EDITOR_MODE__EDIT || parentEditorMode === EDITOR_MODE__VIEW
|
|
116
|
+
? parentEditorMode
|
|
117
|
+
: null,
|
|
110
118
|
styles = UiGlobals.styles,
|
|
111
119
|
flex = props.flex || 1,
|
|
112
120
|
buildFromItems = () => {
|
|
@@ -125,6 +133,7 @@ function Viewer(props) {
|
|
|
125
133
|
title,
|
|
126
134
|
name,
|
|
127
135
|
label,
|
|
136
|
+
disableLabel = false,
|
|
128
137
|
items,
|
|
129
138
|
useSelectorId = false,
|
|
130
139
|
isHidden = false,
|
|
@@ -160,7 +169,11 @@ function Viewer(props) {
|
|
|
160
169
|
type = 'Text';
|
|
161
170
|
}
|
|
162
171
|
}
|
|
163
|
-
const
|
|
172
|
+
const
|
|
173
|
+
Element = getComponentFromType(type),
|
|
174
|
+
shouldHideFieldUi = type === 'Hidden',
|
|
175
|
+
isCombo = type?.match && type.match(/Combo/);
|
|
176
|
+
|
|
164
177
|
if (item.hasOwnProperty('autoLoad')) {
|
|
165
178
|
viewerTypeProps.autoLoad = item.autoLoad;
|
|
166
179
|
} else {
|
|
@@ -175,7 +188,6 @@ function Viewer(props) {
|
|
|
175
188
|
if (type?.match(/(Grid|GridEditor)$/)) {
|
|
176
189
|
viewerTypeProps.canEditorViewOnly = true;
|
|
177
190
|
}
|
|
178
|
-
const Element = getComponentFromType(type);
|
|
179
191
|
|
|
180
192
|
if (inArray(type, ['Column', 'Row', 'FieldSet'])) {
|
|
181
193
|
if (_.isEmpty(items)) {
|
|
@@ -264,6 +276,10 @@ function Viewer(props) {
|
|
|
264
276
|
>{children}</Element>;
|
|
265
277
|
}
|
|
266
278
|
|
|
279
|
+
if (shouldHideFieldUi) {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
|
|
267
283
|
if (!label && Repository && propertyDef?.title) {
|
|
268
284
|
label = propertyDef.title;
|
|
269
285
|
}
|
|
@@ -334,7 +350,7 @@ function Viewer(props) {
|
|
|
334
350
|
</HStack>;
|
|
335
351
|
}
|
|
336
352
|
|
|
337
|
-
if (!disableLabels && label) {
|
|
353
|
+
if (!disableLabels && !disableLabel && label) {
|
|
338
354
|
const style = {};
|
|
339
355
|
if (defaults?.labelWidth) {
|
|
340
356
|
style.width = defaults.labelWidth;
|
|
@@ -359,14 +375,6 @@ function Viewer(props) {
|
|
|
359
375
|
buildAncillary = () => {
|
|
360
376
|
const
|
|
361
377
|
validAncillaryItems = _.filter(ancillaryItems, (item) => !!item), // filter out any null/undefined items
|
|
362
|
-
parentEditorModeRaw = (getEditorMode && getEditorMode()) || editorMode || null,
|
|
363
|
-
parentEditorMode = parentEditorModeRaw === EDITOR_MODE__ADD
|
|
364
|
-
? EDITOR_MODE__EDIT
|
|
365
|
-
: parentEditorModeRaw,
|
|
366
|
-
normalizedParentEditorMode =
|
|
367
|
-
parentEditorMode === EDITOR_MODE__EDIT || parentEditorMode === EDITOR_MODE__VIEW
|
|
368
|
-
? parentEditorMode
|
|
369
|
-
: null,
|
|
370
378
|
components = [];
|
|
371
379
|
setAncillaryButtons([]);
|
|
372
380
|
if (validAncillaryItems.length) {
|
|
@@ -584,7 +592,7 @@ function Viewer(props) {
|
|
|
584
592
|
|
|
585
593
|
<Toolbar className="justify-end">
|
|
586
594
|
<HStack className="flex-1 items-center">
|
|
587
|
-
<Text className="text-[20px] ml-1 text-grey-500">{isEditorModeControlledByParent ? 'View Mode (Inherited)' : 'View Mode'}</Text>
|
|
595
|
+
<Text className="text-[20px] ml-1 text-grey-500">{isEditorModeControlledByParent && normalizedParentEditorMode === EDITOR_MODE__VIEW ? 'View Mode (Inherited)' : 'View Mode'}</Text>
|
|
588
596
|
</HStack>
|
|
589
597
|
{onEditMode && (!canUser || canUser(EDIT)) &&
|
|
590
598
|
<Button
|
|
@@ -18,6 +18,11 @@ import Upload from '../Icons/Upload';
|
|
|
18
18
|
import Cookies from 'js-cookie';
|
|
19
19
|
import _ from 'lodash';
|
|
20
20
|
|
|
21
|
+
const
|
|
22
|
+
MODES__GRID = 'grid',
|
|
23
|
+
MODES__BATCH = 'batch',
|
|
24
|
+
MODES__TEMPLATE = 'template';
|
|
25
|
+
|
|
21
26
|
function UploadsDownloadsWindow(props) {
|
|
22
27
|
const {
|
|
23
28
|
Repository,
|
|
@@ -37,8 +42,8 @@ function UploadsDownloadsWindow(props) {
|
|
|
37
42
|
showInfo,
|
|
38
43
|
} = props,
|
|
39
44
|
[importFile, setImportFile] = useState(null),
|
|
40
|
-
[width, height] = useAdjustedWindowSize(400,
|
|
41
|
-
onDownload = (
|
|
45
|
+
[width, height] = useAdjustedWindowSize(400, 550),
|
|
46
|
+
onDownload = (mode) => {
|
|
42
47
|
|
|
43
48
|
const win = window.open('');
|
|
44
49
|
win.document.write('<html><head><title>Downloading</title></head><body><img style="position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);" src="' +
|
|
@@ -63,7 +68,7 @@ function UploadsDownloadsWindow(props) {
|
|
|
63
68
|
columns,
|
|
64
69
|
order,
|
|
65
70
|
model,
|
|
66
|
-
|
|
71
|
+
mode,
|
|
67
72
|
...Repository._params,
|
|
68
73
|
...downloadParams,
|
|
69
74
|
}),
|
|
@@ -79,9 +84,6 @@ function UploadsDownloadsWindow(props) {
|
|
|
79
84
|
}
|
|
80
85
|
}, 1000);
|
|
81
86
|
},
|
|
82
|
-
onDownloadTemplate = () => {
|
|
83
|
-
onDownload(true);
|
|
84
|
-
},
|
|
85
87
|
onUploadLocal = async () => {
|
|
86
88
|
const
|
|
87
89
|
url = Repository.api.baseURL + Repository.name + '/uploadBatch',
|
|
@@ -130,24 +132,40 @@ function UploadsDownloadsWindow(props) {
|
|
|
130
132
|
const items = [
|
|
131
133
|
{
|
|
132
134
|
type: 'DisplayField',
|
|
133
|
-
text:
|
|
135
|
+
text: "Get the current grid's contents as an Excel file.",
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: 'Button',
|
|
139
|
+
text: 'Get as Excel',
|
|
140
|
+
isEditable: false,
|
|
141
|
+
icon: Excel,
|
|
142
|
+
_icon: {
|
|
143
|
+
size: 'md',
|
|
144
|
+
},
|
|
145
|
+
onPress: () => onDownload(MODES__GRID),
|
|
146
|
+
className: 'mb-5',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
type: 'DisplayField',
|
|
150
|
+
text: "Batch download the current grid's records,\n"
|
|
151
|
+
+ "so they can be edited and re-uploaded.",
|
|
134
152
|
},
|
|
135
153
|
{
|
|
136
154
|
type: 'Button',
|
|
137
|
-
text: 'Download',
|
|
155
|
+
text: 'Batch Download',
|
|
138
156
|
isEditable: false,
|
|
139
157
|
icon: Excel,
|
|
140
158
|
_icon: {
|
|
141
159
|
size: 'md',
|
|
142
160
|
},
|
|
143
|
-
onPress: () => onDownload(),
|
|
161
|
+
onPress: () => onDownload(MODES__BATCH),
|
|
144
162
|
className: 'mb-5',
|
|
145
163
|
},
|
|
146
164
|
];
|
|
147
165
|
if (!isDownloadOnly) {
|
|
148
166
|
items.push({
|
|
149
167
|
type: 'DisplayField',
|
|
150
|
-
text: '
|
|
168
|
+
text: 'Batch upload an Excel file to the current grid.',
|
|
151
169
|
});
|
|
152
170
|
items.push({
|
|
153
171
|
type: 'File',
|
|
@@ -161,7 +179,7 @@ function UploadsDownloadsWindow(props) {
|
|
|
161
179
|
items: [
|
|
162
180
|
{
|
|
163
181
|
type: 'Button',
|
|
164
|
-
text: 'Upload',
|
|
182
|
+
text: 'Batch Upload',
|
|
165
183
|
isEditable: false,
|
|
166
184
|
icon: Upload,
|
|
167
185
|
_icon: {
|
|
@@ -175,7 +193,7 @@ function UploadsDownloadsWindow(props) {
|
|
|
175
193
|
text: 'Get Template',
|
|
176
194
|
icon: Download,
|
|
177
195
|
isEditable: false,
|
|
178
|
-
onPress:
|
|
196
|
+
onPress: () => onDownload(MODES__TEMPLATE),
|
|
179
197
|
},
|
|
180
198
|
|
|
181
199
|
],
|