@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 +1 -1
- package/src/Components/Accordion/Accordion.js +0 -1
- package/src/Components/Buttons/SquareButton.js +28 -10
- package/src/Components/Form/Field/CKEditor/CKEditor.js +0 -6
- package/src/Components/Form/Field/Combo/Combo.js +65 -68
- package/src/Components/Form/Field/Date.js +1 -0
- package/src/Components/Form/Form.js +8 -2
- package/src/Components/Layout/Footer.js +1 -1
- package/src/Components/Tree/Tree.js +1 -1
- package/src/Functions/buildAdditionalButtons.js +1 -1
package/package.json
CHANGED
|
@@ -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={
|
|
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
|
-
|
|
310
|
-
|
|
311
|
-
|
|
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)
|
|
350
|
-
|
|
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
|
-
|
|
361
|
-
|
|
362
|
-
|
|
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
|
|
378
|
-
Repository.filter(
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
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={
|
|
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
|
|
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(
|
|
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(
|
|
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:
|
|
743
|
+
color: 'trueGray.600',
|
|
747
744
|
size: 'sm',
|
|
748
745
|
}}
|
|
749
|
-
|
|
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
|
}
|
|
@@ -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
|
-
|
|
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
|
}
|