@solidxai/core-ui 0.1.5-beta.5 → 0.1.5-beta.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.
- package/dist/components/core/chatter/SolidChatterDateDivider.js +1 -1
- package/dist/components/core/chatter/SolidChatterDateDivider.js.map +1 -1
- package/dist/components/core/chatter/SolidChatterDateDivider.tsx +1 -1
- package/dist/components/core/dashboard/DashboardFilter.js +1 -1
- package/dist/components/core/dashboard/DashboardFilter.js.map +1 -1
- package/dist/components/core/dashboard/DashboardFilter.tsx +5 -5
- package/dist/components/core/dashboard/PrimeDataTableWrapper.d.ts +3 -0
- package/dist/components/core/dashboard/PrimeDataTableWrapper.d.ts.map +1 -0
- package/dist/components/core/dashboard/PrimeDataTableWrapper.js +21 -0
- package/dist/components/core/dashboard/PrimeDataTableWrapper.js.map +1 -0
- package/dist/components/core/dashboard/PrimeDataTableWrapper.tsx +40 -0
- package/dist/components/core/dashboard/SolidDashboard.d.ts +0 -1
- package/dist/components/core/dashboard/SolidDashboard.d.ts.map +1 -1
- package/dist/components/core/dashboard/SolidDashboard.js +50 -26
- package/dist/components/core/dashboard/SolidDashboard.js.map +1 -1
- package/dist/components/core/dashboard/SolidDashboard.module.css +6 -2
- package/dist/components/core/dashboard/SolidDashboard.tsx +112 -65
- package/dist/components/core/dashboard/SolidDashboardBody.d.ts +13 -1
- package/dist/components/core/dashboard/SolidDashboardBody.d.ts.map +1 -1
- package/dist/components/core/dashboard/SolidDashboardBody.js +134 -48
- package/dist/components/core/dashboard/SolidDashboardBody.js.map +1 -1
- package/dist/components/core/dashboard/SolidDashboardBody.tsx +143 -91
- package/dist/components/core/dashboard/SolidQuestionRenderer.d.ts.map +1 -1
- package/dist/components/core/dashboard/SolidQuestionRenderer.js +1 -1
- package/dist/components/core/dashboard/SolidQuestionRenderer.js.map +1 -1
- package/dist/components/core/dashboard/SolidQuestionRenderer.tsx +12 -10
- package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.d.ts.map +1 -1
- package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.js +29 -2
- package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.js.map +1 -1
- package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.tsx +33 -3
- package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.d.ts +10 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.js +16 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.js.map +1 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.ts +19 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.d.ts +8 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.js +64 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.js.map +1 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.ts +30 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.d.ts +8 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.js +62 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.js.map +1 -0
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.ts +29 -0
- package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.js +2 -2
- package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.js.map +1 -1
- package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.tsx +2 -2
- package/dist/components/core/form/SolidFormView.js +1 -1
- package/dist/components/core/form/SolidFormView.js.map +1 -1
- package/dist/components/core/form/SolidFormView.tsx +1 -1
- package/dist/components/core/list/SolidListView.d.ts.map +1 -1
- package/dist/components/core/list/SolidListView.js +7 -4
- package/dist/components/core/list/SolidListView.js.map +1 -1
- package/dist/components/core/list/SolidListView.tsx +4 -2
- package/dist/constants/error-messages.d.ts +3 -0
- package/dist/constants/error-messages.d.ts.map +1 -1
- package/dist/constants/error-messages.js +3 -0
- package/dist/constants/error-messages.js.map +1 -1
- package/dist/constants/error-messages.ts +24 -20
- package/dist/helpers/registry.d.ts.map +1 -1
- package/dist/helpers/registry.js +7 -0
- package/dist/helpers/registry.js.map +1 -1
- package/dist/helpers/registry.ts +8 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/index.ts +8 -0
- package/dist/redux/api/dashboardLayoutApi.d.ts +24 -0
- package/dist/redux/api/dashboardLayoutApi.d.ts.map +1 -0
- package/dist/redux/api/dashboardLayoutApi.js +34 -0
- package/dist/redux/api/dashboardLayoutApi.js.map +1 -0
- package/dist/redux/api/dashboardLayoutApi.ts +55 -0
- package/dist/redux/store/defaultStoreConfig.d.ts +4 -0
- package/dist/redux/store/defaultStoreConfig.d.ts.map +1 -1
- package/dist/redux/store/defaultStoreConfig.js +3 -2
- package/dist/redux/store/defaultStoreConfig.js.map +1 -1
- package/dist/redux/store/defaultStoreConfig.ts +4 -2
- package/dist/routes/pages/admin/core/DashboardPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/DashboardPage.js +3 -7
- package/dist/routes/pages/admin/core/DashboardPage.js.map +1 -1
- package/dist/routes/pages/admin/core/DashboardPage.tsx +2 -5
- package/dist/routes/solidRoutes.js +1 -1
- package/dist/routes/solidRoutes.js.map +1 -1
- package/dist/routes/solidRoutes.tsx +1 -1
- package/package.json +13 -11
|
@@ -9,6 +9,42 @@ var __assign = (this && this.__assign) || function () {
|
|
|
9
9
|
};
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
23
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
12
48
|
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
13
49
|
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
14
50
|
if (ar || !(i in from)) {
|
|
@@ -18,59 +54,109 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
18
54
|
}
|
|
19
55
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
20
56
|
};
|
|
21
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
57
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
22
58
|
import 'gridstack/dist/gridstack.min.css';
|
|
23
59
|
import styles from './SolidDashboard.module.css';
|
|
24
60
|
import { SolidQuestionRenderer } from './SolidQuestionRenderer';
|
|
25
|
-
import
|
|
26
|
-
import {
|
|
27
|
-
import
|
|
28
|
-
import
|
|
61
|
+
import ReactGridLayout, { useContainerWidth } from "react-grid-layout";
|
|
62
|
+
import { useEffect, useRef } from 'react';
|
|
63
|
+
import PrimeDataTableWrapper from './PrimeDataTableWrapper';
|
|
64
|
+
import 'react-grid-layout/css/styles.css';
|
|
65
|
+
import 'react-resizable/css/styles.css';
|
|
66
|
+
import { useLazyGetUserDashboardLayoutByDashboardIdQuery } from '../../../redux/api/dashboardLayoutApi';
|
|
67
|
+
import showToast from '../../../helpers/showToast';
|
|
68
|
+
import { ERROR_MESSAGES } from '../../../constants/error-messages';
|
|
69
|
+
import { Toast } from 'primereact/toast';
|
|
70
|
+
var generateDefaultLayout = function (questions) {
|
|
71
|
+
return questions.map(function (q, index) {
|
|
72
|
+
var col = index % 3;
|
|
73
|
+
var row = Math.floor(index / 3);
|
|
74
|
+
return {
|
|
75
|
+
i: String(q.name),
|
|
76
|
+
x: col * 4,
|
|
77
|
+
y: row * 4,
|
|
78
|
+
w: 4,
|
|
79
|
+
h: 4,
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
};
|
|
29
83
|
var SolidDashboardBody = function (_a) {
|
|
30
|
-
|
|
31
|
-
var
|
|
84
|
+
var dashboardId = _a.dashboardId, questions = _a.questions, _b = _a.filters, filters = _b === void 0 ? [] : _b, dashboardLayout = _a.dashboardLayout, setDashboardLayout = _a.setDashboardLayout;
|
|
85
|
+
var toast = useRef(null);
|
|
86
|
+
var sortedQuestions = __spreadArray([], questions, true).map(function (q, index) { return (__assign(__assign({}, q), { defaultIndex: index + 1 })); })
|
|
87
|
+
.sort(function (a, b) { var _a, _b; return ((_a = a.sequenceNumber) !== null && _a !== void 0 ? _a : a.defaultIndex) - ((_b = b.sequenceNumber) !== null && _b !== void 0 ? _b : b.defaultIndex); });
|
|
88
|
+
var _c = useContainerWidth(), width = _c.width, containerRef = _c.containerRef, mounted = _c.mounted;
|
|
89
|
+
var isLayoutReady = useRef(false);
|
|
90
|
+
var _d = useLazyGetUserDashboardLayoutByDashboardIdQuery(), fetchUserLayout = _d[0], _e = _d[1], userLayoutData = _e.data, isSuccess = _e.isSuccess, isLoading = _e.isLoading;
|
|
91
|
+
useEffect(function () {
|
|
92
|
+
if (!dashboardId || questions.length === 0)
|
|
93
|
+
return;
|
|
94
|
+
var loadLayout = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
95
|
+
var response, raw, savedLayout_1, layout, error_1;
|
|
96
|
+
var _a;
|
|
97
|
+
return __generator(this, function (_b) {
|
|
98
|
+
switch (_b.label) {
|
|
99
|
+
case 0:
|
|
100
|
+
_b.trys.push([0, 2, , 3]);
|
|
101
|
+
return [4 /*yield*/, fetchUserLayout(dashboardId).unwrap()];
|
|
102
|
+
case 1:
|
|
103
|
+
response = _b.sent();
|
|
104
|
+
raw = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.layout;
|
|
105
|
+
savedLayout_1 = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
|
106
|
+
layout = savedLayout_1
|
|
107
|
+
? sortedQuestions.map(function (q) {
|
|
108
|
+
var saved = savedLayout_1.find(function (s) { return s.i === String(q.name); });
|
|
109
|
+
return saved !== null && saved !== void 0 ? saved : generateDefaultLayout([q])[0];
|
|
110
|
+
})
|
|
111
|
+
: generateDefaultLayout(sortedQuestions);
|
|
112
|
+
setDashboardLayout(layout);
|
|
113
|
+
setTimeout(function () { isLayoutReady.current = true; }, 100);
|
|
114
|
+
return [3 /*break*/, 3];
|
|
115
|
+
case 2:
|
|
116
|
+
error_1 = _b.sent();
|
|
117
|
+
if (error_1.status === 403) {
|
|
118
|
+
showToast(toast, "error", ERROR_MESSAGES.FORBIDDEN_ERROR, ERROR_MESSAGES.FORBIDDEN_ERROR);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
showToast(toast, "error", ERROR_MESSAGES.SOMETHING_WRONG, ERROR_MESSAGES.SOMETHING_WRONG);
|
|
122
|
+
}
|
|
123
|
+
return [3 /*break*/, 3];
|
|
124
|
+
case 3: return [2 /*return*/];
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}); };
|
|
128
|
+
loadLayout();
|
|
129
|
+
}, [questions, dashboardId]);
|
|
32
130
|
// useEffect(() => {
|
|
33
|
-
// if (
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
// //
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
.
|
|
62
|
-
.map(function (question) {
|
|
63
|
-
var _a, _b;
|
|
64
|
-
var queryParams = qs.stringify({ isPreview: false, filters: filters }, { arrayFormat: 'brackets' });
|
|
65
|
-
var _c = useGetDashboardQuestionDataByIdQuery({
|
|
66
|
-
id: question.id,
|
|
67
|
-
qs: queryParams,
|
|
68
|
-
}), questionData = _c.data, isLoading = _c.isLoading;
|
|
69
|
-
if (isLoading)
|
|
70
|
-
return _jsx(ProgressSpinner, {});
|
|
71
|
-
var textAlign = (_a = question === null || question === void 0 ? void 0 : question.textAlign) !== null && _a !== void 0 ? _a : 'start';
|
|
72
|
-
return (_jsx("div", { className: "col-12 p-3", children: _jsxs("div", { className: "".concat(styles.SolidChartCardWrapper, " p-4"), style: { maxHeight: '40vh', overflowY: 'scroll' }, children: [_jsx("div", { className: "font-medium text-".concat(textAlign, " ").concat(styles.SolidChartTitle), children: question.name }), _jsx("div", { className: "mt-2 font-bold text-3xl text-".concat(textAlign, " ").concat(styles.SolidChartTitle), children: questionData.data.kpi }), _jsx("div", { className: 'mt-3', children: _jsx(PrimeReactDatatableRenderer, { options: JSON.parse(question === null || question === void 0 ? void 0 : question.chartOptions), visualizationData: (_b = questionData === null || questionData === void 0 ? void 0 : questionData.data) === null || _b === void 0 ? void 0 : _b.visualizationData }) })] }) }, question.id));
|
|
73
|
-
})] }) }));
|
|
131
|
+
// if (questions.length === 0) return;
|
|
132
|
+
// const saved = getSavedLayout();
|
|
133
|
+
// setDashboardLayout(generateLayout(sortedQuestions, saved));
|
|
134
|
+
// // Delay the ready flag so onLayoutChange doesn't fire before we're set
|
|
135
|
+
// setTimeout(() => { isLayoutReady.current = true; }, 100);
|
|
136
|
+
// }, [questions]);
|
|
137
|
+
var handleLayoutChange = function (newLayout) {
|
|
138
|
+
if (!isLayoutReady.current)
|
|
139
|
+
return;
|
|
140
|
+
// v2 passes LayoutItem[] at runtime despite the type saying Layout
|
|
141
|
+
var layoutArray = newLayout;
|
|
142
|
+
var updated = layoutArray.map(function (item) { return ({
|
|
143
|
+
i: item.i,
|
|
144
|
+
x: item.x,
|
|
145
|
+
y: item.y,
|
|
146
|
+
w: item.w,
|
|
147
|
+
h: item.h,
|
|
148
|
+
}); });
|
|
149
|
+
setDashboardLayout(updated);
|
|
150
|
+
// saving is handled by the parent/caller
|
|
151
|
+
};
|
|
152
|
+
return (_jsxs(_Fragment, { children: [_jsx(Toast, { ref: toast }), _jsx("div", { ref: containerRef, className: "p-4 ".concat(styles.SolidDashboardContentWrapper), style: { width: '100%', overflowY: 'auto', minHeight: 0 }, children: mounted && dashboardLayout.length > 0 && (_jsx(ReactGridLayout, { width: width, layout: dashboardLayout, gridConfig: {
|
|
153
|
+
cols: 12,
|
|
154
|
+
rowHeight: 120,
|
|
155
|
+
}, dragConfig: {
|
|
156
|
+
handle: ".drag-handle",
|
|
157
|
+
}, resizeConfig: {
|
|
158
|
+
enabled: true,
|
|
159
|
+
}, onLayoutChange: handleLayoutChange, children: sortedQuestions.map(function (question) { return (_jsx("div", { className: "drag-handle cursor-move rounded shadow p-2 overflow-hidden", style: { backgroundColor: 'transparent' }, children: question.visualisedAs === "prime-datatable" ? (_jsx(PrimeDataTableWrapper, { question: question, filters: filters })) : (_jsx(SolidQuestionRenderer, { question: question, filters: filters, isPreview: false })) }, String(question.name))); }) })) })] }));
|
|
74
160
|
};
|
|
75
161
|
export default SolidDashboardBody;
|
|
76
162
|
//# sourceMappingURL=SolidDashboardBody.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SolidDashboardBody.js","sourceRoot":"","sources":["../../../../src/components/core/dashboard/SolidDashboardBody.tsx"],"names":[],"mappings":"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","sourcesContent":["\nimport 'gridstack/dist/gridstack.min.css';\nimport { GridStackOptions, GridStackWidget } from 'gridstack';\nimport styles from './SolidDashboard.module.css'\nimport { SolidQuestionRenderer } from './SolidQuestionRenderer';\nimport { SqlExpression } from '../../../types/solid-core';\nimport PrimeReactDatatableRenderer from './chart-renderers/PrimeReactDatatableRenderer';\nimport { useGetDashboardQuestionDataByIdQuery } from '../../../redux/api/dashboardQuestionApi';\nimport qs from 'qs';\nimport { ProgressSpinner } from 'primereact/progressspinner';\n\nexport interface SolidDashboardBodyProps {\n dashboardOptions?: GridStackOptions;\n widgetOptions?: GridStackWidget[];\n // Replace `any` with a proper `Question` type when available\n questions: any[];\n filters: SqlExpression[];\n}\n\nconst SolidDashboardBody = ({ questions, filters = [] }: SolidDashboardBodyProps) => {\n // const gridRef = useRef<HTMLDivElement>(null);\n\n // useEffect(() => {\n // if (!gridRef.current) return;\n\n // // Initialize Gridstack on the specific ref\n // const grid = GridStack.init(dashboardOptions || {}, gridRef.current);\n\n // // Load widgets if provided\n // if (widgetOptions && widgetOptions.length > 0) {\n // grid.load(\n // widgetOptions.map((widget) => ({\n // ...widget,\n // content: `${widget.content ?? 'Widget'}`,\n // }))\n // );\n // }\n\n // // Cleanup on unmount\n // return () => {\n // grid.destroy(false);\n // };\n // }, [dashboardOptions, widgetOptions]);\n\n\n // Fallback sequencing\n const questionsWithDefaultIndex = questions.map((q, index) => ({\n ...q,\n defaultIndex: index + 1,\n }));\n\n\n const sortedQuestions = [...questionsWithDefaultIndex].sort((a, b) => {\n const aSeq = a.sequenceNumber ?? a.defaultIndex;\n const bSeq = b.sequenceNumber ?? b.defaultIndex;\n return aSeq - bSeq;\n });\n\n\n return (\n <div className={`p-4 overflow-y-auto ${styles.SolidDashboardContentWrapper}`}>\n {/* <div className=\"grid-stack\" ref={gridRef}></div> */}\n <div className='grid'>\n {/* {questions && questions.map((question: any) => {\n return (\n <div className='col-4 p-3'>\n <SolidQuestionRenderer question={question} filters={filters} key={question.id} isPreview={false} />\n </div>\n )\n })} */}\n {sortedQuestions\n .filter((question: any) => question.visualisedAs !== 'prime-datatable')\n .map((question: any) => (\n <div className=\"col-4 p-3\" key={question.id}>\n <SolidQuestionRenderer\n question={question}\n filters={filters}\n isPreview={false}\n />\n </div>\n ))}\n\n {sortedQuestions\n .filter((question: any) => question.visualisedAs === 'prime-datatable')\n .map((question: any) => {\n const queryParams = qs.stringify({ isPreview: false, filters }, { arrayFormat: 'brackets' });\n\n const { data: questionData, isLoading } = useGetDashboardQuestionDataByIdQuery({\n id: question.id,\n qs: queryParams,\n });\n\n if (isLoading) return <ProgressSpinner />;\n const textAlign = question?.textAlign ?? 'start'\n\n return (\n <div className=\"col-12 p-3\" key={question.id}>\n <div className={`${styles.SolidChartCardWrapper} p-4`} style={{ maxHeight: '40vh', overflowY: 'scroll' }}>\n <div className={`font-medium text-${textAlign} ${styles.SolidChartTitle}`}>{question.name}</div>\n <div className={`mt-2 font-bold text-3xl text-${textAlign} ${styles.SolidChartTitle}`}>{questionData.data.kpi}</div>\n <div className='mt-3'>\n\n <PrimeReactDatatableRenderer\n options={JSON.parse(question?.chartOptions)}\n visualizationData={questionData?.data?.visualizationData}\n />\n </div>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n );\n};\n\nexport default SolidDashboardBody;"]}
|
|
1
|
+
{"version":3,"file":"SolidDashboardBody.js","sourceRoot":"","sources":["../../../../src/components/core/dashboard/SolidDashboardBody.tsx"],"names":[],"mappings":"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","sourcesContent":["\nimport 'gridstack/dist/gridstack.min.css';\nimport { GridStackOptions, GridStackWidget } from 'gridstack';\nimport styles from './SolidDashboard.module.css'\nimport { SolidQuestionRenderer } from './SolidQuestionRenderer';\nimport { SqlExpression } from '../../../types/solid-core';\nimport ReactGridLayout, { useContainerWidth, Layout, LayoutItem } from \"react-grid-layout\";\nimport { useEffect, useRef, useState } from 'react';\nimport PrimeDataTableWrapper from './PrimeDataTableWrapper';\nimport 'react-grid-layout/css/styles.css';\nimport 'react-resizable/css/styles.css';\nimport { useLazyGetUserDashboardLayoutByDashboardIdQuery } from '../../../redux/api/dashboardLayoutApi';\nimport showToast from '../../../helpers/showToast';\nimport { ERROR_MESSAGES } from '../../../constants/error-messages';\nimport { Toast } from 'primereact/toast';\n\nexport interface SolidDashboardBodyProps {\n dashboardOptions?: GridStackOptions;\n widgetOptions?: GridStackWidget[];\n // Replace `any` with a proper `Question` type when available\n dashboardId: string;\n questions: any[];\n filters: SqlExpression[];\n dashboardLayout: GridItem[];\n setDashboardLayout: (dashboardLayout: GridItem[]) => void;\n}\n\nexport type GridItem = {\n i: string;\n x: number;\n y: number;\n w: number;\n h: number;\n};\n\n// Layout is Layout[] at runtime in v2 — the type definition is misleading\ntype LayoutArray = LayoutItem[];\n\n\nconst generateDefaultLayout = (questions: any[]): GridItem[] => {\n return questions.map((q, index) => {\n const col = index % 3;\n const row = Math.floor(index / 3);\n return {\n i: String(q.name),\n x: col * 4, // 0, 4, 8 in a 12-col grid\n y: row * 4,\n w: 4,\n h: 4,\n };\n });\n};\n\n\nconst SolidDashboardBody = ({ dashboardId, questions, filters = [], dashboardLayout, setDashboardLayout }: SolidDashboardBodyProps) => {\n const toast = useRef<Toast>(null);\n\n const sortedQuestions = [...questions]\n .map((q, index) => ({ ...q, defaultIndex: index + 1 }))\n .sort((a, b) => (a.sequenceNumber ?? a.defaultIndex) - (b.sequenceNumber ?? b.defaultIndex));\n\n const { width, containerRef, mounted } = useContainerWidth();\n const isLayoutReady = useRef(false);\n\n const [fetchUserLayout, { data: userLayoutData, isSuccess, isLoading }] =\n useLazyGetUserDashboardLayoutByDashboardIdQuery();\n\n useEffect(() => {\n if (!dashboardId || questions.length === 0) return;\n const loadLayout = async () => {\n try {\n const response = await fetchUserLayout(dashboardId).unwrap();\n const raw = response?.data?.layout;\n const savedLayout = typeof raw === 'string' ? JSON.parse(raw) : raw;\n\n const layout = savedLayout\n ? sortedQuestions.map((q) => {\n const saved = (savedLayout as GridItem[]).find(s => s.i === String(q.name));\n return saved ?? generateDefaultLayout([q])[0];\n })\n : generateDefaultLayout(sortedQuestions);\n\n setDashboardLayout(layout);\n setTimeout(() => { isLayoutReady.current = true; }, 100);\n } catch (error: any) {\n if (error.status === 403) {\n showToast(toast, \"error\", ERROR_MESSAGES.FORBIDDEN_ERROR, ERROR_MESSAGES.FORBIDDEN_ERROR);\n } else {\n showToast(toast, \"error\", ERROR_MESSAGES.SOMETHING_WRONG, ERROR_MESSAGES.SOMETHING_WRONG);\n }\n }\n };\n\n loadLayout();\n }, [questions, dashboardId]);\n\n\n // useEffect(() => {\n // if (questions.length === 0) return;\n // const saved = getSavedLayout();\n // setDashboardLayout(generateLayout(sortedQuestions, saved));\n // // Delay the ready flag so onLayoutChange doesn't fire before we're set\n // setTimeout(() => { isLayoutReady.current = true; }, 100);\n // }, [questions]);\n\n\n const handleLayoutChange = (newLayout: Layout) => {\n if (!isLayoutReady.current) return;\n\n // v2 passes LayoutItem[] at runtime despite the type saying Layout\n const layoutArray = newLayout as unknown as LayoutItem[];\n\n const updated: GridItem[] = layoutArray.map(item => ({\n i: item.i,\n x: item.x,\n y: item.y,\n w: item.w,\n h: item.h,\n }));\n\n setDashboardLayout(updated);\n // saving is handled by the parent/caller\n };\n\n return (\n <>\n <Toast ref={toast} />\n <div\n ref={containerRef as React.RefObject<HTMLDivElement>}\n className={`p-4 ${styles.SolidDashboardContentWrapper}`}\n style={{ width: '100%', overflowY: 'auto', minHeight: 0 }}\n\n >\n {mounted && dashboardLayout.length > 0 && (\n <ReactGridLayout\n width={width}\n layout={dashboardLayout}\n gridConfig={{\n cols: 12,\n rowHeight: 120,\n }}\n dragConfig={{\n handle: \".drag-handle\",\n }}\n resizeConfig={{\n enabled: true,\n }}\n onLayoutChange={handleLayoutChange}\n >\n {sortedQuestions.map((question: any) => (\n <div key={String(question.name)} className=\"drag-handle cursor-move rounded shadow p-2 overflow-hidden\" style={{ backgroundColor: 'transparent' }}>\n {/* <div className=\" mb-2 font-bold\">\n {question.name}\n </div> */}\n {question.visualisedAs === \"prime-datatable\" ? (\n <PrimeDataTableWrapper question={question} filters={filters} />\n ) : (\n <SolidQuestionRenderer question={question} filters={filters} isPreview={false} />\n )}\n </div>\n ))}\n </ReactGridLayout>\n )}\n </div>\n </>\n );\n};\n\nexport default SolidDashboardBody;"]}
|
|
@@ -4,113 +4,165 @@ import { GridStackOptions, GridStackWidget } from 'gridstack';
|
|
|
4
4
|
import styles from './SolidDashboard.module.css'
|
|
5
5
|
import { SolidQuestionRenderer } from './SolidQuestionRenderer';
|
|
6
6
|
import { SqlExpression } from '../../../types/solid-core';
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import
|
|
7
|
+
import ReactGridLayout, { useContainerWidth, Layout, LayoutItem } from "react-grid-layout";
|
|
8
|
+
import { useEffect, useRef, useState } from 'react';
|
|
9
|
+
import PrimeDataTableWrapper from './PrimeDataTableWrapper';
|
|
10
|
+
import 'react-grid-layout/css/styles.css';
|
|
11
|
+
import 'react-resizable/css/styles.css';
|
|
12
|
+
import { useLazyGetUserDashboardLayoutByDashboardIdQuery } from '../../../redux/api/dashboardLayoutApi';
|
|
13
|
+
import showToast from '../../../helpers/showToast';
|
|
14
|
+
import { ERROR_MESSAGES } from '../../../constants/error-messages';
|
|
15
|
+
import { Toast } from 'primereact/toast';
|
|
11
16
|
|
|
12
17
|
export interface SolidDashboardBodyProps {
|
|
13
18
|
dashboardOptions?: GridStackOptions;
|
|
14
19
|
widgetOptions?: GridStackWidget[];
|
|
15
20
|
// Replace `any` with a proper `Question` type when available
|
|
21
|
+
dashboardId: string;
|
|
16
22
|
questions: any[];
|
|
17
23
|
filters: SqlExpression[];
|
|
24
|
+
dashboardLayout: GridItem[];
|
|
25
|
+
setDashboardLayout: (dashboardLayout: GridItem[]) => void;
|
|
18
26
|
}
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
export type GridItem = {
|
|
29
|
+
i: string;
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
w: number;
|
|
33
|
+
h: number;
|
|
34
|
+
};
|
|
22
35
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// // Cleanup on unmount
|
|
40
|
-
// return () => {
|
|
41
|
-
// grid.destroy(false);
|
|
42
|
-
// };
|
|
43
|
-
// }, [dashboardOptions, widgetOptions]);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// Fallback sequencing
|
|
47
|
-
const questionsWithDefaultIndex = questions.map((q, index) => ({
|
|
48
|
-
...q,
|
|
49
|
-
defaultIndex: index + 1,
|
|
50
|
-
}));
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const sortedQuestions = [...questionsWithDefaultIndex].sort((a, b) => {
|
|
54
|
-
const aSeq = a.sequenceNumber ?? a.defaultIndex;
|
|
55
|
-
const bSeq = b.sequenceNumber ?? b.defaultIndex;
|
|
56
|
-
return aSeq - bSeq;
|
|
36
|
+
// Layout is Layout[] at runtime in v2 — the type definition is misleading
|
|
37
|
+
type LayoutArray = LayoutItem[];
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
const generateDefaultLayout = (questions: any[]): GridItem[] => {
|
|
41
|
+
return questions.map((q, index) => {
|
|
42
|
+
const col = index % 3;
|
|
43
|
+
const row = Math.floor(index / 3);
|
|
44
|
+
return {
|
|
45
|
+
i: String(q.name),
|
|
46
|
+
x: col * 4, // 0, 4, 8 in a 12-col grid
|
|
47
|
+
y: row * 4,
|
|
48
|
+
w: 4,
|
|
49
|
+
h: 4,
|
|
50
|
+
};
|
|
57
51
|
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
const SolidDashboardBody = ({ dashboardId, questions, filters = [], dashboardLayout, setDashboardLayout }: SolidDashboardBodyProps) => {
|
|
56
|
+
const toast = useRef<Toast>(null);
|
|
57
|
+
|
|
58
|
+
const sortedQuestions = [...questions]
|
|
59
|
+
.map((q, index) => ({ ...q, defaultIndex: index + 1 }))
|
|
60
|
+
.sort((a, b) => (a.sequenceNumber ?? a.defaultIndex) - (b.sequenceNumber ?? b.defaultIndex));
|
|
61
|
+
|
|
62
|
+
const { width, containerRef, mounted } = useContainerWidth();
|
|
63
|
+
const isLayoutReady = useRef(false);
|
|
64
|
+
|
|
65
|
+
const [fetchUserLayout, { data: userLayoutData, isSuccess, isLoading }] =
|
|
66
|
+
useLazyGetUserDashboardLayoutByDashboardIdQuery();
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (!dashboardId || questions.length === 0) return;
|
|
70
|
+
const loadLayout = async () => {
|
|
71
|
+
try {
|
|
72
|
+
const response = await fetchUserLayout(dashboardId).unwrap();
|
|
73
|
+
const raw = response?.data?.layout;
|
|
74
|
+
const savedLayout = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
|
75
|
+
|
|
76
|
+
const layout = savedLayout
|
|
77
|
+
? sortedQuestions.map((q) => {
|
|
78
|
+
const saved = (savedLayout as GridItem[]).find(s => s.i === String(q.name));
|
|
79
|
+
return saved ?? generateDefaultLayout([q])[0];
|
|
80
|
+
})
|
|
81
|
+
: generateDefaultLayout(sortedQuestions);
|
|
82
|
+
|
|
83
|
+
setDashboardLayout(layout);
|
|
84
|
+
setTimeout(() => { isLayoutReady.current = true; }, 100);
|
|
85
|
+
} catch (error: any) {
|
|
86
|
+
if (error.status === 403) {
|
|
87
|
+
showToast(toast, "error", ERROR_MESSAGES.FORBIDDEN_ERROR, ERROR_MESSAGES.FORBIDDEN_ERROR);
|
|
88
|
+
} else {
|
|
89
|
+
showToast(toast, "error", ERROR_MESSAGES.SOMETHING_WRONG, ERROR_MESSAGES.SOMETHING_WRONG);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
loadLayout();
|
|
95
|
+
}, [questions, dashboardId]);
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
// useEffect(() => {
|
|
99
|
+
// if (questions.length === 0) return;
|
|
100
|
+
// const saved = getSavedLayout();
|
|
101
|
+
// setDashboardLayout(generateLayout(sortedQuestions, saved));
|
|
102
|
+
// // Delay the ready flag so onLayoutChange doesn't fire before we're set
|
|
103
|
+
// setTimeout(() => { isLayoutReady.current = true; }, 100);
|
|
104
|
+
// }, [questions]);
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
const handleLayoutChange = (newLayout: Layout) => {
|
|
108
|
+
if (!isLayoutReady.current) return;
|
|
109
|
+
|
|
110
|
+
// v2 passes LayoutItem[] at runtime despite the type saying Layout
|
|
111
|
+
const layoutArray = newLayout as unknown as LayoutItem[];
|
|
112
|
+
|
|
113
|
+
const updated: GridItem[] = layoutArray.map(item => ({
|
|
114
|
+
i: item.i,
|
|
115
|
+
x: item.x,
|
|
116
|
+
y: item.y,
|
|
117
|
+
w: item.w,
|
|
118
|
+
h: item.h,
|
|
119
|
+
}));
|
|
58
120
|
|
|
121
|
+
setDashboardLayout(updated);
|
|
122
|
+
// saving is handled by the parent/caller
|
|
123
|
+
};
|
|
59
124
|
|
|
60
125
|
return (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
<div
|
|
64
|
-
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
return (
|
|
97
|
-
<div className="col-12 p-3" key={question.id}>
|
|
98
|
-
<div className={`${styles.SolidChartCardWrapper} p-4`} style={{ maxHeight: '40vh', overflowY: 'scroll' }}>
|
|
99
|
-
<div className={`font-medium text-${textAlign} ${styles.SolidChartTitle}`}>{question.name}</div>
|
|
100
|
-
<div className={`mt-2 font-bold text-3xl text-${textAlign} ${styles.SolidChartTitle}`}>{questionData.data.kpi}</div>
|
|
101
|
-
<div className='mt-3'>
|
|
102
|
-
|
|
103
|
-
<PrimeReactDatatableRenderer
|
|
104
|
-
options={JSON.parse(question?.chartOptions)}
|
|
105
|
-
visualizationData={questionData?.data?.visualizationData}
|
|
106
|
-
/>
|
|
107
|
-
</div>
|
|
108
|
-
</div>
|
|
126
|
+
<>
|
|
127
|
+
<Toast ref={toast} />
|
|
128
|
+
<div
|
|
129
|
+
ref={containerRef as React.RefObject<HTMLDivElement>}
|
|
130
|
+
className={`p-4 ${styles.SolidDashboardContentWrapper}`}
|
|
131
|
+
style={{ width: '100%', overflowY: 'auto', minHeight: 0 }}
|
|
132
|
+
|
|
133
|
+
>
|
|
134
|
+
{mounted && dashboardLayout.length > 0 && (
|
|
135
|
+
<ReactGridLayout
|
|
136
|
+
width={width}
|
|
137
|
+
layout={dashboardLayout}
|
|
138
|
+
gridConfig={{
|
|
139
|
+
cols: 12,
|
|
140
|
+
rowHeight: 120,
|
|
141
|
+
}}
|
|
142
|
+
dragConfig={{
|
|
143
|
+
handle: ".drag-handle",
|
|
144
|
+
}}
|
|
145
|
+
resizeConfig={{
|
|
146
|
+
enabled: true,
|
|
147
|
+
}}
|
|
148
|
+
onLayoutChange={handleLayoutChange}
|
|
149
|
+
>
|
|
150
|
+
{sortedQuestions.map((question: any) => (
|
|
151
|
+
<div key={String(question.name)} className="drag-handle cursor-move rounded shadow p-2 overflow-hidden" style={{ backgroundColor: 'transparent' }}>
|
|
152
|
+
{/* <div className=" mb-2 font-bold">
|
|
153
|
+
{question.name}
|
|
154
|
+
</div> */}
|
|
155
|
+
{question.visualisedAs === "prime-datatable" ? (
|
|
156
|
+
<PrimeDataTableWrapper question={question} filters={filters} />
|
|
157
|
+
) : (
|
|
158
|
+
<SolidQuestionRenderer question={question} filters={filters} isPreview={false} />
|
|
159
|
+
)}
|
|
109
160
|
</div>
|
|
110
|
-
)
|
|
111
|
-
|
|
161
|
+
))}
|
|
162
|
+
</ReactGridLayout>
|
|
163
|
+
)}
|
|
112
164
|
</div>
|
|
113
|
-
|
|
165
|
+
</>
|
|
114
166
|
);
|
|
115
167
|
};
|
|
116
168
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SolidQuestionRenderer.d.ts","sourceRoot":"","sources":["../../../../src/components/core/dashboard/SolidQuestionRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAS1D,KAAK,0BAA0B,GAAG;IAC9B,QAAQ,EAAE,GAAG,CAAC;IACd,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACtB,CAAC;AAQF,eAAO,MAAM,qBAAqB,qCAAmD,0BAA0B,
|
|
1
|
+
{"version":3,"file":"SolidQuestionRenderer.d.ts","sourceRoot":"","sources":["../../../../src/components/core/dashboard/SolidQuestionRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAS1D,KAAK,0BAA0B,GAAG;IAC9B,QAAQ,EAAE,GAAG,CAAC;IACd,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACtB,CAAC;AAQF,eAAO,MAAM,qBAAqB,qCAAmD,0BAA0B,4CAwD9G,CAAA"}
|
|
@@ -32,6 +32,6 @@ export var SolidQuestionRenderer = function (_a) {
|
|
|
32
32
|
// const visualizationData = questionData.data.visualizationData;
|
|
33
33
|
// const visualizedAs = question.data.visualisedAs;
|
|
34
34
|
return (_jsxs(_Fragment, { children: [questionDataIsLoading && _jsx(ProgressSpinner, {}), !questionDataIsLoading &&
|
|
35
|
-
_jsxs("div", { className: "".concat(styles.SolidChartCardWrapper, " p-4
|
|
35
|
+
_jsxs("div", { className: "".concat(styles.SolidChartCardWrapper, " h-full"), children: [_jsxs("div", { className: 'flex flex-col p-4 pb-3', style: { borderBottom: "1px solid #e4e3e3" }, children: [_jsx("div", { className: "font-medium text-".concat(textAlign, " ").concat(styles.SolidChartTitle), children: question.name }), _jsx("div", { className: "mt-2 font-bold text-3xl text-".concat(textAlign, " ").concat(styles.SolidChartTitle), children: questionData.data.kpi })] }), _jsxs("div", { className: 'mt-3 flex-1 min-h-0 p-4 pt-2', children: [['bar', 'line', 'pie'].includes(question.visualisedAs) && _jsx(ChartJsRenderer, { options: options, visualizationData: questionData.data.visualizationData, visualizedAs: question.visualisedAs }), question.visualisedAs === 'prime-meter-group' && _jsx(MeterGroup, { values: questionData.data.visualizationData.dataset, max: (_e = (_d = (_c = questionData === null || questionData === void 0 ? void 0 : questionData.data) === null || _c === void 0 ? void 0 : _c.visualizationData) === null || _d === void 0 ? void 0 : _d.dataset) === null || _e === void 0 ? void 0 : _e.reduce(function (total, item) { return total + item.value; }, 0) }), question.visualisedAs === 'prime-datatable' && _jsx(PrimeReactDatatableRenderer, { options: options, visualizationData: questionData.data.visualizationData })] })] })] }));
|
|
36
36
|
};
|
|
37
37
|
//# sourceMappingURL=SolidQuestionRenderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SolidQuestionRenderer.js","sourceRoot":"","sources":["../../../../src/components/core/dashboard/SolidQuestionRenderer.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,oCAAoC,EAAE,MAAM,yCAAyC,CAAC;AAE/F,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,2BAA2B,MAAM,+CAA+C,CAAC;AACxF,OAAO,MAAM,MAAM,6BAA6B,CAAC;AAcjD,MAAM,CAAC,IAAM,qBAAqB,GAAG,UAAC,EAAyE;;QAAvE,QAAQ,cAAA,EAAE,eAAY,EAAZ,OAAO,mBAAG,EAAE,KAAA,EAAE,iBAAiB,EAAjB,SAAS,mBAAG,KAAK,KAAA;IAC7E,IAAI,CAAC,QAAQ,EAAE;QACX,OAAO,CACH,cAAK,SAAS,EAAE,UAAG,MAAM,CAAC,qBAAqB,SAAM,YACjD,KAAC,OAAO,IAAC,IAAI,EAAC,qBAAqB,GAAG,GACpC,CACT,CAAC;KACL;IAED,IAAM,SAAS,GAAG,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,SAAS,mCAAI,OAAO,CAAA;IAChD,IAAI,CAAC,QAAQ,EAAE;QACX,OAAO,CACH,4BACI,KAAC,OAAO,IAAC,IAAI,EAAC,qBAAqB,GAAG,GACvC,CACN,CAAA;KACJ;IACD,+EAA+E;IAE/E,0BAA0B;IAC1B,IAAM,WAAW,GAAG,EAAE,CAAC,SAAS,CAC5B;QACI,SAAS,WAAA;QACT,OAAO,SAAA;KACV,CAGJ,CAAC;IACI,IAAA,KAAqF,oCAAoC,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,EAAvJ,YAAY,UAAA,EAAa,qBAAqB,eAAA,EAAS,iBAAiB,WAA+E,CAAC;IAGtK,6DAA6D;IAC7D,iFAAiF;IACjF,wEAAwE;IACxE,IAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,YAAY,CAAC,CAAC;IACnD,qCAAqC;IACrC,iEAAiE;IACjE,mDAAmD;IACnD,OAAO,CACH,8BACK,qBAAqB,IAAI,KAAC,eAAe,KAAG,EAC5C,CAAC,qBAAqB;
|
|
1
|
+
{"version":3,"file":"SolidQuestionRenderer.js","sourceRoot":"","sources":["../../../../src/components/core/dashboard/SolidQuestionRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["\nimport { useGetDashboardQuestionDataByIdQuery } from '../../../redux/api/dashboardQuestionApi';\nimport { SqlExpression } from '../../../types/solid-core';\nimport { Message } from 'primereact/message';\nimport { MeterGroup } from 'primereact/metergroup';\nimport { ProgressSpinner } from 'primereact/progressspinner';\nimport qs from 'qs';\nimport { ChartJsRenderer } from './chart-renderers/ChartJsRenderer';\nimport PrimeReactDatatableRenderer from './chart-renderers/PrimeReactDatatableRenderer';\nimport styles from './SolidDashboard.module.css';\n\ntype SolidQuestionRendererProps = {\n question: any;\n filters: SqlExpression[];\n isPreview: boolean;\n};\n\ntype DataItem = {\n value: number;\n label?: string | HTMLElement;\n color?: string;\n}\n\nexport const SolidQuestionRenderer = ({ question, filters = [], isPreview = false }: SolidQuestionRendererProps) => {\n if (!question) {\n return (\n <div className={`${styles.SolidChartCardWrapper} p-4`}>\n <Message text=\"Preview Unavailable\" />\n </div>\n );\n }\n\n const textAlign = question?.textAlign ?? 'start'\n if (!question) {\n return (\n <>\n <Message text=\"Preview Unavailable\" />\n </>\n )\n }\n // console.log(`Rendering BarChartRenderer using question id: ${question.id}`);\n\n // load the question data.\n const queryParams = qs.stringify(\n {\n isPreview,\n filters,\n },\n // ensures proper handling of arrays\n // { arrayFormat: 'indices' }\n );\n const { data: questionData, isLoading: questionDataIsLoading, error: questionDataError } = useGetDashboardQuestionDataByIdQuery({ id: question.id, qs: queryParams });\n\n\n // console.log(`Question data: `); console.log(questionData);\n // console.log(`Question data is loading: `); console.log(questionDataIsLoading);\n // console.log(`Question data error: `); console.log(questionDataError);\n const options = JSON.parse(question?.chartOptions);\n // const kpi = questionData.data.kpi;\n // const visualizationData = questionData.data.visualizationData;\n // const visualizedAs = question.data.visualisedAs;\n return (\n <>\n {questionDataIsLoading && <ProgressSpinner />}\n {!questionDataIsLoading &&\n <div className={`${styles.SolidChartCardWrapper} h-full`}>\n <div className='flex flex-col p-4 pb-3' style={{ borderBottom: \"1px solid #e4e3e3\" }}>\n <div className={`font-medium text-${textAlign} ${styles.SolidChartTitle}`}>{question.name}</div>\n <div className={`mt-2 font-bold text-3xl text-${textAlign} ${styles.SolidChartTitle}`}>{questionData.data.kpi}</div>\n </div>\n <div className='mt-3 flex-1 min-h-0 p-4 pt-2'>\n {['bar', 'line', 'pie'].includes(question.visualisedAs) && <ChartJsRenderer options={options} visualizationData={questionData.data.visualizationData} visualizedAs={question.visualisedAs} />}\n {question.visualisedAs === 'prime-meter-group' && <MeterGroup values={questionData.data.visualizationData.dataset} max={questionData?.data?.visualizationData?.dataset?.reduce((total: number, item: DataItem) => total + item.value, 0)} />}\n {question.visualisedAs === 'prime-datatable' && <PrimeReactDatatableRenderer options={options} visualizationData={questionData.data.visualizationData} />}\n </div>\n </div>\n }\n </>\n )\n}"]}
|
|
@@ -15,7 +15,7 @@ type SolidQuestionRendererProps = {
|
|
|
15
15
|
isPreview: boolean;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
type DataItem= {
|
|
18
|
+
type DataItem = {
|
|
19
19
|
value: number;
|
|
20
20
|
label?: string | HTMLElement;
|
|
21
21
|
color?: string;
|
|
@@ -63,16 +63,18 @@ export const SolidQuestionRenderer = ({ question, filters = [], isPreview = fals
|
|
|
63
63
|
<>
|
|
64
64
|
{questionDataIsLoading && <ProgressSpinner />}
|
|
65
65
|
{!questionDataIsLoading &&
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
<div className={`${styles.SolidChartCardWrapper} h-full`}>
|
|
67
|
+
<div className='flex flex-col p-4 pb-3' style={{ borderBottom: "1px solid #e4e3e3" }}>
|
|
68
|
+
<div className={`font-medium text-${textAlign} ${styles.SolidChartTitle}`}>{question.name}</div>
|
|
69
|
+
<div className={`mt-2 font-bold text-3xl text-${textAlign} ${styles.SolidChartTitle}`}>{questionData.data.kpi}</div>
|
|
70
|
+
</div>
|
|
71
|
+
<div className='mt-3 flex-1 min-h-0 p-4 pt-2'>
|
|
72
|
+
{['bar', 'line', 'pie'].includes(question.visualisedAs) && <ChartJsRenderer options={options} visualizationData={questionData.data.visualizationData} visualizedAs={question.visualisedAs} />}
|
|
73
|
+
{question.visualisedAs === 'prime-meter-group' && <MeterGroup values={questionData.data.visualizationData.dataset} max={questionData?.data?.visualizationData?.dataset?.reduce((total: number, item: DataItem) => total + item.value, 0)} />}
|
|
74
|
+
{question.visualisedAs === 'prime-datatable' && <PrimeReactDatatableRenderer options={options} visualizationData={questionData.data.visualizationData} />}
|
|
75
|
+
</div>
|
|
73
76
|
</div>
|
|
74
|
-
|
|
75
|
-
}
|
|
77
|
+
}
|
|
76
78
|
</>
|
|
77
79
|
)
|
|
78
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartJsRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/dashboard/chart-renderers/ChartJsRenderer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChartJsRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/dashboard/chart-renderers/ChartJsRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,oEAAoE,CAAC;AAI5E,KAAK,oBAAoB,GAAG;IACxB,OAAO,EAAE,GAAG,CAAC;IACb,iBAAiB,EAAE,GAAG,CAAC;IACvB,YAAY,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;CACxC,CAAC;AACF,eAAO,MAAM,eAAe,iDAAkD,oBAAoB,4CAoCjG,CAAA"}
|