@onehat/ui 0.3.375 → 0.3.379

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.375",
3
+ "version": "0.3.379",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -542,12 +542,8 @@ export default function withFilters(WrappedComponent) {
542
542
  newSlots = _.clone(modalSlots),
543
543
  i = searchAllText ? ixPlusOne : ix; // compensate for 'q' filter's possible presence
544
544
 
545
- if (newFilters[i]?.value) {
546
- newFilters[i].value = value;
547
- } else {
548
- newFilters[i] = getFormattedFilter(value);
549
- }
550
- newSlots[ix] = value;
545
+ newFilters[i] = getFormattedFilter(value);
546
+ newSlots[i] = value;
551
547
 
552
548
  setModalFilters(newFilters);
553
549
  setModalSlots(newSlots);
@@ -10,21 +10,19 @@ import {
10
10
  UI_MODE_WEB,
11
11
  CURRENT_MODE,
12
12
  } from '../../Constants/UiModes.js';
13
+ import {
14
+ REPORT_TYPES__EXCEL,
15
+ REPORT_TYPES__PDF,
16
+ } from '../../Constants/ReportTypes.js';
13
17
  import Form from '../Form/Form.js';
14
18
  import withComponent from '../Hoc/withComponent.js';
15
19
  import testProps from '../../Functions/testProps.js';
16
20
  import ChartLine from '../Icons/ChartLine.js';
17
21
  import Pdf from '../Icons/Pdf.js';
18
22
  import Excel from '../Icons/Excel.js';
19
- import UiGlobals from '../../UiGlobals.js';
20
- import downloadInBackground from '../../Functions/downloadInBackground.js';
21
- import downloadWithFetch from '../../Functions/downloadWithFetch.js';
23
+ import getReport from '../../Functions/getReport.js';
22
24
  import _ from 'lodash';
23
25
 
24
- const
25
- PDF = 'PDF',
26
- EXCEL = 'PhpOffice';
27
-
28
26
  function Report(props) {
29
27
  if (CURRENT_MODE !== UI_MODE_WEB) {
30
28
  return <Text>Reports are web only!</Text>;
@@ -40,30 +38,7 @@ function Report(props) {
40
38
  showReportHeaders = true,
41
39
  h = '300px',
42
40
  } = props,
43
- url = UiGlobals.baseURL + 'Reports/getReport',
44
- buttons = [],
45
- getReport = (reportType, data) => {
46
- const params = {
47
- report_id: reportId,
48
- outputFileType: reportType,
49
- showReportHeaders,
50
- // download_token, // not sure this is needed
51
- ...data,
52
- };
53
-
54
- if (reportType === EXCEL) {
55
- downloadInBackground(url, params);
56
- } else {
57
- const options = {
58
- method: 'POST',
59
- headers: {
60
- 'Content-Type': 'application/json',
61
- },
62
- body: JSON.stringify(params),
63
- };
64
- downloadWithFetch(url, options);
65
- }
66
- };
41
+ buttons = [];
67
42
 
68
43
  const propsIcon = props._icon || {};
69
44
  propsIcon.size = 60;
@@ -86,7 +61,12 @@ function Report(props) {
86
61
  key: 'excelBtn',
87
62
  text: 'Download Excel',
88
63
  leftIcon: <Icon as={Excel} size="md" color="#fff" />,
89
- onPress: (data) => getReport(EXCEL, data),
64
+ onPress: (data) => getReport({
65
+ reportId,
66
+ data,
67
+ reportType: REPORT_TYPES__EXCEL,
68
+ showReportHeaders,
69
+ }),
90
70
  ml: 1,
91
71
  });
92
72
  }
@@ -96,7 +76,12 @@ function Report(props) {
96
76
  key: 'pdfBtn',
97
77
  text: 'Download PDF',
98
78
  leftIcon: <Icon as={Pdf} size="md" color="#fff" />,
99
- onPress: (data) => getReport(PDF, data),
79
+ onPress: (data) => getReport({
80
+ reportId,
81
+ data,
82
+ reportType: REPORT_TYPES__PDF,
83
+ showReportHeaders,
84
+ }),
100
85
  ml: 1,
101
86
  });
102
87
  }
@@ -50,6 +50,7 @@ import Input from '../Form/Field/Input.js';
50
50
  import Xmark from '../Icons/Xmark.js';
51
51
  import Dot from '../Icons/Dot.js';
52
52
  import Collapse from '../Icons/Collapse.js';
53
+ import Expand from '../Icons/Expand.js';
53
54
  import FolderClosed from '../Icons/FolderClosed.js';
54
55
  import FolderOpen from '../Icons/FolderOpen.js';
55
56
  import MagnifyingGlass from '../Icons/MagnifyingGlass.js';
@@ -354,16 +355,17 @@ function TreeComponent(props) {
354
355
 
355
356
  buildRowToDatumMap();
356
357
  },
357
- onCollapseAll = (setNewTreeNodeData = true) => {
358
- // Go through whole tree and collapse all nodes
358
+ onCollapseAll = () => {
359
359
  const newTreeNodeData = _.clone(getTreeNodeData());
360
360
  collapseNodes(newTreeNodeData);
361
-
362
- if (setNewTreeNodeData) {
361
+ setTreeNodeData(newTreeNodeData);
362
+ },
363
+ onExpandAll = () => {
364
+ confirm('Are you sure you want to expand the whole tree? This may take a while.', async () => {
365
+ const newTreeNodeData = _.clone(getTreeNodeData());
366
+ await expandNodes(newTreeNodeData);
363
367
  setTreeNodeData(newTreeNodeData);
364
- }
365
- buildRowToDatumMap();
366
- return newTreeNodeData;
368
+ });
367
369
  },
368
370
  onSearchTree = async (q) => {
369
371
  let found = [];
@@ -655,6 +657,10 @@ function TreeComponent(props) {
655
657
 
656
658
  try {
657
659
 
660
+ if (depth === 'all') {
661
+ depth = 9999;
662
+ }
663
+
658
664
  const children = await datum.item.loadChildren(depth);
659
665
  datum.children = buildTreeNodeData(children);
660
666
  datum.isExpanded = true;
@@ -685,6 +691,25 @@ function TreeComponent(props) {
685
691
  }
686
692
  });
687
693
  },
694
+ expandNodes = async (nodes) => {
695
+ await expandNodesRecursive(nodes);
696
+ buildRowToDatumMap();
697
+ },
698
+ expandNodesRecursive = async (nodes) => {
699
+ // TODO: instead of doing everything sequentially,
700
+ // load the tree in parallel, using aync functions
701
+ // Every time a node loads, it should update the tree.
702
+
703
+ for (const node of nodes) {
704
+ if (node.item.hasChildren && !node.item.areChildrenLoaded) {
705
+ await loadChildren(node, 'all');
706
+ }
707
+ node.isExpanded = true;
708
+ if (!_.isEmpty(node.children)) {
709
+ await expandNodesRecursive(node.children);
710
+ }
711
+ }
712
+ },
688
713
  expandPath = async (cPath, highlight = true) => {
689
714
  // First, close the whole tree.
690
715
  let newTreeNodeData = _.clone(getTreeNodeData());
@@ -789,12 +814,19 @@ function TreeComponent(props) {
789
814
  isDisabled: !treeSearchValue.length,
790
815
  },
791
816
  {
792
- key: 'collapseBtn',
817
+ key: 'collapseAllBtn',
793
818
  text: 'Collapse whole tree',
794
819
  handler: onCollapseAll,
795
820
  icon: Collapse,
796
821
  isDisabled: false,
797
822
  },
823
+ {
824
+ key: 'expandAllBtn',
825
+ text: 'Expand whole tree',
826
+ handler: onExpandAll,
827
+ icon: Expand,
828
+ isDisabled: false,
829
+ },
798
830
  ];
799
831
  if (canNodesReorder) {
800
832
  buttons.push({
@@ -0,0 +1,2 @@
1
+ export const REPORT_TYPES__EXCEL = 'PhpOffice';
2
+ export const REPORT_TYPES__PDF = 'PDF';
@@ -0,0 +1,42 @@
1
+ import {
2
+ REPORT_TYPES__EXCEL,
3
+ REPORT_TYPES__PDF,
4
+ } from '../Constants/ReportTypes.js';
5
+ import downloadInBackground from './downloadInBackground.js';
6
+ import downloadWithFetch from './downloadWithFetch.js';
7
+ import UiGlobals from '../UiGlobals.js';
8
+
9
+ export default function getReport(args) {
10
+ const {
11
+ reportId,
12
+ data = {},
13
+ reportType = REPORT_TYPES__EXCEL,
14
+ showReportHeaders = true,
15
+ } = args;
16
+
17
+ if (!reportId) {
18
+ throw Error('downloadReport: report_id is required');
19
+ }
20
+
21
+ const
22
+ url = UiGlobals.baseURL + 'Reports/getReport',
23
+ params = {
24
+ report_id: reportId,
25
+ outputFileType: reportType,
26
+ showReportHeaders,
27
+ ...data,
28
+ };
29
+
30
+ if (reportType === REPORT_TYPES__EXCEL) {
31
+ downloadInBackground(url, params);
32
+ } else {
33
+ const options = {
34
+ method: 'POST',
35
+ headers: {
36
+ 'Content-Type': 'application/json',
37
+ },
38
+ body: JSON.stringify(params),
39
+ };
40
+ downloadWithFetch(url, options);
41
+ }
42
+ };