@onehat/ui 0.3.37 → 0.3.39

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.37",
3
+ "version": "0.3.39",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -516,7 +516,7 @@ export function ComboComponent(props) {
516
516
  };
517
517
  }}
518
518
  allowToggleSelection={true}
519
- disableAdjustingPageSizeToHeight={true}
519
+ autoAdjustPageSizeToHeight={false}
520
520
  {...props}
521
521
  h={styles.FORM_COMBO_MENU_HEIGHT + 'px'}
522
522
  disablePresetButtons={!isEditor}
@@ -20,7 +20,7 @@ export default function PageSizeCombo(props) {
20
20
  // [ 1, '1/pg', ],
21
21
  [ 5, '5/pg', ],
22
22
  [ 10, '10/pg', ],
23
- [ 20, '20pg', ],
23
+ [ 20, '20/pg', ],
24
24
  [ 50, '50/pg', ],
25
25
  [ 100, '100/pg', ],
26
26
  ]}
@@ -77,7 +77,7 @@ function GridComponent(props) {
77
77
  pullToRefresh = true,
78
78
  hideNavColumn = true,
79
79
  noneFoundText,
80
- disableAdjustingPageSizeToHeight = false,
80
+ autoAdjustPageSizeToHeight = true,
81
81
  disableLoadingIndicator = false,
82
82
  disableSelectorSelected = false,
83
83
  showRowExpander = false,
@@ -150,7 +150,7 @@ function GridComponent(props) {
150
150
  gridRef = useRef(),
151
151
  gridContainerRef = useRef(),
152
152
  isAddingRef = useRef(),
153
- [isRendered, setIsRendered] = useState(false),
153
+ isRenderedRef = useRef(),
154
154
  [isReady, setIsReady] = useState(false),
155
155
  [isLoading, setIsLoading] = useState(false),
156
156
  [localColumnsConfig, setLocalColumnsConfigRaw] = useState([]),
@@ -622,50 +622,49 @@ function GridComponent(props) {
622
622
  }
623
623
  setDragRowSlot(null);
624
624
  },
625
- onLayout = (e) => {
626
-
625
+ adjustPageSizeToHeight = (e) => {
627
626
  let doLoad = false;
628
- if (!isRendered) {
629
- setIsRendered(true);
627
+ if (!isRenderedRef.current) {
628
+ isRenderedRef.current = true;
630
629
  if (loadOnRender && Repository && !Repository.isLoaded && !Repository.isLoading && !Repository.isAutoLoad) {
631
630
  doLoad = true; // first time in onLayout only!
632
631
  }
633
632
  }
634
633
 
635
- const adjustPageSizeToHeight = !!(disableAdjustingPageSizeToHeight || !Repository || CURRENT_MODE !== UI_MODE_WEB || !gridRef.current || isAddingRef.current);
634
+ let adjustPageSizeToHeight = true;
635
+ if (!autoAdjustPageSizeToHeight || !Repository || !UiGlobals.autoAdjustPageSizeToHeight) {
636
+ adjustPageSizeToHeight = false;
637
+ }
636
638
  if (adjustPageSizeToHeight) {
637
- // this currently only works on web
638
639
  const
639
- gr = gridContainerRef.current,
640
- // scrollableNode = gr.getScrollableNode(),
641
- // scrollableNodeBoundingBox = scrollableNode.getBoundingClientRect(),
642
- // scrollableNodeHeight = scrollableNodeBoundingBox.height,
643
- // firstRow = scrollableNode.children[0].children[showHeaders ? 1: 0];
644
- height = gr.getBoundingClientRect().height;
645
- // IDEALLY, we want the grid to load right away with appropriate limits.
646
- // Currently, it's been loading once, then doing layout then loading again with correct limit.
647
- // How do we get the right limit before it renders??
648
- // Estimate based on (container height -header -footer) / avg height? This won't work for rows that exceed the avg height.
649
- // Maybe we do that avg at first, and if it exceeds, then we do another query to lose the later ones, which are hidden anyway.
650
- // It'll only do that once. Better to hide the offscreen ones, than to show gap at first, and later fill it
651
- // if (firstRow) { // TODO: this assumes there is a row there already, which is wrong!
652
- // const
653
- // rowHeight = firstRow.getBoundingClientRect().height,
654
- // rowsPerContainer = Math.floor(scrollableNodeHeight / rowHeight);
655
- // let pageSize = rowsPerContainer;
656
- // if (showHeaders) {
657
- // pageSize--;
658
- // }
659
- // if (pageSize !== Repository.pageSize) {
660
- // Repository.setPageSize(pageSize);
661
- // }
662
- // }
640
+ containerHeight = e.nativeEvent.layout.height,
641
+ headerHeight = showHeaders ? 50 : 0,
642
+ footerHeight = !disablePagination ? 50 : 0,
643
+ height = containerHeight - headerHeight - footerHeight,
644
+ rowHeight = 48,
645
+ rowsPerContainer = Math.floor(height / rowHeight);
646
+ let pageSize = rowsPerContainer;
647
+ if (showHeaders) {
648
+ pageSize--;
649
+ }
650
+ if (pageSize !== Repository.pageSize) {
651
+ Repository.setPageSize(pageSize);
652
+ }
663
653
  }
664
654
  if (doLoad) {
665
655
  Repository.load();
666
656
  }
667
657
  },
668
- debouncedOnLayout = useCallback(_.debounce(onLayout, 500), []);
658
+ debouncedAdjustPageSizeToHeight = useCallback(_.debounce(adjustPageSizeToHeight, 200), []),
659
+ onLayout = (e) => {
660
+ if (!isRenderedRef.current) {
661
+ // first time, call this immediately
662
+ adjustPageSizeToHeight(e);
663
+ } else {
664
+ // debounce all subsequent calls
665
+ debouncedAdjustPageSizeToHeight(e);
666
+ }
667
+ };
669
668
 
670
669
  useEffect(() => {
671
670
 
@@ -821,7 +820,21 @@ function GridComponent(props) {
821
820
  let listFooterComponent = null;
822
821
  if (!disableBottomToolbar) {
823
822
  if (Repository && bottomToolbar === 'pagination' && !disablePagination && Repository.isPaginated) {
824
- listFooterComponent = <PaginationToolbar Repository={Repository} self={self} toolbarItems={footerToolbarItemComponents} disablePageSize={!disableAdjustingPageSizeToHeight} />;
823
+ let disablePageSize = autoAdjustPageSizeToHeight; // component setting
824
+ if (!_.isNil(UiGlobals.autoAdjustPageSizeToHeight) && !UiGlobals.autoAdjustPageSizeToHeight) { // global setting
825
+ disablePageSize = false;
826
+ }
827
+ let showMoreOnly = false;
828
+ if (UiGlobals.paginationIsShowMoreOnly) { // global setting
829
+ showMoreOnly = true;
830
+ }
831
+ listFooterComponent = <PaginationToolbar
832
+ Repository={Repository}
833
+ self={self}
834
+ toolbarItems={footerToolbarItemComponents}
835
+ disablePageSize={disablePageSize}
836
+ showMoreOnly={showMoreOnly}
837
+ />;
825
838
  } else if (footerToolbarItemComponents.length) {
826
839
  listFooterComponent = <Toolbar>{footerToolbarItemComponents}</Toolbar>;
827
840
  }
@@ -841,7 +854,7 @@ function GridComponent(props) {
841
854
  bg={bg}
842
855
  borderWidth={styles.GRID_BORDER_WIDTH}
843
856
  borderColor={styles.GRID_BORDER_COLOR}
844
- onLayout={debouncedOnLayout}
857
+ onLayout={onLayout}
845
858
  {...sizeProps}
846
859
  >
847
860
  {topToolbar}
@@ -253,7 +253,7 @@ export default function withFilters(WrappedComponent) {
253
253
  const
254
254
  filterProps = {
255
255
  mx: 1,
256
- disableAdjustingPageSizeToHeight: true,
256
+ autoAdjustPageSizeToHeight: false,
257
257
  pageSize: 20,
258
258
  uniqueRepository: true,
259
259
  },
@@ -528,7 +528,6 @@ export default function withFilters(WrappedComponent) {
528
528
  editorType={EDITOR_TYPE__PLAIN}
529
529
  flex={1}
530
530
  startingValues={formStartingValues}
531
- minHeight={minHeight}
532
531
  items={[
533
532
  {
534
533
  type: 'Column',
@@ -16,6 +16,7 @@ import ChartLine from '../Icons/ChartLine.js';
16
16
  import Pdf from '../Icons/Pdf.js';
17
17
  import Excel from '../Icons/Excel.js';
18
18
  import UiGlobals from '../../UiGlobals.js';
19
+ import qs from 'qs';
19
20
  import _ from 'lodash';
20
21
 
21
22
  const
@@ -40,6 +41,14 @@ function Report(props) {
40
41
  styles = UiGlobals.styles,
41
42
  url = UiGlobals.baseURL + 'Reports/getReport',
42
43
  buttons = [],
44
+ downloadInBackground = (data) => {
45
+ const a = document.createElement('A');
46
+ a.href = url + '?' + qs.stringify(data);
47
+ a.download = true;
48
+ document.body.appendChild(a);
49
+ a.click();
50
+ document.body.removeChild(a);
51
+ },
43
52
  downloadWithFetch = (data) => {
44
53
  const options = {
45
54
  method: 'POST',
@@ -66,10 +75,14 @@ function Report(props) {
66
75
  showReportHeaders,
67
76
  // download_token, // not sure this is needed
68
77
  ...data,
69
- },
70
- closeWindow = reportType === EXCEL;
78
+ };
71
79
 
72
- downloadWithFetch(params, closeWindow);
80
+ if (reportType === EXCEL) {
81
+ downloadInBackground(params);
82
+ } else {
83
+ // opens a new window
84
+ downloadWithFetch(params);
85
+ }
73
86
  };
74
87
 
75
88
  const propsIcon = props._icon || {};
@@ -5,6 +5,7 @@ import {
5
5
  Text,
6
6
  } from 'native-base';
7
7
  import useForceUpdate from '../../Hooks/useForceUpdate.js';
8
+ import Button from '../Buttons/Button.js';
8
9
  import IconButton from '../Buttons/IconButton.js';
9
10
  import AngleLeft from '../Icons/AngleLeft.js';
10
11
  import AnglesLeft from '../Icons/AnglesLeft.js';
@@ -18,6 +19,7 @@ export default function Pagination(props) {
18
19
  const {
19
20
  minimize = false,
20
21
  disablePageSize = false,
22
+ showMoreOnly = false,
21
23
 
22
24
  // withComponent
23
25
  self,
@@ -56,90 +58,104 @@ export default function Pagination(props) {
56
58
  w: 20,
57
59
  };
58
60
  let items = [],
61
+ isDisabled = false;
62
+ if (showMoreOnly) {
63
+ isDisabled = (pageEnd === total);
64
+ items.push(<Button
65
+ key="showMore"
66
+ parent={self}
67
+ reference="showMoreBtn"
68
+ onPress={() => Repository.showMore()}
69
+ isDisabled={isDisabled}
70
+ tooltip="Show More"
71
+ >Show More</Button>);
72
+ } else {
59
73
  isDisabled = page === 1;
60
- items.push(<IconButton
61
- key="first"
62
- parent={self}
63
- reference="firstPageBtn"
64
- {...iconButtonProps}
65
- isDisabled={isDisabled}
66
- icon={<Icon as={AnglesLeft} {...iconProps} color={isDisabled ? 'disabled' : 'trueGray.600'} />}
67
- onPress={() => Repository.setPage(1)}
68
- tooltip="First Page"
69
- />);
70
- items.push(<IconButton
71
- key="prev"
72
- parent={self}
73
- reference="prevPageBtn"
74
- {...iconButtonProps}
75
- isDisabled={isDisabled}
76
- icon={<Icon as={AngleLeft} {...iconProps} color={isDisabled ? 'disabled' : 'trueGray.600'} />}
77
- onPress={() => Repository.prevPage()}
78
- tooltip="Previous Page"
79
- />);
80
- if (!minimize) {
81
- items.push(<Row
82
- key="pageSelector"
83
- mx={3}
84
- justifyContent="center"
85
- alignItems="center"
86
- >
87
- <Text mr={2}>Page</Text>
88
- <Input
89
- parent={self}
90
- reference="pageInput"
91
- keyboardType="numeric"
92
- value={page?.toString()}
93
- onChangeValue={(value) => Repository.setPage(value)}
94
- maxValue={totalPages}
95
- isDisabled={totalPages === 1}
96
- w={10}
97
- tooltip="Set Page"
98
- />
99
- <Text ml={2}>of {totalPages}</Text>
100
- </Row>);
101
- }
102
-
103
- isDisabled = page === totalPages || totalPages <= 1;
104
- items.push(<IconButton
105
- key="next"
106
- parent={self}
107
- reference="nextPageBtn"
108
- {...iconButtonProps}
109
- isDisabled={isDisabled}
110
- icon={<Icon as={AngleRight} {...iconProps} color={isDisabled ? 'disabled' : 'trueGray.600'} />}
111
- onPress={() => Repository.nextPage()}
112
- tooltip="Next Page"
113
- />);
114
- items.push(<IconButton
115
- key="last"
116
- parent={self}
117
- reference="lastPageBtn"
118
- {...iconButtonProps}
119
- isDisabled={isDisabled}
120
- icon={<Icon as={AnglesRight} {...iconProps} color={isDisabled ? 'disabled' : 'trueGray.600'} />}
121
- onPress={() => Repository.setPage(totalPages)}
122
- tooltip="Last Page"
123
- />);
124
- if (!Repository.isLocal) {
125
74
  items.push(<IconButton
126
- key="reload"
75
+ key="first"
127
76
  parent={self}
128
- reference="reloadPageBtn"
77
+ reference="firstPageBtn"
129
78
  {...iconButtonProps}
130
- icon={<Icon as={Rotate} {...iconProps} color="trueGray.600" />}
131
- onPress={() => Repository.reload()}
132
- tooltip="Reload"
79
+ isDisabled={isDisabled}
80
+ icon={<Icon as={AnglesLeft} {...iconProps} color={isDisabled ? 'disabled' : 'trueGray.600'} />}
81
+ onPress={() => Repository.setPage(1)}
82
+ tooltip="First Page"
133
83
  />);
134
- }
135
-
136
- if (!minimize && !disablePageSize) {
137
- items.push(<PageSizeCombo key="pageSize" pageSize={pageSize} Repository={Repository} />);
138
- }
139
-
140
- let pageSpan = `${pageStart} ${pageEnd}`;
141
- if (pageStart === pageEnd) {
142
- pageSpan = pageStart;
84
+ items.push(<IconButton
85
+ key="prev"
86
+ parent={self}
87
+ reference="prevPageBtn"
88
+ {...iconButtonProps}
89
+ isDisabled={isDisabled}
90
+ icon={<Icon as={AngleLeft} {...iconProps} color={isDisabled ? 'disabled' : 'trueGray.600'} />}
91
+ onPress={() => Repository.prevPage()}
92
+ tooltip="Previous Page"
93
+ />);
94
+ if (!minimize) {
95
+ items.push(<Row
96
+ key="pageSelector"
97
+ mx={3}
98
+ justifyContent="center"
99
+ alignItems="center"
100
+ >
101
+ <Text mr={2}>Page</Text>
102
+ <Input
103
+ parent={self}
104
+ reference="pageInput"
105
+ keyboardType="numeric"
106
+ value={page?.toString()}
107
+ onChangeValue={(value) => Repository.setPage(value)}
108
+ maxValue={totalPages}
109
+ isDisabled={totalPages === 1}
110
+ w={10}
111
+ tooltip="Set Page"
112
+ />
113
+ <Text ml={2}>of {totalPages}</Text>
114
+ </Row>);
115
+ }
116
+
117
+ isDisabled = page === totalPages || totalPages <= 1;
118
+ items.push(<IconButton
119
+ key="next"
120
+ parent={self}
121
+ reference="nextPageBtn"
122
+ {...iconButtonProps}
123
+ isDisabled={isDisabled}
124
+ icon={<Icon as={AngleRight} {...iconProps} color={isDisabled ? 'disabled' : 'trueGray.600'} />}
125
+ onPress={() => Repository.nextPage()}
126
+ tooltip="Next Page"
127
+ />);
128
+ items.push(<IconButton
129
+ key="last"
130
+ parent={self}
131
+ reference="lastPageBtn"
132
+ {...iconButtonProps}
133
+ isDisabled={isDisabled}
134
+ icon={<Icon as={AnglesRight} {...iconProps} color={isDisabled ? 'disabled' : 'trueGray.600'} />}
135
+ onPress={() => Repository.setPage(totalPages)}
136
+ tooltip="Last Page"
137
+ />);
138
+ if (!Repository.isLocal) {
139
+ items.push(<IconButton
140
+ key="reload"
141
+ parent={self}
142
+ reference="reloadPageBtn"
143
+ {...iconButtonProps}
144
+ icon={<Icon as={Rotate} {...iconProps} color="trueGray.600" />}
145
+ onPress={() => Repository.reload()}
146
+ tooltip="Reload"
147
+ />);
148
+ }
149
+ if (!minimize && !disablePageSize) {
150
+ items.push(<PageSizeCombo key="pageSize" pageSize={pageSize} Repository={Repository} />);
151
+ }
152
+ if (!minimize) {
153
+ let pageSpan = `${pageStart} – ${pageEnd}`;
154
+ if (pageStart === pageEnd) {
155
+ pageSpan = pageStart;
156
+ }
157
+ items.push(<Text key="pageDisplay" ml={3}>Displaying {pageSpan} of {total}</Text>);
158
+ }
143
159
  }
144
160
 
145
161
  return <Row
@@ -150,7 +166,6 @@ export default function Pagination(props) {
150
166
  {...props}
151
167
  >
152
168
  {items}
153
- {!minimize && <Text ml={3}>Displaying {pageSpan} of {total}</Text>}
154
169
  </Row>;
155
170
  }, [
156
171
  // Repository,
@@ -162,6 +177,4 @@ export default function Pagination(props) {
162
177
  pageEnd,
163
178
  minimize,
164
179
  ])
165
-
166
-
167
180
  };