@onehat/ui 0.4.106 → 0.4.107
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 -1
- package/src/Components/Form/Field/Combo/Combo.js +20 -0
- package/src/Components/Form/Form.js +28 -3
- package/src/Components/Grid/Grid.js +1 -1
- package/src/Components/Grid/GridRow.js +4 -6
- package/src/Components/Hoc/withEditor.js +5 -5
- package/src/Components/Hoc/withPdfButtons.js +61 -48
- package/src/Components/Layout/SetupButton.js +29 -3
- package/src/Components/Viewer/Viewer.js +7 -4
package/package.json
CHANGED
|
@@ -46,10 +46,11 @@ function Editor(props) {
|
|
|
46
46
|
if (canRecordBeEdited && !canRecordBeEdited(selection)) {
|
|
47
47
|
canEdit = false;
|
|
48
48
|
}
|
|
49
|
+
const record = selection[0];
|
|
50
|
+
self.record = record; // make it so we can target the record from within a Viewer or Form
|
|
49
51
|
|
|
50
52
|
// Repository?.isRemotePhantomMode && selection.length === 1 &&
|
|
51
53
|
if (getEditorMode() === EDITOR_MODE__VIEW || isEditorViewOnly || !canEdit) {
|
|
52
|
-
const record = selection[0];
|
|
53
54
|
if (record.isDestroyed) {
|
|
54
55
|
return null;
|
|
55
56
|
}
|
|
@@ -1223,6 +1223,25 @@ export const ComboComponent = forwardRef((props, ref) => {
|
|
|
1223
1223
|
}
|
|
1224
1224
|
|
|
1225
1225
|
if (isViewerShown && Editor) {
|
|
1226
|
+
let modalBackdrop = <ModalBackdrop className="Combo-viewer-ModalBackdrop" />;
|
|
1227
|
+
if (CURRENT_MODE === UI_MODE_NATIVE) {
|
|
1228
|
+
// Gluestack's ModalBackdrop was not working on Native,
|
|
1229
|
+
// so workaround is to do it manually for now
|
|
1230
|
+
modalBackdrop = <Pressable
|
|
1231
|
+
onPress={onViewerClose}
|
|
1232
|
+
className={clsx(
|
|
1233
|
+
'Combo-viewer-ModalBackdrop-replacment',
|
|
1234
|
+
'h-full',
|
|
1235
|
+
'w-full',
|
|
1236
|
+
'absolute',
|
|
1237
|
+
'top-0',
|
|
1238
|
+
'left-0',
|
|
1239
|
+
'bg-[#000]',
|
|
1240
|
+
'opacity-50',
|
|
1241
|
+
)}
|
|
1242
|
+
/>;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1226
1245
|
const propsForViewer = _.pick(props, [
|
|
1227
1246
|
'disableCopy',
|
|
1228
1247
|
'disableDuplicate',
|
|
@@ -1246,6 +1265,7 @@ export const ComboComponent = forwardRef((props, ref) => {
|
|
|
1246
1265
|
isOpen={true}
|
|
1247
1266
|
onClose={onViewerClose}
|
|
1248
1267
|
>
|
|
1268
|
+
{modalBackdrop}
|
|
1249
1269
|
<Editor
|
|
1250
1270
|
editorType={EDITOR_TYPE__WINDOWED}
|
|
1251
1271
|
isEditorViewOnly={true}
|
|
@@ -240,6 +240,7 @@ function Form(props) {
|
|
|
240
240
|
resolver: yupResolver(validatorToUse),
|
|
241
241
|
context: { isPhantom },
|
|
242
242
|
}),
|
|
243
|
+
currentEditorMode = getEditorMode(),
|
|
243
244
|
buildFromColumnsConfig = () => {
|
|
244
245
|
// Only used in InlineEditor
|
|
245
246
|
// Build the fields that match the current columnsConfig in the grid
|
|
@@ -1045,7 +1046,7 @@ function Form(props) {
|
|
|
1045
1046
|
)}
|
|
1046
1047
|
>{title}</Text>;
|
|
1047
1048
|
if (icon) {
|
|
1048
|
-
titleElement = <HStack className="items-center"><Icon as={icon} className="w-[32px] h-[32px] mr-2" />{titleElement}</HStack>
|
|
1049
|
+
titleElement = <HStack className="items-center mb-1"><Icon as={icon} className="w-[32px] h-[32px] mr-2" />{titleElement}</HStack>
|
|
1049
1050
|
}
|
|
1050
1051
|
}
|
|
1051
1052
|
if (description) {
|
|
@@ -1149,6 +1150,29 @@ function Form(props) {
|
|
|
1149
1150
|
}
|
|
1150
1151
|
}, [record]);
|
|
1151
1152
|
|
|
1153
|
+
useEffect(() => {
|
|
1154
|
+
if (skipAll) {
|
|
1155
|
+
return;
|
|
1156
|
+
}
|
|
1157
|
+
if (currentEditorMode !== EDITOR_MODE__ADD) {
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
if (!containerWidth) {
|
|
1161
|
+
// Wait until fields are mounted; before this, isValid can be false with empty errors.
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
// In some flows the editor mode flips to ADD after the record effect runs.
|
|
1166
|
+
// Validate again so the Add button is enabled immediately when form is valid.
|
|
1167
|
+
const timeoutId = setTimeout(() => {
|
|
1168
|
+
trigger();
|
|
1169
|
+
}, 0);
|
|
1170
|
+
|
|
1171
|
+
return () => {
|
|
1172
|
+
clearTimeout(timeoutId);
|
|
1173
|
+
};
|
|
1174
|
+
}, [record, currentEditorMode, containerWidth, trigger]);
|
|
1175
|
+
|
|
1152
1176
|
useEffect(() => {
|
|
1153
1177
|
if (skipAll) {
|
|
1154
1178
|
return;
|
|
@@ -1249,7 +1273,8 @@ function Form(props) {
|
|
|
1249
1273
|
showCloseBtn = false,
|
|
1250
1274
|
showCancelBtn = false,
|
|
1251
1275
|
showSaveBtn = false,
|
|
1252
|
-
showSubmitBtn = false
|
|
1276
|
+
showSubmitBtn = false,
|
|
1277
|
+
isAddMode = getEditorMode() === EDITOR_MODE__ADD;
|
|
1253
1278
|
if (containerWidth) { // we need to render this component twice in order to get the container width. Skip this on first render
|
|
1254
1279
|
|
|
1255
1280
|
// create editor
|
|
@@ -1332,7 +1357,7 @@ function Form(props) {
|
|
|
1332
1357
|
isSaveDisabled = true;
|
|
1333
1358
|
isSubmitDisabled = true;
|
|
1334
1359
|
}
|
|
1335
|
-
if (_.isEmpty(formState.dirtyFields) && !isPhantom) {
|
|
1360
|
+
if (_.isEmpty(formState.dirtyFields) && !isPhantom && !isAddMode) {
|
|
1336
1361
|
isSaveDisabled = true;
|
|
1337
1362
|
}
|
|
1338
1363
|
if (onDelete && getEditorMode() === EDITOR_MODE__EDIT && isSingle) {
|
|
@@ -430,7 +430,7 @@ function GridComponent(props) {
|
|
|
430
430
|
return processedConfig;
|
|
431
431
|
});
|
|
432
432
|
const items = _.map(processedButtons, (config, ix) => getIconButtonFromConfig(config, ix, self));
|
|
433
|
-
if (canRowsReorder && CURRENT_MODE === UI_MODE_WEB) { // DND is currently web-only TODO: implement for RN
|
|
433
|
+
if (canRowsReorder && CURRENT_MODE === UI_MODE_WEB && onEdit && (!canUser || canUser(EDIT)) && !isEditorViewOnly) { // DND is currently web-only TODO: implement for RN
|
|
434
434
|
items.unshift(<IconButton
|
|
435
435
|
{...testProps('reorderBtn')}
|
|
436
436
|
key="reorderBtn"
|
|
@@ -450,6 +450,8 @@ const GridRow = forwardRef((props, ref) => {
|
|
|
450
450
|
)}
|
|
451
451
|
/>}
|
|
452
452
|
</>;
|
|
453
|
+
const hasCustomBgClass = rowProps?.className && /\bbg-/.test(rowProps.className);
|
|
454
|
+
|
|
453
455
|
if (dropTargetRef) {
|
|
454
456
|
rowContents = <HStack
|
|
455
457
|
ref={dropTargetRef}
|
|
@@ -459,9 +461,7 @@ const GridRow = forwardRef((props, ref) => {
|
|
|
459
461
|
'flex-1',
|
|
460
462
|
'grow-1',
|
|
461
463
|
)}
|
|
462
|
-
style={{
|
|
463
|
-
backgroundColor: bg,
|
|
464
|
-
}}
|
|
464
|
+
style={hasCustomBgClass ? undefined : { backgroundColor: bg }}
|
|
465
465
|
>{rowContents}</HStack>;
|
|
466
466
|
}
|
|
467
467
|
|
|
@@ -485,9 +485,7 @@ const GridRow = forwardRef((props, ref) => {
|
|
|
485
485
|
{...rowProps}
|
|
486
486
|
key={hash}
|
|
487
487
|
className={rowClassName}
|
|
488
|
-
style={{
|
|
489
|
-
backgroundColor: bg,
|
|
490
|
-
}}
|
|
488
|
+
style={hasCustomBgClass ? undefined : { backgroundColor: bg }}
|
|
491
489
|
>{rowContents}</HStackNative>;
|
|
492
490
|
if (rowProps.tooltip) {
|
|
493
491
|
row = <Tooltip
|
|
@@ -149,7 +149,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
149
149
|
selection = getSelection();
|
|
150
150
|
if (!_.isEmpty(formState?.dirtyFields) && newSelection !== selection && getEditorMode() === EDITOR_MODE__EDIT) {
|
|
151
151
|
confirm('This record has unsaved changes. Are you sure you want to cancel editing? Changes will be lost.', doIt);
|
|
152
|
-
} else if (selection && selection[0] && !selection[0].isDestroyed &&
|
|
152
|
+
} else if (selection && selection[0] && !selection[0].isDestroyed && selection[0].isPhantom) {
|
|
153
153
|
confirm('This new record is unsaved. Are you sure you want to cancel editing? Changes will be lost.', async () => {
|
|
154
154
|
await selection[0].delete();
|
|
155
155
|
doIt();
|
|
@@ -216,7 +216,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
216
216
|
if (!record || record.isDestroyed) {
|
|
217
217
|
return false;
|
|
218
218
|
}
|
|
219
|
-
return !!
|
|
219
|
+
return !!record.isPhantom;
|
|
220
220
|
},
|
|
221
221
|
getIsEditorDisabledByParent = () => {
|
|
222
222
|
return getIsParentSaveLocked();
|
|
@@ -680,8 +680,8 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
680
680
|
// just update this one entity
|
|
681
681
|
selection[0].setValues(data);
|
|
682
682
|
|
|
683
|
-
//
|
|
684
|
-
if (selection[0].
|
|
683
|
+
// In ADD mode, if record is phantom and nothing is dirty, stage it so save() still submits and solidifies.
|
|
684
|
+
if (getEditorMode() === EDITOR_MODE__ADD && selection[0].isPhantom && !selection[0].isDirty) {
|
|
685
685
|
selection[0].markStaged();
|
|
686
686
|
useStaged = true;
|
|
687
687
|
}
|
|
@@ -834,7 +834,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
834
834
|
if (canRecordBeEdited && canRecordBeEdited(selection) === false) {
|
|
835
835
|
return EDITOR_MODE__VIEW;
|
|
836
836
|
}
|
|
837
|
-
if (selection.length === 1 && !selection[0].isDestroyed &&
|
|
837
|
+
if (selection.length === 1 && !selection[0].isDestroyed && selection[0].isPhantom && !disableAdd) {
|
|
838
838
|
return EDITOR_MODE__ADD;
|
|
839
839
|
}
|
|
840
840
|
return selection.length ? EDITOR_MODE__EDIT : EDITOR_MODE__VIEW;
|
|
@@ -33,7 +33,9 @@ export default function withPdfButtons(WrappedComponent) {
|
|
|
33
33
|
additionalEditButtons = [],
|
|
34
34
|
additionalViewButtons = [],
|
|
35
35
|
items = [],
|
|
36
|
+
pdfItems,
|
|
36
37
|
ancillaryItems = [],
|
|
38
|
+
pdfAncillaryItems,
|
|
37
39
|
columnDefaults = {},
|
|
38
40
|
|
|
39
41
|
// withComponent
|
|
@@ -58,32 +60,15 @@ export default function withPdfButtons(WrappedComponent) {
|
|
|
58
60
|
styles = UiGlobals.styles,
|
|
59
61
|
propertyNames = [],
|
|
60
62
|
buildModalItems = () => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
let {
|
|
70
|
-
additionalEditButtons,
|
|
71
|
-
items,
|
|
72
|
-
} = item;
|
|
73
|
-
if (!_.isEmpty(items)) {
|
|
74
|
-
_.each(items, (item) => {
|
|
75
|
-
walkTreeToDeleteAdditionalEditButtons(item);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
if (additionalEditButtons) {
|
|
79
|
-
delete item.additionalEditButtons;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
_.each(modalItems, walkTreeToDeleteAdditionalEditButtons);
|
|
63
|
+
// Build a cloned PDF item tree so we never mutate source items by reference.
|
|
64
|
+
const
|
|
65
|
+
itemsTouse = pdfItems || items,
|
|
66
|
+
ancillaryItemsToUse = pdfAncillaryItems || ancillaryItems,
|
|
67
|
+
modalItems = _.compact(_.map(itemsTouse, (item, ix) => buildNextLayer(item, ix, columnDefaults)));
|
|
83
68
|
|
|
84
|
-
if (!_.isEmpty(
|
|
69
|
+
if (!_.isEmpty(ancillaryItemsToUse)) {
|
|
85
70
|
const
|
|
86
|
-
ancillaryItemsClone = _.cloneDeepWith(
|
|
71
|
+
ancillaryItemsClone = _.cloneDeepWith(ancillaryItemsToUse, (value) => {
|
|
87
72
|
// Exclude the 'parent' property from being cloned, as it would introduce an infinitely recursive loop
|
|
88
73
|
if (value && value.parent) {
|
|
89
74
|
const { parent, ...rest } = value;
|
|
@@ -127,47 +112,75 @@ export default function withPdfButtons(WrappedComponent) {
|
|
|
127
112
|
return modalItems;
|
|
128
113
|
},
|
|
129
114
|
buildNextLayer = (item, ix, defaults) => {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
115
|
+
if (!item) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const {
|
|
120
|
+
type,
|
|
121
|
+
name,
|
|
122
|
+
title,
|
|
123
|
+
items: childItems,
|
|
124
|
+
isHiddenInViewMode,
|
|
125
|
+
} = item;
|
|
126
|
+
|
|
135
127
|
if (inArray(type, ['Column', 'FieldSet'])) {
|
|
136
|
-
|
|
137
|
-
|
|
128
|
+
const nextDefaults = {
|
|
129
|
+
...(defaults || {}),
|
|
130
|
+
...(item.defaults || {}),
|
|
131
|
+
labelWidth: '90%',
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const nextItem = {
|
|
135
|
+
type,
|
|
136
|
+
defaults: nextDefaults,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
if (title) {
|
|
140
|
+
nextItem.title = title;
|
|
141
|
+
}
|
|
142
|
+
if (item.reference) {
|
|
143
|
+
nextItem.reference = item.reference;
|
|
144
|
+
}
|
|
145
|
+
if (item.flex) {
|
|
146
|
+
nextItem.flex = item.flex;
|
|
138
147
|
}
|
|
139
148
|
if (type === 'FieldSet') {
|
|
140
|
-
|
|
141
|
-
|
|
149
|
+
nextItem.showToggleAllCheckbox = true;
|
|
150
|
+
nextItem.isCollapsible = false;
|
|
142
151
|
}
|
|
143
|
-
|
|
144
|
-
if (!_.isEmpty(
|
|
145
|
-
|
|
146
|
-
item.items = _.map(items, (item, ix) => {
|
|
147
|
-
if (!item){
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
return buildNextLayer(item, ix, defaults);
|
|
151
|
-
});
|
|
152
|
+
|
|
153
|
+
if (!_.isEmpty(childItems)) {
|
|
154
|
+
nextItem.items = _.compact(_.map(childItems, (childItem, childIx) => buildNextLayer(childItem, childIx, nextDefaults)));
|
|
152
155
|
}
|
|
153
|
-
|
|
156
|
+
|
|
157
|
+
return nextItem;
|
|
154
158
|
}
|
|
155
159
|
|
|
156
|
-
if (
|
|
160
|
+
if (isHiddenInViewMode || type === 'Button') {
|
|
157
161
|
return null;
|
|
158
162
|
}
|
|
159
163
|
|
|
160
|
-
|
|
164
|
+
let resolvedTitle = title;
|
|
165
|
+
if (!resolvedTitle) {
|
|
161
166
|
const propertyDef = name && Repository?.getSchema().getPropertyDefinition(name);
|
|
162
167
|
if (propertyDef?.title) {
|
|
163
|
-
|
|
168
|
+
resolvedTitle = propertyDef.title;
|
|
164
169
|
}
|
|
165
170
|
}
|
|
166
171
|
if (name) {
|
|
167
172
|
propertyNames.push(name); // for validator
|
|
168
173
|
}
|
|
169
|
-
|
|
170
|
-
|
|
174
|
+
if (!name) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
type: 'Checkbox',
|
|
180
|
+
name,
|
|
181
|
+
title: resolvedTitle,
|
|
182
|
+
isEditable: false, // hack to force all checkboxes to use same render branch in Form
|
|
183
|
+
};
|
|
171
184
|
},
|
|
172
185
|
buildValidator = () => {
|
|
173
186
|
const propertyValidatorDefs = {};
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
selectIsSetupMode,
|
|
4
4
|
toggleSetupMode,
|
|
5
5
|
} from '@src/Models/Slices/AppSlice';
|
|
6
|
+
import clsx from 'clsx';
|
|
6
7
|
import Button from '../Buttons/Button';
|
|
7
8
|
import IconButton from '../Buttons/IconButton';
|
|
8
9
|
import Gear from '../Icons/Gear';
|
|
@@ -13,19 +14,44 @@ export default function SetupButton(props) {
|
|
|
13
14
|
} = props,
|
|
14
15
|
dispatch = useDispatch(),
|
|
15
16
|
isSetupMode = useSelector(selectIsSetupMode),
|
|
16
|
-
onPress = () => dispatch(toggleSetupMode())
|
|
17
|
+
onPress = () => dispatch(toggleSetupMode()),
|
|
18
|
+
buttonClassName = clsx(
|
|
19
|
+
'SetupButton',
|
|
20
|
+
isSetupMode
|
|
21
|
+
? 'bg-red-500 data-[hover=true]:bg-red-600 data-[active=true]:bg-red-700'
|
|
22
|
+
: 'bg-grey-100 data-[hover=true]:bg-grey-900/20 data-[active=true]:bg-grey-900/50',
|
|
23
|
+
),
|
|
24
|
+
textClassName = clsx(
|
|
25
|
+
isSetupMode
|
|
26
|
+
? 'text-white data-[hover=true]:text-white data-[active=true]:text-white'
|
|
27
|
+
: 'text-black data-[hover=true]:text-black data-[active=true]:text-black',
|
|
28
|
+
),
|
|
29
|
+
iconClassName = clsx(
|
|
30
|
+
isSetupMode ? 'fill-white' : 'fill-black',
|
|
31
|
+
isSetupMode ? 'text-white' : 'text-black',
|
|
32
|
+
);
|
|
33
|
+
|
|
17
34
|
return isMinimized ?
|
|
18
35
|
<IconButton
|
|
19
36
|
icon={Gear}
|
|
37
|
+
_icon={{
|
|
38
|
+
className: iconClassName,
|
|
39
|
+
}}
|
|
20
40
|
onPress={onPress}
|
|
21
41
|
tooltip="Toggle Setup Mode"
|
|
22
|
-
className=
|
|
42
|
+
className={buttonClassName}
|
|
23
43
|
/> :
|
|
24
44
|
<Button
|
|
25
45
|
text={isSetupMode ? 'Exit Setup' : 'Setup'}
|
|
26
46
|
icon={Gear}
|
|
47
|
+
_text={{
|
|
48
|
+
className: textClassName,
|
|
49
|
+
}}
|
|
50
|
+
_icon={{
|
|
51
|
+
className: iconClassName,
|
|
52
|
+
}}
|
|
27
53
|
onPress={onPress}
|
|
28
54
|
tooltip="Toggle Setup Mode"
|
|
29
|
-
className=
|
|
55
|
+
className={buttonClassName}
|
|
30
56
|
/>;
|
|
31
57
|
};
|
|
@@ -51,6 +51,7 @@ function Viewer(props) {
|
|
|
51
51
|
const {
|
|
52
52
|
viewerCanDelete = false,
|
|
53
53
|
items = [], // Columns, FieldSets, Fields, etc to define the form
|
|
54
|
+
isItemsCustomLayout = false,
|
|
54
55
|
ancillaryItems = [], // additional items which are not controllable form elements, but should appear in the form
|
|
55
56
|
showAncillaryButtons = false,
|
|
56
57
|
columnDefaults = {}, // defaults for each Column defined in items (above)
|
|
@@ -183,7 +184,7 @@ function Viewer(props) {
|
|
|
183
184
|
let children;
|
|
184
185
|
const style = {};
|
|
185
186
|
if (type === 'Column') {
|
|
186
|
-
const isEverythingInOneColumn = containerWidth < styles.FORM_ONE_COLUMN_THRESHOLD;
|
|
187
|
+
const isEverythingInOneColumn = isItemsCustomLayout || containerWidth < styles.FORM_ONE_COLUMN_THRESHOLD;
|
|
187
188
|
if (itemPropsToPass.hasOwnProperty('flex')) {
|
|
188
189
|
if (!isEverythingInOneColumn) {
|
|
189
190
|
style.flex = itemPropsToPass.flex;
|
|
@@ -489,7 +490,9 @@ function Viewer(props) {
|
|
|
489
490
|
const
|
|
490
491
|
showDeleteBtn = onDelete && viewerCanDelete,
|
|
491
492
|
showCloseBtn = !isSideEditor && !isSmartEditor && onClose,
|
|
492
|
-
showFooter = (showDeleteBtn || showCloseBtn)
|
|
493
|
+
showFooter = (showDeleteBtn || showCloseBtn),
|
|
494
|
+
hasTopLevelColumns = _.some(items, (item) => item?.type === 'Column'),
|
|
495
|
+
shouldUseHorizontalViewerLayout = !isItemsCustomLayout && hasTopLevelColumns && containerWidth >= styles.FORM_ONE_COLUMN_THRESHOLD;
|
|
493
496
|
let additionalButtons = null,
|
|
494
497
|
viewerComponents = null,
|
|
495
498
|
ancillaryComponents = null,
|
|
@@ -611,8 +614,8 @@ function Viewer(props) {
|
|
|
611
614
|
{buildAdditionalButtons(_.omitBy(getAncillaryButtons(), (btnConfig) => btnConfig.reference === 'scrollToTop'))}
|
|
612
615
|
</Toolbar>}
|
|
613
616
|
|
|
614
|
-
{
|
|
615
|
-
{
|
|
617
|
+
{shouldUseHorizontalViewerLayout ? <HStack className="Viewer-formComponents-HStack p-4 gap-4 justify-center">{viewerComponents}</HStack> : null}
|
|
618
|
+
{!shouldUseHorizontalViewerLayout ? <VStack className="Viewer-formComponents-VStack p-4">{viewerComponents}</VStack> : null}
|
|
616
619
|
<VStack className="Viewer-AncillaryComponents m-2 pt-4 px-2">{ancillaryComponents}</VStack>
|
|
617
620
|
</ScrollView>
|
|
618
621
|
|