@onehat/ui 0.3.333 → 0.3.335
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/Editor/Editor.js +2 -2
- package/src/Components/Form/Form.js +7 -1
- package/src/Components/Grid/Grid.js +129 -96
- package/src/Components/Hoc/Secondary/withSecondaryEditor.js +57 -2
- package/src/Components/Hoc/withData.js +1 -4
- package/src/Components/Hoc/withEditor.js +78 -2
- package/src/Components/Hoc/withPdfButtons.js +11 -2
- package/src/Components/Hoc/withPermissions.js +110 -0
- package/src/Components/Hoc/withPresetButtons.js +62 -33
- package/src/Components/Messages/Unauthorized.js +17 -0
- package/src/Components/Tree/Tree.js +57 -32
- package/src/Components/Viewer/Viewer.js +17 -9
- package/src/Constants/Commands.js +8 -0
- package/src/Functions/chunkArray.js +7 -0
- package/src/Components/WaitModal.js +0 -31
|
@@ -2,11 +2,22 @@ import { useEffect, useState, useRef, } from 'react';
|
|
|
2
2
|
import {
|
|
3
3
|
Button,
|
|
4
4
|
} from 'native-base';
|
|
5
|
+
import {
|
|
6
|
+
ADD,
|
|
7
|
+
EDIT,
|
|
8
|
+
DELETE,
|
|
9
|
+
VIEW,
|
|
10
|
+
COPY,
|
|
11
|
+
DUPLICATE,
|
|
12
|
+
PRINT,
|
|
13
|
+
UPLOAD_DOWNLOAD,
|
|
14
|
+
} from '../../Constants/Commands.js';
|
|
5
15
|
import {
|
|
6
16
|
EDITOR_MODE__VIEW,
|
|
7
17
|
EDITOR_MODE__ADD,
|
|
8
18
|
EDITOR_MODE__EDIT,
|
|
9
19
|
EDITOR_TYPE__SIDE,
|
|
20
|
+
EDITOR_TYPE__INLINE,
|
|
10
21
|
} from '../../Constants/Editor.js';
|
|
11
22
|
import UiGlobals from '../../UiGlobals.js';
|
|
12
23
|
import _ from 'lodash';
|
|
@@ -20,7 +31,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
20
31
|
|
|
21
32
|
let [editorMode, setEditorMode] = useState(EDITOR_MODE__VIEW); // Can change below, so use 'let'
|
|
22
33
|
const {
|
|
23
|
-
userCanEdit = true,
|
|
34
|
+
userCanEdit = true, // not permissions, but capability
|
|
24
35
|
userCanView = true,
|
|
25
36
|
canEditorViewOnly = false, // whether the editor can *ever* change state out of 'View' mode
|
|
26
37
|
disableAdd = false,
|
|
@@ -56,6 +67,10 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
56
67
|
// withData
|
|
57
68
|
Repository,
|
|
58
69
|
|
|
70
|
+
// withPermissions
|
|
71
|
+
canUser,
|
|
72
|
+
showPermissionsError,
|
|
73
|
+
|
|
59
74
|
// withSelection
|
|
60
75
|
selection,
|
|
61
76
|
setSelection,
|
|
@@ -108,6 +123,11 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
108
123
|
return newEntityDisplayValueRef.current;
|
|
109
124
|
},
|
|
110
125
|
doAdd = async (e, values) => {
|
|
126
|
+
if (canUser && !canUser(ADD)) {
|
|
127
|
+
showPermissionsError(ADD);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
111
131
|
let addValues = values;
|
|
112
132
|
|
|
113
133
|
if (Repository?.isLoading) {
|
|
@@ -201,6 +221,10 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
201
221
|
setIsEditorShown(true);
|
|
202
222
|
},
|
|
203
223
|
doEdit = async () => {
|
|
224
|
+
if (canUser && !canUser(EDIT)) {
|
|
225
|
+
showPermissionsError(EDIT);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
204
228
|
if (_.isEmpty(selection) || (_.isArray(selection) && (selection.length > 1 || selection[0]?.isDestroyed))) {
|
|
205
229
|
return;
|
|
206
230
|
}
|
|
@@ -215,6 +239,10 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
215
239
|
setIsEditorShown(true);
|
|
216
240
|
},
|
|
217
241
|
doDelete = async (args) => {
|
|
242
|
+
if (canUser && !canUser(DELETE)) {
|
|
243
|
+
showPermissionsError(DELETE);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
218
246
|
let cb = null;
|
|
219
247
|
if (_.isFunction(args)) {
|
|
220
248
|
cb = args;
|
|
@@ -267,6 +295,10 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
267
295
|
deleteRecord(false, cb);
|
|
268
296
|
},
|
|
269
297
|
deleteRecord = async (moveSubtreeUp, cb) => {
|
|
298
|
+
if (canUser && !canUser(DELETE)) {
|
|
299
|
+
showPermissionsError(DELETE);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
270
302
|
if (getListeners().onBeforeDelete) {
|
|
271
303
|
const listenerResult = await getListeners().onBeforeDelete(selection);
|
|
272
304
|
if (listenerResult === false) {
|
|
@@ -296,6 +328,17 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
296
328
|
if (!userCanView) {
|
|
297
329
|
return;
|
|
298
330
|
}
|
|
331
|
+
if (canUser && !canUser(VIEW)) {
|
|
332
|
+
showPermissionsError(VIEW);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
if (editorType === EDITOR_TYPE__INLINE) {
|
|
336
|
+
alert('Cannot view in inline editor.');
|
|
337
|
+
return; // inline editor doesn't have a view mode
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// check permissions for view
|
|
341
|
+
|
|
299
342
|
if (selection.length !== 1) {
|
|
300
343
|
return;
|
|
301
344
|
}
|
|
@@ -311,6 +354,14 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
311
354
|
if (!userCanEdit || disableDuplicate) {
|
|
312
355
|
return;
|
|
313
356
|
}
|
|
357
|
+
if (canUser && !canUser(DUPLICATE)) {
|
|
358
|
+
showPermissionsError(DUPLICATE);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// check permissions for duplicate
|
|
363
|
+
|
|
364
|
+
|
|
314
365
|
if (selection.length !== 1) {
|
|
315
366
|
return;
|
|
316
367
|
}
|
|
@@ -339,6 +390,12 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
339
390
|
doEdit();
|
|
340
391
|
},
|
|
341
392
|
doEditorSave = async (data, e) => {
|
|
393
|
+
let mode = editorMode === EDITOR_MODE__ADD ? ADD : EDIT;
|
|
394
|
+
if (canUser && !canUser(mode)) {
|
|
395
|
+
showPermissionsError(mode);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
|
|
342
399
|
// NOTE: The Form submits onSave for both adds (when not isAutoSsave) and edits.
|
|
343
400
|
const isSingle = selection.length === 1;
|
|
344
401
|
let useStaged = false;
|
|
@@ -395,7 +452,11 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
395
452
|
await getListeners().onAfterAddSave(selection);
|
|
396
453
|
}
|
|
397
454
|
setIsAdding(false);
|
|
398
|
-
|
|
455
|
+
if (!canUser || canUser(EDIT)) {
|
|
456
|
+
setEditorMode(EDITOR_MODE__EDIT);
|
|
457
|
+
} else {
|
|
458
|
+
setEditorMode(EDITOR_MODE__VIEW);
|
|
459
|
+
}
|
|
399
460
|
} else if (editorMode === EDITOR_MODE__EDIT) {
|
|
400
461
|
if (getListeners().onAfterEdit) {
|
|
401
462
|
await getListeners().onAfterEdit(selection);
|
|
@@ -440,6 +501,11 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
440
501
|
setIsEditorShown(false);
|
|
441
502
|
},
|
|
442
503
|
doEditorDelete = async () => {
|
|
504
|
+
if (canUser && !canUser(DELETE)) {
|
|
505
|
+
showPermissionsError(DELETE);
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
|
|
443
509
|
doDelete(() => {
|
|
444
510
|
setEditorMode(EDITOR_MODE__VIEW);
|
|
445
511
|
setIsEditorShown(false);
|
|
@@ -484,9 +550,19 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
484
550
|
return mode;
|
|
485
551
|
},
|
|
486
552
|
setEditMode = () => {
|
|
553
|
+
if (canUser && !canUser(EDIT)) {
|
|
554
|
+
showPermissionsError(EDIT);
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
|
|
487
558
|
setEditorMode(EDITOR_MODE__EDIT);
|
|
488
559
|
},
|
|
489
560
|
setViewMode = () => {
|
|
561
|
+
if (canUser && !canUser(VIEW)) {
|
|
562
|
+
showPermissionsError(VIEW);
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
|
|
490
566
|
function doIt() {
|
|
491
567
|
setEditorMode(EDITOR_MODE__VIEW);
|
|
492
568
|
}
|
|
@@ -4,6 +4,9 @@ import {
|
|
|
4
4
|
Row,
|
|
5
5
|
Text,
|
|
6
6
|
} from 'native-base';
|
|
7
|
+
import {
|
|
8
|
+
VIEW,
|
|
9
|
+
} from '../../Constants/Commands.js';
|
|
7
10
|
import * as yup from 'yup'; // https://github.com/jquense/yup#string
|
|
8
11
|
import Inflector from 'inflector-js';
|
|
9
12
|
import qs from 'qs';
|
|
@@ -19,15 +22,21 @@ import _ from 'lodash';
|
|
|
19
22
|
export default function withPdfButtons(WrappedComponent) {
|
|
20
23
|
return withModal((props) => {
|
|
21
24
|
|
|
25
|
+
let showButtons = true;
|
|
22
26
|
if (!props.showPdfBtns) {
|
|
27
|
+
showButtons = false;
|
|
28
|
+
}
|
|
29
|
+
if (props.canUser && !props.canUser(VIEW)) { // permissions
|
|
30
|
+
showButtons = false;
|
|
31
|
+
}
|
|
32
|
+
if (!showButtons) {
|
|
23
33
|
// bypass everything.
|
|
24
34
|
// If we don't do this, we get an infinite recursion with Form
|
|
25
35
|
// because this HOC wraps Form and uses Form itself.
|
|
26
36
|
return <WrappedComponent {...props} />;
|
|
27
37
|
}
|
|
28
38
|
|
|
29
|
-
const
|
|
30
|
-
{
|
|
39
|
+
const {
|
|
31
40
|
additionalEditButtons = [],
|
|
32
41
|
additionalViewButtons = [],
|
|
33
42
|
items = [],
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import Inflector from 'inflector-js';
|
|
2
|
+
import inArray from '../../Functions/inArray.js';
|
|
3
|
+
import {
|
|
4
|
+
ADD,
|
|
5
|
+
EDIT,
|
|
6
|
+
DELETE,
|
|
7
|
+
VIEW,
|
|
8
|
+
COPY,
|
|
9
|
+
DUPLICATE,
|
|
10
|
+
PRINT,
|
|
11
|
+
UPLOAD_DOWNLOAD,
|
|
12
|
+
} from '../../Constants/Commands.js';
|
|
13
|
+
import UiGlobals from '../../UiGlobals.js';
|
|
14
|
+
import _ from 'lodash';
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
export default function withPermissions(WrappedComponent, forceUsePermissions = false) {
|
|
18
|
+
return (props) => {
|
|
19
|
+
|
|
20
|
+
if (!props.usePermissions && !forceUsePermissions) {
|
|
21
|
+
return <WrappedComponent {...props} />;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
// withAlert
|
|
26
|
+
alert,
|
|
27
|
+
|
|
28
|
+
// withData
|
|
29
|
+
Repository,
|
|
30
|
+
} = props,
|
|
31
|
+
model = Repository?.schema?.name,
|
|
32
|
+
checkPermission = (permission) => {
|
|
33
|
+
const
|
|
34
|
+
reduxState = UiGlobals.redux?.getState(),
|
|
35
|
+
permissions = reduxState?.app?.permissions;
|
|
36
|
+
if (!permissions) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return inArray(permission, permissions);
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
showPermissionsError = (permission, modelForAlert = null) => {
|
|
43
|
+
if (!modelForAlert) {
|
|
44
|
+
modelForAlert = model; // use default model if none supplied
|
|
45
|
+
}
|
|
46
|
+
modelForAlert = Inflector.humanize(Inflector.underscore(modelForAlert)); // 'PmEvents' -> 'pm events'
|
|
47
|
+
|
|
48
|
+
alert(`You are not authorized to ${permission} ${modelForAlert}.`);
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Check if user has permission to perform an action
|
|
53
|
+
*
|
|
54
|
+
* Example usages:
|
|
55
|
+
* canUser('view') // check if user can perform 'view' action on the default model
|
|
56
|
+
* canUser('add', 'PmEvents') // check if user can perform 'add' action on a specific model
|
|
57
|
+
* canUser('do_something_else) // check if user has a custom permission
|
|
58
|
+
*
|
|
59
|
+
* @param {string} permission - The permission to check for.
|
|
60
|
+
* @param {string} modelToCheck - The model to check for the permission on.
|
|
61
|
+
* @returns {boolean} - Whether user has permission
|
|
62
|
+
*/
|
|
63
|
+
canUser = (permission, modelToCheck = null) => {
|
|
64
|
+
|
|
65
|
+
// deal with special cases that refer to other permissions
|
|
66
|
+
switch(permission) {
|
|
67
|
+
case PRINT:
|
|
68
|
+
permission = VIEW;
|
|
69
|
+
break;
|
|
70
|
+
case COPY:
|
|
71
|
+
case DUPLICATE: {
|
|
72
|
+
// user must have ADD _and_ EDIT permissions, so check both
|
|
73
|
+
const
|
|
74
|
+
hasAddPermission = canUser(ADD, modelToCheck),
|
|
75
|
+
hasEditPermission = canUser(EDIT, modelToCheck);
|
|
76
|
+
return hasAddPermission && hasEditPermission;
|
|
77
|
+
}
|
|
78
|
+
case UPLOAD_DOWNLOAD: {
|
|
79
|
+
// user must have VIEW, ADD, EDIT, and DELETE permissions, so check all of them
|
|
80
|
+
const
|
|
81
|
+
hasViewPermission = canUser(VIEW, modelToCheck),
|
|
82
|
+
hasAddPermission = canUser(ADD, modelToCheck),
|
|
83
|
+
hasEditPermission = canUser(EDIT, modelToCheck),
|
|
84
|
+
hasDeletePermission = canUser(DELETE, modelToCheck);
|
|
85
|
+
return hasViewPermission && hasAddPermission && hasEditPermission && hasDeletePermission;
|
|
86
|
+
}
|
|
87
|
+
default:
|
|
88
|
+
// do nothing
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// standard CRUD permissions
|
|
93
|
+
if (inArray(permission, [VIEW, ADD, EDIT, DELETE])) {
|
|
94
|
+
if (!modelToCheck) {
|
|
95
|
+
modelToCheck = model; // use default model if none supplied
|
|
96
|
+
}
|
|
97
|
+
modelToCheck = Inflector.underscore(modelToCheck); // 'PmEvents' -> 'pm_events'
|
|
98
|
+
permission += '_' + modelToCheck; // e.g. 'view_pm_events'
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return checkPermission(permission);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
return <WrappedComponent
|
|
105
|
+
{...props}
|
|
106
|
+
canUser={canUser}
|
|
107
|
+
showPermissionsError={showPermissionsError}
|
|
108
|
+
/>;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -2,6 +2,16 @@ import React, { useState, useEffect, } from 'react';
|
|
|
2
2
|
import {
|
|
3
3
|
Modal,
|
|
4
4
|
} from 'native-base';
|
|
5
|
+
import {
|
|
6
|
+
ADD,
|
|
7
|
+
EDIT,
|
|
8
|
+
DELETE,
|
|
9
|
+
VIEW,
|
|
10
|
+
COPY,
|
|
11
|
+
DUPLICATE,
|
|
12
|
+
PRINT,
|
|
13
|
+
UPLOAD_DOWNLOAD,
|
|
14
|
+
} from '../../constants/Commands.js';
|
|
5
15
|
import Clipboard from '../Icons/Clipboard.js';
|
|
6
16
|
import Duplicate from '../Icons/Duplicate.js';
|
|
7
17
|
import Edit from '../Icons/Edit.js';
|
|
@@ -18,14 +28,14 @@ import _ from 'lodash';
|
|
|
18
28
|
// and a toolbar button that match in text label, icon, and handler.
|
|
19
29
|
|
|
20
30
|
const presetButtons = [
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
//
|
|
28
|
-
|
|
31
|
+
ADD,
|
|
32
|
+
EDIT,
|
|
33
|
+
DELETE,
|
|
34
|
+
VIEW,
|
|
35
|
+
COPY,
|
|
36
|
+
DUPLICATE,
|
|
37
|
+
// PRINT,
|
|
38
|
+
UPLOAD_DOWNLOAD,
|
|
29
39
|
];
|
|
30
40
|
|
|
31
41
|
export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
@@ -42,9 +52,9 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
42
52
|
additionalToolbarButtons = [],
|
|
43
53
|
useUploadDownload = false,
|
|
44
54
|
onChangeColumnsConfig,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
canRecordBeEdited,
|
|
56
|
+
canRecordBeDeleted,
|
|
57
|
+
canRecordBeDuplicated,
|
|
48
58
|
...propsToPass
|
|
49
59
|
} = props,
|
|
50
60
|
{
|
|
@@ -71,8 +81,11 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
71
81
|
// withData
|
|
72
82
|
Repository,
|
|
73
83
|
|
|
84
|
+
// withPermissions
|
|
85
|
+
canUser,
|
|
86
|
+
|
|
74
87
|
// withEditor
|
|
75
|
-
userCanEdit = true,
|
|
88
|
+
userCanEdit = true, // not permissions, but capability
|
|
76
89
|
userCanView = true,
|
|
77
90
|
onAdd,
|
|
78
91
|
onEdit,
|
|
@@ -101,44 +114,60 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
101
114
|
isTypeDisabledCompletely = (type) => {
|
|
102
115
|
let isDisabled = false;
|
|
103
116
|
switch(type) {
|
|
104
|
-
case
|
|
117
|
+
case ADD:
|
|
105
118
|
if (disableAdd || canEditorViewOnly) {
|
|
106
119
|
isDisabled = true;
|
|
120
|
+
} else if (canUser && !canUser(ADD)) { // check Permissions
|
|
121
|
+
isDisabled = true;
|
|
107
122
|
}
|
|
108
123
|
break;
|
|
109
|
-
case
|
|
124
|
+
case EDIT:
|
|
110
125
|
if (disableEdit || canEditorViewOnly || isSideEditor) {
|
|
111
126
|
isDisabled = true;
|
|
127
|
+
} else if (canUser && !canUser(EDIT)) { // check Permissions
|
|
128
|
+
isDisabled = true;
|
|
112
129
|
}
|
|
113
130
|
break;
|
|
114
|
-
case
|
|
131
|
+
case DELETE:
|
|
115
132
|
if (disableDelete || canEditorViewOnly) {
|
|
116
133
|
isDisabled = true;
|
|
134
|
+
} else if (canUser && !canUser(DELETE)) { // check Permissions
|
|
135
|
+
isDisabled = true;
|
|
117
136
|
}
|
|
118
137
|
break;
|
|
119
|
-
case
|
|
138
|
+
case VIEW:
|
|
120
139
|
if (disableView || isSideEditor) {
|
|
121
140
|
isDisabled = true;
|
|
141
|
+
} else if (canUser && !canUser(VIEW)) { // check Permissions
|
|
142
|
+
isDisabled = true;
|
|
122
143
|
}
|
|
123
144
|
break;
|
|
124
|
-
case
|
|
145
|
+
case COPY:
|
|
125
146
|
if (disableCopy) {
|
|
126
147
|
isDisabled = true;
|
|
148
|
+
} else if (canUser && !canUser(COPY)) { // check Permissions
|
|
149
|
+
isDisabled = true;
|
|
127
150
|
}
|
|
128
151
|
break;
|
|
129
|
-
case
|
|
152
|
+
case DUPLICATE:
|
|
130
153
|
if (disableDuplicate || canEditorViewOnly) {
|
|
131
154
|
isDisabled = true;
|
|
155
|
+
} else if (canUser && !canUser(DUPLICATE)) { // check Permissions
|
|
156
|
+
isDisabled = true;
|
|
132
157
|
}
|
|
133
158
|
break;
|
|
134
|
-
case
|
|
159
|
+
case PRINT:
|
|
135
160
|
if (disablePrint) {
|
|
136
161
|
isDisabled = true;
|
|
162
|
+
} else if (canUser && !canUser(PRINT)) { // check Permissions
|
|
163
|
+
isDisabled = true;
|
|
137
164
|
}
|
|
138
165
|
break;
|
|
139
|
-
case
|
|
166
|
+
case UPLOAD_DOWNLOAD:
|
|
140
167
|
if (!useUploadDownload) {
|
|
141
168
|
isDisabled = true;
|
|
169
|
+
} else if (canUser && !canUser(UPLOAD_DOWNLOAD)) { // check Permissions
|
|
170
|
+
isDisabled = true;
|
|
142
171
|
}
|
|
143
172
|
break;
|
|
144
173
|
default:
|
|
@@ -152,7 +181,7 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
152
181
|
icon = null,
|
|
153
182
|
isDisabled = false;
|
|
154
183
|
switch(type) {
|
|
155
|
-
case
|
|
184
|
+
case ADD:
|
|
156
185
|
key = 'addBtn';
|
|
157
186
|
text = 'Add';
|
|
158
187
|
handler = onAdd;
|
|
@@ -164,7 +193,7 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
164
193
|
isDisabled = true;
|
|
165
194
|
}
|
|
166
195
|
break;
|
|
167
|
-
case
|
|
196
|
+
case EDIT:
|
|
168
197
|
key = 'editBtn';
|
|
169
198
|
text = 'Edit';
|
|
170
199
|
handler = onEdit;
|
|
@@ -175,11 +204,11 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
175
204
|
if (_.isEmpty(selection) || (_.isArray(selection) && selection.length > 1)) {
|
|
176
205
|
isDisabled = true;
|
|
177
206
|
}
|
|
178
|
-
if (
|
|
207
|
+
if (canRecordBeEdited && !canRecordBeEdited(selection)) {
|
|
179
208
|
isDisabled = true;
|
|
180
209
|
}
|
|
181
210
|
break;
|
|
182
|
-
case
|
|
211
|
+
case DELETE:
|
|
183
212
|
key = 'deleteBtn';
|
|
184
213
|
text = 'Delete';
|
|
185
214
|
handler = onDelete;
|
|
@@ -190,7 +219,7 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
190
219
|
if (_.isEmpty(selection) || (_.isArray(selection) && selection.length > 1)) {
|
|
191
220
|
isDisabled = true;
|
|
192
221
|
}
|
|
193
|
-
if (
|
|
222
|
+
if (canRecordBeDeleted && !canRecordBeDeleted(selection)) {
|
|
194
223
|
isDisabled = true;
|
|
195
224
|
}
|
|
196
225
|
if (isTree) {
|
|
@@ -200,7 +229,7 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
200
229
|
}
|
|
201
230
|
}
|
|
202
231
|
break;
|
|
203
|
-
case
|
|
232
|
+
case VIEW:
|
|
204
233
|
key = 'viewBtn';
|
|
205
234
|
text = 'View';
|
|
206
235
|
handler = onView;
|
|
@@ -213,7 +242,7 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
213
242
|
isDisabled = true;
|
|
214
243
|
}
|
|
215
244
|
break;
|
|
216
|
-
case
|
|
245
|
+
case COPY:
|
|
217
246
|
key = 'copyBtn';
|
|
218
247
|
text = 'Copy to Clipboard';
|
|
219
248
|
handler = onCopyToClipboard;
|
|
@@ -226,7 +255,7 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
226
255
|
isDisabled = true;
|
|
227
256
|
}
|
|
228
257
|
break;
|
|
229
|
-
case
|
|
258
|
+
case DUPLICATE:
|
|
230
259
|
key = 'duplicateBtn';
|
|
231
260
|
text = 'Duplicate';
|
|
232
261
|
handler = onDuplicate;
|
|
@@ -238,16 +267,16 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
238
267
|
if (_.isEmpty(selection) || selection.length > 1) {
|
|
239
268
|
isDisabled = true;
|
|
240
269
|
}
|
|
241
|
-
if (
|
|
270
|
+
if (canRecordBeDuplicated && !canRecordBeDuplicated(selection)) {
|
|
242
271
|
isDisabled = true;
|
|
243
272
|
}
|
|
244
273
|
break;
|
|
245
|
-
// case
|
|
274
|
+
// case PRINT:
|
|
246
275
|
// text = 'Print';
|
|
247
276
|
// handler = onPrint;
|
|
248
277
|
// icon = <Print />;
|
|
249
278
|
// break;
|
|
250
|
-
case
|
|
279
|
+
case UPLOAD_DOWNLOAD:
|
|
251
280
|
key = 'uploadDownloadBtn';
|
|
252
281
|
text = 'Upload/Download';
|
|
253
282
|
handler = onUploadDownload;
|
|
@@ -274,8 +303,8 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
274
303
|
if (isTypeDisabledCompletely(type)) { // i.e. not just temporarily disabled because of selection
|
|
275
304
|
return;
|
|
276
305
|
}
|
|
277
|
-
if ((!userCanEdit && inArray(type, [
|
|
278
|
-
(!userCanView && type ===
|
|
306
|
+
if ((!userCanEdit && inArray(type, [ADD, EDIT, DELETE, DUPLICATE,])) ||
|
|
307
|
+
(!userCanView && type === VIEW)) {
|
|
279
308
|
return;
|
|
280
309
|
}
|
|
281
310
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Column,
|
|
3
|
+
Text,
|
|
4
|
+
} from 'native-base';
|
|
5
|
+
|
|
6
|
+
export default function Unauthorized(props) {
|
|
7
|
+
const
|
|
8
|
+
{
|
|
9
|
+
text = 'Unauthorized.',
|
|
10
|
+
} = props;
|
|
11
|
+
return <Column justifyContent="center" alignItems="center" w="100%" flex={1}>
|
|
12
|
+
<Text
|
|
13
|
+
textAlign="center"
|
|
14
|
+
color="#f00"
|
|
15
|
+
>{text}</Text>
|
|
16
|
+
</Column>;
|
|
17
|
+
}
|