@saltcorn/builder 1.6.0-alpha.6 → 1.6.0-alpha.8
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 +85 -1
- 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 +145 -30
- 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 +18 -11
- 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
|
@@ -12,6 +12,7 @@ import React, {
|
|
|
12
12
|
useRef,
|
|
13
13
|
useMemo,
|
|
14
14
|
} from "react";
|
|
15
|
+
import useTranslation from "../hooks/useTranslation";
|
|
15
16
|
import { useEditor, useNode } from "@craftjs/core";
|
|
16
17
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
17
18
|
import { faPlus, faTimes } from "@fortawesome/free-solid-svg-icons";
|
|
@@ -21,6 +22,14 @@ import optionsCtx from "./context";
|
|
|
21
22
|
import { WrapElem } from "./Toolbox";
|
|
22
23
|
import { isEqual, throttle, chunk } from "lodash";
|
|
23
24
|
|
|
25
|
+
const getSelectedNodes = (selected) => {
|
|
26
|
+
if (!selected) return [];
|
|
27
|
+
if (typeof selected.has === "function") {
|
|
28
|
+
return [...selected];
|
|
29
|
+
}
|
|
30
|
+
return [selected];
|
|
31
|
+
};
|
|
32
|
+
|
|
24
33
|
export /**
|
|
25
34
|
* @param {object} props
|
|
26
35
|
* @param {*} props.name
|
|
@@ -88,6 +97,7 @@ const InitNewElement = ({ nodekeys, savingState, setSavingState }) => {
|
|
|
88
97
|
const { actions, query, connectors } = useEditor((state, query) => {
|
|
89
98
|
return {};
|
|
90
99
|
});
|
|
100
|
+
const { t } = useTranslation();
|
|
91
101
|
const options = useContext(optionsCtx);
|
|
92
102
|
const doSave = (query, keepalive) => {
|
|
93
103
|
if (!query.serialize) return;
|
|
@@ -130,8 +140,8 @@ const InitNewElement = ({ nodekeys, savingState, setSavingState }) => {
|
|
|
130
140
|
.catch((e) => {
|
|
131
141
|
const text =
|
|
132
142
|
e.message === "Failed to fetch"
|
|
133
|
-
? "Network connection lost"
|
|
134
|
-
: e || "Unable to save";
|
|
143
|
+
? t("Network connection lost")
|
|
144
|
+
: e || t("Unable to save");
|
|
135
145
|
// don't log duplicates
|
|
136
146
|
if (savingState.error) setSavingState({ isSaving: false, error: text });
|
|
137
147
|
else {
|
|
@@ -207,11 +217,11 @@ export /**
|
|
|
207
217
|
* @namespace
|
|
208
218
|
*/
|
|
209
219
|
const Library = ({ expanded }) => {
|
|
210
|
-
const { actions, selected, query, connectors } = useEditor((state, query) => {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
});
|
|
220
|
+
const { actions, selected, selectedNodes, query, connectors } = useEditor((state, query) => ({
|
|
221
|
+
selected: getSelectedNodes(state.events.selected)[0] || null,
|
|
222
|
+
selectedNodes: getSelectedNodes(state.events.selected),
|
|
223
|
+
}));
|
|
224
|
+
const { t } = useTranslation();
|
|
215
225
|
const options = useContext(optionsCtx);
|
|
216
226
|
const [adding, setAdding] = useState(false);
|
|
217
227
|
const [newName, setNewName] = useState("");
|
|
@@ -222,9 +232,11 @@ const Library = ({ expanded }) => {
|
|
|
222
232
|
* @returns {void}
|
|
223
233
|
*/
|
|
224
234
|
const addSelected = () => {
|
|
235
|
+
if (!selected && selectedNodes.length === 0) return;
|
|
236
|
+
const nodeToSave = selected || selectedNodes[0];
|
|
225
237
|
const layout = craftToSaltcorn(
|
|
226
238
|
JSON.parse(query.serialize()),
|
|
227
|
-
|
|
239
|
+
nodeToSave,
|
|
228
240
|
options
|
|
229
241
|
);
|
|
230
242
|
const data = { layout, icon, name: newName };
|
|
@@ -255,17 +267,17 @@ const Library = ({ expanded }) => {
|
|
|
255
267
|
id="dropdownMenuButton"
|
|
256
268
|
aria-haspopup="true"
|
|
257
269
|
aria-expanded="false"
|
|
258
|
-
disabled={!selected}
|
|
270
|
+
disabled={!selected && selectedNodes.length === 0}
|
|
259
271
|
onClick={() => setAdding(!adding)}
|
|
260
272
|
>
|
|
261
273
|
<FontAwesomeIcon icon={faPlus} className="me-1" />
|
|
262
|
-
Add
|
|
274
|
+
{t("Add")}
|
|
263
275
|
</button>
|
|
264
276
|
<div
|
|
265
277
|
className={`dropdown-menu py-3 px-4 ${adding ? "show" : ""}`}
|
|
266
278
|
aria-labelledby="dropdownMenuButton"
|
|
267
279
|
>
|
|
268
|
-
<label>Name</label>
|
|
280
|
+
<label>{t("Name")}</label>
|
|
269
281
|
<input
|
|
270
282
|
type="text"
|
|
271
283
|
className="form-control"
|
|
@@ -273,7 +285,7 @@ const Library = ({ expanded }) => {
|
|
|
273
285
|
onChange={(e) => e?.target && setNewName(e.target.value)}
|
|
274
286
|
/>
|
|
275
287
|
<br />
|
|
276
|
-
<label>Icon</label>
|
|
288
|
+
<label>{t("Icon")}</label>
|
|
277
289
|
<FontIconPicker
|
|
278
290
|
className="w-100"
|
|
279
291
|
value={icon}
|
|
@@ -283,7 +295,7 @@ const Library = ({ expanded }) => {
|
|
|
283
295
|
/>
|
|
284
296
|
<button className={`btn btn-primary mt-3`} onClick={addSelected}>
|
|
285
297
|
<FontAwesomeIcon icon={faPlus} className="me-1" />
|
|
286
|
-
Add
|
|
298
|
+
{t("Add")}
|
|
287
299
|
</button>
|
|
288
300
|
<button
|
|
289
301
|
className={`btn btn-outline-secondary ms-2 mt-3`}
|
|
@@ -115,12 +115,12 @@ const RenderNode = ({ render }) => {
|
|
|
115
115
|
sibIx + 1
|
|
116
116
|
);
|
|
117
117
|
};
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
118
|
+
return (
|
|
119
|
+
<>
|
|
120
|
+
{(isActive || isHover) &&
|
|
121
|
+
id !== "ROOT" &&
|
|
122
|
+
!(name === "Column" && !isActive)
|
|
123
|
+
? ReactDOM.createPortal(
|
|
124
124
|
<div
|
|
125
125
|
ref={currentRef}
|
|
126
126
|
className={`selected-indicator ${
|