@onehat/ui 0.3.380 → 0.3.382
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 +1 -0
- package/src/Components/Form/Field/Tag/Tag.js +1 -0
- package/src/Components/Form/Form.js +5 -0
- package/src/Components/Grid/Grid.js +34 -11
- package/src/Components/Hoc/Secondary/withSecondaryEditor.js +2 -1
- package/src/Components/Hoc/Secondary/withSecondarySideEditor.js +1 -0
- package/src/Components/Hoc/Secondary/withSecondaryWindowedEditor.js +1 -0
- package/src/Components/Hoc/withEditor.js +2 -1
- package/src/Components/Hoc/withInlineEditor.js +1 -0
- package/src/Components/Hoc/withSideEditor.js +1 -0
- package/src/Components/Hoc/withWindowedEditor.js +1 -0
- package/src/Components/Tree/Tree.js +26 -16
- package/src/Components/Viewer/Viewer.js +2 -0
- package/src/PlatformImports/Web/Attachments.js +2 -1
package/package.json
CHANGED
|
@@ -239,6 +239,7 @@ function TagComponent(props) {
|
|
|
239
239
|
if (propsToPass.selectorId) {
|
|
240
240
|
_combo.selectorId = propsToPass.selectorId;
|
|
241
241
|
_combo.selectorSelected = propsToPass.selectorSelected;
|
|
242
|
+
_combo.selectorSelectedField = propsToPass.selectorSelectedField;
|
|
242
243
|
}
|
|
243
244
|
|
|
244
245
|
return <>
|
|
@@ -127,6 +127,7 @@ function Form(props) {
|
|
|
127
127
|
// parent container
|
|
128
128
|
selectorId,
|
|
129
129
|
selectorSelected,
|
|
130
|
+
selectorSelectedField,
|
|
130
131
|
|
|
131
132
|
// withAlert
|
|
132
133
|
alert,
|
|
@@ -337,6 +338,7 @@ function Form(props) {
|
|
|
337
338
|
|
|
338
339
|
if (useSelectorId) { // This causes the whole form to use selectorId
|
|
339
340
|
editorTypeProps.selectorId = selectorId;
|
|
341
|
+
editorTypeProps.selectorSelectedField = selectorSelectedField;
|
|
340
342
|
}
|
|
341
343
|
if (propsToPass.selectorId || editorTypeProps.selectorId) { // editorTypeProps.selectorId causes just this one field to use selectorId
|
|
342
344
|
if (_.isNil(propsToPass.selectorSelected)) {
|
|
@@ -589,6 +591,7 @@ function Form(props) {
|
|
|
589
591
|
|
|
590
592
|
if (useSelectorId) { // This causes the whole form to use selectorId
|
|
591
593
|
editorTypeProps.selectorId = selectorId;
|
|
594
|
+
editorTypeProps.selectorSelectedField = selectorSelectedField;
|
|
592
595
|
}
|
|
593
596
|
if (propsToPass.selectorId || editorTypeProps.selectorId) { // editorTypeProps.selectorId causes just this one field to use selectorId
|
|
594
597
|
if (_.isNil(propsToPass.selectorSelected)) {
|
|
@@ -708,6 +711,7 @@ function Form(props) {
|
|
|
708
711
|
title = null,
|
|
709
712
|
description = null,
|
|
710
713
|
selectorId,
|
|
714
|
+
selectorSelectedField,
|
|
711
715
|
...propsToPass
|
|
712
716
|
} = item;
|
|
713
717
|
if (isMultiple && type !== 'Attachments') {
|
|
@@ -721,6 +725,7 @@ function Form(props) {
|
|
|
721
725
|
element = <Element
|
|
722
726
|
{...testProps('ancillary-' + type)}
|
|
723
727
|
selectorId={selectorId}
|
|
728
|
+
selectorSelectedField={selectorSelectedField}
|
|
724
729
|
selectorSelected={selectorSelected || record}
|
|
725
730
|
flex={1}
|
|
726
731
|
uniqueRepository={true}
|
|
@@ -111,7 +111,6 @@ function GridComponent(props) {
|
|
|
111
111
|
hideNavColumn = true,
|
|
112
112
|
noneFoundText,
|
|
113
113
|
autoAdjustPageSizeToHeight = true,
|
|
114
|
-
disableSelectorSelected = false,
|
|
115
114
|
showRowExpander = false,
|
|
116
115
|
getExpandedRowContent,
|
|
117
116
|
showHeaders = true,
|
|
@@ -140,6 +139,22 @@ function GridComponent(props) {
|
|
|
140
139
|
alternatingInterval = 2,
|
|
141
140
|
defaultRowHeight = 48,
|
|
142
141
|
|
|
142
|
+
// The selectorSelected mechanism allows us to filter results of the primary model, (e.g. WorkOrders)
|
|
143
|
+
// by the selection on the secondary model (e.g. Equipment). It's used on Grids, Trees, Forms, etc.
|
|
144
|
+
// The 'selectorId' is the name of the primary model's filter (e.g. 'WorkOrders.equipment_id').
|
|
145
|
+
// which gets submitted to the server as a condition (e.g. 'conditions[WorkOrders.equipment_id]').
|
|
146
|
+
// The 'selectorSelected' is the Entity on the secondary model which is selected (e.g. Equipment).
|
|
147
|
+
// The 'selectorSelectedField' is the field on the secondary model to use as the value for the filter
|
|
148
|
+
// (e.g. 'fleet_id'). If not given, it defaults to 'id'.
|
|
149
|
+
// It can be disabled altogether for a specific grid ('disableSelectorSelected'), and configured
|
|
150
|
+
// so that no selection means no results ('noSelectorMeansNoResults').
|
|
151
|
+
|
|
152
|
+
selectorId,
|
|
153
|
+
selectorSelected,
|
|
154
|
+
selectorSelectedField = 'id',
|
|
155
|
+
noSelectorMeansNoResults = false,
|
|
156
|
+
disableSelectorSelected = false,
|
|
157
|
+
|
|
143
158
|
// withComponent
|
|
144
159
|
self,
|
|
145
160
|
|
|
@@ -182,16 +197,11 @@ function GridComponent(props) {
|
|
|
182
197
|
deselectAll,
|
|
183
198
|
selectRangeTo,
|
|
184
199
|
isInSelection,
|
|
185
|
-
noSelectorMeansNoResults = false,
|
|
186
200
|
selectNext,
|
|
187
201
|
selectPrev,
|
|
188
202
|
addNextToSelection,
|
|
189
203
|
addPrevToSelection,
|
|
190
204
|
|
|
191
|
-
// DataMgt
|
|
192
|
-
selectorId,
|
|
193
|
-
selectorSelected,
|
|
194
|
-
|
|
195
205
|
// withInlineEditor
|
|
196
206
|
inlineEditor = null,
|
|
197
207
|
isInlineEditorShown = false,
|
|
@@ -212,6 +222,7 @@ function GridComponent(props) {
|
|
|
212
222
|
expandedRowsRef = useRef({}),
|
|
213
223
|
cachedDragElements = useRef(),
|
|
214
224
|
dragSelectionRef = useRef([]),
|
|
225
|
+
previousSelectorId = useRef(),
|
|
215
226
|
[isInited, setIsInited] = useState(false),
|
|
216
227
|
[isReady, setIsReady] = useState(false),
|
|
217
228
|
[isLoading, setIsLoading] = useState(false),
|
|
@@ -755,11 +766,23 @@ function GridComponent(props) {
|
|
|
755
766
|
if (disableSelectorSelected || !selectorId) {
|
|
756
767
|
return
|
|
757
768
|
}
|
|
758
|
-
|
|
759
|
-
if (
|
|
760
|
-
|
|
769
|
+
|
|
770
|
+
if (previousSelectorId.current && selectorId !== previousSelectorId.current) {
|
|
771
|
+
Repository.pauseEvents();
|
|
772
|
+
Repository.clearFilters(previousSelectorId.current);
|
|
773
|
+
Repository.resumeEvents();
|
|
774
|
+
}
|
|
775
|
+
previousSelectorId.current = selectorId;
|
|
776
|
+
|
|
777
|
+
let value = null;
|
|
778
|
+
if (selectorSelected) {
|
|
779
|
+
value = selectorSelected[selectorSelectedField];
|
|
780
|
+
}
|
|
781
|
+
if (noSelectorMeansNoResults && _.isEmpty(selectorSelected)) {
|
|
782
|
+
value = 'NO_MATCHES';
|
|
761
783
|
}
|
|
762
|
-
|
|
784
|
+
|
|
785
|
+
Repository.filter(selectorId, value, false); // false so it doesn't clear existing filters
|
|
763
786
|
},
|
|
764
787
|
onGridKeyDown = (e) => {
|
|
765
788
|
if (isInlineEditorShown) {
|
|
@@ -968,7 +991,7 @@ function GridComponent(props) {
|
|
|
968
991
|
|
|
969
992
|
applySelectorSelected();
|
|
970
993
|
|
|
971
|
-
}, [selectorSelected]);
|
|
994
|
+
}, [selectorId, selectorSelected]);
|
|
972
995
|
|
|
973
996
|
if (canUser && !canUser('view')) {
|
|
974
997
|
return <Unauthorized />;
|
|
@@ -60,6 +60,7 @@ export default function withSecondaryEditor(WrappedComponent, isTree = false) {
|
|
|
60
60
|
// parent container
|
|
61
61
|
secondarySelectorId,
|
|
62
62
|
secondarySelectorSelected,
|
|
63
|
+
secondarySelectorSelectedField = 'id',
|
|
63
64
|
|
|
64
65
|
// withSecondaryData
|
|
65
66
|
SecondaryRepository,
|
|
@@ -150,7 +151,7 @@ export default function withSecondaryEditor(WrappedComponent, isTree = false) {
|
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
if (secondarySelectorId && !_.isEmpty(secondarySelectorSelected)) {
|
|
153
|
-
addValues[secondarySelectorId] = secondarySelectorSelected
|
|
154
|
+
addValues[secondarySelectorId] = secondarySelectorSelected[secondarySelectorSelectedField];
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
if (getNewEntityDisplayValue()) {
|
|
@@ -35,6 +35,7 @@ export default function withSecondarySideEditor(WrappedComponent, isTree = false
|
|
|
35
35
|
// pull these out, as we don't want them going to the Editor
|
|
36
36
|
secondarySelectorId,
|
|
37
37
|
secondarySelectorSelected,
|
|
38
|
+
secondarySelectorSelectedField,
|
|
38
39
|
|
|
39
40
|
...propsToPass
|
|
40
41
|
} = props;
|
|
@@ -41,6 +41,7 @@ export default function withSecondaryWindowedEditor(WrappedComponent, isTree = f
|
|
|
41
41
|
// pull these out, as we don't want them going to the SecondaryEditor
|
|
42
42
|
secondarySelectorId,
|
|
43
43
|
secondarySelectorSelected,
|
|
44
|
+
secondarySelectorSelectedField,
|
|
44
45
|
h,
|
|
45
46
|
|
|
46
47
|
...propsToPass
|
|
@@ -60,6 +60,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
60
60
|
// parent container
|
|
61
61
|
selectorId,
|
|
62
62
|
selectorSelected,
|
|
63
|
+
selectorSelectedField = 'id',
|
|
63
64
|
|
|
64
65
|
// withData
|
|
65
66
|
Repository,
|
|
@@ -149,7 +150,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
149
150
|
}
|
|
150
151
|
|
|
151
152
|
if (selectorId && !_.isEmpty(selectorSelected)) {
|
|
152
|
-
addValues[selectorId] = selectorSelected
|
|
153
|
+
addValues[selectorId] = selectorSelected[selectorSelectedField];
|
|
153
154
|
}
|
|
154
155
|
|
|
155
156
|
if (getNewEntityDisplayValue()) {
|
|
@@ -43,6 +43,7 @@ import getIconButtonFromConfig from '../../Functions/getIconButtonFromConfig.js'
|
|
|
43
43
|
import inArray from '../../Functions/inArray.js';
|
|
44
44
|
import testProps from '../../Functions/testProps.js';
|
|
45
45
|
import nbToRgb from '../../Functions/nbToRgb.js';
|
|
46
|
+
import CenterBox from '../Layout/CenterBox.js';
|
|
46
47
|
import ReloadTreeButton from '../Buttons/ReloadTreeButton.js';
|
|
47
48
|
import TreeNode, { DraggableTreeNode } from './TreeNode.js';
|
|
48
49
|
import FormPanel from '../Panel/FormPanel.js';
|
|
@@ -114,6 +115,10 @@ function TreeComponent(props) {
|
|
|
114
115
|
canRecordBeEdited,
|
|
115
116
|
onTreeLoad,
|
|
116
117
|
|
|
118
|
+
selectorId,
|
|
119
|
+
selectorSelected,
|
|
120
|
+
selectorSelectedField = 'id',
|
|
121
|
+
|
|
117
122
|
// withComponent
|
|
118
123
|
self,
|
|
119
124
|
|
|
@@ -155,10 +160,6 @@ function TreeComponent(props) {
|
|
|
155
160
|
isInSelection,
|
|
156
161
|
noSelectorMeansNoResults = false,
|
|
157
162
|
|
|
158
|
-
// DataMgt
|
|
159
|
-
selectorId,
|
|
160
|
-
selectorSelected,
|
|
161
|
-
|
|
162
163
|
} = props,
|
|
163
164
|
styles = UiGlobals.styles,
|
|
164
165
|
forceUpdate = useForceUpdate(),
|
|
@@ -1205,19 +1206,15 @@ function TreeComponent(props) {
|
|
|
1205
1206
|
})();
|
|
1206
1207
|
return () => {};
|
|
1207
1208
|
}
|
|
1208
|
-
|
|
1209
|
-
(async () => {
|
|
1210
|
-
if (autoLoadRootNodes) {
|
|
1211
|
-
await reloadTree();
|
|
1212
|
-
}
|
|
1213
|
-
setIsReady(true);
|
|
1214
|
-
})();
|
|
1215
|
-
|
|
1216
1209
|
|
|
1217
1210
|
// set up @onehat/data repository
|
|
1218
1211
|
const
|
|
1219
1212
|
setTrue = () => setIsLoading(true),
|
|
1220
1213
|
setFalse = () => setIsLoading(false);
|
|
1214
|
+
|
|
1215
|
+
if (Repository.isLoading) {
|
|
1216
|
+
setTrue();
|
|
1217
|
+
}
|
|
1221
1218
|
|
|
1222
1219
|
Repository.on('beforeLoad', setTrue);
|
|
1223
1220
|
Repository.on('load', setFalse);
|
|
@@ -1227,6 +1224,13 @@ function TreeComponent(props) {
|
|
|
1227
1224
|
Repository.on('changeFilters', reloadTree);
|
|
1228
1225
|
Repository.on('changeSorters', reloadTree);
|
|
1229
1226
|
|
|
1227
|
+
(async () => {
|
|
1228
|
+
if (autoLoadRootNodes) {
|
|
1229
|
+
await reloadTree();
|
|
1230
|
+
}
|
|
1231
|
+
setIsReady(true);
|
|
1232
|
+
})();
|
|
1233
|
+
|
|
1230
1234
|
return () => {
|
|
1231
1235
|
Repository.off('beforeLoad', setTrue);
|
|
1232
1236
|
Repository.off('load', setFalse);
|
|
@@ -1243,7 +1247,7 @@ function TreeComponent(props) {
|
|
|
1243
1247
|
return () => {};
|
|
1244
1248
|
}
|
|
1245
1249
|
if (!disableSelectorSelected && selectorId) {
|
|
1246
|
-
let id = selectorSelected?.
|
|
1250
|
+
let id = selectorSelected?.[selectorSelectedField] ?? null;
|
|
1247
1251
|
if (_.isEmpty(selectorSelected)) {
|
|
1248
1252
|
id = noSelectorMeansNoResults ? 'NO_MATCHES' : null;
|
|
1249
1253
|
}
|
|
@@ -1252,7 +1256,9 @@ function TreeComponent(props) {
|
|
|
1252
1256
|
}, [selectorId, selectorSelected]);
|
|
1253
1257
|
|
|
1254
1258
|
if (canUser && !canUser('view')) {
|
|
1255
|
-
return <
|
|
1259
|
+
return <CenterBox>
|
|
1260
|
+
<Unauthorized />
|
|
1261
|
+
</CenterBox>;
|
|
1256
1262
|
}
|
|
1257
1263
|
|
|
1258
1264
|
if (setWithEditListeners) {
|
|
@@ -1279,7 +1285,9 @@ function TreeComponent(props) {
|
|
|
1279
1285
|
footerToolbarItemComponents = useMemo(() => getFooterToolbarItems(), [Repository?.hash, additionalToolbarButtons, isDragMode, getTreeNodeData()]);
|
|
1280
1286
|
|
|
1281
1287
|
if (!isReady) {
|
|
1282
|
-
return <
|
|
1288
|
+
return <CenterBox>
|
|
1289
|
+
<Loading />
|
|
1290
|
+
</CenterBox>;
|
|
1283
1291
|
}
|
|
1284
1292
|
|
|
1285
1293
|
const treeNodes = renderTreeNodes(getTreeNodeData());
|
|
@@ -1336,7 +1344,9 @@ function TreeComponent(props) {
|
|
|
1336
1344
|
>
|
|
1337
1345
|
<ScrollView {...testProps('ScrollView')} flex={1} w="100%">
|
|
1338
1346
|
{!treeNodes?.length ?
|
|
1339
|
-
<
|
|
1347
|
+
<CenterBox>
|
|
1348
|
+
<NoRecordsFound text={noneFoundText} onRefresh={reloadTree} />
|
|
1349
|
+
</CenterBox> :
|
|
1340
1350
|
treeNodes}
|
|
1341
1351
|
</ScrollView>
|
|
1342
1352
|
</Column>
|
|
@@ -58,6 +58,7 @@ function Viewer(props) {
|
|
|
58
58
|
// parent container
|
|
59
59
|
selectorId,
|
|
60
60
|
selectorSelected,
|
|
61
|
+
selectorSelectedField,
|
|
61
62
|
|
|
62
63
|
} = props,
|
|
63
64
|
scrollViewRef = useRef(),
|
|
@@ -209,6 +210,7 @@ function Viewer(props) {
|
|
|
209
210
|
{...testProps('ancillary-' + type)}
|
|
210
211
|
selectorId={selectorId}
|
|
211
212
|
selectorSelected={selectorSelected || record}
|
|
213
|
+
selectorSelectedField={selectorSelectedField}
|
|
212
214
|
flex={1}
|
|
213
215
|
h={350}
|
|
214
216
|
canEditorViewOnly={true}
|
|
@@ -94,6 +94,7 @@ function AttachmentsElement(props) {
|
|
|
94
94
|
|
|
95
95
|
// parentContainer
|
|
96
96
|
selectorSelected,
|
|
97
|
+
selectorSelectedField = 'id',
|
|
97
98
|
|
|
98
99
|
// withData
|
|
99
100
|
Repository,
|
|
@@ -105,7 +106,7 @@ function AttachmentsElement(props) {
|
|
|
105
106
|
} = props,
|
|
106
107
|
styles = UiGlobals.styles,
|
|
107
108
|
model = _.isArray(selectorSelected) && selectorSelected[0] ? selectorSelected[0].repository?.name : selectorSelected?.repository?.name,
|
|
108
|
-
modelidCalc = _.isArray(selectorSelected) ? _.map(selectorSelected, (entity) => entity
|
|
109
|
+
modelidCalc = _.isArray(selectorSelected) ? _.map(selectorSelected, (entity) => entity[selectorSelectedField]) : selectorSelected?.[selectorSelectedField],
|
|
109
110
|
modelid = useRef(modelidCalc),
|
|
110
111
|
[isReady, setIsReady] = useState(false),
|
|
111
112
|
[isUploading, setIsUploading] = useState(false),
|