@onehat/ui 0.3.70 → 0.3.72

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.70",
3
+ "version": "0.3.72",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -130,7 +130,6 @@ export default function Accordion(props) {
130
130
  if (!containerInitialHeight) {
131
131
  const { height } = e.nativeEvent.layout;
132
132
  setContainerInitialHeight(height);
133
- console.log('height', height);
134
133
  }
135
134
  if (onLayout) {
136
135
  onLayout(e);
@@ -4,12 +4,14 @@ import {
4
4
  Pressable,
5
5
  Text,
6
6
  } from 'native-base';
7
+ import IconButton from './IconButton.js';
7
8
  import UiGlobals from '../../UiGlobals.js';
8
9
 
9
10
  export default function SquareButton(props) {
10
11
  const {
11
12
  text,
12
13
  isActive = false,
14
+ showText = true,
13
15
  activeColor,
14
16
  invertColorWhenActive = false,
15
17
  disableInteractions = false,
@@ -17,7 +19,9 @@ export default function SquareButton(props) {
17
19
  ...propsToPass
18
20
  } = props,
19
21
  styles = UiGlobals.styles,
22
+ bg = isActive ? activeColor || '#56a6f8' : '#fff',
20
23
  color = invertColorWhenActive && isActive ? '#fff' : '#000';
24
+
21
25
  const propsIcon = props._icon || {};
22
26
  let icon = props.icon;
23
27
  if (!icon) {
@@ -26,14 +30,6 @@ export default function SquareButton(props) {
26
30
  if (!text) {
27
31
  throw Error('text missing');
28
32
  }
29
-
30
- if (React.isValidElement(icon)) {
31
- if (!_.isEmpty(propsIcon)) {
32
- icon = React.cloneElement(icon, {...propsIcon});
33
- }
34
- } else {
35
- icon = <Icon as={icon} {...propsIcon} />;
36
- }
37
33
 
38
34
  const
39
35
  hoverProps = {},
@@ -42,7 +38,29 @@ export default function SquareButton(props) {
42
38
  hoverProps.bg = styles.ICON_BUTTON_BG_HOVER;
43
39
  pressedProps.bg = styles.ICON_BUTTON_BG_PRESSED;
44
40
  }
45
-
41
+
42
+ if (!showText) {
43
+ return <IconButton
44
+ icon={icon}
45
+ borderRadius="md"
46
+ p={2}
47
+ _icon={{
48
+ size: '20px',
49
+ color,
50
+ }}
51
+ {...propsToPass}
52
+ bg={bg}
53
+ />;
54
+ }
55
+
56
+ if (React.isValidElement(icon)) {
57
+ if (!_.isEmpty(propsIcon)) {
58
+ icon = React.cloneElement(icon, {...propsIcon});
59
+ }
60
+ } else {
61
+ icon = <Icon as={icon} {...propsIcon} />;
62
+ }
63
+
46
64
  return <Pressable
47
65
  borderRadius="md"
48
66
  flexDirection="column"
@@ -50,7 +68,7 @@ export default function SquareButton(props) {
50
68
  alignItems="center"
51
69
  p={2}
52
70
  {...propsToPass}
53
- bg={isActive ? activeColor || '#56a6f8' : '#fff'}
71
+ bg={bg}
54
72
  // _hover={hoverProps}
55
73
  // _pressed={pressedProps}
56
74
  >
@@ -45,12 +45,6 @@ const
45
45
  const value = editor.getData();
46
46
  debouncedSetValueRef.current(value);
47
47
  }}
48
- // onBlur={(event, editor) => {
49
- // console.log( 'Blur.', editor);
50
- // }}
51
- // onFocus={(event, editor) => {
52
- // console.log( 'Focus.', editor);
53
- // }}
54
48
  />
55
49
  </Row>;
56
50
  },
@@ -1,6 +1,5 @@
1
1
  import React, { useState, useEffect, useRef, } from 'react';
2
2
  import {
3
- Button,
4
3
  Modal,
5
4
  Popover,
6
5
  Pressable,
@@ -26,6 +25,8 @@ import Check from '../../../Icons/Check.js';
26
25
  import Xmark from '../../../Icons/Xmark.js';
27
26
  import _ from 'lodash';
28
27
 
28
+ const FILTER_NAME = 'q';
29
+
29
30
  export function ComboComponent(props) {
30
31
  const {
31
32
  additionalButtons,
@@ -287,7 +288,11 @@ export function ComboComponent(props) {
287
288
  onClearBtn = () => {
288
289
  setTextInputValue('');
289
290
  setValue(null);
290
- }
291
+ },
292
+ onXBtnPress = () => {
293
+ hideMenu();
294
+ setValue(null);
295
+ },
291
296
  isEventStillInComponent = (e) => {
292
297
  const {
293
298
  relatedTarget
@@ -300,38 +305,38 @@ export function ComboComponent(props) {
300
305
  menuRef.current === relatedTarget ||
301
306
  menuRef.current?.contains(relatedTarget);
302
307
  },
308
+ getFilterName = () => {
309
+ // Only used for remote repositories
310
+ // Gets the filter name of the query, which becomes the condition sent to server
311
+ let filterName = FILTER_NAME;
312
+ if (Repository.isRemote) {
313
+ const
314
+ schema = Repository.getSchema(),
315
+ displayFieldName = schema.model.displayProperty,
316
+ displayFieldDef = schema.getPropertyDefinition(displayFieldName);
317
+
318
+ // Verify displayField is a real field
319
+ if (!displayFieldDef.isVirtual) {
320
+ filterName = displayFieldName + ' LIKE';
321
+ }
322
+ }
323
+ return filterName;
324
+ },
303
325
  clearGridFilters = async () => {
304
326
  if (Repository) {
305
327
  if (Repository.isLoading) {
306
328
  await Repository.waitUntilDoneLoading();
307
329
  }
330
+ const filterName = getFilterName();
331
+ if (Repository.hasFilter(filterName)) {
332
+ Repository.clearFilters(filterName);
333
+ }
308
334
 
309
- // clear filter
310
- if (Repository.isRemote || Repository.remote) {
311
- let searchField = 'q';
312
- const searchValue = null;
313
-
314
- // Check to see if displayField is a real field
315
- const
316
- schema = Repository.getSchema(),
317
- displayFieldName = schema.model.displayProperty,
318
- displayFieldDef = schema.getPropertyDefinition(displayFieldName);
319
- if (!displayFieldDef.isVirtual) {
320
- searchField = displayFieldName + ' LIKE';
321
- }
322
-
323
- if (Repository.hasFilter(searchField)) {
324
- Repository.clear();
325
- await Repository.filter(searchField, searchValue);
326
- if (!this.isAutoLoad) {
327
- await Repository.reload();
328
- }
335
+ if (Repository.isRemote) {
336
+ if (!this.isAutoLoad) {
337
+ await Repository.reload();
329
338
  }
330
-
331
- } else {
332
- Repository.clear();
333
339
  }
334
-
335
340
  } else {
336
341
  setFilteredData(data);
337
342
  }
@@ -345,41 +350,34 @@ export function ComboComponent(props) {
345
350
 
346
351
  let found;
347
352
  if (Repository) {
353
+ if (Repository.isLoading) {
354
+ await Repository.waitUntilDoneLoading();
355
+ }
348
356
 
349
- if (_.isEmpty(value) && Repository.hasFilters) {
350
- Repository.clearFilters();
357
+ if (_.isEmpty(value)) {
358
+ clearGridFilters();
351
359
  return;
352
360
  }
353
361
 
354
- if (Repository.isLoading) {
355
- await Repository.waitUntilDoneLoading();
356
- }
357
-
358
362
  // Set filter
363
+ const filterName = getFilterName();
359
364
  if (Repository.isRemote) {
360
- const
361
- schema = Repository.getSchema(),
362
- displayFieldName = schema.model.displayProperty,
363
- displayFieldDef = schema.getPropertyDefinition(displayFieldName),
364
- searchValue = _.isEmpty(value) ? null : value + '%';
365
- let searchField = 'q';
366
-
367
- // Verify displayField is a real field
368
- if (!displayFieldDef.isVirtual) {
369
- searchField = displayFieldName + ' LIKE';
370
- }
371
-
372
- await Repository.filter(searchField, searchValue);
365
+ // remote
366
+ const filterValue = _.isEmpty(value) ? null : value + '%';
367
+ await Repository.filter(filterName, filterValue);
373
368
  if (!this.isAutoLoad) {
374
369
  await Repository.reload();
375
370
  }
376
371
  } else {
377
- // local filter
378
- Repository.filter((entity) => {
379
- const
380
- displayValue = entity.displayValue,
381
- regex = new RegExp('^' + value);
382
- return displayValue.match(regex);
372
+ // local
373
+ Repository.filter({
374
+ name: filterName,
375
+ fn: (entity) => {
376
+ const
377
+ displayValue = entity.displayValue,
378
+ regex = new RegExp('^' + value);
379
+ return displayValue.match(regex);
380
+ },
383
381
  });
384
382
  }
385
383
 
@@ -407,6 +405,12 @@ export function ComboComponent(props) {
407
405
  inputRef.current.focus();
408
406
  }
409
407
 
408
+ return () => {
409
+ if (Repository && !Repository.isUnique && !Repository.isDestroyed) {
410
+ clearGridFilters();
411
+ }
412
+ };
413
+
410
414
  }, [isRendered]);
411
415
 
412
416
  useEffect(() => {
@@ -442,7 +446,7 @@ export function ComboComponent(props) {
442
446
  size: 'sm',
443
447
  }}
444
448
  isDisabled={isDisabled}
445
- onPress={onClearBtn}
449
+ onPress={onXBtnPress}
446
450
  h="100%"
447
451
  bg={styles.FORM_COMBO_TRIGGER_BG}
448
452
  _hover={{
@@ -481,6 +485,7 @@ export function ComboComponent(props) {
481
485
  </Pressable> :
482
486
  <Input
483
487
  ref={inputRef}
488
+ reference="ComboInput"
484
489
  value={textInputValue}
485
490
  autoSubmit={true}
486
491
  isDisabled={isDisabled}
@@ -488,14 +493,6 @@ export function ComboComponent(props) {
488
493
  onKeyPress={onInputKeyPress}
489
494
  onFocus={onInputFocus}
490
495
  onBlur={onInputBlur}
491
- onLayout={(e) => {
492
- const {
493
- height,
494
- width,
495
- } = e.nativeEvent.layout;
496
- setWidth(Math.round(width));
497
- setTop(Math.round(height));
498
- }}
499
496
  flex={1}
500
497
  h="100%"
501
498
  m={0}
@@ -536,7 +533,8 @@ export function ComboComponent(props) {
536
533
 
537
534
  if (UiGlobals.mode === UI_MODE_REACT_NATIVE) {
538
535
  // This input and trigger are for show
539
- // The just show the current value and open the menu
536
+ // The just show the current getDisplayValue and open the menu
537
+ const displayValue = getDisplayValue();
540
538
  inputAndTrigger = <>
541
539
  <Pressable
542
540
  onPress={showMenu}
@@ -553,13 +551,13 @@ export function ComboComponent(props) {
553
551
  borderColor="trueGray.400"
554
552
  borderTopRightRadius={0}
555
553
  borderBottomRightRadius={0}
556
- color={_.isEmpty(textInputValue) ? 'trueGray.400' : '#000'}
554
+ color={_.isEmpty(displayValue) ? 'trueGray.400' : '#000'}
557
555
  fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
558
556
  bg={styles.FORM_COMBO_INPUT_BG}
559
557
  _focus={{
560
558
  bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
561
559
  }}
562
- >{_.isEmpty(textInputValue) ? placeholder : textInputValue}</Text>
560
+ >{_.isEmpty(displayValue) ? placeholder : displayValue}</Text>
563
561
  </Pressable>
564
562
  <IconButton
565
563
  ref={triggerRef}
@@ -739,15 +737,13 @@ export function ComboComponent(props) {
739
737
  if (UiGlobals.mode === UI_MODE_REACT_NATIVE) {
740
738
  if (isEditor) {
741
739
  // in RN, an editor has no way to accept the selection of the grid, so we need to add a check button to do this
742
- const isCheckBtnDisabled = _.isEmpty(value);
743
740
  checkBtn = <IconButton
744
741
  _icon={{
745
742
  as: Check,
746
- color: isCheckBtnDisabled ? 'disabled' : 'trueGray.600',
743
+ color: 'trueGray.600',
747
744
  size: 'sm',
748
745
  }}
749
- isDisabled={isCheckBtnDisabled}
750
- onPress={acceptSelection}
746
+ onPress={onXBtnPress}
751
747
  h="100%"
752
748
  borderWidth={1}
753
749
  borderColor="#bbb"
@@ -760,6 +756,7 @@ export function ComboComponent(props) {
760
756
  }
761
757
  const inputAndTriggerClone = // for RN, this is the actual input and trigger, as we need them to appear up above in the modal
762
758
  <Row h={10}>
759
+ {xButton}
763
760
  {disableDirectEntry ?
764
761
  <Text
765
762
  ref={inputRef}
@@ -781,6 +778,7 @@ export function ComboComponent(props) {
781
778
  >{textInputValue}</Text> :
782
779
  <Input
783
780
  ref={inputRef}
781
+ reference="ComboInput"
784
782
  value={textInputValue}
785
783
  autoSubmit={true}
786
784
  isDisabled={isDisabled}
@@ -835,7 +833,6 @@ export function ComboComponent(props) {
835
833
  >
836
834
  {inputAndTriggerClone}
837
835
  {grid}
838
- <Button mt={2} onPress={() => setIsMenuShown(false)}>Close</Button>
839
836
  </Modal>;
840
837
  }
841
838
  }
@@ -570,6 +570,7 @@ export function DateElement(props) {
570
570
  /> */}
571
571
  <Box bg="#fff">
572
572
  <Datetime
573
+ initialDate={moment(value).toDate()}
573
574
  selectedStartDate={moment(value).toDate()}
574
575
  onDateChange={onPickerChange}
575
576
  todayBackgroundColor="#eee"
@@ -107,6 +107,7 @@ function Form(props) {
107
107
  onClose,
108
108
  onDelete,
109
109
  editorStateRef,
110
+ disableView,
110
111
 
111
112
  // parent container
112
113
  selectorId,
@@ -696,7 +697,7 @@ function Form(props) {
696
697
  leftIcon={<Icon as={AngleLeft} color="#fff" size="sm" />}
697
698
  color="#fff"
698
699
  >Back</Button>}
699
- {isSingle && editorMode === EDITOR_MODE__EDIT && onViewMode &&
700
+ {isSingle && editorMode === EDITOR_MODE__EDIT && onViewMode && !disableView &&
700
701
  <Button
701
702
  key="viewBtn"
702
703
  onPress={onViewMode}
@@ -736,7 +737,12 @@ function Form(props) {
736
737
  if (isEditorViewOnly) {
737
738
  showCloseBtn = true;
738
739
  } else {
739
- if (formState.isDirty || record?.isPhantom) {
740
+ const
741
+ formIsDirty = formState.isDirty,
742
+ recordIsPhantom = record?.isPhantom;
743
+ // console.log('formIsDirty', formIsDirty);
744
+ // console.log('recordIsPhantom', recordIsPhantom);
745
+ if (formIsDirty || recordIsPhantom) {
740
746
  if (isSingle && onCancel) {
741
747
  showCancelBtn = true;
742
748
  }
@@ -13,7 +13,7 @@ export default function Footer(props) {
13
13
  testID="footer"
14
14
  w="100%"
15
15
  p={2}
16
- safeAreaBottom
16
+ // safeAreaBottom
17
17
  {...props}
18
18
  >
19
19
  {props.children}
@@ -973,7 +973,7 @@ function TreeComponent(props) {
973
973
  setHighlitedDatum(null);
974
974
 
975
975
  } else {
976
- console.log('setDropRowIx', newIx);
976
+ // console.log('setDropRowIx', newIx);
977
977
  setDropRowIx(newIx);
978
978
 
979
979
  // highlight the drop node
@@ -32,7 +32,7 @@ export default function buildAdditionalButtons(configs, self, handlerArgs = {})
32
32
  const button = <Button
33
33
  color={color}
34
34
  ml={2}
35
- mb={2}
35
+ // mb={2}
36
36
  parent={self}
37
37
  reference={key}
38
38
  {...buttonProps}