@onehat/ui 0.2.73 → 0.2.75
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/Buttons/IconButton.js +7 -2
- package/src/Components/Grid/Grid.js +18 -53
- package/src/Components/Hoc/withAlert.js +42 -39
- package/src/Components/Hoc/withEditor.js +116 -16
- package/src/Components/Hoc/withPresetButtons.js +4 -0
- package/src/Components/Hoc/withSideEditor.js +2 -2
- package/src/Components/Hoc/withWindowedEditor.js +2 -2
- package/src/Components/Tree/Tree.js +394 -354
- package/src/Constants/Styles.js +3 -6
- package/src/Functions/getIconButtonFromConfig.js +37 -0
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
Tooltip,
|
|
7
7
|
} from 'native-base';
|
|
8
8
|
import styles from '../../Constants/Styles.js';
|
|
9
|
+
import _ from 'lodash';
|
|
9
10
|
|
|
10
11
|
const IconButton = React.forwardRef((props, ref) => {
|
|
11
12
|
const {
|
|
@@ -17,12 +18,16 @@ const IconButton = React.forwardRef((props, ref) => {
|
|
|
17
18
|
tooltipPlacement = 'bottom',
|
|
18
19
|
} = props;
|
|
19
20
|
const propsIcon = props._icon || {};
|
|
20
|
-
let icon = props.icon
|
|
21
|
+
let icon = props.icon,
|
|
21
22
|
ret;
|
|
22
23
|
if (isLoading) {
|
|
23
24
|
icon = <Spinner {..._spinner} />;
|
|
24
25
|
}
|
|
25
|
-
if (
|
|
26
|
+
if (React.isValidElement(icon)) {
|
|
27
|
+
if (!_.isEmpty(propsIcon)) {
|
|
28
|
+
icon = React.cloneElement(icon, {...propsIcon});
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
26
31
|
icon = <Icon as={icon} {...propsIcon} />;
|
|
27
32
|
}
|
|
28
33
|
const pressable = <Pressable
|
|
@@ -35,6 +35,7 @@ import withMultiSelection from '../Hoc/withMultiSelection.js';
|
|
|
35
35
|
import withSelection from '../Hoc/withSelection.js';
|
|
36
36
|
import withWindowedEditor from '../Hoc/withWindowedEditor.js';
|
|
37
37
|
import withInlineEditor from '../Hoc/withInlineEditor.js';
|
|
38
|
+
import getIconButtonFromConfig from '../../Functions/getIconButtonFromConfig.js';
|
|
38
39
|
import testProps from '../../Functions/testProps.js';
|
|
39
40
|
import nbToRgb from '../../Functions/nbToRgb.js';
|
|
40
41
|
import GridHeaderRow from './GridHeaderRow.js';
|
|
@@ -52,7 +53,7 @@ import _ from 'lodash';
|
|
|
52
53
|
// The default export is *with* the HOC. A separate *raw* component is
|
|
53
54
|
// exported which can be combined with many HOCs for various functionality.
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
function GridComponent(props) {
|
|
56
57
|
const {
|
|
57
58
|
|
|
58
59
|
columnsConfig = [], // json configurations for each column
|
|
@@ -217,42 +218,8 @@ export function GridComponent(props) {
|
|
|
217
218
|
}
|
|
218
219
|
},
|
|
219
220
|
getFooterToolbarItems = () => {
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
_hover: {
|
|
223
|
-
bg: 'trueGray.400',
|
|
224
|
-
},
|
|
225
|
-
mx: 1,
|
|
226
|
-
px: 3,
|
|
227
|
-
},
|
|
228
|
-
iconProps = {
|
|
229
|
-
alignSelf: 'center',
|
|
230
|
-
size: styles.GRID_TOOLBAR_ITEMS_ICON_SIZE,
|
|
231
|
-
h: 20,
|
|
232
|
-
w: 20,
|
|
233
|
-
},
|
|
234
|
-
items = _.map(additionalToolbarButtons, (config, ix) => {
|
|
235
|
-
let {
|
|
236
|
-
text,
|
|
237
|
-
handler,
|
|
238
|
-
icon = null,
|
|
239
|
-
isDisabled = false,
|
|
240
|
-
} = config;
|
|
241
|
-
if (icon) {
|
|
242
|
-
const thisIconProps = {
|
|
243
|
-
color: isDisabled ? styles.GRID_TOOLBAR_ITEMS_DISABLED_COLOR : styles.GRID_TOOLBAR_ITEMS_COLOR,
|
|
244
|
-
};
|
|
245
|
-
icon = React.cloneElement(icon, {...iconProps, ...thisIconProps});
|
|
246
|
-
}
|
|
247
|
-
return <IconButton
|
|
248
|
-
key={ix}
|
|
249
|
-
{...iconButtonProps}
|
|
250
|
-
onPress={handler}
|
|
251
|
-
icon={icon}
|
|
252
|
-
isDisabled={isDisabled}
|
|
253
|
-
tooltip={text}
|
|
254
|
-
/>;
|
|
255
|
-
});
|
|
221
|
+
const items = _.map(additionalToolbarButtons, getIconButtonFromConfig);
|
|
222
|
+
|
|
256
223
|
if (canRowsReorder) {
|
|
257
224
|
items.unshift(<IconButton
|
|
258
225
|
key="reorderBtn"
|
|
@@ -851,21 +818,19 @@ export function GridComponent(props) {
|
|
|
851
818
|
|
|
852
819
|
}
|
|
853
820
|
|
|
854
|
-
const Grid = withAlert(
|
|
821
|
+
export const Grid = withAlert(
|
|
855
822
|
withEvents(
|
|
856
823
|
withData(
|
|
857
824
|
withMultiSelection(
|
|
858
825
|
withSelection(
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
true // isGrid
|
|
866
|
-
)
|
|
826
|
+
withFilters(
|
|
827
|
+
withPresetButtons(
|
|
828
|
+
withContextMenu(
|
|
829
|
+
GridComponent
|
|
830
|
+
),
|
|
831
|
+
true // isGrid
|
|
867
832
|
)
|
|
868
|
-
|
|
833
|
+
)
|
|
869
834
|
)
|
|
870
835
|
)
|
|
871
836
|
)
|
|
@@ -920,13 +885,13 @@ export const InlineGridEditor = withAlert(
|
|
|
920
885
|
withMultiSelection(
|
|
921
886
|
withSelection(
|
|
922
887
|
withInlineEditor(
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
888
|
+
withFilters(
|
|
889
|
+
withPresetButtons(
|
|
890
|
+
withContextMenu(
|
|
926
891
|
GridComponent
|
|
927
|
-
)
|
|
928
|
-
|
|
929
|
-
|
|
892
|
+
)
|
|
893
|
+
),
|
|
894
|
+
true // isGrid
|
|
930
895
|
)
|
|
931
896
|
)
|
|
932
897
|
)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useState, useRef, useEffect, } from 'react';
|
|
2
2
|
import {
|
|
3
|
+
AlertDialog,
|
|
3
4
|
Button,
|
|
4
5
|
Column,
|
|
5
6
|
Icon,
|
|
@@ -30,26 +31,29 @@ export default function withAlert(WrappedComponent) {
|
|
|
30
31
|
[customButtons, setCustomButtons] = useState(),
|
|
31
32
|
[mode, setMode] = useState(ALERT_MODE_OK),
|
|
32
33
|
autoFocusRef = useRef(null),
|
|
33
|
-
|
|
34
|
+
cancelRef = useRef(null),
|
|
35
|
+
onAlert = (arg1, okCallback, includeCancel = false) => {
|
|
34
36
|
clearAll();
|
|
35
37
|
if (_.isString(arg1)) {
|
|
36
38
|
setMode(ALERT_MODE_OK);
|
|
37
39
|
setTitle('Alert');
|
|
38
40
|
setMessage(arg1);
|
|
39
|
-
setOkCallback(() =>
|
|
41
|
+
setOkCallback(() => okCallback);
|
|
42
|
+
setIncludeCancel(includeCancel);
|
|
40
43
|
} else if (_.isPlainObject(arg1)) {
|
|
41
44
|
// custom
|
|
42
45
|
const {
|
|
43
46
|
title = 'Alert',
|
|
44
47
|
message,
|
|
45
48
|
buttons,
|
|
49
|
+
includeCancel,
|
|
46
50
|
} = arg1;
|
|
47
51
|
setMode(ALERT_MODE_CUSTOM);
|
|
48
52
|
setTitle(title);
|
|
49
53
|
setMessage(message);
|
|
50
54
|
setCustomButtons(buttons);
|
|
55
|
+
setIncludeCancel(includeCancel);
|
|
51
56
|
}
|
|
52
|
-
setIncludeCancel(includeCancel);
|
|
53
57
|
showAlert();
|
|
54
58
|
},
|
|
55
59
|
onConfirm = (message, callback, includeCancel = false) => {
|
|
@@ -65,31 +69,29 @@ export default function withAlert(WrappedComponent) {
|
|
|
65
69
|
setIsAlertShown(false);
|
|
66
70
|
},
|
|
67
71
|
onOk = () => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (callback) {
|
|
71
|
-
callback();
|
|
72
|
+
if (okCallback) {
|
|
73
|
+
okCallback();
|
|
72
74
|
}
|
|
75
|
+
hideAlert();
|
|
73
76
|
},
|
|
74
77
|
onYes = () => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (callback) {
|
|
78
|
-
callback();
|
|
78
|
+
if (yesCallback) {
|
|
79
|
+
yesCallback();
|
|
79
80
|
}
|
|
81
|
+
hideAlert();
|
|
80
82
|
},
|
|
81
83
|
onNo = () => {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (callback) {
|
|
85
|
-
callback();
|
|
84
|
+
if (noCallback) {
|
|
85
|
+
noCallback();
|
|
86
86
|
}
|
|
87
|
+
hideAlert();
|
|
87
88
|
},
|
|
88
89
|
showAlert = () => {
|
|
89
90
|
setIsAlertShown(true);
|
|
90
91
|
},
|
|
91
92
|
hideAlert = () => {
|
|
92
93
|
setIsAlertShown(false);
|
|
94
|
+
clearAll();
|
|
93
95
|
},
|
|
94
96
|
clearAll = () => {
|
|
95
97
|
setOkCallback();
|
|
@@ -104,7 +106,9 @@ export default function withAlert(WrappedComponent) {
|
|
|
104
106
|
key="cancelBtn"
|
|
105
107
|
onPress={onCancel}
|
|
106
108
|
color="#fff"
|
|
107
|
-
|
|
109
|
+
colorScheme="coolGray"
|
|
110
|
+
variant="ghost" // or unstyled
|
|
111
|
+
ref={cancelRef}
|
|
108
112
|
>Cancel</Button>);
|
|
109
113
|
}
|
|
110
114
|
switch(mode) {
|
|
@@ -128,10 +132,13 @@ export default function withAlert(WrappedComponent) {
|
|
|
128
132
|
ref={autoFocusRef}
|
|
129
133
|
onPress={onYes}
|
|
130
134
|
color="#fff"
|
|
135
|
+
colorScheme="danger"
|
|
131
136
|
>Yes</Button>);
|
|
132
137
|
break;
|
|
133
138
|
case ALERT_MODE_CUSTOM:
|
|
134
|
-
|
|
139
|
+
_.each(customButtons, (button) => {
|
|
140
|
+
buttons.push(button);
|
|
141
|
+
});
|
|
135
142
|
break;
|
|
136
143
|
default:
|
|
137
144
|
}
|
|
@@ -141,36 +148,32 @@ export default function withAlert(WrappedComponent) {
|
|
|
141
148
|
{...props}
|
|
142
149
|
alert={onAlert}
|
|
143
150
|
confirm={onConfirm}
|
|
151
|
+
hideAlert={hideAlert}
|
|
144
152
|
/>
|
|
145
|
-
|
|
153
|
+
|
|
154
|
+
<AlertDialog
|
|
155
|
+
leastDestructiveRef={cancelRef}
|
|
146
156
|
isOpen={isAlertShown}
|
|
147
|
-
onOpen={() => {debugger;}}
|
|
148
157
|
onClose={() => setIsAlertShown(false)}
|
|
149
158
|
>
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
<Panel
|
|
156
|
-
title={title}
|
|
157
|
-
isCollapsible={false}
|
|
158
|
-
p={0}
|
|
159
|
-
footer={<Footer justifyContent="flex-end" >
|
|
160
|
-
<Button.Group space={2}>
|
|
161
|
-
{buttons}
|
|
162
|
-
</Button.Group>
|
|
163
|
-
</Footer>}
|
|
164
|
-
>
|
|
165
|
-
<Row flex={1} p={5}>
|
|
159
|
+
<AlertDialog.Content>
|
|
160
|
+
<AlertDialog.CloseButton />
|
|
161
|
+
<AlertDialog.Header>{title}</AlertDialog.Header>
|
|
162
|
+
<AlertDialog.Body>
|
|
163
|
+
<Row>
|
|
166
164
|
<Column w="40px" p={0} mr={5}>
|
|
167
165
|
<Icon as={TriangleExclamation} size={10} color="#f00" />
|
|
168
166
|
</Column>
|
|
169
|
-
<Text>{message}</Text>
|
|
167
|
+
<Text flex={1}>{message}</Text>
|
|
170
168
|
</Row>
|
|
171
|
-
</
|
|
172
|
-
|
|
173
|
-
|
|
169
|
+
</AlertDialog.Body>
|
|
170
|
+
<AlertDialog.Footer>
|
|
171
|
+
<Button.Group space={2}>
|
|
172
|
+
{buttons}
|
|
173
|
+
</Button.Group>
|
|
174
|
+
</AlertDialog.Footer>
|
|
175
|
+
</AlertDialog.Content>
|
|
176
|
+
</AlertDialog>
|
|
174
177
|
</>;
|
|
175
178
|
};
|
|
176
179
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { useEffect, useState, } from 'react';
|
|
1
|
+
import { useEffect, useState, useRef, } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
} from 'native-base';
|
|
2
5
|
import {
|
|
3
6
|
EDITOR_MODE__VIEW,
|
|
4
7
|
EDITOR_MODE__ADD,
|
|
@@ -6,7 +9,7 @@ import {
|
|
|
6
9
|
} from '../../Constants/Editor.js';
|
|
7
10
|
import _ from 'lodash';
|
|
8
11
|
|
|
9
|
-
export default function withEditor(WrappedComponent) {
|
|
12
|
+
export default function withEditor(WrappedComponent, isTree = false) {
|
|
10
13
|
return (props) => {
|
|
11
14
|
|
|
12
15
|
let [editorMode, setEditorMode] = useState(EDITOR_MODE__VIEW); // Can change below, so use 'let'
|
|
@@ -39,12 +42,23 @@ export default function withEditor(WrappedComponent) {
|
|
|
39
42
|
setSelection,
|
|
40
43
|
|
|
41
44
|
// withAlert
|
|
45
|
+
alert,
|
|
42
46
|
confirm,
|
|
47
|
+
hideAlert,
|
|
43
48
|
} = props,
|
|
49
|
+
listeners = useRef({}),
|
|
44
50
|
[currentRecord, setCurrentRecord] = useState(null),
|
|
45
51
|
[isEditorShown, setIsEditorShown] = useState(false),
|
|
46
52
|
[isEditorViewOnly, setIsEditorViewOnly] = useState(false),
|
|
53
|
+
[isModalShown, setIsModalShown] = useState(false),
|
|
47
54
|
[lastSelection, setLastSelection] = useState(),
|
|
55
|
+
getListeners = () => {
|
|
56
|
+
return listeners.current;
|
|
57
|
+
},
|
|
58
|
+
setListeners = (obj) => {
|
|
59
|
+
listeners.current = obj;
|
|
60
|
+
// forceUpdate(); // we don't want to get into an infinite loop of renders. Simply directly assign the listeners in every child render
|
|
61
|
+
},
|
|
48
62
|
onAdd = async () => {
|
|
49
63
|
const defaultValues = Repository.getSchema().model.defaultValues;
|
|
50
64
|
let addValues = _.clone(defaultValues);
|
|
@@ -53,35 +67,84 @@ export default function withEditor(WrappedComponent) {
|
|
|
53
67
|
addValues[selectorId] = selectorSelected.id;
|
|
54
68
|
}
|
|
55
69
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
70
|
+
if (getListeners().onBeforeAdd) {
|
|
71
|
+
const listenerResult = await getListeners().onBeforeAdd();
|
|
72
|
+
if (listenerResult === false) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (isTree) {
|
|
78
|
+
if (!selection[0]) {
|
|
79
|
+
throw Error('Must select a parent node.');
|
|
80
|
+
}
|
|
81
|
+
addValues.parentId = selection[0].id;
|
|
82
|
+
} else {
|
|
83
|
+
// Set repository to sort by id DESC and switch to page 1, so this new entity is guaranteed to show up on the current page, even after saving
|
|
84
|
+
const currentSorter = Repository.sorters[0];
|
|
85
|
+
if (currentSorter.name !== Repository.schema.model.idProperty || currentSorter.direction !== 'DESC') {
|
|
86
|
+
Repository.pauseEvents();
|
|
87
|
+
Repository.sort(Repository.schema.model.idProperty, 'DESC');
|
|
88
|
+
Repository.setPage(1);
|
|
89
|
+
Repository.resumeEvents();
|
|
90
|
+
await Repository.reload();
|
|
91
|
+
}
|
|
64
92
|
}
|
|
65
93
|
|
|
66
94
|
// Unmap the values, so we can input true originalData
|
|
67
95
|
addValues = Repository.unmapData(addValues);
|
|
68
96
|
|
|
69
|
-
const entity = await Repository.add(addValues, false, true
|
|
97
|
+
const entity = await Repository.add(addValues, false, true);
|
|
70
98
|
setSelection([entity]);
|
|
71
99
|
setIsEditorViewOnly(false);
|
|
72
100
|
setEditorMode(EDITOR_MODE__ADD);
|
|
73
101
|
setIsEditorShown(true);
|
|
102
|
+
|
|
103
|
+
if (getListeners().onAfterAdd) {
|
|
104
|
+
await getListeners().onAfterAdd(entity);
|
|
105
|
+
}
|
|
74
106
|
},
|
|
75
|
-
onEdit = () => {
|
|
107
|
+
onEdit = async () => {
|
|
108
|
+
if (getListeners().onBeforeEdit) {
|
|
109
|
+
const listenerResult = await getListeners().onBeforeEdit();
|
|
110
|
+
if (listenerResult === false) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
76
114
|
setIsEditorViewOnly(false);
|
|
77
115
|
setEditorMode(EDITOR_MODE__EDIT);
|
|
78
116
|
setIsEditorShown(true);
|
|
79
117
|
},
|
|
80
|
-
onDelete = () => {
|
|
118
|
+
onDelete = async () => {
|
|
119
|
+
if (getListeners().onBeforeDelete) {
|
|
120
|
+
const listenerResult = await getListeners().onBeforeDelete();
|
|
121
|
+
if (listenerResult === false) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
81
125
|
const
|
|
82
126
|
isSingle = selection.length === 1,
|
|
83
|
-
|
|
127
|
+
firstSelection = selection[0],
|
|
128
|
+
isTree = firstSelection?.isTree,
|
|
129
|
+
hasChildren = firstSelection?.hasChildren,
|
|
130
|
+
isPhantom = firstSelection?.isPhantom;
|
|
84
131
|
|
|
132
|
+
if (isSingle && isTree && hasChildren) {
|
|
133
|
+
alert({
|
|
134
|
+
title: 'Move up children?',
|
|
135
|
+
message: 'The node you have selected for deletion has children. ' +
|
|
136
|
+
'Should these children be moved up to this node\'s parent, or be deleted?',
|
|
137
|
+
buttons: [
|
|
138
|
+
<Button colorScheme="danger" onPress={onMoveChildren} key="moveBtn">
|
|
139
|
+
Move Children
|
|
140
|
+
</Button>,
|
|
141
|
+
<Button colorScheme="danger" onPress={onDeleteChildren} key="deleteBtn">
|
|
142
|
+
Delete Children
|
|
143
|
+
</Button>
|
|
144
|
+
],
|
|
145
|
+
includeCancel: true,
|
|
146
|
+
});
|
|
147
|
+
} else
|
|
85
148
|
if (isSingle && isPhantom) {
|
|
86
149
|
deleteRecord();
|
|
87
150
|
} else {
|
|
@@ -89,13 +152,28 @@ export default function withEditor(WrappedComponent) {
|
|
|
89
152
|
confirm('Are you sure you want to delete the ' + identifier, deleteRecord);
|
|
90
153
|
}
|
|
91
154
|
},
|
|
92
|
-
|
|
155
|
+
onMoveChildren = () => {
|
|
156
|
+
hideAlert();
|
|
157
|
+
deleteRecord(true);
|
|
158
|
+
},
|
|
159
|
+
onDeleteChildren = () => {
|
|
160
|
+
hideAlert();
|
|
161
|
+
deleteRecord();
|
|
162
|
+
},
|
|
163
|
+
deleteRecord = async (moveSubtreeUp) => {
|
|
164
|
+
if (getListeners().onBeforeDeleteSave) {
|
|
165
|
+
await getListeners().onBeforeDeleteSave(selection);
|
|
166
|
+
}
|
|
167
|
+
|
|
93
168
|
await Repository.delete(selection);
|
|
94
169
|
if (!Repository.isAutoSave) {
|
|
95
170
|
await Repository.save();
|
|
96
171
|
}
|
|
172
|
+
if (getListeners().onAfterDelete) {
|
|
173
|
+
await getListeners().onAfterDelete(selection);
|
|
174
|
+
}
|
|
97
175
|
},
|
|
98
|
-
viewRecord = () => {
|
|
176
|
+
viewRecord = async () => {
|
|
99
177
|
if (!userCanView) {
|
|
100
178
|
return;
|
|
101
179
|
}
|
|
@@ -105,6 +183,10 @@ export default function withEditor(WrappedComponent) {
|
|
|
105
183
|
setIsEditorViewOnly(true);
|
|
106
184
|
setEditorMode(EDITOR_MODE__VIEW);
|
|
107
185
|
setIsEditorShown(true);
|
|
186
|
+
|
|
187
|
+
if (getListeners().onAfterDelete) {
|
|
188
|
+
await getListeners().onAfterDelete(entity);
|
|
189
|
+
}
|
|
108
190
|
},
|
|
109
191
|
duplicateRecord = async () => {
|
|
110
192
|
if (!userCanEdit || disableDuplicate) {
|
|
@@ -143,8 +225,17 @@ export default function withEditor(WrappedComponent) {
|
|
|
143
225
|
}
|
|
144
226
|
});
|
|
145
227
|
}
|
|
228
|
+
|
|
229
|
+
if (getListeners().onBeforeEditSave) {
|
|
230
|
+
await getListeners().onBeforeEditSave(what);
|
|
231
|
+
}
|
|
232
|
+
|
|
146
233
|
await Repository.save();
|
|
147
234
|
setIsEditorShown(false);
|
|
235
|
+
|
|
236
|
+
if (getListeners().onAfterEdit) {
|
|
237
|
+
await getListeners().onAfterEdit(what);
|
|
238
|
+
}
|
|
148
239
|
},
|
|
149
240
|
onEditorCancel = async () => {
|
|
150
241
|
const
|
|
@@ -160,9 +251,17 @@ export default function withEditor(WrappedComponent) {
|
|
|
160
251
|
setIsEditorShown(false);
|
|
161
252
|
},
|
|
162
253
|
onEditorDelete = async () => {
|
|
254
|
+
if (getListeners().onBeforeDeleteSave) {
|
|
255
|
+
await getListeners().onBeforeDeleteSave(selection);
|
|
256
|
+
}
|
|
257
|
+
|
|
163
258
|
await deleteRecord();
|
|
164
259
|
setEditorMode(EDITOR_MODE__VIEW);
|
|
165
260
|
setIsEditorShown(false);
|
|
261
|
+
|
|
262
|
+
if (getListeners().onAfterDelete) {
|
|
263
|
+
await getListeners().onAfterDelete(selection);
|
|
264
|
+
}
|
|
166
265
|
},
|
|
167
266
|
calculateEditorMode = () => {
|
|
168
267
|
let mode = EDITOR_MODE__VIEW;
|
|
@@ -213,6 +312,7 @@ export default function withEditor(WrappedComponent) {
|
|
|
213
312
|
onEditorCancel={onEditorCancel}
|
|
214
313
|
onEditorDelete={(!userCanEdit || disableDelete || (editorMode === EDITOR_MODE__ADD && (selection[0]?.isPhantom || currentRecord?.isPhantom))) ? null : onEditorDelete}
|
|
215
314
|
onEditorClose={onEditorClose}
|
|
315
|
+
setWithEditListeners={setListeners}
|
|
216
316
|
isEditor={true}
|
|
217
317
|
useEditor={useEditor}
|
|
218
318
|
userCanEdit={userCanEdit}
|
|
@@ -34,6 +34,7 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
34
34
|
{
|
|
35
35
|
// for local use
|
|
36
36
|
isEditor = false,
|
|
37
|
+
isTree = false,
|
|
37
38
|
useEditor = true,
|
|
38
39
|
disableAdd = !isEditor,
|
|
39
40
|
disableEdit = !isEditor,
|
|
@@ -125,6 +126,9 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
125
126
|
if (selectorId && !selectorSelected) {
|
|
126
127
|
isDisabled = true;
|
|
127
128
|
}
|
|
129
|
+
if (isTree && _.isEmpty(selection)) {
|
|
130
|
+
isDisabled = true;
|
|
131
|
+
}
|
|
128
132
|
break;
|
|
129
133
|
case 'edit':
|
|
130
134
|
text = 'Edit';
|
|
@@ -6,7 +6,7 @@ import withEditor from './withEditor.js';
|
|
|
6
6
|
import _ from 'lodash';
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
export default function withSideEditor(WrappedComponent) {
|
|
9
|
+
export default function withSideEditor(WrappedComponent, isTree = false) {
|
|
10
10
|
return withEditor((props) => {
|
|
11
11
|
const {
|
|
12
12
|
Editor,
|
|
@@ -19,7 +19,7 @@ export default function withSideEditor(WrappedComponent) {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
return <Container
|
|
22
|
-
center={<WrappedComponent {...props} />}
|
|
22
|
+
center={<WrappedComponent isTree={isTree} {...props} />}
|
|
23
23
|
east={<Editor
|
|
24
24
|
editorType={EDITOR_TYPE__SIDE}
|
|
25
25
|
flex={sideFlex}
|
|
@@ -25,7 +25,7 @@ import _ from 'lodash';
|
|
|
25
25
|
// then switch position to absolute, draggable area would be header of panel
|
|
26
26
|
// const DraggableColumn = withAdditionalProps(withDraggable(Column));
|
|
27
27
|
|
|
28
|
-
export default function withWindowedEditor(WrappedComponent) {
|
|
28
|
+
export default function withWindowedEditor(WrappedComponent, isTree = false) {
|
|
29
29
|
return withEditor((props) => {
|
|
30
30
|
const {
|
|
31
31
|
useEditor = false,
|
|
@@ -40,7 +40,7 @@ export default function withWindowedEditor(WrappedComponent) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
return <>
|
|
43
|
-
<WrappedComponent {...props} />
|
|
43
|
+
<WrappedComponent isTree={isTree} {...props} />
|
|
44
44
|
{useEditor && isEditorShown &&
|
|
45
45
|
<Modal
|
|
46
46
|
isOpen={true}
|