@saltcorn/builder 1.1.2-beta.8 → 1.1.2-beta.9
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 +1 -1
- package/package.json +2 -2
- package/src/components/Library.js +1 -0
- package/src/components/elements/Action.js +3 -2
- package/src/components/elements/Container.js +76 -25
- package/src/components/elements/DropMenu.js +2 -0
- package/src/components/elements/Image.js +25 -15
- package/src/components/elements/Link.js +2 -0
- package/src/components/elements/ViewLink.js +2 -0
- package/src/components/elements/utils.js +28 -12
- package/src/components/storage.js +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/builder",
|
|
3
|
-
"version": "1.1.2-beta.
|
|
3
|
+
"version": "1.1.2-beta.9",
|
|
4
4
|
"description": "Drag and drop view builder for Saltcorn, open-source no-code platform",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"homepage": "https://saltcorn.com",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@babel/preset-react": "7.24.7",
|
|
21
21
|
"@craftjs/core": "0.1.0-beta.20",
|
|
22
22
|
"@craftjs/utils": "0.1.0-beta.20",
|
|
23
|
-
"@saltcorn/common-code": "1.1.2-beta.
|
|
23
|
+
"@saltcorn/common-code": "1.1.2-beta.9",
|
|
24
24
|
"saltcorn-craft-layers-noeye": "0.1.0-beta.22",
|
|
25
25
|
"@fonticonpicker/react-fonticonpicker": "1.2.0",
|
|
26
26
|
"@fortawesome/fontawesome-svg-core": "1.2.34",
|
|
@@ -110,6 +110,7 @@ const InitNewElement = ({ nodekeys, savingState, setSavingState }) => {
|
|
|
110
110
|
|
|
111
111
|
fetch(`/${urlroot}/savebuilder/${options.page_id || options.view_id}`, {
|
|
112
112
|
method: "POST", // or 'PUT'
|
|
113
|
+
keepalive: true,
|
|
113
114
|
headers: {
|
|
114
115
|
"Content-Type": "application/json",
|
|
115
116
|
"CSRF-Token": options.csrfToken,
|
|
@@ -85,8 +85,7 @@ const Action = ({
|
|
|
85
85
|
};
|
|
86
86
|
|
|
87
87
|
export /**
|
|
88
|
-
* @category saltcorn-builder
|
|
89
|
-
* @subcategory components
|
|
88
|
+
* @category saltcorn-builder * @subcategory components
|
|
90
89
|
* @namespace
|
|
91
90
|
* @returns {div}
|
|
92
91
|
*/
|
|
@@ -108,6 +107,7 @@ const ActionSettings = () => {
|
|
|
108
107
|
action_bgcol: node.data.props.action_bgcol,
|
|
109
108
|
action_bordercol: node.data.props.action_bordercol,
|
|
110
109
|
action_textcol: node.data.props.action_textcol,
|
|
110
|
+
action_class: node.data.props.action_class,
|
|
111
111
|
nsteps: node.data.props.nsteps,
|
|
112
112
|
step_only_ifs: node.data.props.step_only_ifs,
|
|
113
113
|
step_action_names: node.data.props.step_action_names,
|
|
@@ -134,6 +134,7 @@ const ActionSettings = () => {
|
|
|
134
134
|
step_action_names,
|
|
135
135
|
spinner,
|
|
136
136
|
is_submit_action,
|
|
137
|
+
|
|
137
138
|
} = node;
|
|
138
139
|
const options = useContext(optionsCtx);
|
|
139
140
|
const getCfgFields = (fv) => (options.actionConfigForms || {})[fv];
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
AlignBottom,
|
|
37
37
|
SlashCircle,
|
|
38
38
|
Image,
|
|
39
|
+
Images,
|
|
39
40
|
Rainbow,
|
|
40
41
|
Palette,
|
|
41
42
|
EyeFill,
|
|
@@ -194,6 +195,7 @@ const ContainerSettings = () => {
|
|
|
194
195
|
bgColor: node.data.props.bgColor,
|
|
195
196
|
isFormula: node.data.props.isFormula,
|
|
196
197
|
bgFileId: node.data.props.bgFileId,
|
|
198
|
+
bgField: node.data.props.bgField,
|
|
197
199
|
imageSize: node.data.props.imageSize,
|
|
198
200
|
htmlElement: node.data.props.htmlElement,
|
|
199
201
|
vAlign: node.data.props.vAlign,
|
|
@@ -260,6 +262,7 @@ const ContainerSettings = () => {
|
|
|
260
262
|
click_action,
|
|
261
263
|
style,
|
|
262
264
|
transform,
|
|
265
|
+
bgField,
|
|
263
266
|
} = node;
|
|
264
267
|
const options = useContext(optionsCtx);
|
|
265
268
|
const { uploadedFiles } = useContext(previewCtx);
|
|
@@ -340,6 +343,17 @@ const ContainerSettings = () => {
|
|
|
340
343
|
node={node}
|
|
341
344
|
setProp={setProp}
|
|
342
345
|
/>
|
|
346
|
+
<SettingsRow
|
|
347
|
+
field={{
|
|
348
|
+
name: "opacity",
|
|
349
|
+
label: "Opacity",
|
|
350
|
+
type: "Float",
|
|
351
|
+
attributes: { min: 0, max: 1 },
|
|
352
|
+
}}
|
|
353
|
+
node={node}
|
|
354
|
+
setProp={setProp}
|
|
355
|
+
isStyle={true}
|
|
356
|
+
/>
|
|
343
357
|
<SettingsRow
|
|
344
358
|
field={{
|
|
345
359
|
name: "position",
|
|
@@ -462,6 +476,9 @@ const ContainerSettings = () => {
|
|
|
462
476
|
options: [
|
|
463
477
|
{ value: "None", label: <SlashCircle /> },
|
|
464
478
|
{ value: "Image", label: <Image /> },
|
|
479
|
+
...(options.mode === "show"
|
|
480
|
+
? [{ value: "Image Field", label: <Images /> }]
|
|
481
|
+
: []),
|
|
465
482
|
{ value: "Color", label: <Palette /> },
|
|
466
483
|
{ value: "Gradient", label: <Rainbow /> },
|
|
467
484
|
],
|
|
@@ -532,30 +549,59 @@ const ContainerSettings = () => {
|
|
|
532
549
|
</Fragment>
|
|
533
550
|
)}
|
|
534
551
|
{bgType === "Image" && (
|
|
535
|
-
<
|
|
536
|
-
<
|
|
537
|
-
<
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
<
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
{
|
|
547
|
-
|
|
548
|
-
|
|
552
|
+
<tr>
|
|
553
|
+
<td>
|
|
554
|
+
<label>File</label>
|
|
555
|
+
</td>
|
|
556
|
+
<td>
|
|
557
|
+
<select
|
|
558
|
+
value={bgFileId}
|
|
559
|
+
className="form-control-sm w-100 form-select"
|
|
560
|
+
onChange={setAProp("bgFileId")}
|
|
561
|
+
>
|
|
562
|
+
{options.images.map((f, ix) => (
|
|
563
|
+
<option key={ix} value={f.id}>
|
|
564
|
+
{f.filename}
|
|
565
|
+
</option>
|
|
566
|
+
))}
|
|
567
|
+
{(uploadedFiles || []).map((uf, ix) => (
|
|
568
|
+
<option key={ix} value={uf.id}>
|
|
569
|
+
{uf.filename}
|
|
570
|
+
</option>
|
|
571
|
+
))}{" "}
|
|
572
|
+
</select>
|
|
573
|
+
</td>
|
|
574
|
+
</tr>
|
|
575
|
+
)}
|
|
576
|
+
{bgType === "Image Field" && (
|
|
577
|
+
<tr>
|
|
578
|
+
<td>
|
|
579
|
+
<label>File field</label>
|
|
580
|
+
</td>
|
|
581
|
+
<td>
|
|
582
|
+
<select
|
|
583
|
+
value={bgField}
|
|
584
|
+
className="form-control-sm w-100 form-select"
|
|
585
|
+
onChange={setAProp("bgField")}
|
|
586
|
+
>
|
|
587
|
+
{options.fields
|
|
588
|
+
.filter(
|
|
589
|
+
(f) =>
|
|
590
|
+
f.type === "String" ||
|
|
591
|
+
(f.type && f.type.name === "String") ||
|
|
592
|
+
(f.type && f.type === "File")
|
|
593
|
+
)
|
|
594
|
+
.map((f, ix) => (
|
|
595
|
+
<option key={ix} value={f.name}>
|
|
596
|
+
{f.label}
|
|
549
597
|
</option>
|
|
550
598
|
))}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
</td>
|
|
558
|
-
</tr>
|
|
599
|
+
</select>
|
|
600
|
+
</td>
|
|
601
|
+
</tr>
|
|
602
|
+
)}
|
|
603
|
+
{(bgType === "Image" || bgType === "Image Field") && (
|
|
604
|
+
<Fragment>
|
|
559
605
|
<tr>
|
|
560
606
|
<td>
|
|
561
607
|
<label>Size</label>
|
|
@@ -863,7 +909,7 @@ const ContainerSettings = () => {
|
|
|
863
909
|
name: "animateName",
|
|
864
910
|
label: "Animation",
|
|
865
911
|
type: "select",
|
|
866
|
-
options: ["None", ...options.keyframes || []],
|
|
912
|
+
options: ["None", ...(options.keyframes || [])],
|
|
867
913
|
}}
|
|
868
914
|
node={node}
|
|
869
915
|
setProp={setProp}
|
|
@@ -882,8 +928,12 @@ const ContainerSettings = () => {
|
|
|
882
928
|
node={node}
|
|
883
929
|
setProp={setProp}
|
|
884
930
|
/>
|
|
885
|
-
|
|
886
|
-
field={{
|
|
931
|
+
<SettingsRow
|
|
932
|
+
field={{
|
|
933
|
+
name: "animateInitialHide",
|
|
934
|
+
label: "Initially hidden",
|
|
935
|
+
type: "Bool",
|
|
936
|
+
}}
|
|
887
937
|
node={node}
|
|
888
938
|
setProp={setProp}
|
|
889
939
|
/>
|
|
@@ -1086,6 +1136,7 @@ Container.craft = {
|
|
|
1086
1136
|
vAlign: "top",
|
|
1087
1137
|
hAlign: "left",
|
|
1088
1138
|
bgFileId: 0,
|
|
1139
|
+
bgField: "",
|
|
1089
1140
|
rotate: 0,
|
|
1090
1141
|
isFormula: {},
|
|
1091
1142
|
bgType: "None",
|
|
@@ -99,6 +99,7 @@ const DropMenuSettings = () => {
|
|
|
99
99
|
action_style: node.data.props.action_style,
|
|
100
100
|
action_size: node.data.props.action_size,
|
|
101
101
|
action_title: node.data.props.action_title,
|
|
102
|
+
action_class: node.data.props.action_class,
|
|
102
103
|
action_icon: node.data.props.action_icon,
|
|
103
104
|
action_bgcol: node.data.props.action_bgcol,
|
|
104
105
|
action_bordercol: node.data.props.action_bordercol,
|
|
@@ -182,6 +183,7 @@ DropMenu.craft = {
|
|
|
182
183
|
"action_icon",
|
|
183
184
|
"action_bgcol",
|
|
184
185
|
"action_title",
|
|
186
|
+
"action_class",
|
|
185
187
|
"action_bordercol",
|
|
186
188
|
"action_textcol",
|
|
187
189
|
"menu_direction",
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
OrFormula,
|
|
19
19
|
setAPropGen,
|
|
20
20
|
buildOptions,
|
|
21
|
+
SettingsRow,
|
|
21
22
|
} from "./utils";
|
|
22
23
|
|
|
23
24
|
export /**
|
|
@@ -38,21 +39,19 @@ const Image = ({ fileid, block, srctype, url, alt, style }) => {
|
|
|
38
39
|
connectors: { connect, drag },
|
|
39
40
|
} = useNode((node) => ({ selected: node.events.selected }));
|
|
40
41
|
const theurl = srctype === "File" ? `/files/serve/${fileid}` : url;
|
|
41
|
-
return (
|
|
42
|
-
<span
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
)}
|
|
55
|
-
</span>
|
|
42
|
+
return fileid === 0 ? (
|
|
43
|
+
<span>No images Available</span>
|
|
44
|
+
) : (
|
|
45
|
+
<img
|
|
46
|
+
{...blockProps(block)}
|
|
47
|
+
ref={(dom) => connect(drag(dom))}
|
|
48
|
+
className={`${style && style.width ? "" : "w-100"} image-widget ${
|
|
49
|
+
selected ? "selected-node" : ""
|
|
50
|
+
}`}
|
|
51
|
+
style={reactifyStyles(style || {})}
|
|
52
|
+
src={theurl}
|
|
53
|
+
alt={alt}
|
|
54
|
+
></img>
|
|
56
55
|
);
|
|
57
56
|
};
|
|
58
57
|
|
|
@@ -274,6 +273,17 @@ const ImageSettings = () => {
|
|
|
274
273
|
</td>
|
|
275
274
|
</tr>
|
|
276
275
|
)}
|
|
276
|
+
<SettingsRow
|
|
277
|
+
field={{
|
|
278
|
+
name: "object-fit",
|
|
279
|
+
label: "Object fit",
|
|
280
|
+
type: "select",
|
|
281
|
+
options: ["none", "fill", "contain", "cover", "scale-down"],
|
|
282
|
+
}}
|
|
283
|
+
node={node}
|
|
284
|
+
setProp={setProp}
|
|
285
|
+
isStyle={true}
|
|
286
|
+
/>
|
|
277
287
|
{srctype !== "Upload" && (
|
|
278
288
|
<tr>
|
|
279
289
|
<td colSpan="2">
|
|
@@ -108,6 +108,7 @@ const LinkSettings = () => {
|
|
|
108
108
|
link_style: node.data.props.link_style,
|
|
109
109
|
link_size: node.data.props.link_size,
|
|
110
110
|
link_title: node.data.props.link_title,
|
|
111
|
+
link_class: node.data.props.link_class,
|
|
111
112
|
link_icon: node.data.props.link_icon,
|
|
112
113
|
link_bgcol: node.data.props.link_bgcol,
|
|
113
114
|
link_bordercol: node.data.props.link_bordercol,
|
|
@@ -392,6 +393,7 @@ Link.craft = {
|
|
|
392
393
|
"link_icon",
|
|
393
394
|
"link_style",
|
|
394
395
|
"link_title",
|
|
396
|
+
"link_class",
|
|
395
397
|
"link_bgcol",
|
|
396
398
|
"link_bordercol",
|
|
397
399
|
"link_textcol",
|
|
@@ -114,6 +114,7 @@ const ViewLinkSettings = () => {
|
|
|
114
114
|
link_size: node.data.props.link_size,
|
|
115
115
|
link_icon: node.data.props.link_icon,
|
|
116
116
|
link_title: node.data.props.link_title,
|
|
117
|
+
link_class: node.data.props.link_class,
|
|
117
118
|
textStyle: node.data.props.textStyle,
|
|
118
119
|
link_bgcol: node.data.props.link_bgcol,
|
|
119
120
|
link_bordercol: node.data.props.link_bordercol,
|
|
@@ -403,6 +404,7 @@ ViewLink.craft = {
|
|
|
403
404
|
"link_icon",
|
|
404
405
|
"link_size",
|
|
405
406
|
"link_title",
|
|
407
|
+
"link_class",
|
|
406
408
|
"link_target_blank",
|
|
407
409
|
"link_bgcol",
|
|
408
410
|
"link_bordercol",
|
|
@@ -993,6 +993,8 @@ const ConfigField = ({
|
|
|
993
993
|
className={`field-${field?.name} form-control`}
|
|
994
994
|
value={value || ""}
|
|
995
995
|
step={0.01}
|
|
996
|
+
max={or_if_undef(field?.attributes?.max, undefined)}
|
|
997
|
+
min={or_if_undef(field?.attributes?.min, undefined)}
|
|
996
998
|
onChange={(e) => e.target && myOnChange(e.target.value)}
|
|
997
999
|
/>
|
|
998
1000
|
),
|
|
@@ -1543,18 +1545,32 @@ const ButtonOrLinkSettingsRows = ({
|
|
|
1543
1545
|
]
|
|
1544
1546
|
: []),
|
|
1545
1547
|
values[keyPrefix + "style"] !== "on_page_load" ? (
|
|
1546
|
-
<
|
|
1547
|
-
<
|
|
1548
|
-
<
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
<
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1548
|
+
<Fragment>
|
|
1549
|
+
<tr key="btntitle">
|
|
1550
|
+
<td>
|
|
1551
|
+
<label>Hover title</label>
|
|
1552
|
+
</td>
|
|
1553
|
+
<td>
|
|
1554
|
+
<input
|
|
1555
|
+
className="form-control linkoractiontitle"
|
|
1556
|
+
value={values[keyPrefix + "title"]}
|
|
1557
|
+
onChange={setAProp(keyPrefix + "title")}
|
|
1558
|
+
/>
|
|
1559
|
+
</td>
|
|
1560
|
+
</tr>
|
|
1561
|
+
<tr key="btnclass">
|
|
1562
|
+
<td>
|
|
1563
|
+
<label>Class</label>
|
|
1564
|
+
</td>
|
|
1565
|
+
<td>
|
|
1566
|
+
<input
|
|
1567
|
+
className="form-control linkoractionclass"
|
|
1568
|
+
value={values[keyPrefix + "class"]}
|
|
1569
|
+
onChange={setAProp(keyPrefix + "class")}
|
|
1570
|
+
/>
|
|
1571
|
+
</td>
|
|
1572
|
+
</tr>
|
|
1573
|
+
</Fragment>
|
|
1558
1574
|
) : null,
|
|
1559
1575
|
];
|
|
1560
1576
|
};
|
|
@@ -194,6 +194,7 @@ const layoutToNodes = (
|
|
|
194
194
|
action_size={segment.action_size || ""}
|
|
195
195
|
action_icon={segment.action_icon || ""}
|
|
196
196
|
action_title={segment.action_title || ""}
|
|
197
|
+
action_class={segment.action_class || ""}
|
|
197
198
|
action_bgcol={segment.action_bgcol || ""}
|
|
198
199
|
action_bordercol={segment.action_bordercol || ""}
|
|
199
200
|
action_textcol={segment.action_textcol || ""}
|
|
@@ -255,6 +256,7 @@ const layoutToNodes = (
|
|
|
255
256
|
: segment.fullPageWidth
|
|
256
257
|
}
|
|
257
258
|
bgFileId={segment.bgFileId}
|
|
259
|
+
bgField={segment.bgField}
|
|
258
260
|
imageSize={segment.imageSize || "contain"}
|
|
259
261
|
imgResponsiveWidths={segment.imgResponsiveWidths}
|
|
260
262
|
bgType={segment.bgType || "None"}
|
|
@@ -544,6 +546,7 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT", options) => {
|
|
|
544
546
|
display: node.props.display,
|
|
545
547
|
fullPageWidth: node.props.fullPageWidth || false,
|
|
546
548
|
bgFileId: node.props.bgFileId,
|
|
549
|
+
bgField: node.props.bgField,
|
|
547
550
|
bgType: node.props.bgType,
|
|
548
551
|
imageSize: node.props.imageSize,
|
|
549
552
|
imgResponsiveWidths: node.props.imgResponsiveWidths,
|
|
@@ -683,6 +686,7 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT", options) => {
|
|
|
683
686
|
action_size: node.props.action_size,
|
|
684
687
|
action_icon: node.props.action_icon,
|
|
685
688
|
action_title: node.props.action_title,
|
|
689
|
+
action_class: node.props.action_class,
|
|
686
690
|
action_bgcol: node.props.action_bgcol,
|
|
687
691
|
action_bordercol: node.props.action_bordercol,
|
|
688
692
|
action_textcol: node.props.action_textcol,
|
|
@@ -715,7 +719,9 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT", options) => {
|
|
|
715
719
|
action_size: node.props.action_size,
|
|
716
720
|
action_icon: node.props.action_icon,
|
|
717
721
|
action_title: node.props.action_title,
|
|
722
|
+
action_class: node.props.action_class,
|
|
718
723
|
action_bgcol: node.props.action_bgcol,
|
|
724
|
+
spinner: node.props.spinner,
|
|
719
725
|
action_bordercol: node.props.action_bordercol,
|
|
720
726
|
action_textcol: node.props.action_textcol,
|
|
721
727
|
nsteps: node.props.nsteps,
|