@onehat/ui 0.2.67 → 0.2.69

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.2.67",
3
+ "version": "0.2.69",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "license": "UNLICENSED",
27
27
  "dependencies": {
28
- "@onehat/data": "^1.18.1",
28
+ "@onehat/data": "^1.18.7",
29
29
  "@hookform/resolvers": "^3.1.1",
30
30
  "@k-renwick/colour-mixer": "^1.2.1",
31
31
  "js-cookie": "^3.0.5",
@@ -15,6 +15,7 @@ import {
15
15
  import getSaved from '../../Functions/getSaved.js';
16
16
  import setSaved from '../../Functions/setSaved.js';
17
17
  import Splitter from './Splitter.js';
18
+ import _ from 'lodash';
18
19
 
19
20
  export default function Container(props) {
20
21
  const {
@@ -881,7 +881,8 @@ export const WindowedGridEditor = withAlert(
881
881
  withPresetButtons(
882
882
  withContextMenu(
883
883
  Grid
884
- )
884
+ ),
885
+ true // isGrid
885
886
  )
886
887
  )
887
888
  )
@@ -901,7 +902,8 @@ export const InlineGridEditor = withAlert(
901
902
  withContextMenu(
902
903
  withFilters(
903
904
  Grid
904
- )
905
+ ),
906
+ true // isGrid
905
907
  )
906
908
  )
907
909
  )
@@ -22,7 +22,7 @@ const presetButtons = [
22
22
  // 'print',
23
23
  ];
24
24
 
25
- export default function withPresetButtons(WrappedComponent) {
25
+ export default function withPresetButtons(WrappedComponent, isGrid = false) {
26
26
  return (props) => {
27
27
  const {
28
28
  // extract and pass
@@ -37,10 +37,10 @@ export default function withPresetButtons(WrappedComponent) {
37
37
  disableAdd = false,
38
38
  disableEdit = false,
39
39
  disableDelete = false,
40
- disableView = false,
41
- disableCopy = false,
42
- disableDuplicate = false,
43
- disablePrint = false,
40
+ disableView = !isGrid,
41
+ disableCopy = !isGrid,
42
+ disableDuplicate = !isGrid,
43
+ disablePrint = !isGrid,
44
44
 
45
45
  // withEditor
46
46
  userCanEdit = true,
@@ -60,14 +60,14 @@ import _ from 'lodash';
60
60
  //////////////////////
61
61
 
62
62
  // I'm thinking if a repository senses that it's a tree, then at initial load
63
- // it should get the root node +1 level of children.
63
+ // it should get the root nodes +1 level of children.
64
64
  //
65
65
  // How would it then subsequently get the proper children?
66
66
  // i.e. When a node gets its children, how will it do this
67
67
  // while maintaining the nodes that already exist there?
68
68
  // We don't want it to *replace* all exisitng nodes!
69
69
  //
70
- // And if the repository does a reload, should it just get root+1 again?
70
+ // And if the repository does a reload, should it just get roots+1 again?
71
71
  // Changing filters would potentially change the tree structure.
72
72
  // Changing sorting would only change the ordering, not what is expanded/collapsed or visible/invisible.
73
73
 
@@ -78,9 +78,6 @@ import _ from 'lodash';
78
78
  // How does this interface with Repository?
79
79
  // Maybe if Repository is not AjaxRepository, everything needs to be present at once!
80
80
 
81
-
82
- // isRootVisible
83
-
84
81
  //////////////////////
85
82
  //////////////////////
86
83
 
@@ -91,7 +88,7 @@ import _ from 'lodash';
91
88
 
92
89
  export function Tree(props) {
93
90
  const {
94
- isRootVisible = true,
91
+ areRootsVisible = true,
95
92
  getAdditionalParams = () => { // URL params needed to get nodes from server (e.g, { venue_id: 1, getEquipment: true, getRentalEquipment: false, }), in addition to filters.
96
93
  return {};
97
94
  },
@@ -111,7 +108,7 @@ export function Tree(props) {
111
108
  }
112
109
  return icon;
113
110
  },
114
- nodeProps = (item) => {
111
+ getNodeProps = (item) => {
115
112
  return {};
116
113
  },
117
114
  noneFoundText,
@@ -170,6 +167,7 @@ export function Tree(props) {
170
167
  [searchFormData, setSearchFormData] = useState([]),
171
168
  [dragNodeSlot, setDragNodeSlot] = useState(null),
172
169
  [dragNodeIx, setDragNodeIx] = useState(),
170
+ [treeSearchValue, setTreeSearchValue] = useState(''),
173
171
  onNodeClick = (item, e) => {
174
172
  const
175
173
  {
@@ -243,13 +241,12 @@ export function Tree(props) {
243
241
  getHeaderToolbarItems = () => {
244
242
  const
245
243
  buttons = [
246
-
247
244
  {
248
245
  key: 'searchBtn',
249
246
  text: 'Search tree',
250
247
  handler: onSearchTree,
251
248
  icon: MagnifyingGlass,
252
- isDisabled: false,
249
+ isDisabled: !treeSearchValue.length,
253
250
  },
254
251
  {
255
252
  key: 'collapseBtn',
@@ -262,7 +259,7 @@ export function Tree(props) {
262
259
  if (canNodesReorder) {
263
260
  buttons.push({
264
261
  key: 'reorderBtn',
265
- text: 'Reorder tree',
262
+ text: 'Enter reorder mode',
266
263
  handler: () => setIsReorderMode(!isReorderMode),
267
264
  icon: isReorderMode ? NoReorderRows : ReorderRows,
268
265
  isDisabled: false,
@@ -274,7 +271,8 @@ export function Tree(props) {
274
271
  key="searchTree"
275
272
  flex={1}
276
273
  placeholder="Search all tree nodes"
277
- onChangeValue={onSearchTree}
274
+ onChangeText={(val) => setTreeSearchValue(val)}
275
+ value={treeSearchValue}
278
276
  autoSubmit={false}
279
277
  />);
280
278
 
@@ -292,11 +290,12 @@ export function Tree(props) {
292
290
  mx: 1,
293
291
  px: 3,
294
292
  },
295
- iconProps = {
293
+ _icon = {
296
294
  alignSelf: 'center',
297
295
  size: styles.TREE_TOOLBAR_ITEMS_ICON_SIZE,
298
296
  h: 20,
299
297
  w: 20,
298
+ color: isDisabled ? styles.TREE_TOOLBAR_ITEMS_DISABLED_COLOR : styles.TREE_TOOLBAR_ITEMS_COLOR,
300
299
  };
301
300
  let {
302
301
  key,
@@ -305,16 +304,11 @@ export function Tree(props) {
305
304
  icon = null,
306
305
  isDisabled = false,
307
306
  } = config;
308
- if (icon) {
309
- const thisIconProps = {
310
- color: isDisabled ? styles.TREE_TOOLBAR_ITEMS_DISABLED_COLOR : styles.TREE_TOOLBAR_ITEMS_COLOR,
311
- };
312
- icon = React.cloneElement(icon, {...iconProps, ...thisIconProps});
313
- }
314
307
  return <IconButton
315
308
  key={key || ix}
316
309
  onPress={handler}
317
310
  icon={icon}
311
+ _icon={_icon}
318
312
  isDisabled={isDisabled}
319
313
  tooltip={text}
320
314
  {...iconButtonProps}
@@ -326,15 +320,14 @@ export function Tree(props) {
326
320
  // renderTreeNode uses this to render the nodes.
327
321
  const
328
322
  isRoot = treeNode.isRoot,
329
- isLeaf = !treeNode.hasChildren,
330
323
  datum = {
331
324
  item: treeNode,
332
325
  text: getNodeText(treeNode),
333
- iconCollapsed: isLeaf ? null : getNodeIcon(treeNode, false),
334
- iconExpanded: isLeaf ? null : getNodeIcon(treeNode, true),
335
- iconLeaf: isLeaf ? getNodeIcon(treeNode) : null,
326
+ iconCollapsed: getNodeIcon(treeNode, false),
327
+ iconExpanded: getNodeIcon(treeNode, true),
328
+ iconLeaf: getNodeIcon(treeNode),
336
329
  isExpanded: isRoot, // all non-root treeNodes are not expanded by default
337
- isVisible: isRoot ? isRootVisible : true,
330
+ isVisible: isRoot ? areRootsVisible : true,
338
331
  children: buildTreeNodeData(treeNode.children), // recursively get data for children
339
332
  };
340
333
 
@@ -348,7 +341,9 @@ export function Tree(props) {
348
341
  return data;
349
342
  },
350
343
  renderTreeNode = (datum) => {
351
- const item = datum.item;
344
+ const
345
+ item = datum.item,
346
+ depth = item.depth;
352
347
  if (item.isDestroyed) {
353
348
  return null;
354
349
  }
@@ -402,7 +397,7 @@ export function Tree(props) {
402
397
  }
403
398
  }}
404
399
  flexDirection="row"
405
- flexGrow={1}
400
+ ml={((areRootsVisible ? depth : depth -1) * 20) + 'px'}
406
401
  >
407
402
  {({
408
403
  isHovered,
@@ -462,7 +457,7 @@ export function Tree(props) {
462
457
  return nodes;
463
458
  },
464
459
  renderAllTreeNodes = () => {
465
- const nodes = [];
460
+ let nodes = [];
466
461
  _.each(treeNodeData, (datum) => {
467
462
  const node = renderTreeNode(datum);
468
463
  if (_.isEmpty(node)) {
@@ -471,6 +466,10 @@ export function Tree(props) {
471
466
 
472
467
  nodes.push(node);
473
468
 
469
+ if (!datum.isExpanded) {
470
+ return;
471
+ }
472
+
474
473
  if (_.isEmpty(datum.children)) {
475
474
  return;
476
475
  }
@@ -480,7 +479,7 @@ export function Tree(props) {
480
479
  return;
481
480
  }
482
481
 
483
- nodes.concat(children);
482
+ nodes = nodes.concat(children);
484
483
  });
485
484
  return nodes;
486
485
  },
@@ -490,7 +489,7 @@ export function Tree(props) {
490
489
  datum.isExpanded = !datum.isExpanded;
491
490
  forceUpdate();
492
491
 
493
- if (datum.item?.repository.isRemote && datum.item.hasChildren && !datum.item.isChildrenLoaded) {
492
+ if (datum.isExpanded && datum.item?.repository.isRemote && datum.item.hasChildren && !datum.item.isChildrenLoaded) {
494
493
  loadChildren(datum, 1);
495
494
  }
496
495
  },
@@ -514,16 +513,16 @@ export function Tree(props) {
514
513
  const newTreeNodeData = _.clone(treeNodeData);
515
514
 
516
515
  // Recursive method to collapse all children
517
- function collapseChildren(children) {
518
- _.each(children, (child) => {
519
- child.isExpanded = true;
520
- if (!_.isEmpty(child.children)) {
521
- collapseChildren(child.children);
516
+ function collapseNodes(nodes) {
517
+ _.each(nodes, (node) => {
518
+ node.isExpanded = false;
519
+ if (!_.isEmpty(node.children)) {
520
+ collapseNodes(node.children);
522
521
  }
523
522
  });
524
523
  }
525
524
 
526
- collapseChildren(newTreeNodeData);
525
+ collapseNodes(newTreeNodeData);
527
526
 
528
527
  if (setNewTreeNodeData) {
529
528
  setTreeNodeData(newTreeNodeData);
@@ -935,7 +934,9 @@ export function Tree(props) {
935
934
 
936
935
  let rootNodes;
937
936
  if (Repository) {
938
- rootNodes = await Repository.getRootNodes(true, 1, getAdditionalParams);
937
+ if (!Repository.areRootNodesLoaded) {
938
+ rootNodes = await Repository.getRootNodes(true, 1, getAdditionalParams);
939
+ }
939
940
  } else {
940
941
  // TODO: Make this work for data array
941
942
 
@@ -1004,14 +1005,12 @@ export function Tree(props) {
1004
1005
  }, [selectorId, selectorSelected]);
1005
1006
 
1006
1007
  const
1007
- headerToolbarItemComponents = useMemo(() => getHeaderToolbarItems(), []),
1008
- footerToolbarItemComponents = useMemo(() => getFooterToolbarItems(), [additionalToolbarButtons, isReorderMode]);
1008
+ headerToolbarItemComponents = useMemo(() => getHeaderToolbarItems(), [treeSearchValue, treeNodeData]),
1009
+ footerToolbarItemComponents = useMemo(() => getFooterToolbarItems(), [additionalToolbarButtons, isReorderMode, treeNodeData]);
1009
1010
 
1010
1011
  if (!isReady) {
1011
1012
  return null;
1012
1013
  }
1013
-
1014
- // Actual TreeNodes
1015
1014
  const treeNodes = renderAllTreeNodes();
1016
1015
 
1017
1016
  // headers & footers
@@ -1031,21 +1030,21 @@ export function Tree(props) {
1031
1030
  w="100%"
1032
1031
  >
1033
1032
  {topToolbar}
1034
- {headerToolbarItemComponents}
1033
+ {headerToolbarItemComponents?.length && <Row>{headerToolbarItemComponents}</Row>}
1035
1034
 
1036
- <Column w="100%" flex={1} borderTopWidth={isLoading ? 2 : 1} borderTopColor={isLoading ? '#f00' : 'trueGray.300'} onClick={() => {
1035
+ <Column w="100%" flex={1} p={2} borderTopWidth={isLoading ? 2 : 1} borderTopColor={isLoading ? '#f00' : 'trueGray.300'} onClick={() => {
1037
1036
  if (!isReorderMode) {
1038
1037
  deselectAll();
1039
1038
  }
1040
1039
  }}>
1041
- {!treeNodes.length ? <NoRecordsFound text={noneFoundText} onRefresh={onRefresh} /> :
1040
+ {!treeNodes?.length ? <NoRecordsFound text={noneFoundText} onRefresh={onRefresh} /> :
1042
1041
  treeNodes}
1043
1042
  </Column>
1044
1043
 
1045
1044
  {treeFooterComponent}
1046
1045
  </Column>
1047
1046
 
1048
- <Modal
1047
+ {/* <Modal
1049
1048
  isOpen={isSearchModalShown}
1050
1049
  onClose={() => setIsSearchModalShown(false)}
1051
1050
  >
@@ -1095,7 +1094,7 @@ export function Tree(props) {
1095
1094
  }}
1096
1095
  />
1097
1096
  </Column>
1098
- </Modal>
1097
+ </Modal> */}
1099
1098
  </>;
1100
1099
 
1101
1100
  }
@@ -1,6 +1,7 @@
1
1
  import { useState, useMemo, } from 'react';
2
2
  import {
3
3
  Box,
4
+ Icon,
4
5
  Row,
5
6
  Text,
6
7
  } from 'native-base';
@@ -20,20 +21,21 @@ export default function TreeNode(props) {
20
21
  bg,
21
22
  datum,
22
23
  onToggle,
24
+ ...propsToPass
23
25
  } = props,
24
26
  styles = UiGlobals.styles,
25
27
  item = datum.item,
26
28
  isPhantom = item.isPhantom,
27
29
  isExpanded = datum.isExpanded,
28
- hasChildren = datum.hasChildren,
29
- depth = datum.depth,
30
+ hasChildren = item.hasChildren,
31
+ depth = item.depth,
30
32
  text = datum.text,
31
33
  iconCollapsed = datum.iconCollapsed,
32
34
  iconExpanded = datum.iconExpanded,
33
35
  iconLeaf = datum.iconLeaf,
34
36
  hash = item?.hash || item;
35
37
 
36
- const icon = hasChildren ? (isExpanded ? iconCollapsed : iconExpanded) : iconLeaf;
38
+ const icon = hasChildren ? (isExpanded ? iconExpanded : iconCollapsed) : iconLeaf;
37
39
 
38
40
  return useMemo(() => {
39
41
 
@@ -47,13 +49,9 @@ export default function TreeNode(props) {
47
49
  >
48
50
  {isPhantom && <Box position="absolute" bg="#f00" h={2} w={2} t={0} l={0} />}
49
51
 
50
- <IconButton
51
- icon={icon}
52
- onPress={onToggle}
53
- />
52
+ {hasChildren ? <IconButton icon={icon} onPress={() => onToggle(datum)} /> : <Icon as={icon} />}
54
53
 
55
54
  <Text
56
- key={key}
57
55
  overflow="hidden"
58
56
  textOverflow="ellipsis"
59
57
  alignSelf="center"