@onehat/ui 0.3.10 → 0.3.13

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onehat/ui",
3
- "version": "0.3.10",
3
+ "version": "0.3.13",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -11,7 +11,7 @@ export default function Editor(props) {
11
11
  const {
12
12
  Form,
13
13
  Viewer,
14
- isEditorViewOnly: isViewOnly,
14
+ isEditorViewOnly,
15
15
  onEditorCancel: onCancel,
16
16
  onEditorSave: onSave,
17
17
  onEditorClose: onClose,
@@ -29,14 +29,14 @@ export default function Editor(props) {
29
29
 
30
30
  if (_.isEmpty(selection)) {
31
31
  return null; // hide the editor when no selection
32
- return <Box {...props} bg="#ddd" />;
33
32
  }
34
33
 
35
- if (Repository?.isRemotePhantomMode && selection.length === 1 && editorMode === EDITOR_MODE__VIEW) {
34
+ // Repository?.isRemotePhantomMode && selection.length === 1 &&
35
+ if (editorMode === EDITOR_MODE__VIEW) {
36
36
  return <Viewer
37
37
  {...props}
38
38
  record={selection[0]}
39
- onEditMode={isViewOnly ? null : onEditMode}
39
+ onEditMode={isEditorViewOnly ? null : onEditMode}
40
40
  onClose={onClose}
41
41
  onDelete={onDelete}
42
42
  />;
@@ -6,6 +6,9 @@ import {
6
6
  Row,
7
7
  Text,
8
8
  } from 'native-base';
9
+ import {
10
+ EDITOR_TYPE__SIDE,
11
+ } from '../../Constants/Editor.js';
9
12
  import UiGlobals from '../../UiGlobals.js';
10
13
  import getComponentFromType from '../../Functions/getComponentFromType.js';
11
14
  import Label from '../Form/Label.js';
@@ -29,10 +32,12 @@ export default function Viewer(props) {
29
32
  selectorSelected,
30
33
 
31
34
  // withEditor
35
+ editorType,
32
36
  onEditMode,
33
37
  onClose,
34
38
  onDelete,
35
39
  } = props,
40
+ isSideEditor = editorType === EDITOR_TYPE__SIDE,
36
41
  styles = UiGlobals.styles,
37
42
  flex = props.flex || 1,
38
43
  buildAncillary = () => {
@@ -45,12 +50,17 @@ export default function Viewer(props) {
45
50
  selectorId = null,
46
51
  ...propsToPass
47
52
  } = item;
53
+ if (!propsToPass.h) {
54
+ propsToPass.h = 400;
55
+ }
48
56
  const
49
57
  Element = getComponentFromType(type),
50
58
  element = <Element
51
59
  selectorId={selectorId}
52
- selectorSelected={selectorId ? record : selectorSelected}
60
+ selectorSelected={selectorSelected || record}
53
61
  flex={1}
62
+ h={350}
63
+ canEditorViewOnly={true}
54
64
  {...propsToPass}
55
65
  />;
56
66
  if (title) {
@@ -65,6 +75,10 @@ export default function Viewer(props) {
65
75
  return components;
66
76
  };
67
77
 
78
+ const
79
+ showDeleteBtn = onDelete && viewerCanDelete,
80
+ showCloseBtn = !isSideEditor;
81
+
68
82
  return <Column flex={flex} {...props}>
69
83
  <ScrollView width="100%" _web={{ height: 1 }}>
70
84
  <Column m={2}>
@@ -88,26 +102,28 @@ export default function Viewer(props) {
88
102
 
89
103
  </Column>
90
104
  </ScrollView>
91
- <Footer justifyContent="flex-end">
92
- {onDelete && viewerCanDelete &&
93
- <Row flex={1} justifyContent="flex-start">
94
- <Button
95
- key="deleteBtn"
96
- onPress={onDelete}
97
- bg="warning"
98
- _hover={{
99
- bg: 'warningHover',
100
- }}
101
- color="#fff"
102
- >Delete</Button>
103
- </Row>}
104
- <Button.Group space={2}>
105
- <Button
106
- key="closeBtn"
107
- onPress={onClose}
108
- color="#fff"
109
- >Close</Button>
110
- </Button.Group>
111
- </Footer>
105
+ {(showDeleteBtn || showCloseBtn) &&
106
+ <Footer justifyContent="flex-end">
107
+ {showDeleteBtn &&
108
+ <Row flex={1} justifyContent="flex-start">
109
+ <Button
110
+ key="deleteBtn"
111
+ onPress={onDelete}
112
+ bg="warning"
113
+ _hover={{
114
+ bg: 'warningHover',
115
+ }}
116
+ color="#fff"
117
+ >Delete</Button>
118
+ </Row>}
119
+ {showCloseBtn &&
120
+ <Button.Group space={2}>
121
+ <Button
122
+ key="closeBtn"
123
+ onPress={onClose}
124
+ color="#fff"
125
+ >Close</Button>
126
+ </Button.Group>}
127
+ </Footer>}
112
128
  </Column>;
113
129
  }
@@ -34,7 +34,7 @@ export function ComboComponent(props) {
34
34
  tooltip = null,
35
35
  menuMinWidth = 150,
36
36
  disableDirectEntry = false,
37
- disablePagination = true,
37
+ disablePagination = false,
38
38
  hideMenuOnSelection = true,
39
39
  _input = {},
40
40
  isEditor = false,
@@ -90,16 +90,12 @@ export function ComboComponent(props) {
90
90
  if (rectTop !== top) {
91
91
  setTop(rectTop);
92
92
  }
93
- setHeight(null);
94
93
  } else {
95
94
  // Menu is above the combo
96
-
97
- const rectTop = rect.top -200;
95
+ const rectTop = rect.top - styles.FORM_COMBO_MENU_HEIGHT;
98
96
  if (rectTop !== top) {
99
97
  setTop(rectTop);
100
98
  }
101
-
102
- setHeight(200);
103
99
  }
104
100
  if (rect.left !== left) {
105
101
  setLeft(rect.left);
@@ -489,14 +485,12 @@ export function ComboComponent(props) {
489
485
  top={top + 'px'}
490
486
  left={left + 'px'}
491
487
  w={width + 'px'}
492
- h={height ? height + 'px' : null}
493
488
  minWidth={menuMinWidth}
494
489
  overflow="auto"
495
490
  bg="#fff"
496
491
  >
497
492
  <Popover.Body
498
493
  ref={menuRef}
499
- maxHeight={200}
500
494
  borderWidth={1}
501
495
  borderColor='trueGray.400'
502
496
  borderTopWidth={0}
@@ -505,8 +499,6 @@ export function ComboComponent(props) {
505
499
  <WhichGrid
506
500
  showHeaders={false}
507
501
  showHovers={true}
508
- pageSize={100}
509
- disableAdjustingPageSizeToHeight={true}
510
502
  shadow={1}
511
503
  getRowProps={() => {
512
504
  return {
@@ -519,6 +511,7 @@ export function ComboComponent(props) {
519
511
  };
520
512
  }}
521
513
  {...props}
514
+ h={styles.FORM_COMBO_MENU_HEIGHT + 'px'}
522
515
  disablePresetButtons={!isEditor}
523
516
  disablePagination={disablePagination}
524
517
  setSelection={(selection) => {
@@ -81,7 +81,7 @@ function Form(props) {
81
81
  Repository,
82
82
 
83
83
  // withEditor
84
- isViewOnly = false,
84
+ isEditorViewOnly = false,
85
85
  editorMode,
86
86
  onCancel,
87
87
  onSave,
@@ -102,6 +102,7 @@ function Form(props) {
102
102
  isMultiple = _.isArray(record),
103
103
  isSingle = !isMultiple, // for convenience
104
104
  forceUpdate = useForceUpdate(),
105
+ [previousRecord, setPreviousRecord] = useState(record),
105
106
  initialValues = _.merge(startingValues, (record && !record.isDestroyed ? record.submitValues : {})),
106
107
  defaultValues = isMultiple ? getNullFieldValues(initialValues, Repository) : initialValues, // when multiple entities, set all default values to null
107
108
  {
@@ -299,7 +300,7 @@ function Form(props) {
299
300
  label = propertyDef.title;
300
301
  }
301
302
 
302
- if (isViewOnly || !isEditable) {
303
+ if (isEditorViewOnly || !isEditable) {
303
304
  const
304
305
  Text = getComponentFromType('Text'),
305
306
  value = (record && record[name]) || (startingValues && startingValues[name]) || null;
@@ -420,6 +421,9 @@ function Form(props) {
420
421
  selectorId,
421
422
  ...propsToPass
422
423
  } = item;
424
+ if (!propsToPass.h) {
425
+ propsToPass.h = 400;
426
+ }
423
427
  const
424
428
  Element = getComponentFromType(type),
425
429
  element = <Element
@@ -444,8 +448,23 @@ function Form(props) {
444
448
  if (editorType === EDITOR_TYPE__INLINE) {
445
449
  alert(errors.message);
446
450
  }
451
+ },
452
+ onSaveDecorated = async (data, e) => {
453
+ // reset the form after a save
454
+ const result = await onSave(data, e);
455
+ if (result) {
456
+ const values = record.submitValues;
457
+ reset(values);
458
+ }
447
459
  };
448
460
 
461
+ useEffect(() => {
462
+ if (record !== previousRecord) {
463
+ setPreviousRecord(record);
464
+ reset(defaultValues);
465
+ }
466
+ }, [record]);
467
+
449
468
  useEffect(() => {
450
469
  if (!Repository) {
451
470
  return () => {};
@@ -585,7 +604,7 @@ function Form(props) {
585
604
  </Row>}
586
605
  <Button.Group space={2} {...buttonGroupProps}>
587
606
 
588
- {!isViewOnly && <IconButton
607
+ {!isEditorViewOnly && <IconButton
589
608
  key="resetBtn"
590
609
  onPress={() => {
591
610
  if (onReset) {
@@ -595,19 +614,19 @@ function Form(props) {
595
614
  }}
596
615
  icon={<Rotate color="#fff" />}
597
616
  />}
598
- {!isViewOnly && onCancel && <Button
617
+ {!isEditorViewOnly && onCancel && <Button
599
618
  key="cancelBtn"
600
619
  variant="ghost"
601
620
  onPress={onCancel}
602
621
  color="#fff"
603
622
  >Cancel</Button>}
604
- {!isViewOnly && onSave && <Button
623
+ {!isEditorViewOnly && onSave && <Button
605
624
  key="saveBtn"
606
- onPress={(e) => handleSubmit(onSave, onSubmitError)(e)}
625
+ onPress={(e) => handleSubmit(onSaveDecorated, onSubmitError)(e)}
607
626
  isDisabled={isSaveDisabled}
608
627
  color="#fff"
609
628
  >{editorMode === EDITOR_MODE__ADD ? 'Add' : 'Save'}</Button>}
610
- {isViewOnly && onClose && <Button
629
+ {isEditorViewOnly && onClose && editorType !== EDITOR_TYPE__SIDE && <Button
611
630
  key="closeBtn"
612
631
  onPress={onClose}
613
632
  color="#fff"
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useRef, useMemo, } from 'react';
1
+ import React, { useState, useEffect, useRef, useMemo, useCallback, } from 'react';
2
2
  import {
3
3
  Column,
4
4
  FlatList,
@@ -104,6 +104,7 @@ function GridComponent(props) {
104
104
  onDuplicate,
105
105
  onReset,
106
106
  onContextMenu,
107
+ isAdding,
107
108
 
108
109
  // withData
109
110
  Repository,
@@ -141,6 +142,7 @@ function GridComponent(props) {
141
142
  styles = UiGlobals.styles,
142
143
  forceUpdate = useForceUpdate(),
143
144
  gridRef = useRef(),
145
+ isAddingRef = useRef(),
144
146
  [isReady, setIsReady] = useState(false),
145
147
  [isLoading, setIsLoading] = useState(false),
146
148
  [localColumnsConfig, setLocalColumnsConfigRaw] = useState([]),
@@ -616,41 +618,34 @@ function GridComponent(props) {
616
618
  setDragRowSlot(null);
617
619
  },
618
620
  onLayout = (e) => {
619
- if (disableAdjustingPageSizeToHeight || !Repository) {
621
+ if (disableAdjustingPageSizeToHeight || !Repository || CURRENT_MODE !== UI_MODE_WEB || !gridRef.current || isAddingRef.current) {
620
622
  return;
621
623
  }
622
- const {
623
- nativeEvent: {
624
- layout,
625
- target,
626
- },
627
- } = e;
628
- let pageSize;
629
- if (CURRENT_MODE === UI_MODE_WEB) {
630
- const
631
- targetBoundingBox = target.getBoundingClientRect(),
632
- targetHeight = targetBoundingBox.height,
633
- firstRow = target.children[0]?.children[0]?.children[0]?.children[0]?.children[0];
634
- if (firstRow) {
635
- const
636
- rowBoundingBox = firstRow.getBoundingClientRect(),
637
- rowHeight = rowBoundingBox.height,
638
- rowsPerTarget = Math.floor(targetHeight / rowHeight);
639
- pageSize = rowsPerTarget;
640
- if (showHeaders) {
641
- pageSize--;
642
- }
643
- if (bottomToolbar) {
644
- pageSize--;
645
- }
646
- }
624
+
625
+ const
626
+ gr = gridRef.current,
627
+ scrollableNode = gr.getScrollableNode(),
628
+ scrollableNodeBoundingBox = scrollableNode.getBoundingClientRect(),
629
+ scrollableNodeHeight = scrollableNodeBoundingBox.height,
630
+ firstRow = scrollableNode.children[0].children[showHeaders ? 1: 0];
631
+
632
+ if (!firstRow) {
633
+ return;
647
634
  }
648
-
649
- if (pageSize) {
635
+
636
+ const
637
+ rowHeight = firstRow.getBoundingClientRect().height,
638
+ rowsPerContainer = Math.floor(scrollableNodeHeight / rowHeight);
639
+ let pageSize = rowsPerContainer;
640
+ if (showHeaders) {
641
+ pageSize--;
642
+ }
643
+ if (pageSize !== Repository.pageSize) {
650
644
  Repository.setPageSize(pageSize);
651
645
  }
652
- };
653
-
646
+ },
647
+ debouncedOnLayout = useCallback(_.debounce(onLayout, 500), []);
648
+
654
649
  useEffect(() => {
655
650
 
656
651
  const calculateLocalColumnsConfig = () => {
@@ -778,6 +773,9 @@ function GridComponent(props) {
778
773
 
779
774
  }, [selectorId, selectorSelected]);
780
775
 
776
+
777
+ isAddingRef.current = isAdding;
778
+
781
779
  const footerToolbarItemComponents = useMemo(() => getFooterToolbarItems(), [additionalToolbarButtons, isDragMode]);
782
780
 
783
781
  if (!isReady) {
@@ -811,18 +809,19 @@ function GridComponent(props) {
811
809
  } else {
812
810
  sizeProps.flex = flex ?? 1;
813
811
  }
812
+
814
813
  return <Column
815
814
  {...testProps('Grid')}
816
815
  w="100%"
817
816
  bg={bg}
818
817
  borderWidth={styles.GRID_BORDER_WIDTH}
819
818
  borderColor={styles.GRID_BORDER_COLOR}
820
- onLayout={onLayout}
819
+ onLayout={debouncedOnLayout}
821
820
  {...sizeProps}
822
821
  >
823
822
  {topToolbar}
824
823
 
825
- <Column w="100%" flex={1} borderTopWidth={isLoading ? 2 : 1} borderTopColor={isLoading ? '#f00' : 'trueGray.300'} onClick={() => {
824
+ <Column w="100%" flex={1} minHeight={40} borderTopWidth={isLoading ? 2 : 1} borderTopColor={isLoading ? '#f00' : 'trueGray.300'} onClick={() => {
826
825
  if (!isDragMode && !isInlineEditorShown) {
827
826
  deselectAll();
828
827
  }
@@ -14,9 +14,9 @@ export default function withEditor(WrappedComponent, isTree = false) {
14
14
 
15
15
  let [editorMode, setEditorMode] = useState(EDITOR_MODE__VIEW); // Can change below, so use 'let'
16
16
  const {
17
- useEditor = true,
18
17
  userCanEdit = true,
19
18
  userCanView = true,
19
+ canEditorViewOnly = false, // whether the editor can *ever* change state out of 'View' mode
20
20
  disableAdd = false,
21
21
  disableEdit = false,
22
22
  disableDelete = false,
@@ -49,8 +49,9 @@ export default function withEditor(WrappedComponent, isTree = false) {
49
49
  listeners = useRef({}),
50
50
  editorStateRef = useRef(),
51
51
  [currentRecord, setCurrentRecord] = useState(null),
52
+ [isAdding, setIsAdding] = useState(false),
52
53
  [isEditorShown, setIsEditorShown] = useState(false),
53
- [isEditorViewOnly, setIsEditorViewOnly] = useState(false),
54
+ [isEditorViewOnly, setIsEditorViewOnly] = useState(canEditorViewOnly), // current state of whether editor is in view-only mode
54
55
  [lastSelection, setLastSelection] = useState(),
55
56
  setSelectionDecorated = (newSelection) => {
56
57
  function doIt() {
@@ -71,7 +72,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
71
72
  // forceUpdate(); // we don't want to get into an infinite loop of renders. Simply directly assign the listeners in every child render
72
73
  },
73
74
  onAdd = async () => {
74
- const defaultValues = Repository.getSchema().model.defaultValues;
75
+ const defaultValues = Repository.getSchema().getDefaultValues();
75
76
  let addValues = _.clone(defaultValues);
76
77
 
77
78
  if (selectorId && !_.isEmpty(selectorSelected)) {
@@ -105,6 +106,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
105
106
  // Unmap the values, so we can input true originalData
106
107
  addValues = Repository.unmapData(addValues);
107
108
 
109
+ setIsAdding(true);
108
110
  const entity = await Repository.add(addValues, false, true);
109
111
  setSelection([entity]);
110
112
  setIsEditorViewOnly(false);
@@ -198,8 +200,8 @@ export default function withEditor(WrappedComponent, isTree = false) {
198
200
  setEditorMode(EDITOR_MODE__VIEW);
199
201
  setIsEditorShown(true);
200
202
 
201
- if (getListeners().onAfterDelete) {
202
- await getListeners().onAfterDelete(entity);
203
+ if (getListeners().onAfterView) {
204
+ await getListeners().onAfterView(entity);
203
205
  }
204
206
  },
205
207
  duplicateRecord = async () => {
@@ -245,11 +247,15 @@ export default function withEditor(WrappedComponent, isTree = false) {
245
247
  }
246
248
 
247
249
  await Repository.save();
250
+
251
+ setIsAdding(false);
248
252
  setIsEditorShown(false);
249
253
 
250
254
  if (getListeners().onAfterEdit) {
251
255
  await getListeners().onAfterEdit(what);
252
256
  }
257
+
258
+ return true;
253
259
  },
254
260
  onEditorCancel = () => {
255
261
  async function doIt() {
@@ -259,6 +265,8 @@ export default function withEditor(WrappedComponent, isTree = false) {
259
265
  if (isSingle && isPhantom) {
260
266
  await deleteRecord();
261
267
  }
268
+
269
+ setIsAdding(false);
262
270
  setEditorMode(EDITOR_MODE__VIEW);
263
271
  setIsEditorShown(false);
264
272
  }
@@ -279,8 +287,8 @@ export default function withEditor(WrappedComponent, isTree = false) {
279
287
  });
280
288
  },
281
289
  calculateEditorMode = () => {
282
- let mode = EDITOR_MODE__VIEW;
283
- if (userCanEdit) {
290
+ let mode = editorMode;
291
+ if (!canEditorViewOnly && userCanEdit) {
284
292
  if (selection.length > 1) {
285
293
  if (!disableEdit) {
286
294
  // For multiple entities selected, change it to edit multiple mode
@@ -314,6 +322,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
314
322
  // When selection changes, set the mode appropriately
315
323
  const mode = calculateEditorMode();
316
324
  setEditorMode(mode);
325
+
317
326
  setLastSelection(selection);
318
327
  }, [selection]);
319
328
 
@@ -329,6 +338,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
329
338
  setCurrentRecord={setCurrentRecord}
330
339
  isEditorShown={isEditorShown}
331
340
  isEditorViewOnly={isEditorViewOnly}
341
+ isAdding={isAdding}
332
342
  editorMode={editorMode}
333
343
  onEditMode={onEditMode}
334
344
  onViewMode={onViewMode}
@@ -345,7 +355,6 @@ export default function withEditor(WrappedComponent, isTree = false) {
345
355
  onEditorClose={onEditorClose}
346
356
  setWithEditListeners={setListeners}
347
357
  isEditor={true}
348
- useEditor={useEditor}
349
358
  userCanEdit={userCanEdit}
350
359
  userCanView={userCanView}
351
360
  disableAdd={disableAdd}
@@ -21,9 +21,8 @@ import _ from 'lodash';
21
21
  export default function withInlineEditor(WrappedComponent) {
22
22
  return withEditor((props) => {
23
23
  const {
24
- useEditor = false,
25
24
  editorType,
26
- isEditorShown,
25
+ isEditorShown = false,
27
26
  setIsEditorShown,
28
27
  isEditorViewOnly,
29
28
  onEditorCancel,
@@ -79,7 +78,7 @@ export default function withInlineEditor(WrappedComponent) {
79
78
  }
80
79
 
81
80
  let inlineEditor = null;
82
- if (useEditor && Repository) {
81
+ if (Repository) {
83
82
  inlineEditor = <>
84
83
  {isEditorShown && <Box
85
84
  ref={maskRef}
@@ -108,7 +107,7 @@ export default function withInlineEditor(WrappedComponent) {
108
107
  record={selection[0]}
109
108
  Repository={Repository}
110
109
  isMultiple={selection.length > 1}
111
- isViewOnly={isEditorViewOnly}
110
+ isEditorViewOnly={isEditorViewOnly}
112
111
  columnsConfig={localColumnsConfig}
113
112
  onCancel={onEditorCancel}
114
113
  onSave={onEditorSave}
@@ -16,8 +16,8 @@ const presetButtons = [
16
16
  'add',
17
17
  'edit',
18
18
  'delete',
19
- 'copy',
20
19
  'view',
20
+ 'copy',
21
21
  'duplicate',
22
22
  // 'print',
23
23
  ];
@@ -41,13 +41,14 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
41
41
  // for local use
42
42
  isEditor = false,
43
43
  isTree = false,
44
- useEditor = true,
44
+ isSideEditor = false,
45
+ canEditorViewOnly = false,
45
46
  disableAdd = !isEditor,
46
47
  disableEdit = !isEditor,
47
48
  disableDelete = !isEditor,
48
49
  disableView = !isGrid,
49
50
  disableCopy = !isGrid,
50
- disableDuplicate = !isGrid,
51
+ disableDuplicate = !isEditor,
51
52
  disablePrint = !isGrid,
52
53
 
53
54
  // withEditor
@@ -61,7 +62,6 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
61
62
 
62
63
  // withSelection
63
64
  selection,
64
- setSelection,
65
65
 
66
66
  // parent container
67
67
  selectorId,
@@ -81,22 +81,22 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
81
81
  let isDisabled = false;
82
82
  switch(type) {
83
83
  case 'add':
84
- if (disableAdd || !useEditor) {
84
+ if (disableAdd || canEditorViewOnly) {
85
85
  isDisabled = true;
86
86
  }
87
87
  break;
88
88
  case 'edit':
89
- if (disableEdit || !useEditor) {
89
+ if (disableEdit || canEditorViewOnly || isSideEditor) {
90
90
  isDisabled = true;
91
91
  }
92
92
  break;
93
93
  case 'delete':
94
- if (disableDelete || !useEditor) {
94
+ if (disableDelete || canEditorViewOnly) {
95
95
  isDisabled = true;
96
96
  }
97
97
  break;
98
98
  case 'view':
99
- if (disableView) {
99
+ if (disableView || isSideEditor) {
100
100
  isDisabled = true;
101
101
  }
102
102
  break;
@@ -106,7 +106,7 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
106
106
  }
107
107
  break;
108
108
  case 'duplicate':
109
- if (disableDuplicate || !useEditor) {
109
+ if (disableDuplicate || canEditorViewOnly) {
110
110
  isDisabled = true;
111
111
  }
112
112
  break;
@@ -250,7 +250,7 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
250
250
  }
251
251
 
252
252
  // Send it to clipboard
253
- navigator.clipboard.writeText(text);
253
+ navigator?.clipboard.writeText(text);
254
254
  };
255
255
  // onPrint = () => {
256
256
  // debugger;
@@ -213,7 +213,7 @@ export default function withSelection(WrappedComponent) {
213
213
  setValue(localValue);
214
214
  }
215
215
  },
216
- conformSelectionToValue = () => {
216
+ conformSelectionToValue = async () => {
217
217
  // adjust the selection to match the value
218
218
  let newSelection = [];
219
219
  if (Repository) {
@@ -222,9 +222,20 @@ export default function withSelection(WrappedComponent) {
222
222
  if (_.isArray(value)) {
223
223
  newSelection = Repository.getBy((entity) => inArray(entity.id, value));
224
224
  } else {
225
- const found = Repository.getById(value);
225
+ let found = Repository.getById(value);
226
226
  if (found) {
227
227
  newSelection.push(found);
228
+ } else if (Repository?.isRemote && Repository?.entities.length) {
229
+
230
+ // Value cannot be found in Repository, but actually exists on server
231
+ // Try to get this value from the server directly
232
+ Repository.filter(Repository.schema.model.idProperty, value);
233
+ await Repository.load();
234
+ found = Repository.getById(value);
235
+ if (found) {
236
+ newSelection.push(found);
237
+ }
238
+
228
239
  }
229
240
  }
230
241
  }
@@ -270,7 +281,7 @@ export default function withSelection(WrappedComponent) {
270
281
 
271
282
  if (usesWithValue && !_.isNil(value)) {
272
283
 
273
- conformSelectionToValue();
284
+ await conformSelectionToValue();
274
285
 
275
286
  } else if (autoSelectFirstItem) {
276
287
  let newSelection = [];
@@ -21,6 +21,7 @@ export default function withSideEditor(WrappedComponent, isTree = false) {
21
21
  return <Container
22
22
  center={<WrappedComponent
23
23
  isTree={isTree}
24
+ isSideEditor={true}
24
25
  {...props}
25
26
  />}
26
27
  east={<Editor
@@ -28,8 +28,7 @@ import _ from 'lodash';
28
28
  export default function withWindowedEditor(WrappedComponent, isTree = false) {
29
29
  return withEditor((props) => {
30
30
  const {
31
- useEditor = false,
32
- isEditorShown,
31
+ isEditorShown = false,
33
32
  setIsEditorShown,
34
33
  Editor,
35
34
  editorProps = {},
@@ -41,7 +40,7 @@ export default function withWindowedEditor(WrappedComponent, isTree = false) {
41
40
 
42
41
  return <>
43
42
  <WrappedComponent {...props} />
44
- {useEditor && isEditorShown &&
43
+ {isEditorShown &&
45
44
  <Modal
46
45
  isOpen={true}
47
46
  onClose={() => setIsEditorShown(false)}
@@ -9,6 +9,7 @@ import {
9
9
  HORIZONTAL,
10
10
  VERTICAL,
11
11
  } from '../../Constants/Directions.js';
12
+ import Inflector from 'inflector-js';
12
13
  import Header from './Header.js';
13
14
  import Mask from './Mask.js';
14
15
  import withCollapsible from '../Hoc/withCollapsible.js';
@@ -33,7 +34,7 @@ function Panel(props) {
33
34
  onLayout = null,
34
35
 
35
36
  // Header
36
- title = props.model,
37
+ title = Inflector.humanize(Inflector.underscore(props.model)),
37
38
  showHeader = true,
38
39
  header = null,
39
40
  isClosable = false,
@@ -60,7 +60,7 @@ export default function ManagerScreen(props) {
60
60
  whichComponent = sideModeComponent;
61
61
  }
62
62
 
63
- return <Column flex={1} w="100%">
63
+ return <Column maxHeight="100vh" overflow="hidden" flex={1} w="100%">
64
64
  <Row
65
65
  h="80px"
66
66
  py={2}
@@ -89,6 +89,8 @@ export default function ManagerScreen(props) {
89
89
  tooltip="Side Editor"
90
90
  />
91
91
  </Row>
92
+
92
93
  {whichComponent}
94
+
93
95
  </Column>;
94
96
  }
@@ -16,6 +16,7 @@ const defaults = {
16
16
  FORM_COMBO_INPUT_FONTSIZE: DEFAULT_FONTSIZE,
17
17
  FORM_COMBO_INPUT_BG: WHITE,
18
18
  FORM_COMBO_INPUT_FOCUS_BG: FOCUS,
19
+ FORM_COMBO_MENU_HEIGHT: 250,
19
20
  FORM_COMBO_TRIGGER_BG: WHITE,
20
21
  FORM_COMBO_TRIGGER_HOVER_BG: 'trueGray.300',
21
22
  FORM_DATE_ICON_BG: 'primary.200',
@@ -49,7 +49,7 @@ function AttachmentsElement(props) {
49
49
 
50
50
  } = props,
51
51
  styles = UiGlobals.styles,
52
- model = selectorSelected?.repository.name,
52
+ model = selectorSelected?.repository?.name,
53
53
  modelid = selectorSelected?.id,
54
54
  [isReady, setIsReady] = useState(false),
55
55
  [isUploading, setIsUploading] = useState(false),