@saltcorn/builder 0.8.3-alpha.1 → 0.8.3-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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/builder",
|
|
3
|
-
"version": "0.8.3-
|
|
3
|
+
"version": "0.8.3-beta.0",
|
|
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",
|
|
@@ -36,14 +36,20 @@
|
|
|
36
36
|
"react-dom": "16.13.1",
|
|
37
37
|
"react-transition-group": "4.4.1",
|
|
38
38
|
"@tippyjs/react": "4.2.6",
|
|
39
|
-
"webpack": "
|
|
40
|
-
"webpack-cli": "
|
|
41
|
-
"lodash": "4.17.
|
|
39
|
+
"webpack": "5.68.0",
|
|
40
|
+
"webpack-cli": "4.9.2",
|
|
41
|
+
"lodash": "4.17.21",
|
|
42
|
+
"immer": ">=9.0.6",
|
|
43
|
+
"glob-parent": "^5.1.2"
|
|
42
44
|
},
|
|
43
45
|
"publishConfig": {
|
|
44
46
|
"access": "public"
|
|
45
47
|
},
|
|
46
48
|
"dependencies": {
|
|
47
49
|
"styled-components": "4.4.1"
|
|
50
|
+
},
|
|
51
|
+
"overrides": {
|
|
52
|
+
"immer": "9.0.6",
|
|
53
|
+
"glob-parent": "^5.1.2"
|
|
48
54
|
}
|
|
49
55
|
}
|
|
@@ -277,6 +277,26 @@ const BoxModelEditor = ({ setProp, node, sizeWithStyle }) => {
|
|
|
277
277
|
setProp={setProp}
|
|
278
278
|
isStyle={!!sizeWithStyle}
|
|
279
279
|
/>
|
|
280
|
+
<SettingsRow
|
|
281
|
+
field={{
|
|
282
|
+
name: "min-width",
|
|
283
|
+
label: "min width",
|
|
284
|
+
type: "DimUnits",
|
|
285
|
+
}}
|
|
286
|
+
node={node}
|
|
287
|
+
setProp={setProp}
|
|
288
|
+
isStyle={true}
|
|
289
|
+
/>
|
|
290
|
+
<SettingsRow
|
|
291
|
+
field={{
|
|
292
|
+
name: "max-width",
|
|
293
|
+
label: "max width",
|
|
294
|
+
type: "DimUnits",
|
|
295
|
+
}}
|
|
296
|
+
node={node}
|
|
297
|
+
setProp={setProp}
|
|
298
|
+
isStyle={true}
|
|
299
|
+
/>
|
|
280
300
|
<SettingsRow
|
|
281
301
|
field={{ name: "height", label: "height", type: "DimUnits" }}
|
|
282
302
|
node={node}
|
|
@@ -293,6 +313,16 @@ const BoxModelEditor = ({ setProp, node, sizeWithStyle }) => {
|
|
|
293
313
|
setProp={setProp}
|
|
294
314
|
isStyle={!!sizeWithStyle}
|
|
295
315
|
/>
|
|
316
|
+
<SettingsRow
|
|
317
|
+
field={{
|
|
318
|
+
name: "max-height",
|
|
319
|
+
label: "max height",
|
|
320
|
+
type: "DimUnits",
|
|
321
|
+
}}
|
|
322
|
+
node={node}
|
|
323
|
+
setProp={setProp}
|
|
324
|
+
isStyle={true}
|
|
325
|
+
/>
|
|
296
326
|
</Fragment>
|
|
297
327
|
)}
|
|
298
328
|
{selectedCategory === "border" && (
|
|
@@ -34,43 +34,58 @@ export /**
|
|
|
34
34
|
* @category saltcorn-builder
|
|
35
35
|
* @subcategory components
|
|
36
36
|
*/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
37
|
+
const Link = ({
|
|
38
|
+
text,
|
|
39
|
+
block,
|
|
40
|
+
isFormula,
|
|
41
|
+
textStyle,
|
|
42
|
+
link_style,
|
|
43
|
+
link_size,
|
|
44
|
+
link_icon,
|
|
45
|
+
link_bgcol,
|
|
46
|
+
link_bordercol,
|
|
47
|
+
link_textcol,
|
|
48
|
+
}) => {
|
|
49
|
+
const {
|
|
50
|
+
selected,
|
|
51
|
+
connectors: { connect, drag },
|
|
52
|
+
} = useNode((node) => ({ selected: node.events.selected }));
|
|
53
|
+
if (!link_style)
|
|
53
54
|
return (
|
|
54
55
|
<span
|
|
55
|
-
className={`${textStyle} is-builder-link ${
|
|
56
|
-
|
|
57
|
-
{
|
|
56
|
+
className={`${textStyle} is-builder-link ${
|
|
57
|
+
selected ? "selected-node" : ""
|
|
58
|
+
} ${isFormula?.text ? "font-monospace" : ""} ${block ? "d-block" : ""}`}
|
|
59
|
+
ref={(dom) => connect(drag(dom))}
|
|
60
|
+
>
|
|
61
|
+
<DynamicFontAwesomeIcon icon={link_icon} className="me-1" />
|
|
62
|
+
{isFormula?.text ? `=${text}` : text}
|
|
63
|
+
</span>
|
|
64
|
+
);
|
|
65
|
+
else
|
|
66
|
+
return (
|
|
67
|
+
<button
|
|
68
|
+
className={`${textStyle} is-builder-link ${
|
|
69
|
+
selected ? "selected-node" : ""
|
|
70
|
+
} ${isFormula?.text ? "font-monospace" : ""} ${link_style} ${
|
|
71
|
+
link_size || ""
|
|
72
|
+
} ${block ? "d-block" : ""}`}
|
|
58
73
|
ref={(dom) => connect(drag(dom))}
|
|
59
74
|
style={
|
|
60
75
|
link_style === "btn btn-custom-color"
|
|
61
76
|
? {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
77
|
+
backgroundColor: link_bgcol || "#000000",
|
|
78
|
+
borderColor: link_bordercol || "#000000",
|
|
79
|
+
color: link_textcol || "#000000",
|
|
80
|
+
}
|
|
66
81
|
: {}
|
|
67
82
|
}
|
|
68
83
|
>
|
|
69
84
|
<DynamicFontAwesomeIcon icon={link_icon} className="me-1" />
|
|
70
85
|
{isFormula?.text ? `=${text}` : text}
|
|
71
|
-
</
|
|
86
|
+
</button>
|
|
72
87
|
);
|
|
73
|
-
|
|
88
|
+
};
|
|
74
89
|
|
|
75
90
|
export /**
|
|
76
91
|
* @returns {div}
|
|
@@ -78,222 +93,223 @@ export /**
|
|
|
78
93
|
* @category saltcorn-builder
|
|
79
94
|
* @subcategory components
|
|
80
95
|
*/
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
96
|
+
const LinkSettings = () => {
|
|
97
|
+
const node = useNode((node) => ({
|
|
98
|
+
text: node.data.props.text,
|
|
99
|
+
url: node.data.props.url,
|
|
100
|
+
block: node.data.props.block,
|
|
101
|
+
isFormula: node.data.props.isFormula,
|
|
102
|
+
textStyle: node.data.props.textStyle,
|
|
103
|
+
nofollow: node.data.props.nofollow,
|
|
104
|
+
in_modal: node.data.props.in_modal,
|
|
105
|
+
view_state_fml: node.data.props.view_state_fml,
|
|
106
|
+
link_src: node.data.props.link_src,
|
|
107
|
+
target_blank: node.data.props.target_blank,
|
|
108
|
+
link_style: node.data.props.link_style,
|
|
109
|
+
link_size: node.data.props.link_size,
|
|
110
|
+
link_icon: node.data.props.link_icon,
|
|
111
|
+
link_bgcol: node.data.props.link_bgcol,
|
|
112
|
+
link_bordercol: node.data.props.link_bordercol,
|
|
113
|
+
link_textcol: node.data.props.link_textcol,
|
|
114
|
+
transfer_state: node.data.props.transfer_state,
|
|
115
|
+
}));
|
|
116
|
+
const {
|
|
117
|
+
actions: { setProp },
|
|
118
|
+
text,
|
|
119
|
+
url,
|
|
120
|
+
block,
|
|
121
|
+
isFormula,
|
|
122
|
+
textStyle,
|
|
123
|
+
nofollow,
|
|
124
|
+
target_blank,
|
|
125
|
+
link_src,
|
|
126
|
+
in_modal,
|
|
127
|
+
transfer_state,
|
|
128
|
+
view_state_fml,
|
|
129
|
+
} = node;
|
|
130
|
+
const options = useContext(optionsCtx);
|
|
131
|
+
const setAProp = setAPropGen(setProp);
|
|
132
|
+
return (
|
|
133
|
+
<div>
|
|
134
|
+
<table className="w-100">
|
|
135
|
+
<tbody>
|
|
136
|
+
<tr>
|
|
137
|
+
<td>
|
|
138
|
+
<label>Text to display</label>
|
|
139
|
+
</td>
|
|
140
|
+
<td>
|
|
141
|
+
<OrFormula nodekey="text" {...{ setProp, isFormula, node }}>
|
|
142
|
+
<input
|
|
143
|
+
type="text"
|
|
144
|
+
className="form-control text-to-display"
|
|
145
|
+
value={text}
|
|
146
|
+
onChange={setAProp("text")}
|
|
147
|
+
/>
|
|
148
|
+
</OrFormula>
|
|
149
|
+
</td>
|
|
150
|
+
</tr>
|
|
151
|
+
<tr>
|
|
152
|
+
<td>
|
|
153
|
+
<label>Link source</label>
|
|
154
|
+
</td>
|
|
155
|
+
<td>
|
|
156
|
+
<select
|
|
157
|
+
value={link_src}
|
|
158
|
+
className="form-control form-select"
|
|
159
|
+
onChange={(e) => {
|
|
160
|
+
if (!e.target) return;
|
|
161
|
+
const value = e.target.value;
|
|
162
|
+
setProp((prop) => {
|
|
163
|
+
prop.link_src = value;
|
|
164
|
+
if (value !== "URL" && prop.isFormula) {
|
|
165
|
+
prop.isFormula.url = false;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}}
|
|
169
|
+
>
|
|
170
|
+
<option>URL</option>
|
|
171
|
+
{(options.pages || []).length > 0 && <option>Page</option>}
|
|
172
|
+
{(options.views || []).length > 0 &&
|
|
173
|
+
["page", "filter"].includes(options.mode) && (
|
|
174
|
+
<option>View</option>
|
|
175
|
+
)}
|
|
176
|
+
</select>
|
|
177
|
+
</td>
|
|
178
|
+
</tr>
|
|
179
|
+
{link_src === "URL" && (
|
|
121
180
|
<tr>
|
|
122
181
|
<td>
|
|
123
|
-
<label>
|
|
182
|
+
<label>URL</label>
|
|
124
183
|
</td>
|
|
125
184
|
<td>
|
|
126
|
-
<OrFormula nodekey="
|
|
185
|
+
<OrFormula nodekey="url" {...{ setProp, isFormula, node }}>
|
|
127
186
|
<input
|
|
128
187
|
type="text"
|
|
129
|
-
className="form-control
|
|
130
|
-
value={
|
|
131
|
-
onChange={setAProp("
|
|
188
|
+
className="form-control "
|
|
189
|
+
value={url}
|
|
190
|
+
onChange={setAProp("url")}
|
|
132
191
|
/>
|
|
133
192
|
</OrFormula>
|
|
134
193
|
</td>
|
|
135
194
|
</tr>
|
|
195
|
+
)}
|
|
196
|
+
{link_src === "Page" && (
|
|
136
197
|
<tr>
|
|
137
198
|
<td>
|
|
138
|
-
<label>
|
|
199
|
+
<label>Page</label>
|
|
139
200
|
</td>
|
|
140
201
|
<td>
|
|
141
202
|
<select
|
|
142
|
-
value={
|
|
203
|
+
value={url}
|
|
143
204
|
className="form-control form-select"
|
|
144
|
-
onChange={(
|
|
145
|
-
if (!e.target) return;
|
|
146
|
-
const value = e.target.value;
|
|
147
|
-
setProp((prop) => {
|
|
148
|
-
prop.link_src = value;
|
|
149
|
-
if (value !== "URL" && prop.isFormula) {
|
|
150
|
-
prop.isFormula.url = false;
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
}}
|
|
205
|
+
onChange={setAProp("url")}
|
|
154
206
|
>
|
|
155
|
-
<option
|
|
156
|
-
{(options.pages || []).
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
207
|
+
<option></option>
|
|
208
|
+
{(options.pages || []).map((p, ix) => (
|
|
209
|
+
<option key={ix} value={`/page/${p.name}`}>
|
|
210
|
+
{p.name}
|
|
211
|
+
</option>
|
|
212
|
+
))}
|
|
161
213
|
</select>
|
|
162
214
|
</td>
|
|
163
215
|
</tr>
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
</
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
{
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
<select
|
|
209
|
-
value={url}
|
|
210
|
-
className="form-control form-select"
|
|
211
|
-
onChange={setAProp("url")}
|
|
212
|
-
>
|
|
213
|
-
<option></option>
|
|
214
|
-
{(options.views || []).map((p, ix) => (
|
|
215
|
-
<option key={ix} value={`/view/${p.name}`}>
|
|
216
|
-
{p.name} [{p.viewtemplate}]
|
|
217
|
-
</option>
|
|
218
|
-
))}
|
|
219
|
-
</select>
|
|
220
|
-
</td>
|
|
221
|
-
</tr>
|
|
222
|
-
)}
|
|
223
|
-
{link_src === "View" && (
|
|
224
|
-
<tr>
|
|
225
|
-
<td>
|
|
226
|
-
<label>State Formula</label>
|
|
227
|
-
</td>
|
|
228
|
-
<td>
|
|
229
|
-
<input
|
|
230
|
-
type="text"
|
|
231
|
-
className="form-control"
|
|
232
|
-
value={view_state_fml}
|
|
233
|
-
onChange={setAProp("view_state_fml")}
|
|
234
|
-
/>
|
|
235
|
-
</td>
|
|
236
|
-
</tr>
|
|
237
|
-
)}
|
|
238
|
-
<ButtonOrLinkSettingsRows
|
|
239
|
-
setProp={setProp}
|
|
240
|
-
keyPrefix="link_"
|
|
241
|
-
btnClass="btn"
|
|
242
|
-
values={node}
|
|
243
|
-
linkFirst={true}
|
|
244
|
-
/>
|
|
245
|
-
</tbody>
|
|
246
|
-
</table>
|
|
247
|
-
|
|
248
|
-
<div className="form-check">
|
|
249
|
-
<input
|
|
250
|
-
className="form-check-input"
|
|
251
|
-
name="block"
|
|
252
|
-
type="checkbox"
|
|
253
|
-
checked={nofollow}
|
|
254
|
-
onChange={setAProp("nofollow", { checked: true })}
|
|
255
|
-
/>
|
|
256
|
-
<label className="form-check-label">Nofollow</label>
|
|
257
|
-
</div>
|
|
258
|
-
<div className="form-check">
|
|
259
|
-
<input
|
|
260
|
-
className="form-check-input"
|
|
261
|
-
name="block"
|
|
262
|
-
type="checkbox"
|
|
263
|
-
checked={target_blank}
|
|
264
|
-
onChange={setAProp("target_blank", { checked: true })}
|
|
216
|
+
)}
|
|
217
|
+
{link_src === "View" && (
|
|
218
|
+
<tr>
|
|
219
|
+
<td>
|
|
220
|
+
<label>View</label>
|
|
221
|
+
</td>
|
|
222
|
+
<td>
|
|
223
|
+
<select
|
|
224
|
+
value={url}
|
|
225
|
+
className="form-control form-select"
|
|
226
|
+
onChange={setAProp("url")}
|
|
227
|
+
>
|
|
228
|
+
<option></option>
|
|
229
|
+
{(options.views || []).map((p, ix) => (
|
|
230
|
+
<option key={ix} value={`/view/${p.name}`}>
|
|
231
|
+
{p.name} [{p.viewtemplate}]
|
|
232
|
+
</option>
|
|
233
|
+
))}
|
|
234
|
+
</select>
|
|
235
|
+
</td>
|
|
236
|
+
</tr>
|
|
237
|
+
)}
|
|
238
|
+
{link_src === "View" && (
|
|
239
|
+
<tr>
|
|
240
|
+
<td>
|
|
241
|
+
<label>State Formula</label>
|
|
242
|
+
</td>
|
|
243
|
+
<td>
|
|
244
|
+
<input
|
|
245
|
+
type="text"
|
|
246
|
+
className="form-control"
|
|
247
|
+
value={view_state_fml}
|
|
248
|
+
onChange={setAProp("view_state_fml")}
|
|
249
|
+
/>
|
|
250
|
+
</td>
|
|
251
|
+
</tr>
|
|
252
|
+
)}
|
|
253
|
+
<ButtonOrLinkSettingsRows
|
|
254
|
+
setProp={setProp}
|
|
255
|
+
keyPrefix="link_"
|
|
256
|
+
btnClass="btn"
|
|
257
|
+
values={node}
|
|
258
|
+
linkFirst={true}
|
|
259
|
+
linkIsBlank={true}
|
|
265
260
|
/>
|
|
266
|
-
|
|
267
|
-
|
|
261
|
+
</tbody>
|
|
262
|
+
</table>
|
|
263
|
+
|
|
264
|
+
<div className="form-check">
|
|
265
|
+
<input
|
|
266
|
+
className="form-check-input"
|
|
267
|
+
name="block"
|
|
268
|
+
type="checkbox"
|
|
269
|
+
checked={nofollow}
|
|
270
|
+
onChange={setAProp("nofollow", { checked: true })}
|
|
271
|
+
/>
|
|
272
|
+
<label className="form-check-label">Nofollow</label>
|
|
273
|
+
</div>
|
|
274
|
+
<div className="form-check">
|
|
275
|
+
<input
|
|
276
|
+
className="form-check-input"
|
|
277
|
+
name="block"
|
|
278
|
+
type="checkbox"
|
|
279
|
+
checked={target_blank}
|
|
280
|
+
onChange={setAProp("target_blank", { checked: true })}
|
|
281
|
+
/>
|
|
282
|
+
<label className="form-check-label">Open in new tab</label>
|
|
283
|
+
</div>
|
|
284
|
+
<div className="form-check">
|
|
285
|
+
<input
|
|
286
|
+
className="form-check-input"
|
|
287
|
+
name="block"
|
|
288
|
+
type="checkbox"
|
|
289
|
+
checked={in_modal}
|
|
290
|
+
onChange={setAProp("in_modal", { checked: true })}
|
|
291
|
+
/>
|
|
292
|
+
<label className="form-check-label">Open in popup modal?</label>
|
|
293
|
+
</div>
|
|
294
|
+
|
|
295
|
+
{["filter", "page"].includes(options.mode) && (
|
|
268
296
|
<div className="form-check">
|
|
269
297
|
<input
|
|
270
298
|
className="form-check-input"
|
|
271
299
|
name="block"
|
|
272
300
|
type="checkbox"
|
|
273
|
-
checked={
|
|
274
|
-
onChange={setAProp("
|
|
301
|
+
checked={transfer_state}
|
|
302
|
+
onChange={setAProp("transfer_state", { checked: true })}
|
|
275
303
|
/>
|
|
276
|
-
<label className="form-check-label">
|
|
304
|
+
<label className="form-check-label">Transfer state</label>
|
|
277
305
|
</div>
|
|
306
|
+
)}
|
|
278
307
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
type="checkbox"
|
|
285
|
-
checked={transfer_state}
|
|
286
|
-
onChange={setAProp("transfer_state", { checked: true })}
|
|
287
|
-
/>
|
|
288
|
-
<label className="form-check-label">Transfer state</label>
|
|
289
|
-
</div>
|
|
290
|
-
)}
|
|
291
|
-
|
|
292
|
-
<BlockSetting block={block} setProp={setProp} />
|
|
293
|
-
<TextStyleSetting textStyle={textStyle} setProp={setProp} />
|
|
294
|
-
</div>
|
|
295
|
-
);
|
|
296
|
-
};
|
|
308
|
+
<BlockSetting block={block} setProp={setProp} />
|
|
309
|
+
<TextStyleSetting textStyle={textStyle} setProp={setProp} />
|
|
310
|
+
</div>
|
|
311
|
+
);
|
|
312
|
+
};
|
|
297
313
|
|
|
298
314
|
/**
|
|
299
315
|
* @type {object}
|
|
@@ -329,8 +345,7 @@ Link.craft = {
|
|
|
329
345
|
"link_textcol",
|
|
330
346
|
"in_modal",
|
|
331
347
|
"transfer_state",
|
|
332
|
-
"view_state_fml"
|
|
333
|
-
|
|
348
|
+
"view_state_fml",
|
|
334
349
|
],
|
|
335
350
|
},
|
|
336
351
|
};
|