@saltcorn/builder 1.6.0-alpha.0 → 1.6.0-alpha.10
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 +4126 -2
- package/dist/builder_bundle.js.LICENSE.txt +18 -51
- package/package.json +31 -27
- package/src/components/Builder.js +334 -122
- package/src/components/Library.js +25 -13
- package/src/components/RenderNode.js +19 -8
- 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 +18 -9
- 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 +37 -10
- 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
|
@@ -11,6 +11,7 @@ import React, {
|
|
|
11
11
|
useEffect,
|
|
12
12
|
useState,
|
|
13
13
|
} from "react";
|
|
14
|
+
import useTranslation from "../../hooks/useTranslation";
|
|
14
15
|
|
|
15
16
|
import { Element, useNode, useEditor } from "@craftjs/core";
|
|
16
17
|
import { setAPropGen, SettingsFromFields } from "./utils";
|
|
@@ -38,6 +39,7 @@ const ListColumn = ({
|
|
|
38
39
|
col_width,
|
|
39
40
|
col_width_units,
|
|
40
41
|
}) => {
|
|
42
|
+
const { t } = useTranslation();
|
|
41
43
|
const {
|
|
42
44
|
selected,
|
|
43
45
|
id,
|
|
@@ -75,16 +77,18 @@ const ListColumn = ({
|
|
|
75
77
|
<div className={`list-column flex-50 p-2`}>
|
|
76
78
|
<div className="d-flex justify-content-between h-100">
|
|
77
79
|
<div className="">
|
|
78
|
-
Column {childIx}
|
|
80
|
+
{t("Column")} {childIx}
|
|
79
81
|
{header_label ? `: ${header_label}` : ""}
|
|
80
82
|
<br />
|
|
81
83
|
{showif ? (
|
|
82
|
-
<span className="badge bg-secondary me-2">showif</span>
|
|
84
|
+
<span className="badge bg-secondary me-2">{t("showif")}</span>
|
|
83
85
|
) : (
|
|
84
86
|
""
|
|
85
87
|
)}
|
|
86
88
|
{alignment && alignment !== "Default" ? (
|
|
87
|
-
<span className="badge bg-secondary me-2">
|
|
89
|
+
<span className="badge bg-secondary me-2">
|
|
90
|
+
{t("Align")} {alignment}
|
|
91
|
+
</span>
|
|
88
92
|
) : (
|
|
89
93
|
""
|
|
90
94
|
)}
|
|
@@ -53,7 +53,10 @@ ListColumns.craft = {
|
|
|
53
53
|
canDrag: () => false,
|
|
54
54
|
canDrop: () => false,
|
|
55
55
|
canMoveIn: (incoming) => {
|
|
56
|
-
|
|
56
|
+
const incomingNodes = Array.isArray(incoming) ? incoming : [incoming];
|
|
57
|
+
return incomingNodes.every(
|
|
58
|
+
(node) => node?.data?.displayName === "ListColumn"
|
|
59
|
+
);
|
|
57
60
|
},
|
|
58
61
|
},
|
|
59
62
|
related: {
|
|
@@ -68,7 +68,7 @@ export const SingleLineEditor = React.forwardRef(
|
|
|
68
68
|
}
|
|
69
69
|
);
|
|
70
70
|
|
|
71
|
-
export const MultiLineCodeEditor = ({ setProp, value, onChange }) => {
|
|
71
|
+
export const MultiLineCodeEditor = ({ setProp, value, onChange, isModalEditor = false }) => {
|
|
72
72
|
const options = React.useContext(optionsCtx);
|
|
73
73
|
|
|
74
74
|
const handleEditorWillMount = (monaco) => {
|
|
@@ -77,7 +77,7 @@ export const MultiLineCodeEditor = ({ setProp, value, onChange }) => {
|
|
|
77
77
|
return (
|
|
78
78
|
<div className="form-control p-0 pt-2">
|
|
79
79
|
<Editor
|
|
80
|
-
height="150px"
|
|
80
|
+
height={isModalEditor ? "100%" : "150px"}
|
|
81
81
|
value={value}
|
|
82
82
|
onChange={onChange}
|
|
83
83
|
defaultLanguage="typescript"
|
|
@@ -86,6 +86,7 @@ export const MultiLineCodeEditor = ({ setProp, value, onChange }) => {
|
|
|
86
86
|
options={multiLineEditorOptions}
|
|
87
87
|
//theme="myCoolTheme"
|
|
88
88
|
beforeMount={handleEditorWillMount}
|
|
89
|
+
className={isModalEditor ? 'code-modal-form' : ''}
|
|
89
90
|
/>
|
|
90
91
|
</div>
|
|
91
92
|
);
|
|
@@ -93,6 +94,7 @@ export const MultiLineCodeEditor = ({ setProp, value, onChange }) => {
|
|
|
93
94
|
|
|
94
95
|
const multiLineEditorOptions = {
|
|
95
96
|
fontSize: "14px",
|
|
97
|
+
minHeight:"80vh",
|
|
96
98
|
fontWeight: "normal",
|
|
97
99
|
wordWrap: "off",
|
|
98
100
|
lineNumbers: "off",
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import React, { Fragment, useContext, useEffect } from "react";
|
|
1
|
+
import React, { Fragment, useState, useContext, useEffect } from "react";
|
|
2
|
+
import useTranslation from "../../hooks/useTranslation";
|
|
2
3
|
import { useNode } from "@craftjs/core";
|
|
3
4
|
import optionsCtx from "../context";
|
|
4
5
|
import previewCtx from "../preview_context";
|
|
5
6
|
import { fetchPagePreview, setAPropGen } from "./utils";
|
|
6
7
|
|
|
7
8
|
export const Page = ({ page }) => {
|
|
9
|
+
const { t } = useTranslation();
|
|
8
10
|
const {
|
|
9
11
|
selected,
|
|
10
12
|
node_id,
|
|
@@ -35,13 +37,14 @@ export const Page = ({ page }) => {
|
|
|
35
37
|
dangerouslySetInnerHTML={{ __html: myPreview }}
|
|
36
38
|
></div>
|
|
37
39
|
) : (
|
|
38
|
-
|
|
40
|
+
`${t("Page")}: ${page}`
|
|
39
41
|
)}
|
|
40
42
|
</div>
|
|
41
43
|
);
|
|
42
44
|
};
|
|
43
45
|
|
|
44
46
|
export const PageSettings = () => {
|
|
47
|
+
const { t } = useTranslation();
|
|
45
48
|
const node = useNode((node) => ({
|
|
46
49
|
page: node.data.props.page,
|
|
47
50
|
node_id: node.id,
|
|
@@ -58,7 +61,7 @@ export const PageSettings = () => {
|
|
|
58
61
|
<div>
|
|
59
62
|
<Fragment>
|
|
60
63
|
<div>
|
|
61
|
-
<label>Page to embed</label>
|
|
64
|
+
<label>{t("Page to embed")}</label>
|
|
62
65
|
<select
|
|
63
66
|
value={page}
|
|
64
67
|
className="form-control form-select"
|
|
@@ -83,7 +86,7 @@ export const PageSettings = () => {
|
|
|
83
86
|
target="_blank"
|
|
84
87
|
href={`/pageedit/edit/${page}`}
|
|
85
88
|
>
|
|
86
|
-
Edit this page
|
|
89
|
+
{t("Edit this page")}
|
|
87
90
|
</a>
|
|
88
91
|
) : null}
|
|
89
92
|
</div>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { Fragment, useState, useContext } from "react";
|
|
2
|
+
import useTranslation from "../../hooks/useTranslation";
|
|
3
|
+
import optionsCtx from "../context";
|
|
2
4
|
import { removeWhitespaces } from "./utils";
|
|
3
5
|
import {
|
|
4
6
|
parseLegacyRelation,
|
|
@@ -6,14 +8,14 @@ import {
|
|
|
6
8
|
Relation,
|
|
7
9
|
} from "@saltcorn/common-code";
|
|
8
10
|
|
|
9
|
-
const buildBadgeCfgs = (sourceTblName, type, path, caches, relString) => {
|
|
11
|
+
const buildBadgeCfgs = (sourceTblName, type, path, caches, relString, t) => {
|
|
10
12
|
if (type === RelationType.OWN)
|
|
11
|
-
return [{ table: `${sourceTblName} (same table)` }];
|
|
13
|
+
return [{ table: `${sourceTblName} ${t("(same table)")}` }];
|
|
12
14
|
else if (type === RelationType.INDEPENDENT)
|
|
13
|
-
return [{ table: "None (no relation)" }];
|
|
14
|
-
else if (path.length === 0) return [{ table: "invalid relation" }];
|
|
15
|
+
return [{ table: t("None (no relation)") }];
|
|
16
|
+
else if (path.length === 0) return [{ table: t("invalid relation") }];
|
|
15
17
|
else if (relString === Relation.fixedUserRelation)
|
|
16
|
-
return [{ table: "logged in user" }];
|
|
18
|
+
return [{ table: t("logged in user") }];
|
|
17
19
|
else {
|
|
18
20
|
const result = [];
|
|
19
21
|
let currentCfg = null;
|
|
@@ -82,6 +84,7 @@ const buildBadge = ({ up, table, down }, index) => {
|
|
|
82
84
|
};
|
|
83
85
|
|
|
84
86
|
export const RelationBadges = ({ view, relation, parentTbl, caches }) => {
|
|
87
|
+
const { t } = useTranslation();
|
|
85
88
|
if (relation) {
|
|
86
89
|
return (
|
|
87
90
|
<div className="overflow-scroll">
|
|
@@ -90,16 +93,17 @@ export const RelationBadges = ({ view, relation, parentTbl, caches }) => {
|
|
|
90
93
|
relation.type,
|
|
91
94
|
relation.path,
|
|
92
95
|
caches,
|
|
93
|
-
relation.relationString
|
|
96
|
+
relation.relationString,
|
|
97
|
+
t
|
|
94
98
|
).map(buildBadge)}
|
|
95
99
|
</div>
|
|
96
100
|
);
|
|
97
101
|
} else {
|
|
98
|
-
if (!view) return buildBadge({ table: "invalid relation" }, 0);
|
|
102
|
+
if (!view) return buildBadge({ table: t("invalid relation") }, 0);
|
|
99
103
|
const [prefix, rest] = view.split(":");
|
|
100
|
-
if (!rest) return buildBadge({ table: "invalid relation" }, 0);
|
|
104
|
+
if (!rest) return buildBadge({ table: t("invalid relation") }, 0);
|
|
101
105
|
const { type, path } = parseLegacyRelation(prefix, rest, parentTbl);
|
|
102
|
-
if (path.length === 0) return buildBadge({ table: "invalid relation" }, 0);
|
|
106
|
+
if (path.length === 0) return buildBadge({ table: t("invalid relation") }, 0);
|
|
103
107
|
else if (path.length === 1 && (type === "Independent" || type === "Own"))
|
|
104
108
|
return (
|
|
105
109
|
<div className="overflow-scroll">
|
|
@@ -114,7 +118,8 @@ export const RelationBadges = ({ view, relation, parentTbl, caches }) => {
|
|
|
114
118
|
type,
|
|
115
119
|
path,
|
|
116
120
|
caches,
|
|
117
|
-
relation.relationString
|
|
121
|
+
relation.relationString,
|
|
122
|
+
t
|
|
118
123
|
).map(buildBadge)}
|
|
119
124
|
</div>
|
|
120
125
|
);
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
/* globals $ */
|
|
2
|
+
|
|
1
3
|
import React from "react";
|
|
4
|
+
import { createRoot } from "react-dom/client";
|
|
2
5
|
import { removeWhitespaces, rand_ident } from "./utils";
|
|
3
|
-
import
|
|
6
|
+
import useTranslation from "../../hooks/useTranslation";
|
|
4
7
|
|
|
5
8
|
const maxLevelDefault = 10;
|
|
9
|
+
const renderInto = (container, node) => {
|
|
10
|
+
if (!container) return;
|
|
11
|
+
const root = container.__scRoot || createRoot(container);
|
|
12
|
+
container.__scRoot = root;
|
|
13
|
+
root.render(node);
|
|
14
|
+
};
|
|
6
15
|
|
|
7
16
|
const keyLabel = (key, type) =>
|
|
8
17
|
type === "fk" ? `${key.name}` : `${key.name} (from ${key.table})`;
|
|
@@ -78,15 +87,11 @@ const Relation = ({ cfg }) => {
|
|
|
78
87
|
maxLevel,
|
|
79
88
|
setMaxLevel,
|
|
80
89
|
};
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
setActiveClasses(level, maxLevel, itemId);
|
|
87
|
-
if (level > maxLevel) setMaxLevel(level);
|
|
88
|
-
}
|
|
89
|
-
);
|
|
90
|
+
const container = document.getElementById(nextDropId);
|
|
91
|
+
renderInto(container, <RelationLayer cfg={layerCfg} />);
|
|
92
|
+
toggleLayers(level, maxLevel, [`#${toggleId}`]);
|
|
93
|
+
setActiveClasses(level, maxLevel, itemId);
|
|
94
|
+
if (level > maxLevel) setMaxLevel(level);
|
|
90
95
|
}}
|
|
91
96
|
>
|
|
92
97
|
{keyLabel(relation, type)}
|
|
@@ -178,6 +183,7 @@ const RelationLayer = ({ cfg }) => {
|
|
|
178
183
|
* @returns
|
|
179
184
|
*/
|
|
180
185
|
export const RelationOnDemandPicker = ({ relations, update }) => {
|
|
186
|
+
const { t } = useTranslation();
|
|
181
187
|
const [maxLevel, setMaxLevel] = React.useState(maxLevelDefault);
|
|
182
188
|
const toggleId = "_relation_picker_toggle_";
|
|
183
189
|
const layerCfg = {
|
|
@@ -189,7 +195,7 @@ export const RelationOnDemandPicker = ({ relations, update }) => {
|
|
|
189
195
|
};
|
|
190
196
|
return (
|
|
191
197
|
<div>
|
|
192
|
-
<label>Relation</label>
|
|
198
|
+
<label>{t("Relation")}</label>
|
|
193
199
|
<div style={{ zIndex: 10000 }} className="dropstart">
|
|
194
200
|
<button
|
|
195
201
|
id={toggleId}
|
|
@@ -201,7 +207,7 @@ export const RelationOnDemandPicker = ({ relations, update }) => {
|
|
|
201
207
|
setMaxLevel(maxLevelDefault);
|
|
202
208
|
}}
|
|
203
209
|
>
|
|
204
|
-
Select
|
|
210
|
+
{t("Select")}
|
|
205
211
|
</button>
|
|
206
212
|
<div className="dropdown-menu">
|
|
207
213
|
<RelationLayer cfg={layerCfg} />
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
* @subcategory components / elements
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, { Fragment, useState } from "react";
|
|
8
|
-
import
|
|
7
|
+
import React, { Fragment, useState, useEffect, useContext } from "react";
|
|
8
|
+
import useTranslation from "../../hooks/useTranslation";
|
|
9
|
+
import optionsCtx from "../context";
|
|
10
|
+
import { useNode, Element } from "@craftjs/core";
|
|
9
11
|
import { Column } from "./Column";
|
|
10
12
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
11
13
|
import { faCaretDown } from "@fortawesome/free-solid-svg-icons";
|
|
@@ -21,13 +23,23 @@ export /**
|
|
|
21
23
|
* @category saltcorn-builder
|
|
22
24
|
* @subcategory components
|
|
23
25
|
*/
|
|
24
|
-
const SearchBar = ({ has_dropdown, children, show_badges }) => {
|
|
26
|
+
const SearchBar = ({ has_dropdown, children, contents, show_badges }) => {
|
|
27
|
+
const { t } = useTranslation();
|
|
25
28
|
const {
|
|
26
29
|
selected,
|
|
27
30
|
connectors: { connect, drag },
|
|
28
31
|
} = useNode((node) => ({ selected: node.events.selected }));
|
|
29
32
|
const [showDropdown, setDropdown] = useState(false);
|
|
30
33
|
const [dropWidth, setDropWidth] = useState(200);
|
|
34
|
+
|
|
35
|
+
const renderContents = () => {
|
|
36
|
+
const actualChildren = contents || children;
|
|
37
|
+
if (!actualChildren) return null;
|
|
38
|
+
if (React.isValidElement(actualChildren)) return actualChildren;
|
|
39
|
+
if (Array.isArray(actualChildren)) return actualChildren;
|
|
40
|
+
return actualChildren;
|
|
41
|
+
};
|
|
42
|
+
|
|
31
43
|
return (
|
|
32
44
|
<div
|
|
33
45
|
className={`input-group ${selected ? "selected-node" : ""}`}
|
|
@@ -47,7 +59,7 @@ const SearchBar = ({ has_dropdown, children, show_badges }) => {
|
|
|
47
59
|
<input
|
|
48
60
|
type="text"
|
|
49
61
|
className="form-control bg-light"
|
|
50
|
-
placeholder="Search..."
|
|
62
|
+
placeholder={t("Search...")}
|
|
51
63
|
readOnly={true}
|
|
52
64
|
/>
|
|
53
65
|
|
|
@@ -70,10 +82,19 @@ const SearchBar = ({ has_dropdown, children, show_badges }) => {
|
|
|
70
82
|
}`}
|
|
71
83
|
style={{ width: dropWidth, left: 0 }}
|
|
72
84
|
>
|
|
73
|
-
<
|
|
85
|
+
<Element canvas id="searchbar-contents" is={Column}>
|
|
86
|
+
{renderContents()}
|
|
87
|
+
</Element>
|
|
74
88
|
</div>
|
|
75
89
|
</Fragment>
|
|
76
90
|
)}
|
|
91
|
+
{!has_dropdown && (
|
|
92
|
+
<div style={{ display: "none" }}>
|
|
93
|
+
<Element canvas id="searchbar-contents" is={Column}>
|
|
94
|
+
{renderContents()}
|
|
95
|
+
</Element>
|
|
96
|
+
</div>
|
|
97
|
+
)}
|
|
77
98
|
</div>
|
|
78
99
|
);
|
|
79
100
|
};
|
|
@@ -85,6 +106,7 @@ export /**
|
|
|
85
106
|
* @subcategory components
|
|
86
107
|
*/
|
|
87
108
|
const SearchBarSettings = () => {
|
|
109
|
+
const { t } = useTranslation();
|
|
88
110
|
const {
|
|
89
111
|
actions: { setProp },
|
|
90
112
|
has_dropdown,
|
|
@@ -107,7 +129,7 @@ const SearchBarSettings = () => {
|
|
|
107
129
|
checked={has_dropdown}
|
|
108
130
|
onChange={setAProp("has_dropdown", { checked: true })}
|
|
109
131
|
/>
|
|
110
|
-
<label className="form-check-label">Has Dropdown</label>
|
|
132
|
+
<label className="form-check-label">{t("Has Dropdown")}</label>
|
|
111
133
|
</div>
|
|
112
134
|
<div className="form-check">
|
|
113
135
|
<input
|
|
@@ -117,7 +139,7 @@ const SearchBarSettings = () => {
|
|
|
117
139
|
checked={show_badges}
|
|
118
140
|
onChange={setAProp("show_badges", { checked: true })}
|
|
119
141
|
/>
|
|
120
|
-
<label className="form-check-label">Show current state badges</label>
|
|
142
|
+
<label className="form-check-label">{t("Show current state badges")}</label>
|
|
121
143
|
</div>
|
|
122
144
|
<div className="form-check">
|
|
123
145
|
<input
|
|
@@ -127,7 +149,7 @@ const SearchBarSettings = () => {
|
|
|
127
149
|
checked={autofocus}
|
|
128
150
|
onChange={setAProp("autofocus", { checked: true })}
|
|
129
151
|
/>
|
|
130
|
-
<label className="form-check-label">Autofocus</label>
|
|
152
|
+
<label className="form-check-label">{t("Autofocus")}</label>
|
|
131
153
|
</div>
|
|
132
154
|
</div>
|
|
133
155
|
);
|
|
@@ -142,11 +164,16 @@ SearchBar.craft = {
|
|
|
142
164
|
has_dropdown: false,
|
|
143
165
|
show_badges: false,
|
|
144
166
|
autofocus: false,
|
|
167
|
+
contents: [],
|
|
145
168
|
},
|
|
146
169
|
related: {
|
|
147
170
|
settings: SearchBarSettings,
|
|
148
171
|
segment_type: "search_bar",
|
|
149
|
-
|
|
150
|
-
|
|
172
|
+
fields: [
|
|
173
|
+
{ name: "has_dropdown" },
|
|
174
|
+
{ name: "show_badges" },
|
|
175
|
+
{ name: "autofocus" },
|
|
176
|
+
{ label: "Contents", name: "contents", type: "Nodes", nodeID: "searchbar-contents" },
|
|
177
|
+
],
|
|
151
178
|
},
|
|
152
179
|
};
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import React, { Fragment, useState, useContext, useEffect } from "react";
|
|
8
8
|
import { ntimes } from "./Columns";
|
|
9
9
|
import { Column } from "./Column";
|
|
10
|
+
import useTranslation from "../../hooks/useTranslation";
|
|
10
11
|
import optionsCtx from "../context";
|
|
11
12
|
import { setAPropGen, SettingsFromFields } from "./utils";
|
|
12
13
|
|
|
@@ -67,60 +68,76 @@ const Table = ({
|
|
|
67
68
|
);
|
|
68
69
|
};
|
|
69
70
|
|
|
70
|
-
const
|
|
71
|
-
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
123
|
-
|
|
71
|
+
const TableSettings = () => {
|
|
72
|
+
const { t } = useTranslation();
|
|
73
|
+
const fields = [
|
|
74
|
+
{
|
|
75
|
+
label: t("Rows"),
|
|
76
|
+
name: "rows",
|
|
77
|
+
type: "Integer",
|
|
78
|
+
attributes: { min: 0 },
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
label: t("Columns"),
|
|
82
|
+
name: "columns",
|
|
83
|
+
type: "Integer",
|
|
84
|
+
attributes: { min: 0 },
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "customClass",
|
|
88
|
+
label: t("Custom class"),
|
|
89
|
+
type: "String",
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
label: t("Bootstrap style"),
|
|
93
|
+
name: "bs_style",
|
|
94
|
+
type: "Bool",
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
label: t("Small"),
|
|
98
|
+
name: "bs_small",
|
|
99
|
+
type: "Bool",
|
|
100
|
+
showIf: { bs_style: true },
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
label: t("Striped"),
|
|
104
|
+
name: "bs_striped",
|
|
105
|
+
type: "Bool",
|
|
106
|
+
showIf: { bs_style: true },
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
label: t("Bordered"),
|
|
110
|
+
name: "bs_bordered",
|
|
111
|
+
type: "Bool",
|
|
112
|
+
showIf: { bs_style: true },
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
label: t("Borderless"),
|
|
116
|
+
name: "bs_borderless",
|
|
117
|
+
type: "Bool",
|
|
118
|
+
showIf: { bs_style: true },
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
label: t("Auto width"),
|
|
122
|
+
name: "bs_wauto",
|
|
123
|
+
type: "Bool",
|
|
124
|
+
showIf: { bs_style: true },
|
|
125
|
+
},
|
|
126
|
+
];
|
|
127
|
+
return (
|
|
128
|
+
<SettingsFromFields
|
|
129
|
+
fields={fields}
|
|
130
|
+
onChange={(fnm, v, setProp) => {
|
|
131
|
+
if (fnm === "rows")
|
|
132
|
+
setProp((prop) => {
|
|
133
|
+
ntimes(v, (i) => {
|
|
134
|
+
if (!prop.contents[i]) prop.contents[i] = [];
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
}}
|
|
138
|
+
/>
|
|
139
|
+
);
|
|
140
|
+
};
|
|
124
141
|
|
|
125
142
|
/**
|
|
126
143
|
* @type {object}
|
|
@@ -128,16 +145,6 @@ const fields = [
|
|
|
128
145
|
Table.craft = {
|
|
129
146
|
displayName: "Table",
|
|
130
147
|
related: {
|
|
131
|
-
settings:
|
|
132
|
-
onChange(fnm, v, setProp) {
|
|
133
|
-
if (fnm === "rows")
|
|
134
|
-
setProp((prop) => {
|
|
135
|
-
ntimes(v, (i) => {
|
|
136
|
-
if (!prop.contents[i]) prop.contents[i] = [];
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
},
|
|
140
|
-
}),
|
|
141
|
-
fields,
|
|
148
|
+
settings: TableSettings,
|
|
142
149
|
},
|
|
143
150
|
};
|