@onehat/ui 0.2.65 → 0.2.66

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.65",
3
+ "version": "0.2.66",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -14,6 +14,7 @@ export default function Editor(props) {
14
14
  onEditorCancel: onCancel,
15
15
  onEditorSave: onSave,
16
16
  onEditorClose: onClose,
17
+ onEditorDelete: onDelete,
17
18
  editorMode,
18
19
  setEditorMode,
19
20
 
@@ -41,6 +42,7 @@ export default function Editor(props) {
41
42
  Repository={Repository}
42
43
  onEditMode={isViewOnly ? null : onEditMode}
43
44
  onClose={onClose}
45
+ onDelete={onDelete}
44
46
  {...props}
45
47
  />;
46
48
  }
@@ -49,11 +51,12 @@ export default function Editor(props) {
49
51
  // and only show in one column when it's not.
50
52
 
51
53
  return <Form
54
+ {...props}
52
55
  record={selection}
53
56
  onViewMode={onViewMode}
54
57
  onCancel={onCancel}
55
58
  onSave={onSave}
56
59
  onClose={onClose}
57
- {...props}
60
+ onDelete={onDelete}
58
61
  />;
59
62
  }
@@ -0,0 +1,71 @@
1
+ import {
2
+ Button,
3
+ Column,
4
+ Icon,
5
+ ScrollView,
6
+ Row,
7
+ Text,
8
+ } from 'native-base';
9
+ import Label from '../Form/Label.js';
10
+ import Pencil from '../Icons/Pencil.js';
11
+ import Footer from '../Layout/Footer.js';
12
+ import _ from 'lodash';
13
+
14
+ // This is a wrapper for the Viewer subcomponent passed to props,]
15
+ // that adds
16
+
17
+
18
+ export default function Viewer(props) {
19
+ const {
20
+ Viewer, // Subcomponent
21
+ additionalViewButtons = [],
22
+ onEditMode,
23
+ onClose,
24
+ onDelete,
25
+ } = props;
26
+
27
+ return <Column flex={1} w="100%">
28
+ <ScrollView flex={1} w="100%">
29
+ <Column m={2}>
30
+ {onEditMode && <Row mb={4} justifyContent="flex-end">
31
+ <Button
32
+ key="editBtn"
33
+ onPress={onEditMode}
34
+ leftIcon={<Icon as={Pencil} color="#fff" size="sm" />}
35
+ color="#fff"
36
+ >To Edit</Button>
37
+ </Row>}
38
+
39
+ {!_.isEmpty(additionalViewButtons) &&
40
+ <Row p={2} alignItems="center" justifyContent="flex-end">
41
+ {additionalViewButtons}
42
+ </Row>}
43
+
44
+ <Viewer {...props} />
45
+
46
+ </Column>
47
+ </ScrollView>
48
+ <Footer justifyContent="flex-end">
49
+ {onDelete && <Row flex={1} justifyContent="flex-start">
50
+ <Button
51
+ key="deleteBtn"
52
+ onPress={() => {
53
+ confirm('Are you sure you want to delete this record?', onDelete);
54
+ }}
55
+ bg="warning"
56
+ _hover={{
57
+ bg: 'warningHover',
58
+ }}
59
+ color="#fff"
60
+ >Delete</Button>
61
+ </Row>}
62
+ <Button.Group space={2}>
63
+ <Button
64
+ key="closeBtn"
65
+ onPress={onClose}
66
+ color="#fff"
67
+ >Close</Button>
68
+ </Button.Group>
69
+ </Footer>
70
+ </Column>;
71
+ }
@@ -65,7 +65,7 @@ function Form(props) {
65
65
  onBack,
66
66
  onReset,
67
67
  onViewMode,
68
- additionalButtons = [],
68
+ additionalEditButtons = [],
69
69
  ancillaryComponents = [],
70
70
 
71
71
  // sizing of outer container
@@ -83,9 +83,9 @@ function Form(props) {
83
83
  isViewOnly = false,
84
84
  editorMode,
85
85
  onCancel,
86
- onEditorSave,
87
- onSave = onEditorSave,
86
+ onSave,
88
87
  onClose,
88
+ onDelete,
89
89
 
90
90
  // DataMgt
91
91
  selectorId,
@@ -121,7 +121,7 @@ function Form(props) {
121
121
  mode: 'onChange', // onChange | onBlur | onSubmit | onTouched | all
122
122
  // reValidateMode: 'onChange', // onChange | onBlur | onSubmit
123
123
  defaultValues,
124
- // values: defaultValues, // NOTE: This will cause a looping re-render if not used carefully!
124
+ // values: defaultValues,
125
125
  // resetOptions: {
126
126
  // keepDirtyValues: false, // user-interacted input will be retained
127
127
  // keepErrors: false, // input errors will be retained with value update
@@ -478,6 +478,14 @@ function Form(props) {
478
478
  editorModeF = isMultiple ? 'Edit Multiple' : 'Edit';
479
479
  break;
480
480
  }
481
+
482
+ let isSaveDisabled = false;
483
+ if (!_.isEmpty(formState.errors)) {
484
+ isSaveDisabled = true;
485
+ }
486
+ if (_.isEmpty(formState.dirtyFields) && !record?.isRemotePhantom) {
487
+ isSaveDisabled = true;
488
+ }
481
489
 
482
490
  return <Column {...sizeProps} onLayout={onLayout}>
483
491
 
@@ -504,15 +512,29 @@ function Form(props) {
504
512
  color="#fff"
505
513
  >To View</Button>}
506
514
  </Row>
507
- {!_.isEmpty(additionalButtons) &&
515
+ {editorMode === EDITOR_MODE__EDIT && !_.isEmpty(additionalEditButtons) &&
508
516
  <Row p={2} alignItems="center" justifyContent="flex-end">
509
- {additionalButtons}
517
+ {additionalEditButtons}
510
518
  </Row>}
511
519
 
512
520
  {editor}
513
521
 
514
522
  <Footer justifyContent="flex-end" {...footerProps}>
523
+ {onDelete && <Row flex={1} justifyContent="flex-start">
524
+ <Button
525
+ key="deleteBtn"
526
+ onPress={() => {
527
+ confirm('Are you sure you want to delete this record?', onDelete);
528
+ }}
529
+ bg="warning"
530
+ _hover={{
531
+ bg: 'warningHover',
532
+ }}
533
+ color="#fff"
534
+ >Delete</Button>
535
+ </Row>}
515
536
  <Button.Group space={2} {...buttonGroupProps}>
537
+
516
538
  {!isViewOnly && <IconButton
517
539
  key="resetBtn"
518
540
  onPress={() => {
@@ -538,7 +560,7 @@ function Form(props) {
538
560
  {!isViewOnly && onSave && <Button
539
561
  key="saveBtn"
540
562
  onPress={(e) => handleSubmit(onSave, onSubmitError)(e)}
541
- isDisabled={!_.isEmpty(formState.errors) || (!isSingle && !record?.isPhantom && !_.isEmpty(formState.dirtyFields))}
563
+ isDisabled={isSaveDisabled}
542
564
  color="#fff"
543
565
  >{editorMode === EDITOR_MODE__ADD ? 'Add' : 'Save'}</Button>}
544
566
  {isViewOnly && onClose && <Button
@@ -23,7 +23,7 @@ export default function withEditor(WrappedComponent) {
23
23
  if (selection.length > 1) {
24
24
  return 'records?';
25
25
  }
26
- return 'record' + (selection[0].displayValue ? ' ' + selection[0].displayValue : '') + '?';
26
+ return 'record' + (selection[0].displayValue ? ' "' + selection[0].displayValue + '"' : '') + '?';
27
27
  },
28
28
  record,
29
29
 
@@ -45,10 +45,7 @@ export default function withEditor(WrappedComponent) {
45
45
  [isEditorShown, setIsEditorShown] = useState(false),
46
46
  [isEditorViewOnly, setIsEditorViewOnly] = useState(false),
47
47
  [lastSelection, setLastSelection] = useState(),
48
- addRecord = async () => {
49
- if (!userCanEdit || disableAdd) {
50
- return;
51
- }
48
+ onAdd = async () => {
52
49
  const defaultValues = Repository.getSchema().model.defaultValues;
53
50
  let addValues = _.clone(defaultValues);
54
51
 
@@ -75,30 +72,24 @@ export default function withEditor(WrappedComponent) {
75
72
  setEditorMode(EDITOR_MODE__ADD);
76
73
  setIsEditorShown(true);
77
74
  },
78
- editRecord = () => {
79
- if (!userCanEdit || disableEdit) {
80
- return;
81
- }
75
+ onEdit = () => {
82
76
  setIsEditorViewOnly(false);
83
77
  setEditorMode(EDITOR_MODE__EDIT);
84
78
  setIsEditorShown(true);
85
79
  },
86
- deleteRecord = (e) => {
87
- if (!userCanEdit || disableDelete) {
88
- return;
89
- }
80
+ onDelete = () => {
90
81
  const
91
82
  isSingle = selection.length === 1,
92
83
  isPhantom = selection[0] && selection[0].isPhantom;
93
84
 
94
85
  if (isSingle && isPhantom) {
95
- onDelete();
86
+ deleteRecord();
96
87
  } else {
97
88
  const identifier = getRecordIdentifier(selection);
98
- confirm('Are you sure you want to delete the ' + identifier, onDelete);
89
+ confirm('Are you sure you want to delete the ' + identifier, deleteRecord);
99
90
  }
100
91
  },
101
- onDelete = async () => {
92
+ deleteRecord = async () => {
102
93
  await Repository.delete(selection);
103
94
  if (!Repository.isAutoSave) {
104
95
  await Repository.save();
@@ -160,7 +151,7 @@ export default function withEditor(WrappedComponent) {
160
151
  isSingle = selection.length === 1,
161
152
  isPhantom = selection[0] && selection[0].isPhantom;
162
153
  if (isSingle && isPhantom) {
163
- await onDelete();
154
+ await deleteRecord();
164
155
  }
165
156
  setEditorMode(EDITOR_MODE__VIEW);
166
157
  setIsEditorShown(false);
@@ -168,6 +159,11 @@ export default function withEditor(WrappedComponent) {
168
159
  onEditorClose = () => {
169
160
  setIsEditorShown(false);
170
161
  },
162
+ onEditorDelete = async () => {
163
+ await deleteRecord();
164
+ setEditorMode(EDITOR_MODE__VIEW);
165
+ setIsEditorShown(false);
166
+ },
171
167
  calculateEditorMode = () => {
172
168
  let mode = EDITOR_MODE__VIEW;
173
169
  if (userCanEdit) {
@@ -208,13 +204,14 @@ export default function withEditor(WrappedComponent) {
208
204
  editorMode={editorMode}
209
205
  setEditorMode={setEditorMode}
210
206
  setIsEditorShown={setIsEditorShown}
211
- onAdd={addRecord}
212
- onEdit={editRecord}
213
- onDelete={deleteRecord}
207
+ onAdd={(!userCanEdit || disableAdd) ? null : onAdd}
208
+ onEdit={(!userCanEdit || disableEdit) ? null : onEdit}
209
+ onDelete={(!userCanEdit || disableDelete || (editorMode === EDITOR_MODE__ADD && (selection[0]?.isPhantom || currentRecord?.isPhantom))) ? null : onDelete}
214
210
  onView={viewRecord}
215
211
  onDuplicate={duplicateRecord}
216
212
  onEditorSave={onEditorSave}
217
213
  onEditorCancel={onEditorCancel}
214
+ onEditorDelete={(!userCanEdit || disableDelete || (editorMode === EDITOR_MODE__ADD && (selection[0]?.isPhantom || currentRecord?.isPhantom))) ? null : onEditorDelete}
218
215
  onEditorClose={onEditorClose}
219
216
  useEditor={useEditor}
220
217
  userCanEdit={userCanEdit}
@@ -23,6 +23,7 @@ const ThemeOverrides = {
23
23
  vip: '#3a78bc',
24
24
  navBlue: '#3b82f6',
25
25
  warning: '#d92b2b',
26
+ warningHover: '#af1313',
26
27
  orange: '#de9000',
27
28
  greens: {
28
29
  100: '#4CAF50',