@ea-lab/reactive-json 0.0.20 → 0.0.21
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/README.md +1 -1
- package/dist/esm/types/component/action/HashChangeListener.d.ts +9 -0
- package/{lib/component/action/Hide.jsx → dist/esm/types/component/action/Hide.d.ts} +2 -6
- package/dist/esm/types/component/action/MessageListener.d.ts +9 -0
- package/dist/esm/types/component/action/Popover.d.ts +5 -0
- package/dist/esm/types/component/action/ReactOnEvent.d.ts +26 -0
- package/dist/esm/types/component/action/Redirect.d.ts +9 -0
- package/dist/esm/types/component/action/Tooltip.d.ts +5 -0
- package/{lib/component/action/VisuallyHide.jsx → dist/esm/types/component/action/VisuallyHide.d.ts} +1 -4
- package/dist/esm/types/component/element/form/CheckBoxField.d.ts +7 -0
- package/dist/esm/types/component/element/form/DateField.d.ts +2 -0
- package/dist/esm/types/component/element/form/NumberField.d.ts +7 -0
- package/dist/esm/types/component/element/form/SelectField.d.ts +7 -0
- package/dist/esm/types/component/element/form/TextAreaField.d.ts +6 -0
- package/dist/esm/types/component/element/form/TextField.d.ts +6 -0
- package/dist/esm/types/component/element/form/formElementsCommon.d.ts +23 -0
- package/dist/esm/types/component/element/html/AccordionItem.d.ts +16 -0
- package/dist/esm/types/component/element/html/FolderSortableTree.d.ts +6 -0
- package/dist/esm/types/component/element/html/FormatNumeral.d.ts +7 -0
- package/dist/esm/types/component/element/html/Html.d.ts +8 -0
- package/dist/esm/types/component/element/html/LabelFromValue.d.ts +22 -0
- package/dist/esm/types/component/element/html/Modal.d.ts +6 -0
- package/dist/esm/types/component/element/html/ModalForm.d.ts +9 -0
- package/dist/esm/types/component/element/html/Paragraph.d.ts +5 -0
- package/dist/esm/types/component/element/html/PreformattedMarkup.d.ts +7 -0
- package/dist/esm/types/component/element/html/SortableTreeItemCollapseButton.d.ts +9 -0
- package/dist/esm/types/component/element/html/Tabs.d.ts +18 -0
- package/dist/esm/types/component/element/special/BootstrapElement.d.ts +10 -0
- package/dist/esm/types/component/element/special/Count.d.ts +13 -0
- package/dist/esm/types/component/element/special/DataFilter.d.ts +11 -0
- package/dist/esm/types/component/element/special/DelayedActions.d.ts +25 -0
- package/dist/esm/types/component/element/special/PageControls.d.ts +9 -0
- package/dist/esm/types/component/element/special/Phantom.d.ts +17 -0
- package/dist/esm/types/component/element/special/Switch.d.ts +6 -0
- package/dist/esm/types/component/hook/usePagination.d.ts +30 -0
- package/dist/esm/types/component/index.d.ts +5 -0
- package/dist/esm/types/component/reaction/addData.d.ts +6 -0
- package/dist/esm/types/component/reaction/fetchData.d.ts +8 -0
- package/dist/esm/types/component/reaction/moveData.d.ts +6 -0
- package/dist/esm/types/component/reaction/postMessage.d.ts +6 -0
- package/dist/esm/types/component/reaction/redirectNow.d.ts +6 -0
- package/dist/esm/types/component/reaction/removeData.d.ts +6 -0
- package/dist/esm/types/component/reaction/setClipboardData.d.ts +6 -0
- package/dist/esm/types/component/reaction/setData.d.ts +6 -0
- package/dist/esm/types/component/reaction/submitData.d.ts +8 -0
- package/dist/esm/types/component/reaction/triggerEvent.d.ts +6 -0
- package/dist/esm/types/component/utility/formatString.d.ts +17 -0
- package/dist/esm/types/engine/Actions.d.ts +19 -0
- package/dist/esm/types/engine/ComponentCollector.d.ts +12 -0
- package/{lib/engine/EventDispatcherContext.jsx → dist/esm/types/engine/EventDispatcherContext.d.ts} +4 -7
- package/dist/esm/types/engine/EventDispatcherProvider.d.ts +16 -0
- package/{lib/engine/GlobalDataContext.jsx → dist/esm/types/engine/GlobalDataContext.d.ts} +1 -4
- package/dist/esm/types/engine/GlobalDataContextProvider.d.ts +11 -0
- package/{lib/engine/PaginationContext.jsx → dist/esm/types/engine/PaginationContext.d.ts} +3 -4
- package/dist/esm/types/engine/PaginationProvider.d.ts +12 -0
- package/dist/esm/types/engine/ReactiveJsonRoot.d.ts +28 -0
- package/{lib/engine/TemplateContext.jsx → dist/esm/types/engine/TemplateContext.d.ts} +1 -4
- package/dist/esm/types/engine/TemplateSystem.d.ts +89 -0
- package/dist/esm/types/engine/View.d.ts +7 -0
- package/dist/esm/types/index.d.ts +6 -0
- package/dist/esm/types/main.d.ts +10 -0
- package/dist/index.cjs.js +9201 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.esm.js +9180 -0
- package/dist/index.esm.js.map +1 -0
- package/package.json +26 -15
- package/dist/reactive-json.css +0 -5
- package/dist/reactive-json.js +0 -47707
- package/dist/reactive-json.js.map +0 -1
- package/dist/reactive-json.umd.cjs +0 -366
- package/dist/reactive-json.umd.cjs.map +0 -1
- package/lib/component/action/HashChangeListener.jsx +0 -66
- package/lib/component/action/MessageListener.jsx +0 -62
- package/lib/component/action/Popover.jsx +0 -53
- package/lib/component/action/ReactOnEvent.jsx +0 -118
- package/lib/component/action/Redirect.jsx +0 -26
- package/lib/component/action/Tooltip.jsx +0 -27
- package/lib/component/element/form/CheckBoxField.jsx +0 -215
- package/lib/component/element/form/DateField.jsx +0 -42
- package/lib/component/element/form/NumberField.jsx +0 -29
- package/lib/component/element/form/SelectField.jsx +0 -130
- package/lib/component/element/form/TextAreaField.jsx +0 -48
- package/lib/component/element/form/TextField.jsx +0 -65
- package/lib/component/element/form/formElementsCommon.jsx +0 -54
- package/lib/component/element/html/AccordionItem.jsx +0 -42
- package/lib/component/element/html/FolderSortableTree.jsx +0 -307
- package/lib/component/element/html/FormatNumeral.jsx +0 -118
- package/lib/component/element/html/Html.jsx +0 -107
- package/lib/component/element/html/LabelFromValue.jsx +0 -89
- package/lib/component/element/html/Modal.jsx +0 -77
- package/lib/component/element/html/ModalForm.jsx +0 -30
- package/lib/component/element/html/Paragraph.jsx +0 -10
- package/lib/component/element/html/PreformattedMarkup.jsx +0 -54
- package/lib/component/element/html/SortableTreeItemCollapseButton.jsx +0 -20
- package/lib/component/element/html/Tabs.jsx +0 -55
- package/lib/component/element/special/BootstrapElement.jsx +0 -32
- package/lib/component/element/special/Count.jsx +0 -46
- package/lib/component/element/special/DataFilter.jsx +0 -156
- package/lib/component/element/special/DelayedActions.jsx +0 -119
- package/lib/component/element/special/PageControls.jsx +0 -19
- package/lib/component/element/special/Phantom.jsx +0 -25
- package/lib/component/element/special/Switch.jsx +0 -131
- package/lib/component/hook/usePagination.jsx +0 -184
- package/lib/component/reaction/addData.jsx +0 -23
- package/lib/component/reaction/fetchData.jsx +0 -83
- package/lib/component/reaction/moveData.jsx +0 -52
- package/lib/component/reaction/postMessage.jsx +0 -43
- package/lib/component/reaction/redirectNow.jsx +0 -17
- package/lib/component/reaction/removeData.jsx +0 -48
- package/lib/component/reaction/setClipboardData.jsx +0 -20
- package/lib/component/reaction/setData.jsx +0 -23
- package/lib/component/reaction/submitData.jsx +0 -136
- package/lib/component/reaction/triggerEvent.jsx +0 -62
- package/lib/component/utility/formatString.jsx +0 -59
- package/lib/engine/Actions.jsx +0 -392
- package/lib/engine/ComponentCollector.js +0 -28
- package/lib/engine/EventDispatcherProvider.jsx +0 -80
- package/lib/engine/GlobalDataContextProvider.jsx +0 -33
- package/lib/engine/PaginationProvider.jsx +0 -61
- package/lib/engine/ReactiveJsonRoot.jsx +0 -318
- package/lib/engine/TemplateSystem.jsx +0 -302
- package/lib/engine/View.jsx +0 -248
- package/lib/main.jsx +0 -52
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import ActionDependant from "../../../engine/Actions";
|
|
2
|
-
import GlobalDataContext from "../../../engine/GlobalDataContext";
|
|
3
|
-
import TemplateContext from "../../../engine/TemplateContext";
|
|
4
|
-
import {evaluateTemplateValue} from "../../../engine/TemplateSystem";
|
|
5
|
-
import {useContext} from "react";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Transforms a number into a numeral of a specific language: roman, upper latin, lower latin, ... and custom.
|
|
9
|
-
*/
|
|
10
|
-
const FormatNumeral = ({props}) => {
|
|
11
|
-
const globalDataContext = useContext(GlobalDataContext);
|
|
12
|
-
const templateContext = useContext(TemplateContext);
|
|
13
|
-
|
|
14
|
-
let formatted = false;
|
|
15
|
-
|
|
16
|
-
if (props.content !== undefined) {
|
|
17
|
-
const evaluated = evaluateTemplateValue({valueToEvaluate: props.content, globalDataContext, templateContext});
|
|
18
|
-
|
|
19
|
-
switch (props.format) {
|
|
20
|
-
case "roman-upper":
|
|
21
|
-
formatted = convertArabicToRoman(evaluated);
|
|
22
|
-
break;
|
|
23
|
-
|
|
24
|
-
case "roman-lower":
|
|
25
|
-
formatted = convertArabicToRoman(evaluated, true);
|
|
26
|
-
break;
|
|
27
|
-
|
|
28
|
-
case "latin-upper":
|
|
29
|
-
formatted = convertArabicToLatinLetters(evaluated);
|
|
30
|
-
break;
|
|
31
|
-
|
|
32
|
-
case "latin-lower":
|
|
33
|
-
formatted = convertArabicToLatinLetters(evaluated, true);
|
|
34
|
-
break;
|
|
35
|
-
|
|
36
|
-
default:
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return (
|
|
42
|
-
<ActionDependant {...props}>
|
|
43
|
-
<>
|
|
44
|
-
{(formatted !== false) && formatted}
|
|
45
|
-
</>
|
|
46
|
-
</ActionDependant>
|
|
47
|
-
);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Converts an arabic number to latin letters.
|
|
52
|
-
*
|
|
53
|
-
* Implementation inspired by: https://stackoverflow.com/a/11090169.
|
|
54
|
-
*
|
|
55
|
-
* @param number The number to convert.
|
|
56
|
-
* @param asLowerCase Set to true for lowercase.
|
|
57
|
-
*
|
|
58
|
-
* @returns {*|string|number|false} Number in roman counting, or false if invalid.
|
|
59
|
-
*/
|
|
60
|
-
function convertArabicToLatinLetters(number, asLowerCase = false) {
|
|
61
|
-
if (number < 1) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
let mod = number % 26,
|
|
66
|
-
pow = number / 26 | 0,
|
|
67
|
-
out = mod ? String.fromCharCode(64 + mod) : (--pow, 'Z');
|
|
68
|
-
|
|
69
|
-
const letters = pow ? convertArabicToLatinLetters(pow) + out : out;
|
|
70
|
-
|
|
71
|
-
return asLowerCase ? letters.toLowerCase() : letters;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Converts an arabic number to roman conuting.
|
|
76
|
-
*
|
|
77
|
-
* Implementation inspired by: https://www.30secondsofcode.org/js/s/to-roman-numeral/.
|
|
78
|
-
*
|
|
79
|
-
* Added the lowercase option.
|
|
80
|
-
*
|
|
81
|
-
* @param number The number to convert.
|
|
82
|
-
* @param asLowercase Set to true for lowercase.
|
|
83
|
-
*
|
|
84
|
-
* @returns {number|string|false} Number in roman counting, or false if invalid.
|
|
85
|
-
*/
|
|
86
|
-
function convertArabicToRoman(number, asLowercase = false) {
|
|
87
|
-
if (number < 1) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const lookup = [
|
|
92
|
-
['M', 1000],
|
|
93
|
-
['CM', 900],
|
|
94
|
-
['D', 500],
|
|
95
|
-
['CD', 400],
|
|
96
|
-
['C', 100],
|
|
97
|
-
['XC', 90],
|
|
98
|
-
['L', 50],
|
|
99
|
-
['XL', 40],
|
|
100
|
-
['X', 10],
|
|
101
|
-
['IX', 9],
|
|
102
|
-
['V', 5],
|
|
103
|
-
['IV', 4],
|
|
104
|
-
['I', 1],
|
|
105
|
-
];
|
|
106
|
-
|
|
107
|
-
const uppercase = lookup.reduce(
|
|
108
|
-
(acc, [k, v]) => {
|
|
109
|
-
acc += k.repeat(Math.floor(number / v));
|
|
110
|
-
number = number % v;
|
|
111
|
-
return acc;
|
|
112
|
-
},
|
|
113
|
-
'');
|
|
114
|
-
|
|
115
|
-
return asLowercase ? uppercase.toLowerCase() : uppercase;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export default FormatNumeral;
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import {evaluateAttributes} from "../../../engine/TemplateSystem";
|
|
2
|
-
import View from "../../../engine/View";
|
|
3
|
-
import ActionDependant from "../../../engine/Actions";
|
|
4
|
-
import {useContext} from "react";
|
|
5
|
-
import GlobalDataContext from "../../../engine/GlobalDataContext";
|
|
6
|
-
import TemplateContext from "../../../engine/TemplateContext";
|
|
7
|
-
|
|
8
|
-
export const normalizeAttributesForReactJsx = (maybeAttributesObj) => {
|
|
9
|
-
if (typeof maybeAttributesObj !== "object" || Object.keys(maybeAttributesObj).length === 0) {
|
|
10
|
-
// Not a valid attributes object.
|
|
11
|
-
return {};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const mapping = {
|
|
15
|
-
"class": "className",
|
|
16
|
-
// TODO: checked to defaultChecked seems incorrect. Commented out for removal.
|
|
17
|
-
// "checked": "defaultChecked",
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
// Recreate a shallow copy with the normalized attribute keys.
|
|
21
|
-
const attributesObj = {};
|
|
22
|
-
|
|
23
|
-
for (const [attributeName, attributeValue] of Object.entries(maybeAttributesObj)) {
|
|
24
|
-
const finalAttributeName = mapping.hasOwnProperty(attributeName)
|
|
25
|
-
? mapping[attributeName]
|
|
26
|
-
: attributeName;
|
|
27
|
-
attributesObj[finalAttributeName] = attributeValue;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return attributesObj;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const Html = ({props, currentData, datafield, path}) => {
|
|
34
|
-
const globalDataContext = useContext(GlobalDataContext);
|
|
35
|
-
const templateContext = useContext(TemplateContext);
|
|
36
|
-
|
|
37
|
-
const Tag = `${props.tag}`;
|
|
38
|
-
const extra = props.extra ?? {};
|
|
39
|
-
|
|
40
|
-
// We need to alter the incoming attributes.
|
|
41
|
-
// Normalize the attributes for JSX.
|
|
42
|
-
const attrs = normalizeAttributesForReactJsx(props.attributes);
|
|
43
|
-
const attrsFromCurrentData = normalizeAttributesForReactJsx(currentData.attributes);
|
|
44
|
-
|
|
45
|
-
// Infer the props (template) attributes with the data attributes.
|
|
46
|
-
for (const attrName of Object.keys(attrsFromCurrentData)) {
|
|
47
|
-
if (attrName.charAt(0) === '+') {
|
|
48
|
-
// Append to the props attribute value.
|
|
49
|
-
const finalAttributeName = attrName.substring(1);
|
|
50
|
-
attrs[finalAttributeName] = (attrs[finalAttributeName] ?? "").length > 0
|
|
51
|
-
// Append using a space.
|
|
52
|
-
? " " + attrsFromCurrentData[attrName]
|
|
53
|
-
// Set directly.
|
|
54
|
-
: attrsFromCurrentData[attrName];
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Set the props attribute value directly.
|
|
59
|
-
attrs[attrName] = attrsFromCurrentData[attrName];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const evaluatedAttrs = evaluateAttributes({attrs, globalDataContext, templateContext});
|
|
63
|
-
|
|
64
|
-
// console.log({
|
|
65
|
-
// "cpn": "Html",
|
|
66
|
-
// "props": props,
|
|
67
|
-
// "currentData": currentData,
|
|
68
|
-
// "datafield": datafield,
|
|
69
|
-
// "path": path,
|
|
70
|
-
// "finalAttrs": attrs,
|
|
71
|
-
// });
|
|
72
|
-
|
|
73
|
-
const isVoidTag = (tag) => {
|
|
74
|
-
const voidTagList = ["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"];
|
|
75
|
-
return tag && (voidTagList.indexOf(tag) !== -1);
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
return <ActionDependant {...props}>
|
|
79
|
-
{isVoidTag(props.tag)
|
|
80
|
-
? <>
|
|
81
|
-
<Tag {...evaluatedAttrs}/>
|
|
82
|
-
{Object.keys(extra).length ? (
|
|
83
|
-
<View
|
|
84
|
-
props={extra}
|
|
85
|
-
/>
|
|
86
|
-
) : ("")}
|
|
87
|
-
</>
|
|
88
|
-
: <>
|
|
89
|
-
<Tag {...evaluatedAttrs}>
|
|
90
|
-
{props.content &&
|
|
91
|
-
(<View
|
|
92
|
-
currentData={currentData.content ?? undefined}
|
|
93
|
-
datafield={"content"}
|
|
94
|
-
path={path + ".content"}
|
|
95
|
-
props={props.content}
|
|
96
|
-
/>)}
|
|
97
|
-
</Tag>
|
|
98
|
-
{Object.keys(extra).length ? (
|
|
99
|
-
<View
|
|
100
|
-
props={extra}
|
|
101
|
-
/>
|
|
102
|
-
) : ("")}
|
|
103
|
-
</>}
|
|
104
|
-
</ActionDependant>;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export default Html;
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import ActionDependant from "../../../engine/Actions";
|
|
2
|
-
import GlobalDataContext from "../../../engine/GlobalDataContext";
|
|
3
|
-
import TemplateContext from "../../../engine/TemplateContext";
|
|
4
|
-
import {evaluateTemplateValue} from "../../../engine/TemplateSystem";
|
|
5
|
-
import View from "../../../engine/View";
|
|
6
|
-
import {useContext} from "react";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Shows the label associated to a value.
|
|
10
|
-
*
|
|
11
|
-
* Uses an option-like structure as data source.
|
|
12
|
-
* Thus, it's compatible with SelectField, CheckBoxField...
|
|
13
|
-
*
|
|
14
|
-
* E.g.: [{"label": "Public name", "value": "option value"}].
|
|
15
|
-
*
|
|
16
|
-
* @param currentData
|
|
17
|
-
* @param datafield
|
|
18
|
-
* @param path
|
|
19
|
-
* @param props
|
|
20
|
-
* @returns {JSX.Element}
|
|
21
|
-
* @constructor
|
|
22
|
-
*/
|
|
23
|
-
const LabelFromValue = ({currentData, datafield, path, props}) => {
|
|
24
|
-
const globalDataContext = useContext(GlobalDataContext);
|
|
25
|
-
const templateContext = useContext(TemplateContext);
|
|
26
|
-
|
|
27
|
-
const dynamicOptions = props.dynamicOptions ?? undefined;
|
|
28
|
-
|
|
29
|
-
let options;
|
|
30
|
-
|
|
31
|
-
if (dynamicOptions) {
|
|
32
|
-
// Build the options through the given data.
|
|
33
|
-
options = evaluateTemplateValue({valueToEvaluate: dynamicOptions, globalDataContext, templateContext}) ?? [];
|
|
34
|
-
} else {
|
|
35
|
-
options = props.options ?? [];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// This is the data that contains the current value of this component.
|
|
39
|
-
let formData;
|
|
40
|
-
|
|
41
|
-
// This is the field value when the data is not supplied on initialization.
|
|
42
|
-
const defaultFieldValue = props.defaultFieldValue ?? undefined;
|
|
43
|
-
|
|
44
|
-
const dataLocation = props.dataLocation ?? undefined;
|
|
45
|
-
|
|
46
|
-
if (dataLocation) {
|
|
47
|
-
// A custom data location has been specified.
|
|
48
|
-
formData = evaluateTemplateValue({
|
|
49
|
-
globalDataContext: globalDataContext,
|
|
50
|
-
templateContext: templateContext,
|
|
51
|
-
valueToEvaluate: dataLocation,
|
|
52
|
-
}) ?? defaultFieldValue;
|
|
53
|
-
} else {
|
|
54
|
-
// Use the template data.
|
|
55
|
-
if ((templateContext.templateData[datafield] ?? undefined) === undefined) {
|
|
56
|
-
// Initialize the data for this component.
|
|
57
|
-
templateContext.templateData = (typeof templateContext.templateData === "object") ? templateContext.templateData : {};
|
|
58
|
-
templateContext.templateData[datafield] = defaultFieldValue;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// The "form" data is located in the template context data,
|
|
62
|
-
// under the datafield key. (Dev note: this is maybe not the best way to handle this.)
|
|
63
|
-
formData = templateContext.templateData[datafield];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
let finalValue = options.find((option) => option.value === formData);
|
|
67
|
-
|
|
68
|
-
if (!finalValue || !finalValue.label) {
|
|
69
|
-
if (!formData) {
|
|
70
|
-
// Nothing to show.
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Show the raw data.
|
|
75
|
-
finalValue = formData;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return (
|
|
79
|
-
<ActionDependant {...props}>
|
|
80
|
-
<View
|
|
81
|
-
currentData={currentData}
|
|
82
|
-
datafield={datafield}
|
|
83
|
-
path={path}
|
|
84
|
-
props={finalValue.label}/>
|
|
85
|
-
</ActionDependant>
|
|
86
|
-
);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
export default LabelFromValue;
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import GlobalDataContext from "../../../engine/GlobalDataContext";
|
|
2
|
-
import TemplateContext from "../../../engine/TemplateContext";
|
|
3
|
-
import {dataLocationToPath, evaluateTemplateValue, useEvaluatedAttributes} from "../../../engine/TemplateSystem";
|
|
4
|
-
import ActionDependant from "../../../engine/Actions";
|
|
5
|
-
import View from "../../../engine/View";
|
|
6
|
-
import {useContext, useState} from "react";
|
|
7
|
-
import {default as BsModal} from 'react-bootstrap/Modal';
|
|
8
|
-
|
|
9
|
-
const Modal = ({currentData, path, props}) => {
|
|
10
|
-
const globalDataContext = useContext(GlobalDataContext);
|
|
11
|
-
const templateContext = useContext(TemplateContext);
|
|
12
|
-
|
|
13
|
-
// The modal will be opened by default when in state mode.
|
|
14
|
-
const [show, setShow] = useState(true);
|
|
15
|
-
|
|
16
|
-
const evaluatedAttrs = useEvaluatedAttributes(props.attributes);
|
|
17
|
-
|
|
18
|
-
const {showBoolPath} = props;
|
|
19
|
-
|
|
20
|
-
// State mode is when the given bool path is not a path.
|
|
21
|
-
const isInStateMode = typeof showBoolPath !== "string";
|
|
22
|
-
|
|
23
|
-
// This is the value which control the modal opening state.
|
|
24
|
-
evaluatedAttrs.show = isInStateMode
|
|
25
|
-
? show
|
|
26
|
-
: evaluateTemplateValue({
|
|
27
|
-
valueToEvaluate: props?.showBoolPath ?? false, globalDataContext, templateContext
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const handleClose = () => {
|
|
31
|
-
if (isInStateMode) {
|
|
32
|
-
setShow(false);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// A bool path is given, this will be used to control the modal visibility.
|
|
37
|
-
const fullPath = dataLocationToPath({
|
|
38
|
-
dataLocation: showBoolPath,
|
|
39
|
-
currentPath: templateContext.templatePath,
|
|
40
|
-
globalDataContext,
|
|
41
|
-
templateContext,
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
globalDataContext.updateData(undefined, fullPath);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
// Add the reactive-json class to identify this modal as managed by reactive-json.
|
|
48
|
-
const base = evaluatedAttrs.className ? evaluatedAttrs.className.split(" ") : [];
|
|
49
|
-
base.push("reactive-json");
|
|
50
|
-
evaluatedAttrs.className = base.join(" ");
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<ActionDependant {...props}>
|
|
54
|
-
<BsModal {...evaluatedAttrs} onHide={handleClose}>
|
|
55
|
-
{(props.headerTitle || props.closeButton) &&
|
|
56
|
-
<BsModal.Header closeButton={props.closeButton}>
|
|
57
|
-
<BsModal.Title>
|
|
58
|
-
<View
|
|
59
|
-
currentData={currentData?.headerTitle ?? undefined}
|
|
60
|
-
datafield={"headerTitle"}
|
|
61
|
-
path={(path ?? "") + ".headerTitle"}
|
|
62
|
-
props={props?.headerTitle}/>
|
|
63
|
-
</BsModal.Title>
|
|
64
|
-
</BsModal.Header>}
|
|
65
|
-
{props.body && <BsModal.Body>
|
|
66
|
-
<View
|
|
67
|
-
currentData={currentData?.body ?? undefined}
|
|
68
|
-
datafield={"body"}
|
|
69
|
-
path={(path ?? "") + ".body"}
|
|
70
|
-
props={props?.body}/>
|
|
71
|
-
</BsModal.Body>}
|
|
72
|
-
</BsModal>
|
|
73
|
-
</ActionDependant>
|
|
74
|
-
);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export default Modal;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import Button from 'react-bootstrap/Button';
|
|
3
|
-
import Modal from 'react-bootstrap/Modal';
|
|
4
|
-
import View from "../../../engine/View";
|
|
5
|
-
|
|
6
|
-
function ModalForm({show, path, handleClose, handleSave, form, currentData}) {
|
|
7
|
-
|
|
8
|
-
return (
|
|
9
|
-
<>
|
|
10
|
-
<Modal show={show} onHide={handleClose}>
|
|
11
|
-
<Modal.Header closeButton>
|
|
12
|
-
<Modal.Title>Modal heading</Modal.Title>
|
|
13
|
-
</Modal.Header>
|
|
14
|
-
<Modal.Body>
|
|
15
|
-
<View props={form} currentData={currentData} path={path}/>
|
|
16
|
-
</Modal.Body>
|
|
17
|
-
<Modal.Footer>
|
|
18
|
-
<Button variant="secondary" onClick={handleClose}>
|
|
19
|
-
Close
|
|
20
|
-
</Button>
|
|
21
|
-
<Button variant="primary" onClick={handleSave}>
|
|
22
|
-
Save Changes
|
|
23
|
-
</Button>
|
|
24
|
-
</Modal.Footer>
|
|
25
|
-
</Modal>
|
|
26
|
-
</>
|
|
27
|
-
)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export default ModalForm;
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import ActionDependant from "../../../engine/Actions";
|
|
2
|
-
import GlobalDataContext from "../../../engine/GlobalDataContext";
|
|
3
|
-
import TemplateContext from "../../../engine/TemplateContext";
|
|
4
|
-
import {evaluateTemplateValue} from "../../../engine/TemplateSystem";
|
|
5
|
-
import parse from 'html-react-parser';
|
|
6
|
-
import React, {useContext} from 'react';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* List of tags that are allowed by default.
|
|
10
|
-
*
|
|
11
|
-
* @type {string[]}
|
|
12
|
-
*/
|
|
13
|
-
const defaultHtmlTagAllowList = [
|
|
14
|
-
"abbr", "acronym", "b", "blockquote", "br", "caption", "code", "div", "em", "h1", "h2", "h3", "h4", "h5", "h6",
|
|
15
|
-
"i", "li", "ol", "p", "span", "sup", "strong", "table", "tbody",
|
|
16
|
-
"td", "tfoot", "th", "thead", "tr", "ul",
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Preformatted markup component that takes content and inserts it as HTML.
|
|
21
|
-
*/
|
|
22
|
-
const PreformattedMarkup = ({props}) => {
|
|
23
|
-
const templateContext = useContext(TemplateContext);
|
|
24
|
-
const globalDataContext = useContext(GlobalDataContext);
|
|
25
|
-
|
|
26
|
-
const html = evaluateTemplateValue({valueToEvaluate: props.content, templateContext, globalDataContext});
|
|
27
|
-
|
|
28
|
-
// Allow the base list to be overridden. Useful to disallow all tags, by supplying an empty array.
|
|
29
|
-
const htmlTagAllowList = Array.isArray(props.htmlTagAllowList) ? props.htmlTagAllowList : defaultHtmlTagAllowList;
|
|
30
|
-
|
|
31
|
-
// Allow the list to be extended with the additionalAllowedTags component property.
|
|
32
|
-
const completeTagAllowList = [...htmlTagAllowList, ...(props.additionalAllowedTags ?? [])]
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<ActionDependant {...props}>
|
|
36
|
-
{parse(html, {
|
|
37
|
-
replace(domNode) {
|
|
38
|
-
/*
|
|
39
|
-
* Filter tags to remove any risk about rendering dangerous markup.
|
|
40
|
-
* Attributes (e.g. onclick) do not need to be filtered because they are not parsed as code:
|
|
41
|
-
* https://github.com/remarkablemark/html-react-parser/issues/73#issuecomment-426119592
|
|
42
|
-
*/
|
|
43
|
-
if (domNode.type === "tag" && completeTagAllowList.indexOf(domNode.name) < 0) {
|
|
44
|
-
// Not an allowed tag.
|
|
45
|
-
// Replace by a fragment which will effectively replace by nothing.
|
|
46
|
-
return <></>;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
})}
|
|
50
|
-
</ActionDependant>
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export default PreformattedMarkup;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import ActionDependant from "../../../engine/Actions";
|
|
2
|
-
import TemplateContext from "../../../engine/TemplateContext";
|
|
3
|
-
import {useContext} from "react";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* This is the collapse button for the sortable tree.
|
|
7
|
-
*
|
|
8
|
-
* It's used when SortableTree is used with a manualDrag option.
|
|
9
|
-
*/
|
|
10
|
-
const SortableTreeItemCollapseButton = ({props}) => {
|
|
11
|
-
const templateContext = useContext(TemplateContext);
|
|
12
|
-
|
|
13
|
-
return (
|
|
14
|
-
<ActionDependant {...props}>
|
|
15
|
-
{templateContext.sortableTreeData._treeAddCollapseButton?.()}
|
|
16
|
-
</ActionDependant>
|
|
17
|
-
)
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export default SortableTreeItemCollapseButton;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import ActionDependant from "../../../engine/Actions";
|
|
2
|
-
import GlobalDataContext from "../../../engine/GlobalDataContext";
|
|
3
|
-
import TemplateContext from "../../../engine/TemplateContext";
|
|
4
|
-
import {
|
|
5
|
-
evaluateAttributes, useEvaluatedAttributes
|
|
6
|
-
} from "../../../engine/TemplateSystem";
|
|
7
|
-
import View from "../../../engine/View";
|
|
8
|
-
import {useContext} from "react";
|
|
9
|
-
import BsTab from 'react-bootstrap/Tab';
|
|
10
|
-
import BsTabs from 'react-bootstrap/Tabs';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Tabs component using the simple Tabs component from react-bootstrap.
|
|
14
|
-
*
|
|
15
|
-
* The react-bootstrap's Tabs component is special as it requires a very
|
|
16
|
-
* specific structure with <Tabs> directly underneath.
|
|
17
|
-
*
|
|
18
|
-
* @param currentData
|
|
19
|
-
* @param path
|
|
20
|
-
* @param props
|
|
21
|
-
* @returns {JSX.Element}
|
|
22
|
-
* @constructor
|
|
23
|
-
*/
|
|
24
|
-
const Tabs = ({currentData, path, props}) => {
|
|
25
|
-
const globalDataContext = useContext(GlobalDataContext);
|
|
26
|
-
const templateContext = useContext(TemplateContext);
|
|
27
|
-
|
|
28
|
-
const evaluatedAttrs = useEvaluatedAttributes(props.attributes);
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<ActionDependant {...props}>
|
|
32
|
-
<BsTabs {...evaluatedAttrs}>
|
|
33
|
-
{Array.isArray(props.tabs) && props.tabs.map((item, index) => {
|
|
34
|
-
const tabAttributes = evaluateAttributes({
|
|
35
|
-
attrs: item.attributes,
|
|
36
|
-
globalDataContext,
|
|
37
|
-
templateContext,
|
|
38
|
-
options: {normalizeBeforeEvaluation: true}
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
return <BsTab {...tabAttributes} key={index}>
|
|
42
|
-
<View
|
|
43
|
-
currentData={currentData?.[index]?.content ?? undefined}
|
|
44
|
-
datafield={"content"}
|
|
45
|
-
path={(path ?? "") + "." + index + ".content"}
|
|
46
|
-
props={item?.content}/>
|
|
47
|
-
</BsTab>
|
|
48
|
-
})}
|
|
49
|
-
|
|
50
|
-
</BsTabs>
|
|
51
|
-
</ActionDependant>
|
|
52
|
-
);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export default Tabs;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import ActionDependant from "../../../engine/Actions";
|
|
2
|
-
import View from "../../../engine/View";
|
|
3
|
-
import {useEvaluatedAttributes} from "../../../engine/TemplateSystem";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Wraps a React Bootstrap component.
|
|
7
|
-
*/
|
|
8
|
-
function BootstrapElement({props, currentData, path, bsComponent}) {
|
|
9
|
-
const attributes = useEvaluatedAttributes(props.attributes);
|
|
10
|
-
|
|
11
|
-
if (props.attributes?.["data-visually-hidden"]) {debugger;}
|
|
12
|
-
|
|
13
|
-
if (!bsComponent) {
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const BsElement = bsComponent;
|
|
18
|
-
|
|
19
|
-
return <ActionDependant {...props}>
|
|
20
|
-
<BsElement {...attributes}>
|
|
21
|
-
{props.content &&
|
|
22
|
-
(<View
|
|
23
|
-
currentData={currentData.content ?? undefined}
|
|
24
|
-
datafield={"content"}
|
|
25
|
-
path={path + ".content"}
|
|
26
|
-
props={props.content}
|
|
27
|
-
/>)}
|
|
28
|
-
</BsElement>
|
|
29
|
-
</ActionDependant>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export default BootstrapElement;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import JSONPath from "jsonpath";
|
|
2
|
-
import {useContext} from "react";
|
|
3
|
-
import GlobalDataContext from "../../../engine/GlobalDataContext";
|
|
4
|
-
import TemplateContext from "../../../engine/TemplateContext";
|
|
5
|
-
import {maybeFormatString} from "../../utility/formatString";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Returns a count for something to count.
|
|
9
|
-
*
|
|
10
|
-
* @param props Component build data.
|
|
11
|
-
*
|
|
12
|
-
* @returns {null|*}
|
|
13
|
-
*
|
|
14
|
-
* @constructor
|
|
15
|
-
*/
|
|
16
|
-
const Count = ({props}) => {
|
|
17
|
-
const globalDataContext = useContext(GlobalDataContext);
|
|
18
|
-
const templateContext = useContext(TemplateContext);
|
|
19
|
-
|
|
20
|
-
const {
|
|
21
|
-
context = "global",
|
|
22
|
-
jsonPathPattern: _jsonPathPattern,
|
|
23
|
-
} = props;
|
|
24
|
-
|
|
25
|
-
const _selectedContext = context === "template" ? TemplateContext : GlobalDataContext;
|
|
26
|
-
const selectedContext = useContext(_selectedContext);
|
|
27
|
-
|
|
28
|
-
if (!_jsonPathPattern) {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const jsonPathPattern = maybeFormatString({
|
|
33
|
-
templateContexts: {
|
|
34
|
-
globalDataContext,
|
|
35
|
-
templateContext
|
|
36
|
-
}
|
|
37
|
-
}, _jsonPathPattern);
|
|
38
|
-
|
|
39
|
-
const selectedContextData = context === "root" ? selectedContext.getRootContext().templateData : selectedContext.templateData;
|
|
40
|
-
|
|
41
|
-
const result = JSONPath.query(selectedContextData, jsonPathPattern);
|
|
42
|
-
|
|
43
|
-
return result.length;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export default Count;
|