@saltcorn/builder 1.6.0-alpha.7 → 1.6.0-alpha.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 +104014 -2
- package/dist/builder_bundle.js.LICENSE.txt +65 -0
- package/package.json +32 -28
- package/src/components/Builder.js +334 -122
- package/src/components/Library.js +25 -13
- package/src/components/RenderNode.js +6 -6
- package/src/components/Toolbox.js +333 -269
- package/src/components/elements/Action.js +144 -29
- package/src/components/elements/Aggregation.js +20 -23
- package/src/components/elements/ArrayManager.js +7 -5
- package/src/components/elements/BoxModelEditor.js +19 -17
- package/src/components/elements/Card.js +47 -34
- package/src/components/elements/Clone.js +74 -2
- package/src/components/elements/Column.js +1 -1
- package/src/components/elements/Columns.js +27 -25
- package/src/components/elements/Container.js +170 -90
- package/src/components/elements/DropDownFilter.js +10 -8
- package/src/components/elements/DropMenu.js +8 -5
- package/src/components/elements/Field.js +9 -7
- package/src/components/elements/HTMLCode.js +3 -1
- package/src/components/elements/Image.js +20 -15
- package/src/components/elements/JoinField.js +15 -11
- package/src/components/elements/Link.js +18 -16
- package/src/components/elements/ListColumn.js +7 -3
- package/src/components/elements/ListColumns.js +4 -1
- package/src/components/elements/MonacoEditor.js +4 -2
- package/src/components/elements/Page.js +7 -4
- package/src/components/elements/RelationBadges.js +16 -11
- package/src/components/elements/RelationOnDemandPicker.js +18 -12
- package/src/components/elements/SearchBar.js +10 -6
- package/src/components/elements/Table.js +72 -65
- package/src/components/elements/Tabs.js +18 -15
- package/src/components/elements/Text.js +19 -14
- package/src/components/elements/ToggleFilter.js +28 -25
- package/src/components/elements/View.js +36 -18
- package/src/components/elements/ViewLink.js +15 -11
- package/src/components/elements/utils.js +224 -55
- package/src/components/storage.js +27 -129
- package/src/hooks/useTranslation.js +11 -0
- package/src/index.js +6 -3
|
@@ -21,12 +21,14 @@ import {
|
|
|
21
21
|
} from "./utils";
|
|
22
22
|
import ContentEditable from "react-contenteditable";
|
|
23
23
|
import optionsCtx from "../context";
|
|
24
|
-
import CKEditor from "ckeditor4-react";
|
|
24
|
+
import { CKEditor } from "ckeditor4-react";
|
|
25
25
|
import FontIconPicker from "@fonticonpicker/react-fonticonpicker";
|
|
26
26
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
27
27
|
import fas from "@fortawesome/free-solid-svg-icons";
|
|
28
28
|
import far from "@fortawesome/free-regular-svg-icons";
|
|
29
29
|
import { SingleLineEditor } from "./MonacoEditor";
|
|
30
|
+
import useTranslation from "../../hooks/useTranslation";
|
|
31
|
+
|
|
30
32
|
const ckConfig = {
|
|
31
33
|
toolbarGroups: [
|
|
32
34
|
{ name: "document", groups: ["mode", "document", "doctools"] },
|
|
@@ -109,7 +111,7 @@ const Text = ({
|
|
|
109
111
|
isFormula.text ? "font-monospace" : ""
|
|
110
112
|
} ${selected ? "selected-node" : ""}`}
|
|
111
113
|
ref={(dom) => connect(drag(dom))}
|
|
112
|
-
|
|
114
|
+
onDoubleClick={(e) => selected && setEditable(true)}
|
|
113
115
|
style={{
|
|
114
116
|
...(font ? { fontFamily: font } : {}),
|
|
115
117
|
...reactifyStyles(style || {}),
|
|
@@ -131,7 +133,7 @@ const Text = ({
|
|
|
131
133
|
) : editable ? (
|
|
132
134
|
<ErrorBoundary>
|
|
133
135
|
<CKEditor
|
|
134
|
-
|
|
136
|
+
initData={text || ""}
|
|
135
137
|
style={{ display: "inline" }}
|
|
136
138
|
onChange={(e) =>
|
|
137
139
|
setProp((props) => (props.text = e.editor.getData()))
|
|
@@ -155,7 +157,9 @@ export /**
|
|
|
155
157
|
* @subcategory components
|
|
156
158
|
*/
|
|
157
159
|
const TextSettings = () => {
|
|
160
|
+
const { t } = useTranslation();
|
|
158
161
|
const node = useNode((node) => ({
|
|
162
|
+
id: node.id,
|
|
159
163
|
text: node.data.props.text,
|
|
160
164
|
block: node.data.props.block,
|
|
161
165
|
inline: node.data.props.inline,
|
|
@@ -198,17 +202,18 @@ const TextSettings = () => {
|
|
|
198
202
|
setProp((prop) => (prop.isFormula.text = checked));
|
|
199
203
|
}}
|
|
200
204
|
/>
|
|
201
|
-
<label className="form-check-label">Formula
|
|
205
|
+
<label className="form-check-label">{t("Formula?")}</label>
|
|
202
206
|
</div>
|
|
203
207
|
)}
|
|
204
|
-
|
|
208
|
+
<label>{t("Text to display")}</label>
|
|
205
209
|
{allowFormula && isFormula.text ? (
|
|
206
210
|
<SingleLineEditor setProp={setProp} value={text} propKey="text" />
|
|
207
211
|
) : (
|
|
208
212
|
<ErrorBoundary>
|
|
209
213
|
<div className="border">
|
|
210
214
|
<CKEditor
|
|
211
|
-
|
|
215
|
+
key={node.id}
|
|
216
|
+
initData={text || ""}
|
|
212
217
|
onChange={(e) => {
|
|
213
218
|
if (e.editor) {
|
|
214
219
|
const text = e.editor.getData();
|
|
@@ -223,7 +228,7 @@ const TextSettings = () => {
|
|
|
223
228
|
)}
|
|
224
229
|
{mode === "edit" && (
|
|
225
230
|
<Fragment>
|
|
226
|
-
<label>Label for Field</label>
|
|
231
|
+
<label>{t("Label for Field")}</label>
|
|
227
232
|
<select
|
|
228
233
|
value={labelFor}
|
|
229
234
|
onChange={setAProp("labelFor")}
|
|
@@ -243,7 +248,7 @@ const TextSettings = () => {
|
|
|
243
248
|
<TextStyleRow textStyle={textStyle} setProp={setProp} />
|
|
244
249
|
<tr>
|
|
245
250
|
<td>
|
|
246
|
-
<label>Icon</label>
|
|
251
|
+
<label>{t("Icon")}</label>
|
|
247
252
|
</td>
|
|
248
253
|
<td>
|
|
249
254
|
<FontIconPicker
|
|
@@ -258,7 +263,7 @@ const TextSettings = () => {
|
|
|
258
263
|
<SettingsRow
|
|
259
264
|
field={{
|
|
260
265
|
name: "font",
|
|
261
|
-
label: "Font family",
|
|
266
|
+
label: t("Font family"),
|
|
262
267
|
type: "Font",
|
|
263
268
|
}}
|
|
264
269
|
node={node}
|
|
@@ -267,7 +272,7 @@ const TextSettings = () => {
|
|
|
267
272
|
<SettingsRow
|
|
268
273
|
field={{
|
|
269
274
|
name: "font-size",
|
|
270
|
-
label: "Font size",
|
|
275
|
+
label: t("Font size"),
|
|
271
276
|
type: "DimUnits",
|
|
272
277
|
}}
|
|
273
278
|
node={node}
|
|
@@ -277,7 +282,7 @@ const TextSettings = () => {
|
|
|
277
282
|
<SettingsRow
|
|
278
283
|
field={{
|
|
279
284
|
name: "font-weight",
|
|
280
|
-
label: "Weight",
|
|
285
|
+
label: t("Weight"),
|
|
281
286
|
type: "Integer",
|
|
282
287
|
min: 100,
|
|
283
288
|
max: 900,
|
|
@@ -290,7 +295,7 @@ const TextSettings = () => {
|
|
|
290
295
|
<SettingsRow
|
|
291
296
|
field={{
|
|
292
297
|
name: "line-height",
|
|
293
|
-
label: "Line height",
|
|
298
|
+
label: t("Line height"),
|
|
294
299
|
type: "DimUnits",
|
|
295
300
|
}}
|
|
296
301
|
node={node}
|
|
@@ -298,7 +303,7 @@ const TextSettings = () => {
|
|
|
298
303
|
isStyle={true}
|
|
299
304
|
/>
|
|
300
305
|
<tr>
|
|
301
|
-
<td>Class</td>
|
|
306
|
+
<td>{t("Class")}</td>
|
|
302
307
|
<td>
|
|
303
308
|
<input
|
|
304
309
|
type="text"
|
|
@@ -312,7 +317,7 @@ const TextSettings = () => {
|
|
|
312
317
|
<SettingsRow
|
|
313
318
|
field={{
|
|
314
319
|
name: "color",
|
|
315
|
-
label: "Color",
|
|
320
|
+
label: t("Color"),
|
|
316
321
|
type: "Color",
|
|
317
322
|
}}
|
|
318
323
|
node={node}
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* @subcategory components / elements
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, { useContext,
|
|
7
|
+
import React, { Fragment, useState, useContext, useEffect } from "react";
|
|
8
8
|
import { useNode } from "@craftjs/core";
|
|
9
|
+
import useTranslation from "../../hooks/useTranslation";
|
|
9
10
|
import optionsCtx from "../context";
|
|
10
11
|
import { blockProps, BlockSetting, setAPropGen, buildOptions } from "./utils";
|
|
11
12
|
|
|
@@ -32,6 +33,7 @@ const ToggleFilter = ({
|
|
|
32
33
|
size,
|
|
33
34
|
style,
|
|
34
35
|
}) => {
|
|
36
|
+
const { t } = useTranslation();
|
|
35
37
|
const {
|
|
36
38
|
selected,
|
|
37
39
|
connectors: { connect, drag },
|
|
@@ -43,7 +45,7 @@ const ToggleFilter = ({
|
|
|
43
45
|
ref={(dom) => connect(drag(dom))}
|
|
44
46
|
>
|
|
45
47
|
<button className={`btn btn-outline-${style || "primary"} ${size}`}>
|
|
46
|
-
{label || value || preset_value || "Set label"}
|
|
48
|
+
{label || value || preset_value || t("Set label")}
|
|
47
49
|
</button>
|
|
48
50
|
</span>
|
|
49
51
|
);
|
|
@@ -56,6 +58,7 @@ export /**
|
|
|
56
58
|
* @subcategory components
|
|
57
59
|
*/
|
|
58
60
|
const ToggleFilterSettings = () => {
|
|
61
|
+
const { t } = useTranslation();
|
|
59
62
|
const {
|
|
60
63
|
actions: { setProp },
|
|
61
64
|
name,
|
|
@@ -85,7 +88,7 @@ const ToggleFilterSettings = () => {
|
|
|
85
88
|
<tbody>
|
|
86
89
|
<tr>
|
|
87
90
|
<td>
|
|
88
|
-
<label>Field</label>
|
|
91
|
+
<label>{t("Field")}</label>
|
|
89
92
|
</td>
|
|
90
93
|
<td>
|
|
91
94
|
<select
|
|
@@ -115,7 +118,7 @@ const ToggleFilterSettings = () => {
|
|
|
115
118
|
</tr>
|
|
116
119
|
<tr>
|
|
117
120
|
<td>
|
|
118
|
-
<label>Value</label>
|
|
121
|
+
<label>{t("Value")}</label>
|
|
119
122
|
</td>
|
|
120
123
|
<td>
|
|
121
124
|
{isBool ? (
|
|
@@ -124,9 +127,9 @@ const ToggleFilterSettings = () => {
|
|
|
124
127
|
className="w-100 form-select"
|
|
125
128
|
onChange={setAProp("value")}
|
|
126
129
|
>
|
|
127
|
-
<option value="on">True</option>
|
|
128
|
-
<option value="off">False</option>
|
|
129
|
-
<option value="?">Both</option>
|
|
130
|
+
<option value="on">{t("True")}</option>
|
|
131
|
+
<option value="off">{t("False")}</option>
|
|
132
|
+
<option value="?">{t("Both")}</option>
|
|
130
133
|
</select>
|
|
131
134
|
) : (
|
|
132
135
|
<input
|
|
@@ -140,7 +143,7 @@ const ToggleFilterSettings = () => {
|
|
|
140
143
|
{preset_options && preset_options.length > 0 ? (
|
|
141
144
|
<tr>
|
|
142
145
|
<td>
|
|
143
|
-
<label>Preset</label>
|
|
146
|
+
<label>{t("Preset")}</label>
|
|
144
147
|
</td>
|
|
145
148
|
<td>
|
|
146
149
|
<select
|
|
@@ -160,7 +163,7 @@ const ToggleFilterSettings = () => {
|
|
|
160
163
|
) : null}
|
|
161
164
|
<tr>
|
|
162
165
|
<td>
|
|
163
|
-
<label>Label</label>
|
|
166
|
+
<label>{t("Label")}</label>
|
|
164
167
|
</td>
|
|
165
168
|
<td>
|
|
166
169
|
<input
|
|
@@ -172,7 +175,7 @@ const ToggleFilterSettings = () => {
|
|
|
172
175
|
</tr>
|
|
173
176
|
<tr>
|
|
174
177
|
<td>
|
|
175
|
-
<label>Button size</label>
|
|
178
|
+
<label>{t("Button size")}</label>
|
|
176
179
|
</td>
|
|
177
180
|
<td>
|
|
178
181
|
<select
|
|
@@ -180,18 +183,18 @@ const ToggleFilterSettings = () => {
|
|
|
180
183
|
value={size}
|
|
181
184
|
onChange={setAProp("size")}
|
|
182
185
|
>
|
|
183
|
-
<option value="">Standard</option>
|
|
184
|
-
<option value="btn-lg">Large</option>
|
|
185
|
-
<option value="btn-sm">Small</option>
|
|
186
|
-
<option value="btn-block">Block</option>
|
|
187
|
-
<option value="btn-block btn-lg">Large block</option>
|
|
188
|
-
<option value="btn-block btn-sm">Small block</option>
|
|
186
|
+
<option value="">{t("Standard")}</option>
|
|
187
|
+
<option value="btn-lg">{t("Large")}</option>
|
|
188
|
+
<option value="btn-sm">{t("Small")}</option>
|
|
189
|
+
<option value="btn-block">{t("Block")}</option>
|
|
190
|
+
<option value="btn-block btn-lg">{t("Large block")}</option>
|
|
191
|
+
<option value="btn-block btn-sm">{t("Small block")}</option>
|
|
189
192
|
</select>
|
|
190
193
|
</td>
|
|
191
194
|
</tr>
|
|
192
195
|
<tr>
|
|
193
196
|
<td>
|
|
194
|
-
<label>Button style</label>
|
|
197
|
+
<label>{t("Button style")}</label>
|
|
195
198
|
</td>
|
|
196
199
|
<td>
|
|
197
200
|
<select
|
|
@@ -201,14 +204,14 @@ const ToggleFilterSettings = () => {
|
|
|
201
204
|
>
|
|
202
205
|
{buildOptions(
|
|
203
206
|
[
|
|
204
|
-
"primary",
|
|
205
|
-
"secondary",
|
|
206
|
-
"success",
|
|
207
|
-
"danger",
|
|
208
|
-
"warning",
|
|
209
|
-
"info",
|
|
210
|
-
"light",
|
|
211
|
-
"dark",
|
|
207
|
+
t("primary"),
|
|
208
|
+
t("secondary"),
|
|
209
|
+
t("success"),
|
|
210
|
+
t("danger"),
|
|
211
|
+
t("warning"),
|
|
212
|
+
t("info"),
|
|
213
|
+
t("light"),
|
|
214
|
+
t("dark"),
|
|
212
215
|
],
|
|
213
216
|
{ valAttr: true, capitalize: true }
|
|
214
217
|
)}
|
|
@@ -8,6 +8,7 @@ import React, { Fragment, useEffect, useMemo } from "react";
|
|
|
8
8
|
import { useNode } from "@craftjs/core";
|
|
9
9
|
import optionsCtx from "../context";
|
|
10
10
|
import previewCtx from "../preview_context";
|
|
11
|
+
import useTranslation from "../../hooks/useTranslation";
|
|
11
12
|
import relationsCtx from "../relations_context";
|
|
12
13
|
import Select from "react-select";
|
|
13
14
|
|
|
@@ -19,6 +20,8 @@ import {
|
|
|
19
20
|
HelpTopicLink,
|
|
20
21
|
initialRelation,
|
|
21
22
|
buildLayers,
|
|
23
|
+
reactSelectStyles,
|
|
24
|
+
builderSelectClassName,
|
|
22
25
|
} from "./utils";
|
|
23
26
|
|
|
24
27
|
import { RelationBadges } from "./RelationBadges";
|
|
@@ -47,6 +50,7 @@ const View = ({ name, view, configuration, state }) => {
|
|
|
47
50
|
node_id,
|
|
48
51
|
connectors: { connect, drag },
|
|
49
52
|
} = useNode((node) => ({ selected: node.events.selected, node_id: node.id }));
|
|
53
|
+
const { t } = useTranslation();
|
|
50
54
|
const options = React.useContext(optionsCtx);
|
|
51
55
|
|
|
52
56
|
let viewname = view;
|
|
@@ -81,7 +85,7 @@ const View = ({ name, view, configuration, state }) => {
|
|
|
81
85
|
dangerouslySetInnerHTML={{ __html: myPreview }}
|
|
82
86
|
></div>
|
|
83
87
|
) : (
|
|
84
|
-
|
|
88
|
+
`${t("View")}: ${label}`
|
|
85
89
|
)}
|
|
86
90
|
</div>
|
|
87
91
|
);
|
|
@@ -94,6 +98,7 @@ export /**
|
|
|
94
98
|
* @namespace
|
|
95
99
|
*/
|
|
96
100
|
const ViewSettings = () => {
|
|
101
|
+
const { t } = useTranslation();
|
|
97
102
|
const node = useNode((node) => ({
|
|
98
103
|
name: node.data.props.name,
|
|
99
104
|
view: node.data.props.view,
|
|
@@ -157,6 +162,7 @@ const ViewSettings = () => {
|
|
|
157
162
|
}
|
|
158
163
|
if (viewname && viewname.includes(".")) viewname = viewname.split(".")[0];
|
|
159
164
|
|
|
165
|
+
let cacheWasPopulated = false;
|
|
160
166
|
if (
|
|
161
167
|
finder &&
|
|
162
168
|
!(relationsCache[tableName] && relationsCache[tableName][viewname])
|
|
@@ -173,8 +179,13 @@ const ViewSettings = () => {
|
|
|
173
179
|
);
|
|
174
180
|
relationsCache[tableName] = relationsCache[tableName] || {};
|
|
175
181
|
relationsCache[tableName][viewname] = { relations, layers };
|
|
176
|
-
|
|
182
|
+
cacheWasPopulated = true;
|
|
177
183
|
}
|
|
184
|
+
useEffect(() => {
|
|
185
|
+
if (cacheWasPopulated) {
|
|
186
|
+
setRelationsCache({ ...relationsCache });
|
|
187
|
+
}
|
|
188
|
+
});
|
|
178
189
|
const [relationsData, setRelationsData] = finder
|
|
179
190
|
? React.useState(relationsCache[tableName][viewname])
|
|
180
191
|
: [undefined, undefined];
|
|
@@ -188,18 +199,23 @@ const ViewSettings = () => {
|
|
|
188
199
|
subView.display_type
|
|
189
200
|
);
|
|
190
201
|
}
|
|
191
|
-
|
|
202
|
+
const needsInitialRelation =
|
|
192
203
|
options.mode !== "filter" &&
|
|
193
204
|
subView?.table_id &&
|
|
194
205
|
!safeRelation &&
|
|
195
206
|
!hasLegacyRelation &&
|
|
196
|
-
relationsData?.relations.length > 0
|
|
197
|
-
) {
|
|
207
|
+
relationsData?.relations.length > 0;
|
|
208
|
+
if (needsInitialRelation) {
|
|
198
209
|
safeRelation = initialRelation(relationsData.relations);
|
|
199
|
-
setProp((prop) => {
|
|
200
|
-
prop.relation = safeRelation.relationString;
|
|
201
|
-
});
|
|
202
210
|
}
|
|
211
|
+
useEffect(() => {
|
|
212
|
+
if (needsInitialRelation) {
|
|
213
|
+
const rel = initialRelation(relationsData.relations);
|
|
214
|
+
setProp((prop) => {
|
|
215
|
+
prop.relation = rel.relationString;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}, [needsInitialRelation]);
|
|
203
219
|
const helpContext = { view_name: viewname };
|
|
204
220
|
if (options.tableName) helpContext.srcTable = options.tableName;
|
|
205
221
|
const set_view_name = (e) => {
|
|
@@ -235,7 +251,7 @@ const ViewSettings = () => {
|
|
|
235
251
|
} else
|
|
236
252
|
window.notifyAlert({
|
|
237
253
|
type: "warning",
|
|
238
|
-
text: `${target_value} has no relations`,
|
|
254
|
+
text: `${target_value} ${t("has no relations")}`,
|
|
239
255
|
});
|
|
240
256
|
}
|
|
241
257
|
}
|
|
@@ -262,11 +278,12 @@ const ViewSettings = () => {
|
|
|
262
278
|
<Select
|
|
263
279
|
options={viewOptions}
|
|
264
280
|
value={selectedView}
|
|
265
|
-
className="react-select view-selector"
|
|
281
|
+
className={builderSelectClassName("react-select view-selector")}
|
|
282
|
+
classNamePrefix="builder-select"
|
|
266
283
|
onChange={set_view_name}
|
|
267
284
|
onBlur={set_view_name}
|
|
268
285
|
menuPortalTarget={document.body}
|
|
269
|
-
styles={
|
|
286
|
+
styles={reactSelectStyles()}
|
|
270
287
|
></Select>
|
|
271
288
|
)}
|
|
272
289
|
</div>
|
|
@@ -304,7 +321,8 @@ const ViewSettings = () => {
|
|
|
304
321
|
<Select
|
|
305
322
|
options={viewOptions}
|
|
306
323
|
value={selectedView}
|
|
307
|
-
className="react-select view-selector"
|
|
324
|
+
className={builderSelectClassName("react-select view-selector")}
|
|
325
|
+
classNamePrefix="builder-select"
|
|
308
326
|
onChange={(e) => {
|
|
309
327
|
const target_value = e?.target?.value || e?.value;
|
|
310
328
|
setProp((prop) => {
|
|
@@ -312,7 +330,7 @@ const ViewSettings = () => {
|
|
|
312
330
|
});
|
|
313
331
|
}}
|
|
314
332
|
menuPortalTarget={document.body}
|
|
315
|
-
styles={
|
|
333
|
+
styles={reactSelectStyles()}
|
|
316
334
|
></Select>
|
|
317
335
|
)}
|
|
318
336
|
</div>
|
|
@@ -322,7 +340,7 @@ const ViewSettings = () => {
|
|
|
322
340
|
theview?.viewtemplate === "Edit" &&
|
|
323
341
|
targetTable ? (
|
|
324
342
|
<div>
|
|
325
|
-
<label>Order field</label>
|
|
343
|
+
<label>{t("Order field")}</label>
|
|
326
344
|
<select
|
|
327
345
|
value={order_field}
|
|
328
346
|
className="form-control form-select"
|
|
@@ -341,7 +359,7 @@ const ViewSettings = () => {
|
|
|
341
359
|
{options.mode !== "edit" && (
|
|
342
360
|
<Fragment>
|
|
343
361
|
<div>
|
|
344
|
-
<label>State</label>
|
|
362
|
+
<label>{t("State")}</label>
|
|
345
363
|
<select
|
|
346
364
|
value={state}
|
|
347
365
|
className="form-control form-select"
|
|
@@ -365,7 +383,7 @@ const ViewSettings = () => {
|
|
|
365
383
|
fixed_state_fields &&
|
|
366
384
|
fixed_state_fields.length > 0 && (
|
|
367
385
|
<Fragment>
|
|
368
|
-
<h6>View state fields</h6>
|
|
386
|
+
<h6>{t("View state fields")}</h6>
|
|
369
387
|
<ConfigForm
|
|
370
388
|
fields={fixed_state_fields}
|
|
371
389
|
configuration={configuration || {}}
|
|
@@ -379,7 +397,7 @@ const ViewSettings = () => {
|
|
|
379
397
|
{
|
|
380
398
|
<Fragment>
|
|
381
399
|
<label>
|
|
382
|
-
Extra state Formula
|
|
400
|
+
{t("Extra state Formula")}
|
|
383
401
|
<HelpTopicLink topic="Extra state formula" {...helpContext} />
|
|
384
402
|
</label>
|
|
385
403
|
<SingleLineEditor
|
|
@@ -401,7 +419,7 @@ const ViewSettings = () => {
|
|
|
401
419
|
target="_blank"
|
|
402
420
|
href={`/viewedit/config/${viewname}`}
|
|
403
421
|
>
|
|
404
|
-
Configure this view
|
|
422
|
+
{t("Configure this view")}
|
|
405
423
|
</a>
|
|
406
424
|
) : null}
|
|
407
425
|
</div>
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import React, { useMemo } from "react";
|
|
8
8
|
import { useNode } from "@craftjs/core";
|
|
9
|
+
import useTranslation from "../../hooks/useTranslation";
|
|
9
10
|
import optionsCtx from "../context";
|
|
10
11
|
import relationsCtx from "../relations_context";
|
|
11
12
|
|
|
@@ -20,6 +21,8 @@ import {
|
|
|
20
21
|
HelpTopicLink,
|
|
21
22
|
initialRelation,
|
|
22
23
|
buildLayers,
|
|
24
|
+
reactSelectStyles,
|
|
25
|
+
builderSelectClassName,
|
|
23
26
|
} from "./utils";
|
|
24
27
|
|
|
25
28
|
import { RelationBadges } from "./RelationBadges";
|
|
@@ -102,6 +105,7 @@ export /**
|
|
|
102
105
|
* @namespace
|
|
103
106
|
*/
|
|
104
107
|
const ViewLinkSettings = () => {
|
|
108
|
+
const { t } = useTranslation();
|
|
105
109
|
const node = useNode((node) => ({
|
|
106
110
|
name: node.data.props.name,
|
|
107
111
|
relation: node.data.props.relation,
|
|
@@ -233,7 +237,7 @@ const ViewLinkSettings = () => {
|
|
|
233
237
|
} else
|
|
234
238
|
window.notifyAlert({
|
|
235
239
|
type: "warning",
|
|
236
|
-
text: `${target_value} has no relations`,
|
|
240
|
+
text: `${target_value} ${t("has no relations")}`,
|
|
237
241
|
});
|
|
238
242
|
}
|
|
239
243
|
}
|
|
@@ -245,24 +249,24 @@ const ViewLinkSettings = () => {
|
|
|
245
249
|
value: name,
|
|
246
250
|
}));
|
|
247
251
|
const selectedView = viewOptions.find((v) => v.value === use_view_name);
|
|
252
|
+
|
|
248
253
|
return (
|
|
249
254
|
<div>
|
|
250
255
|
<table className="w-100">
|
|
251
256
|
<tbody>
|
|
252
257
|
<tr>
|
|
253
258
|
<td colSpan="2">
|
|
254
|
-
<label>View to link to</label>
|
|
259
|
+
<label>{t("View to link to")}</label>
|
|
255
260
|
{options.inJestTestingMode ? null : (
|
|
256
261
|
<Select
|
|
257
262
|
options={viewOptions}
|
|
258
|
-
className="react-select viewlink-selector"
|
|
263
|
+
className={builderSelectClassName("react-select viewlink-selector")}
|
|
264
|
+
classNamePrefix="builder-select"
|
|
259
265
|
value={selectedView}
|
|
260
266
|
onChange={set_view_name}
|
|
261
267
|
onBlur={set_view_name}
|
|
262
268
|
menuPortalTarget={document.body}
|
|
263
|
-
styles={
|
|
264
|
-
menuPortal: (base) => ({ ...base, zIndex: 19999 }),
|
|
265
|
-
}}
|
|
269
|
+
styles={reactSelectStyles()}
|
|
266
270
|
></Select>
|
|
267
271
|
)}
|
|
268
272
|
</td>
|
|
@@ -295,7 +299,7 @@ const ViewLinkSettings = () => {
|
|
|
295
299
|
</tr>
|
|
296
300
|
<tr>
|
|
297
301
|
<td colSpan="2">
|
|
298
|
-
<label>Label (leave blank for default)</label>
|
|
302
|
+
<label>{t("Label (leave blank for default)")}</label>
|
|
299
303
|
<OrFormula nodekey="label" {...{ setProp, isFormula, node }}>
|
|
300
304
|
<input
|
|
301
305
|
type="text"
|
|
@@ -309,7 +313,7 @@ const ViewLinkSettings = () => {
|
|
|
309
313
|
<tr>
|
|
310
314
|
<td colSpan="2">
|
|
311
315
|
<label>
|
|
312
|
-
Extra state Formula
|
|
316
|
+
{t("Extra state Formula")}
|
|
313
317
|
<HelpTopicLink topic="Extra state formula" {...helpContext} />
|
|
314
318
|
</label>
|
|
315
319
|
<SingleLineEditor
|
|
@@ -346,7 +350,7 @@ const ViewLinkSettings = () => {
|
|
|
346
350
|
checked={link_target_blank}
|
|
347
351
|
onChange={setAProp("link_target_blank", { checked: true })}
|
|
348
352
|
/>
|
|
349
|
-
<label className="form-check-label">Open in new tab</label>
|
|
353
|
+
<label className="form-check-label">{t("Open in new tab")}</label>
|
|
350
354
|
</div>
|
|
351
355
|
<div className="form-check">
|
|
352
356
|
<input
|
|
@@ -356,7 +360,7 @@ const ViewLinkSettings = () => {
|
|
|
356
360
|
checked={inModal}
|
|
357
361
|
onChange={setAProp("inModal", { checked: true })}
|
|
358
362
|
/>
|
|
359
|
-
<label className="form-check-label">Open in popup modal
|
|
363
|
+
<label className="form-check-label">{t("Open in popup modal?")}</label>
|
|
360
364
|
</div>
|
|
361
365
|
<BlockSetting block={block} setProp={setProp} />
|
|
362
366
|
<TextStyleSetting textStyle={textStyle} setProp={setProp} />
|
|
@@ -370,7 +374,7 @@ const ViewLinkSettings = () => {
|
|
|
370
374
|
target="_blank"
|
|
371
375
|
href={`/viewedit/config/${use_view_name}`}
|
|
372
376
|
>
|
|
373
|
-
Configure this view
|
|
377
|
+
{t("Configure this view")}
|
|
374
378
|
</a>
|
|
375
379
|
</td>
|
|
376
380
|
</tr>
|