robobyte-front-builder 1.0.19 → 1.0.23

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 (520) hide show
  1. package/INTEGRATION.md +1586 -0
  2. package/README.md +928 -0
  3. package/RoboByteBuilder_User_Manual.docx +0 -0
  4. package/next.config.js +19 -48
  5. package/package.json +42 -86
  6. package/src/context/BuilderContext.jsx +191 -7
  7. package/src/context/SystemContext.js +2 -2
  8. package/src/hooks/useGlobalStore.js +36 -0
  9. package/src/hooks/useTimerEngine.js +54 -0
  10. package/src/lib/index.js +11 -3
  11. package/src/lib/layouts/BlankLayout.jsx +13 -0
  12. package/src/lib/providers/RoboByteFrontBuilderProvider.jsx +61 -7
  13. package/src/lib/themes/builderTheme.js +41 -0
  14. package/src/pages/_app.js +32 -134
  15. package/src/pages/api/ai.js +107 -0
  16. package/src/pages/builders/report/index.js +1 -0
  17. package/src/pages/builders/report/list/index.js +1 -0
  18. package/src/pages/builders/report/viewer/index.js +1 -0
  19. package/src/pages/index.js +88 -37
  20. package/src/pages/printBuilder/index.jsx +263 -0
  21. package/src/pages/printBuilder/layouts/index.jsx +298 -0
  22. package/src/pages/reportModule/reportBuilder/index.js +8 -6
  23. package/src/pages/reportModule/reportBuilder/reportViewer/index.js +92 -25
  24. package/src/pages/reportModule/reportBuilder/reports/index.js +3 -5
  25. package/src/pages/reportModule/reportBuilder/reportsPermissions/index.js +2 -3
  26. package/src/pages/viewBuilder/index.jsx +117 -32
  27. package/src/pages/viewBuilder/views/index.js +3 -3
  28. package/src/pages/viewer/[id]/index.js +2 -1
  29. package/src/services/DeleteService.js +31 -60
  30. package/src/services/Endpoints/PrintLayoutEndpoints.js +42 -0
  31. package/src/services/Endpoints/ReportBuilderEndpoints.js +7 -7
  32. package/src/services/Endpoints.js +2 -0
  33. package/src/services/GetService.js +33 -54
  34. package/src/services/PatchService.js +38 -65
  35. package/src/services/PostService.js +37 -63
  36. package/src/services/UpdateService.js +39 -65
  37. package/src/services/builderHelper/actionExecutor.js +141 -25
  38. package/src/services/builderHelper/builderHelper.js +92 -0
  39. package/src/services/builderHelper/colorSchema.js +95 -0
  40. package/src/services/builderHelper/iconResolver.js +50 -0
  41. package/src/services/builderHelper/jsExecutor.js +212 -46
  42. package/src/services/builderHelper/nodeFactory.js +32 -15
  43. package/src/services/builderHelper/numberFormat.js +123 -0
  44. package/src/services/builderHelper/resolveProps.js +73 -4
  45. package/src/services/builderHelper/thresholdEngine.js +77 -0
  46. package/src/services/builderHelper/tree.js +31 -0
  47. package/src/services/components/agGridAutoComplete.js +5 -9
  48. package/src/services/config.js +9 -1
  49. package/src/services/globalStore.js +80 -0
  50. package/src/services/helper/multiSelectEditor.js +5 -9
  51. package/src/services/helper/multiSelectEditorByBuilder.js +5 -9
  52. package/src/services/reportData/fetchReportData.js +69 -28
  53. package/src/services/routerRef.js +35 -0
  54. package/src/services/sessionLog.js +171 -0
  55. package/src/views/ConfirmDialog.js +2 -2
  56. package/src/views/builder/JSEditor.js +105 -107
  57. package/src/views/builder/SessionLogDialog.jsx +350 -0
  58. package/src/views/builder/UnsavedChangesGuard.jsx +103 -0
  59. package/src/views/builder/inspector/Inspector.jsx +6 -9
  60. package/src/views/builder/inspector/Tabs/ComponentActionsTab.jsx +7 -13
  61. package/src/views/builder/inspector/Tabs/MainTab.jsx +143 -25
  62. package/src/views/builder/inspector/Tabs/RulesTab.jsx +9 -24
  63. package/src/views/builder/inspector/Tabs/StyleTab.jsx +9 -24
  64. package/src/views/builder/inspector/definitions/autocomplete/main.js +4 -6
  65. package/src/views/builder/inspector/definitions/banner/actions.js +7 -0
  66. package/src/views/builder/inspector/definitions/banner/main.js +22 -0
  67. package/src/views/builder/inspector/definitions/banner/rules.js +1 -0
  68. package/src/views/builder/inspector/definitions/banner/style.js +1 -0
  69. package/src/views/builder/inspector/definitions/breadcrumb/main.js +43 -6
  70. package/src/views/builder/inspector/definitions/button/main.js +11 -12
  71. package/src/views/builder/inspector/definitions/button/style.js +18 -30
  72. package/src/views/builder/inspector/definitions/checkbox/actions.js +3 -1
  73. package/src/views/builder/inspector/definitions/checkbox/main.js +4 -6
  74. package/src/views/builder/inspector/definitions/common/main.js +13 -2
  75. package/src/views/builder/inspector/definitions/dataGrid/main.js +23 -0
  76. package/src/views/builder/inspector/definitions/dataTableViewer/main.js +46 -0
  77. package/src/views/builder/inspector/definitions/datepicker/actions.js +3 -1
  78. package/src/views/builder/inspector/definitions/datepicker/main.js +6 -14
  79. package/src/views/builder/inspector/definitions/dialog/main.js +36 -0
  80. package/src/views/builder/inspector/definitions/dropdown/main.js +5 -8
  81. package/src/views/builder/inspector/definitions/excelUpload/actions.js +23 -0
  82. package/src/views/builder/inspector/definitions/excelUpload/main.js +17 -0
  83. package/src/views/builder/inspector/definitions/excelUpload/rules.js +1 -0
  84. package/src/views/builder/inspector/definitions/excelUpload/style.js +45 -0
  85. package/src/views/builder/inspector/definitions/header/main.js +10 -1
  86. package/src/views/builder/inspector/definitions/index.js +106 -19
  87. package/src/views/builder/inspector/definitions/input/actions.js +4 -1
  88. package/src/views/builder/inspector/definitions/input/main.js +20 -11
  89. package/src/views/builder/inspector/definitions/kpi/avatarGroup.js +22 -0
  90. package/src/views/builder/inspector/definitions/kpi/badge.js +17 -0
  91. package/src/views/builder/inspector/definitions/kpi/bulletChart.js +47 -0
  92. package/src/views/builder/inspector/definitions/kpi/chart.js +55 -0
  93. package/src/views/builder/inspector/definitions/kpi/colorScale.js +60 -0
  94. package/src/views/builder/inspector/definitions/kpi/comparisonBars.js +41 -0
  95. package/src/views/builder/inspector/definitions/kpi/countdown.js +46 -0
  96. package/src/views/builder/inspector/definitions/kpi/donut.js +51 -0
  97. package/src/views/builder/inspector/definitions/kpi/funnel.js +25 -0
  98. package/src/views/builder/inspector/definitions/kpi/gauge.js +39 -0
  99. package/src/views/builder/inspector/definitions/kpi/heatmapGrid.js +96 -0
  100. package/src/views/builder/inspector/definitions/kpi/iconBox.js +20 -0
  101. package/src/views/builder/inspector/definitions/kpi/metric.js +45 -0
  102. package/src/views/builder/inspector/definitions/kpi/rating.js +27 -0
  103. package/src/views/builder/inspector/definitions/kpi/statusDot.js +18 -0
  104. package/src/views/builder/inspector/definitions/kpi/stepStage.js +65 -0
  105. package/src/views/builder/inspector/definitions/kpi/tagList.js +32 -0
  106. package/src/views/builder/inspector/definitions/kpi/timeline.js +80 -0
  107. package/src/views/builder/inspector/definitions/kpi/trend.js +20 -0
  108. package/src/views/builder/inspector/definitions/label/main.js +10 -1
  109. package/src/views/builder/inspector/definitions/layout/main.js +27 -3
  110. package/src/views/builder/inspector/definitions/number/main.js +6 -14
  111. package/src/views/builder/inspector/definitions/pageNumber/main.js +21 -0
  112. package/src/views/builder/inspector/definitions/popover/main.js +71 -0
  113. package/src/views/builder/inspector/definitions/radio/main.js +5 -8
  114. package/src/views/builder/inspector/definitions/repeater/main.js +31 -0
  115. package/src/views/builder/inspector/definitions/reportViewer/main.js +28 -1
  116. package/src/views/builder/inspector/definitions/richtext/main.js +5 -8
  117. package/src/views/builder/inspector/definitions/signature/main.js +4 -1
  118. package/src/views/builder/inspector/definitions/tag/main.js +5 -8
  119. package/src/views/builder/inspector/definitions/textarea/actions.js +4 -1
  120. package/src/views/builder/inspector/definitions/textarea/main.js +5 -7
  121. package/src/views/builder/inspector/definitions/time/main.js +5 -8
  122. package/src/views/builder/inspector/definitions/toggle/main.js +5 -19
  123. package/src/views/builder/inspector/definitions/treeView/main.js +61 -0
  124. package/src/views/builder/inspector/definitions/viewRenderer/main.js +53 -0
  125. package/src/views/builder/inspector/definitions/wizard/main.js +68 -0
  126. package/src/views/builder/inspector/definitions/wizard-step/main.js +25 -0
  127. package/src/views/builder/inspector/fields/ActionsConfigEditor.jsx +426 -0
  128. package/src/views/builder/inspector/fields/ColorSchemaField.jsx +140 -0
  129. package/src/views/builder/inspector/fields/ColumnFunctionEditor.jsx +238 -0
  130. package/src/views/builder/inspector/fields/ColumnMappingEditor.jsx +105 -0
  131. package/src/views/builder/inspector/fields/ColumnsConfigEditor.jsx +506 -0
  132. package/src/views/builder/inspector/fields/DonutRingsEditorField.jsx +337 -0
  133. package/src/views/builder/inspector/fields/ExtraColsEditor.jsx +618 -0
  134. package/src/views/builder/inspector/fields/FunctionHelpPopover.jsx +295 -0
  135. package/src/views/builder/inspector/fields/IconEditor.jsx +64 -0
  136. package/src/views/builder/inspector/fields/KpiActionField.jsx +223 -0
  137. package/src/views/builder/inspector/fields/MarkersEditorField.jsx +173 -0
  138. package/src/views/builder/inspector/fields/SelectEditor.jsx +9 -5
  139. package/src/views/builder/inspector/fields/SeriesEditorField.jsx +363 -0
  140. package/src/views/builder/inspector/fields/TableColumnsEditor.jsx +104 -0
  141. package/src/views/builder/inspector/fields/ThresholdsEditor.jsx +247 -0
  142. package/src/views/builder/inspector/fields/ValueFunctionsRefPanel.jsx +217 -0
  143. package/src/views/builder/inspector/fields/columnEditorShared.jsx +217 -0
  144. package/src/views/builder/sidebar/Sidebar.jsx +4 -2
  145. package/src/views/builder/sidebar/SidebarTabs.jsx +28 -17
  146. package/src/views/builder/sidebar/tabs/ActionsTab.jsx +7 -3
  147. package/src/views/builder/sidebar/tabs/AiTab/AiPreviewDialog.jsx +193 -0
  148. package/src/views/builder/sidebar/tabs/AiTab/aiProvider.js +53 -0
  149. package/src/views/builder/sidebar/tabs/AiTab/index.jsx +409 -0
  150. package/src/views/builder/sidebar/tabs/AiTab/schemaTransformer.js +167 -0
  151. package/src/views/builder/sidebar/tabs/AiTab/schemaValidator.js +64 -0
  152. package/src/views/builder/sidebar/tabs/AiTab/systemPrompt.js +1151 -0
  153. package/src/views/builder/sidebar/tabs/AiTab/trainingExport.js +131 -0
  154. package/src/views/builder/sidebar/tabs/Components/ComponentsTab.jsx +31 -31
  155. package/src/views/builder/sidebar/tabs/Components/componentCatalog.js +43 -21
  156. package/src/views/builder/sidebar/tabs/Components/printComponentCatalog.js +81 -0
  157. package/src/views/builder/sidebar/tabs/TimersTab.jsx +338 -0
  158. package/src/views/builder/sidebar/tabs/TreeTab.jsx +13 -4
  159. package/src/views/builder/sidebar/tabs/ViewTab.jsx +173 -13
  160. package/src/views/builder/viewer/AdornedLabel.jsx +82 -0
  161. package/src/views/builder/viewer/ComponentRenderer.jsx +98 -24
  162. package/src/views/builder/viewer/DialogsZone.jsx +259 -0
  163. package/src/views/builder/viewer/FieldLabel.jsx +106 -0
  164. package/src/views/builder/viewer/PrintDialog.jsx +481 -0
  165. package/src/views/builder/viewer/ProductionViewer.jsx +80 -5
  166. package/src/views/builder/viewer/Viewer.jsx +106 -8
  167. package/src/views/builder/viewer/ViewerComponentWrapper.jsx +70 -9
  168. package/src/views/builder/viewer/ViewerToolbar.jsx +285 -56
  169. package/src/views/builder/viewer/renderers/AutoCompleteRenderer.jsx +26 -22
  170. package/src/views/builder/viewer/renderers/AvatarGroupRenderer.jsx +112 -0
  171. package/src/views/builder/viewer/renderers/BadgeRenderer.jsx +79 -0
  172. package/src/views/builder/viewer/renderers/BannerRenderer.jsx +62 -0
  173. package/src/views/builder/viewer/renderers/BreadcrumbRenderer.jsx +203 -15
  174. package/src/views/builder/viewer/renderers/BulletChartRenderer.jsx +147 -0
  175. package/src/views/builder/viewer/renderers/ButtonRenderer.jsx +98 -39
  176. package/src/views/builder/viewer/renderers/CardRenderer.jsx +1 -1
  177. package/src/views/builder/viewer/renderers/ChartRenderer.jsx +388 -0
  178. package/src/views/builder/viewer/renderers/CheckboxRenderer.jsx +17 -9
  179. package/src/views/builder/viewer/renderers/ColorScaleRenderer.jsx +300 -0
  180. package/src/views/builder/viewer/renderers/ComparisonBarsRenderer.jsx +133 -0
  181. package/src/views/builder/viewer/renderers/ContainerRenderer.jsx +3 -1
  182. package/src/views/builder/viewer/renderers/CountdownRenderer.jsx +249 -0
  183. package/src/views/builder/viewer/renderers/DataGridRenderer.jsx +380 -0
  184. package/src/views/builder/viewer/renderers/DataTableViewerRenderer.jsx +240 -0
  185. package/src/views/builder/viewer/renderers/DatePickerRenderer.jsx +25 -24
  186. package/src/views/builder/viewer/renderers/DialogRenderer.jsx +327 -0
  187. package/src/views/builder/viewer/renderers/DividerRenderer.jsx +1 -1
  188. package/src/views/builder/viewer/renderers/DonutRenderer.jsx +294 -0
  189. package/src/views/builder/viewer/renderers/DropdownRenderer.jsx +36 -44
  190. package/src/views/builder/viewer/renderers/ExcelUploadRenderer.jsx +639 -0
  191. package/src/views/builder/viewer/renderers/FunnelRenderer.jsx +93 -0
  192. package/src/views/builder/viewer/renderers/GaugeRenderer.jsx +159 -0
  193. package/src/views/builder/viewer/renderers/HeaderRenderer.jsx +31 -9
  194. package/src/views/builder/viewer/renderers/HeatmapGridRenderer.jsx +432 -0
  195. package/src/views/builder/viewer/renderers/IconBoxRenderer.jsx +59 -0
  196. package/src/views/builder/viewer/renderers/ImageRenderer.jsx +1 -1
  197. package/src/views/builder/viewer/renderers/InputRenderer.jsx +75 -18
  198. package/src/views/builder/viewer/renderers/LabelRenderer.jsx +35 -9
  199. package/src/views/builder/viewer/renderers/LayoutCellRenderer.jsx +102 -40
  200. package/src/views/builder/viewer/renderers/LayoutContextMenu.jsx +8 -8
  201. package/src/views/builder/viewer/renderers/LayoutRenderer.jsx +48 -6
  202. package/src/views/builder/viewer/renderers/LinkRenderer.jsx +1 -1
  203. package/src/views/builder/viewer/renderers/MenuRenderer.jsx +2 -2
  204. package/src/views/builder/viewer/renderers/MetricRenderer.jsx +80 -0
  205. package/src/views/builder/viewer/renderers/NumberFormatRenderer.jsx +21 -30
  206. package/src/views/builder/viewer/renderers/PageNumberRenderer.jsx +76 -0
  207. package/src/views/builder/viewer/renderers/PopoverRenderer.jsx +350 -0
  208. package/src/views/builder/viewer/renderers/ProgressCircleRenderer.jsx +1 -1
  209. package/src/views/builder/viewer/renderers/ProgressLineRenderer.jsx +1 -1
  210. package/src/views/builder/viewer/renderers/RadioGroupRenderer.jsx +28 -39
  211. package/src/views/builder/viewer/renderers/RatingRenderer.jsx +80 -0
  212. package/src/views/builder/viewer/renderers/RepeaterRenderer.jsx +297 -38
  213. package/src/views/builder/viewer/renderers/ReportViewerRenderer.jsx +263 -5
  214. package/src/views/builder/viewer/renderers/RichTextRenderer.jsx +60 -66
  215. package/src/views/builder/viewer/renderers/RowActionsCell.jsx +308 -0
  216. package/src/views/builder/viewer/renderers/SignatureRenderer.jsx +33 -62
  217. package/src/views/builder/viewer/renderers/StatusDotRenderer.jsx +75 -0
  218. package/src/views/builder/viewer/renderers/StepStageRenderer.jsx +348 -0
  219. package/src/views/builder/viewer/renderers/TagListRenderer.jsx +115 -0
  220. package/src/views/builder/viewer/renderers/TagPickerRenderer.jsx +31 -45
  221. package/src/views/builder/viewer/renderers/TextAreaRenderer.jsx +25 -18
  222. package/src/views/builder/viewer/renderers/TextRenderer.jsx +7 -1
  223. package/src/views/builder/viewer/renderers/TimePickerRenderer.jsx +25 -24
  224. package/src/views/builder/viewer/renderers/TimelineRenderer.jsx +525 -0
  225. package/src/views/builder/viewer/renderers/ToggleRenderer.jsx +21 -27
  226. package/src/views/builder/viewer/renderers/TreeViewRenderer.jsx +832 -0
  227. package/src/views/builder/viewer/renderers/TrendRenderer.jsx +66 -0
  228. package/src/views/builder/viewer/renderers/ViewRendererRenderer.jsx +315 -0
  229. package/src/views/builder/viewer/renderers/WizardRenderer.jsx +380 -64
  230. package/src/views/builder/viewer/renderers/WizardStepRenderer.jsx +21 -12
  231. package/src/views/builder/viewer/renderers/dataGridComponents.jsx +824 -0
  232. package/src/views/customFilter/CustomFilterDialog.js +1023 -660
  233. package/src/views/customFilter/FixedFilterDialog.js +649 -0
  234. package/src/views/customFilter/SearchFilterDialog.js +248 -0
  235. package/src/views/genericTable/BuilderExpressionParams.js +3 -3
  236. package/src/views/genericTable/ColumnConfiguratorDialog.js +33 -24
  237. package/src/views/genericTable/FixedFilterDialog.js +3 -2
  238. package/src/views/genericTable/FormattingSettingsDialog.js +8 -3
  239. package/src/views/genericTable/SGrid.js +821 -448
  240. package/src/views/genericTable/SearchFilterDialog.js +3 -2
  241. package/src/views/genericTable/cellEditors/autocompleteEditor.js +5 -9
  242. package/src/views/genericTable/convertStringFunctions.js +274 -138
  243. package/src/views/genericTable/statusBar/rowCountStatusBar.js +3 -1
  244. package/src/views/genericTable/updateRefHelpers.js +9 -6
  245. package/src/views/printBuilder/PrintBuilderViewer.jsx +627 -0
  246. package/src/views/printBuilder/PrintPreviewCanvas.jsx +157 -0
  247. package/src/views/rolePermissions/UpdateReportPermissionDialog.js +3 -2
  248. package/src/@core/components/auth/AclGuard.js +0 -55
  249. package/src/@core/components/auth/AuthGuard.js +0 -40
  250. package/src/@core/components/auth/GuestGuard.js +0 -30
  251. package/src/@core/components/custom-inputs/Horizontal.jsx +0 -143
  252. package/src/@core/components/custom-inputs/Image.jsx +0 -78
  253. package/src/@core/components/custom-inputs/Vertical.jsx +0 -113
  254. package/src/@core/components/customizer/index.jsx +0 -470
  255. package/src/@core/components/customizer/styles.module.css +0 -169
  256. package/src/@core/components/mui/Avatar.jsx +0 -41
  257. package/src/@core/components/mui/Badge.jsx +0 -20
  258. package/src/@core/components/mui/IconButton.jsx +0 -74
  259. package/src/@core/components/mui/TabList.jsx +0 -60
  260. package/src/@core/components/option-menu/index.jsx +0 -137
  261. package/src/@core/components/scroll-to-top/index.jsx +0 -43
  262. package/src/@core/components/spinner/index.js +0 -26
  263. package/src/@core/components/window-wrapper/index.js +0 -27
  264. package/src/@core/contexts/settingsContext.jsx +0 -98
  265. package/src/@core/hooks/useBgColor.js +0 -63
  266. package/src/@core/hooks/useImageVariant.js +0 -27
  267. package/src/@core/hooks/useLayoutInit.js +0 -37
  268. package/src/@core/hooks/useObjectCookie.js +0 -18
  269. package/src/@core/hooks/useSettings.jsx +0 -15
  270. package/src/@core/layouts/BlankLayout.js +0 -37
  271. package/src/@core/layouts/BlankLayoutWithAppBar.js +0 -51
  272. package/src/@core/layouts/HorizontalLayout.jsx +0 -151
  273. package/src/@core/layouts/Layout.js +0 -39
  274. package/src/@core/layouts/VerticalLayout.jsx +0 -124
  275. package/src/@core/layouts/components/blank-layout-with-appBar/index.js +0 -115
  276. package/src/@core/layouts/components/horizontal/app-bar-content/index.js +0 -67
  277. package/src/@core/layouts/components/horizontal/navigation/HorizontalNavGroup.js +0 -352
  278. package/src/@core/layouts/components/horizontal/navigation/HorizontalNavItems.js +0 -21
  279. package/src/@core/layouts/components/horizontal/navigation/HorizontalNavLink.js +0 -195
  280. package/src/@core/layouts/components/horizontal/navigation/index.js +0 -31
  281. package/src/@core/layouts/components/shared-components/LanguageDropdown.js +0 -96
  282. package/src/@core/layouts/components/shared-components/ModeToggler.js +0 -32
  283. package/src/@core/layouts/components/shared-components/NotificationDropdown.js +0 -226
  284. package/src/@core/layouts/components/shared-components/UserDropdown.js +0 -177
  285. package/src/@core/layouts/components/shared-components/footer/FooterContent.js +0 -46
  286. package/src/@core/layouts/components/shared-components/footer/index.js +0 -61
  287. package/src/@core/layouts/components/vertical/appBar/index.js +0 -74
  288. package/src/@core/layouts/components/vertical/navigation/Drawer.js +0 -122
  289. package/src/@core/layouts/components/vertical/navigation/VerticalNavGroup.js +0 -435
  290. package/src/@core/layouts/components/vertical/navigation/VerticalNavHeader.js +0 -180
  291. package/src/@core/layouts/components/vertical/navigation/VerticalNavItems.js +0 -26
  292. package/src/@core/layouts/components/vertical/navigation/VerticalNavLink.js +0 -258
  293. package/src/@core/layouts/components/vertical/navigation/VerticalNavSectionTitle.js +0 -102
  294. package/src/@core/layouts/components/vertical/navigation/index.js +0 -169
  295. package/src/@core/layouts/utils.js +0 -69
  296. package/src/@core/styles/Table.module.css +0 -93
  297. package/src/@core/styles/horizontal/menuItemStyles.js +0 -100
  298. package/src/@core/styles/horizontal/menuRootStyles.js +0 -19
  299. package/src/@core/styles/libs/fullcalendar/index.js +0 -461
  300. package/src/@core/styles/libs/keen-slider/index.js +0 -111
  301. package/src/@core/styles/libs/react-apexcharts/index.js +0 -107
  302. package/src/@core/styles/libs/react-cleave/index.js +0 -33
  303. package/src/@core/styles/libs/react-credit-cards/index.js +0 -11
  304. package/src/@core/styles/libs/react-datepicker/index.js +0 -388
  305. package/src/@core/styles/libs/react-draft-wysiwyg/index.js +0 -144
  306. package/src/@core/styles/libs/react-dropzone/index.js +0 -76
  307. package/src/@core/styles/libs/react-hot-toast/index.js +0 -37
  308. package/src/@core/styles/libs/recharts/index.js +0 -47
  309. package/src/@core/styles/stepper.js +0 -103
  310. package/src/@core/styles/vertical/menuItemStyles.js +0 -138
  311. package/src/@core/styles/vertical/menuSectionStyles.js +0 -54
  312. package/src/@core/styles/vertical/navigationCustomStyles.js +0 -62
  313. package/src/@core/svg/ContentCompact.jsx +0 -17
  314. package/src/@core/svg/ContentWide.jsx +0 -17
  315. package/src/@core/svg/DirectionLtr.jsx +0 -93
  316. package/src/@core/svg/DirectionRtl.jsx +0 -93
  317. package/src/@core/svg/LayoutCollapsed.jsx +0 -59
  318. package/src/@core/svg/LayoutHorizontal.jsx +0 -42
  319. package/src/@core/svg/LayoutVertical.jsx +0 -59
  320. package/src/@core/svg/Logo.jsx +0 -76
  321. package/src/@core/svg/SkinBordered.jsx +0 -54
  322. package/src/@core/svg/SkinDefault.jsx +0 -59
  323. package/src/@core/tailwind/plugin.js +0 -78
  324. package/src/@core/theme/ThemeComponent.js +0 -63
  325. package/src/@core/theme/ThemeOptions.js +0 -71
  326. package/src/@core/theme/breakpoints/index.js +0 -11
  327. package/src/@core/theme/colorSchemes.js +0 -326
  328. package/src/@core/theme/customShadows.js +0 -11
  329. package/src/@core/theme/globalStyles.js +0 -81
  330. package/src/@core/theme/index.js +0 -42
  331. package/src/@core/theme/overrides/accordion.js +0 -51
  332. package/src/@core/theme/overrides/accordion.jsx +0 -85
  333. package/src/@core/theme/overrides/alerts.js +0 -110
  334. package/src/@core/theme/overrides/alerts.jsx +0 -180
  335. package/src/@core/theme/overrides/autocomplete.js +0 -14
  336. package/src/@core/theme/overrides/autocomplete.jsx +0 -68
  337. package/src/@core/theme/overrides/avatar.js +0 -38
  338. package/src/@core/theme/overrides/avatars.js +0 -27
  339. package/src/@core/theme/overrides/backdrop.js +0 -22
  340. package/src/@core/theme/overrides/badges.js +0 -16
  341. package/src/@core/theme/overrides/breadcrumbs.js +0 -11
  342. package/src/@core/theme/overrides/button-group.js +0 -84
  343. package/src/@core/theme/overrides/button.js +0 -93
  344. package/src/@core/theme/overrides/buttonGroup.js +0 -9
  345. package/src/@core/theme/overrides/card.js +0 -83
  346. package/src/@core/theme/overrides/checkbox.jsx +0 -95
  347. package/src/@core/theme/overrides/chip.js +0 -72
  348. package/src/@core/theme/overrides/dataGrid.js +0 -114
  349. package/src/@core/theme/overrides/dateTimePicker.js +0 -65
  350. package/src/@core/theme/overrides/dialog.js +0 -120
  351. package/src/@core/theme/overrides/divider.js +0 -13
  352. package/src/@core/theme/overrides/drawer.js +0 -20
  353. package/src/@core/theme/overrides/fab.js +0 -13
  354. package/src/@core/theme/overrides/form-control-label.js +0 -19
  355. package/src/@core/theme/overrides/icon-button.js +0 -145
  356. package/src/@core/theme/overrides/index.js +0 -103
  357. package/src/@core/theme/overrides/input.js +0 -72
  358. package/src/@core/theme/overrides/link.js +0 -9
  359. package/src/@core/theme/overrides/list.js +0 -44
  360. package/src/@core/theme/overrides/menu.js +0 -25
  361. package/src/@core/theme/overrides/pagination.js +0 -41
  362. package/src/@core/theme/overrides/paper.js +0 -9
  363. package/src/@core/theme/overrides/popover.js +0 -16
  364. package/src/@core/theme/overrides/progress.js +0 -38
  365. package/src/@core/theme/overrides/radio.jsx +0 -80
  366. package/src/@core/theme/overrides/rating.js +0 -16
  367. package/src/@core/theme/overrides/rating.jsx +0 -32
  368. package/src/@core/theme/overrides/select.js +0 -19
  369. package/src/@core/theme/overrides/select.jsx +0 -52
  370. package/src/@core/theme/overrides/slider.js +0 -97
  371. package/src/@core/theme/overrides/snackbar.js +0 -19
  372. package/src/@core/theme/overrides/switch.js +0 -73
  373. package/src/@core/theme/overrides/switches.js +0 -25
  374. package/src/@core/theme/overrides/table-pagination.js +0 -39
  375. package/src/@core/theme/overrides/table.js +0 -81
  376. package/src/@core/theme/overrides/tabs.js +0 -30
  377. package/src/@core/theme/overrides/timeline.js +0 -80
  378. package/src/@core/theme/overrides/toggle-button.js +0 -33
  379. package/src/@core/theme/overrides/toggleButton.js +0 -16
  380. package/src/@core/theme/overrides/tooltip.js +0 -21
  381. package/src/@core/theme/overrides/typography.js +0 -13
  382. package/src/@core/theme/palette/index.js +0 -107
  383. package/src/@core/theme/shadows/index.js +0 -61
  384. package/src/@core/theme/shadows.js +0 -12
  385. package/src/@core/theme/spacing/index.js +0 -3
  386. package/src/@core/theme/spacing.js +0 -5
  387. package/src/@core/theme/typography/index.js +0 -65
  388. package/src/@core/theme/typography.js +0 -84
  389. package/src/@core/utils/create-emotion-cache.js +0 -5
  390. package/src/@core/utils/hex-to-rgba.js +0 -11
  391. package/src/@core/utils/serverHelpers.js +0 -45
  392. package/src/@menu/components/RouterLink.jsx +0 -18
  393. package/src/@menu/components/horizontal-menu/HorizontalNav.jsx +0 -88
  394. package/src/@menu/components/horizontal-menu/Menu.jsx +0 -83
  395. package/src/@menu/components/horizontal-menu/MenuButton.jsx +0 -100
  396. package/src/@menu/components/horizontal-menu/MenuItem.jsx +0 -183
  397. package/src/@menu/components/horizontal-menu/SubMenu.jsx +0 -418
  398. package/src/@menu/components/horizontal-menu/SubMenuContent.jsx +0 -41
  399. package/src/@menu/components/horizontal-menu/VerticalNavInHorizontal.jsx +0 -20
  400. package/src/@menu/components/vertical-menu/Menu.jsx +0 -161
  401. package/src/@menu/components/vertical-menu/MenuButton.jsx +0 -95
  402. package/src/@menu/components/vertical-menu/MenuItem.jsx +0 -180
  403. package/src/@menu/components/vertical-menu/MenuSection.jsx +0 -124
  404. package/src/@menu/components/vertical-menu/NavCollapseIcons.jsx +0 -70
  405. package/src/@menu/components/vertical-menu/NavHeader.jsx +0 -39
  406. package/src/@menu/components/vertical-menu/SubMenu.jsx +0 -420
  407. package/src/@menu/components/vertical-menu/SubMenuContent.jsx +0 -101
  408. package/src/@menu/components/vertical-menu/VerticalNav.jsx +0 -216
  409. package/src/@menu/contexts/horizontalNavContext.jsx +0 -29
  410. package/src/@menu/contexts/verticalNavContext.jsx +0 -65
  411. package/src/@menu/defaultConfigs.js +0 -12
  412. package/src/@menu/hooks/useHorizontalMenu.jsx +0 -19
  413. package/src/@menu/hooks/useHorizontalNav.jsx +0 -19
  414. package/src/@menu/hooks/useMediaQuery.jsx +0 -29
  415. package/src/@menu/hooks/useVerticalMenu.jsx +0 -19
  416. package/src/@menu/hooks/useVerticalNav.jsx +0 -19
  417. package/src/@menu/horizontal-menu/index.jsx +0 -8
  418. package/src/@menu/styles/StyledBackdrop.jsx +0 -15
  419. package/src/@menu/styles/StyledMenuIcon.jsx +0 -12
  420. package/src/@menu/styles/StyledMenuLabel.jsx +0 -16
  421. package/src/@menu/styles/StyledMenuPrefix.jsx +0 -10
  422. package/src/@menu/styles/StyledMenuSectionLabel.jsx +0 -21
  423. package/src/@menu/styles/StyledMenuSuffix.jsx +0 -10
  424. package/src/@menu/styles/StyledSubMenuContent.jsx +0 -43
  425. package/src/@menu/styles/horizontal/StyledHorizontalMenu.jsx +0 -13
  426. package/src/@menu/styles/horizontal/StyledHorizontalMenuItem.jsx +0 -26
  427. package/src/@menu/styles/horizontal/StyledHorizontalNav.jsx +0 -11
  428. package/src/@menu/styles/horizontal/StyledHorizontalNavExpandIcon.jsx +0 -33
  429. package/src/@menu/styles/horizontal/StyledHorizontalSubMenuContent.jsx +0 -18
  430. package/src/@menu/styles/horizontal/StyledHorizontalSubMenuContentWrapper.jsx +0 -10
  431. package/src/@menu/styles/horizontal/horizontalUl.module.css +0 -15
  432. package/src/@menu/styles/styles.module.css +0 -5
  433. package/src/@menu/styles/vertical/StyledVerticalMenu.jsx +0 -16
  434. package/src/@menu/styles/vertical/StyledVerticalMenuItem.jsx +0 -28
  435. package/src/@menu/styles/vertical/StyledVerticalMenuSection.jsx +0 -23
  436. package/src/@menu/styles/vertical/StyledVerticalNav.jsx +0 -67
  437. package/src/@menu/styles/vertical/StyledVerticalNavBgColorContainer.jsx +0 -15
  438. package/src/@menu/styles/vertical/StyledVerticalNavContainer.jsx +0 -23
  439. package/src/@menu/styles/vertical/StyledVerticalNavExpandIcon.jsx +0 -25
  440. package/src/@menu/styles/vertical/verticalNavBgImage.module.css +0 -10
  441. package/src/@menu/svg/ChevronRight.jsx +0 -9
  442. package/src/@menu/svg/Close.jsx +0 -12
  443. package/src/@menu/svg/RadioCircle.jsx +0 -12
  444. package/src/@menu/svg/RadioCircleMarked.jsx +0 -13
  445. package/src/@menu/utils/menuClasses.js +0 -44
  446. package/src/@menu/utils/menuUtils.jsx +0 -145
  447. package/src/@menu/vertical-menu/index.jsx +0 -11
  448. package/src/configs/acl.js +0 -115
  449. package/src/configs/auth.js +0 -5
  450. package/src/configs/aws-exports.js +0 -30
  451. package/src/configs/firebase.js +0 -25
  452. package/src/configs/i18n.js +0 -34
  453. package/src/configs/primaryColorConfig.js +0 -35
  454. package/src/configs/themeConfig.js +0 -44
  455. package/src/layouts/UserLayout.js +0 -94
  456. package/src/layouts/UserThemeOptions.js +0 -191
  457. package/src/layouts/components/Direction.js +0 -30
  458. package/src/layouts/components/HtmlTooltip.js +0 -15
  459. package/src/layouts/components/Translations.js +0 -11
  460. package/src/layouts/components/UserDropdown.js +0 -217
  461. package/src/layouts/components/UserIcon.js +0 -40
  462. package/src/layouts/components/acl/Can.js +0 -6
  463. package/src/layouts/components/acl/CanViewNavGroup.js +0 -36
  464. package/src/layouts/components/acl/CanViewNavLink.js +0 -17
  465. package/src/layouts/components/acl/CanViewNavSectionTitle.js +0 -17
  466. package/src/layouts/components/horizontal/AppBarContent.js +0 -39
  467. package/src/layouts/components/horizontal/ServerSideNavItems.js +0 -44
  468. package/src/layouts/components/mui/StepperComps.js +0 -55
  469. package/src/layouts/components/vertical/AppBarContent.js +0 -35
  470. package/src/layouts/components/vertical/ServerSideNavItems.js +0 -44
  471. package/src/libs/ApexCharts.jsx +0 -5
  472. package/src/libs/ReactPlayer.jsx +0 -5
  473. package/src/libs/Recharts.jsx +0 -4
  474. package/src/libs/auth.js +0 -124
  475. package/src/libs/styles/AppFullCalendar.js +0 -505
  476. package/src/libs/styles/AppKeenSlider.js +0 -116
  477. package/src/libs/styles/AppReactApexCharts.jsx +0 -110
  478. package/src/libs/styles/AppReactDatepicker.jsx +0 -470
  479. package/src/libs/styles/AppReactDropzone.js +0 -76
  480. package/src/libs/styles/AppReactToastify.jsx +0 -108
  481. package/src/libs/styles/AppRecharts.js +0 -55
  482. package/src/libs/styles/inputOtp.module.css +0 -39
  483. package/src/libs/styles/tiptapEditor.css +0 -72
  484. package/src/navigation/horizontal/index.js +0 -246
  485. package/src/navigation/vertical/index.js +0 -253
  486. package/src/pages/401.js +0 -70
  487. package/src/pages/404.js +0 -67
  488. package/src/pages/500.js +0 -68
  489. package/src/pages/[slug].js +0 -115
  490. package/src/pages/_document.js +0 -72
  491. package/src/pages/api/navigation/regenerate-registry.js +0 -116
  492. package/src/pages/api/navigation/save.js +0 -218
  493. package/src/pages/authModule/acl/index.js +0 -48
  494. package/src/pages/authModule/forgot-password/index.js +0 -228
  495. package/src/pages/authModule/permissions/rolePermissions/[id]/rolePermissionsUser/index.js +0 -392
  496. package/src/pages/authModule/permissions/rolePermissions/index.js +0 -343
  497. package/src/pages/authModule/permissions/systemPermissions/index.js +0 -354
  498. package/src/pages/authModule/privacy/index.js +0 -721
  499. package/src/pages/authModule/users/index.js +0 -210
  500. package/src/pages/login/index.js +0 -328
  501. package/src/pages/mainHome/index.js +0 -181
  502. package/src/views/builder/inspector/definitions/cell/main.js +0 -4
  503. package/src/views/builder/inspector/definitions/column/main.js +0 -9
  504. package/src/views/builder/inspector/definitions/column-group/main.js +0 -18
  505. package/src/views/builder/inspector/definitions/header-cell/main.js +0 -5
  506. package/src/views/builder/inspector/definitions/table/main.js +0 -9
  507. package/src/views/builder/viewer/renderers/CellRenderer.jsx +0 -71
  508. package/src/views/builder/viewer/renderers/ColumnGroupRenderer.jsx +0 -96
  509. package/src/views/builder/viewer/renderers/ColumnRenderer.jsx +0 -71
  510. package/src/views/builder/viewer/renderers/HeaderCellRenderer.jsx +0 -78
  511. package/src/views/builder/viewer/renderers/TabRenderer.jsx +0 -82
  512. package/src/views/builder/viewer/renderers/TableRenderer.jsx +0 -92
  513. package/src/views/pages/auth/FooterIllustrationsV2.js +0 -40
  514. package/src/views/pages/misc/FooterIllustrations.js +0 -47
  515. package/src/views/pages/misc/muiTable/CustomPagination.js +0 -34
  516. package/src/views/pages/users/UserManageDialog.js +0 -283
  517. package/src/views/pages/users/UserViewPage.js +0 -199
  518. package/src/views/users/AddUserNameDialog.js +0 -162
  519. package/src/views/users/ContactManage.js +0 -449
  520. package/src/views/users/ResetPasswordDialog.js +0 -242
@@ -58,7 +58,7 @@ import Grid from '@mui/material/Grid'
58
58
  // ** Icons Imports
59
59
  // ** Store Imports
60
60
  // ** Custom Components Imports
61
- import {useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react'
61
+ import {createContext, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react'
62
62
 
63
63
  // Global styles for flashing effect
64
64
  if (typeof document !== 'undefined') {
@@ -79,15 +79,15 @@ if (typeof document !== 'undefined') {
79
79
 
80
80
  import {Endpoints, Services} from 'src/services/Endpoints'
81
81
  import {
82
- Autocomplete, Checkbox,
82
+ Autocomplete, Button, Checkbox,
83
83
  CircularProgress,
84
- Dialog,
84
+ Dialog, Divider,
85
85
  FormControl, FormControlLabel,
86
86
  IconButton,
87
87
  MenuItem,
88
88
  Select,
89
89
  TextField,
90
- Tooltip,
90
+ Tooltip, Typography,
91
91
  Chip,
92
92
  Stack,
93
93
  Popper,
@@ -98,7 +98,9 @@ import {
98
98
  Menu
99
99
  } from '@mui/material'
100
100
  import {AgGridReact} from "ag-grid-react";
101
- import {Edit, FilterAlt, PrintOutlined, RefreshOutlined, Save, SaveAs, Close} from "@mui/icons-material";
101
+ import {Edit, FilterAlt, PrintOutlined, RefreshOutlined, Save, SaveAs, Close, SearchOutlined} from "@mui/icons-material";
102
+ // Lazy MUI icon resolver for viewer-action button icons (icon name string → component)
103
+ import * as MuiIcons from "@mui/icons-material";
102
104
  import {getRandomInt, Helper} from "services/helper/helper";
103
105
  import PostService from 'services/PostService'
104
106
  import handleChange from 'services/helper/handleChange'
@@ -136,6 +138,7 @@ import {
136
138
  restoreUpdateRefFromOriginal
137
139
  } from './updateRefHelpers'
138
140
  import {processColumnDefinitions, processColumnsConfig} from './convertStringFunctions'
141
+ import { AG_COMPONENTS } from 'views/builder/viewer/renderers/dataGridComponents'
139
142
 
140
143
  // ** Utils Import
141
144
 
@@ -148,6 +151,181 @@ const defaultFinalRequest = {
148
151
  filter: {},
149
152
  params: {}
150
153
  }
154
+
155
+ // ── Templates tool panel ──────────────────────────────────────────────────────
156
+ // Defined outside SGrid so the reference is stable (no remounts on parent renders).
157
+ // State flows in via React Context (AG Grid v33 renders custom components in the
158
+ // same React tree, so context is fully supported).
159
+ const TemplateStateContext = createContext(null)
160
+
161
+ function SettingsSection({ title, children }) {
162
+ return (
163
+ <Box style={{ display: 'block', width: '100%' }}>
164
+ <Box sx={{
165
+ px: 2, py: 0.75,
166
+ bgcolor: 'grey.100',
167
+ borderTop: '1px solid', borderBottom: '1px solid', borderColor: 'divider',
168
+ }}>
169
+ <Typography sx={{ fontSize: '0.6875rem', fontWeight: 700, textTransform: 'uppercase', letterSpacing: 0.8, color: 'text.secondary' }}>
170
+ {title}
171
+ </Typography>
172
+ </Box>
173
+ <Box sx={{ p: 2, boxSizing: 'border-box', width: '100%' }}>
174
+ {children}
175
+ </Box>
176
+ </Box>
177
+ )
178
+ }
179
+
180
+ function TemplatesToolPanel() {
181
+ const ctx = useContext(TemplateStateContext)
182
+ if (!ctx) return null
183
+ const {
184
+ templates, selectedTemplate, setSelectedTemplate,
185
+ handleGetTemplates, handleSaveTemplate,
186
+ handleToggleDialogs, setIsTemplateEditing,
187
+ builderData,
188
+ // Display settings (moved out of the in-grid toolbar) — see toolbar render
189
+ // below. These used to live next to the search field; they were moved to
190
+ // make the toolbar more compact and to follow the same disclosure pattern
191
+ // as Templates (advanced/less-used settings live in the side panel).
192
+ timerValue, setTimerValue,
193
+ isPagination, setIsPagination,
194
+ handleCSVExport, isDownloading,
195
+ isExcelExportAvailable,
196
+ } = ctx
197
+
198
+ return (
199
+ <Box style={{ display: 'flex', flexDirection: 'column', height: '100%', width: 250 }}>
200
+ {/* Panel header */}
201
+ <Box sx={{
202
+ px: 2, py: 1.5,
203
+ borderBottom: '1px solid', borderColor: 'divider',
204
+ bgcolor: 'background.paper',
205
+ position: 'sticky', top: 0, zIndex: 1,
206
+ }}>
207
+ <Typography variant='subtitle2' sx={{ fontWeight: 700, color: 'text.primary' }}>
208
+ Settings
209
+ </Typography>
210
+ </Box>
211
+
212
+ {/* Display settings — auto-refresh timer, full-data toggle, Excel export */}
213
+ <SettingsSection title='Display Settings'>
214
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, width: '100%' }}>
215
+ <Box>
216
+ <Typography variant='caption' sx={{ color: 'text.secondary', display: 'block', mb: 0.5 }}>
217
+ Auto-refresh
218
+ </Typography>
219
+ <Select
220
+ fullWidth
221
+ size='small'
222
+ value={timerValue ?? 0}
223
+ onChange={(e) => setTimerValue?.(e.target.value)}
224
+ >
225
+ <MenuItem value={0}>Off</MenuItem>
226
+ <MenuItem value={0.5}>Every 30s</MenuItem>
227
+ <MenuItem value={1}>Every 1m</MenuItem>
228
+ <MenuItem value={2}>Every 2m</MenuItem>
229
+ <MenuItem value={5}>Every 5m</MenuItem>
230
+ <MenuItem value={15}>Every 15m</MenuItem>
231
+ <MenuItem value={30}>Every 30m</MenuItem>
232
+ </Select>
233
+ </Box>
234
+
235
+ <FormControlLabel
236
+ control={
237
+ <Checkbox
238
+ size='small'
239
+ checked={!isPagination}
240
+ onChange={e => setIsPagination?.(!e.target.checked)}
241
+ color='primary'
242
+ />
243
+ }
244
+ label={<Typography variant='body2'>Load all data (no pagination)</Typography>}
245
+ />
246
+
247
+ {isExcelExportAvailable && (
248
+ <Button
249
+ size='small'
250
+ variant='outlined'
251
+ startIcon={isDownloading ? <CircularProgress size={16}/> : <FileExcelOutline fontSize='small'/>}
252
+ onClick={handleCSVExport}
253
+ disabled={isDownloading}
254
+ fullWidth
255
+ sx={{ justifyContent: 'flex-start' }}
256
+ >
257
+ Export to Excel
258
+ </Button>
259
+ )}
260
+ </Box>
261
+ </SettingsSection>
262
+
263
+ {/* Template section */}
264
+ <SettingsSection title='Template'>
265
+ {builderData?.id == null ? (
266
+ <Typography variant='caption' sx={{ color: 'text.disabled' }}>No report loaded</Typography>
267
+ ) : (
268
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, width: '100%' }}>
269
+ <Autocomplete
270
+ size='small'
271
+ value={selectedTemplate}
272
+ options={templates}
273
+ onChange={(_, value) => setSelectedTemplate(value)}
274
+ getOptionLabel={option => option.name}
275
+ renderInput={params => (
276
+ <TextField
277
+ label='Active Template'
278
+ {...params}
279
+ onMouseDown={handleGetTemplates}
280
+ />
281
+ )}
282
+ />
283
+
284
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1, width: '100%' }}>
285
+ <Button
286
+ size='small'
287
+ variant='outlined'
288
+ startIcon={<Save fontSize='small' />}
289
+ disabled={selectedTemplate == null}
290
+ onClick={handleSaveTemplate}
291
+ fullWidth
292
+ sx={{ justifyContent: 'flex-start' }}
293
+ >
294
+ Save
295
+ </Button>
296
+
297
+ <Button
298
+ size='small'
299
+ variant='outlined'
300
+ startIcon={<SaveAs fontSize='small' />}
301
+ onClick={() => { setIsTemplateEditing(false); handleToggleDialogs('addTemplate') }}
302
+ fullWidth
303
+ sx={{ justifyContent: 'flex-start' }}
304
+ >
305
+ Save As New
306
+ </Button>
307
+
308
+ <Button
309
+ size='small'
310
+ variant='outlined'
311
+ startIcon={<Edit fontSize='small' />}
312
+ disabled={selectedTemplate == null}
313
+ onClick={() => { setIsTemplateEditing(true); handleToggleDialogs('addTemplate') }}
314
+ fullWidth
315
+ sx={{ justifyContent: 'flex-start' }}
316
+ >
317
+ Edit
318
+ </Button>
319
+ </Box>
320
+ </Box>
321
+ )}
322
+ </SettingsSection>
323
+ </Box>
324
+ )
325
+ }
326
+
327
+ // ─────────────────────────────────────────────────────────────────────────────
328
+
151
329
  const SGrid = props => {
152
330
  // ** State
153
331
  const appContext = useContext(SystemContext);
@@ -166,6 +344,13 @@ const SGrid = props => {
166
344
  expireReport,
167
345
  filter: externalFilter,
168
346
  actions,
347
+ // Page-level toolbar buttons rendered after Filter/Refresh.
348
+ // Built by ReportViewerRenderer; each item already has a bound onClick.
349
+ viewerActions,
350
+ // Title / caption rendered on the left side of the toolbar, sharing the
351
+ // row with the search and action buttons. See attached design reference.
352
+ title: viewerTitle,
353
+ caption: viewerCaption,
169
354
  refresh,
170
355
  height,
171
356
  extraCols,
@@ -182,7 +367,16 @@ const SGrid = props => {
182
367
  columnsConfig,
183
368
  dataAsObject = false,
184
369
  isRerender = false,
185
- updateRef
370
+ updateRef,
371
+ // nodeId — builder schema node ID for this ReportViewer (set by ReportViewerRenderer)
372
+ // reportRefs — shared registry { [nodeId]: updateRef } for all reports on the page
373
+ nodeId,
374
+ reportRefs,
375
+ // Viewer state — passed through to column string functions via convertStringFunctions ctx
376
+ data: viewerData,
377
+ dataRef: viewerDataRef,
378
+ openDialog,
379
+ closeDialog,
186
380
  } = props
187
381
  const groupEndPoint = ReportBuilderEndpoints.Post.GenericGet;
188
382
  const streamEndPoint = ReportBuilderEndpoints.Post.GenericGet;
@@ -222,6 +416,17 @@ const SGrid = props => {
222
416
  const searchInputRef = useRef(null);
223
417
  const [searchPopoverOpen, setSearchPopoverOpen] = useState(false);
224
418
  const [searchPopoverAnchor, setSearchPopoverAnchor] = useState(null);
419
+ // Search expansion: collapsed → just an icon button; expanded → full TextField.
420
+ // Auto-expand if the user is typing or already has filters in chips, so the
421
+ // visual state always shows what's active.
422
+ const [isSearchExpanded, setIsSearchExpanded] = useState(false);
423
+ // Keyboard navigation in the search popover. Index points into
424
+ // searchFieldsRef.current. Reset whenever the popover opens or the term
425
+ // changes so the highlight always starts at the top of the list.
426
+ const [highlightedFieldIndex, setHighlightedFieldIndex] = useState(0);
427
+ // refs to ListItemButton DOM nodes so we can scrollIntoView the highlighted
428
+ // item when the user arrows past the visible part of the (capped 240px) list.
429
+ const searchOptionRefs = useRef([]);
225
430
 
226
431
  const searchTermRef = useRef('');
227
432
  const searchFieldsRef = useRef([]); // metadata only, no value
@@ -696,7 +901,7 @@ const SGrid = props => {
696
901
  const propertyType = col.propertyType ?? col.field?.propertyType;
697
902
  const propPath = col.headerName ?? col.path;
698
903
  const fieldName = col.headerName ?? col.path.replace(/\./g, '_');
699
- const processedColumnsConfig = processColumnsConfig(columnsConfig ?? []);
904
+ const processedColumnsConfig = processColumnsConfig(columnsConfig ?? [], { reportRefs, nodeName: nodeId, data: viewerData, dataRef: viewerDataRef, setData, openDialog, closeDialog });
700
905
  const externalColConfig = processedColumnsConfig.find(x => x.field === fieldName)?.config ?? {}
701
906
  const headerName = col.title ?? col.headerName ?? col.path;
702
907
  const hasRouting = routingSettings.some(r => r.fieldName === fieldName);
@@ -959,7 +1164,7 @@ const SGrid = props => {
959
1164
  }))
960
1165
  setSelectParams(localSelectParams);
961
1166
  if (extraCols != null) {
962
- const processedExtraCols = processColumnDefinitions(extraCols);
1167
+ const processedExtraCols = processColumnDefinitions(extraCols, { reportRefs, nodeName: nodeId, data: viewerData, dataRef: viewerDataRef, setData, openDialog, closeDialog });
963
1168
  localColDefs = [...processedExtraCols, ...localColDefs];
964
1169
  }
965
1170
  localColDefs = [...localColDefs, ...defaultCols];
@@ -1010,7 +1215,7 @@ const SGrid = props => {
1010
1215
  tableCols = processColumns(tableCols)
1011
1216
  let localColDefs = [...tableCols, ...defaultCols]
1012
1217
  if (extraCols != null) {
1013
- const processedExtraCols = processColumnDefinitions(extraCols);
1218
+ const processedExtraCols = processColumnDefinitions(extraCols, { reportRefs, nodeName: nodeId, data: viewerData, dataRef: viewerDataRef, setData, openDialog, closeDialog });
1014
1219
  localColDefs = [...processedExtraCols, ...localColDefs]
1015
1220
  }
1016
1221
  const localSelectTFilter = response.data.map(x => ({
@@ -1125,7 +1330,7 @@ const SGrid = props => {
1125
1330
  id: targetPageId ? null : (builderId ?? null)
1126
1331
  };
1127
1332
 
1128
- const base = '/reportBuilder/reportViewer';
1333
+ const base = '/builders/report/viewer';
1129
1334
  let url = base;
1130
1335
  if (targetPageId) {
1131
1336
  url += `?pageId=${encodeURIComponent(targetPageId)}`;
@@ -1301,26 +1506,35 @@ const SGrid = props => {
1301
1506
  }
1302
1507
  }
1303
1508
 
1304
- const sideBarConfig = useMemo(() => ({
1305
- toolPanels: [
1306
- {
1307
- id: 'columns',
1308
- labelDefault: 'Columns',
1309
- labelKey: 'columns',
1310
- iconKey: 'columns',
1311
- toolPanel: 'agColumnsToolPanel',
1312
- toolPanelParams: {
1313
- suppressRowGroups: groupBy != null,
1314
- suppressValues: groupBy != null,
1509
+ const sideBarConfig = useMemo(
1510
+ () => ({
1511
+ toolPanels: [
1512
+ {
1513
+ id: 'columns',
1514
+ labelDefault: 'Columns',
1515
+ labelKey: 'columns',
1516
+ iconKey: 'columns',
1517
+ toolPanel: 'agColumnsToolPanel',
1518
+ toolPanelParams: {
1519
+ suppressRowGroups: groupBy != null,
1520
+ suppressValues: groupBy != null
1521
+ },
1522
+ minWidth: 225
1315
1523
  },
1316
- minWidth: 225,
1317
- },
1318
-
1319
- ],
1320
- position: 'left',
1321
- // ← optionally open this panel by default on init
1322
- defaultToolPanel: 'columns',
1323
- }), [groupBy]); // only re-create if groupBy changes
1524
+ {
1525
+ id: 'templates',
1526
+ labelDefault: 'Templates',
1527
+ labelKey: 'templates',
1528
+ iconKey: 'menu',
1529
+ toolPanel: 'templatesToolPanel',
1530
+ minWidth: 250,
1531
+ }
1532
+ ],
1533
+ position: 'right',
1534
+ defaultToolPanel: '' // closed by default
1535
+ }),
1536
+ [groupBy]
1537
+ ) // only re-create if groupBy changes
1324
1538
  const handleGetAggregationObject = (agg) => {
1325
1539
 
1326
1540
  const matchedCol = builderData.selectedFields.find(col => {
@@ -2319,432 +2533,594 @@ const SGrid = props => {
2319
2533
 
2320
2534
  return (
2321
2535
  <Grid container size={{ xs: 12 }}>
2322
- <Grid container
2323
- sx={{backgroundColor: '#fafafb', justifyContent: 'space-between'}} padding={2}
2324
- size={{ xs: 12 }}>
2325
- <Box sx={{display: 'flex'}}>
2326
- {(builderData?.id != null && minimized !== true) &&
2327
- <Box sx={{minWidth: '250px'}}>
2328
-
2329
- <FormControl fullWidth>
2330
- <Autocomplete
2331
- size={'small'}
2332
- value={selectedTemplate}
2333
- fullWidth
2334
- options={templates}
2335
- onChange={(e, value) => {
2336
- setSelectedTemplate(value)
2337
- }}
2338
-
2339
- getOptionLabel={option => option.name}
2340
- renderInput={params => (
2341
- <TextField
2342
- label='شكل النموذج'
2343
- {...params}
2344
- onMouseDown={() => {
2345
- handleGetTemplates()
2346
- }}
2347
- />
2348
- )}
2349
- />
2350
- </FormControl>
2351
- </Box>
2352
- }
2353
- <Box sx={{ml: '5px'}}>
2354
- <Tooltip title='مؤقت' placement={'top'}>
2355
- <Select variant={'outlined'} value={timerValue} onChange={(e) => setTimerValue(e.target.value)}
2356
- defaultValue={0} size={'small'}
2357
- color='primary' sx={{width: '60px'}}>
2358
- <MenuItem key={1} value={0}>No</MenuItem>
2359
- {/*<MenuItem key={2} value={0.1667}>10s</MenuItem>*/}
2360
- <MenuItem key={2} value={0.5}>30s</MenuItem>
2361
- <MenuItem key={2} value={1}>1m</MenuItem>
2362
- <MenuItem key={2} value={2}>2m</MenuItem>
2363
- <MenuItem key={2} value={5}>5m</MenuItem>
2364
- <MenuItem key={3} value={15}>15m</MenuItem>
2365
- <MenuItem key={4} value={30}>30m</MenuItem>
2366
- </Select>
2367
- </Tooltip>
2368
- </Box>
2369
- </Box>
2370
- {((searchFieldsRef?.current?.length ?? []) > 0) &&
2371
- <Box sx={{flex: 1, px: 1, minWidth: minimized ? 140 : 300, display: 'flex', alignItems: 'center'}}>
2372
- {/*<Tooltip title={'اكتب كلمة البحث ثم اختر الحقل'}>*/}
2373
- <Box sx={{position: 'relative', width: '100%'}}>
2374
- <TextField
2375
- label={'بحث'}
2376
- fullWidth
2377
- size={'small'}
2378
- value={searchTerm}
2379
- inputRef={searchInputRef}
2380
- onFocus={(e) => {
2381
- if ((e.target.value || '').length > 0) {
2382
- setSearchPopoverAnchor(e.currentTarget);
2383
- setSearchPopoverOpen(true);
2384
- }
2385
- }}
2386
- onChange={(e) => {
2387
- const v = e.target.value;
2388
- setSearchTerm(v);
2389
- setSearchPopoverAnchor(e.currentTarget);
2390
- setSearchPopoverOpen((v || '').length > 0);
2391
- }}
2392
- onKeyDown={(e) => {
2393
- if (e.key === 'Enter') {
2394
- e.preventDefault();
2395
- const term = (searchTerm || '').trim();
2396
- if (!term) return;
2397
- const fields = searchFieldsRef?.current ?? [];
2398
- if (fields.length === 0) return;
2399
- handlePickSearchField(fields[0]);
2400
- } else if (e.key === 'Escape') {
2401
- setSearchPopoverOpen(false);
2402
- }
2536
+ <Grid
2537
+ container
2538
+ sx={{ justifyContent: 'space-between', alignItems: 'center', flexWrap: 'nowrap', gap: 2 }}
2539
+ padding={2}
2540
+ size={{ xs: 12 }}
2541
+ >
2542
+ {/*
2543
+ ── Toolbar layout ───────────────────────────────────────────────────
2544
+ One row, split into:
2545
+
2546
+ LEFT : title (h6) + caption (caption) stacked vertically.
2547
+ Both are optional — the block is hidden if neither is set.
2548
+ RIGHT : collapsible search (icon → TextField on focus / when it
2549
+ has a value), Filter (outlined Button), Refresh (outlined
2550
+ Button), then any user-defined viewerActions in order.
2551
+
2552
+ Timer / Select-All / Excel-Export live in the Templates side panel
2553
+ under "Display Settings" — see TemplatesToolPanel above.
2554
+ */}
2555
+
2556
+ {/* ── LEFT: title + caption ─────────────────────────────────────── */}
2557
+ {viewerTitle || viewerCaption ? (
2558
+ <Box sx={{ display: 'flex', flexDirection: 'column', minWidth: 0, flexShrink: 1 }}>
2559
+ {viewerTitle && (
2560
+ <Typography
2561
+ variant='h6'
2562
+ sx={{
2563
+ fontWeight: 600,
2564
+ lineHeight: 1.2,
2565
+ color: 'text.primary',
2566
+ whiteSpace: 'nowrap',
2567
+ overflow: 'hidden',
2568
+ textOverflow: 'ellipsis'
2403
2569
  }}
2404
- InputProps={{
2405
- startAdornment: (
2406
- <Box sx={{display: 'flex', gap: 0.5, flexWrap: 'wrap'}}>
2407
- {(() => {
2408
- const byPath = selectedSearchObjects.reduce((acc, it) => {
2409
- const key = it.path;
2410
- if (!acc[key]) acc[key] = {meta: it, values: []};
2411
- acc[key].values.push(String(it.value));
2412
- return acc;
2413
- }, {});
2414
- return Object.keys(byPath).map(path => {
2415
- const g = byPath[path];
2416
- const labelBase = g.meta.friendlyName || g.meta.path;
2417
- const valueLabel = g.values.reduce((acc, val, idx) => {
2418
- if (idx > 0) acc.push(<strong key={`sep-${idx}`}> أو </strong>);
2419
- acc.push(val);
2420
- return acc;
2421
- }, []);
2422
- return (
2423
- <Chip
2424
- key={`group-${path}`}
2425
- size="small"
2426
- label={
2427
- <span>
2428
- <strong>{labelBase}</strong>: {valueLabel}
2429
- </span>
2430
- } onDelete={() => {
2431
- setSelectedSearchObjects(prev => prev.filter(it => it.path !== path));
2432
- debouncedRefresh();
2433
- }}
2434
- deleteIcon={
2435
- <Box sx={{
2436
- display: 'flex',
2437
- alignItems: 'center',
2438
- px: 0.5,
2439
- bgcolor: 'error.main',
2440
- color: (theme) => theme.palette.error.contrastText,
2441
- height: '100%',
2442
- alignSelf: 'stretch',
2443
- borderTopRightRadius: '4px',
2444
- borderBottomRightRadius: '4px'
2445
- }}>
2446
- <Close fontSize="small"/>
2447
- </Box>
2448
- }
2449
- sx={{
2450
- mr: 0.5,
2451
- borderRadius: '8px',
2452
- '& .MuiChip-deleteIcon': {
2453
- margin: 0
2454
- }
2455
- }}
2456
- />
2457
- );
2458
- });
2459
- })()}
2460
- </Box>
2461
- )
2570
+ >
2571
+ {viewerTitle}
2572
+ </Typography>
2573
+ )}
2574
+ {viewerCaption && (
2575
+ <Typography
2576
+ variant='caption'
2577
+ sx={{
2578
+ color: 'text.secondary',
2579
+ lineHeight: 1.2,
2580
+ whiteSpace: 'nowrap',
2581
+ overflow: 'hidden',
2582
+ textOverflow: 'ellipsis'
2462
2583
  }}
2463
- />
2584
+ >
2585
+ {viewerCaption}
2586
+ </Typography>
2587
+ )}
2588
+ </Box>
2589
+ ) : (
2590
+ // Empty spacer keeps the right-side controls right-aligned even when
2591
+ // no title is set, so layout looks consistent across reports.
2592
+ <Box />
2593
+ )}
2464
2594
 
2465
- <ClickAwayListener onClickAway={() => setSearchPopoverOpen(false)}>
2466
- <Popper
2467
- open={searchPopoverOpen}
2468
- anchorEl={searchPopoverAnchor}
2469
- placement="bottom-start"
2470
- style={{zIndex: 1300, width: searchInputRef?.current?.offsetWidth || undefined}}
2471
- >
2472
- <Paper elevation={3} sx={{mt: 0.5, maxHeight: 240, overflowY: 'auto'}}>
2473
- <List dense>
2474
- {(searchFieldsRef?.current ?? []).map((option, i) => (
2475
- <ListItemButton key={`${option.path}-${i}`} onClick={() => handlePickSearchField(option)}>
2476
- <Box sx={{display: 'flex', flexDirection: 'column'}}>
2477
- <Box sx={{fontSize: 14, fontWeight: 500}}>{option.friendlyName || option.path}</Box>
2478
- {/*<Box sx={{fontSize: 12, color: 'text.secondary'}}>{option.path}</Box>*/}
2595
+ {/* ── RIGHT: search + filter + refresh + viewer actions ──────────── */}
2596
+ <Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', gap: 1, flexShrink: 0 }}>
2597
+ {(searchFieldsRef?.current?.length ?? []) > 0 &&
2598
+ (() => {
2599
+ const hasValue = (searchTerm || '').length > 0 || (selectedSearchObjects?.length ?? 0) > 0
2600
+ const expanded = isSearchExpanded || hasValue
2601
+ if (!expanded) {
2602
+ return (
2603
+ <Tooltip title='بحث' placement='top'>
2604
+ <IconButton
2605
+ size='small'
2606
+ onClick={e => {
2607
+ setIsSearchExpanded(true)
2608
+ setTimeout(() => searchInputRef.current?.focus(), 0)
2609
+ }}
2610
+ sx={{
2611
+ border: '1px solid',
2612
+ borderColor: 'divider',
2613
+ borderRadius: 1,
2614
+ color: 'text.secondary',
2615
+ '&:hover': { borderColor: 'primary.main', color: 'primary.main' }
2616
+ }}
2617
+ >
2618
+ <SearchOutlined fontSize='small' />
2619
+ </IconButton>
2620
+ </Tooltip>
2621
+ )
2622
+ }
2623
+ return (
2624
+ <Box sx={{ px: 0, minWidth: minimized ? 200 : 320, display: 'flex', alignItems: 'center' }}>
2625
+ {/*<Tooltip title={'اكتب كلمة البحث ثم اختر الحقل'}>*/}
2626
+ <Box sx={{ position: 'relative', width: '100%' }}>
2627
+ <TextField
2628
+ placeholder={'بحث...'}
2629
+ fullWidth
2630
+ size={'small'}
2631
+ value={searchTerm}
2632
+ inputRef={searchInputRef}
2633
+ // ── Stylized look matching design reference ────────────────
2634
+ // - Rounded ~12px border on a paper background.
2635
+ // - Soft divider colour at rest, primary on focus/hover.
2636
+ // - Search icon sits at the end of the input (endAdornment).
2637
+ // - No floating label — just a placeholder, so the field
2638
+ // doesn't shift vertically when it gains a value.
2639
+ sx={{
2640
+ '& .MuiOutlinedInput-root': {
2641
+ borderRadius: 3,
2642
+ bgcolor: 'background.paper',
2643
+ pr: 1.25
2644
+ },
2645
+ '& .MuiOutlinedInput-notchedOutline': {
2646
+ borderColor: 'divider'
2647
+ },
2648
+ '&:hover .MuiOutlinedInput-notchedOutline': {
2649
+ borderColor: 'text.disabled'
2650
+ },
2651
+ '& .Mui-focused .MuiOutlinedInput-notchedOutline': {
2652
+ borderWidth: 1
2653
+ }
2654
+ }}
2655
+ onFocus={e => {
2656
+ setIsSearchExpanded(true)
2657
+ if ((e.target.value || '').length > 0) {
2658
+ setSearchPopoverAnchor(e.currentTarget)
2659
+ setSearchPopoverOpen(true)
2660
+ // Reset to top of list whenever the popover opens.
2661
+ setHighlightedFieldIndex(0)
2662
+ }
2663
+ }}
2664
+ onBlur={() => {
2665
+ // Collapse back to the icon only when there's nothing to show.
2666
+ const hasValue = (searchTerm || '').length > 0 || (selectedSearchObjects?.length ?? 0) > 0
2667
+ if (!hasValue) setIsSearchExpanded(false)
2668
+ }}
2669
+ onChange={e => {
2670
+ const v = e.target.value
2671
+ setSearchTerm(v)
2672
+ setSearchPopoverAnchor(e.currentTarget)
2673
+ setSearchPopoverOpen((v || '').length > 0)
2674
+ // Term changed → list order semantically resets, so put
2675
+ // the highlight back at the top.
2676
+ setHighlightedFieldIndex(0)
2677
+ }}
2678
+ onKeyDown={e => {
2679
+ const fields = searchFieldsRef?.current ?? []
2680
+
2681
+ if (e.key === 'ArrowDown') {
2682
+ e.preventDefault()
2683
+ if (!searchPopoverOpen) {
2684
+ // Open the popover if the user starts arrowing
2685
+ // before typing — common pattern in autocompletes.
2686
+ setSearchPopoverAnchor(searchInputRef.current)
2687
+ setSearchPopoverOpen(true)
2688
+ setHighlightedFieldIndex(0)
2689
+ return
2690
+ }
2691
+ if (fields.length === 0) return
2692
+ const next = (highlightedFieldIndex + 1) % fields.length
2693
+ setHighlightedFieldIndex(next)
2694
+ // Keep the highlighted row visible inside the 240px-capped list.
2695
+ searchOptionRefs.current[next]?.scrollIntoView({ block: 'nearest' })
2696
+ return
2697
+ }
2698
+
2699
+ if (e.key === 'ArrowUp') {
2700
+ e.preventDefault()
2701
+ if (!searchPopoverOpen) return
2702
+ if (fields.length === 0) return
2703
+ const prev = (highlightedFieldIndex - 1 + fields.length) % fields.length
2704
+ setHighlightedFieldIndex(prev)
2705
+ searchOptionRefs.current[prev]?.scrollIntoView({ block: 'nearest' })
2706
+ return
2707
+ }
2708
+
2709
+ if (e.key === 'Home') {
2710
+ if (!searchPopoverOpen || fields.length === 0) return
2711
+ e.preventDefault()
2712
+ setHighlightedFieldIndex(0)
2713
+ searchOptionRefs.current[0]?.scrollIntoView({ block: 'nearest' })
2714
+ return
2715
+ }
2716
+
2717
+ if (e.key === 'End') {
2718
+ if (!searchPopoverOpen || fields.length === 0) return
2719
+ e.preventDefault()
2720
+ const last = fields.length - 1
2721
+ setHighlightedFieldIndex(last)
2722
+ searchOptionRefs.current[last]?.scrollIntoView({ block: 'nearest' })
2723
+ return
2724
+ }
2725
+
2726
+ if (e.key === 'Enter') {
2727
+ e.preventDefault()
2728
+ const term = (searchTerm || '').trim()
2729
+ if (!term) return
2730
+ if (fields.length === 0) return
2731
+ // Pick the highlighted field — defaults to the first
2732
+ // (highlightedFieldIndex starts at 0), so users who
2733
+ // never touched the arrow keys still get the same
2734
+ // behaviour as before.
2735
+ const idx = Math.min(Math.max(highlightedFieldIndex, 0), fields.length - 1)
2736
+ handlePickSearchField(fields[idx])
2737
+ return
2738
+ }
2739
+
2740
+ if (e.key === 'Escape') {
2741
+ setSearchPopoverOpen(false)
2742
+ }
2743
+ }}
2744
+ InputProps={{
2745
+ startAdornment: (
2746
+ <Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap' }}>
2747
+ {(() => {
2748
+ const byPath = selectedSearchObjects.reduce((acc, it) => {
2749
+ const key = it.path
2750
+ if (!acc[key]) acc[key] = { meta: it, values: [] }
2751
+ acc[key].values.push(String(it.value))
2752
+ return acc
2753
+ }, {})
2754
+ return Object.keys(byPath).map(path => {
2755
+ const g = byPath[path]
2756
+ const labelBase = g.meta.friendlyName || g.meta.path
2757
+ const valueLabel = g.values.reduce((acc, val, idx) => {
2758
+ if (idx > 0) acc.push(<strong key={`sep-${idx}`}> أو </strong>)
2759
+ acc.push(val)
2760
+ return acc
2761
+ }, [])
2762
+ return (
2763
+ <Chip
2764
+ key={`group-${path}`}
2765
+ size='small'
2766
+ label={
2767
+ <span>
2768
+ <strong>{labelBase}</strong>: {valueLabel}
2769
+ </span>
2770
+ }
2771
+ onDelete={() => {
2772
+ setSelectedSearchObjects(prev => prev.filter(it => it.path !== path))
2773
+ debouncedRefresh()
2774
+ }}
2775
+ deleteIcon={
2776
+ <Box
2777
+ sx={{
2778
+ display: 'flex',
2779
+ alignItems: 'center',
2780
+ px: 0.5,
2781
+ bgcolor: 'error.main',
2782
+ color: theme => theme.palette.error.contrastText,
2783
+ height: '100%',
2784
+ alignSelf: 'stretch',
2785
+ borderTopRightRadius: '4px',
2786
+ borderBottomRightRadius: '4px'
2787
+ }}
2788
+ >
2789
+ <Close fontSize='small' />
2790
+ </Box>
2791
+ }
2792
+ sx={{
2793
+ mr: 0.5,
2794
+ borderRadius: '8px',
2795
+ '& .MuiChip-deleteIcon': {
2796
+ margin: 0
2797
+ }
2798
+ }}
2799
+ />
2800
+ )
2801
+ })
2802
+ })()}
2479
2803
  </Box>
2480
- </ListItemButton>
2481
- ))}
2482
- {((searchFieldsRef?.current ?? []).length === 0) && (
2483
- <ListItemButton disabled>
2484
- <Box sx={{px: 1, py: 0.5, color: 'text.secondary'}}>لا توجد حقول للبحث</Box>
2485
- </ListItemButton>
2486
- )}
2487
- </List>
2488
- </Paper>
2489
- </Popper>
2490
- </ClickAwayListener>
2491
- </Box>
2492
- {/*</Tooltip>*/}
2493
- </Box>}
2494
- <Box sx={{display: 'flex', justifyContent: 'center'}}>
2495
- {<Box>
2496
- <Tooltip title={'جميع البيانات'}>
2497
- <Checkbox
2498
- checked={!isPagination}
2499
- onChange={e => setIsPagination(!e.target.checked)}
2500
- color="primary"
2501
- />
2502
- </Tooltip>
2503
- </Box>}
2504
- {streamEndPoint && !builderData?.isRaw === true && minimized !== true &&
2505
- <Box>
2506
- <Tooltip title='تصدير'>
2507
- <IconButton
2508
- disabled={isDownloading}
2509
- onClick={handleCSVExport}
2510
- color='primary'
2511
- >
2512
- {isDownloading ? <CircularProgress size={24}/> : <FileExcelOutline/>}
2513
- </IconButton>
2514
- </Tooltip>
2515
- </Box>
2516
- }
2517
- {minimized !== true && !isPagination &&
2518
- <Box>
2519
- <Tooltip title="تصدير PDF">
2520
- <IconButton onClick={handlePDFExport} color="primary">
2521
- <PrintOutlined/>
2522
- </IconButton>
2523
- </Tooltip>
2524
- </Box>
2525
- }
2526
- {
2527
- builderData?.id != null && minimized !== true && <>
2528
- <Box>
2529
- <Tooltip title='حفظ النموذج'>
2530
- <IconButton disabled={selectedTemplate == null} onClick={() => {
2531
- handleSaveTemplate()
2532
- }} color='primary'>
2533
- <Save/>
2534
- </IconButton>
2535
- </Tooltip>
2536
- </Box>
2537
- <Box>
2538
- <Tooltip title='حفظ بأسم'>
2539
- <IconButton onClick={() => {
2540
- setIsTemplateEditing(false)
2541
- handleToggleDialogs('addTemplate')
2542
- }} color='primary'>
2543
- <SaveAs/>
2544
- </IconButton>
2545
- </Tooltip>
2546
- </Box>
2547
-
2548
- <Box>
2549
- <Tooltip title='تعديل'>
2550
- <IconButton disabled={selectedTemplate == null}
2551
- onClick={() => {
2552
- setIsTemplateEditing(true)
2553
- handleToggleDialogs('addTemplate')
2554
- }}
2555
- color='primary'
2556
- >
2557
- <Edit/>
2558
- </IconButton>
2559
- </Tooltip>
2560
- </Box>
2561
- </>
2562
- }
2563
- {<Box>
2804
+ ),
2805
+ endAdornment: <SearchOutlined sx={{ color: 'text.disabled', fontSize: 20, mr: 0.25 }} />
2806
+ }}
2807
+ />
2564
2808
 
2565
- <IconButton color={'primary'} onClick={() => handleToggleDialogs('CustomFilter')}>
2566
- <FilterAlt/>
2567
- </IconButton>
2568
- </Box>
2569
- }
2570
- <Box>
2571
- <Tooltip title='اعادة تحميل'>
2572
- <IconButton onClick={() => setLocalRefresh(!localRefresh)}>
2573
- <RefreshOutlined/>
2809
+ <ClickAwayListener onClickAway={() => setSearchPopoverOpen(false)}>
2810
+ <Popper
2811
+ open={searchPopoverOpen}
2812
+ anchorEl={searchPopoverAnchor}
2813
+ placement='bottom-start'
2814
+ style={{ zIndex: 1300, width: searchInputRef?.current?.offsetWidth || undefined }}
2815
+ >
2816
+ <Paper elevation={3} sx={{ mt: 0.5, maxHeight: 240, overflowY: 'auto' }}>
2817
+ <List dense>
2818
+ {(searchFieldsRef?.current ?? []).map((option, i) => (
2819
+ <ListItemButton
2820
+ key={`${option.path}-${i}`}
2821
+ ref={el => { searchOptionRefs.current[i] = el }}
2822
+ selected={i === highlightedFieldIndex}
2823
+ onMouseEnter={() => setHighlightedFieldIndex(i)}
2824
+ // Mouse-down (rather than click) so the input
2825
+ // doesn't lose focus before the handler runs.
2826
+ onMouseDown={(e) => {
2827
+ e.preventDefault()
2828
+ handlePickSearchField(option)
2829
+ }}
2830
+ >
2831
+ <Box sx={{ display: 'flex', flexDirection: 'column' }}>
2832
+ <Box sx={{ fontSize: 14, fontWeight: 500 }}>{option.friendlyName || option.path}</Box>
2833
+ {/*<Box sx={{fontSize: 12, color: 'text.secondary'}}>{option.path}</Box>*/}
2834
+ </Box>
2835
+ </ListItemButton>
2836
+ ))}
2837
+ {(searchFieldsRef?.current ?? []).length === 0 && (
2838
+ <ListItemButton disabled>
2839
+ <Box sx={{ px: 1, py: 0.5, color: 'text.secondary' }}>لا توجد حقول للبحث</Box>
2840
+ </ListItemButton>
2841
+ )}
2842
+ </List>
2843
+ </Paper>
2844
+ </Popper>
2845
+ </ClickAwayListener>
2846
+ </Box>
2847
+ {/*</Tooltip>*/}
2848
+ </Box>
2849
+ )
2850
+ })()}
2851
+
2852
+ {/* PDF export — only visible when the user has chosen "Load all data"
2853
+ (otherwise the grid is paginated and PDF would only print the
2854
+ current page). Kept as a compact IconButton — the primary
2855
+ actions in this toolbar are Filter / Refresh / viewerActions. */}
2856
+ {minimized !== true && !isPagination && (
2857
+ <Tooltip title='تصدير PDF'>
2858
+ <IconButton onClick={handlePDFExport} color='primary' size='small'>
2859
+ <PrintOutlined fontSize='small' />
2574
2860
  </IconButton>
2575
2861
  </Tooltip>
2576
- </Box>
2577
-
2862
+ )}
2863
+ <Button
2864
+ size='medium'
2865
+ color='primary'
2866
+ variant='outlined'
2867
+ onClick={() => setLocalRefresh(!localRefresh)}
2868
+ // sx={{ border: '1px solid' }}
2869
+ >
2870
+ <RefreshOutlined fontSize='small' />
2871
+ </Button>
2872
+ <Button
2873
+ size='small'
2874
+ variant='outlined'
2875
+ color='primary'
2876
+ startIcon={<FilterAlt fontSize='small' />}
2877
+ onClick={() => handleToggleDialogs('CustomFilter')}
2878
+ >
2879
+ Filter
2880
+ </Button>
2881
+
2882
+ {/* Viewer actions — rendered after Filter/Refresh in declared order.
2883
+ Each item is already bound by ReportViewerRenderer:
2884
+ { key, label, icon, color, variant, onClick, disabled, confirmation }
2885
+ Icon is a string name resolved against @mui/icons-material. */}
2886
+ {Array.isArray(viewerActions) &&
2887
+ viewerActions.map(action => {
2888
+ const IconCmp = action.icon ? MuiIcons[action.icon] : null
2889
+ const variant = action.variant ?? 'outlined'
2890
+ const color = action.color ?? 'primary'
2891
+ return (
2892
+ <Button
2893
+ key={action.key}
2894
+ size='small'
2895
+ variant={variant}
2896
+ color={color}
2897
+ startIcon={IconCmp ? <IconCmp fontSize='small' /> : null}
2898
+ onClick={action.onClick}
2899
+ disabled={Boolean(action.disabled)}
2900
+ >
2901
+ {action.label}
2902
+ </Button>
2903
+ )
2904
+ })}
2578
2905
  </Box>
2579
2906
  </Grid>
2580
- <div style={{width: "100%", height: minimized === true ? "0px" : height ?? "70vh", direction: 'ltr'}}>
2581
- <AgGridReact
2582
-
2583
- debug={false}
2584
- columnHoverHighlight={true}
2585
- theme={agTheme}
2586
- enableRtl={true}
2587
- columnDefs={colDefs.current}
2588
- rowModelType={"serverSide"}
2589
- onGridReady={onGridReady}
2590
- maxConcurrentDatasourceRequests={0}
2591
- cacheBlockSize={100}
2592
- onRowSelected={onRowSelected}
2593
- // getChildCount={getChildCount}
2594
- sideBar={sideBarConfig}
2595
- context={{
2596
- tRouting,
2597
- builderId: builderData?.id,
2598
- updateRef: updateRef,
2599
- settings: builderModel?.settings
2600
- }} // pass routing, builder id, updateRef and settings
2601
- gridOptions={{
2602
- enableRangeSelection: true,
2603
- enableCharts: true,
2604
- getContextMenuItems: (params) => {
2605
- const rowUniqueId = builderModel?.settings?.rowUniqueId
2606
- const rowData = params.node?.data
2607
- const defaultItems = params.defaultItems || []
2608
-
2609
- if (!updateRef || !rowUniqueId || !rowData) {
2610
- return defaultItems
2611
- }
2612
-
2613
- const rowIdValue = getRowIdFromSettings(rowData, rowUniqueId)
2614
- const hasUpdate = updateRef.current && Array.isArray(updateRef.current) &&
2615
- updateRef.current.some(item => item.rowId === rowIdValue)
2907
+ <TemplateStateContext.Provider
2908
+ value={{
2909
+ templates,
2910
+ selectedTemplate,
2911
+ setSelectedTemplate,
2912
+ handleGetTemplates,
2913
+ handleSaveTemplate,
2914
+ handleToggleDialogs,
2915
+ setIsTemplateEditing,
2916
+ builderData,
2917
+ // ── Display settings (rendered in the side panel) ────────────────────
2918
+ timerValue,
2919
+ setTimerValue,
2920
+ isPagination,
2921
+ setIsPagination,
2922
+ handleCSVExport,
2923
+ isDownloading,
2924
+ // Hide the Excel button in the side panel for raw / minimized reports.
2925
+ isExcelExportAvailable: Boolean(streamEndPoint && !builderData?.isRaw === true && minimized !== true)
2926
+ }}
2927
+ >
2928
+ <Box
2929
+ sx={{
2930
+ width: '100%',
2931
+ height: minimized === true ? '0px' : height ?? '70vh',
2932
+ direction: 'ltr',
2933
+ // Top corners flush with the toolbar above. AG Grid's quartz theme
2934
+ // rounds .ag-root-wrapper by default; we force the two top corners
2935
+ // to 0 so the grid sits seamlessly under the toolbar regardless of
2936
+ // the toolbar's own bottom edge. Bottom corners keep their theme
2937
+ // radius so the grid still looks like a contained surface.
2938
+ '& .ag-root-wrapper': {
2939
+ borderTopLeftRadius: 0,
2940
+ borderTopRightRadius: 0
2941
+ }
2942
+ }}
2943
+ >
2944
+ <AgGridReact
2945
+ debug={false}
2946
+ columnHoverHighlight={true}
2947
+ theme={agTheme}
2948
+ enableRtl={true}
2949
+ columnDefs={colDefs.current}
2950
+ rowModelType={'serverSide'}
2951
+ onGridReady={onGridReady}
2952
+ maxConcurrentDatasourceRequests={0}
2953
+ cacheBlockSize={100}
2954
+ onRowSelected={onRowSelected}
2955
+ // getChildCount={getChildCount}
2956
+ sideBar={sideBarConfig}
2957
+ context={{
2958
+ tRouting,
2959
+ builderId: builderData?.id,
2960
+ updateRef: updateRef,
2961
+ settings: builderModel?.settings,
2962
+ // Node identity — available inside all column functions as params.context.nodeId / nodeName
2963
+ nodeId: nodeId ?? null,
2964
+ nodeName: nodeId ?? null, // alias for convenience
2965
+ // Shared registry — access any report's ref: params.context.reportRefs.current['nodeId']
2966
+ reportRefs: reportRefs ?? null,
2967
+ // Returns the latest viewer state snapshot — used by MultiSelectEditor to commit values
2968
+ getViewerContext: () => ({
2969
+ data: viewerData,
2970
+ setData: setData ?? (() => {}),
2971
+ dataRef: viewerDataRef,
2972
+ reportRefs: reportRefs ?? null
2973
+ })
2974
+ }} // pass routing, builder id, updateRef, node identity and reportRefs
2975
+ gridOptions={{
2976
+ enableRangeSelection: true,
2977
+ enableCharts: true,
2978
+ getContextMenuItems: params => {
2979
+ const rowUniqueId = builderModel?.settings?.rowUniqueId
2980
+ const rowData = params.node?.data
2981
+ const defaultItems = params.defaultItems || []
2982
+
2983
+ if (!updateRef || !rowUniqueId || !rowData) {
2984
+ return defaultItems
2985
+ }
2616
2986
 
2617
- const customItems = []
2987
+ const rowIdValue = getRowIdFromSettings(rowData, rowUniqueId)
2988
+ const hasUpdate =
2989
+ updateRef.current &&
2990
+ Array.isArray(updateRef.current) &&
2991
+ updateRef.current.some(item => item.rowId === rowIdValue)
2992
+
2993
+ const customItems = []
2994
+
2995
+ if (hasUpdate) {
2996
+ customItems.push({
2997
+ name: 'Remove Row from Update Ref',
2998
+ icon: '<span class="ag-icon ag-icon-cancel" unselectable="on" role="presentation"></span>',
2999
+ action: () => {
3000
+ removeUpdateRefByRowId(updateRef, rowData, rowUniqueId)
3001
+ params.api.refreshCells({ force: true })
3002
+ }
3003
+ })
3004
+ }
2618
3005
 
2619
- if (hasUpdate) {
2620
3006
  customItems.push({
2621
- name: 'Remove Row from Update Ref',
2622
- icon: '<span class="ag-icon ag-icon-cancel" unselectable="on" role="presentation"></span>',
3007
+ name: 'Clone Update Ref (Backup)',
3008
+ icon: '<span class="ag-icon ag-icon-copy" unselectable="on" role="presentation"></span>',
2623
3009
  action: () => {
2624
- removeUpdateRefByRowId(updateRef, rowData, rowUniqueId)
2625
- params.api.refreshCells({force: true})
2626
- }
3010
+ cloneUpdateRefToOriginal(updateRef, originalRefData)
3011
+ params.api.refreshCells({ force: true })
3012
+ },
3013
+ disabled: !updateRef.current || updateRef.current.length === 0
2627
3014
  })
2628
- }
2629
3015
 
2630
- customItems.push({
2631
- name: 'Clone Update Ref (Backup)',
2632
- icon: '<span class="ag-icon ag-icon-copy" unselectable="on" role="presentation"></span>',
2633
- action: () => {
2634
- cloneUpdateRefToOriginal(updateRef, originalRefData)
2635
- params.api.refreshCells({force: true})
2636
- },
2637
- disabled: !updateRef.current || updateRef.current.length === 0
2638
- })
3016
+ customItems.push({
3017
+ name: 'Restore Update Ref (from Backup)',
3018
+ icon: '<span class="ag-icon ag-icon-undo" unselectable="on" role="presentation"></span>',
3019
+ action: () => {
3020
+ restoreUpdateRefFromOriginal(updateRef, originalRefData)
3021
+ params.api.refreshCells({ force: true })
3022
+ },
3023
+ disabled: !originalRefData.current || originalRefData.current.length === 0
3024
+ })
2639
3025
 
2640
- customItems.push({
2641
- name: 'Restore Update Ref (from Backup)',
2642
- icon: '<span class="ag-icon ag-icon-undo" unselectable="on" role="presentation"></span>',
2643
- action: () => {
2644
- restoreUpdateRefFromOriginal(updateRef, originalRefData)
2645
- params.api.refreshCells({force: true})
2646
- },
2647
- disabled: !originalRefData.current || originalRefData.current.length === 0
2648
- })
3026
+ customItems.push({
3027
+ name: 'Normalize Update Ref (Merge Duplicates)',
3028
+ icon: '<span class="ag-icon ag-icon-columns" unselectable="on" role="presentation"></span>',
3029
+ action: () => {
3030
+ normalizeUpdateRef(updateRef)
3031
+ params.api.refreshCells({ force: true })
3032
+ },
3033
+ disabled: !updateRef.current || updateRef.current.length === 0
3034
+ })
2649
3035
 
2650
- customItems.push({
2651
- name: 'Normalize Update Ref (Merge Duplicates)',
2652
- icon: '<span class="ag-icon ag-icon-columns" unselectable="on" role="presentation"></span>',
2653
- action: () => {
2654
- normalizeUpdateRef(updateRef)
2655
- params.api.refreshCells({force: true})
2656
- },
2657
- disabled: !updateRef.current || updateRef.current.length === 0
2658
- })
3036
+ customItems.push({
3037
+ name: 'Clear All Update Ref',
3038
+ icon: '<span class="ag-icon ag-icon-cancel" unselectable="on" role="presentation"></span>',
3039
+ action: () => {
3040
+ if (updateRef.current && Array.isArray(updateRef.current)) {
3041
+ const count = updateRef.current.length
3042
+ clearAllUpdateRef(updateRef)
3043
+ params.api.refreshCells({ force: true })
3044
+ console.log(`Cleared ${count} rows from updateRef`)
3045
+ }
3046
+ },
3047
+ disabled: !updateRef.current || updateRef.current.length === 0
3048
+ })
2659
3049
 
2660
- customItems.push({
2661
- name: 'Clear All Update Ref',
2662
- icon: '<span class="ag-icon ag-icon-cancel" unselectable="on" role="presentation"></span>',
2663
- action: () => {
2664
- if (updateRef.current && Array.isArray(updateRef.current)) {
2665
- const count = updateRef.current.length
2666
- clearAllUpdateRef(updateRef)
2667
- params.api.refreshCells({force: true})
2668
- console.log(`Cleared ${count} rows from updateRef`)
2669
- }
2670
- },
2671
- disabled: !updateRef.current || updateRef.current.length === 0
2672
- })
3050
+ if (customItems.length > 0) {
3051
+ return [...customItems, 'separator', ...defaultItems]
3052
+ }
2673
3053
 
2674
- if (customItems.length > 0) {
2675
- return [
2676
- ...customItems,
2677
- 'separator',
2678
- ...defaultItems
2679
- ]
3054
+ return defaultItems
2680
3055
  }
3056
+ }}
3057
+ rowSelection='multiple'
3058
+ statusBar={{
3059
+ statusPanels: [
3060
+ // { statusPanel: 'agTotalRowCountComponent' },
3061
+ {
3062
+ statusPanel: CustomStatusBar,
3063
+ align: 'left'
3064
+ }
2681
3065
 
2682
- return defaultItems
2683
- }
2684
- }}
2685
- rowSelection="multiple"
2686
- statusBar={{
2687
- statusPanels: [
2688
- // { statusPanel: 'agTotalRowCountComponent' },
2689
- {
2690
- statusPanel: CustomStatusBar,
2691
- align: 'left',
2692
- },
2693
-
2694
- // { statusPanel: 'agFilteredRowCountComponent' },
2695
- // { statusPanel: 'agSelectedRowCountComponent' },
2696
- ],
2697
- }}
2698
- groupHeaderHeight={25}
2699
- // onChartCreated={x => console.log(x)}
2700
- headerHeight={25}
2701
- autoGroupColumnDef={autoGroupColumnDef}
2702
- getRowId={getRowId}
2703
- serverSideDatasource={datasource}
2704
- blockLoadDebounceMillis={200}
2705
- pinnedBottomRowData={pagedAgg}
2706
- suppressRowClickSelection={true}
2707
- serverSidePivotResultFieldSeparator={"_"}
2708
- pivotKeySeparator={"_"}
2709
- getRowStyle={(row) => {
2710
- if (row.node.group) {
2711
- return {fontWeight: 'bold'};
2712
- }
2713
- if (expireReport) {
2714
- if (row.node?.data?.expireDate && new Date(row.node.data.expireDate) <= new Date()) {
2715
- return {background: '#FF625F'};
3066
+ // { statusPanel: 'agFilteredRowCountComponent' },
3067
+ // { statusPanel: 'agSelectedRowCountComponent' },
3068
+ ]
3069
+ }}
3070
+ groupHeaderHeight={25}
3071
+ // onChartCreated={x => console.log(x)}
3072
+ headerHeight={25}
3073
+ autoGroupColumnDef={autoGroupColumnDef}
3074
+ getRowId={getRowId}
3075
+ serverSideDatasource={datasource}
3076
+ blockLoadDebounceMillis={200}
3077
+ pinnedBottomRowData={pagedAgg}
3078
+ suppressRowClickSelection={true}
3079
+ serverSidePivotResultFieldSeparator={'_'}
3080
+ pivotKeySeparator={'_'}
3081
+ getRowStyle={row => {
3082
+ if (row.node.group) {
3083
+ return { fontWeight: 'bold' }
2716
3084
  }
2717
- if (row.node?.data?.expireDate) {
2718
- const expireDate = new Date(row.node.data.expireDate);
2719
- const currentDate = new Date();
2720
- const diffInDays = (expireDate - currentDate) / (1000 * 60 * 60 * 24); // Convert milliseconds to days
2721
-
2722
- if (diffInDays > 10) {
2723
- return {background: '#8AFF8A'};
2724
- } else if (diffInDays > 0) {
2725
- return {background: '#fcfd74'};
3085
+ if (expireReport) {
3086
+ if (row.node?.data?.expireDate && new Date(row.node.data.expireDate) <= new Date()) {
3087
+ return { background: '#FF625F' }
3088
+ }
3089
+ if (row.node?.data?.expireDate) {
3090
+ const expireDate = new Date(row.node.data.expireDate)
3091
+ const currentDate = new Date()
3092
+ const diffInDays = (expireDate - currentDate) / (1000 * 60 * 60 * 24) // Convert milliseconds to days
3093
+
3094
+ if (diffInDays > 10) {
3095
+ return { background: '#8AFF8A' }
3096
+ } else if (diffInDays > 0) {
3097
+ return { background: '#fcfd74' }
3098
+ }
2726
3099
  }
2727
3100
  }
2728
- }
2729
- }}
2730
-
2731
- components={{
2732
- routingCell: RoutingCell,
2733
- imageCell: ImageCell,
2734
- customStatusBar: CustomStatusBar,
2735
- // agColumnsToolPanel: CustomColumnsToolPanel
2736
-
2737
- }}
2738
-
2739
-
2740
- onSortChanged={params => {
2741
- const sm = params.columns;
2742
- if (sm.length == 1 && sm.some(s => s.colId === 'IZ_groupCount')) {
2743
- params.api.refreshServerSide({purge: true})
2744
- }
2745
- }}
2746
- />
2747
- </div>
3101
+ }}
3102
+ components={{
3103
+ ...AG_COMPONENTS,
3104
+ routingCell: RoutingCell,
3105
+ imageCell: ImageCell,
3106
+ customStatusBar: CustomStatusBar,
3107
+ templatesToolPanel: TemplatesToolPanel
3108
+ }}
3109
+ onCellValueChanged={params => {
3110
+ // Guard: skip undefined phantom reverts produced by MultiSelectEditor's stopEditing(true) cancel path
3111
+ if (params.newValue === undefined && params.colDef?.cellEditor === 'MultiSelectEditor') {
3112
+ return
3113
+ }
3114
+ }}
3115
+ onSortChanged={params => {
3116
+ const sm = params.columns
3117
+ if (sm.length == 1 && sm.some(s => s.colId === 'IZ_groupCount')) {
3118
+ params.api.refreshServerSide({ purge: true })
3119
+ }
3120
+ }}
3121
+ />
3122
+ </Box>
3123
+ </TemplateStateContext.Provider>
2748
3124
  <Dialog
2749
3125
  fullWidth
2750
3126
  open={openDialogs?.addTemplate && builderData?.id != null}
@@ -2760,7 +3136,8 @@ const SGrid = props => {
2760
3136
  pageName={'Builder' + builderData?.id}
2761
3137
  item={isTemplateEditing === true ? selectedTemplate : null}
2762
3138
  template={gridApi?.getColumnState()}
2763
- userId={authValues?.user?.id}/>
3139
+ userId={authValues?.user?.id}
3140
+ />
2764
3141
  </Dialog>
2765
3142
  <Dialog
2766
3143
  fullWidth
@@ -2772,36 +3149,32 @@ const SGrid = props => {
2772
3149
  {openDialogs.CustomFilter && (
2773
3150
  <CustomFilterDialog
2774
3151
  handleToggleDialogs={handleToggleDialogs}
2775
- Filter={(Filter?.LocalTfilter || []).filter(f => (f.isMainFilter !== true))}
3152
+ Filter={(Filter?.LocalTfilter || []).filter(f => f.isMainFilter !== true)}
2776
3153
  customFilterCode={Filter?.customFilterCode}
2777
3154
  handleFilterChange={handleFilterChange}
2778
3155
  className={builderData?.reportSource?.fullName}
2779
3156
  LocalFilter={false}
2780
-
2781
- isViewer={router.pathname.includes('reportViewer')}
3157
+ isViewer={router.pathname.includes('report/viewer')}
2782
3158
  selectTFilter={selectTFilter}
2783
3159
  selectParamsMeta={builderData?.selectionParams || []}
2784
3160
  selectParamsValues={selectParams}
2785
- onSelectParamsSave={(list) => {
3161
+ onSelectParamsSave={list => {
2786
3162
  // list is array of { index, value, type }
2787
3163
  setSelectParams(prev => {
2788
- const arr = [...(prev || [])];
2789
- (list || []).forEach(item => {
2790
- const i = item.index;
2791
- const type = item.type;
2792
- const current = arr[i] || {id: i, PropertyType: type, value: null};
2793
- arr[i] = {...current, PropertyType: current.PropertyType || type, value: item.value};
2794
- });
2795
- return arr;
2796
- });
3164
+ const arr = [...(prev || [])]
3165
+ ;(list || []).forEach(item => {
3166
+ const i = item.index
3167
+ const type = item.type
3168
+ const current = arr[i] || { id: i, PropertyType: type, value: null }
3169
+ arr[i] = { ...current, PropertyType: current.PropertyType || type, value: item.value }
3170
+ })
3171
+ return arr
3172
+ })
2797
3173
  }}
2798
3174
  />
2799
3175
  )}
2800
3176
  </Dialog>
2801
-
2802
-
2803
3177
  </Grid>
2804
-
2805
3178
  )
2806
3179
  }
2807
3180