@saltcorn/builder 0.7.3 → 0.7.4-beta.2
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 +12 -12
- package/package.json +2 -1
- package/src/components/Builder.js +5 -39
- package/src/components/Library.js +47 -4
- package/src/components/elements/Container.js +2 -1
- package/src/components/elements/DropDownFilter.js +5 -0
- package/src/components/elements/View.js +2 -1
- package/src/components/elements/ViewLink.js +2 -1
- package/src/components/elements/utils.js +671 -647
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/builder",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4-beta.2",
|
|
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",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"react-contenteditable": "3.3.5",
|
|
36
36
|
"react-dom": "16.13.1",
|
|
37
37
|
"react-transition-group": "4.4.1",
|
|
38
|
+
"@tippyjs/react": "4.2.6",
|
|
38
39
|
"webpack": "4.43.0",
|
|
39
40
|
"webpack-cli": "3.3.11",
|
|
40
41
|
"lodash": "4.17.11"
|
|
@@ -58,7 +58,6 @@ import {
|
|
|
58
58
|
} from "./elements/utils";
|
|
59
59
|
import { InitNewElement, Library } from "./Library";
|
|
60
60
|
import { RenderNode } from "./RenderNode";
|
|
61
|
-
import { isEqual } from "lodash";
|
|
62
61
|
const { Provider } = optionsCtx;
|
|
63
62
|
|
|
64
63
|
/**
|
|
@@ -389,47 +388,11 @@ const Builder = ({ options, layout, mode }) => {
|
|
|
389
388
|
const [previews, setPreviews] = useState({});
|
|
390
389
|
const [uploadedFiles, setUploadedFiles] = useState([]);
|
|
391
390
|
const nodekeys = useRef([]);
|
|
392
|
-
const [saveTimeout, setSaveTimeout] = useState(false);
|
|
393
391
|
const [isSaving, setIsSaving] = useState(false);
|
|
394
|
-
const [savedData, setSavedData] = useState(false);
|
|
395
|
-
const doSave = (query) => {
|
|
396
|
-
if (!query.serialize) return;
|
|
397
392
|
|
|
398
|
-
const data = craftToSaltcorn(JSON.parse(query.serialize()));
|
|
399
|
-
const urlroot = options.page_id ? "pageedit" : "viewedit";
|
|
400
|
-
if (savedData === false) {
|
|
401
|
-
//do not save on first call
|
|
402
|
-
setSavedData(data.layout);
|
|
403
|
-
setIsSaving(false);
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
if (isEqual(savedData, data.layout)) return;
|
|
407
|
-
setSavedData(data.layout);
|
|
408
|
-
|
|
409
|
-
fetch(`/${urlroot}/savebuilder/${options.page_id || options.view_id}`, {
|
|
410
|
-
method: "POST", // or 'PUT'
|
|
411
|
-
headers: {
|
|
412
|
-
"Content-Type": "application/json",
|
|
413
|
-
"CSRF-Token": options.csrfToken,
|
|
414
|
-
},
|
|
415
|
-
body: JSON.stringify(data),
|
|
416
|
-
}).then(() => {
|
|
417
|
-
setIsSaving(false);
|
|
418
|
-
});
|
|
419
|
-
};
|
|
420
|
-
const nodesChange = (query) => {
|
|
421
|
-
if (saveTimeout) clearTimeout(saveTimeout);
|
|
422
|
-
setIsSaving(true);
|
|
423
|
-
setSaveTimeout(
|
|
424
|
-
setTimeout(() => {
|
|
425
|
-
doSave(query);
|
|
426
|
-
setSaveTimeout(false);
|
|
427
|
-
}, 500)
|
|
428
|
-
);
|
|
429
|
-
};
|
|
430
393
|
return (
|
|
431
394
|
<ErrorBoundary>
|
|
432
|
-
<Editor onRender={RenderNode}
|
|
395
|
+
<Editor onRender={RenderNode}>
|
|
433
396
|
<Provider value={options}>
|
|
434
397
|
<PreviewCtx.Provider
|
|
435
398
|
value={{ previews, setPreviews, uploadedFiles, setUploadedFiles }}
|
|
@@ -437,7 +400,10 @@ const Builder = ({ options, layout, mode }) => {
|
|
|
437
400
|
<div className="row" style={{ marginTop: "-5px" }}>
|
|
438
401
|
<div className="col-sm-auto left-builder-col">
|
|
439
402
|
<div className="componets-and-library-accordion toolbox-card">
|
|
440
|
-
<InitNewElement
|
|
403
|
+
<InitNewElement
|
|
404
|
+
nodekeys={nodekeys}
|
|
405
|
+
setIsSaving={setIsSaving}
|
|
406
|
+
/>
|
|
441
407
|
<Accordion>
|
|
442
408
|
<div className="card mt-1" accordiontitle="Components">
|
|
443
409
|
{{
|
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
* @subcategory components
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, {
|
|
7
|
+
import React, {
|
|
8
|
+
useEffect,
|
|
9
|
+
useContext,
|
|
10
|
+
useState,
|
|
11
|
+
Fragment,
|
|
12
|
+
useRef,
|
|
13
|
+
} from "react";
|
|
8
14
|
import { useEditor, useNode } from "@craftjs/core";
|
|
9
15
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
10
16
|
import { faPlus, faTimes } from "@fortawesome/free-solid-svg-icons";
|
|
@@ -13,10 +19,11 @@ import faIcons from "./elements/faicons";
|
|
|
13
19
|
import { craftToSaltcorn, layoutToNodes } from "./storage";
|
|
14
20
|
import optionsCtx from "./context";
|
|
15
21
|
import { WrapElem } from "./Toolbox";
|
|
22
|
+
import { isEqual } from "lodash";
|
|
16
23
|
|
|
17
24
|
/**
|
|
18
|
-
*
|
|
19
|
-
* @param {object[]} xs
|
|
25
|
+
*
|
|
26
|
+
* @param {object[]} xs
|
|
20
27
|
* @returns {object[]}
|
|
21
28
|
*/
|
|
22
29
|
const twoByTwos = (xs) => {
|
|
@@ -67,10 +74,38 @@ export /**
|
|
|
67
74
|
* @subcategory components
|
|
68
75
|
* @namespace
|
|
69
76
|
*/
|
|
70
|
-
const InitNewElement = ({ nodekeys }) => {
|
|
77
|
+
const InitNewElement = ({ nodekeys, setIsSaving }) => {
|
|
78
|
+
const [saveTimeout, setSaveTimeout] = useState(false);
|
|
79
|
+
const savedData = useRef(false);
|
|
71
80
|
const { actions, query, connectors } = useEditor((state, query) => {
|
|
72
81
|
return {};
|
|
73
82
|
});
|
|
83
|
+
const options = useContext(optionsCtx);
|
|
84
|
+
const doSave = (query) => {
|
|
85
|
+
if (!query.serialize) return;
|
|
86
|
+
|
|
87
|
+
const data = craftToSaltcorn(JSON.parse(query.serialize()));
|
|
88
|
+
const urlroot = options.page_id ? "pageedit" : "viewedit";
|
|
89
|
+
if (savedData.current === false) {
|
|
90
|
+
//do not save on first call
|
|
91
|
+
savedData.current = JSON.stringify(data.layout);
|
|
92
|
+
setIsSaving(false);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (isEqual(savedData.current, JSON.stringify(data.layout))) return;
|
|
96
|
+
savedData.current = JSON.stringify(data.layout);
|
|
97
|
+
|
|
98
|
+
fetch(`/${urlroot}/savebuilder/${options.page_id || options.view_id}`, {
|
|
99
|
+
method: "POST", // or 'PUT'
|
|
100
|
+
headers: {
|
|
101
|
+
"Content-Type": "application/json",
|
|
102
|
+
"CSRF-Token": options.csrfToken,
|
|
103
|
+
},
|
|
104
|
+
body: JSON.stringify(data),
|
|
105
|
+
}).then(() => {
|
|
106
|
+
setIsSaving(false);
|
|
107
|
+
});
|
|
108
|
+
};
|
|
74
109
|
const onNodesChange = (arg, arg1) => {
|
|
75
110
|
const nodes = arg.getSerializedNodes();
|
|
76
111
|
const newNodeIds = [];
|
|
@@ -98,6 +133,14 @@ const InitNewElement = ({ nodekeys }) => {
|
|
|
98
133
|
actions.selectNode(id);
|
|
99
134
|
}
|
|
100
135
|
}
|
|
136
|
+
if (saveTimeout) clearTimeout(saveTimeout);
|
|
137
|
+
setIsSaving(true);
|
|
138
|
+
setSaveTimeout(
|
|
139
|
+
setTimeout(() => {
|
|
140
|
+
doSave(query);
|
|
141
|
+
setSaveTimeout(false);
|
|
142
|
+
}, 500)
|
|
143
|
+
);
|
|
101
144
|
};
|
|
102
145
|
useEffect(() => {
|
|
103
146
|
const nodes = query.getSerializedNodes();
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
reactifyStyles,
|
|
20
20
|
bstyleopt,
|
|
21
21
|
setAPropGen,
|
|
22
|
+
FormulaTooltip,
|
|
22
23
|
} from "./utils";
|
|
23
24
|
import {
|
|
24
25
|
BorderOuter,
|
|
@@ -757,7 +758,7 @@ const ContainerSettings = () => {
|
|
|
757
758
|
onChange={setAProp("showIfFormula")}
|
|
758
759
|
/>
|
|
759
760
|
<div style={{ marginTop: "-5px" }}>
|
|
760
|
-
<small className="text-muted font-monospace">FORMULA
|
|
761
|
+
<small className="text-muted font-monospace">FORMULA <FormulaTooltip /></small>
|
|
761
762
|
</div>
|
|
762
763
|
</td>
|
|
763
764
|
</tr>
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
fetchViewPreview,
|
|
17
17
|
ConfigForm,
|
|
18
18
|
setAPropGen,
|
|
19
|
+
FormulaTooltip,
|
|
19
20
|
} from "./utils";
|
|
20
21
|
|
|
21
22
|
export /**
|
|
@@ -158,7 +159,7 @@ const ViewSettings = () => {
|
|
|
158
159
|
{(state === "shared" || options.mode === "page") && (
|
|
159
160
|
<Fragment>
|
|
160
161
|
{" "}
|
|
161
|
-
<label>Extra state Formula
|
|
162
|
+
<label>Extra state Formula <FormulaTooltip /></label>
|
|
162
163
|
<input
|
|
163
164
|
type="text"
|
|
164
165
|
className="viewlink-label form-control"
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
TextStyleSetting,
|
|
16
16
|
ButtonOrLinkSettingsRows,
|
|
17
17
|
setAPropGen,
|
|
18
|
+
FormulaTooltip,
|
|
18
19
|
} from "./utils";
|
|
19
20
|
|
|
20
21
|
export /**
|
|
@@ -157,7 +158,7 @@ const ViewLinkSettings = () => {
|
|
|
157
158
|
</tr>
|
|
158
159
|
<tr>
|
|
159
160
|
<td colSpan="2">
|
|
160
|
-
<label>Extra state Formula
|
|
161
|
+
<label>Extra state Formula <FormulaTooltip /></label>
|
|
161
162
|
<input
|
|
162
163
|
type="text"
|
|
163
164
|
className="viewlink-label form-control"
|