@onehat/ui 0.3.59 → 0.3.60
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/Form/Field/Combo/Combo.js +385 -263
- package/src/Components/Form/Form.js +22 -11
- package/src/Components/Grid/Grid.js +63 -58
- package/src/Components/Grid/GridRow.js +5 -2
- package/src/Components/Grid/NoRecordsFound.js +2 -0
- package/src/Components/Hoc/withAlert.js +11 -0
- package/src/Constants/Alert.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useEffect, useRef, } from 'react';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
Modal,
|
|
4
4
|
Popover,
|
|
5
5
|
Pressable,
|
|
6
6
|
Row,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
Tooltip,
|
|
9
9
|
} from 'native-base';
|
|
10
10
|
import {
|
|
11
|
+
UI_MODE_REACT_NATIVE,
|
|
11
12
|
UI_MODE_WEB,
|
|
12
13
|
} from '../../../../Constants/UiModes.js';
|
|
13
14
|
import UiGlobals from '../../../../UiGlobals.js';
|
|
@@ -60,7 +61,6 @@ export function ComboComponent(props) {
|
|
|
60
61
|
triggerRef = useRef(),
|
|
61
62
|
menuRef = useRef(),
|
|
62
63
|
displayValueRef = useRef(null),
|
|
63
|
-
savedSearch = useRef(null),
|
|
64
64
|
typingTimeout = useRef(),
|
|
65
65
|
[isMenuShown, setIsMenuShown] = useState(false),
|
|
66
66
|
[isRendered, setIsRendered] = useState(false),
|
|
@@ -117,12 +117,6 @@ export function ComboComponent(props) {
|
|
|
117
117
|
toggleMenu = () => {
|
|
118
118
|
setIsMenuShown(!isMenuShown);
|
|
119
119
|
},
|
|
120
|
-
getSavedSearch = () => {
|
|
121
|
-
return savedSearch.current;
|
|
122
|
-
},
|
|
123
|
-
setSavedSearch = (val) => {
|
|
124
|
-
savedSearch.current = val;
|
|
125
|
-
},
|
|
126
120
|
resetInputTextValue = () => {
|
|
127
121
|
setTextInputValue(getDisplayValue());
|
|
128
122
|
},
|
|
@@ -186,9 +180,7 @@ export function ComboComponent(props) {
|
|
|
186
180
|
}
|
|
187
181
|
|
|
188
182
|
if (_.isEmpty(value)) {
|
|
189
|
-
|
|
190
|
-
hideMenu();
|
|
191
|
-
return;
|
|
183
|
+
setValue(null);
|
|
192
184
|
}
|
|
193
185
|
|
|
194
186
|
setTextInputValue(value);
|
|
@@ -200,7 +192,9 @@ export function ComboComponent(props) {
|
|
|
200
192
|
}, 300);
|
|
201
193
|
},
|
|
202
194
|
onInputFocus = (e) => {
|
|
203
|
-
inputRef.current.select
|
|
195
|
+
if (inputRef.current.select) {
|
|
196
|
+
inputRef.current.select();
|
|
197
|
+
}
|
|
204
198
|
},
|
|
205
199
|
onInputBlur = (e) => {
|
|
206
200
|
if (isEventStillInComponent(e)) {
|
|
@@ -278,8 +272,6 @@ export function ComboComponent(props) {
|
|
|
278
272
|
} else {
|
|
279
273
|
throw Error('Not yet implemented');
|
|
280
274
|
}
|
|
281
|
-
|
|
282
|
-
setSavedSearch(null);
|
|
283
275
|
|
|
284
276
|
} else {
|
|
285
277
|
// throw Error('Not yet implemented');
|
|
@@ -331,7 +323,6 @@ export function ComboComponent(props) {
|
|
|
331
323
|
Repository.filter(filter);
|
|
332
324
|
}
|
|
333
325
|
|
|
334
|
-
setSavedSearch(value);
|
|
335
326
|
setNewEntityDisplayValue(value); // capture the search query so we can tell Grid what to use for a new entity's displayValue
|
|
336
327
|
|
|
337
328
|
} else {
|
|
@@ -435,105 +426,47 @@ export function ComboComponent(props) {
|
|
|
435
426
|
self.clear = onClearBtn;
|
|
436
427
|
}
|
|
437
428
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
429
|
+
let xButton = null,
|
|
430
|
+
inputAndTrigger = null,
|
|
431
|
+
grid = null,
|
|
432
|
+
dropdownMenu = null,
|
|
433
|
+
assembledComponents = null;
|
|
434
|
+
|
|
435
|
+
if (showXButton && !_.isNil(value)) {
|
|
436
|
+
xButton = <IconButton
|
|
437
|
+
_icon={{
|
|
438
|
+
as: Xmark,
|
|
439
|
+
color: 'trueGray.600',
|
|
440
|
+
size: 'sm',
|
|
441
|
+
}}
|
|
442
|
+
isDisabled={isDisabled}
|
|
443
|
+
onPress={onClearBtn}
|
|
444
|
+
h="100%"
|
|
445
|
+
bg={styles.FORM_COMBO_TRIGGER_BG}
|
|
446
|
+
_hover={{
|
|
447
|
+
bg: styles.FORM_COMBO_TRIGGER_HOVER_BG,
|
|
448
|
+
}}
|
|
449
|
+
/>;
|
|
441
450
|
}
|
|
442
451
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
'disableCopy',
|
|
453
|
-
'disableDuplicate',
|
|
454
|
-
'disablePrint',
|
|
455
|
-
]);
|
|
456
|
-
|
|
457
|
-
const WhichGrid = isEditor ? WindowedGridEditor : Grid;
|
|
458
|
-
|
|
459
|
-
let comboComponent = <Row {...refProps} justifyContent="center" alignItems="center" h={styles.FORM_COMBO_HEIGHT} flex={1} onLayout={() => setIsRendered(true)}>
|
|
460
|
-
{showXButton && !_.isNil(value) &&
|
|
461
|
-
<IconButton
|
|
462
|
-
_icon={{
|
|
463
|
-
as: Xmark,
|
|
464
|
-
color: 'trueGray.600',
|
|
465
|
-
size: 'sm',
|
|
466
|
-
}}
|
|
467
|
-
isDisabled={isDisabled}
|
|
468
|
-
onPress={onClearBtn}
|
|
469
|
-
h="100%"
|
|
470
|
-
bg={styles.FORM_COMBO_TRIGGER_BG}
|
|
471
|
-
_hover={{
|
|
472
|
-
bg: styles.FORM_COMBO_TRIGGER_HOVER_BG,
|
|
473
|
-
}}
|
|
474
|
-
/>}
|
|
475
|
-
{disableDirectEntry ?
|
|
476
|
-
<Pressable
|
|
477
|
-
onPress={toggleMenu}
|
|
478
|
-
flex={1}
|
|
479
|
-
h="100%"
|
|
480
|
-
>
|
|
481
|
-
<Text
|
|
482
|
-
ref={inputRef}
|
|
483
|
-
onLayout={(e) => {
|
|
484
|
-
// On web, this is not needed, but on RN it might be, so leave it in for now
|
|
485
|
-
const {
|
|
486
|
-
height,
|
|
487
|
-
width,
|
|
488
|
-
top,
|
|
489
|
-
left,
|
|
490
|
-
} = e.nativeEvent.layout;
|
|
491
|
-
setWidth(width);
|
|
492
|
-
setTop(top + height);
|
|
493
|
-
setLeft(left);
|
|
494
|
-
}}
|
|
495
|
-
flex={1}
|
|
496
|
-
h="100%"
|
|
497
|
-
numberOfLines={1}
|
|
498
|
-
ellipsizeMode="head"
|
|
499
|
-
m={0}
|
|
500
|
-
p={2}
|
|
501
|
-
borderWidth={1}
|
|
502
|
-
borderColor="trueGray.400"
|
|
503
|
-
borderTopRightRadius={0}
|
|
504
|
-
borderBottomRightRadius={0}
|
|
505
|
-
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
506
|
-
bg={styles.FORM_COMBO_INPUT_BG}
|
|
507
|
-
_focus={{
|
|
508
|
-
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
509
|
-
}}
|
|
510
|
-
>{textInputValue}</Text>
|
|
511
|
-
</Pressable> :
|
|
512
|
-
<Input
|
|
452
|
+
if (UiGlobals.mode === UI_MODE_WEB) {
|
|
453
|
+
inputAndTrigger = <>
|
|
454
|
+
{disableDirectEntry ?
|
|
455
|
+
<Pressable
|
|
456
|
+
onPress={toggleMenu}
|
|
457
|
+
flex={1}
|
|
458
|
+
h="100%"
|
|
459
|
+
>
|
|
460
|
+
<Text
|
|
513
461
|
ref={inputRef}
|
|
514
|
-
value={textInputValue}
|
|
515
|
-
autoSubmit={true}
|
|
516
|
-
isDisabled={isDisabled}
|
|
517
|
-
onChangeValue={onInputChangeText}
|
|
518
|
-
onKeyPress={onInputKeyPress}
|
|
519
|
-
onFocus={onInputFocus}
|
|
520
|
-
onBlur={onInputBlur}
|
|
521
|
-
onLayout={(e) => {
|
|
522
|
-
// On web, this is not needed, but on RN it might be, so leave it in for now
|
|
523
|
-
const {
|
|
524
|
-
height,
|
|
525
|
-
width,
|
|
526
|
-
top,
|
|
527
|
-
left,
|
|
528
|
-
} = e.nativeEvent.layout;
|
|
529
|
-
setWidth(width);
|
|
530
|
-
setTop(top + height);
|
|
531
|
-
setLeft(left);
|
|
532
|
-
}}
|
|
533
462
|
flex={1}
|
|
534
463
|
h="100%"
|
|
464
|
+
numberOfLines={1}
|
|
465
|
+
ellipsizeMode="head"
|
|
535
466
|
m={0}
|
|
536
|
-
|
|
467
|
+
p={2}
|
|
468
|
+
borderWidth={1}
|
|
469
|
+
borderColor="trueGray.400"
|
|
537
470
|
borderTopRightRadius={0}
|
|
538
471
|
borderBottomRightRadius={0}
|
|
539
472
|
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
@@ -541,171 +474,360 @@ export function ComboComponent(props) {
|
|
|
541
474
|
_focus={{
|
|
542
475
|
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
543
476
|
}}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
<
|
|
547
|
-
ref={
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
color: 'primary.800',
|
|
551
|
-
size: 'sm',
|
|
552
|
-
}}
|
|
477
|
+
>{textInputValue}</Text>
|
|
478
|
+
</Pressable> :
|
|
479
|
+
<Input
|
|
480
|
+
ref={inputRef}
|
|
481
|
+
value={textInputValue}
|
|
482
|
+
autoSubmit={true}
|
|
553
483
|
isDisabled={isDisabled}
|
|
554
|
-
|
|
555
|
-
|
|
484
|
+
onChangeValue={onInputChangeText}
|
|
485
|
+
onKeyPress={onInputKeyPress}
|
|
486
|
+
onFocus={onInputFocus}
|
|
487
|
+
onBlur={onInputBlur}
|
|
488
|
+
onLayout={(e) => {
|
|
489
|
+
const {
|
|
490
|
+
height,
|
|
491
|
+
width,
|
|
492
|
+
} = e.nativeEvent.layout;
|
|
493
|
+
setWidth(Math.round(width));
|
|
494
|
+
setTop(Math.round(height));
|
|
495
|
+
}}
|
|
496
|
+
flex={1}
|
|
556
497
|
h="100%"
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
bg={styles.
|
|
563
|
-
|
|
564
|
-
bg: styles.
|
|
498
|
+
m={0}
|
|
499
|
+
autoSubmitDelay={0}
|
|
500
|
+
borderTopRightRadius={0}
|
|
501
|
+
borderBottomRightRadius={0}
|
|
502
|
+
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
503
|
+
bg={styles.FORM_COMBO_INPUT_BG}
|
|
504
|
+
_focus={{
|
|
505
|
+
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
565
506
|
}}
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
507
|
+
{..._input}
|
|
508
|
+
/>}
|
|
509
|
+
<IconButton
|
|
510
|
+
ref={triggerRef}
|
|
511
|
+
_icon={{
|
|
512
|
+
as: CaretDown,
|
|
513
|
+
color: 'primary.800',
|
|
514
|
+
size: 'sm',
|
|
515
|
+
}}
|
|
516
|
+
isDisabled={isDisabled}
|
|
517
|
+
onPress={onTriggerPress}
|
|
518
|
+
onBlur={onTriggerBlur}
|
|
519
|
+
h="100%"
|
|
520
|
+
borderWidth={1}
|
|
521
|
+
borderColor="#bbb"
|
|
522
|
+
borderLeftWidth={0}
|
|
523
|
+
borderLeftRadius={0}
|
|
524
|
+
borderRightRadius="md"
|
|
525
|
+
bg={styles.FORM_COMBO_TRIGGER_BG}
|
|
526
|
+
_hover={{
|
|
527
|
+
bg: styles.FORM_COMBO_TRIGGER_HOVER_BG,
|
|
528
|
+
}}
|
|
529
|
+
/>
|
|
530
|
+
</>;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (UiGlobals.mode === UI_MODE_REACT_NATIVE) {
|
|
534
|
+
// This input and trigger are for show
|
|
535
|
+
// The just show the current value and open the menu
|
|
536
|
+
inputAndTrigger = <>
|
|
537
|
+
<Pressable
|
|
538
|
+
onPress={showMenu}
|
|
539
|
+
flex={1}
|
|
540
|
+
>
|
|
541
|
+
<Text
|
|
542
|
+
flex={1}
|
|
543
|
+
h="100%"
|
|
544
|
+
numberOfLines={1}
|
|
545
|
+
ellipsizeMode="head"
|
|
546
|
+
m={0}
|
|
547
|
+
p={2}
|
|
548
|
+
borderWidth={1}
|
|
549
|
+
borderColor="trueGray.400"
|
|
550
|
+
borderTopRightRadius={0}
|
|
551
|
+
borderBottomRightRadius={0}
|
|
552
|
+
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
553
|
+
bg={styles.FORM_COMBO_INPUT_BG}
|
|
554
|
+
_focus={{
|
|
555
|
+
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
572
556
|
}}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
557
|
+
>{textInputValue}</Text>
|
|
558
|
+
</Pressable>
|
|
559
|
+
<IconButton
|
|
560
|
+
ref={triggerRef}
|
|
561
|
+
_icon={{
|
|
562
|
+
as: CaretDown,
|
|
563
|
+
color: 'primary.800',
|
|
564
|
+
size: 'sm',
|
|
565
|
+
}}
|
|
566
|
+
isDisabled={isDisabled}
|
|
567
|
+
onPress={onTriggerPress}
|
|
568
|
+
h="100%"
|
|
569
|
+
borderWidth={1}
|
|
570
|
+
borderColor="#bbb"
|
|
571
|
+
borderLeftWidth={0}
|
|
572
|
+
borderLeftRadius={0}
|
|
573
|
+
borderRightRadius="md"
|
|
574
|
+
bg={styles.FORM_COMBO_TRIGGER_BG}
|
|
575
|
+
_hover={{
|
|
576
|
+
bg: styles.FORM_COMBO_TRIGGER_HOVER_BG,
|
|
577
|
+
}}
|
|
578
|
+
/>
|
|
579
|
+
</>;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
if (isMenuShown) {
|
|
583
|
+
const gridProps = _.pick(props, [
|
|
584
|
+
'Editor',
|
|
585
|
+
'model',
|
|
586
|
+
'Repository',
|
|
587
|
+
'data',
|
|
588
|
+
'idIx',
|
|
589
|
+
'displayIx',
|
|
590
|
+
'value',
|
|
591
|
+
'disableView',
|
|
592
|
+
'disableCopy',
|
|
593
|
+
'disableDuplicate',
|
|
594
|
+
'disablePrint',
|
|
595
|
+
]);
|
|
596
|
+
const WhichGrid = isEditor ? WindowedGridEditor : Grid;
|
|
597
|
+
grid = <WhichGrid
|
|
598
|
+
showHeaders={false}
|
|
599
|
+
showHovers={true}
|
|
600
|
+
shadow={1}
|
|
601
|
+
getRowProps={() => {
|
|
602
|
+
return {
|
|
603
|
+
borderBottomWidth: 1,
|
|
604
|
+
borderBottomColor: 'trueGray.300',
|
|
605
|
+
py: 1,
|
|
606
|
+
pl: 4,
|
|
607
|
+
pr: 2,
|
|
608
|
+
w: '100%',
|
|
609
|
+
};
|
|
610
|
+
}}
|
|
611
|
+
autoAdjustPageSizeToHeight={false}
|
|
612
|
+
{...gridProps}
|
|
613
|
+
reference="dropdownGrid"
|
|
614
|
+
parent={self}
|
|
615
|
+
h={UiGlobals.mode === UI_MODE_WEB ? styles.FORM_COMBO_MENU_HEIGHT + 'px' : null}
|
|
616
|
+
newEntityDisplayValue={newEntityDisplayValue}
|
|
617
|
+
disablePresetButtons={!isEditor}
|
|
618
|
+
onChangeSelection={(selection) => {
|
|
619
|
+
|
|
620
|
+
if (Repository && selection[0]?.isPhantom) {
|
|
621
|
+
// do nothing
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
setGridSelection(selection);
|
|
626
|
+
|
|
627
|
+
if (Repository) {
|
|
628
|
+
|
|
629
|
+
// When we first open the menu, we try to match the selection to the value, ignore this
|
|
630
|
+
if (selection[0]?.displayValue === getDisplayValue()) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// when user selected the record matching the current value, kill search mode
|
|
635
|
+
if (selection[0]?.id === value) {
|
|
636
|
+
setIsSearchMode(false);
|
|
637
|
+
resetInputTextValue();
|
|
638
|
+
if (hideMenuOnSelection) {
|
|
639
|
+
hideMenu();
|
|
640
|
+
}
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
setValue(selection[0] ? selection[0].id : null);
|
|
645
|
+
|
|
646
|
+
} else {
|
|
647
|
+
|
|
648
|
+
// When we first open the menu, we try to match the selection to the value, ignore this
|
|
649
|
+
if (selection[0] && selection[0][displayIx] === getDisplayValue()) {
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// when user selected the record matching the current value, kill search mode
|
|
654
|
+
if (selection[0] && selection[0][idIx] === value) {
|
|
655
|
+
setIsSearchMode(false);
|
|
656
|
+
resetInputTextValue();
|
|
657
|
+
if (hideMenuOnSelection) {
|
|
658
|
+
hideMenu();
|
|
659
|
+
}
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
setValue(selection[0] ? selection[0][idIx] : null);
|
|
664
|
+
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
if (_.isEmpty(selection)) {
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
if (hideMenuOnSelection && !isEditor) {
|
|
672
|
+
hideMenu();
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
}}
|
|
676
|
+
onSave={(selection) => {
|
|
677
|
+
const entity = selection[0];
|
|
678
|
+
if (entity?.id !== value) {
|
|
679
|
+
// Either a phantom record was just solidified into a real record, or a new (non-phantom) record was added.
|
|
680
|
+
// Select it and set the value of the combo.
|
|
681
|
+
setGridSelection([entity]);
|
|
682
|
+
const id = entity.id;
|
|
683
|
+
setValue(id);
|
|
684
|
+
}
|
|
685
|
+
}}
|
|
686
|
+
onRowPress={(item, e) => {
|
|
687
|
+
if (onRowPress) {
|
|
688
|
+
onRowPress(item, e);
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
const id = Repository ? item.id : item[idIx];
|
|
692
|
+
if (id === value) {
|
|
693
|
+
hideMenu();
|
|
694
|
+
onInputFocus();
|
|
695
|
+
}
|
|
696
|
+
}}
|
|
697
|
+
/>;
|
|
698
|
+
if (UiGlobals.mode === UI_MODE_WEB) {
|
|
699
|
+
dropdownMenu = <Popover
|
|
700
|
+
isOpen={isMenuShown}
|
|
701
|
+
onClose={() => {
|
|
702
|
+
hideMenu();
|
|
703
|
+
}}
|
|
704
|
+
trigger={emptyFn}
|
|
705
|
+
trapFocus={false}
|
|
706
|
+
placement={'auto'}
|
|
707
|
+
// _fade={{
|
|
708
|
+
// entryDuration: 0, // Doesn't work, as Popover doesn't have animation controls like Modal does. See node_modules/native-base/src/components/composites/Popover/Popover.tsx line 99 (vs .../composites/Modal/Modal.tsx line 113 which has ..._fade) I added a feature request to NativeBase https://github.com/GeekyAnts/NativeBase/issues/5651
|
|
709
|
+
// }}
|
|
710
|
+
{...props}
|
|
711
|
+
>
|
|
712
|
+
<Popover.Content
|
|
713
|
+
position="absolute"
|
|
714
|
+
top={top + 'px'}
|
|
715
|
+
left={left + 'px'}
|
|
716
|
+
w={width + 'px'}
|
|
717
|
+
minWidth={menuMinWidth}
|
|
718
|
+
overflow="auto"
|
|
719
|
+
bg="#fff"
|
|
720
|
+
|
|
721
|
+
h={200}
|
|
580
722
|
>
|
|
581
|
-
<Popover.
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
overflow="auto"
|
|
588
|
-
bg="#fff"
|
|
723
|
+
<Popover.Body
|
|
724
|
+
ref={menuRef}
|
|
725
|
+
borderWidth={1}
|
|
726
|
+
borderColor='trueGray.400'
|
|
727
|
+
borderTopWidth={0}
|
|
728
|
+
p={0}
|
|
589
729
|
>
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
}
|
|
685
|
-
}}
|
|
686
|
-
onRowPress={(item, e) => {
|
|
687
|
-
if (onRowPress) {
|
|
688
|
-
onRowPress(item, e);
|
|
689
|
-
return;
|
|
690
|
-
}
|
|
691
|
-
const id = Repository ? item.id : item[idIx];
|
|
692
|
-
if (id === value) {
|
|
693
|
-
hideMenu();
|
|
694
|
-
onInputFocus();
|
|
695
|
-
}
|
|
696
|
-
}}
|
|
697
|
-
/>
|
|
698
|
-
</Popover.Body>
|
|
699
|
-
</Popover.Content>
|
|
700
|
-
</Popover>
|
|
701
|
-
</Row>;
|
|
730
|
+
{grid}
|
|
731
|
+
</Popover.Body>
|
|
732
|
+
</Popover.Content>
|
|
733
|
+
</Popover>;
|
|
734
|
+
}
|
|
735
|
+
if (UiGlobals.mode === UI_MODE_REACT_NATIVE) {
|
|
736
|
+
const inputAndTriggerClone = // for RN, this is the actual input and trigger, as we need them to appear up above in the modal
|
|
737
|
+
<Row h={10}>
|
|
738
|
+
{disableDirectEntry ?
|
|
739
|
+
<Text
|
|
740
|
+
ref={inputRef}
|
|
741
|
+
flex={1}
|
|
742
|
+
h="100%"
|
|
743
|
+
numberOfLines={1}
|
|
744
|
+
ellipsizeMode="head"
|
|
745
|
+
m={0}
|
|
746
|
+
p={2}
|
|
747
|
+
borderWidth={1}
|
|
748
|
+
borderColor="trueGray.400"
|
|
749
|
+
borderTopRightRadius={0}
|
|
750
|
+
borderBottomRightRadius={0}
|
|
751
|
+
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
752
|
+
bg={styles.FORM_COMBO_INPUT_BG}
|
|
753
|
+
_focus={{
|
|
754
|
+
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
755
|
+
}}
|
|
756
|
+
>{textInputValue}</Text> :
|
|
757
|
+
<Input
|
|
758
|
+
ref={inputRef}
|
|
759
|
+
value={textInputValue}
|
|
760
|
+
autoSubmit={true}
|
|
761
|
+
isDisabled={isDisabled}
|
|
762
|
+
onChangeValue={onInputChangeText}
|
|
763
|
+
onKeyPress={onInputKeyPress}
|
|
764
|
+
onFocus={onInputFocus}
|
|
765
|
+
onBlur={onInputBlur}
|
|
766
|
+
flex={1}
|
|
767
|
+
h="100%"
|
|
768
|
+
m={0}
|
|
769
|
+
autoSubmitDelay={0}
|
|
770
|
+
borderTopRightRadius={0}
|
|
771
|
+
borderBottomRightRadius={0}
|
|
772
|
+
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
773
|
+
bg={styles.FORM_COMBO_INPUT_BG}
|
|
774
|
+
_focus={{
|
|
775
|
+
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
776
|
+
}}
|
|
777
|
+
{..._input}
|
|
778
|
+
/>}
|
|
779
|
+
<IconButton
|
|
780
|
+
_icon={{
|
|
781
|
+
as: CaretDown,
|
|
782
|
+
color: 'primary.800',
|
|
783
|
+
size: 'sm',
|
|
784
|
+
}}
|
|
785
|
+
isDisabled={isDisabled}
|
|
786
|
+
onPress={() => hideMenu()}
|
|
787
|
+
h="100%"
|
|
788
|
+
borderWidth={1}
|
|
789
|
+
borderColor="#bbb"
|
|
790
|
+
borderLeftWidth={0}
|
|
791
|
+
borderLeftRadius={0}
|
|
792
|
+
borderRightRadius="md"
|
|
793
|
+
bg={styles.FORM_COMBO_TRIGGER_BG}
|
|
794
|
+
_hover={{
|
|
795
|
+
bg: styles.FORM_COMBO_TRIGGER_HOVER_BG,
|
|
796
|
+
}}
|
|
797
|
+
/>
|
|
798
|
+
</Row>;
|
|
799
|
+
dropdownMenu = <Modal
|
|
800
|
+
isOpen={true}
|
|
801
|
+
onClose={() => setIsMenuShown(false)}
|
|
802
|
+
top="30%"
|
|
803
|
+
w="100%"
|
|
804
|
+
h={400}
|
|
805
|
+
px={5}
|
|
806
|
+
>
|
|
807
|
+
{inputAndTriggerClone}
|
|
808
|
+
{grid}
|
|
809
|
+
</Modal>;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
const refProps = {};
|
|
814
|
+
if (tooltipRef) {
|
|
815
|
+
refProps.ref = tooltipRef;
|
|
816
|
+
}
|
|
817
|
+
assembledComponents = <Row {...refProps} justifyContent="center" alignItems="center" h={styles.FORM_COMBO_HEIGHT} flex={1} onLayout={() => setIsRendered(true)}>
|
|
818
|
+
{xButton}
|
|
819
|
+
{inputAndTrigger}
|
|
820
|
+
{additionalButtons}
|
|
821
|
+
{dropdownMenu}
|
|
822
|
+
</Row>;
|
|
823
|
+
|
|
702
824
|
if (tooltip) {
|
|
703
|
-
|
|
704
|
-
{
|
|
825
|
+
assembledComponents = <Tooltip label={tooltip} placement={tooltipPlacement}>
|
|
826
|
+
{assembledComponents}
|
|
705
827
|
</Tooltip>;
|
|
706
828
|
}
|
|
707
829
|
|
|
708
|
-
return
|
|
830
|
+
return assembledComponents;
|
|
709
831
|
}
|
|
710
832
|
|
|
711
833
|
export const Combo = withComponent(
|
|
@@ -71,6 +71,7 @@ function Form(props) {
|
|
|
71
71
|
footerProps = {},
|
|
72
72
|
buttonGroupProps = {}, // buttons in footer
|
|
73
73
|
checkIsEditingDisabled = true,
|
|
74
|
+
disableLabels = false,
|
|
74
75
|
onBack,
|
|
75
76
|
onReset,
|
|
76
77
|
onViewMode,
|
|
@@ -295,6 +296,9 @@ function Form(props) {
|
|
|
295
296
|
if (isHidden) {
|
|
296
297
|
return null;
|
|
297
298
|
}
|
|
299
|
+
if (type === 'DisplayField') {
|
|
300
|
+
isEditable = false;
|
|
301
|
+
}
|
|
298
302
|
const propertyDef = name && Repository?.getSchema().getPropertyDefinition(name);
|
|
299
303
|
if (!useAdditionalEditButtons) {
|
|
300
304
|
item = _.omit(item, 'additionalEditButtons');
|
|
@@ -330,13 +334,13 @@ function Form(props) {
|
|
|
330
334
|
editorTypeProps.autoLoad = true;
|
|
331
335
|
}
|
|
332
336
|
}
|
|
333
|
-
if (isCombo) {
|
|
337
|
+
if (isCombo && _.isNil(propsToPass.showXButton)) {
|
|
334
338
|
editorTypeProps.showXButton = true;
|
|
335
339
|
}
|
|
336
340
|
const Element = getComponentFromType(type);
|
|
337
341
|
let children;
|
|
338
|
-
|
|
339
|
-
if (inArray(type, ['Column', 'FieldSet'])) {
|
|
342
|
+
|
|
343
|
+
if (inArray(type, ['Column', 'Row', 'FieldSet'])) {
|
|
340
344
|
if (_.isEmpty(items)) {
|
|
341
345
|
return null;
|
|
342
346
|
}
|
|
@@ -357,6 +361,9 @@ function Form(props) {
|
|
|
357
361
|
}
|
|
358
362
|
propsToPass.pl = 3;
|
|
359
363
|
}
|
|
364
|
+
if (type === 'Row') {
|
|
365
|
+
propsToPass.w = '100%';
|
|
366
|
+
}
|
|
360
367
|
const itemDefaults = item.defaults;
|
|
361
368
|
children = _.map(items, (item, ix) => {
|
|
362
369
|
return buildFromItem(item, ix, itemDefaults);
|
|
@@ -376,7 +383,7 @@ function Form(props) {
|
|
|
376
383
|
reference={name}
|
|
377
384
|
{...propsToPass}
|
|
378
385
|
/>;
|
|
379
|
-
if (label) {
|
|
386
|
+
if (!disableLabels && label) {
|
|
380
387
|
const labelProps = {};
|
|
381
388
|
if (defaults?.labelWidth) {
|
|
382
389
|
labelProps.w = defaults.labelWidth;
|
|
@@ -483,19 +490,24 @@ function Form(props) {
|
|
|
483
490
|
</Row>;
|
|
484
491
|
}
|
|
485
492
|
|
|
486
|
-
|
|
493
|
+
let requiredIndicator = null;
|
|
494
|
+
if (propertyDef?.validator?.spec && !propertyDef.validator.spec.optional) {
|
|
495
|
+
requiredIndicator = <Text color="#f00" fontSize="30px" pr={1}>*</Text>;
|
|
496
|
+
}
|
|
497
|
+
if (!disableLabels && label && editorType !== EDITOR_TYPE__INLINE) {
|
|
487
498
|
const labelProps = {};
|
|
488
499
|
if (defaults?.labelWidth) {
|
|
489
500
|
labelProps.w = defaults.labelWidth;
|
|
490
501
|
}
|
|
491
|
-
let requiredIndicator = null;
|
|
492
|
-
if (propertyDef?.validator?.spec && !propertyDef.validator.spec.optional) {
|
|
493
|
-
requiredIndicator = <Text color="#f00" pr={1}>*</Text>;
|
|
494
|
-
}
|
|
495
502
|
element = <Row w="100%" py={1}>
|
|
496
503
|
<Label {...labelProps}>{requiredIndicator}{label}</Label>
|
|
497
504
|
{element}
|
|
498
505
|
</Row>;
|
|
506
|
+
} else if (disableLabels && requiredIndicator) {
|
|
507
|
+
element = <Row w="100%" py={1}>
|
|
508
|
+
{requiredIndicator}
|
|
509
|
+
{element}
|
|
510
|
+
</Row>;
|
|
499
511
|
}
|
|
500
512
|
|
|
501
513
|
const dirtyIcon = isDirty ? <Icon as={Pencil} size="2xs" color="trueGray.300" position="absolute" top="2px" left="2px" /> : null;
|
|
@@ -740,8 +752,7 @@ function Form(props) {
|
|
|
740
752
|
}
|
|
741
753
|
|
|
742
754
|
return <Column {...sizeProps} onLayout={onLayoutDecorated} ref={formRef}>
|
|
743
|
-
{containerWidth && <>
|
|
744
|
-
|
|
755
|
+
{!!containerWidth && <>
|
|
745
756
|
{editorType === EDITOR_TYPE__INLINE &&
|
|
746
757
|
<ScrollView
|
|
747
758
|
horizontal={true}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
Pressable,
|
|
6
6
|
Icon,
|
|
7
7
|
Row,
|
|
8
|
+
ScrollView,
|
|
8
9
|
Text,
|
|
9
10
|
} from 'native-base';
|
|
10
11
|
import {
|
|
@@ -97,7 +98,7 @@ function GridComponent(props) {
|
|
|
97
98
|
additionalToolbarButtons = [],
|
|
98
99
|
h,
|
|
99
100
|
flex,
|
|
100
|
-
bg,
|
|
101
|
+
bg = '#fff',
|
|
101
102
|
|
|
102
103
|
// withComponent
|
|
103
104
|
self,
|
|
@@ -177,8 +178,8 @@ function GridComponent(props) {
|
|
|
177
178
|
}
|
|
178
179
|
const
|
|
179
180
|
{
|
|
180
|
-
shiftKey,
|
|
181
|
-
metaKey,
|
|
181
|
+
shiftKey = false,
|
|
182
|
+
metaKey = false,
|
|
182
183
|
} = e;
|
|
183
184
|
let allowToggle = allowToggleSelection;
|
|
184
185
|
if (metaKey) {
|
|
@@ -277,24 +278,31 @@ function GridComponent(props) {
|
|
|
277
278
|
if (isHeaderRow || isDragMode) {
|
|
278
279
|
return
|
|
279
280
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
onEditorRowClick
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
onEdit
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
281
|
+
if (CURRENT_MODE === UI_MODE_WEB) {
|
|
282
|
+
switch (e.detail) {
|
|
283
|
+
case 1: // single click
|
|
284
|
+
onRowClick(item, e); // sets selection
|
|
285
|
+
if (onEditorRowClick) {
|
|
286
|
+
onEditorRowClick(item, index, e);
|
|
287
|
+
}
|
|
288
|
+
break;
|
|
289
|
+
case 2: // double click
|
|
290
|
+
if (!isSelected) { // If a row was already selected when double-clicked, the first click will deselect it,
|
|
291
|
+
onRowClick(item, e); // so reselect it
|
|
292
|
+
}
|
|
293
|
+
if (onEdit) {
|
|
294
|
+
onEdit();
|
|
295
|
+
}
|
|
296
|
+
break;
|
|
297
|
+
case 3: // triple click
|
|
298
|
+
break;
|
|
299
|
+
default:
|
|
300
|
+
}
|
|
301
|
+
} else if (CURRENT_MODE === UI_MODE_REACT_NATIVE) {
|
|
302
|
+
onRowClick(item, e); // sets selection
|
|
303
|
+
if (onEditorRowClick) {
|
|
304
|
+
onEditorRowClick(item, index, e);
|
|
305
|
+
}
|
|
298
306
|
}
|
|
299
307
|
}}
|
|
300
308
|
onLongPress={(e) => {
|
|
@@ -877,43 +885,40 @@ function GridComponent(props) {
|
|
|
877
885
|
deselectAll();
|
|
878
886
|
}
|
|
879
887
|
}}>
|
|
880
|
-
{!entities?.length ?
|
|
881
|
-
<
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
bg="trueGray.100"
|
|
915
|
-
{...flatListProps}
|
|
916
|
-
/>}
|
|
888
|
+
{!entities?.length ?
|
|
889
|
+
<NoRecordsFound text={noneFoundText} onRefresh={onRefresh} /> :
|
|
890
|
+
<ScrollView flex={1} w="100%">
|
|
891
|
+
<FlatList
|
|
892
|
+
ref={gridRef}
|
|
893
|
+
scrollEnabled={false}
|
|
894
|
+
nestedScrollEnabled={true}
|
|
895
|
+
contentContainerStyle={{
|
|
896
|
+
overflow: 'auto',
|
|
897
|
+
borderWidth: isDragMode ? styles.REORDER_BORDER_WIDTH : 0,
|
|
898
|
+
borderColor: isDragMode ? styles.REORDER_BORDER_COLOR : null,
|
|
899
|
+
borderStyle: styles.REORDER_BORDER_STYLE,
|
|
900
|
+
flex: 1,
|
|
901
|
+
}}
|
|
902
|
+
refreshing={isLoading}
|
|
903
|
+
onRefresh={pullToRefresh ? onRefresh : null}
|
|
904
|
+
progressViewOffset={100}
|
|
905
|
+
data={rowData}
|
|
906
|
+
keyExtractor={(item) => {
|
|
907
|
+
let id;
|
|
908
|
+
if (item.id) {
|
|
909
|
+
id = item.id;
|
|
910
|
+
} else if (fields) {
|
|
911
|
+
id = item[idIx];
|
|
912
|
+
}
|
|
913
|
+
return String(id);
|
|
914
|
+
}}
|
|
915
|
+
initialNumToRender={initialNumToRender}
|
|
916
|
+
initialScrollIndex={0}
|
|
917
|
+
renderItem={renderRow}
|
|
918
|
+
bg="trueGray.100"
|
|
919
|
+
{...flatListProps}
|
|
920
|
+
/>
|
|
921
|
+
</ScrollView>}
|
|
917
922
|
</Column>
|
|
918
923
|
|
|
919
924
|
{listFooterComponent}
|
|
@@ -146,11 +146,13 @@ export default function GridRow(props) {
|
|
|
146
146
|
if (_.isFunction(value)) {
|
|
147
147
|
return value(key);
|
|
148
148
|
}
|
|
149
|
-
|
|
149
|
+
const elementProps = {};
|
|
150
|
+
if (UiGlobals.mode === UI_MODE_WEB) {
|
|
151
|
+
elementProps.textOverflow = 'ellipsis';
|
|
152
|
+
}
|
|
150
153
|
return <Text
|
|
151
154
|
key={key}
|
|
152
155
|
overflow="hidden"
|
|
153
|
-
textOverflow="ellipsis"
|
|
154
156
|
alignSelf="center"
|
|
155
157
|
style={{
|
|
156
158
|
userSelect: 'none',
|
|
@@ -160,6 +162,7 @@ export default function GridRow(props) {
|
|
|
160
162
|
py={styles.GRID_CELL_PY}
|
|
161
163
|
numberOfLines={1}
|
|
162
164
|
ellipsizeMode="head"
|
|
165
|
+
{...elementProps}
|
|
163
166
|
{...propsToPass}
|
|
164
167
|
>{value}</Text>;
|
|
165
168
|
});
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from 'native-base';
|
|
11
11
|
import {
|
|
12
12
|
ALERT_MODE_OK,
|
|
13
|
+
ALERT_MODE_YES,
|
|
13
14
|
ALERT_MODE_YES_NO,
|
|
14
15
|
ALERT_MODE_CUSTOM,
|
|
15
16
|
} from '../../Constants/Alert.js';
|
|
@@ -70,6 +71,7 @@ export default function withAlert(WrappedComponent) {
|
|
|
70
71
|
setMessage(message);
|
|
71
72
|
setIncludeCancel(includeCancel);
|
|
72
73
|
setYesCallback(() => callback);
|
|
74
|
+
setNoCallback(null);
|
|
73
75
|
showAlert();
|
|
74
76
|
},
|
|
75
77
|
onCancel = () => {
|
|
@@ -127,6 +129,15 @@ export default function withAlert(WrappedComponent) {
|
|
|
127
129
|
color="#fff"
|
|
128
130
|
>OK</Button>);
|
|
129
131
|
break;
|
|
132
|
+
case ALERT_MODE_YES:
|
|
133
|
+
buttons.push(<Button
|
|
134
|
+
key="yesBtn"
|
|
135
|
+
ref={autoFocusRef}
|
|
136
|
+
onPress={onYes}
|
|
137
|
+
color="#fff"
|
|
138
|
+
colorScheme="danger"
|
|
139
|
+
>Yes</Button>);
|
|
140
|
+
break;
|
|
130
141
|
case ALERT_MODE_YES_NO:
|
|
131
142
|
buttons.push(<Button
|
|
132
143
|
key="noBtn"
|
package/src/Constants/Alert.js
CHANGED