@saltcorn/builder 0.7.4 → 0.8.0-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 +1 -1
- package/package.json +1 -1
- package/src/components/elements/Aggregation.js +1 -0
- package/src/components/elements/Container.js +738 -741
- package/src/components/elements/Image.js +228 -227
- package/src/components/elements/View.js +185 -140
- package/src/components/elements/ViewLink.js +193 -147
- package/src/components/elements/utils.js +4 -2
- package/src/components/storage.js +381 -380
|
@@ -37,48 +37,49 @@ export /**
|
|
|
37
37
|
* @subcategory components
|
|
38
38
|
* @namespace
|
|
39
39
|
*/
|
|
40
|
-
const ViewLink = ({
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
40
|
+
const ViewLink = ({
|
|
41
|
+
name,
|
|
42
|
+
block,
|
|
43
|
+
view_name,
|
|
44
|
+
minRole,
|
|
45
|
+
link_style,
|
|
46
|
+
link_size,
|
|
47
|
+
link_icon,
|
|
48
|
+
inModal,
|
|
49
|
+
label,
|
|
50
|
+
textStyle,
|
|
51
|
+
link_bgcol,
|
|
52
|
+
link_bordercol,
|
|
53
|
+
link_textcol,
|
|
54
|
+
}) => {
|
|
55
|
+
const {
|
|
56
|
+
selected,
|
|
57
|
+
connectors: { connect, drag },
|
|
58
|
+
} = useNode((node) => ({ selected: node.events.selected }));
|
|
59
|
+
const names = name.split(":");
|
|
60
|
+
|
|
61
|
+
const displabel = label || view_name || (names.length > 1 ? names[1] : names[0]);
|
|
62
|
+
return (
|
|
63
|
+
<span
|
|
64
|
+
className={`${textStyle} ${inModal ? "btn btn-secondary btn-sm" : ""} ${selected ? "selected-node" : "is-builder-link"
|
|
65
|
+
} ${link_style} ${link_size}`}
|
|
66
|
+
{...blockProps(block)}
|
|
67
|
+
ref={(dom) => connect(drag(dom))}
|
|
68
|
+
style={
|
|
69
|
+
link_style === "btn btn-custom-color"
|
|
70
|
+
? {
|
|
70
71
|
backgroundColor: link_bgcol || "#000000",
|
|
71
72
|
borderColor: link_bordercol || "#000000",
|
|
72
73
|
color: link_textcol || "#000000",
|
|
73
74
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
};
|
|
75
|
+
: {}
|
|
76
|
+
}
|
|
77
|
+
>
|
|
78
|
+
{link_icon ? <i className={`${link_icon} me-1`}></i> : ""}
|
|
79
|
+
{displabel}
|
|
80
|
+
</span>
|
|
81
|
+
);
|
|
82
|
+
};
|
|
82
83
|
|
|
83
84
|
export /**
|
|
84
85
|
* @returns {div}
|
|
@@ -86,122 +87,165 @@ export /**
|
|
|
86
87
|
* @subcategory components
|
|
87
88
|
* @namespace
|
|
88
89
|
*/
|
|
89
|
-
const ViewLinkSettings = () => {
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
errorString =
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
90
|
+
const ViewLinkSettings = () => {
|
|
91
|
+
const node = useNode((node) => ({
|
|
92
|
+
name: node.data.props.name,
|
|
93
|
+
block: node.data.props.block,
|
|
94
|
+
minRole: node.data.props.minRole,
|
|
95
|
+
isFormula: node.data.props.isFormula,
|
|
96
|
+
label: node.data.props.label,
|
|
97
|
+
inModal: node.data.props.inModal,
|
|
98
|
+
link_target_blank: node.data.props.link_target_blank,
|
|
99
|
+
link_style: node.data.props.link_style,
|
|
100
|
+
link_size: node.data.props.link_size,
|
|
101
|
+
link_icon: node.data.props.link_icon,
|
|
102
|
+
textStyle: node.data.props.textStyle,
|
|
103
|
+
link_bgcol: node.data.props.link_bgcol,
|
|
104
|
+
link_bordercol: node.data.props.link_bordercol,
|
|
105
|
+
link_textcol: node.data.props.link_textcol,
|
|
106
|
+
extra_state_fml: node.data.props.extra_state_fml,
|
|
107
|
+
view_name: node.data.props.view_name,
|
|
108
|
+
}));
|
|
109
|
+
const {
|
|
110
|
+
actions: { setProp },
|
|
111
|
+
name,
|
|
112
|
+
block,
|
|
113
|
+
minRole,
|
|
114
|
+
label,
|
|
115
|
+
isFormula,
|
|
116
|
+
inModal,
|
|
117
|
+
textStyle,
|
|
118
|
+
extra_state_fml,
|
|
119
|
+
view_name,
|
|
120
|
+
link_target_blank
|
|
121
|
+
} = node;
|
|
122
|
+
const options = useContext(optionsCtx);
|
|
123
|
+
let errorString = false;
|
|
124
|
+
try {
|
|
125
|
+
Function("return " + extra_state_fml);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
errorString = error.message;
|
|
128
|
+
}
|
|
129
|
+
const setAProp = setAPropGen(setProp);
|
|
130
|
+
//legacy values
|
|
131
|
+
const use_view_name
|
|
132
|
+
= view_name || (name && (names => names.length > 1 ? names[1] : names[0])(name.split(":")))
|
|
133
|
+
const set_view_name = (e) => {
|
|
134
|
+
if (e.target) {
|
|
135
|
+
const target_value = e.target.value;
|
|
136
|
+
setProp((prop) => (prop.view_name = target_value));
|
|
137
|
+
if (target_value !== use_view_name) {
|
|
138
|
+
setProp((prop) => (prop.name = options.view_relation_opts[target_value][0].value));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
return (
|
|
143
|
+
<div>
|
|
144
|
+
<table className="w-100">
|
|
145
|
+
<tbody>
|
|
146
|
+
<tr>
|
|
147
|
+
<td colSpan="2">
|
|
148
|
+
<label>View to link to</label>
|
|
149
|
+
<select
|
|
150
|
+
value={use_view_name}
|
|
151
|
+
className="form-control form-select"
|
|
152
|
+
onChange={set_view_name}
|
|
153
|
+
onBlur={set_view_name}
|
|
154
|
+
>
|
|
155
|
+
{options.view_name_opts.map((f, ix) => (
|
|
156
|
+
<option key={ix} value={f.name}>
|
|
157
|
+
{f.label}
|
|
158
|
+
</option>
|
|
159
|
+
))}
|
|
160
|
+
</select>
|
|
161
|
+
</td>
|
|
162
|
+
</tr>
|
|
163
|
+
<tr>
|
|
164
|
+
<td colSpan="2">
|
|
165
|
+
<label>Relation</label>
|
|
166
|
+
<select
|
|
167
|
+
value={name}
|
|
168
|
+
className="form-control form-select"
|
|
169
|
+
onChange={setAProp("name")}
|
|
170
|
+
onBlur={setAProp("name")}
|
|
171
|
+
>
|
|
172
|
+
{(options.view_relation_opts[use_view_name] || []).map((f, ix) => (
|
|
173
|
+
<option key={ix} value={f.value}>
|
|
174
|
+
{f.label}
|
|
175
|
+
</option>
|
|
176
|
+
))}
|
|
177
|
+
</select>
|
|
178
|
+
</td>
|
|
179
|
+
</tr>
|
|
180
|
+
<tr>
|
|
181
|
+
<td colSpan="2">
|
|
182
|
+
<label>Label (leave blank for default)</label>
|
|
183
|
+
<OrFormula nodekey="label" {...{ setProp, isFormula, node }}>
|
|
184
|
+
<input
|
|
185
|
+
type="text"
|
|
186
|
+
className="viewlink-label form-control"
|
|
187
|
+
value={label}
|
|
188
|
+
onChange={setAProp("label")}
|
|
189
|
+
/>
|
|
190
|
+
</OrFormula>
|
|
191
|
+
</td>
|
|
192
|
+
</tr>
|
|
193
|
+
<tr>
|
|
194
|
+
<td colSpan="2">
|
|
195
|
+
<label>Extra state Formula <FormulaTooltip /></label>
|
|
150
196
|
<input
|
|
151
197
|
type="text"
|
|
152
198
|
className="viewlink-label form-control"
|
|
153
|
-
value={
|
|
154
|
-
onChange={setAProp("
|
|
199
|
+
value={extra_state_fml}
|
|
200
|
+
onChange={setAProp("extra_state_fml")}
|
|
155
201
|
/>
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
type="text"
|
|
164
|
-
className="viewlink-label form-control"
|
|
165
|
-
value={extra_state_fml}
|
|
166
|
-
onChange={setAProp("extra_state_fml")}
|
|
167
|
-
/>
|
|
168
|
-
{errorString ? (
|
|
169
|
-
<small className="text-danger font-monospace d-block">
|
|
170
|
-
{errorString}
|
|
171
|
-
</small>
|
|
172
|
-
) : null}
|
|
173
|
-
</td>
|
|
174
|
-
</tr>
|
|
202
|
+
{errorString ? (
|
|
203
|
+
<small className="text-danger font-monospace d-block">
|
|
204
|
+
{errorString}
|
|
205
|
+
</small>
|
|
206
|
+
) : null}
|
|
207
|
+
</td>
|
|
208
|
+
</tr>
|
|
175
209
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
210
|
+
<ButtonOrLinkSettingsRows
|
|
211
|
+
setProp={setProp}
|
|
212
|
+
keyPrefix="link_"
|
|
213
|
+
btnClass="btn"
|
|
214
|
+
values={node}
|
|
215
|
+
linkFirst={true}
|
|
216
|
+
/>
|
|
217
|
+
</tbody>
|
|
218
|
+
</table>
|
|
219
|
+
<div className="form-check">
|
|
220
|
+
<input
|
|
221
|
+
className="form-check-input"
|
|
222
|
+
name="block"
|
|
223
|
+
type="checkbox"
|
|
224
|
+
checked={link_target_blank}
|
|
225
|
+
onChange={setAProp("link_target_blank", { checked: true })}
|
|
182
226
|
/>
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
227
|
+
<label className="form-check-label">Open in new tab</label>
|
|
228
|
+
</div>
|
|
229
|
+
<div className="form-check">
|
|
230
|
+
<input
|
|
231
|
+
className="form-check-input"
|
|
232
|
+
name="block"
|
|
233
|
+
type="checkbox"
|
|
234
|
+
checked={inModal}
|
|
235
|
+
onChange={setAProp("inModal", { checked: true })}
|
|
236
|
+
/>
|
|
237
|
+
<label className="form-check-label">Open in popup modal?</label>
|
|
238
|
+
</div>
|
|
239
|
+
<BlockSetting block={block} setProp={setProp} />
|
|
240
|
+
<TextStyleSetting textStyle={textStyle} setProp={setProp} />
|
|
241
|
+
<table>
|
|
242
|
+
<tbody>
|
|
243
|
+
<MinRoleSettingRow minRole={minRole} setProp={setProp} />
|
|
244
|
+
</tbody>
|
|
245
|
+
</table>
|
|
194
246
|
</div>
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
<table>
|
|
198
|
-
<tbody>
|
|
199
|
-
<MinRoleSettingRow minRole={minRole} setProp={setProp} />
|
|
200
|
-
</tbody>
|
|
201
|
-
</table>
|
|
202
|
-
</div>
|
|
203
|
-
);
|
|
204
|
-
};
|
|
247
|
+
);
|
|
248
|
+
};
|
|
205
249
|
|
|
206
250
|
/**
|
|
207
251
|
* @type {object}
|
|
@@ -223,8 +267,10 @@ ViewLink.craft = {
|
|
|
223
267
|
{ name: "inModal", segment_name: "in_modal", column_name: "in_modal" },
|
|
224
268
|
"minRole",
|
|
225
269
|
"link_style",
|
|
270
|
+
"view_name",
|
|
226
271
|
"link_icon",
|
|
227
272
|
"link_size",
|
|
273
|
+
"link_target_blank",
|
|
228
274
|
"link_bgcol",
|
|
229
275
|
"link_bordercol",
|
|
230
276
|
"link_textcol",
|
|
@@ -80,11 +80,10 @@ export const BlockOrInlineSetting = ({ block, inline, textStyle, setProp }) =>
|
|
|
80
80
|
|
|
81
81
|
export const FormulaTooltip = () => {
|
|
82
82
|
const { fields } = useContext(optionsCtx);
|
|
83
|
-
console.log(fields);
|
|
84
83
|
return <Tooltip>
|
|
85
84
|
<div>Formulae in Saltcorn are JavaScript expressions based on the current database row.</div>
|
|
86
85
|
{fields ? <Fragment> Variables in scope:
|
|
87
|
-
{fields.map((f, ix) => <Fragment
|
|
86
|
+
{fields.map((f, ix) => <Fragment key={ix}><code>{f.name}</code>{" "}</Fragment>)}</Fragment> : null}
|
|
88
87
|
|
|
89
88
|
<a className="d-block" href="https://wiki.saltcorn.com/view/ShowPage/formulas">Wiki page on formulas</a>
|
|
90
89
|
</Tooltip>
|
|
@@ -700,6 +699,7 @@ export /**
|
|
|
700
699
|
className="form-control form-select"
|
|
701
700
|
value={value || ""}
|
|
702
701
|
onChange={(e) => e.target && myOnChange(e.target.value)}
|
|
702
|
+
onBlur={(e) => e.target && myOnChange(e.target.value)}
|
|
703
703
|
>
|
|
704
704
|
{options.map((o, ix) => (
|
|
705
705
|
<option
|
|
@@ -726,6 +726,7 @@ export /**
|
|
|
726
726
|
className="form-control form-select"
|
|
727
727
|
value={value || ""}
|
|
728
728
|
onChange={(e) => e.target && myOnChange(e.target.value)}
|
|
729
|
+
onBlur={(e) => e.target && myOnChange(e.target.value)}
|
|
729
730
|
>
|
|
730
731
|
<option value={""}></option>
|
|
731
732
|
{Object.entries(options.fonts || {}).map(([nm, ff], ix) => (
|
|
@@ -790,6 +791,7 @@ export /**
|
|
|
790
791
|
className="form-control form-select"
|
|
791
792
|
value={value || ""}
|
|
792
793
|
onChange={(e) => e.target && myOnChange(e.target.value)}
|
|
794
|
+
onBlur={(e) => e.target && myOnChange(e.target.value)}
|
|
793
795
|
>
|
|
794
796
|
{field.options.map((o, ix) => (
|
|
795
797
|
<option key={ix}>{o}</option>
|