@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.
Files changed (40) hide show
  1. package/dist/builder_bundle.js +85 -1
  2. package/dist/builder_bundle.js.LICENSE.txt +65 -0
  3. package/package.json +32 -28
  4. package/src/components/Builder.js +334 -122
  5. package/src/components/Library.js +25 -13
  6. package/src/components/RenderNode.js +6 -6
  7. package/src/components/Toolbox.js +333 -269
  8. package/src/components/elements/Action.js +145 -30
  9. package/src/components/elements/Aggregation.js +20 -23
  10. package/src/components/elements/ArrayManager.js +7 -5
  11. package/src/components/elements/BoxModelEditor.js +19 -17
  12. package/src/components/elements/Card.js +47 -34
  13. package/src/components/elements/Clone.js +74 -2
  14. package/src/components/elements/Column.js +1 -1
  15. package/src/components/elements/Columns.js +27 -25
  16. package/src/components/elements/Container.js +170 -90
  17. package/src/components/elements/DropDownFilter.js +10 -8
  18. package/src/components/elements/DropMenu.js +8 -5
  19. package/src/components/elements/Field.js +9 -7
  20. package/src/components/elements/HTMLCode.js +3 -1
  21. package/src/components/elements/Image.js +20 -15
  22. package/src/components/elements/JoinField.js +15 -11
  23. package/src/components/elements/Link.js +18 -16
  24. package/src/components/elements/ListColumn.js +7 -3
  25. package/src/components/elements/ListColumns.js +4 -1
  26. package/src/components/elements/MonacoEditor.js +4 -2
  27. package/src/components/elements/Page.js +7 -4
  28. package/src/components/elements/RelationBadges.js +16 -11
  29. package/src/components/elements/RelationOnDemandPicker.js +18 -12
  30. package/src/components/elements/SearchBar.js +10 -6
  31. package/src/components/elements/Table.js +72 -65
  32. package/src/components/elements/Tabs.js +18 -15
  33. package/src/components/elements/Text.js +19 -14
  34. package/src/components/elements/ToggleFilter.js +28 -25
  35. package/src/components/elements/View.js +18 -11
  36. package/src/components/elements/ViewLink.js +15 -11
  37. package/src/components/elements/utils.js +224 -55
  38. package/src/components/storage.js +27 -129
  39. package/src/hooks/useTranslation.js +11 -0
  40. 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
- return {
212
- selected: state.events.selected,
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
- selected,
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
- return (
119
- <>
120
- {(isActive || isHover) &&
121
- id !== "ROOT" &&
122
- !(name === "Column" && !isActive)
123
- ? ReactDOM.createPortal(
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 ${