@onehat/ui 0.3.58 → 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 +398 -226
- package/src/Components/Form/Field/Tag/Tag.js +55 -46
- package/src/Components/Form/Field/Tag/ValueBox.js +45 -0
- package/src/Components/Form/Form.js +32 -12
- 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 +17 -2
- package/src/Components/Hoc/withFilters.js +3 -1
- package/src/Components/Hoc/withValue.js +8 -0
- package/src/Components/Icons/Images.js +14 -0
- package/src/Constants/Alert.js +1 -0
- package/src/Functions/delay.js +3 -0
- package/src/Functions/isVideo.js +18 -0
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { useState, } from 'react';
|
|
1
|
+
import { useState, useRef, } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Column,
|
|
4
4
|
Modal,
|
|
5
5
|
Row,
|
|
6
|
-
Text,
|
|
7
6
|
} from 'native-base';
|
|
8
7
|
import {
|
|
9
8
|
EDITOR_TYPE__WINDOWED,
|
|
@@ -12,49 +11,11 @@ import withAlert from '../../../Hoc/withAlert.js';
|
|
|
12
11
|
import withComponent from '../../../Hoc/withComponent.js';
|
|
13
12
|
import withData from '../../../Hoc/withData.js';
|
|
14
13
|
import withValue from '../../../Hoc/withValue.js';
|
|
15
|
-
import
|
|
16
|
-
import Eye from '../../../Icons/Eye.js';
|
|
17
|
-
import Xmark from '../../../Icons/Xmark.js';
|
|
14
|
+
import ValueBox from './ValueBox.js';
|
|
18
15
|
import Combo, { ComboEditor } from '../Combo/Combo.js';
|
|
19
16
|
import _ from 'lodash';
|
|
20
17
|
|
|
21
18
|
|
|
22
|
-
function ValueBox(props) {
|
|
23
|
-
const {
|
|
24
|
-
text,
|
|
25
|
-
onView,
|
|
26
|
-
onDelete,
|
|
27
|
-
} = props;
|
|
28
|
-
return <Row
|
|
29
|
-
borderWidth={1}
|
|
30
|
-
borderColor="trueGray.400"
|
|
31
|
-
borderRadius="md"
|
|
32
|
-
mr={1}
|
|
33
|
-
bg="trueGray.200"
|
|
34
|
-
alignItems="center"
|
|
35
|
-
>
|
|
36
|
-
<IconButton
|
|
37
|
-
_icon={{
|
|
38
|
-
as: Eye,
|
|
39
|
-
color: 'trueGray.600',
|
|
40
|
-
size: 'sm',
|
|
41
|
-
}}
|
|
42
|
-
onPress={onView}
|
|
43
|
-
h="100%"
|
|
44
|
-
/>
|
|
45
|
-
<Text color="trueGray.600" mr={onDelete ? 0 : 2}>{text}</Text>
|
|
46
|
-
{onDelete &&
|
|
47
|
-
<IconButton
|
|
48
|
-
_icon={{
|
|
49
|
-
as: Xmark,
|
|
50
|
-
color: 'trueGray.600',
|
|
51
|
-
size: 'sm',
|
|
52
|
-
}}
|
|
53
|
-
onPress={onDelete}
|
|
54
|
-
h="100%"
|
|
55
|
-
/>}
|
|
56
|
-
</Row>;
|
|
57
|
-
}
|
|
58
19
|
|
|
59
20
|
function TagComponent(props) {
|
|
60
21
|
|
|
@@ -67,6 +28,9 @@ function TagComponent(props) {
|
|
|
67
28
|
// parent Form
|
|
68
29
|
onChangeValue,
|
|
69
30
|
|
|
31
|
+
// withAlert
|
|
32
|
+
alert,
|
|
33
|
+
|
|
70
34
|
// withComponent
|
|
71
35
|
self,
|
|
72
36
|
|
|
@@ -75,8 +39,15 @@ function TagComponent(props) {
|
|
|
75
39
|
setValue,
|
|
76
40
|
...propsToPass // break connection between Tag and Combo props
|
|
77
41
|
} = props,
|
|
42
|
+
ignoreNextComboValueChangeRef = useRef(false),
|
|
78
43
|
[isViewerShown, setIsViewerShown] = useState(false),
|
|
79
44
|
[viewerSelection, setViewerSelection] = useState(false),
|
|
45
|
+
getIgnoreNextComboValueChange = () => {
|
|
46
|
+
return ignoreNextComboValueChangeRef.current;
|
|
47
|
+
},
|
|
48
|
+
setIgnoreNextComboValueChange = (bool) => {
|
|
49
|
+
ignoreNextComboValueChangeRef.current = bool;
|
|
50
|
+
},
|
|
80
51
|
onViewerClose = () => setIsViewerShown(false),
|
|
81
52
|
onView = async (item, e) => {
|
|
82
53
|
const
|
|
@@ -101,27 +72,63 @@ function TagComponent(props) {
|
|
|
101
72
|
setViewerSelection([record]);
|
|
102
73
|
setIsViewerShown(true);
|
|
103
74
|
},
|
|
104
|
-
|
|
75
|
+
clearComboValue = () => {
|
|
76
|
+
setIgnoreNextComboValueChange(true); // we're clearing out the value of the underlying Combo, so ignore it when this combo submits the new value change
|
|
77
|
+
self.children.combo.clear();
|
|
78
|
+
},
|
|
79
|
+
onChangeComboValue = (comboValue) => {
|
|
80
|
+
if (getIgnoreNextComboValueChange()) {
|
|
81
|
+
setIgnoreNextComboValueChange(false);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
105
85
|
// make sure value doesn't already exist
|
|
106
86
|
let exists = false;
|
|
107
87
|
_.each(value, (val) => {
|
|
108
|
-
if (val.id ===
|
|
88
|
+
if (val.id === comboValue) {
|
|
109
89
|
exists = true;
|
|
110
90
|
return false; // break
|
|
111
91
|
}
|
|
112
92
|
});
|
|
113
93
|
if (exists) {
|
|
94
|
+
clearComboValue();
|
|
114
95
|
alert('Value already exists!');
|
|
115
96
|
return;
|
|
116
97
|
}
|
|
117
98
|
|
|
99
|
+
// The value we get from combo is a simple int
|
|
100
|
+
// Convert this to id and displayValue from either Repository or data array.
|
|
101
|
+
const
|
|
102
|
+
Repository = props.Repository,
|
|
103
|
+
data = props.data,
|
|
104
|
+
idIx = props.idIx,
|
|
105
|
+
displayIx = props.displayIx,
|
|
106
|
+
id = comboValue;
|
|
107
|
+
let item,
|
|
108
|
+
displayValue;
|
|
109
|
+
if (Repository) {
|
|
110
|
+
item = Repository.getById(id);
|
|
111
|
+
if (!item) {
|
|
112
|
+
throw Error('item not found');
|
|
113
|
+
}
|
|
114
|
+
displayValue = item.displayValue;
|
|
115
|
+
} else {
|
|
116
|
+
item = _.find(data, (datum) => datum[idIx] === id);
|
|
117
|
+
if (!item) {
|
|
118
|
+
throw Error('item not found');
|
|
119
|
+
}
|
|
120
|
+
displayValue = item[displayIx];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
118
124
|
// add new value
|
|
119
125
|
const newValue = _.clone(value); // so we trigger a re-render
|
|
120
126
|
newValue.push({
|
|
121
|
-
id
|
|
122
|
-
text:
|
|
127
|
+
id,
|
|
128
|
+
text: displayValue,
|
|
123
129
|
})
|
|
124
130
|
setValue(newValue);
|
|
131
|
+
clearComboValue();
|
|
125
132
|
},
|
|
126
133
|
onDelete = (val) => {
|
|
127
134
|
// Remove from value array
|
|
@@ -174,7 +181,9 @@ function TagComponent(props) {
|
|
|
174
181
|
<WhichCombo
|
|
175
182
|
Repository={props.Repository}
|
|
176
183
|
Editor={props.Editor}
|
|
177
|
-
|
|
184
|
+
onChangeValue={onChangeComboValue}
|
|
185
|
+
parent={self}
|
|
186
|
+
reference="combo"
|
|
178
187
|
/>}
|
|
179
188
|
</Column>
|
|
180
189
|
{isViewerShown &&
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Row,
|
|
3
|
+
Text,
|
|
4
|
+
} from 'native-base';
|
|
5
|
+
import IconButton from '../../../Buttons/IconButton.js';
|
|
6
|
+
import Eye from '../../../Icons/Eye.js';
|
|
7
|
+
import Xmark from '../../../Icons/Xmark.js';
|
|
8
|
+
import _ from 'lodash';
|
|
9
|
+
|
|
10
|
+
export default function ValueBox(props) {
|
|
11
|
+
const {
|
|
12
|
+
text,
|
|
13
|
+
onView,
|
|
14
|
+
onDelete,
|
|
15
|
+
} = props;
|
|
16
|
+
return <Row
|
|
17
|
+
borderWidth={1}
|
|
18
|
+
borderColor="trueGray.400"
|
|
19
|
+
borderRadius="md"
|
|
20
|
+
mr={1}
|
|
21
|
+
bg="trueGray.200"
|
|
22
|
+
alignItems="center"
|
|
23
|
+
>
|
|
24
|
+
<IconButton
|
|
25
|
+
_icon={{
|
|
26
|
+
as: Eye,
|
|
27
|
+
color: 'trueGray.600',
|
|
28
|
+
size: 'sm',
|
|
29
|
+
}}
|
|
30
|
+
onPress={onView}
|
|
31
|
+
h="100%"
|
|
32
|
+
/>
|
|
33
|
+
<Text color="trueGray.600" mr={onDelete ? 0 : 2}>{text}</Text>
|
|
34
|
+
{onDelete &&
|
|
35
|
+
<IconButton
|
|
36
|
+
_icon={{
|
|
37
|
+
as: Xmark,
|
|
38
|
+
color: 'trueGray.600',
|
|
39
|
+
size: 'sm',
|
|
40
|
+
}}
|
|
41
|
+
onPress={onDelete}
|
|
42
|
+
h="100%"
|
|
43
|
+
/>}
|
|
44
|
+
</Row>;
|
|
45
|
+
}
|
|
@@ -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');
|
|
@@ -322,17 +326,21 @@ function Form(props) {
|
|
|
322
326
|
type = 'Text';
|
|
323
327
|
}
|
|
324
328
|
}
|
|
329
|
+
const isCombo = type?.match && type.match(/Combo/);
|
|
325
330
|
if (item.hasOwnProperty('autoLoad')) {
|
|
326
331
|
editorTypeProps.autoLoad = item.autoLoad;
|
|
327
332
|
} else {
|
|
328
|
-
if (
|
|
333
|
+
if (isCombo && Repository?.isRemote && !Repository?.isLoaded) {
|
|
329
334
|
editorTypeProps.autoLoad = true;
|
|
330
335
|
}
|
|
331
336
|
}
|
|
337
|
+
if (isCombo && _.isNil(propsToPass.showXButton)) {
|
|
338
|
+
editorTypeProps.showXButton = true;
|
|
339
|
+
}
|
|
332
340
|
const Element = getComponentFromType(type);
|
|
333
341
|
let children;
|
|
334
|
-
|
|
335
|
-
if (inArray(type, ['Column', 'FieldSet'])) {
|
|
342
|
+
|
|
343
|
+
if (inArray(type, ['Column', 'Row', 'FieldSet'])) {
|
|
336
344
|
if (_.isEmpty(items)) {
|
|
337
345
|
return null;
|
|
338
346
|
}
|
|
@@ -353,6 +361,9 @@ function Form(props) {
|
|
|
353
361
|
}
|
|
354
362
|
propsToPass.pl = 3;
|
|
355
363
|
}
|
|
364
|
+
if (type === 'Row') {
|
|
365
|
+
propsToPass.w = '100%';
|
|
366
|
+
}
|
|
356
367
|
const itemDefaults = item.defaults;
|
|
357
368
|
children = _.map(items, (item, ix) => {
|
|
358
369
|
return buildFromItem(item, ix, itemDefaults);
|
|
@@ -372,7 +383,7 @@ function Form(props) {
|
|
|
372
383
|
reference={name}
|
|
373
384
|
{...propsToPass}
|
|
374
385
|
/>;
|
|
375
|
-
if (label) {
|
|
386
|
+
if (!disableLabels && label) {
|
|
376
387
|
const labelProps = {};
|
|
377
388
|
if (defaults?.labelWidth) {
|
|
378
389
|
labelProps.w = defaults.labelWidth;
|
|
@@ -479,19 +490,24 @@ function Form(props) {
|
|
|
479
490
|
</Row>;
|
|
480
491
|
}
|
|
481
492
|
|
|
482
|
-
|
|
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) {
|
|
483
498
|
const labelProps = {};
|
|
484
499
|
if (defaults?.labelWidth) {
|
|
485
500
|
labelProps.w = defaults.labelWidth;
|
|
486
501
|
}
|
|
487
|
-
let requiredIndicator = null;
|
|
488
|
-
if (propertyDef?.validator?.spec && !propertyDef.validator.spec.optional) {
|
|
489
|
-
requiredIndicator = <Text color="#f00" pr={1}>*</Text>;
|
|
490
|
-
}
|
|
491
502
|
element = <Row w="100%" py={1}>
|
|
492
503
|
<Label {...labelProps}>{requiredIndicator}{label}</Label>
|
|
493
504
|
{element}
|
|
494
505
|
</Row>;
|
|
506
|
+
} else if (disableLabels && requiredIndicator) {
|
|
507
|
+
element = <Row w="100%" py={1}>
|
|
508
|
+
{requiredIndicator}
|
|
509
|
+
{element}
|
|
510
|
+
</Row>;
|
|
495
511
|
}
|
|
496
512
|
|
|
497
513
|
const dirtyIcon = isDirty ? <Icon as={Pencil} size="2xs" color="trueGray.300" position="absolute" top="2px" left="2px" /> : null;
|
|
@@ -736,8 +752,7 @@ function Form(props) {
|
|
|
736
752
|
}
|
|
737
753
|
|
|
738
754
|
return <Column {...sizeProps} onLayout={onLayoutDecorated} ref={formRef}>
|
|
739
|
-
{containerWidth && <>
|
|
740
|
-
|
|
755
|
+
{!!containerWidth && <>
|
|
741
756
|
{editorType === EDITOR_TYPE__INLINE &&
|
|
742
757
|
<ScrollView
|
|
743
758
|
horizontal={true}
|
|
@@ -779,7 +794,12 @@ function Form(props) {
|
|
|
779
794
|
}
|
|
780
795
|
reset();
|
|
781
796
|
}}
|
|
782
|
-
icon={
|
|
797
|
+
icon={Rotate}
|
|
798
|
+
_icon={{
|
|
799
|
+
color: !formState.isDirty ? 'trueGray.400' : '#000',
|
|
800
|
+
}}
|
|
801
|
+
isDisabled={!formState.isDirty}
|
|
802
|
+
mr={2}
|
|
783
803
|
/>}
|
|
784
804
|
|
|
785
805
|
{showCancelBtn &&
|
|
@@ -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';
|
|
@@ -27,6 +28,7 @@ export default function withAlert(WrappedComponent) {
|
|
|
27
28
|
[isAlertShown, setIsAlertShown] = useState(false),
|
|
28
29
|
[title, setTitle] = useState(''),
|
|
29
30
|
[message, setMessage] = useState(''),
|
|
31
|
+
[canClose, setCanClose] = useState(true),
|
|
30
32
|
[includeCancel, setIncludeCancel] = useState(false),
|
|
31
33
|
[okCallback, setOkCallback] = useState(),
|
|
32
34
|
[yesCallback, setYesCallback] = useState(),
|
|
@@ -35,7 +37,7 @@ export default function withAlert(WrappedComponent) {
|
|
|
35
37
|
[mode, setMode] = useState(ALERT_MODE_OK),
|
|
36
38
|
autoFocusRef = useRef(null),
|
|
37
39
|
cancelRef = useRef(null),
|
|
38
|
-
onAlert = (arg1, okCallback, includeCancel = false) => {
|
|
40
|
+
onAlert = (arg1, okCallback, includeCancel = false, canClose = true) => {
|
|
39
41
|
clearAll();
|
|
40
42
|
if (_.isString(arg1)) {
|
|
41
43
|
setMode(ALERT_MODE_OK);
|
|
@@ -43,6 +45,7 @@ export default function withAlert(WrappedComponent) {
|
|
|
43
45
|
setMessage(arg1);
|
|
44
46
|
setOkCallback(() => okCallback);
|
|
45
47
|
setIncludeCancel(includeCancel);
|
|
48
|
+
setCanClose(canClose);
|
|
46
49
|
} else if (_.isPlainObject(arg1)) {
|
|
47
50
|
// custom
|
|
48
51
|
const {
|
|
@@ -50,12 +53,14 @@ export default function withAlert(WrappedComponent) {
|
|
|
50
53
|
message,
|
|
51
54
|
buttons,
|
|
52
55
|
includeCancel,
|
|
56
|
+
canClose,
|
|
53
57
|
} = arg1;
|
|
54
58
|
setMode(ALERT_MODE_CUSTOM);
|
|
55
59
|
setTitle(title);
|
|
56
60
|
setMessage(message);
|
|
57
61
|
setCustomButtons(buttons);
|
|
58
62
|
setIncludeCancel(includeCancel);
|
|
63
|
+
setCanClose(canClose);
|
|
59
64
|
}
|
|
60
65
|
showAlert();
|
|
61
66
|
},
|
|
@@ -66,6 +71,7 @@ export default function withAlert(WrappedComponent) {
|
|
|
66
71
|
setMessage(message);
|
|
67
72
|
setIncludeCancel(includeCancel);
|
|
68
73
|
setYesCallback(() => callback);
|
|
74
|
+
setNoCallback(null);
|
|
69
75
|
showAlert();
|
|
70
76
|
},
|
|
71
77
|
onCancel = () => {
|
|
@@ -123,6 +129,15 @@ export default function withAlert(WrappedComponent) {
|
|
|
123
129
|
color="#fff"
|
|
124
130
|
>OK</Button>);
|
|
125
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;
|
|
126
141
|
case ALERT_MODE_YES_NO:
|
|
127
142
|
buttons.push(<Button
|
|
128
143
|
key="noBtn"
|
|
@@ -161,7 +176,7 @@ export default function withAlert(WrappedComponent) {
|
|
|
161
176
|
onClose={() => setIsAlertShown(false)}
|
|
162
177
|
>
|
|
163
178
|
<AlertDialog.Content>
|
|
164
|
-
<AlertDialog.CloseButton />
|
|
179
|
+
{canClose && <AlertDialog.CloseButton />}
|
|
165
180
|
<AlertDialog.Header>{title}</AlertDialog.Header>
|
|
166
181
|
<AlertDialog.Body>
|
|
167
182
|
<Row>
|
|
@@ -536,7 +536,9 @@ export default function withFilters(WrappedComponent) {
|
|
|
536
536
|
},
|
|
537
537
|
]}
|
|
538
538
|
onCancel={(e) => {
|
|
539
|
-
|
|
539
|
+
setIsFilterSelectorShown(false);
|
|
540
|
+
}}
|
|
541
|
+
onClose={(e) => {
|
|
540
542
|
setIsFilterSelectorShown(false);
|
|
541
543
|
}}
|
|
542
544
|
onSave={(data, e) => {
|
|
@@ -28,6 +28,9 @@ export default function withValue(WrappedComponent) {
|
|
|
28
28
|
isValueAlwaysArray = false,
|
|
29
29
|
isValueAsStringifiedJson = false,
|
|
30
30
|
|
|
31
|
+
// withComponent
|
|
32
|
+
self,
|
|
33
|
+
|
|
31
34
|
// withData
|
|
32
35
|
Repository,
|
|
33
36
|
idIx,
|
|
@@ -120,6 +123,11 @@ export default function withValue(WrappedComponent) {
|
|
|
120
123
|
}, []);
|
|
121
124
|
}
|
|
122
125
|
|
|
126
|
+
if (self) {
|
|
127
|
+
self.setValue = setValue;
|
|
128
|
+
self.value = getLocalValue();
|
|
129
|
+
}
|
|
130
|
+
|
|
123
131
|
|
|
124
132
|
// Convert localValue to normal JS primitives for field components
|
|
125
133
|
let convertedValue = getLocalValue();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc.
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import Svg, { Path } from "react-native-svg"
|
|
4
|
+
import { Icon } from 'native-base';
|
|
5
|
+
|
|
6
|
+
function SvgComponent(props) {
|
|
7
|
+
return (
|
|
8
|
+
<Icon xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" {...props}>
|
|
9
|
+
<Path d="M512 32H160c-35.35 0-64 28.65-64 64v224c0 35.35 28.65 64 64 64h352c35.35 0 64-28.65 64-64V96c0-35.35-28.7-64-64-64zm16 288c0 8.822-7.178 16-16 16h-16L386.7 175.1c-3-4.4-8-7.1-13.4-7.1a15.978 15.978 0 00-13.31 7.125l-62.74 94.11L274.9 238.6c-3-4.2-7.8-6.6-12.9-6.6a16.007 16.007 0 00-12.93 6.574L176 336h-16c-8.822 0-16-7.178-16-16V96c0-8.822 7.178-16 16-16h352c8.822 0 16 7.178 16 16v224zM224 112c-17.67 0-32 14.33-32 32s14.33 32 32 32c17.68 0 32-14.33 32-32s-14.3-32-32-32zm232 368H120C53.83 480 0 426.2 0 360V120c0-13.2 10.75-24 24-24s24 10.8 24 24v240c0 39.7 32.3 72 72 72h336c13.25 0 24 10.75 24 24s-10.7 24-24 24z" />
|
|
10
|
+
</Icon>
|
|
11
|
+
)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default SvgComponent
|
package/src/Constants/Alert.js
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export default function isVideo(mimetype) {
|
|
2
|
+
switch(mimetype) {
|
|
3
|
+
case 'video/quicktime':
|
|
4
|
+
case 'video/mp4':
|
|
5
|
+
case 'video/mpeg':
|
|
6
|
+
case 'video/ogg':
|
|
7
|
+
case 'video/webm':
|
|
8
|
+
case 'video/mp2t':
|
|
9
|
+
case 'video/3gpp':
|
|
10
|
+
case 'video/3gpp2':
|
|
11
|
+
case 'video/x-msvideo':
|
|
12
|
+
case 'video/x-ms-wmv':
|
|
13
|
+
case 'video/x-flv':
|
|
14
|
+
case 'application/x-mpegURL':
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
}
|