@ea-lab/reactive-json 0.0.0

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 (66) hide show
  1. package/README.md +83 -0
  2. package/dist/reactive-json.css +5 -0
  3. package/dist/reactive-json.js +56303 -0
  4. package/dist/reactive-json.umd.cjs +382 -0
  5. package/lib/component/action/HashChangeListener.jsx +66 -0
  6. package/lib/component/action/Hide.jsx +14 -0
  7. package/lib/component/action/MessageListener.jsx +62 -0
  8. package/lib/component/action/Popover.jsx +53 -0
  9. package/lib/component/action/ReactOnEvent.jsx +118 -0
  10. package/lib/component/action/Redirect.jsx +26 -0
  11. package/lib/component/action/Tooltip.jsx +27 -0
  12. package/lib/component/action/VisuallyHide.jsx +15 -0
  13. package/lib/component/element/chart/BarChart.jsx +40 -0
  14. package/lib/component/element/chart/DoughnutChart.jsx +32 -0
  15. package/lib/component/element/chart/LineChart.jsx +40 -0
  16. package/lib/component/element/chart/PolarAreaChart.jsx +32 -0
  17. package/lib/component/element/form/CheckBoxField.jsx +215 -0
  18. package/lib/component/element/form/DateField.jsx +42 -0
  19. package/lib/component/element/form/NumberField.jsx +29 -0
  20. package/lib/component/element/form/SelectField.jsx +130 -0
  21. package/lib/component/element/form/TextAreaField.jsx +48 -0
  22. package/lib/component/element/form/TextField.jsx +65 -0
  23. package/lib/component/element/form/formElementsCommon.jsx +54 -0
  24. package/lib/component/element/html/AccordionItem.jsx +42 -0
  25. package/lib/component/element/html/FolderSortableTree.jsx +307 -0
  26. package/lib/component/element/html/FormatNumeral.jsx +118 -0
  27. package/lib/component/element/html/Html.jsx +107 -0
  28. package/lib/component/element/html/LabelFromValue.jsx +89 -0
  29. package/lib/component/element/html/Modal.jsx +77 -0
  30. package/lib/component/element/html/ModalForm.jsx +30 -0
  31. package/lib/component/element/html/Paragraph.jsx +10 -0
  32. package/lib/component/element/html/PreformattedMarkup.jsx +54 -0
  33. package/lib/component/element/html/SortableTreeItemCollapseButton.jsx +20 -0
  34. package/lib/component/element/html/Tabs.jsx +55 -0
  35. package/lib/component/element/special/BootstrapElement.jsx +32 -0
  36. package/lib/component/element/special/Count.jsx +46 -0
  37. package/lib/component/element/special/DataFilter.jsx +156 -0
  38. package/lib/component/element/special/DelayedActions.jsx +119 -0
  39. package/lib/component/element/special/PageControls.jsx +19 -0
  40. package/lib/component/element/special/Phantom.jsx +25 -0
  41. package/lib/component/element/special/Switch.jsx +131 -0
  42. package/lib/component/hook/usePagination.jsx +184 -0
  43. package/lib/component/reaction/addData.jsx +23 -0
  44. package/lib/component/reaction/fetchData.jsx +83 -0
  45. package/lib/component/reaction/moveData.jsx +52 -0
  46. package/lib/component/reaction/postMessage.jsx +43 -0
  47. package/lib/component/reaction/redirectNow.jsx +17 -0
  48. package/lib/component/reaction/removeData.jsx +48 -0
  49. package/lib/component/reaction/setClipboardData.jsx +20 -0
  50. package/lib/component/reaction/setData.jsx +23 -0
  51. package/lib/component/reaction/submitData.jsx +136 -0
  52. package/lib/component/reaction/triggerEvent.jsx +62 -0
  53. package/lib/component/utility/formatString.jsx +59 -0
  54. package/lib/engine/Actions.jsx +392 -0
  55. package/lib/engine/EventDispatcherContext.jsx +16 -0
  56. package/lib/engine/EventDispatcherProvider.jsx +80 -0
  57. package/lib/engine/GlobalDataContext.jsx +13 -0
  58. package/lib/engine/GlobalDataContextProvider.jsx +33 -0
  59. package/lib/engine/PaginationContext.jsx +10 -0
  60. package/lib/engine/PaginationProvider.jsx +61 -0
  61. package/lib/engine/ReactiveJsonRoot.jsx +315 -0
  62. package/lib/engine/TemplateContext.jsx +13 -0
  63. package/lib/engine/TemplateSystem.jsx +302 -0
  64. package/lib/engine/View.jsx +240 -0
  65. package/lib/main.jsx +41 -0
  66. package/package.json +72 -0
@@ -0,0 +1,66 @@
1
+ import {useContext, useEffect} from "react";
2
+ import {reactionFunctions} from "./ReactOnEvent";
3
+ import EventDispatcherContext from "../../engine/EventDispatcherContext";
4
+ import GlobalDataContext from "../../engine/GlobalDataContext";
5
+ import TemplateContext from "../../engine/TemplateContext";
6
+ import {evaluateTemplateValueCollection} from "../../engine/TemplateSystem";
7
+
8
+ /**
9
+ * Listens to hash changes (URL fragment) on the window object and executes a reaction function in response.
10
+ *
11
+ * @param {{}} props
12
+ * @returns {JSX.Element}
13
+ * @constructor
14
+ */
15
+ const HashChangeListener = (props) => {
16
+ const eventDispatcherContext = useContext(EventDispatcherContext);
17
+ const globalDataContext = useContext(GlobalDataContext);
18
+ const templateContext = useContext(TemplateContext);
19
+
20
+ const actionProps = props?.actionProps ?? undefined;
21
+
22
+ useEffect(() => {
23
+ const payload = actionProps ?? undefined;
24
+ const functionToCall = actionProps?.what ?? undefined;
25
+ const whenHashIs = actionProps?.whenHashIs ?? undefined;
26
+ const whenHashWas = actionProps?.whenHashWas ?? undefined;
27
+
28
+ const whenHashIs_evaluated = evaluateTemplateValueCollection({
29
+ globalDataContext,
30
+ templateContext,
31
+ valueToEvaluate: whenHashIs
32
+ });
33
+
34
+ const whenHashWas_evaluated = evaluateTemplateValueCollection({
35
+ globalDataContext,
36
+ templateContext,
37
+ valueToEvaluate: whenHashWas
38
+ });
39
+
40
+ const listener = (event) => {
41
+ // The hash contains the '#' character.
42
+ if (typeof whenHashIs_evaluated === "string" && ((new URL(event.newUrl)).hash !== whenHashIs_evaluated)) {
43
+ return;
44
+ }
45
+
46
+ if (typeof whenHashWas_evaluated === "string" && ((new URL(event.oldUrl)).hash !== whenHashIs_evaluated)) {
47
+ return;
48
+ }
49
+
50
+ const toCall = functionToCall && (reactionFunctions[functionToCall] ?? undefined);
51
+
52
+ toCall && toCall({args: payload, event, globalDataContext, templateContext});
53
+ };
54
+
55
+ // Dev note: we use a context to prevent adding too many real event listeners which would slow down the build.
56
+ eventDispatcherContext?.addEventListener("hashchange", listener);
57
+
58
+ return () => {
59
+ eventDispatcherContext?.removeEventListener("hashchange", listener);
60
+ };
61
+ }, [eventDispatcherContext, globalDataContext, actionProps, templateContext]);
62
+
63
+ return <>{props.children}</>;
64
+ };
65
+
66
+ export default HashChangeListener;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Action which will not render the children.
3
+ *
4
+ * This will also cancel any subsequent actions.
5
+ *
6
+ * @returns {null}
7
+ * @constructor
8
+ */
9
+ const Hide = () => {
10
+ // Simply don't render the children.
11
+ return null;
12
+ };
13
+
14
+ export default Hide;
@@ -0,0 +1,62 @@
1
+ import {useContext, useEffect} from "react";
2
+ import {reactionFunctions} from "./ReactOnEvent";
3
+ import EventDispatcherContext from "../../engine/EventDispatcherContext";
4
+ import GlobalDataContext from "../../engine/GlobalDataContext";
5
+ import TemplateContext from "../../engine/TemplateContext";
6
+ import {evaluateTemplateValueCollection} from "../../engine/TemplateSystem";
7
+ import {isEqual} from "lodash";
8
+
9
+ /**
10
+ * Listens to messages on the window object and executes a reaction function in response.
11
+ *
12
+ * @param {{}} props
13
+ * @returns {JSX.Element}
14
+ * @constructor
15
+ */
16
+ const MessageListener = (props) => {
17
+ const eventDispatcherContext = useContext(EventDispatcherContext);
18
+ const globalDataContext = useContext(GlobalDataContext);
19
+ const templateContext = useContext(TemplateContext);
20
+
21
+ const actionProps = props?.actionProps ?? undefined;
22
+
23
+ useEffect(() => {
24
+ const payload = actionProps ?? undefined;
25
+ const functionToCall = actionProps?.what ?? undefined;
26
+ const whenMessageIs = actionProps?.whenMessageIs ?? undefined;
27
+
28
+ const whenMessageIs_evaluated = evaluateTemplateValueCollection({
29
+ globalDataContext,
30
+ templateContext,
31
+ valueToEvaluate: whenMessageIs
32
+ });
33
+
34
+ const listener = (event) => {
35
+ if (event.origin !== window.location.origin) {
36
+ // The message is not allowed because it targets an unknown origin.
37
+ return;
38
+ }
39
+
40
+ // The "event.data" is supposed to be already evaluated.
41
+ // Use lodash's isEqual to compare the values properly (deep compare for objects).
42
+ if (!isEqual(event.data, whenMessageIs_evaluated)) {
43
+ return;
44
+ }
45
+
46
+ const toCall = functionToCall && (reactionFunctions[functionToCall] ?? undefined);
47
+
48
+ toCall && toCall({args: payload, event, globalDataContext, templateContext});
49
+ };
50
+
51
+ // Dev note: we use a context to prevent adding too many real event listeners which would slow down the build.
52
+ eventDispatcherContext?.addEventListener("message", listener);
53
+
54
+ return () => {
55
+ eventDispatcherContext?.removeEventListener("message", listener);
56
+ };
57
+ }, [eventDispatcherContext, globalDataContext, actionProps, templateContext]);
58
+
59
+ return <>{props.children}</>;
60
+ };
61
+
62
+ export default MessageListener;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Action which will append a popover when the current component is hovered.
3
+ */
4
+
5
+ import {OverlayTrigger, Popover as BsPopover} from "react-bootstrap";
6
+ import View from "../../engine/View";
7
+ import {useEvaluatedAttributes} from "../../engine/TemplateSystem";
8
+ import {useRef} from "react";
9
+
10
+ const Popover = (props) => {
11
+ // We use the React Bootstrap Popover component. It works like the Tooltip component.
12
+ // It requires an OverlayTrigger wrapping component that handles the hover interaction.
13
+ // The OverlayTrigger child must be able to get a "ref" (as in react refs),
14
+ // So we wrap the children in a custom HTML tag (popover-reference) to be sure it will work.
15
+ const bodyAttrs = useEvaluatedAttributes(props.actionProps.bodyAttributes || {});
16
+ const headerAttrs = useEvaluatedAttributes(props.actionProps.headerAttributes || {});
17
+
18
+ // This ref is used to help building complex structures like popovers inside modals.
19
+ // Without this, the popover will show behind the modal instead of being in front.
20
+ // It is usually expected to have the popover over the modal, but if we don't want
21
+ // this effect for a specific case, we should make this configurable to not set
22
+ // the ref.
23
+ const containerRef = useRef(null);
24
+
25
+ return <div ref={containerRef}>
26
+ <OverlayTrigger
27
+ container={containerRef}
28
+ placement={props.actionProps.placement ?? "top"}
29
+ trigger={props.actionProps.trigger ?? "click"}
30
+ overlay={<BsPopover>
31
+ {props.actionProps.header && <BsPopover.Header {...headerAttrs}>
32
+ <View
33
+ props={props.actionProps.header}
34
+ currentData={props.componentProps?.currentData?.actions?.[props.actionIndex]?.header ?? undefined}
35
+ datafield={"header"}
36
+ path={props.componentProps.path + ".actions." + props.actionIndex + ".header"}
37
+ />
38
+ </BsPopover.Header>}
39
+ <BsPopover.Body {...bodyAttrs}>
40
+ <View
41
+ props={props.actionProps.body}
42
+ currentData={props.componentProps?.currentData?.actions?.[props.actionIndex]?.body ?? undefined}
43
+ datafield={"body"}
44
+ path={props.componentProps.path + ".actions." + props.actionIndex + ".body"}
45
+ />
46
+ </BsPopover.Body>
47
+ </BsPopover>}>
48
+ <popover-reference>{props.children}</popover-reference>
49
+ </OverlayTrigger>
50
+ </div>;
51
+ };
52
+
53
+ export default Popover;
@@ -0,0 +1,118 @@
1
+ import {Children, cloneElement, Fragment, isValidElement, useContext} from "react";
2
+ import GlobalDataContext from "../../engine/GlobalDataContext";
3
+ import TemplateContext from "../../engine/TemplateContext";
4
+ import {addData} from "../reaction/addData";
5
+ import {fetchData} from "../reaction/fetchData";
6
+ import {moveData} from "../reaction/moveData";
7
+ import {postMessage} from "../reaction/postMessage";
8
+ import {redirectNow} from "../reaction/redirectNow";
9
+ import {removeData} from "../reaction/removeData";
10
+ import {setData} from "../reaction/setData";
11
+ import {submitData} from "../reaction/submitData";
12
+ import {triggerEvent} from "../reaction/triggerEvent";
13
+ import {setClipboardData} from "../reaction/setClipboardData";
14
+
15
+ /**
16
+ * Functions that will be executed on specific events.
17
+ *
18
+ * @type {{}}
19
+ */
20
+ export const reactionFunctions = {
21
+ addData,
22
+ fetchData,
23
+ moveData,
24
+ postMessage,
25
+ redirectNow,
26
+ removeData,
27
+ setClipboardData,
28
+ setData,
29
+ submitData,
30
+ triggerEvent,
31
+ };
32
+
33
+ /**
34
+ * Action component which will append one or more event listeners on the element.
35
+ *
36
+ * @param {Object} props
37
+ *
38
+ * @constructor
39
+ */
40
+ const ReactOnEvent = (props) => {
41
+ const globalDataContext = useContext(GlobalDataContext);
42
+ const templateContext = useContext(TemplateContext);
43
+
44
+ const {actionProps: reactionFunctionProps} = props;
45
+
46
+ // Event attributes to inject.
47
+ const eventPropsForAttributes = {};
48
+
49
+ for (const [eventName, eventReactionFunctionProps] of Object.entries(reactionFunctionProps)) {
50
+ // Prepare the callback.
51
+ // There will be 1 callback per eventName.
52
+ // Each callback will have a list of objects, each object representing 1 reaction function call.
53
+ eventPropsForAttributes[eventName] = (event) => {
54
+ let lastStopPropagation = true;
55
+
56
+ for (const singleReactionFunctionProps of eventReactionFunctionProps) {
57
+ // singleReactionFunctionProps is the object containing info from the data structure.
58
+ if (!singleReactionFunctionProps) {
59
+ continue;
60
+ }
61
+
62
+ const reactionFunction = singleReactionFunctionProps.what && (reactionFunctions[singleReactionFunctionProps.what] ?? null);
63
+
64
+ if (!reactionFunction) {
65
+ continue;
66
+ }
67
+
68
+ // Call the reaction function with the props, the event details, and context data.
69
+ reactionFunction({args: singleReactionFunctionProps, event, globalDataContext, templateContext});
70
+
71
+ if (singleReactionFunctionProps.stopPropagation === true) {
72
+ // Stop executing reaction functions of this event early.
73
+ break;
74
+ }
75
+
76
+ lastStopPropagation = singleReactionFunctionProps.stopPropagation ?? true;
77
+ }
78
+
79
+ if (lastStopPropagation !== false) {
80
+ // Stop propagation unless "stopPropagation" is explicitly set on false.
81
+ // Stopping the propagation is the default behavior.
82
+ event.stopPropagation();
83
+ }
84
+ };
85
+ }
86
+
87
+ // Recreate the component with the event attributes.
88
+ // The recursive map is required because the item can be nested into a React.Fragment,
89
+ // and we want to add the attributes on the "real" element.
90
+ const recursiveMap = (children) => {
91
+ if (!children) {
92
+ return children;
93
+ }
94
+
95
+ const childrenArray = Children.toArray(children);
96
+
97
+ return Children.map(childrenArray, child => {
98
+ if (child.type === Fragment) {
99
+ // Dig deeper.
100
+ return recursiveMap(child?.props?.children);
101
+ }
102
+
103
+ if (typeof child !== 'object' || !isValidElement(child)) {
104
+ // Not a React element that can welcome attributes.
105
+ return child;
106
+ }
107
+
108
+ // Clone the element and append the attributes.
109
+ return cloneElement(child, eventPropsForAttributes);
110
+ });
111
+ };
112
+
113
+ const clonedChild = recursiveMap(props.children);
114
+
115
+ return <>{clonedChild}</>;
116
+ };
117
+
118
+ export default ReactOnEvent;
@@ -0,0 +1,26 @@
1
+ import {evaluateTemplateValue} from "../../engine/TemplateSystem";
2
+ import {useContext} from "react";
3
+ import GlobalDataContext from "../../engine/GlobalDataContext";
4
+ import TemplateContext from "../../engine/TemplateContext";
5
+
6
+ /**
7
+ * Redirects when the conditions are valid.
8
+ *
9
+ * @param {{actionProps: {to}}} props Action props.
10
+ *
11
+ * @constructor
12
+ */
13
+ const Redirect = (props) => {
14
+ const globalDataContext = useContext(GlobalDataContext);
15
+ const templateContext = useContext(TemplateContext);
16
+
17
+ const {to} = props.actionProps;
18
+
19
+ if (!to || typeof to !== "string") {
20
+ return;
21
+ }
22
+
23
+ window.location.href = evaluateTemplateValue({valueToEvaluate: to, globalDataContext, templateContext});
24
+ };
25
+
26
+ export default Redirect;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Action which will append a tooltip when the current component is hovered.
3
+ */
4
+
5
+ import {OverlayTrigger, Tooltip as BsTooltip} from "react-bootstrap";
6
+ import View from "../../engine/View";
7
+
8
+ const Tooltip = (props) => {
9
+ // We use the React Bootstrap Tooltip component.
10
+ // It requires an OverlayTrigger wrapping component that handles the hover interaction.
11
+ // The OverlayTrigger child must be able to get a "ref" (as in react refs),
12
+ // So we wrap the children in a custom HTML tag (tooltip-reference) to be sure it will work.
13
+ return <OverlayTrigger
14
+ placement={props.actionProps.placement ?? "top"}
15
+ overlay={<BsTooltip>
16
+ <View
17
+ props={props.actionProps.content}
18
+ currentData={props.componentProps?.currentData?.actions?.[props.actionIndex] ?? undefined}
19
+ datafield={props.actionIndex}
20
+ path={props.componentProps.path + ".actions." + props.actionIndex}
21
+ />
22
+ </BsTooltip>}>
23
+ <tooltip-reference>{props.children}</tooltip-reference>
24
+ </OverlayTrigger>;
25
+ };
26
+
27
+ export default Tooltip;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Action which will render the children, but hide it using a wrapping div.
3
+ *
4
+ * This action is used when the element to hide must still be present in the DOM
5
+ * to respond to events.
6
+ *
7
+ * @param {{}} props
8
+ * @returns {JSX.Element}
9
+ * @constructor
10
+ */
11
+ const VisuallyHide = (props) => {
12
+ return <visually-hidden style={{"display": "none"}}>{props.children}</visually-hidden>;
13
+ };
14
+
15
+ export default VisuallyHide;
@@ -0,0 +1,40 @@
1
+ import ActionDependant from "../../../engine/Actions";
2
+ import GlobalDataContext from "../../../engine/GlobalDataContext";
3
+ import TemplateContext from "../../../engine/TemplateContext";
4
+ import {evaluateTemplateValue, useEvaluatedAttributes} from "../../../engine/TemplateSystem";
5
+ import {
6
+ BarElement,
7
+ CategoryScale,
8
+ Chart as ChartJS,
9
+ Legend,
10
+ LinearScale,
11
+ Title,
12
+ Tooltip,
13
+ } from "chart.js";
14
+ import {useContext} from "react";
15
+ import {Bar} from "react-chartjs-2";
16
+
17
+ // Register the necessary modules for Chart.js.
18
+ ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend);
19
+
20
+ const BarChart = ({props}) => {
21
+ const globalDataContext = useContext(GlobalDataContext);
22
+ const templateContext = useContext(TemplateContext);
23
+ const attributes = useEvaluatedAttributes(props.attributes);
24
+
25
+ const options = props.options || {};
26
+
27
+ const chartData = evaluateTemplateValue({
28
+ valueToEvaluate: props.data,
29
+ globalDataContext,
30
+ templateContext,
31
+ });
32
+
33
+ return (
34
+ <ActionDependant {...props}>
35
+ {chartData && <Bar {...attributes} data={chartData} options={options}/>}
36
+ </ActionDependant>
37
+ );
38
+ };
39
+
40
+ export default BarChart;
@@ -0,0 +1,32 @@
1
+ import ActionDependant from "../../../engine/Actions";
2
+ import GlobalDataContext from "../../../engine/GlobalDataContext";
3
+ import TemplateContext from "../../../engine/TemplateContext";
4
+ import {evaluateTemplateValue, useEvaluatedAttributes} from "../../../engine/TemplateSystem";
5
+ import {Chart as ChartJS, ArcElement, Tooltip, Legend} from "chart.js";
6
+ import {useContext} from "react";
7
+ import {Doughnut} from "react-chartjs-2";
8
+
9
+ // Registering necessary components for Chart.js
10
+ ChartJS.register(ArcElement, Tooltip, Legend);
11
+
12
+ const DoughnutChart = ({props}) => {
13
+ const globalDataContext = useContext(GlobalDataContext);
14
+ const templateContext = useContext(TemplateContext);
15
+ const attributes = useEvaluatedAttributes(props.attributes);
16
+
17
+ const options = props.options || {};
18
+
19
+ const chartData = evaluateTemplateValue({
20
+ valueToEvaluate: props.data,
21
+ globalDataContext,
22
+ templateContext,
23
+ });
24
+
25
+ return (
26
+ <ActionDependant {...props}>
27
+ {chartData && <Doughnut {...attributes} data={chartData} options={options}/>}
28
+ </ActionDependant>
29
+ );
30
+ };
31
+
32
+ export default DoughnutChart;
@@ -0,0 +1,40 @@
1
+ import ActionDependant from "../../../engine/Actions";
2
+ import GlobalDataContext from "../../../engine/GlobalDataContext";
3
+ import TemplateContext from "../../../engine/TemplateContext";
4
+ import {evaluateTemplateValue, useEvaluatedAttributes} from "../../../engine/TemplateSystem";
5
+ import {
6
+ CategoryScale,
7
+ Chart as ChartJS, Filler,
8
+ Legend,
9
+ LinearScale,
10
+ LineElement, PointElement,
11
+ Title,
12
+ Tooltip,
13
+ } from "chart.js";
14
+ import {useContext} from "react";
15
+ import {Line} from "react-chartjs-2";
16
+
17
+ // Register the necessary modules for Chart.js.
18
+ ChartJS.register(CategoryScale, LinearScale, LineElement, PointElement, Title, Tooltip, Legend, Filler);
19
+
20
+ const LineChart = ({props}) => {
21
+ const globalDataContext = useContext(GlobalDataContext);
22
+ const templateContext = useContext(TemplateContext);
23
+ const attributes = useEvaluatedAttributes(props.attributes);
24
+
25
+ const options = props.options || {};
26
+
27
+ const chartData = evaluateTemplateValue({
28
+ valueToEvaluate: props.data,
29
+ globalDataContext,
30
+ templateContext,
31
+ });
32
+
33
+ return (
34
+ <ActionDependant {...props}>
35
+ {chartData && <Line {...attributes} data={chartData} options={options}/>}
36
+ </ActionDependant>
37
+ );
38
+ };
39
+
40
+ export default LineChart;
@@ -0,0 +1,32 @@
1
+ import ActionDependant from "../../../engine/Actions";
2
+ import GlobalDataContext from "../../../engine/GlobalDataContext";
3
+ import TemplateContext from "../../../engine/TemplateContext";
4
+ import {evaluateTemplateValue, useEvaluatedAttributes} from "../../../engine/TemplateSystem";
5
+ import {Chart, RadialLinearScale, ArcElement, Tooltip, Legend} from 'chart.js';
6
+ import {useContext} from "react";
7
+ import {PolarArea} from 'react-chartjs-2';
8
+
9
+ // Registering the necessary components for Chart.js.
10
+ Chart.register(RadialLinearScale, ArcElement, Tooltip, Legend);
11
+
12
+ const PolarAreaChart = ({props}) => {
13
+ const globalDataContext = useContext(GlobalDataContext);
14
+ const templateContext = useContext(TemplateContext);
15
+ const attributes = useEvaluatedAttributes(props.attributes);
16
+
17
+ const options = props.options || {};
18
+
19
+ const chartData = evaluateTemplateValue({
20
+ valueToEvaluate: props.data,
21
+ globalDataContext,
22
+ templateContext,
23
+ });
24
+
25
+ return (
26
+ <ActionDependant {...props}>
27
+ {chartData && <PolarArea {...attributes} data={chartData} options={options}/>}
28
+ </ActionDependant>
29
+ );
30
+ };
31
+
32
+ export default PolarAreaChart;