@onehat/ui 0.2.50 → 0.2.51

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.50",
3
+ "version": "0.2.51",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -5,6 +5,7 @@ import {
5
5
  Spinner,
6
6
  Tooltip,
7
7
  } from 'native-base';
8
+ import styles from '../../Constants/Styles.js';
8
9
 
9
10
  const IconButton = React.forwardRef((props, ref) => {
10
11
  const {
@@ -29,7 +30,7 @@ const IconButton = React.forwardRef((props, ref) => {
29
30
  alignItems="center"
30
31
  p={2}
31
32
  _disabled={{
32
- bg: 'trueGray.300',
33
+ bg: styles.ICON_BUTTON_BG_DISABLED,
33
34
  }}
34
35
  {...props}
35
36
  >
@@ -277,6 +277,7 @@ export function DateElement(props) {
277
277
  setTop(top + height);
278
278
  setLeft(left);
279
279
  }}
280
+ w={props.w || null}
280
281
  />
281
282
  {/* <Pressable
282
283
  flex={1}
@@ -1,4 +1,4 @@
1
- import { useState, useEffect, } from 'react';
1
+ import { useState, useEffect, useId, } from 'react';
2
2
  import {
3
3
  Column,
4
4
  Modal,
@@ -34,6 +34,8 @@ export default function withFilters(WrappedComponent) {
34
34
  customFilters = [], // of shape: { title, type, field, value, getRepoFilters(value) }
35
35
  minFilters = 3,
36
36
  maxFilters = 6,
37
+ getSaved,
38
+ setSaved,
37
39
 
38
40
  // withData
39
41
  Repository,
@@ -54,6 +56,7 @@ export default function withFilters(WrappedComponent) {
54
56
  excludeFields: modelExcludeFields,
55
57
  filteringDisabled: modelFilteringDisabled,
56
58
  } = Repository.getSchema().model,
59
+ id = useId(),
57
60
 
58
61
  // determine the starting filters
59
62
  startingFilters = !_.isEmpty(customFilters) ? customFilters : // custom filters override component filters
@@ -103,7 +106,7 @@ export default function withFilters(WrappedComponent) {
103
106
  }
104
107
 
105
108
  const
106
- [filters, setFilters] = useState(formattedStartingFilters), // array of formatted filters
109
+ [filters, setFiltersRaw] = useState(formattedStartingFilters), // array of formatted filters
107
110
  [slots, setSlots] = useState(startingSlots), // array of field names user is currently filtering on; blank slots have a null entry in array
108
111
  [modalFilters, setModalFilters] = useState([]),
109
112
  [modalSlots, setModalSlots] = useState([]),
@@ -144,6 +147,29 @@ export default function withFilters(WrappedComponent) {
144
147
  setModalFilters(newFilters);
145
148
  setModalSlots(newSlots);
146
149
  },
150
+ setFilters = (filters, doSetSlots = true, save = true) => {
151
+ setFiltersRaw(filters);
152
+
153
+ if (doSetSlots) {
154
+ const newSlots = [];
155
+ _.each(filters, (filter, ix) => {
156
+ if (searchAllText && ix === 0) {
157
+ return; // skip
158
+ }
159
+ newSlots.push(filter.field);
160
+ });
161
+ if (newSlots.length < minFilters) {
162
+ // Add more slots until we get to minFilters
163
+ for(let i = newSlots.length; i < minFilters; i++) {
164
+ newSlots.push(null);
165
+ }
166
+ }
167
+ setSlots(newSlots);
168
+ }
169
+ if (save && setSaved) {
170
+ setSaved(id + '-filters', filters);
171
+ }
172
+ },
147
173
  onFilterChangeValue = (field, value) => {
148
174
  // handler for when a filter value changes
149
175
  const newFilters = [];
@@ -153,7 +179,7 @@ export default function withFilters(WrappedComponent) {
153
179
  }
154
180
  newFilters.push(filter);
155
181
  });
156
- setFilters(newFilters);
182
+ setFilters(newFilters, false);
157
183
  },
158
184
  onClearFilters = () => {
159
185
  // Clears values for all active filters
@@ -162,7 +188,7 @@ export default function withFilters(WrappedComponent) {
162
188
  filter.value = null;
163
189
  newFilters.push(filter);
164
190
  });
165
- setFilters(newFilters);
191
+ setFilters(newFilters, false);
166
192
  },
167
193
  getFilterByField = (field) => {
168
194
  return _.find(filters, (filter) => {
@@ -240,61 +266,73 @@ export default function withFilters(WrappedComponent) {
240
266
  };
241
267
 
242
268
  useEffect(() => {
243
- // Whenever the filters change in some way, make repository conform to these new filters
244
- const newRepoFilters = [];
269
+ (async () => {
270
+
271
+ // Whenever the filters change in some way, make repository conform to these new filters
272
+ const newRepoFilters = [];
273
+ let filtersToUse = filters
274
+
275
+ if (!isReady && getSaved) {
276
+ const savedFilters = await getSaved(id + '-filters');
277
+ if (!_.isEmpty(savedFilters)) {
278
+ // load saved filters
279
+ filtersToUse = savedFilters;
280
+ setFilters(savedFilters, true, false); // false to skip save
281
+ }
282
+ }
245
283
 
246
- if (isUsingCustomFilters) {
247
- _.each(filters, (filter) => {
248
- const repoFiltersFromFilter = filter.getRepoFilters(value);
249
- _.each(repoFiltersFromFilter, (repoFilter) => { // one custom filter might generate multiple filters for the repository
250
- newRepoFilters.push(repoFilter);
284
+ if (isUsingCustomFilters) {
285
+ _.each(filtersToUse, (filter) => {
286
+ const repoFiltersFromFilter = filter.getRepoFilters(value);
287
+ _.each(repoFiltersFromFilter, (repoFilter) => { // one custom filter might generate multiple filters for the repository
288
+ newRepoFilters.push(repoFilter);
289
+ });
251
290
  });
252
- });
253
- } else {
254
- const newFilterNames = [];
255
- _.each(filters, (filter) => {
256
- const {
257
- field,
258
- value,
259
- } = filter,
260
- isFilterRange = getIsFilterRange(field);
261
- if (isFilterRange) {
262
- if (!!value) {
263
- const
264
- highField = field + ' <=',
265
- lowField = field + ' >=',
266
- highValue = value.high,
267
- lowValue = value.low;
268
- newFilterNames.push(highField);
269
- newFilterNames.push(lowField);
270
- newRepoFilters.push({ name: highField, value: highValue, });
271
- newRepoFilters.push({ name: lowField, value: lowValue, });
291
+ } else {
292
+ const newFilterNames = [];
293
+ _.each(filtersToUse, (filter) => {
294
+ const {
295
+ field,
296
+ value,
297
+ } = filter,
298
+ isFilterRange = getIsFilterRange(field);
299
+ if (isFilterRange) {
300
+ if (!!value) {
301
+ const
302
+ highField = field + ' <=',
303
+ lowField = field + ' >=',
304
+ highValue = value.high,
305
+ lowValue = value.low;
306
+ newFilterNames.push(highField);
307
+ newFilterNames.push(lowField);
308
+ newRepoFilters.push({ name: highField, value: highValue, });
309
+ newRepoFilters.push({ name: lowField, value: lowValue, });
310
+ }
311
+ } else {
312
+ newFilterNames.push(field);
313
+ newRepoFilters.push({ name: field, value, });
272
314
  }
273
- } else {
274
- newFilterNames.push(field);
275
- newRepoFilters.push({ name: field, value, });
276
- }
277
- });
315
+ });
278
316
 
279
- // Go through previousFilterNames and see if any are no longer used.
280
- _.each(previousFilterNames, (name) => {
281
- if (!inArray(name, newFilterNames)) {
282
- newRepoFilters.push({ name, value: null, }); // no longer used, so set it to null so it'll be deleted
283
- }
284
- });
285
- setPreviousFilterNames(newFilterNames);
286
- }
317
+ // Go through previousFilterNames and see if any are no longer used.
318
+ _.each(previousFilterNames, (name) => {
319
+ if (!inArray(name, newFilterNames)) {
320
+ newRepoFilters.push({ name, value: null, }); // no longer used, so set it to null so it'll be deleted
321
+ }
322
+ });
323
+ setPreviousFilterNames(newFilterNames);
324
+ }
287
325
 
288
- Repository.filter(newRepoFilters, null, false); // false so other filters remain
326
+ Repository.filter(newRepoFilters, null, false); // false so other filters remain
289
327
 
290
- if (searchAllText && Repository.searchAncillary && !Repository.hasBaseParam('searchAncillary')) {
291
- Repository.setBaseParam('searchAncillary', true);
292
- }
293
-
294
- if (!isReady) {
295
- setIsReady(true);
296
- }
328
+ if (searchAllText && Repository.searchAncillary && !Repository.hasBaseParam('searchAncillary')) {
329
+ Repository.setBaseParam('searchAncillary', true);
330
+ }
297
331
 
332
+ if (!isReady) {
333
+ setIsReady(true);
334
+ }
335
+ })();
298
336
  }, [filters]);
299
337
 
300
338
  if (!isReady) {
@@ -324,6 +362,8 @@ export default function withFilters(WrappedComponent) {
324
362
  }}
325
363
  ml={1}
326
364
  onPress={() => {
365
+ const f = filters;
366
+ const s = slots;
327
367
  setModalFilters(filters);
328
368
  setModalSlots(slots);
329
369
  setIsFilterSelectorShown(true);
@@ -420,9 +460,7 @@ export default function withFilters(WrappedComponent) {
420
460
  onSave={(data, e) => {
421
461
  // Conform filters to this new choice of filters
422
462
 
423
- const
424
- newFilters = [],
425
- newSlots = [];
463
+ const newFilters = [];
426
464
 
427
465
  if (searchAllText) {
428
466
  newFilters.push(filters[0]);
@@ -435,20 +473,10 @@ export default function withFilters(WrappedComponent) {
435
473
  }
436
474
 
437
475
  const newFilter = getFormattedFilter(field);
438
-
439
476
  newFilters.push(newFilter);
440
- newSlots.push(field);
441
477
  });
442
478
 
443
- if (newSlots.length < minFilters) {
444
- // Add more slots until we get to minFilters
445
- for(let i = newSlots.length; i < minFilters; i++) {
446
- newSlots.push(null);
447
- }
448
- }
449
-
450
479
  setFilters(newFilters);
451
- setSlots(newSlots);
452
480
 
453
481
  // Close the modal
454
482
  setIsFilterSelectorShown(false);
@@ -61,6 +61,7 @@ const defaults = {
61
61
  GRID_TOOLBAR_ITEMS_COLOR: 'trueGray.800',
62
62
  GRID_TOOLBAR_ITEMS_DISABLED_COLOR: 'disabled',
63
63
  GRID_TOOLBAR_ITEMS_ICON_SIZE: 'sm',
64
+ ICON_BUTTON_BG_DISABLED: 'trueGray.200',
64
65
  PANEL_FOOTER_BG: 'primary.100', // :alpha.50
65
66
  PANEL_HEADER_BG: 'primary.100',
66
67
  PANEL_HEADER_BG_VERTICAL: 'primary.100',