@saltcorn/builder 0.6.4-beta.6 → 0.7.0-beta.1
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/Builder.js +7 -7
- package/src/components/Library.js +3 -3
- package/src/components/RenderNode.js +7 -7
- package/src/components/elements/Action.js +13 -15
- package/src/components/elements/Aggregation.js +3 -3
- package/src/components/elements/Card.js +1 -1
- package/src/components/elements/Columns.js +1 -1
- package/src/components/elements/Container.js +7 -8
- package/src/components/elements/DropDownFilter.js +1 -1
- package/src/components/elements/Field.js +2 -2
- package/src/components/elements/Image.js +3 -3
- package/src/components/elements/JoinField.js +2 -2
- package/src/components/elements/Link.js +5 -5
- package/src/components/elements/SearchBar.js +26 -29
- package/src/components/elements/Tabs.js +24 -2
- package/src/components/elements/Text.js +68 -18
- package/src/components/elements/ToggleFilter.js +5 -5
- package/src/components/elements/View.js +2 -2
- package/src/components/elements/ViewLink.js +2 -2
- package/src/components/elements/utils.js +41 -25
- package/src/components/storage.js +4 -0
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
TextStyleRow,
|
|
16
16
|
DynamicFontAwesomeIcon,
|
|
17
17
|
isBlock,
|
|
18
|
+
reactifyStyles,
|
|
19
|
+
SettingsRow,
|
|
18
20
|
} from "./utils";
|
|
19
21
|
import ContentEditable from "react-contenteditable";
|
|
20
22
|
import optionsCtx from "../context";
|
|
@@ -74,7 +76,16 @@ export /**
|
|
|
74
76
|
* @category saltcorn-builder
|
|
75
77
|
* @subcategory components
|
|
76
78
|
*/
|
|
77
|
-
const Text = ({
|
|
79
|
+
const Text = ({
|
|
80
|
+
text,
|
|
81
|
+
block,
|
|
82
|
+
inline,
|
|
83
|
+
isFormula,
|
|
84
|
+
textStyle,
|
|
85
|
+
icon,
|
|
86
|
+
font,
|
|
87
|
+
style,
|
|
88
|
+
}) => {
|
|
78
89
|
const {
|
|
79
90
|
connectors: { connect, drag },
|
|
80
91
|
selected,
|
|
@@ -92,14 +103,17 @@ const Text = ({ text, block, inline, isFormula, textStyle, icon, font }) => {
|
|
|
92
103
|
<div
|
|
93
104
|
className={`${
|
|
94
105
|
isBlock(block, inline, textStyle) ? "d-block" : "d-inline-block"
|
|
95
|
-
} ${textStyle} is-text ${isFormula.text ? "
|
|
106
|
+
} ${textStyle} is-text ${isFormula.text ? "font-monospace" : ""} ${
|
|
96
107
|
selected ? "selected-node" : ""
|
|
97
108
|
}`}
|
|
98
109
|
ref={(dom) => connect(drag(dom))}
|
|
99
110
|
onClick={(e) => selected && setEditable(true)}
|
|
100
|
-
style={
|
|
111
|
+
style={{
|
|
112
|
+
...(font ? { fontFamily: font } : {}),
|
|
113
|
+
...reactifyStyles(style || {}),
|
|
114
|
+
}}
|
|
101
115
|
>
|
|
102
|
-
<DynamicFontAwesomeIcon icon={icon} className="
|
|
116
|
+
<DynamicFontAwesomeIcon icon={icon} className="me-1" />
|
|
103
117
|
{isFormula.text ? (
|
|
104
118
|
<Fragment>
|
|
105
119
|
=
|
|
@@ -146,6 +160,7 @@ const TextSettings = () => {
|
|
|
146
160
|
labelFor: node.data.props.labelFor,
|
|
147
161
|
icon: node.data.props.icon,
|
|
148
162
|
font: node.data.props.font,
|
|
163
|
+
style: node.data.props.style,
|
|
149
164
|
}));
|
|
150
165
|
const {
|
|
151
166
|
actions: { setProp },
|
|
@@ -157,6 +172,7 @@ const TextSettings = () => {
|
|
|
157
172
|
labelFor,
|
|
158
173
|
icon,
|
|
159
174
|
font,
|
|
175
|
+
style,
|
|
160
176
|
} = node;
|
|
161
177
|
const { mode, fields } = useContext(optionsCtx);
|
|
162
178
|
const setAProp = (key) => (e) => {
|
|
@@ -208,7 +224,11 @@ const TextSettings = () => {
|
|
|
208
224
|
{mode === "edit" && (
|
|
209
225
|
<Fragment>
|
|
210
226
|
<label>Label for Field</label>
|
|
211
|
-
<select
|
|
227
|
+
<select
|
|
228
|
+
value={labelFor}
|
|
229
|
+
onChange={setAProp("labelFor")}
|
|
230
|
+
className="form-control form-select"
|
|
231
|
+
>
|
|
212
232
|
<option value={""}></option>
|
|
213
233
|
{fields.map((f, ix) => (
|
|
214
234
|
<option key={ix} value={f.name}>
|
|
@@ -235,19 +255,48 @@ const TextSettings = () => {
|
|
|
235
255
|
/>
|
|
236
256
|
</td>
|
|
237
257
|
</tr>
|
|
238
|
-
<
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
258
|
+
<SettingsRow
|
|
259
|
+
field={{
|
|
260
|
+
name: "font",
|
|
261
|
+
label: "Font family",
|
|
262
|
+
type: "Font",
|
|
263
|
+
}}
|
|
264
|
+
node={node}
|
|
265
|
+
setProp={setProp}
|
|
266
|
+
/>
|
|
267
|
+
<SettingsRow
|
|
268
|
+
field={{
|
|
269
|
+
name: "font-size",
|
|
270
|
+
label: "Font size",
|
|
271
|
+
type: "DimUnits",
|
|
272
|
+
}}
|
|
273
|
+
node={node}
|
|
274
|
+
setProp={setProp}
|
|
275
|
+
isStyle={true}
|
|
276
|
+
/>
|
|
277
|
+
<SettingsRow
|
|
278
|
+
field={{
|
|
279
|
+
name: "font-weight",
|
|
280
|
+
label: "Weight",
|
|
281
|
+
type: "Integer",
|
|
282
|
+
min: 100,
|
|
283
|
+
max: 900,
|
|
284
|
+
step: 100,
|
|
285
|
+
}}
|
|
286
|
+
node={node}
|
|
287
|
+
setProp={setProp}
|
|
288
|
+
isStyle={true}
|
|
289
|
+
/>
|
|
290
|
+
<SettingsRow
|
|
291
|
+
field={{
|
|
292
|
+
name: "line-height",
|
|
293
|
+
label: "Line height",
|
|
294
|
+
type: "DimUnits",
|
|
295
|
+
}}
|
|
296
|
+
node={node}
|
|
297
|
+
setProp={setProp}
|
|
298
|
+
isStyle={true}
|
|
299
|
+
/>
|
|
251
300
|
</tbody>
|
|
252
301
|
</table>
|
|
253
302
|
<BlockOrInlineSetting
|
|
@@ -272,6 +321,7 @@ Text.craft = {
|
|
|
272
321
|
textStyle: "",
|
|
273
322
|
labelFor: "",
|
|
274
323
|
font: "",
|
|
324
|
+
style: {},
|
|
275
325
|
},
|
|
276
326
|
displayName: "Text",
|
|
277
327
|
related: {
|
|
@@ -94,7 +94,7 @@ const ToggleFilterSettings = () => {
|
|
|
94
94
|
<td>
|
|
95
95
|
<select
|
|
96
96
|
value={name}
|
|
97
|
-
className="form-control"
|
|
97
|
+
className="form-control form-select"
|
|
98
98
|
onChange={(e) => {
|
|
99
99
|
setProp((prop) => (prop.name = e.target.value));
|
|
100
100
|
const field = options.fields.find(
|
|
@@ -121,7 +121,7 @@ const ToggleFilterSettings = () => {
|
|
|
121
121
|
{isBool ? (
|
|
122
122
|
<select
|
|
123
123
|
value={value}
|
|
124
|
-
className="w-100"
|
|
124
|
+
className="w-100 form-select"
|
|
125
125
|
onChange={setAProp("value")}
|
|
126
126
|
>
|
|
127
127
|
<option value="on">True</option>
|
|
@@ -145,7 +145,7 @@ const ToggleFilterSettings = () => {
|
|
|
145
145
|
<td>
|
|
146
146
|
<select
|
|
147
147
|
value={preset_value}
|
|
148
|
-
className="form-control"
|
|
148
|
+
className="form-control form-select"
|
|
149
149
|
onChange={setAProp("preset_value")}
|
|
150
150
|
>
|
|
151
151
|
<option value=""></option>
|
|
@@ -176,7 +176,7 @@ const ToggleFilterSettings = () => {
|
|
|
176
176
|
</td>
|
|
177
177
|
<td>
|
|
178
178
|
<select
|
|
179
|
-
className="form-control"
|
|
179
|
+
className="form-control form-select"
|
|
180
180
|
value={size}
|
|
181
181
|
onChange={setAProp("size")}
|
|
182
182
|
>
|
|
@@ -195,7 +195,7 @@ const ToggleFilterSettings = () => {
|
|
|
195
195
|
</td>
|
|
196
196
|
<td>
|
|
197
197
|
<select
|
|
198
|
-
className="form-control"
|
|
198
|
+
className="form-control form-select"
|
|
199
199
|
value={style}
|
|
200
200
|
onChange={setAProp("style")}
|
|
201
201
|
>
|
|
@@ -109,7 +109,7 @@ const ViewSettings = () => {
|
|
|
109
109
|
<label>View to {options.mode === "show" ? "embed" : "show"}</label>
|
|
110
110
|
<select
|
|
111
111
|
value={view}
|
|
112
|
-
className="form-control"
|
|
112
|
+
className="form-control form-select"
|
|
113
113
|
onChange={(e) => {
|
|
114
114
|
setProp((prop) => (prop.view = e.target.value));
|
|
115
115
|
}}
|
|
@@ -127,7 +127,7 @@ const ViewSettings = () => {
|
|
|
127
127
|
<label>State</label>
|
|
128
128
|
<select
|
|
129
129
|
value={state}
|
|
130
|
-
className="form-control"
|
|
130
|
+
className="form-control form-select"
|
|
131
131
|
onChange={setAProp("state")}
|
|
132
132
|
>
|
|
133
133
|
<option value="shared">Shared</option>
|
|
@@ -72,7 +72,7 @@ const ViewLink = ({
|
|
|
72
72
|
: {}
|
|
73
73
|
}
|
|
74
74
|
>
|
|
75
|
-
{link_icon ? <i className={`${link_icon}
|
|
75
|
+
{link_icon ? <i className={`${link_icon} me-1`}></i> : ""}
|
|
76
76
|
{displabel}
|
|
77
77
|
</span>
|
|
78
78
|
);
|
|
@@ -120,7 +120,7 @@ const ViewLinkSettings = () => {
|
|
|
120
120
|
<label>View to link to</label>
|
|
121
121
|
<select
|
|
122
122
|
value={name}
|
|
123
|
-
className="form-control"
|
|
123
|
+
className="form-control form-select"
|
|
124
124
|
onChange={(e) =>
|
|
125
125
|
setProp((prop) => (prop.name = e.target.value))
|
|
126
126
|
}
|
|
@@ -130,22 +130,21 @@ const OrFormula = ({ setProp, isFormula, node, nodekey, children }) => {
|
|
|
130
130
|
) : (
|
|
131
131
|
children
|
|
132
132
|
)}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
</div>
|
|
133
|
+
|
|
134
|
+
<button
|
|
135
|
+
className={`btn activate-formula ${
|
|
136
|
+
isFormula[nodekey] ? "btn-secondary" : "btn-outline-secondary"
|
|
137
|
+
}`}
|
|
138
|
+
title="Calculated formula"
|
|
139
|
+
type="button"
|
|
140
|
+
onClick={switchIsFml}
|
|
141
|
+
>
|
|
142
|
+
<i className="fas fa-calculator"></i>
|
|
143
|
+
</button>
|
|
145
144
|
</div>
|
|
146
145
|
{isFormula[nodekey] && (
|
|
147
146
|
<div style={{ marginTop: "-5px" }}>
|
|
148
|
-
<small className="text-muted
|
|
147
|
+
<small className="text-muted font-monospace">FORMULA</small>
|
|
149
148
|
</div>
|
|
150
149
|
)}
|
|
151
150
|
</Fragment>
|
|
@@ -167,6 +166,7 @@ const MinRoleSetting = ({ minRole, setProp }) => {
|
|
|
167
166
|
<div>
|
|
168
167
|
<label>Minimum Role</label>
|
|
169
168
|
<select
|
|
169
|
+
className="form-control form-select"
|
|
170
170
|
value={minRole}
|
|
171
171
|
onChange={(e) => (e) => {
|
|
172
172
|
if (e.target) {
|
|
@@ -204,7 +204,7 @@ const MinRoleSettingRow = ({ minRole, setProp }) => {
|
|
|
204
204
|
<td>
|
|
205
205
|
<select
|
|
206
206
|
value={minRole}
|
|
207
|
-
className="form-control"
|
|
207
|
+
className="form-control form-select"
|
|
208
208
|
onChange={(e) => {
|
|
209
209
|
if (e.target) {
|
|
210
210
|
const target_value = e.target.value;
|
|
@@ -236,7 +236,7 @@ const TextStyleSelect = ({ textStyle, setProp }) => {
|
|
|
236
236
|
return (
|
|
237
237
|
<select
|
|
238
238
|
value={textStyle}
|
|
239
|
-
className="form-control"
|
|
239
|
+
className="form-control form-select"
|
|
240
240
|
onChange={(e) => {
|
|
241
241
|
if (e.target) {
|
|
242
242
|
const target_value = e.target.value;
|
|
@@ -251,12 +251,12 @@ const TextStyleSelect = ({ textStyle, setProp }) => {
|
|
|
251
251
|
<option value="h4">Heading 4</option>
|
|
252
252
|
<option value="h5">Heading 5</option>
|
|
253
253
|
<option value="h6">Heading 6</option>
|
|
254
|
-
<option value="
|
|
254
|
+
<option value="fw-bold">Bold</option>
|
|
255
255
|
<option value="font-italic">Italics</option>
|
|
256
256
|
<option value="small">Small</option>
|
|
257
257
|
<option value="text-muted">Muted</option>
|
|
258
258
|
<option value="text-underline">Underline</option>
|
|
259
|
-
<option value="
|
|
259
|
+
<option value="font-monospace">Monospace</option>
|
|
260
260
|
</select>
|
|
261
261
|
);
|
|
262
262
|
};
|
|
@@ -321,7 +321,7 @@ const Accordion = ({ titles, children }) => {
|
|
|
321
321
|
<div
|
|
322
322
|
className={`bg-${
|
|
323
323
|
isCurrent ? "primary" : "secondary"
|
|
324
|
-
}
|
|
324
|
+
} ps-1 text-white w-100 mt-1`}
|
|
325
325
|
onClick={() => setCurrentTab(ix)}
|
|
326
326
|
>
|
|
327
327
|
<span className="w-1em">
|
|
@@ -565,12 +565,12 @@ export /**
|
|
|
565
565
|
const ConfigForm = ({ fields, configuration, setProp, node, onChange }) => (
|
|
566
566
|
<div>
|
|
567
567
|
{fields.map((f, ix) => {
|
|
568
|
-
if (f.showIf &&
|
|
568
|
+
if (f.showIf && configuration) {
|
|
569
569
|
let noshow = false;
|
|
570
570
|
Object.entries(f.showIf).forEach(([nm, value]) => {
|
|
571
571
|
if (Array.isArray(value))
|
|
572
|
-
noshow = noshow || value.includes(
|
|
573
|
-
else noshow = noshow || value !==
|
|
572
|
+
noshow = noshow || value.includes(configuration[nm]);
|
|
573
|
+
else noshow = noshow || value !== configuration[nm];
|
|
574
574
|
});
|
|
575
575
|
if (noshow) return null;
|
|
576
576
|
}
|
|
@@ -625,6 +625,8 @@ const ConfigField = ({
|
|
|
625
625
|
* @param {object} v
|
|
626
626
|
* @returns {void}
|
|
627
627
|
*/
|
|
628
|
+
const options = useContext(optionsCtx);
|
|
629
|
+
|
|
628
630
|
const myOnChange = (v) => {
|
|
629
631
|
setProp((prop) => {
|
|
630
632
|
if (configuration) {
|
|
@@ -660,7 +662,7 @@ const ConfigField = ({
|
|
|
660
662
|
: field.attributes.options;
|
|
661
663
|
return (
|
|
662
664
|
<select
|
|
663
|
-
className="form-control"
|
|
665
|
+
className="form-control form-select"
|
|
664
666
|
value={value || ""}
|
|
665
667
|
onChange={(e) => e.target && myOnChange(e.target.value)}
|
|
666
668
|
>
|
|
@@ -684,6 +686,20 @@ const ConfigField = ({
|
|
|
684
686
|
/>
|
|
685
687
|
);
|
|
686
688
|
},
|
|
689
|
+
Font: () => (
|
|
690
|
+
<select
|
|
691
|
+
className="form-control form-select"
|
|
692
|
+
value={value || ""}
|
|
693
|
+
onChange={(e) => e.target && myOnChange(e.target.value)}
|
|
694
|
+
>
|
|
695
|
+
<option value={""}></option>
|
|
696
|
+
{Object.entries(options.fonts || {}).map(([nm, ff], ix) => (
|
|
697
|
+
<option key={ix} value={ff}>
|
|
698
|
+
{nm}
|
|
699
|
+
</option>
|
|
700
|
+
))}
|
|
701
|
+
</select>
|
|
702
|
+
),
|
|
687
703
|
Integer: () => (
|
|
688
704
|
<input
|
|
689
705
|
type="number"
|
|
@@ -736,7 +752,7 @@ const ConfigField = ({
|
|
|
736
752
|
),
|
|
737
753
|
select: () => (
|
|
738
754
|
<select
|
|
739
|
-
className="form-control"
|
|
755
|
+
className="form-control form-select"
|
|
740
756
|
value={value || ""}
|
|
741
757
|
onChange={(e) => e.target && myOnChange(e.target.value)}
|
|
742
758
|
>
|
|
@@ -1031,7 +1047,7 @@ const ButtonOrLinkSettingsRows = ({
|
|
|
1031
1047
|
</td>
|
|
1032
1048
|
<td>
|
|
1033
1049
|
<select
|
|
1034
|
-
className="form-control"
|
|
1050
|
+
className="form-control form-select"
|
|
1035
1051
|
value={values[keyPrefix + "style"]}
|
|
1036
1052
|
onChange={setAProp(keyPrefix + "style")}
|
|
1037
1053
|
>
|
|
@@ -1063,7 +1079,7 @@ const ButtonOrLinkSettingsRows = ({
|
|
|
1063
1079
|
</td>
|
|
1064
1080
|
<td>
|
|
1065
1081
|
<select
|
|
1066
|
-
className="form-control"
|
|
1082
|
+
className="form-control form-select"
|
|
1067
1083
|
value={values[keyPrefix + "size"]}
|
|
1068
1084
|
onChange={setAProp(keyPrefix + "size")}
|
|
1069
1085
|
>
|
|
@@ -128,6 +128,7 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
|
128
128
|
inline={segment.inline || false}
|
|
129
129
|
textStyle={segment.textStyle || ""}
|
|
130
130
|
labelFor={segment.labelFor || ""}
|
|
131
|
+
style={segment.style || {}}
|
|
131
132
|
icon={segment.icon}
|
|
132
133
|
font={segment.font || ""}
|
|
133
134
|
/>
|
|
@@ -225,6 +226,7 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
|
|
|
225
226
|
titles={segment.titles}
|
|
226
227
|
ntabs={segment.ntabs}
|
|
227
228
|
independent={segment.independent}
|
|
229
|
+
deeplink={segment.deeplink}
|
|
228
230
|
tabsStyle={segment.tabsStyle}
|
|
229
231
|
contents={segment.contents.map(toTag)}
|
|
230
232
|
/>
|
|
@@ -394,6 +396,7 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
|
|
|
394
396
|
textStyle: node.props.textStyle,
|
|
395
397
|
isFormula: node.props.isFormula,
|
|
396
398
|
labelFor: node.props.labelFor,
|
|
399
|
+
style: node.props.style,
|
|
397
400
|
icon: node.props.icon,
|
|
398
401
|
font: node.props.font,
|
|
399
402
|
};
|
|
@@ -417,6 +420,7 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
|
|
|
417
420
|
titles: node.props.titles,
|
|
418
421
|
tabsStyle: node.props.tabsStyle,
|
|
419
422
|
independent: node.props.independent,
|
|
423
|
+
deeplink: node.props.deeplink,
|
|
420
424
|
ntabs: node.props.ntabs,
|
|
421
425
|
};
|
|
422
426
|
}
|