@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.
Files changed (112) hide show
  1. package/dist/components/auth/SolidOTPVerify.d.ts +3 -0
  2. package/dist/components/auth/SolidOTPVerify.d.ts.map +1 -0
  3. package/dist/components/auth/SolidOTPVerify.js +67 -0
  4. package/dist/components/auth/SolidOTPVerify.js.map +1 -0
  5. package/dist/components/auth/SolidOTPVerify.tsx +133 -0
  6. package/dist/components/common/AuthBanner.js.map +1 -1
  7. package/dist/components/core/chatter/SolidChatterDateDivider.d.ts.map +1 -1
  8. package/dist/components/core/chatter/SolidChatterDateDivider.js +4 -1
  9. package/dist/components/core/chatter/SolidChatterDateDivider.js.map +1 -1
  10. package/dist/components/core/chatter/SolidChatterDateDivider.tsx +5 -1
  11. package/dist/components/core/common/LoadDynamicJsxComponent.d.ts +2 -0
  12. package/dist/components/core/common/LoadDynamicJsxComponent.d.ts.map +1 -0
  13. package/dist/components/core/common/LoadDynamicJsxComponent.js +50 -0
  14. package/dist/components/core/common/LoadDynamicJsxComponent.js.map +1 -0
  15. package/dist/components/core/common/LoadDynamicJsxComponent.tsx +70 -0
  16. package/dist/components/core/dashboard/DashboardFilter.js +1 -1
  17. package/dist/components/core/dashboard/DashboardFilter.js.map +1 -1
  18. package/dist/components/core/dashboard/DashboardFilter.tsx +5 -5
  19. package/dist/components/core/dashboard/PrimeDataTableWrapper.d.ts +3 -0
  20. package/dist/components/core/dashboard/PrimeDataTableWrapper.d.ts.map +1 -0
  21. package/dist/components/core/dashboard/PrimeDataTableWrapper.js +21 -0
  22. package/dist/components/core/dashboard/PrimeDataTableWrapper.js.map +1 -0
  23. package/dist/components/core/dashboard/PrimeDataTableWrapper.tsx +40 -0
  24. package/dist/components/core/dashboard/SolidDashboard.d.ts +0 -1
  25. package/dist/components/core/dashboard/SolidDashboard.d.ts.map +1 -1
  26. package/dist/components/core/dashboard/SolidDashboard.js +50 -26
  27. package/dist/components/core/dashboard/SolidDashboard.js.map +1 -1
  28. package/dist/components/core/dashboard/SolidDashboard.module.css +6 -2
  29. package/dist/components/core/dashboard/SolidDashboard.tsx +112 -65
  30. package/dist/components/core/dashboard/SolidDashboardBody.d.ts +13 -1
  31. package/dist/components/core/dashboard/SolidDashboardBody.d.ts.map +1 -1
  32. package/dist/components/core/dashboard/SolidDashboardBody.js +134 -48
  33. package/dist/components/core/dashboard/SolidDashboardBody.js.map +1 -1
  34. package/dist/components/core/dashboard/SolidDashboardBody.tsx +143 -91
  35. package/dist/components/core/dashboard/SolidQuestionRenderer.d.ts.map +1 -1
  36. package/dist/components/core/dashboard/SolidQuestionRenderer.js +1 -1
  37. package/dist/components/core/dashboard/SolidQuestionRenderer.js.map +1 -1
  38. package/dist/components/core/dashboard/SolidQuestionRenderer.tsx +12 -10
  39. package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.d.ts.map +1 -1
  40. package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.js +29 -2
  41. package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.js.map +1 -1
  42. package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.tsx +33 -3
  43. package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.d.ts +10 -0
  44. package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.d.ts.map +1 -0
  45. package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.js +16 -0
  46. package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.js.map +1 -0
  47. package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.ts +19 -0
  48. package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.d.ts +8 -0
  49. package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.d.ts.map +1 -0
  50. package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.js +64 -0
  51. package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.js.map +1 -0
  52. package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.ts +30 -0
  53. package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.d.ts +8 -0
  54. package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.d.ts.map +1 -0
  55. package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.js +62 -0
  56. package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.js.map +1 -0
  57. package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.ts +29 -0
  58. package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.js +2 -2
  59. package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.js.map +1 -1
  60. package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.tsx +2 -2
  61. package/dist/constants/error-messages.d.ts +3 -0
  62. package/dist/constants/error-messages.d.ts.map +1 -1
  63. package/dist/constants/error-messages.js +3 -0
  64. package/dist/constants/error-messages.js.map +1 -1
  65. package/dist/constants/error-messages.ts +24 -20
  66. package/dist/helpers/registry.d.ts.map +1 -1
  67. package/dist/helpers/registry.js +7 -0
  68. package/dist/helpers/registry.js.map +1 -1
  69. package/dist/helpers/registry.ts +8 -0
  70. package/dist/index.d.ts +2 -0
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +2 -0
  73. package/dist/index.js.map +1 -1
  74. package/dist/index.ts +8 -0
  75. package/dist/nextAuth/authProviders.d.ts +4 -0
  76. package/dist/nextAuth/authProviders.d.ts.map +1 -0
  77. package/dist/nextAuth/authProviders.js +198 -0
  78. package/dist/nextAuth/authProviders.js.map +1 -0
  79. package/dist/nextAuth/authProviders.tsx +232 -0
  80. package/dist/nextAuth/handleLogout.d.ts +2 -0
  81. package/dist/nextAuth/handleLogout.d.ts.map +1 -0
  82. package/dist/nextAuth/handleLogout.js +36 -0
  83. package/dist/nextAuth/handleLogout.js.map +1 -0
  84. package/dist/nextAuth/handleLogout.tsx +39 -0
  85. package/dist/nextAuth/refreshAccessToken.d.ts +2 -0
  86. package/dist/nextAuth/refreshAccessToken.d.ts.map +1 -0
  87. package/dist/nextAuth/refreshAccessToken.js +24 -0
  88. package/dist/nextAuth/refreshAccessToken.js.map +1 -0
  89. package/dist/nextAuth/refreshAccessToken.tsx +28 -0
  90. package/dist/redux/api/dashboardLayoutApi.d.ts +24 -0
  91. package/dist/redux/api/dashboardLayoutApi.d.ts.map +1 -0
  92. package/dist/redux/api/dashboardLayoutApi.js +34 -0
  93. package/dist/redux/api/dashboardLayoutApi.js.map +1 -0
  94. package/dist/redux/api/dashboardLayoutApi.ts +55 -0
  95. package/dist/redux/features/settingsSlice.d.ts +20 -0
  96. package/dist/redux/features/settingsSlice.d.ts.map +1 -0
  97. package/dist/redux/features/settingsSlice.js +39 -0
  98. package/dist/redux/features/settingsSlice.js.map +1 -0
  99. package/dist/redux/features/settingsSlice.ts +60 -0
  100. package/dist/redux/store/defaultStoreConfig.d.ts +4 -0
  101. package/dist/redux/store/defaultStoreConfig.d.ts.map +1 -1
  102. package/dist/redux/store/defaultStoreConfig.js +3 -2
  103. package/dist/redux/store/defaultStoreConfig.js.map +1 -1
  104. package/dist/redux/store/defaultStoreConfig.ts +4 -2
  105. package/dist/routes/pages/admin/core/DashboardPage.d.ts.map +1 -1
  106. package/dist/routes/pages/admin/core/DashboardPage.js +3 -7
  107. package/dist/routes/pages/admin/core/DashboardPage.js.map +1 -1
  108. package/dist/routes/pages/admin/core/DashboardPage.tsx +2 -5
  109. package/dist/routes/solidRoutes.js +1 -1
  110. package/dist/routes/solidRoutes.js.map +1 -1
  111. package/dist/routes/solidRoutes.tsx +1 -1
  112. 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, dashboardId?: number, dashboardName?: 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 (dashboardId !== undefined) {
74
- filters.id = { $eq: dashboardId };
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.dashboardId, params.dashboardName)) // FIXME : error handling should be done properly
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
- <Button
279
- label="Filter"
280
- icon={filters.length > 0 ? "pi pi-filter-fill" : "pi pi-filter"}
281
- outlined={filters.length === 0}
282
- severity={filters.length > 0 ? "info" : "secondary"}
283
- style={filters.length > 0 ? { background: "rgb(114, 46, 209)" } : {}}
284
- size="small"
285
- onClick={() => setIsDashboardFilterVisible(true)}
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
- // label="Clear Filters"
323
+ type="button"
324
+ size="small"
290
325
  icon="pi pi-filter-slash"
291
- severity="danger"
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
- {mcpUrl && (
312
- <div className={`chatter-section ${isOpenSolidXAiPanel === false ? 'collapsed' : 'open'}`} style={{ width: chatterWidth }}>
313
- {isOpenSolidXAiPanel && (
314
- <div
315
- style={{
316
- width: 5,
317
- cursor: 'col-resize',
318
- position: 'absolute',
319
- left: 0,
320
- top: 0,
321
- bottom: 0,
322
- height: '100%',
323
- zIndex: 9,
324
- }}
325
- onMouseDown={() => setIsResizing(true)}
326
- />
327
- )}
328
- {isOpenSolidXAiPanel &&
329
- <Button
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-chevron-left"
376
+ icon="pi pi-angle-double-right"
346
377
  size="small"
347
- className="px-0"
348
- style={{ width: 30 }}
349
- onClick={handleOpen}
378
+ text
379
+ className="chatter-collapse-btn"
380
+ style={{ width: 30, height: 30, aspectRatio: '1/1' }}
381
+ onClick={handleClose}
350
382
  />
351
- </div>
352
- :
353
- <SolidAiMainWrapper mcpUrl={mcpUrl} />
354
- }
355
- </div>
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
- declare const SolidDashboardBody: ({ questions, filters }: SolidDashboardBodyProps) => import("react/jsx-runtime").JSX.Element;
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;AAM1D,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;IAElC,SAAS,EAAE,GAAG,EAAE,CAAC;IACjB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,QAAA,MAAM,kBAAkB,2BAAiC,uBAAuB,4CA+F/E,CAAC;AAEF,eAAe,kBAAkB,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 PrimeReactDatatableRenderer from './chart-renderers/PrimeReactDatatableRenderer';
26
- import { useGetDashboardQuestionDataByIdQuery } from '../../../redux/api/dashboardQuestionApi';
27
- import qs from 'qs';
28
- import { ProgressSpinner } from 'primereact/progressspinner';
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
- // const gridRef = useRef<HTMLDivElement>(null);
31
- var questions = _a.questions, _b = _a.filters, filters = _b === void 0 ? [] : _b;
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 (!gridRef.current) return;
34
- // // Initialize Gridstack on the specific ref
35
- // const grid = GridStack.init(dashboardOptions || {}, gridRef.current);
36
- // // Load widgets if provided
37
- // if (widgetOptions && widgetOptions.length > 0) {
38
- // grid.load(
39
- // widgetOptions.map((widget) => ({
40
- // ...widget,
41
- // content: `${widget.content ?? 'Widget'}`,
42
- // }))
43
- // );
44
- // }
45
- // // Cleanup on unmount
46
- // return () => {
47
- // grid.destroy(false);
48
- // };
49
- // }, [dashboardOptions, widgetOptions]);
50
- // Fallback sequencing
51
- var questionsWithDefaultIndex = questions.map(function (q, index) { return (__assign(__assign({}, q), { defaultIndex: index + 1 })); });
52
- var sortedQuestions = __spreadArray([], questionsWithDefaultIndex, true).sort(function (a, b) {
53
- var _a, _b;
54
- var aSeq = (_a = a.sequenceNumber) !== null && _a !== void 0 ? _a : a.defaultIndex;
55
- var bSeq = (_b = b.sequenceNumber) !== null && _b !== void 0 ? _b : b.defaultIndex;
56
- return aSeq - bSeq;
57
- });
58
- return (_jsx("div", { className: "p-4 overflow-y-auto ".concat(styles.SolidDashboardContentWrapper), children: _jsxs("div", { className: 'grid', children: [sortedQuestions
59
- .filter(function (question) { return question.visualisedAs !== 'prime-datatable'; })
60
- .map(function (question) { return (_jsx("div", { className: "col-4 p-3", children: _jsx(SolidQuestionRenderer, { question: question, filters: filters, isPreview: false }) }, question.id)); }), sortedQuestions
61
- .filter(function (question) { return question.visualisedAs === 'prime-datatable'; })
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;"]}