@saltcorn/builder 0.9.4-beta.9 → 0.9.5-beta.0
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/dist/builder_bundle.js +20 -12
- package/package.json +3 -2
- package/src/components/Builder.js +34 -54
- package/src/components/Library.js +16 -4
- package/src/components/RenderNode.js +5 -0
- package/src/components/Toolbox.js +61 -2
- package/src/components/elements/Action.js +12 -0
- package/src/components/elements/Aggregation.js +200 -104
- package/src/components/elements/BoxModelEditor.js +8 -8
- package/src/components/elements/Column.js +16 -2
- package/src/components/elements/Columns.js +3 -3
- package/src/components/elements/Container.js +25 -1
- package/src/components/elements/DropMenu.js +31 -2
- package/src/components/elements/Field.js +22 -20
- package/src/components/elements/HTMLCode.js +1 -1
- package/src/components/elements/JoinField.js +25 -1
- package/src/components/elements/Link.js +1 -0
- package/src/components/elements/ListColumn.js +177 -0
- package/src/components/elements/ListColumns.js +62 -0
- package/src/components/elements/Tabs.js +26 -0
- package/src/components/elements/Text.js +4 -2
- package/src/components/elements/View.js +37 -32
- package/src/components/elements/ViewLink.js +21 -14
- package/src/components/elements/utils.js +64 -24
- package/src/components/storage.js +65 -5
- package/tests/relations_finder.test.js +1 -0
|
@@ -19,6 +19,7 @@ import faIcons from "./faicons";
|
|
|
19
19
|
import { Columns, ntimes } from "./Columns";
|
|
20
20
|
import Tippy from "@tippyjs/react";
|
|
21
21
|
import { RelationType } from "@saltcorn/common-code";
|
|
22
|
+
import Select from "react-select";
|
|
22
23
|
|
|
23
24
|
export const DynamicFontAwesomeIcon = ({ icon, className }) => {
|
|
24
25
|
if (!icon) return null;
|
|
@@ -139,7 +140,7 @@ export /**
|
|
|
139
140
|
*/
|
|
140
141
|
const OrFormula = ({ setProp, isFormula, node, nodekey, children }) => {
|
|
141
142
|
const { mode } = React.useContext(optionsCtx);
|
|
142
|
-
|
|
143
|
+
const allowFormula = mode === "show" || mode === "list";
|
|
143
144
|
/**
|
|
144
145
|
* @returns {void}
|
|
145
146
|
*/
|
|
@@ -160,14 +161,14 @@ const OrFormula = ({ setProp, isFormula, node, nodekey, children }) => {
|
|
|
160
161
|
});
|
|
161
162
|
};
|
|
162
163
|
let errorString = false;
|
|
163
|
-
if (
|
|
164
|
+
if (allowFormula && isFormula[nodekey]) {
|
|
164
165
|
try {
|
|
165
166
|
Function("return " + node[nodekey]);
|
|
166
167
|
} catch (error) {
|
|
167
168
|
errorString = error.message;
|
|
168
169
|
}
|
|
169
170
|
}
|
|
170
|
-
return
|
|
171
|
+
return !allowFormula ? (
|
|
171
172
|
children
|
|
172
173
|
) : (
|
|
173
174
|
<Fragment>
|
|
@@ -492,6 +493,7 @@ export const fetchViewPreview =
|
|
|
492
493
|
};
|
|
493
494
|
let viewname,
|
|
494
495
|
body = configuration ? { ...configuration } : {};
|
|
496
|
+
if (!view) return "";
|
|
495
497
|
if (view.includes(":")) {
|
|
496
498
|
const [prefix, rest] = view.split(":");
|
|
497
499
|
const tokens = rest.split(".");
|
|
@@ -902,24 +904,51 @@ const ConfigField = ({
|
|
|
902
904
|
spellCheck={false}
|
|
903
905
|
/>
|
|
904
906
|
),
|
|
905
|
-
select: () =>
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
907
|
+
select: () => {
|
|
908
|
+
if (field.class?.includes?.("selectizable")) {
|
|
909
|
+
const seloptions = field.options.map((o, ix) =>
|
|
910
|
+
o.name && o.label
|
|
911
|
+
? { value: o.name, label: o.label }
|
|
912
|
+
: { value: o, label: o }
|
|
913
|
+
);
|
|
914
|
+
return (
|
|
915
|
+
<Select
|
|
916
|
+
options={seloptions}
|
|
917
|
+
value={seloptions.find((so) => value === so.value)}
|
|
918
|
+
onChange={(e) =>
|
|
919
|
+
(e.name && myOnChange(e.name)) ||
|
|
920
|
+
(e.value && myOnChange(e.value)) ||
|
|
921
|
+
(typeof e === "string" && myOnChange(e))
|
|
922
|
+
}
|
|
923
|
+
onBlur={(e) =>
|
|
924
|
+
(e.name && myOnChange(e.name)) ||
|
|
925
|
+
(e.value && myOnChange(e.value)) ||
|
|
926
|
+
(typeof e === "string" && myOnChange(e))
|
|
927
|
+
}
|
|
928
|
+
menuPortalTarget={document.body}
|
|
929
|
+
styles={{ menuPortal: (base) => ({ ...base, zIndex: 19999 }) }}
|
|
930
|
+
></Select>
|
|
931
|
+
);
|
|
932
|
+
} else
|
|
933
|
+
return (
|
|
934
|
+
<select
|
|
935
|
+
className="form-control form-select"
|
|
936
|
+
value={value || ""}
|
|
937
|
+
onChange={(e) => e.target && myOnChange(e.target.value)}
|
|
938
|
+
onBlur={(e) => e.target && myOnChange(e.target.value)}
|
|
939
|
+
>
|
|
940
|
+
{field.options.map((o, ix) =>
|
|
941
|
+
o.name && o.label ? (
|
|
942
|
+
<option key={ix} value={o.name}>
|
|
943
|
+
{o.label}
|
|
944
|
+
</option>
|
|
945
|
+
) : (
|
|
946
|
+
<option key={ix}>{o}</option>
|
|
947
|
+
)
|
|
948
|
+
)}
|
|
949
|
+
</select>
|
|
950
|
+
);
|
|
951
|
+
},
|
|
923
952
|
btn_select: () => (
|
|
924
953
|
<div className="btn-group w-100" role="group">
|
|
925
954
|
{field.options.map((o, ix) => (
|
|
@@ -1017,8 +1046,15 @@ export /**
|
|
|
1017
1046
|
* @returns {table}
|
|
1018
1047
|
*/
|
|
1019
1048
|
const SettingsFromFields =
|
|
1020
|
-
(
|
|
1049
|
+
(fieldsIn, opts = {}) =>
|
|
1021
1050
|
() => {
|
|
1051
|
+
const fields = [...fieldsIn];
|
|
1052
|
+
if (opts.additionalFieldsOptionKey) {
|
|
1053
|
+
const options = React.useContext(optionsCtx);
|
|
1054
|
+
|
|
1055
|
+
const addFields = options[opts.additionalFieldsOptionKey];
|
|
1056
|
+
fields.push(...(addFields || []));
|
|
1057
|
+
}
|
|
1022
1058
|
const node = useNode((node) => {
|
|
1023
1059
|
const ps = {};
|
|
1024
1060
|
fields.forEach((f) => {
|
|
@@ -1258,9 +1294,12 @@ const ButtonOrLinkSettingsRows = ({
|
|
|
1258
1294
|
<option value={addBtnClass("btn-outline-secondary")}>
|
|
1259
1295
|
Secondary outline button
|
|
1260
1296
|
</option>
|
|
1297
|
+
<option value={addBtnClass("btn-outline-danger")}>
|
|
1298
|
+
Danger outline button
|
|
1299
|
+
</option>
|
|
1261
1300
|
<option value={addBtnClass("btn-outline-warning")}>
|
|
1262
1301
|
Warning outline button
|
|
1263
|
-
</option>
|
|
1302
|
+
</option>
|
|
1264
1303
|
<option value={addBtnClass("btn-outline-info")}>
|
|
1265
1304
|
Info outline button
|
|
1266
1305
|
</option>
|
|
@@ -1270,7 +1309,7 @@ const ButtonOrLinkSettingsRows = ({
|
|
|
1270
1309
|
{!linkFirst ? (
|
|
1271
1310
|
<option value={addBtnClass("btn-link")}>Link</option>
|
|
1272
1311
|
) : null}
|
|
1273
|
-
{!linkFirst ? (
|
|
1312
|
+
{!linkFirst && allowRunOnLoad ? (
|
|
1274
1313
|
<option value="on_page_load">Run on Page Load</option>
|
|
1275
1314
|
) : null}
|
|
1276
1315
|
</select>
|
|
@@ -1290,6 +1329,7 @@ const ButtonOrLinkSettingsRows = ({
|
|
|
1290
1329
|
<option value="">Standard</option>
|
|
1291
1330
|
<option value="btn-lg">Large</option>
|
|
1292
1331
|
<option value="btn-sm">Small</option>
|
|
1332
|
+
<option value="btn-sm btn-xs">Extra Small</option>
|
|
1293
1333
|
<option value="btn-block">Block</option>
|
|
1294
1334
|
<option value="btn-block btn-lg">Large block</option>
|
|
1295
1335
|
</select>
|
|
@@ -12,6 +12,8 @@ import { Empty } from "./elements/Empty";
|
|
|
12
12
|
import { Columns, ntimes, sum } from "./elements/Columns";
|
|
13
13
|
import { JoinField } from "./elements/JoinField";
|
|
14
14
|
import { Tabs } from "./elements/Tabs";
|
|
15
|
+
import { ListColumns } from "./elements/ListColumns";
|
|
16
|
+
import { ListColumn } from "./elements/ListColumn";
|
|
15
17
|
import { Table } from "./elements/Table";
|
|
16
18
|
import { Aggregation } from "./elements/Aggregation";
|
|
17
19
|
import { LineBreak } from "./elements/LineBreak";
|
|
@@ -76,6 +78,8 @@ const allElements = [
|
|
|
76
78
|
DropMenu,
|
|
77
79
|
Page,
|
|
78
80
|
Table,
|
|
81
|
+
ListColumn,
|
|
82
|
+
ListColumns,
|
|
79
83
|
];
|
|
80
84
|
|
|
81
85
|
export /**
|
|
@@ -88,7 +92,7 @@ export /**
|
|
|
88
92
|
* @subcategory components
|
|
89
93
|
* @namespace
|
|
90
94
|
*/
|
|
91
|
-
const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
95
|
+
const layoutToNodes = (layout, query, actions, parent = "ROOT", options) => {
|
|
92
96
|
//console.log("layoutToNodes", JSON.stringify(layout));
|
|
93
97
|
/**
|
|
94
98
|
* @param {object} segment
|
|
@@ -129,7 +133,6 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
|
129
133
|
);
|
|
130
134
|
else return <MatchElement key={ix} {...props} />;
|
|
131
135
|
}
|
|
132
|
-
|
|
133
136
|
if (segment.type === "blank") {
|
|
134
137
|
return (
|
|
135
138
|
<Text
|
|
@@ -177,6 +180,7 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
|
177
180
|
step_only_ifs={segment.step_only_ifs || ""}
|
|
178
181
|
step_action_names={segment.step_action_names || ""}
|
|
179
182
|
confirm={segment.confirm}
|
|
183
|
+
spinner={segment.spinner}
|
|
180
184
|
configuration={segment.configuration || {}}
|
|
181
185
|
block={segment.block || false}
|
|
182
186
|
minRole={segment.minRole || 10}
|
|
@@ -200,6 +204,7 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
|
200
204
|
minHeight={segment.minHeight}
|
|
201
205
|
height={segment.height}
|
|
202
206
|
width={segment.width}
|
|
207
|
+
click_action={segment.click_action}
|
|
203
208
|
url={segment.url}
|
|
204
209
|
hoverColor={segment.hoverColor}
|
|
205
210
|
minHeightUnit={segment.minHeightUnit || "px"}
|
|
@@ -258,6 +263,7 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
|
258
263
|
independent={segment.independent}
|
|
259
264
|
startClosed={segment.startClosed}
|
|
260
265
|
deeplink={segment.deeplink}
|
|
266
|
+
acc_init_opens={segment.acc_init_opens}
|
|
261
267
|
disable_inactive={segment.disable_inactive}
|
|
262
268
|
serverRendered={segment.serverRendered}
|
|
263
269
|
tabId={segment.tabId}
|
|
@@ -283,6 +289,27 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
|
283
289
|
)}
|
|
284
290
|
/>
|
|
285
291
|
);
|
|
292
|
+
} else if (segment.besides && segment.list_columns) {
|
|
293
|
+
const addFields = options.additionalColumnFields;
|
|
294
|
+
|
|
295
|
+
return segment.besides.map((col, jx) => {
|
|
296
|
+
const addProps = {};
|
|
297
|
+
(addFields || []).forEach((f) => {
|
|
298
|
+
addProps[f.name] = col[f.name];
|
|
299
|
+
});
|
|
300
|
+
return (
|
|
301
|
+
<ListColumn
|
|
302
|
+
key={jx}
|
|
303
|
+
alignment={col.alignment}
|
|
304
|
+
header_label={col.header_label}
|
|
305
|
+
col_width={col.col_width}
|
|
306
|
+
showif={col.showif}
|
|
307
|
+
col_width_units={col.col_width_units}
|
|
308
|
+
contents={toTag(col.contents)}
|
|
309
|
+
{...addProps}
|
|
310
|
+
></ListColumn>
|
|
311
|
+
);
|
|
312
|
+
});
|
|
286
313
|
} else if (segment.besides) {
|
|
287
314
|
return (
|
|
288
315
|
<Columns
|
|
@@ -317,7 +344,7 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
|
317
344
|
segment.above.forEach((child) => {
|
|
318
345
|
if (child) go(child, parent);
|
|
319
346
|
});
|
|
320
|
-
} else if (segment.besides) {
|
|
347
|
+
} else if (segment.besides && !segment.list_columns) {
|
|
321
348
|
const node = query
|
|
322
349
|
.parseReactElement(
|
|
323
350
|
<Columns
|
|
@@ -339,7 +366,13 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
|
339
366
|
actions.addNodeTree(node, parent);
|
|
340
367
|
} else {
|
|
341
368
|
const tag = toTag(segment);
|
|
342
|
-
if (tag) {
|
|
369
|
+
if (Array.isArray(tag)) {
|
|
370
|
+
tag.forEach((t) => {
|
|
371
|
+
const node = query.parseReactElement(t).toNodeTree();
|
|
372
|
+
//console.log("other", node);
|
|
373
|
+
actions.addNodeTree(node, parent);
|
|
374
|
+
});
|
|
375
|
+
} else if (tag) {
|
|
343
376
|
const node = query.parseReactElement(tag).toNodeTree();
|
|
344
377
|
//console.log("other", node);
|
|
345
378
|
actions.addNodeTree(node, parent);
|
|
@@ -363,7 +396,7 @@ export /**
|
|
|
363
396
|
* @subcategory components
|
|
364
397
|
* @namespace
|
|
365
398
|
*/
|
|
366
|
-
const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
|
|
399
|
+
const craftToSaltcorn = (nodes, startFrom = "ROOT", options) => {
|
|
367
400
|
//console.log(JSON.stringify(nodes, null, 2));
|
|
368
401
|
var columns = [];
|
|
369
402
|
/**
|
|
@@ -415,10 +448,33 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
|
|
|
415
448
|
related.fields.forEach((f) => {
|
|
416
449
|
c[f.column_name || f.name || f] = node.props[f.name || f];
|
|
417
450
|
});
|
|
451
|
+
if (s.isFormula) c.isFormula = s.isFormula;
|
|
418
452
|
columns.push(c);
|
|
419
453
|
}
|
|
420
454
|
return s;
|
|
421
455
|
}
|
|
456
|
+
if (node.displayName === ListColumns.craft.displayName) {
|
|
457
|
+
return {
|
|
458
|
+
besides: node.nodes.map((nm) => go(nodes[nm])),
|
|
459
|
+
list_columns: true,
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
if (node.displayName === ListColumn.craft.displayName) {
|
|
463
|
+
const contents = go(nodes[node.linkedNodes.listcol]);
|
|
464
|
+
const addFields = options.additionalColumnFields;
|
|
465
|
+
const lc = {
|
|
466
|
+
contents,
|
|
467
|
+
col_width: node.props.col_width,
|
|
468
|
+
col_width_units: node.props.col_width_units,
|
|
469
|
+
alignment: node.props.alignment,
|
|
470
|
+
header_label: node.props.header_label,
|
|
471
|
+
showif: node.props.showif,
|
|
472
|
+
};
|
|
473
|
+
(addFields || []).forEach((f) => {
|
|
474
|
+
lc[f.name] = node.props[f.name];
|
|
475
|
+
});
|
|
476
|
+
return lc;
|
|
477
|
+
}
|
|
422
478
|
if (node.isCanvas) {
|
|
423
479
|
if (node.displayName === Container.craft.displayName)
|
|
424
480
|
return {
|
|
@@ -458,6 +514,7 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
|
|
|
458
514
|
gradStartColor: node.props.gradStartColor,
|
|
459
515
|
gradEndColor: node.props.gradEndColor,
|
|
460
516
|
gradDirection: node.props.gradDirection,
|
|
517
|
+
click_action: node.props.click_action,
|
|
461
518
|
rotate: node.props.rotate,
|
|
462
519
|
style: node.props.style,
|
|
463
520
|
};
|
|
@@ -535,6 +592,7 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
|
|
|
535
592
|
field: node.props.field,
|
|
536
593
|
independent: node.props.independent,
|
|
537
594
|
startClosed: node.props.startClosed,
|
|
595
|
+
acc_init_opens: node.props.acc_init_opens,
|
|
538
596
|
deeplink: node.props.deeplink,
|
|
539
597
|
disable_inactive: node.props.disable_inactive,
|
|
540
598
|
serverRendered: node.props.serverRendered,
|
|
@@ -575,6 +633,7 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
|
|
|
575
633
|
action_textcol: node.props.action_textcol,
|
|
576
634
|
minRole: node.props.minRole,
|
|
577
635
|
confirm: node.props.confirm,
|
|
636
|
+
spinner: node.props.spinner,
|
|
578
637
|
nsteps: node.props.nsteps,
|
|
579
638
|
step_only_ifs: node.props.step_only_ifs,
|
|
580
639
|
step_action_names: node.props.step_action_names,
|
|
@@ -587,6 +646,7 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
|
|
|
587
646
|
block: node.props.block,
|
|
588
647
|
configuration: node.props.configuration,
|
|
589
648
|
confirm: node.props.confirm,
|
|
649
|
+
spinner: node.props.spinner,
|
|
590
650
|
action_name: node.props.name,
|
|
591
651
|
...(node.props.name !== "Clear" && node.props.action_row_variable
|
|
592
652
|
? {
|