@solidxai/core-ui 0.1.5-beta.6 → 0.1.5-beta.9
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/auth/SolidOTPVerify.d.ts +3 -0
- package/dist/components/auth/SolidOTPVerify.d.ts.map +1 -0
- package/dist/components/auth/SolidOTPVerify.js +67 -0
- package/dist/components/auth/SolidOTPVerify.js.map +1 -0
- package/dist/components/auth/SolidOTPVerify.tsx +133 -0
- package/dist/components/common/AuthBanner.js.map +1 -1
- package/dist/components/core/chatter/SolidChatterDateDivider.d.ts.map +1 -1
- package/dist/components/core/chatter/SolidChatterDateDivider.js +4 -1
- package/dist/components/core/chatter/SolidChatterDateDivider.js.map +1 -1
- package/dist/components/core/chatter/SolidChatterDateDivider.tsx +5 -1
- package/dist/components/core/common/LoadDynamicJsxComponent.d.ts +2 -0
- package/dist/components/core/common/LoadDynamicJsxComponent.d.ts.map +1 -0
- package/dist/components/core/common/LoadDynamicJsxComponent.js +50 -0
- package/dist/components/core/common/LoadDynamicJsxComponent.js.map +1 -0
- package/dist/components/core/common/LoadDynamicJsxComponent.tsx +70 -0
- 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/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/nextAuth/authProviders.d.ts +4 -0
- package/dist/nextAuth/authProviders.d.ts.map +1 -0
- package/dist/nextAuth/authProviders.js +198 -0
- package/dist/nextAuth/authProviders.js.map +1 -0
- package/dist/nextAuth/authProviders.tsx +232 -0
- package/dist/nextAuth/handleLogout.d.ts +2 -0
- package/dist/nextAuth/handleLogout.d.ts.map +1 -0
- package/dist/nextAuth/handleLogout.js +36 -0
- package/dist/nextAuth/handleLogout.js.map +1 -0
- package/dist/nextAuth/handleLogout.tsx +39 -0
- package/dist/nextAuth/refreshAccessToken.d.ts +2 -0
- package/dist/nextAuth/refreshAccessToken.d.ts.map +1 -0
- package/dist/nextAuth/refreshAccessToken.js +24 -0
- package/dist/nextAuth/refreshAccessToken.js.map +1 -0
- package/dist/nextAuth/refreshAccessToken.tsx +28 -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/features/settingsSlice.d.ts +20 -0
- package/dist/redux/features/settingsSlice.d.ts.map +1 -0
- package/dist/redux/features/settingsSlice.js +39 -0
- package/dist/redux/features/settingsSlice.js.map +1 -0
- package/dist/redux/features/settingsSlice.ts +60 -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
|
@@ -4,10 +4,10 @@ import { SqlExpression } from '../../../types/solid-core';
|
|
|
4
4
|
import { Button } from 'primereact/button';
|
|
5
5
|
import { Tooltip } from "primereact/tooltip";
|
|
6
6
|
import qs from 'qs';
|
|
7
|
-
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
|
7
|
+
import { Dispatch, SetStateAction, useEffect, useRef, useState } from 'react';
|
|
8
8
|
import { SolidXAIIcon } from '../solid-ai/SolidXAIIcon';
|
|
9
9
|
import styles from './SolidDashboard.module.css';
|
|
10
|
-
import SolidDashboardBody from './SolidDashboardBody';
|
|
10
|
+
import SolidDashboardBody, { GridItem } from './SolidDashboardBody';
|
|
11
11
|
import { DashboardFilter } from './DashboardFilter';
|
|
12
12
|
import { SolidAiMainWrapper } from '../solid-ai/SolidAiMainWrapper';
|
|
13
13
|
import { SolidDashboardFilterRequired } from './SolidDashboardFilterRequired';
|
|
@@ -17,6 +17,10 @@ import { useDispatch, useSelector } from "react-redux";
|
|
|
17
17
|
import { showNavbar, toggleNavbar } from "../../../redux/features/navbarSlice";
|
|
18
18
|
import SolidDashboardNotAvailable from './SolidDashboardNotAvailable';
|
|
19
19
|
import { useLazyGetMcpUrlQuery, useLazyGetSolidSettingsQuery } from '../../../redux/api/solidSettingsApi';
|
|
20
|
+
import showToast from '../../../helpers/showToast';
|
|
21
|
+
import { Toast } from "primereact/toast";
|
|
22
|
+
import { ERROR_MESSAGES } from '../../../constants/error-messages';
|
|
23
|
+
import { useUpsertUserDashboardLayoutMutation } from '../../../redux/api/dashboardLayoutApi';
|
|
20
24
|
|
|
21
25
|
export enum DashboardVariableType {
|
|
22
26
|
DATE = 'date',
|
|
@@ -61,7 +65,7 @@ function handleDashboardData(
|
|
|
61
65
|
}
|
|
62
66
|
}
|
|
63
67
|
|
|
64
|
-
function getQueryParams(moduleName: string,
|
|
68
|
+
function getQueryParams(moduleName: string, dashboardName?: string) {
|
|
65
69
|
const filters: any = {
|
|
66
70
|
module: {
|
|
67
71
|
name: {
|
|
@@ -70,10 +74,8 @@ function getQueryParams(moduleName: string, dashboardId?: number, dashboardName?
|
|
|
70
74
|
}
|
|
71
75
|
};
|
|
72
76
|
|
|
73
|
-
if (
|
|
74
|
-
filters.
|
|
75
|
-
} else if (dashboardName !== undefined) {
|
|
76
|
-
filters.name = { $eq: dashboardName };
|
|
77
|
+
if (dashboardName !== undefined) {
|
|
78
|
+
filters.name = { $eqi: dashboardName };
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
const query = {
|
|
@@ -114,12 +116,11 @@ function isRenderDashboardBody(questions: any[], dashboardVariables: DashboardVa
|
|
|
114
116
|
|
|
115
117
|
type SolidDashboardViewProps = {
|
|
116
118
|
moduleName: string;
|
|
117
|
-
dashboardId?: number;
|
|
118
119
|
dashboardName?: string;
|
|
119
120
|
};
|
|
120
121
|
|
|
121
122
|
const SolidDashboard = (params: SolidDashboardViewProps) => {
|
|
122
|
-
const { data, isLoading, error } = useGetDashboardQuery(getQueryParams(params.moduleName, params.
|
|
123
|
+
const { data, isLoading, error } = useGetDashboardQuery(getQueryParams(params.moduleName, params.dashboardName)) // FIXME : error handling should be done properly
|
|
123
124
|
// Define a state called layoutOption and pass it after destructing the widgetOptions and dashboardOptions from layoutOption
|
|
124
125
|
// TODO [HP]: Shouldn't the type of this state variable be something different? Why are we muddling this with layout but calling it body props?
|
|
125
126
|
// TODO [HP]: Body props should be clearly made up of Gridstack layout options, the questions that make up the body & the filter[] which is an array of SqlExpressions
|
|
@@ -132,6 +133,8 @@ const SolidDashboard = (params: SolidDashboardViewProps) => {
|
|
|
132
133
|
// TODO [HP]: replace dashboardVariableFilterRules with filters everywhere...
|
|
133
134
|
// const [dashboardVariableFilterRules, setDashboardVariableFilterRules] = useState<ISolidDashboardVariableFilterRule[]>([]);
|
|
134
135
|
const dispatch = useDispatch();
|
|
136
|
+
const toast = useRef<Toast>(null);
|
|
137
|
+
|
|
135
138
|
const visibleNavbar = useSelector((state: any) => state.navbarState?.visibleNavbar);
|
|
136
139
|
const [filters, setFilters] = useState<SqlExpression[]>([]);
|
|
137
140
|
const [isOpenSolidXAiPanel, setIsOpenSolidXAiPanel] = useState(false);
|
|
@@ -142,6 +145,25 @@ const SolidDashboard = (params: SolidDashboardViewProps) => {
|
|
|
142
145
|
const [isDashboardFilterVisible, setIsDashboardFilterVisible] = useState(false);
|
|
143
146
|
|
|
144
147
|
|
|
148
|
+
const [upsertDashboardLayout, { isLoading: isDashboardLayoutLoading, error: dashboardLayoutError, isSuccess: isDashboardLayoutSuccess, data: dashboardLayoutData }] = useUpsertUserDashboardLayoutMutation();
|
|
149
|
+
|
|
150
|
+
const [dashboardLayout, setDashboardLayout] = useState<GridItem[]>([]);
|
|
151
|
+
|
|
152
|
+
const updateUserDashboardLayout = async () => {
|
|
153
|
+
try {
|
|
154
|
+
const response = await upsertDashboardLayout({
|
|
155
|
+
dashboardId: data?.records[0].id,
|
|
156
|
+
layout: JSON.stringify(dashboardLayout),
|
|
157
|
+
}).unwrap();
|
|
158
|
+
if (response.statusCode === 200) {
|
|
159
|
+
showToast(toast, "success", ERROR_MESSAGES.LAYOUT, ERROR_MESSAGES.DASHBOARD_LAYOUT_UPDATE_SUCCESSFULLY);
|
|
160
|
+
}
|
|
161
|
+
} catch (error) {
|
|
162
|
+
showToast(toast, "error", ERROR_MESSAGES.LAYOUT, ERROR_MESSAGES.DASHBOARD_LAYOUT_UPDATE_FAILED);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
145
167
|
useEffect(() => {
|
|
146
168
|
// Invoke the dashboard api to fetch the dashboard data
|
|
147
169
|
// console.log('Dashboard Data testing:', isLoading, data, error);
|
|
@@ -246,6 +268,8 @@ const SolidDashboard = (params: SolidDashboardViewProps) => {
|
|
|
246
268
|
|
|
247
269
|
return (
|
|
248
270
|
<div className={`h-screen surface-0 flex`}>
|
|
271
|
+
<Toast ref={toast} />
|
|
272
|
+
|
|
249
273
|
<div className={`h-full flex-grow-1 ${styles.SolidDashboardPageContentWrapper}`}>
|
|
250
274
|
{isLoading && <SolidDashboardLoading />}
|
|
251
275
|
{error && <SolidDashboardRenderError />}
|
|
@@ -275,23 +299,44 @@ const SolidDashboard = (params: SolidDashboardViewProps) => {
|
|
|
275
299
|
{dashboardVariables && dashboardVariables.length > 0 && (
|
|
276
300
|
<>
|
|
277
301
|
<div className='flex gap-2'>
|
|
278
|
-
<
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
302
|
+
<a onClick={() => setIsDashboardFilterVisible(true)}>
|
|
303
|
+
<>
|
|
304
|
+
<Button
|
|
305
|
+
type="button"
|
|
306
|
+
icon={filters.length > 0 ? "pi pi-filter-fill" : "pi pi-filter"}
|
|
307
|
+
className={`p-button-sm lg:hidden solid-icon-button `}
|
|
308
|
+
size='small'
|
|
309
|
+
/>
|
|
310
|
+
|
|
311
|
+
<Button
|
|
312
|
+
type="button"
|
|
313
|
+
icon={filters.length > 0 ? "pi pi-filter-fill" : "pi pi-filter"}
|
|
314
|
+
label={"Filter"}
|
|
315
|
+
className={`hidden lg:inline-flex`}
|
|
316
|
+
size='small'
|
|
317
|
+
|
|
318
|
+
/>
|
|
319
|
+
</>
|
|
320
|
+
</a>
|
|
287
321
|
{filters.length > 0 && (
|
|
288
322
|
<Button
|
|
289
|
-
|
|
323
|
+
type="button"
|
|
324
|
+
size="small"
|
|
290
325
|
icon="pi pi-filter-slash"
|
|
291
|
-
severity="
|
|
326
|
+
severity="secondary"
|
|
327
|
+
className="solid-icon-button "
|
|
328
|
+
outlined
|
|
292
329
|
onClick={() => { setFilters([]); setIsDashboardFilterVisible(false); }}
|
|
293
330
|
/>
|
|
294
331
|
)}
|
|
332
|
+
<Button
|
|
333
|
+
type="button"
|
|
334
|
+
size="small"
|
|
335
|
+
icon="pi pi-save"
|
|
336
|
+
severity="secondary"
|
|
337
|
+
className="solid-icon-button "
|
|
338
|
+
outlined
|
|
339
|
+
onClick={() => updateUserDashboardLayout()} />
|
|
295
340
|
</div>
|
|
296
341
|
<DashboardFilter
|
|
297
342
|
dashboardVariables={dashboardVariables}
|
|
@@ -304,58 +349,60 @@ const SolidDashboard = (params: SolidDashboardViewProps) => {
|
|
|
304
349
|
)}
|
|
305
350
|
</div>
|
|
306
351
|
{!isRenderDashboardBody(questions, dashboardVariables, filters) && <SolidDashboardFilterRequired />}
|
|
307
|
-
{isRenderDashboardBody(questions, dashboardVariables, filters) && <SolidDashboardBody questions={questions} filters={filters} />}
|
|
352
|
+
{isRenderDashboardBody(questions, dashboardVariables, filters) && <SolidDashboardBody dashboardId={data?.records[0]?.id} questions={questions} filters={filters} dashboardLayout={dashboardLayout} setDashboardLayout={setDashboardLayout} />}
|
|
308
353
|
</>
|
|
309
354
|
)}
|
|
310
355
|
</div>
|
|
311
|
-
{
|
|
312
|
-
|
|
313
|
-
{isOpenSolidXAiPanel
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
icon="pi pi-angle-double-right"
|
|
331
|
-
size="small"
|
|
332
|
-
text
|
|
333
|
-
className="chatter-collapse-btn"
|
|
334
|
-
style={{ width: 30, height: 30, aspectRatio: '1/1' }}
|
|
335
|
-
onClick={handleClose}
|
|
336
|
-
/>
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
{isOpenSolidXAiPanel === false ?
|
|
340
|
-
<div className="flex flex-column gap-2 justify-content-center p-2">
|
|
341
|
-
<div className="chatter-collapsed-content" onClick={handleOpen}>
|
|
342
|
-
<div className="flex gap-2"> <SolidXAIIcon /> SolidX AI </div>
|
|
343
|
-
</div>
|
|
356
|
+
{
|
|
357
|
+
mcpUrl && (
|
|
358
|
+
<div className={`chatter-section ${isOpenSolidXAiPanel === false ? 'collapsed' : 'open'}`} style={{ width: chatterWidth }}>
|
|
359
|
+
{isOpenSolidXAiPanel && (
|
|
360
|
+
<div
|
|
361
|
+
style={{
|
|
362
|
+
width: 5,
|
|
363
|
+
cursor: 'col-resize',
|
|
364
|
+
position: 'absolute',
|
|
365
|
+
left: 0,
|
|
366
|
+
top: 0,
|
|
367
|
+
bottom: 0,
|
|
368
|
+
height: '100%',
|
|
369
|
+
zIndex: 9,
|
|
370
|
+
}}
|
|
371
|
+
onMouseDown={() => setIsResizing(true)}
|
|
372
|
+
/>
|
|
373
|
+
)}
|
|
374
|
+
{isOpenSolidXAiPanel &&
|
|
344
375
|
<Button
|
|
345
|
-
icon="pi pi-
|
|
376
|
+
icon="pi pi-angle-double-right"
|
|
346
377
|
size="small"
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
378
|
+
text
|
|
379
|
+
className="chatter-collapse-btn"
|
|
380
|
+
style={{ width: 30, height: 30, aspectRatio: '1/1' }}
|
|
381
|
+
onClick={handleClose}
|
|
350
382
|
/>
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
{isOpenSolidXAiPanel === false ?
|
|
386
|
+
<div className="flex flex-column gap-2 justify-content-center p-2">
|
|
387
|
+
<div className="chatter-collapsed-content" onClick={handleOpen}>
|
|
388
|
+
<div className="flex gap-2"> <SolidXAIIcon /> SolidX AI </div>
|
|
389
|
+
</div>
|
|
390
|
+
<Button
|
|
391
|
+
icon="pi pi-chevron-left"
|
|
392
|
+
size="small"
|
|
393
|
+
className="px-0"
|
|
394
|
+
style={{ width: 30 }}
|
|
395
|
+
onClick={handleOpen}
|
|
396
|
+
/>
|
|
397
|
+
</div>
|
|
398
|
+
:
|
|
399
|
+
<SolidAiMainWrapper mcpUrl={mcpUrl} />
|
|
400
|
+
}
|
|
401
|
+
</div>
|
|
402
|
+
)
|
|
403
|
+
}
|
|
357
404
|
|
|
358
|
-
</div>
|
|
405
|
+
</div >
|
|
359
406
|
);
|
|
360
407
|
}
|
|
361
408
|
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import 'gridstack/dist/gridstack.min.css';
|
|
2
2
|
import { GridStackOptions, GridStackWidget } from 'gridstack';
|
|
3
3
|
import { SqlExpression } from '../../../types/solid-core';
|
|
4
|
+
import 'react-grid-layout/css/styles.css';
|
|
5
|
+
import 'react-resizable/css/styles.css';
|
|
4
6
|
export interface SolidDashboardBodyProps {
|
|
5
7
|
dashboardOptions?: GridStackOptions;
|
|
6
8
|
widgetOptions?: GridStackWidget[];
|
|
9
|
+
dashboardId: string;
|
|
7
10
|
questions: any[];
|
|
8
11
|
filters: SqlExpression[];
|
|
12
|
+
dashboardLayout: GridItem[];
|
|
13
|
+
setDashboardLayout: (dashboardLayout: GridItem[]) => void;
|
|
9
14
|
}
|
|
10
|
-
|
|
15
|
+
export type GridItem = {
|
|
16
|
+
i: string;
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
w: number;
|
|
20
|
+
h: number;
|
|
21
|
+
};
|
|
22
|
+
declare const SolidDashboardBody: ({ dashboardId, questions, filters, dashboardLayout, setDashboardLayout }: SolidDashboardBodyProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
23
|
export default SolidDashboardBody;
|
|
12
24
|
//# sourceMappingURL=SolidDashboardBody.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SolidDashboardBody.d.ts","sourceRoot":"","sources":["../../../../src/components/core/dashboard/SolidDashboardBody.tsx"],"names":[],"mappings":"AACA,OAAO,kCAAkC,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"SolidDashboardBody.d.ts","sourceRoot":"","sources":["../../../../src/components/core/dashboard/SolidDashboardBody.tsx"],"names":[],"mappings":"AACA,OAAO,kCAAkC,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAI1D,OAAO,kCAAkC,CAAC;AAC1C,OAAO,gCAAgC,CAAC;AAMxC,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;IAElC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,GAAG,EAAE,CAAC;IACjB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,eAAe,EAAE,QAAQ,EAAE,CAAC;IAC5B,kBAAkB,EAAE,CAAC,eAAe,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;CAC3D;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAqBF,QAAA,MAAM,kBAAkB,6EAAmF,uBAAuB,4CAgHjI,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -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;"]}
|