@saltcorn/builder 0.7.1-beta.2 → 0.7.2-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 +7 -7
- package/package.json +1 -1
- package/src/components/elements/Container.js +22 -0
- package/src/components/elements/Field.js +19 -13
- package/src/components/elements/Image.js +24 -0
- package/src/components/elements/Link.js +15 -0
- package/src/components/elements/View.js +16 -0
- package/src/components/elements/ViewLink.js +18 -1
- package/src/components/elements/utils.js +48 -41
- package/src/components/storage.js +4 -0
package/package.json
CHANGED
|
@@ -229,6 +229,7 @@ const ContainerSettings = () => {
|
|
|
229
229
|
rotate: node.data.props.rotate,
|
|
230
230
|
display: node.data.props.display,
|
|
231
231
|
style: node.data.props.style,
|
|
232
|
+
imgResponsiveWidths: node.data.props.imgResponsiveWidths,
|
|
232
233
|
}));
|
|
233
234
|
const {
|
|
234
235
|
actions: { setProp },
|
|
@@ -257,6 +258,7 @@ const ContainerSettings = () => {
|
|
|
257
258
|
fullPageWidth,
|
|
258
259
|
overflow,
|
|
259
260
|
htmlElement,
|
|
261
|
+
imgResponsiveWidths,
|
|
260
262
|
} = node;
|
|
261
263
|
const options = useContext(optionsCtx);
|
|
262
264
|
const { uploadedFiles } = useContext(previewCtx);
|
|
@@ -520,6 +522,26 @@ const ContainerSettings = () => {
|
|
|
520
522
|
</select>
|
|
521
523
|
</td>
|
|
522
524
|
</tr>
|
|
525
|
+
{imageSize !== "repeat" && (
|
|
526
|
+
<tr>
|
|
527
|
+
<td>
|
|
528
|
+
<label>Responsive widths</label>
|
|
529
|
+
</td>
|
|
530
|
+
|
|
531
|
+
<td>
|
|
532
|
+
<input
|
|
533
|
+
type="text"
|
|
534
|
+
value={imgResponsiveWidths}
|
|
535
|
+
className="form-control"
|
|
536
|
+
onChange={setAProp("imgResponsiveWidths")}
|
|
537
|
+
/>
|
|
538
|
+
<small>
|
|
539
|
+
<i>List of widths to serve resized images,
|
|
540
|
+
e.g. 300, 400, 600</i>
|
|
541
|
+
</small>
|
|
542
|
+
</td>
|
|
543
|
+
</tr>
|
|
544
|
+
)}
|
|
523
545
|
</Fragment>
|
|
524
546
|
)}
|
|
525
547
|
{bgType === "Color" && (
|
|
@@ -46,7 +46,8 @@ const Field = ({
|
|
|
46
46
|
const { previews, setPreviews } = useContext(previewCtx);
|
|
47
47
|
const myPreview = previews[node_id];
|
|
48
48
|
const options = useContext(optionsCtx);
|
|
49
|
-
|
|
49
|
+
const blockDisplays = (options.blockDisplay || {})[name];
|
|
50
|
+
const blockDisplay = blockDisplays && blockDisplays.includes(fieldview);
|
|
50
51
|
useEffect(() => {
|
|
51
52
|
fetchFieldPreview({
|
|
52
53
|
options,
|
|
@@ -60,7 +61,9 @@ const Field = ({
|
|
|
60
61
|
return (
|
|
61
62
|
<div
|
|
62
63
|
className={`${textStyle} ${selected ? "selected-node" : ""} ${
|
|
63
|
-
isBlock(block, inline, textStyle)
|
|
64
|
+
isBlock(block, inline, textStyle) || blockDisplay
|
|
65
|
+
? "d-block"
|
|
66
|
+
: "d-inline-block"
|
|
64
67
|
}`}
|
|
65
68
|
ref={(dom) => connect(drag(dom))}
|
|
66
69
|
>
|
|
@@ -106,6 +109,7 @@ const FieldSettings = () => {
|
|
|
106
109
|
|
|
107
110
|
const fvs = options.field_view_options[name];
|
|
108
111
|
const handlesTextStyle = (options.handlesTextStyle || {})[name];
|
|
112
|
+
const blockDisplay = (options.blockDisplay || {})[name];
|
|
109
113
|
const getCfgFields = (fv) =>
|
|
110
114
|
((options.fieldViewConfigForms || {})[name] || {})[fv];
|
|
111
115
|
const cfgFields = getCfgFields(fieldview);
|
|
@@ -184,17 +188,19 @@ const FieldSettings = () => {
|
|
|
184
188
|
</td>
|
|
185
189
|
</tr>
|
|
186
190
|
)}
|
|
187
|
-
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
<
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
191
|
+
{!(blockDisplay && blockDisplay.includes(fieldview)) && (
|
|
192
|
+
<tr>
|
|
193
|
+
<td></td>
|
|
194
|
+
<td>
|
|
195
|
+
<BlockOrInlineSetting
|
|
196
|
+
block={block}
|
|
197
|
+
inline={inline}
|
|
198
|
+
textStyle={textStyle}
|
|
199
|
+
setProp={setProp}
|
|
200
|
+
/>
|
|
201
|
+
</td>
|
|
202
|
+
</tr>
|
|
203
|
+
)}
|
|
198
204
|
{!(handlesTextStyle && handlesTextStyle.includes(fieldview)) && (
|
|
199
205
|
<TextStyleRow textStyle={textStyle} setProp={setProp} />
|
|
200
206
|
)}
|
|
@@ -71,6 +71,7 @@ const ImageSettings = () => {
|
|
|
71
71
|
block: node.data.props.block,
|
|
72
72
|
style: node.data.props.style,
|
|
73
73
|
isFormula: node.data.props.isFormula,
|
|
74
|
+
imgResponsiveWidths: node.data.props.imgResponsiveWidths,
|
|
74
75
|
}));
|
|
75
76
|
const {
|
|
76
77
|
actions: { setProp },
|
|
@@ -82,6 +83,7 @@ const ImageSettings = () => {
|
|
|
82
83
|
block,
|
|
83
84
|
isFormula,
|
|
84
85
|
filepath,
|
|
86
|
+
imgResponsiveWidths,
|
|
85
87
|
style,
|
|
86
88
|
} = node;
|
|
87
89
|
const options = useContext(optionsCtx);
|
|
@@ -252,6 +254,27 @@ const ImageSettings = () => {
|
|
|
252
254
|
</td>
|
|
253
255
|
</tr>
|
|
254
256
|
)}
|
|
257
|
+
{srctype !== "Upload" && (
|
|
258
|
+
<tr>
|
|
259
|
+
<td>
|
|
260
|
+
<label>Responsive widths</label>
|
|
261
|
+
</td>
|
|
262
|
+
|
|
263
|
+
<td>
|
|
264
|
+
<input
|
|
265
|
+
type="text"
|
|
266
|
+
value={imgResponsiveWidths}
|
|
267
|
+
className="form-control"
|
|
268
|
+
onChange={setAProp("imgResponsiveWidths")}
|
|
269
|
+
/>
|
|
270
|
+
<small>
|
|
271
|
+
<i>
|
|
272
|
+
List of widths to serve resized images, e.g. 300, 400, 600
|
|
273
|
+
</i>
|
|
274
|
+
</small>
|
|
275
|
+
</td>
|
|
276
|
+
</tr>
|
|
277
|
+
)}
|
|
255
278
|
{srctype !== "Upload" && (
|
|
256
279
|
<tr>
|
|
257
280
|
<td colSpan="2">
|
|
@@ -290,6 +313,7 @@ Image.craft = {
|
|
|
290
313
|
{ name: "fileid", default: 0 },
|
|
291
314
|
"field",
|
|
292
315
|
"block",
|
|
316
|
+
"imgResponsiveWidths",
|
|
293
317
|
{ name: "style", default: {} },
|
|
294
318
|
],
|
|
295
319
|
},
|
|
@@ -86,6 +86,7 @@ const LinkSettings = () => {
|
|
|
86
86
|
isFormula: node.data.props.isFormula,
|
|
87
87
|
textStyle: node.data.props.textStyle,
|
|
88
88
|
nofollow: node.data.props.nofollow,
|
|
89
|
+
in_modal: node.data.props.in_modal,
|
|
89
90
|
link_src: node.data.props.link_src,
|
|
90
91
|
target_blank: node.data.props.target_blank,
|
|
91
92
|
link_style: node.data.props.link_style,
|
|
@@ -105,6 +106,7 @@ const LinkSettings = () => {
|
|
|
105
106
|
nofollow,
|
|
106
107
|
target_blank,
|
|
107
108
|
link_src,
|
|
109
|
+
in_modal,
|
|
108
110
|
} = node;
|
|
109
111
|
const options = useContext(optionsCtx);
|
|
110
112
|
const setAProp = (key) => (e) => {
|
|
@@ -247,6 +249,18 @@ const LinkSettings = () => {
|
|
|
247
249
|
/>
|
|
248
250
|
<label className="form-check-label">Open in new tab</label>
|
|
249
251
|
</div>
|
|
252
|
+
<div className="form-check">
|
|
253
|
+
<input
|
|
254
|
+
className="form-check-input"
|
|
255
|
+
name="block"
|
|
256
|
+
type="checkbox"
|
|
257
|
+
checked={in_modal}
|
|
258
|
+
onChange={(e) =>
|
|
259
|
+
setProp((prop) => (prop.in_modal = e.target.checked))
|
|
260
|
+
}
|
|
261
|
+
/>
|
|
262
|
+
<label className="form-check-label">Open in popup modal?</label>
|
|
263
|
+
</div>
|
|
250
264
|
<BlockSetting block={block} setProp={setProp} />
|
|
251
265
|
<TextStyleSetting textStyle={textStyle} setProp={setProp} />
|
|
252
266
|
</div>
|
|
@@ -285,6 +299,7 @@ Link.craft = {
|
|
|
285
299
|
"link_bgcol",
|
|
286
300
|
"link_bordercol",
|
|
287
301
|
"link_textcol",
|
|
302
|
+
"in_modal",
|
|
288
303
|
],
|
|
289
304
|
},
|
|
290
305
|
};
|
|
@@ -79,6 +79,7 @@ const ViewSettings = () => {
|
|
|
79
79
|
name: node.data.props.name,
|
|
80
80
|
view: node.data.props.view,
|
|
81
81
|
state: node.data.props.state,
|
|
82
|
+
extra_state_fml: node.data.props.extra_state_fml,
|
|
82
83
|
configuration: node.data.props.configuration, // fixed states
|
|
83
84
|
node_id: node.id,
|
|
84
85
|
}));
|
|
@@ -90,6 +91,7 @@ const ViewSettings = () => {
|
|
|
90
91
|
state,
|
|
91
92
|
node_id,
|
|
92
93
|
configuration,
|
|
94
|
+
extra_state_fml,
|
|
93
95
|
} = node;
|
|
94
96
|
const options = useContext(optionsCtx);
|
|
95
97
|
const views = options.views;
|
|
@@ -149,6 +151,20 @@ const ViewSettings = () => {
|
|
|
149
151
|
)}
|
|
150
152
|
</Fragment>
|
|
151
153
|
)}
|
|
154
|
+
{(state === "shared" || options.mode === "page") && (
|
|
155
|
+
<Fragment>
|
|
156
|
+
{" "}
|
|
157
|
+
<label>Extra state Formula</label>
|
|
158
|
+
<input
|
|
159
|
+
type="text"
|
|
160
|
+
className="viewlink-label form-control"
|
|
161
|
+
value={extra_state_fml}
|
|
162
|
+
onChange={(e) =>
|
|
163
|
+
setProp((prop) => (prop.extra_state_fml = e.target.value))
|
|
164
|
+
}
|
|
165
|
+
/>
|
|
166
|
+
</Fragment>
|
|
167
|
+
)}
|
|
152
168
|
{view ? (
|
|
153
169
|
<a
|
|
154
170
|
className="d-block mt-2"
|
|
@@ -33,7 +33,7 @@ export /**
|
|
|
33
33
|
* @returns {tr}
|
|
34
34
|
* @category saltcorn-builder
|
|
35
35
|
* @subcategory components
|
|
36
|
-
* @namespace
|
|
36
|
+
* @namespace
|
|
37
37
|
*/
|
|
38
38
|
const ViewLink = ({
|
|
39
39
|
name,
|
|
@@ -99,6 +99,7 @@ const ViewLinkSettings = () => {
|
|
|
99
99
|
link_bgcol: node.data.props.link_bgcol,
|
|
100
100
|
link_bordercol: node.data.props.link_bordercol,
|
|
101
101
|
link_textcol: node.data.props.link_textcol,
|
|
102
|
+
extra_state_fml: node.data.props.extra_state_fml,
|
|
102
103
|
}));
|
|
103
104
|
const {
|
|
104
105
|
actions: { setProp },
|
|
@@ -109,6 +110,7 @@ const ViewLinkSettings = () => {
|
|
|
109
110
|
isFormula,
|
|
110
111
|
inModal,
|
|
111
112
|
textStyle,
|
|
113
|
+
extra_state_fml,
|
|
112
114
|
} = node;
|
|
113
115
|
const options = useContext(optionsCtx);
|
|
114
116
|
return (
|
|
@@ -148,6 +150,20 @@ const ViewLinkSettings = () => {
|
|
|
148
150
|
</OrFormula>
|
|
149
151
|
</td>
|
|
150
152
|
</tr>
|
|
153
|
+
<tr>
|
|
154
|
+
<td colSpan="2">
|
|
155
|
+
<label>Extra state Formula</label>
|
|
156
|
+
<input
|
|
157
|
+
type="text"
|
|
158
|
+
className="viewlink-label form-control"
|
|
159
|
+
value={extra_state_fml}
|
|
160
|
+
onChange={(e) =>
|
|
161
|
+
setProp((prop) => (prop.extra_state_fml = e.target.value))
|
|
162
|
+
}
|
|
163
|
+
/>
|
|
164
|
+
</td>
|
|
165
|
+
</tr>
|
|
166
|
+
|
|
151
167
|
<ButtonOrLinkSettingsRows
|
|
152
168
|
setProp={setProp}
|
|
153
169
|
keyPrefix="link_"
|
|
@@ -203,6 +219,7 @@ ViewLink.craft = {
|
|
|
203
219
|
"link_bgcol",
|
|
204
220
|
"link_bordercol",
|
|
205
221
|
"link_textcol",
|
|
222
|
+
"extra_state_fml",
|
|
206
223
|
],
|
|
207
224
|
},
|
|
208
225
|
};
|
|
@@ -387,53 +387,57 @@ const fetchPreview = ({ url, body, options, setPreviews, node_id, isView }) => {
|
|
|
387
387
|
* @param {object} [args = {}]
|
|
388
388
|
* @return {function}
|
|
389
389
|
*/
|
|
390
|
-
export const fetchFieldPreview =
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
390
|
+
export const fetchFieldPreview =
|
|
391
|
+
(args = {}) =>
|
|
392
|
+
(changes = {}) => {
|
|
393
|
+
const { node_id, options, name, fieldview, setPreviews } = {
|
|
394
|
+
...args,
|
|
395
|
+
...changes,
|
|
396
|
+
};
|
|
397
|
+
const configuration = {
|
|
398
|
+
...(args.configuration || {}),
|
|
399
|
+
...(changes.configuration || {}),
|
|
400
|
+
};
|
|
401
|
+
fetchPreview({
|
|
402
|
+
options,
|
|
403
|
+
node_id,
|
|
404
|
+
setPreviews,
|
|
405
|
+
url: `/field/preview/${options.tableName}/${name}/${fieldview}`,
|
|
406
|
+
body: { configuration },
|
|
407
|
+
});
|
|
398
408
|
};
|
|
399
|
-
fetchPreview({
|
|
400
|
-
options,
|
|
401
|
-
node_id,
|
|
402
|
-
setPreviews,
|
|
403
|
-
url: `/field/preview/${options.tableName}/${name}/${fieldview}`,
|
|
404
|
-
body: { configuration },
|
|
405
|
-
});
|
|
406
|
-
};
|
|
407
409
|
|
|
408
410
|
/**
|
|
409
411
|
* @function
|
|
410
412
|
* @param {object} [args = {}]
|
|
411
413
|
* @return {function}
|
|
412
414
|
*/
|
|
413
|
-
export const fetchViewPreview =
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
415
|
+
export const fetchViewPreview =
|
|
416
|
+
(args = {}) =>
|
|
417
|
+
(changes = {}) => {
|
|
418
|
+
const { node_id, options, view, setPreviews, configuration } = {
|
|
419
|
+
...args,
|
|
420
|
+
...changes,
|
|
421
|
+
};
|
|
422
|
+
let viewname,
|
|
423
|
+
body = configuration ? { ...configuration } : {};
|
|
424
|
+
if (view.includes(":")) {
|
|
425
|
+
const [reltype, rest] = view.split(":");
|
|
426
|
+
const [vnm] = rest.split(".");
|
|
427
|
+
viewname = vnm;
|
|
428
|
+
body.reltype = reltype;
|
|
429
|
+
body.path = rest;
|
|
430
|
+
} else viewname = view;
|
|
427
431
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
};
|
|
432
|
+
fetchPreview({
|
|
433
|
+
options,
|
|
434
|
+
node_id,
|
|
435
|
+
setPreviews,
|
|
436
|
+
url: `/view/${viewname}/preview`,
|
|
437
|
+
body,
|
|
438
|
+
isView: true,
|
|
439
|
+
});
|
|
440
|
+
};
|
|
437
441
|
|
|
438
442
|
export /**
|
|
439
443
|
* @param {object} props
|
|
@@ -650,8 +654,11 @@ const ConfigField = ({
|
|
|
650
654
|
if (field.input_type === "fromtype") field.input_type = null;
|
|
651
655
|
if (field.type && field.type.name === "String" && field.attributes.options) {
|
|
652
656
|
field.input_type = "select";
|
|
653
|
-
field.options =
|
|
654
|
-
|
|
657
|
+
field.options =
|
|
658
|
+
typeof field.attributes.options === "string"
|
|
659
|
+
? field.attributes.options.split(",").map((s) => s.trim())
|
|
660
|
+
: field.attributes.options;
|
|
661
|
+
if (!field.required && field.options) field.options.unshift("");
|
|
655
662
|
}
|
|
656
663
|
const dispatch = {
|
|
657
664
|
String() {
|
|
@@ -142,6 +142,7 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
|
142
142
|
view={segment.view}
|
|
143
143
|
name={segment.name}
|
|
144
144
|
state={segment.state}
|
|
145
|
+
extra_state_fml={segment.extra_state_fml}
|
|
145
146
|
configuration={segment.configuration || {}}
|
|
146
147
|
/>
|
|
147
148
|
);
|
|
@@ -205,6 +206,7 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
|
205
206
|
}
|
|
206
207
|
bgFileId={segment.bgFileId}
|
|
207
208
|
imageSize={segment.imageSize || "contain"}
|
|
209
|
+
imgResponsiveWidths={segment.imgResponsiveWidths}
|
|
208
210
|
bgType={segment.bgType || "None"}
|
|
209
211
|
style={segment.style || {}}
|
|
210
212
|
bgColor={segment.bgColor || "#ffffff"}
|
|
@@ -372,6 +374,7 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
|
|
|
372
374
|
bgFileId: node.props.bgFileId,
|
|
373
375
|
bgType: node.props.bgType,
|
|
374
376
|
imageSize: node.props.imageSize,
|
|
377
|
+
imgResponsiveWidths: node.props.imgResponsiveWidths,
|
|
375
378
|
bgColor: node.props.bgColor,
|
|
376
379
|
setTextColor: node.props.setTextColor,
|
|
377
380
|
textColor: node.props.textColor,
|
|
@@ -437,6 +440,7 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
|
|
|
437
440
|
node.props.name === "not_assigned" ? rand_ident() : node.props.name,
|
|
438
441
|
state: node.props.state,
|
|
439
442
|
configuration: node.props.configuration,
|
|
443
|
+
extra_state_fml: node.props.extra_state_fml,
|
|
440
444
|
};
|
|
441
445
|
}
|
|
442
446
|
|