robobyte-front-builder 1.0.19 → 1.0.21

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 (513) hide show
  1. package/README.md +211 -0
  2. package/next.config.js +19 -48
  3. package/package.json +39 -85
  4. package/src/context/BuilderContext.jsx +134 -6
  5. package/src/context/SystemContext.js +2 -2
  6. package/src/hooks/useGlobalStore.js +36 -0
  7. package/src/hooks/useTimerEngine.js +54 -0
  8. package/src/lib/index.js +11 -3
  9. package/src/lib/layouts/BlankLayout.jsx +13 -0
  10. package/src/lib/providers/RoboByteFrontBuilderProvider.jsx +61 -7
  11. package/src/lib/themes/builderTheme.js +41 -0
  12. package/src/pages/_app.js +32 -134
  13. package/src/pages/api/ai.js +87 -0
  14. package/src/pages/builders/report/index.js +1 -0
  15. package/src/pages/builders/report/list/index.js +1 -0
  16. package/src/pages/builders/report/viewer/index.js +1 -0
  17. package/src/pages/index.js +88 -37
  18. package/src/pages/printBuilder/index.jsx +263 -0
  19. package/src/pages/printBuilder/layouts/index.jsx +298 -0
  20. package/src/pages/reportModule/reportBuilder/index.js +8 -6
  21. package/src/pages/reportModule/reportBuilder/reportViewer/index.js +33 -22
  22. package/src/pages/reportModule/reportBuilder/reports/index.js +3 -5
  23. package/src/pages/reportModule/reportBuilder/reportsPermissions/index.js +2 -3
  24. package/src/pages/viewBuilder/index.jsx +117 -32
  25. package/src/pages/viewBuilder/views/index.js +3 -3
  26. package/src/pages/viewer/[id]/index.js +2 -1
  27. package/src/services/DeleteService.js +31 -60
  28. package/src/services/Endpoints/PrintLayoutEndpoints.js +42 -0
  29. package/src/services/Endpoints.js +2 -0
  30. package/src/services/GetService.js +33 -54
  31. package/src/services/PatchService.js +38 -65
  32. package/src/services/PostService.js +37 -63
  33. package/src/services/UpdateService.js +39 -65
  34. package/src/services/builderHelper/actionExecutor.js +141 -25
  35. package/src/services/builderHelper/builderHelper.js +92 -0
  36. package/src/services/builderHelper/colorSchema.js +95 -0
  37. package/src/services/builderHelper/iconResolver.js +50 -0
  38. package/src/services/builderHelper/jsExecutor.js +212 -46
  39. package/src/services/builderHelper/nodeFactory.js +32 -15
  40. package/src/services/builderHelper/numberFormat.js +123 -0
  41. package/src/services/builderHelper/resolveProps.js +73 -4
  42. package/src/services/builderHelper/thresholdEngine.js +77 -0
  43. package/src/services/builderHelper/tree.js +31 -0
  44. package/src/services/components/agGridAutoComplete.js +5 -9
  45. package/src/services/config.js +9 -1
  46. package/src/services/globalStore.js +80 -0
  47. package/src/services/helper/multiSelectEditor.js +5 -9
  48. package/src/services/helper/multiSelectEditorByBuilder.js +5 -9
  49. package/src/services/reportData/fetchReportData.js +69 -28
  50. package/src/services/routerRef.js +35 -0
  51. package/src/views/ConfirmDialog.js +2 -2
  52. package/src/views/builder/JSEditor.js +105 -107
  53. package/src/views/builder/inspector/Inspector.jsx +6 -9
  54. package/src/views/builder/inspector/Tabs/ComponentActionsTab.jsx +7 -13
  55. package/src/views/builder/inspector/Tabs/MainTab.jsx +143 -25
  56. package/src/views/builder/inspector/Tabs/RulesTab.jsx +9 -24
  57. package/src/views/builder/inspector/Tabs/StyleTab.jsx +9 -24
  58. package/src/views/builder/inspector/definitions/autocomplete/main.js +4 -6
  59. package/src/views/builder/inspector/definitions/banner/actions.js +7 -0
  60. package/src/views/builder/inspector/definitions/banner/main.js +22 -0
  61. package/src/views/builder/inspector/definitions/banner/rules.js +1 -0
  62. package/src/views/builder/inspector/definitions/banner/style.js +1 -0
  63. package/src/views/builder/inspector/definitions/breadcrumb/main.js +43 -6
  64. package/src/views/builder/inspector/definitions/button/main.js +11 -12
  65. package/src/views/builder/inspector/definitions/button/style.js +18 -30
  66. package/src/views/builder/inspector/definitions/checkbox/actions.js +3 -1
  67. package/src/views/builder/inspector/definitions/checkbox/main.js +4 -6
  68. package/src/views/builder/inspector/definitions/common/main.js +13 -2
  69. package/src/views/builder/inspector/definitions/dataGrid/main.js +23 -0
  70. package/src/views/builder/inspector/definitions/dataTableViewer/main.js +46 -0
  71. package/src/views/builder/inspector/definitions/datepicker/actions.js +3 -1
  72. package/src/views/builder/inspector/definitions/datepicker/main.js +6 -14
  73. package/src/views/builder/inspector/definitions/dialog/main.js +36 -0
  74. package/src/views/builder/inspector/definitions/dropdown/main.js +5 -8
  75. package/src/views/builder/inspector/definitions/excelUpload/actions.js +23 -0
  76. package/src/views/builder/inspector/definitions/excelUpload/main.js +17 -0
  77. package/src/views/builder/inspector/definitions/excelUpload/rules.js +1 -0
  78. package/src/views/builder/inspector/definitions/excelUpload/style.js +45 -0
  79. package/src/views/builder/inspector/definitions/header/main.js +10 -1
  80. package/src/views/builder/inspector/definitions/index.js +106 -19
  81. package/src/views/builder/inspector/definitions/input/actions.js +4 -1
  82. package/src/views/builder/inspector/definitions/input/main.js +20 -11
  83. package/src/views/builder/inspector/definitions/kpi/avatarGroup.js +22 -0
  84. package/src/views/builder/inspector/definitions/kpi/badge.js +17 -0
  85. package/src/views/builder/inspector/definitions/kpi/bulletChart.js +47 -0
  86. package/src/views/builder/inspector/definitions/kpi/chart.js +55 -0
  87. package/src/views/builder/inspector/definitions/kpi/colorScale.js +60 -0
  88. package/src/views/builder/inspector/definitions/kpi/comparisonBars.js +41 -0
  89. package/src/views/builder/inspector/definitions/kpi/countdown.js +46 -0
  90. package/src/views/builder/inspector/definitions/kpi/donut.js +51 -0
  91. package/src/views/builder/inspector/definitions/kpi/funnel.js +25 -0
  92. package/src/views/builder/inspector/definitions/kpi/gauge.js +39 -0
  93. package/src/views/builder/inspector/definitions/kpi/heatmapGrid.js +96 -0
  94. package/src/views/builder/inspector/definitions/kpi/iconBox.js +20 -0
  95. package/src/views/builder/inspector/definitions/kpi/metric.js +45 -0
  96. package/src/views/builder/inspector/definitions/kpi/rating.js +27 -0
  97. package/src/views/builder/inspector/definitions/kpi/statusDot.js +18 -0
  98. package/src/views/builder/inspector/definitions/kpi/stepStage.js +65 -0
  99. package/src/views/builder/inspector/definitions/kpi/tagList.js +32 -0
  100. package/src/views/builder/inspector/definitions/kpi/timeline.js +80 -0
  101. package/src/views/builder/inspector/definitions/kpi/trend.js +20 -0
  102. package/src/views/builder/inspector/definitions/label/main.js +10 -1
  103. package/src/views/builder/inspector/definitions/layout/main.js +27 -3
  104. package/src/views/builder/inspector/definitions/number/main.js +6 -14
  105. package/src/views/builder/inspector/definitions/pageNumber/main.js +21 -0
  106. package/src/views/builder/inspector/definitions/popover/main.js +71 -0
  107. package/src/views/builder/inspector/definitions/radio/main.js +5 -8
  108. package/src/views/builder/inspector/definitions/repeater/main.js +31 -0
  109. package/src/views/builder/inspector/definitions/reportViewer/main.js +15 -1
  110. package/src/views/builder/inspector/definitions/richtext/main.js +5 -8
  111. package/src/views/builder/inspector/definitions/signature/main.js +4 -1
  112. package/src/views/builder/inspector/definitions/tag/main.js +5 -8
  113. package/src/views/builder/inspector/definitions/textarea/actions.js +4 -1
  114. package/src/views/builder/inspector/definitions/textarea/main.js +5 -7
  115. package/src/views/builder/inspector/definitions/time/main.js +5 -8
  116. package/src/views/builder/inspector/definitions/toggle/main.js +5 -19
  117. package/src/views/builder/inspector/definitions/treeView/main.js +61 -0
  118. package/src/views/builder/inspector/definitions/viewRenderer/main.js +53 -0
  119. package/src/views/builder/inspector/definitions/wizard/main.js +68 -0
  120. package/src/views/builder/inspector/definitions/wizard-step/main.js +25 -0
  121. package/src/views/builder/inspector/fields/ActionsConfigEditor.jsx +426 -0
  122. package/src/views/builder/inspector/fields/ColorSchemaField.jsx +140 -0
  123. package/src/views/builder/inspector/fields/ColumnFunctionEditor.jsx +238 -0
  124. package/src/views/builder/inspector/fields/ColumnMappingEditor.jsx +105 -0
  125. package/src/views/builder/inspector/fields/ColumnsConfigEditor.jsx +506 -0
  126. package/src/views/builder/inspector/fields/DonutRingsEditorField.jsx +337 -0
  127. package/src/views/builder/inspector/fields/ExtraColsEditor.jsx +618 -0
  128. package/src/views/builder/inspector/fields/FunctionHelpPopover.jsx +295 -0
  129. package/src/views/builder/inspector/fields/IconEditor.jsx +64 -0
  130. package/src/views/builder/inspector/fields/KpiActionField.jsx +223 -0
  131. package/src/views/builder/inspector/fields/MarkersEditorField.jsx +173 -0
  132. package/src/views/builder/inspector/fields/SelectEditor.jsx +9 -5
  133. package/src/views/builder/inspector/fields/SeriesEditorField.jsx +363 -0
  134. package/src/views/builder/inspector/fields/TableColumnsEditor.jsx +104 -0
  135. package/src/views/builder/inspector/fields/ThresholdsEditor.jsx +247 -0
  136. package/src/views/builder/inspector/fields/ValueFunctionsRefPanel.jsx +217 -0
  137. package/src/views/builder/inspector/fields/columnEditorShared.jsx +217 -0
  138. package/src/views/builder/sidebar/Sidebar.jsx +4 -2
  139. package/src/views/builder/sidebar/SidebarTabs.jsx +28 -17
  140. package/src/views/builder/sidebar/tabs/ActionsTab.jsx +7 -3
  141. package/src/views/builder/sidebar/tabs/AiTab/AiPreviewDialog.jsx +193 -0
  142. package/src/views/builder/sidebar/tabs/AiTab/aiProvider.js +49 -0
  143. package/src/views/builder/sidebar/tabs/AiTab/index.jsx +409 -0
  144. package/src/views/builder/sidebar/tabs/AiTab/schemaTransformer.js +102 -0
  145. package/src/views/builder/sidebar/tabs/AiTab/schemaValidator.js +64 -0
  146. package/src/views/builder/sidebar/tabs/AiTab/systemPrompt.js +1151 -0
  147. package/src/views/builder/sidebar/tabs/Components/ComponentsTab.jsx +31 -31
  148. package/src/views/builder/sidebar/tabs/Components/componentCatalog.js +43 -21
  149. package/src/views/builder/sidebar/tabs/Components/printComponentCatalog.js +81 -0
  150. package/src/views/builder/sidebar/tabs/TimersTab.jsx +338 -0
  151. package/src/views/builder/sidebar/tabs/TreeTab.jsx +13 -4
  152. package/src/views/builder/sidebar/tabs/ViewTab.jsx +1 -1
  153. package/src/views/builder/viewer/AdornedLabel.jsx +82 -0
  154. package/src/views/builder/viewer/ComponentRenderer.jsx +98 -24
  155. package/src/views/builder/viewer/DialogsZone.jsx +259 -0
  156. package/src/views/builder/viewer/FieldLabel.jsx +106 -0
  157. package/src/views/builder/viewer/PrintDialog.jsx +481 -0
  158. package/src/views/builder/viewer/ProductionViewer.jsx +80 -5
  159. package/src/views/builder/viewer/Viewer.jsx +106 -8
  160. package/src/views/builder/viewer/ViewerComponentWrapper.jsx +61 -4
  161. package/src/views/builder/viewer/ViewerToolbar.jsx +273 -59
  162. package/src/views/builder/viewer/renderers/AutoCompleteRenderer.jsx +26 -22
  163. package/src/views/builder/viewer/renderers/AvatarGroupRenderer.jsx +112 -0
  164. package/src/views/builder/viewer/renderers/BadgeRenderer.jsx +79 -0
  165. package/src/views/builder/viewer/renderers/BannerRenderer.jsx +62 -0
  166. package/src/views/builder/viewer/renderers/BreadcrumbRenderer.jsx +203 -15
  167. package/src/views/builder/viewer/renderers/BulletChartRenderer.jsx +147 -0
  168. package/src/views/builder/viewer/renderers/ButtonRenderer.jsx +98 -39
  169. package/src/views/builder/viewer/renderers/CardRenderer.jsx +1 -1
  170. package/src/views/builder/viewer/renderers/ChartRenderer.jsx +388 -0
  171. package/src/views/builder/viewer/renderers/CheckboxRenderer.jsx +17 -9
  172. package/src/views/builder/viewer/renderers/ColorScaleRenderer.jsx +300 -0
  173. package/src/views/builder/viewer/renderers/ComparisonBarsRenderer.jsx +133 -0
  174. package/src/views/builder/viewer/renderers/ContainerRenderer.jsx +3 -1
  175. package/src/views/builder/viewer/renderers/CountdownRenderer.jsx +249 -0
  176. package/src/views/builder/viewer/renderers/DataGridRenderer.jsx +380 -0
  177. package/src/views/builder/viewer/renderers/DataTableViewerRenderer.jsx +240 -0
  178. package/src/views/builder/viewer/renderers/DatePickerRenderer.jsx +25 -24
  179. package/src/views/builder/viewer/renderers/DialogRenderer.jsx +327 -0
  180. package/src/views/builder/viewer/renderers/DividerRenderer.jsx +1 -1
  181. package/src/views/builder/viewer/renderers/DonutRenderer.jsx +294 -0
  182. package/src/views/builder/viewer/renderers/DropdownRenderer.jsx +36 -44
  183. package/src/views/builder/viewer/renderers/ExcelUploadRenderer.jsx +639 -0
  184. package/src/views/builder/viewer/renderers/FunnelRenderer.jsx +93 -0
  185. package/src/views/builder/viewer/renderers/GaugeRenderer.jsx +159 -0
  186. package/src/views/builder/viewer/renderers/HeaderRenderer.jsx +31 -9
  187. package/src/views/builder/viewer/renderers/HeatmapGridRenderer.jsx +432 -0
  188. package/src/views/builder/viewer/renderers/IconBoxRenderer.jsx +59 -0
  189. package/src/views/builder/viewer/renderers/ImageRenderer.jsx +1 -1
  190. package/src/views/builder/viewer/renderers/InputRenderer.jsx +75 -18
  191. package/src/views/builder/viewer/renderers/LabelRenderer.jsx +35 -9
  192. package/src/views/builder/viewer/renderers/LayoutCellRenderer.jsx +102 -40
  193. package/src/views/builder/viewer/renderers/LayoutContextMenu.jsx +8 -8
  194. package/src/views/builder/viewer/renderers/LayoutRenderer.jsx +48 -6
  195. package/src/views/builder/viewer/renderers/LinkRenderer.jsx +1 -1
  196. package/src/views/builder/viewer/renderers/MenuRenderer.jsx +2 -2
  197. package/src/views/builder/viewer/renderers/MetricRenderer.jsx +80 -0
  198. package/src/views/builder/viewer/renderers/NumberFormatRenderer.jsx +21 -30
  199. package/src/views/builder/viewer/renderers/PageNumberRenderer.jsx +76 -0
  200. package/src/views/builder/viewer/renderers/PopoverRenderer.jsx +350 -0
  201. package/src/views/builder/viewer/renderers/ProgressCircleRenderer.jsx +1 -1
  202. package/src/views/builder/viewer/renderers/ProgressLineRenderer.jsx +1 -1
  203. package/src/views/builder/viewer/renderers/RadioGroupRenderer.jsx +28 -39
  204. package/src/views/builder/viewer/renderers/RatingRenderer.jsx +80 -0
  205. package/src/views/builder/viewer/renderers/RepeaterRenderer.jsx +297 -38
  206. package/src/views/builder/viewer/renderers/ReportViewerRenderer.jsx +219 -5
  207. package/src/views/builder/viewer/renderers/RichTextRenderer.jsx +60 -66
  208. package/src/views/builder/viewer/renderers/RowActionsCell.jsx +308 -0
  209. package/src/views/builder/viewer/renderers/SignatureRenderer.jsx +33 -62
  210. package/src/views/builder/viewer/renderers/StatusDotRenderer.jsx +75 -0
  211. package/src/views/builder/viewer/renderers/StepStageRenderer.jsx +348 -0
  212. package/src/views/builder/viewer/renderers/TagListRenderer.jsx +115 -0
  213. package/src/views/builder/viewer/renderers/TagPickerRenderer.jsx +31 -45
  214. package/src/views/builder/viewer/renderers/TextAreaRenderer.jsx +25 -18
  215. package/src/views/builder/viewer/renderers/TextRenderer.jsx +7 -1
  216. package/src/views/builder/viewer/renderers/TimePickerRenderer.jsx +25 -24
  217. package/src/views/builder/viewer/renderers/TimelineRenderer.jsx +525 -0
  218. package/src/views/builder/viewer/renderers/ToggleRenderer.jsx +21 -27
  219. package/src/views/builder/viewer/renderers/TreeViewRenderer.jsx +832 -0
  220. package/src/views/builder/viewer/renderers/TrendRenderer.jsx +66 -0
  221. package/src/views/builder/viewer/renderers/ViewRendererRenderer.jsx +315 -0
  222. package/src/views/builder/viewer/renderers/WizardRenderer.jsx +380 -64
  223. package/src/views/builder/viewer/renderers/WizardStepRenderer.jsx +21 -12
  224. package/src/views/builder/viewer/renderers/dataGridComponents.jsx +824 -0
  225. package/src/views/customFilter/CustomFilterDialog.js +1023 -660
  226. package/src/views/customFilter/FixedFilterDialog.js +649 -0
  227. package/src/views/customFilter/SearchFilterDialog.js +248 -0
  228. package/src/views/genericTable/BuilderExpressionParams.js +3 -3
  229. package/src/views/genericTable/ColumnConfiguratorDialog.js +33 -24
  230. package/src/views/genericTable/FixedFilterDialog.js +3 -2
  231. package/src/views/genericTable/FormattingSettingsDialog.js +8 -3
  232. package/src/views/genericTable/SGrid.js +198 -97
  233. package/src/views/genericTable/SearchFilterDialog.js +3 -2
  234. package/src/views/genericTable/cellEditors/autocompleteEditor.js +5 -9
  235. package/src/views/genericTable/convertStringFunctions.js +274 -138
  236. package/src/views/genericTable/statusBar/rowCountStatusBar.js +3 -1
  237. package/src/views/genericTable/updateRefHelpers.js +9 -6
  238. package/src/views/printBuilder/PrintBuilderViewer.jsx +607 -0
  239. package/src/views/printBuilder/PrintPreviewCanvas.jsx +157 -0
  240. package/src/views/rolePermissions/UpdateReportPermissionDialog.js +3 -2
  241. package/src/@core/components/auth/AclGuard.js +0 -55
  242. package/src/@core/components/auth/AuthGuard.js +0 -40
  243. package/src/@core/components/auth/GuestGuard.js +0 -30
  244. package/src/@core/components/custom-inputs/Horizontal.jsx +0 -143
  245. package/src/@core/components/custom-inputs/Image.jsx +0 -78
  246. package/src/@core/components/custom-inputs/Vertical.jsx +0 -113
  247. package/src/@core/components/customizer/index.jsx +0 -470
  248. package/src/@core/components/customizer/styles.module.css +0 -169
  249. package/src/@core/components/mui/Avatar.jsx +0 -41
  250. package/src/@core/components/mui/Badge.jsx +0 -20
  251. package/src/@core/components/mui/IconButton.jsx +0 -74
  252. package/src/@core/components/mui/TabList.jsx +0 -60
  253. package/src/@core/components/option-menu/index.jsx +0 -137
  254. package/src/@core/components/scroll-to-top/index.jsx +0 -43
  255. package/src/@core/components/spinner/index.js +0 -26
  256. package/src/@core/components/window-wrapper/index.js +0 -27
  257. package/src/@core/contexts/settingsContext.jsx +0 -98
  258. package/src/@core/hooks/useBgColor.js +0 -63
  259. package/src/@core/hooks/useImageVariant.js +0 -27
  260. package/src/@core/hooks/useLayoutInit.js +0 -37
  261. package/src/@core/hooks/useObjectCookie.js +0 -18
  262. package/src/@core/hooks/useSettings.jsx +0 -15
  263. package/src/@core/layouts/BlankLayout.js +0 -37
  264. package/src/@core/layouts/BlankLayoutWithAppBar.js +0 -51
  265. package/src/@core/layouts/HorizontalLayout.jsx +0 -151
  266. package/src/@core/layouts/Layout.js +0 -39
  267. package/src/@core/layouts/VerticalLayout.jsx +0 -124
  268. package/src/@core/layouts/components/blank-layout-with-appBar/index.js +0 -115
  269. package/src/@core/layouts/components/horizontal/app-bar-content/index.js +0 -67
  270. package/src/@core/layouts/components/horizontal/navigation/HorizontalNavGroup.js +0 -352
  271. package/src/@core/layouts/components/horizontal/navigation/HorizontalNavItems.js +0 -21
  272. package/src/@core/layouts/components/horizontal/navigation/HorizontalNavLink.js +0 -195
  273. package/src/@core/layouts/components/horizontal/navigation/index.js +0 -31
  274. package/src/@core/layouts/components/shared-components/LanguageDropdown.js +0 -96
  275. package/src/@core/layouts/components/shared-components/ModeToggler.js +0 -32
  276. package/src/@core/layouts/components/shared-components/NotificationDropdown.js +0 -226
  277. package/src/@core/layouts/components/shared-components/UserDropdown.js +0 -177
  278. package/src/@core/layouts/components/shared-components/footer/FooterContent.js +0 -46
  279. package/src/@core/layouts/components/shared-components/footer/index.js +0 -61
  280. package/src/@core/layouts/components/vertical/appBar/index.js +0 -74
  281. package/src/@core/layouts/components/vertical/navigation/Drawer.js +0 -122
  282. package/src/@core/layouts/components/vertical/navigation/VerticalNavGroup.js +0 -435
  283. package/src/@core/layouts/components/vertical/navigation/VerticalNavHeader.js +0 -180
  284. package/src/@core/layouts/components/vertical/navigation/VerticalNavItems.js +0 -26
  285. package/src/@core/layouts/components/vertical/navigation/VerticalNavLink.js +0 -258
  286. package/src/@core/layouts/components/vertical/navigation/VerticalNavSectionTitle.js +0 -102
  287. package/src/@core/layouts/components/vertical/navigation/index.js +0 -169
  288. package/src/@core/layouts/utils.js +0 -69
  289. package/src/@core/styles/Table.module.css +0 -93
  290. package/src/@core/styles/horizontal/menuItemStyles.js +0 -100
  291. package/src/@core/styles/horizontal/menuRootStyles.js +0 -19
  292. package/src/@core/styles/libs/fullcalendar/index.js +0 -461
  293. package/src/@core/styles/libs/keen-slider/index.js +0 -111
  294. package/src/@core/styles/libs/react-apexcharts/index.js +0 -107
  295. package/src/@core/styles/libs/react-cleave/index.js +0 -33
  296. package/src/@core/styles/libs/react-credit-cards/index.js +0 -11
  297. package/src/@core/styles/libs/react-datepicker/index.js +0 -388
  298. package/src/@core/styles/libs/react-draft-wysiwyg/index.js +0 -144
  299. package/src/@core/styles/libs/react-dropzone/index.js +0 -76
  300. package/src/@core/styles/libs/react-hot-toast/index.js +0 -37
  301. package/src/@core/styles/libs/recharts/index.js +0 -47
  302. package/src/@core/styles/stepper.js +0 -103
  303. package/src/@core/styles/vertical/menuItemStyles.js +0 -138
  304. package/src/@core/styles/vertical/menuSectionStyles.js +0 -54
  305. package/src/@core/styles/vertical/navigationCustomStyles.js +0 -62
  306. package/src/@core/svg/ContentCompact.jsx +0 -17
  307. package/src/@core/svg/ContentWide.jsx +0 -17
  308. package/src/@core/svg/DirectionLtr.jsx +0 -93
  309. package/src/@core/svg/DirectionRtl.jsx +0 -93
  310. package/src/@core/svg/LayoutCollapsed.jsx +0 -59
  311. package/src/@core/svg/LayoutHorizontal.jsx +0 -42
  312. package/src/@core/svg/LayoutVertical.jsx +0 -59
  313. package/src/@core/svg/Logo.jsx +0 -76
  314. package/src/@core/svg/SkinBordered.jsx +0 -54
  315. package/src/@core/svg/SkinDefault.jsx +0 -59
  316. package/src/@core/tailwind/plugin.js +0 -78
  317. package/src/@core/theme/ThemeComponent.js +0 -63
  318. package/src/@core/theme/ThemeOptions.js +0 -71
  319. package/src/@core/theme/breakpoints/index.js +0 -11
  320. package/src/@core/theme/colorSchemes.js +0 -326
  321. package/src/@core/theme/customShadows.js +0 -11
  322. package/src/@core/theme/globalStyles.js +0 -81
  323. package/src/@core/theme/index.js +0 -42
  324. package/src/@core/theme/overrides/accordion.js +0 -51
  325. package/src/@core/theme/overrides/accordion.jsx +0 -85
  326. package/src/@core/theme/overrides/alerts.js +0 -110
  327. package/src/@core/theme/overrides/alerts.jsx +0 -180
  328. package/src/@core/theme/overrides/autocomplete.js +0 -14
  329. package/src/@core/theme/overrides/autocomplete.jsx +0 -68
  330. package/src/@core/theme/overrides/avatar.js +0 -38
  331. package/src/@core/theme/overrides/avatars.js +0 -27
  332. package/src/@core/theme/overrides/backdrop.js +0 -22
  333. package/src/@core/theme/overrides/badges.js +0 -16
  334. package/src/@core/theme/overrides/breadcrumbs.js +0 -11
  335. package/src/@core/theme/overrides/button-group.js +0 -84
  336. package/src/@core/theme/overrides/button.js +0 -93
  337. package/src/@core/theme/overrides/buttonGroup.js +0 -9
  338. package/src/@core/theme/overrides/card.js +0 -83
  339. package/src/@core/theme/overrides/checkbox.jsx +0 -95
  340. package/src/@core/theme/overrides/chip.js +0 -72
  341. package/src/@core/theme/overrides/dataGrid.js +0 -114
  342. package/src/@core/theme/overrides/dateTimePicker.js +0 -65
  343. package/src/@core/theme/overrides/dialog.js +0 -120
  344. package/src/@core/theme/overrides/divider.js +0 -13
  345. package/src/@core/theme/overrides/drawer.js +0 -20
  346. package/src/@core/theme/overrides/fab.js +0 -13
  347. package/src/@core/theme/overrides/form-control-label.js +0 -19
  348. package/src/@core/theme/overrides/icon-button.js +0 -145
  349. package/src/@core/theme/overrides/index.js +0 -103
  350. package/src/@core/theme/overrides/input.js +0 -72
  351. package/src/@core/theme/overrides/link.js +0 -9
  352. package/src/@core/theme/overrides/list.js +0 -44
  353. package/src/@core/theme/overrides/menu.js +0 -25
  354. package/src/@core/theme/overrides/pagination.js +0 -41
  355. package/src/@core/theme/overrides/paper.js +0 -9
  356. package/src/@core/theme/overrides/popover.js +0 -16
  357. package/src/@core/theme/overrides/progress.js +0 -38
  358. package/src/@core/theme/overrides/radio.jsx +0 -80
  359. package/src/@core/theme/overrides/rating.js +0 -16
  360. package/src/@core/theme/overrides/rating.jsx +0 -32
  361. package/src/@core/theme/overrides/select.js +0 -19
  362. package/src/@core/theme/overrides/select.jsx +0 -52
  363. package/src/@core/theme/overrides/slider.js +0 -97
  364. package/src/@core/theme/overrides/snackbar.js +0 -19
  365. package/src/@core/theme/overrides/switch.js +0 -73
  366. package/src/@core/theme/overrides/switches.js +0 -25
  367. package/src/@core/theme/overrides/table-pagination.js +0 -39
  368. package/src/@core/theme/overrides/table.js +0 -81
  369. package/src/@core/theme/overrides/tabs.js +0 -30
  370. package/src/@core/theme/overrides/timeline.js +0 -80
  371. package/src/@core/theme/overrides/toggle-button.js +0 -33
  372. package/src/@core/theme/overrides/toggleButton.js +0 -16
  373. package/src/@core/theme/overrides/tooltip.js +0 -21
  374. package/src/@core/theme/overrides/typography.js +0 -13
  375. package/src/@core/theme/palette/index.js +0 -107
  376. package/src/@core/theme/shadows/index.js +0 -61
  377. package/src/@core/theme/shadows.js +0 -12
  378. package/src/@core/theme/spacing/index.js +0 -3
  379. package/src/@core/theme/spacing.js +0 -5
  380. package/src/@core/theme/typography/index.js +0 -65
  381. package/src/@core/theme/typography.js +0 -84
  382. package/src/@core/utils/create-emotion-cache.js +0 -5
  383. package/src/@core/utils/hex-to-rgba.js +0 -11
  384. package/src/@core/utils/serverHelpers.js +0 -45
  385. package/src/@menu/components/RouterLink.jsx +0 -18
  386. package/src/@menu/components/horizontal-menu/HorizontalNav.jsx +0 -88
  387. package/src/@menu/components/horizontal-menu/Menu.jsx +0 -83
  388. package/src/@menu/components/horizontal-menu/MenuButton.jsx +0 -100
  389. package/src/@menu/components/horizontal-menu/MenuItem.jsx +0 -183
  390. package/src/@menu/components/horizontal-menu/SubMenu.jsx +0 -418
  391. package/src/@menu/components/horizontal-menu/SubMenuContent.jsx +0 -41
  392. package/src/@menu/components/horizontal-menu/VerticalNavInHorizontal.jsx +0 -20
  393. package/src/@menu/components/vertical-menu/Menu.jsx +0 -161
  394. package/src/@menu/components/vertical-menu/MenuButton.jsx +0 -95
  395. package/src/@menu/components/vertical-menu/MenuItem.jsx +0 -180
  396. package/src/@menu/components/vertical-menu/MenuSection.jsx +0 -124
  397. package/src/@menu/components/vertical-menu/NavCollapseIcons.jsx +0 -70
  398. package/src/@menu/components/vertical-menu/NavHeader.jsx +0 -39
  399. package/src/@menu/components/vertical-menu/SubMenu.jsx +0 -420
  400. package/src/@menu/components/vertical-menu/SubMenuContent.jsx +0 -101
  401. package/src/@menu/components/vertical-menu/VerticalNav.jsx +0 -216
  402. package/src/@menu/contexts/horizontalNavContext.jsx +0 -29
  403. package/src/@menu/contexts/verticalNavContext.jsx +0 -65
  404. package/src/@menu/defaultConfigs.js +0 -12
  405. package/src/@menu/hooks/useHorizontalMenu.jsx +0 -19
  406. package/src/@menu/hooks/useHorizontalNav.jsx +0 -19
  407. package/src/@menu/hooks/useMediaQuery.jsx +0 -29
  408. package/src/@menu/hooks/useVerticalMenu.jsx +0 -19
  409. package/src/@menu/hooks/useVerticalNav.jsx +0 -19
  410. package/src/@menu/horizontal-menu/index.jsx +0 -8
  411. package/src/@menu/styles/StyledBackdrop.jsx +0 -15
  412. package/src/@menu/styles/StyledMenuIcon.jsx +0 -12
  413. package/src/@menu/styles/StyledMenuLabel.jsx +0 -16
  414. package/src/@menu/styles/StyledMenuPrefix.jsx +0 -10
  415. package/src/@menu/styles/StyledMenuSectionLabel.jsx +0 -21
  416. package/src/@menu/styles/StyledMenuSuffix.jsx +0 -10
  417. package/src/@menu/styles/StyledSubMenuContent.jsx +0 -43
  418. package/src/@menu/styles/horizontal/StyledHorizontalMenu.jsx +0 -13
  419. package/src/@menu/styles/horizontal/StyledHorizontalMenuItem.jsx +0 -26
  420. package/src/@menu/styles/horizontal/StyledHorizontalNav.jsx +0 -11
  421. package/src/@menu/styles/horizontal/StyledHorizontalNavExpandIcon.jsx +0 -33
  422. package/src/@menu/styles/horizontal/StyledHorizontalSubMenuContent.jsx +0 -18
  423. package/src/@menu/styles/horizontal/StyledHorizontalSubMenuContentWrapper.jsx +0 -10
  424. package/src/@menu/styles/horizontal/horizontalUl.module.css +0 -15
  425. package/src/@menu/styles/styles.module.css +0 -5
  426. package/src/@menu/styles/vertical/StyledVerticalMenu.jsx +0 -16
  427. package/src/@menu/styles/vertical/StyledVerticalMenuItem.jsx +0 -28
  428. package/src/@menu/styles/vertical/StyledVerticalMenuSection.jsx +0 -23
  429. package/src/@menu/styles/vertical/StyledVerticalNav.jsx +0 -67
  430. package/src/@menu/styles/vertical/StyledVerticalNavBgColorContainer.jsx +0 -15
  431. package/src/@menu/styles/vertical/StyledVerticalNavContainer.jsx +0 -23
  432. package/src/@menu/styles/vertical/StyledVerticalNavExpandIcon.jsx +0 -25
  433. package/src/@menu/styles/vertical/verticalNavBgImage.module.css +0 -10
  434. package/src/@menu/svg/ChevronRight.jsx +0 -9
  435. package/src/@menu/svg/Close.jsx +0 -12
  436. package/src/@menu/svg/RadioCircle.jsx +0 -12
  437. package/src/@menu/svg/RadioCircleMarked.jsx +0 -13
  438. package/src/@menu/utils/menuClasses.js +0 -44
  439. package/src/@menu/utils/menuUtils.jsx +0 -145
  440. package/src/@menu/vertical-menu/index.jsx +0 -11
  441. package/src/configs/acl.js +0 -115
  442. package/src/configs/auth.js +0 -5
  443. package/src/configs/aws-exports.js +0 -30
  444. package/src/configs/firebase.js +0 -25
  445. package/src/configs/i18n.js +0 -34
  446. package/src/configs/primaryColorConfig.js +0 -35
  447. package/src/configs/themeConfig.js +0 -44
  448. package/src/layouts/UserLayout.js +0 -94
  449. package/src/layouts/UserThemeOptions.js +0 -191
  450. package/src/layouts/components/Direction.js +0 -30
  451. package/src/layouts/components/HtmlTooltip.js +0 -15
  452. package/src/layouts/components/Translations.js +0 -11
  453. package/src/layouts/components/UserDropdown.js +0 -217
  454. package/src/layouts/components/UserIcon.js +0 -40
  455. package/src/layouts/components/acl/Can.js +0 -6
  456. package/src/layouts/components/acl/CanViewNavGroup.js +0 -36
  457. package/src/layouts/components/acl/CanViewNavLink.js +0 -17
  458. package/src/layouts/components/acl/CanViewNavSectionTitle.js +0 -17
  459. package/src/layouts/components/horizontal/AppBarContent.js +0 -39
  460. package/src/layouts/components/horizontal/ServerSideNavItems.js +0 -44
  461. package/src/layouts/components/mui/StepperComps.js +0 -55
  462. package/src/layouts/components/vertical/AppBarContent.js +0 -35
  463. package/src/layouts/components/vertical/ServerSideNavItems.js +0 -44
  464. package/src/libs/ApexCharts.jsx +0 -5
  465. package/src/libs/ReactPlayer.jsx +0 -5
  466. package/src/libs/Recharts.jsx +0 -4
  467. package/src/libs/auth.js +0 -124
  468. package/src/libs/styles/AppFullCalendar.js +0 -505
  469. package/src/libs/styles/AppKeenSlider.js +0 -116
  470. package/src/libs/styles/AppReactApexCharts.jsx +0 -110
  471. package/src/libs/styles/AppReactDatepicker.jsx +0 -470
  472. package/src/libs/styles/AppReactDropzone.js +0 -76
  473. package/src/libs/styles/AppReactToastify.jsx +0 -108
  474. package/src/libs/styles/AppRecharts.js +0 -55
  475. package/src/libs/styles/inputOtp.module.css +0 -39
  476. package/src/libs/styles/tiptapEditor.css +0 -72
  477. package/src/navigation/horizontal/index.js +0 -246
  478. package/src/navigation/vertical/index.js +0 -253
  479. package/src/pages/401.js +0 -70
  480. package/src/pages/404.js +0 -67
  481. package/src/pages/500.js +0 -68
  482. package/src/pages/[slug].js +0 -115
  483. package/src/pages/_document.js +0 -72
  484. package/src/pages/api/navigation/regenerate-registry.js +0 -116
  485. package/src/pages/api/navigation/save.js +0 -218
  486. package/src/pages/authModule/acl/index.js +0 -48
  487. package/src/pages/authModule/forgot-password/index.js +0 -228
  488. package/src/pages/authModule/permissions/rolePermissions/[id]/rolePermissionsUser/index.js +0 -392
  489. package/src/pages/authModule/permissions/rolePermissions/index.js +0 -343
  490. package/src/pages/authModule/permissions/systemPermissions/index.js +0 -354
  491. package/src/pages/authModule/privacy/index.js +0 -721
  492. package/src/pages/authModule/users/index.js +0 -210
  493. package/src/pages/login/index.js +0 -328
  494. package/src/pages/mainHome/index.js +0 -181
  495. package/src/views/builder/inspector/definitions/cell/main.js +0 -4
  496. package/src/views/builder/inspector/definitions/column/main.js +0 -9
  497. package/src/views/builder/inspector/definitions/column-group/main.js +0 -18
  498. package/src/views/builder/inspector/definitions/header-cell/main.js +0 -5
  499. package/src/views/builder/inspector/definitions/table/main.js +0 -9
  500. package/src/views/builder/viewer/renderers/CellRenderer.jsx +0 -71
  501. package/src/views/builder/viewer/renderers/ColumnGroupRenderer.jsx +0 -96
  502. package/src/views/builder/viewer/renderers/ColumnRenderer.jsx +0 -71
  503. package/src/views/builder/viewer/renderers/HeaderCellRenderer.jsx +0 -78
  504. package/src/views/builder/viewer/renderers/TabRenderer.jsx +0 -82
  505. package/src/views/builder/viewer/renderers/TableRenderer.jsx +0 -92
  506. package/src/views/pages/auth/FooterIllustrationsV2.js +0 -40
  507. package/src/views/pages/misc/FooterIllustrations.js +0 -47
  508. package/src/views/pages/misc/muiTable/CustomPagination.js +0 -34
  509. package/src/views/pages/users/UserManageDialog.js +0 -283
  510. package/src/views/pages/users/UserViewPage.js +0 -199
  511. package/src/views/users/AddUserNameDialog.js +0 -162
  512. package/src/views/users/ContactManage.js +0 -449
  513. package/src/views/users/ResetPasswordDialog.js +0 -242
@@ -0,0 +1,824 @@
1
+ /**
2
+ * Custom AG Grid cell renderers and editors for DataGridRenderer.
3
+ *
4
+ * Register via the `components` prop on <AgGridReact>.
5
+ * Reference by string name in colDef: cellRenderer: 'ChipRenderer', etc.
6
+ *
7
+ * ── Cell Renderers ────────────────────────────────────────────────────────────
8
+ * All renderers accept either a single value or an array of strings/values.
9
+ * valueFormatter controls what arrives — if it returns a string or array of
10
+ * strings the renderer will handle both transparently.
11
+ * - Multi-item renderers (ChipRenderer, LinkRenderer, IconRenderer) render one
12
+ * component per array element.
13
+ * - Scalar renderers (BooleanRenderer, CurrencyRenderer, DateRenderer,
14
+ * ProgressRenderer, AvatarRenderer) use the first array element.
15
+ *
16
+ * ChipRenderer — MUI Chip with color mapping per value
17
+ * BooleanRenderer — check / cross icon for truthy/falsy values
18
+ * LinkRenderer — clickable anchor; href from params or value
19
+ * CurrencyRenderer — formatted number with prefix/suffix/decimals
20
+ * DateRenderer — formatted date string
21
+ * ProgressRenderer — LinearProgress bar (value 0-100 or custom max)
22
+ * AvatarRenderer — circular image or initials avatar
23
+ * IconRenderer — MUI icon by name stored in the cell value
24
+ *
25
+ * ── Cell Editors ─────────────────────────────────────────────────────────────
26
+ * SelectEditor — MUI Select with options list
27
+ * AutocompleteEditor — MUI Autocomplete (searchable Select)
28
+ * CheckboxEditor — boolean MUI Checkbox
29
+ * DateEditor — native <input type="date">
30
+ * NumberEditor — numeric input with min / max / step
31
+ *
32
+ * ── cellRendererParams reference ─────────────────────────────────────────────
33
+ * ChipRenderer: { colorMap: { Active:'success', Closed:'error' }, defaultColor:'default', size:'small'|'medium', variant:'filled'|'outlined' }
34
+ * BooleanRenderer: { trueColor:'success.main', falseColor:'error.main', trueIcon:'CheckCircle', falseIcon:'Cancel' }
35
+ * LinkRenderer: { href: 'https://...', hrefField:'url', target:'_blank', label:'Open' }
36
+ * CurrencyRenderer: { prefix:'$', suffix:'', decimals:2, locale:'en-US' }
37
+ * DateRenderer: { format:'short'|'medium'|'long'|'iso' | Intl options object, locale:'en-US' }
38
+ * ProgressRenderer: { max:100, color:'primary'|'secondary'|'success'|'error'|'warning'|'info', showLabel:true }
39
+ * AvatarRenderer: { srcField:'avatarUrl', size:32, shape:'circle'|'square' }
40
+ * IconRenderer: { size:'small'|'medium'|'large', color:'inherit'|'primary'|'error'|... }
41
+ *
42
+ * ── cellEditorParams reference ────────────────────────────────────────────────
43
+ * SelectEditor: { options: ['A','B'] | [{ value, label }], placeholder:'Select...' }
44
+ * AutocompleteEditor: { options: ['A','B'] | [{ value, label }], placeholder:'Search...' }
45
+ * CheckboxEditor: { color:'primary'|'secondary'|'success'|'error' }
46
+ * DateEditor: { min:'2020-01-01', max:'2099-12-31' }
47
+ * NumberEditor: { min:0, max:100, step:1, decimals:2 }
48
+ * MultiSelectEditor: Static options via settings; overridable with async code.
49
+ * options — static array: string[] | object[] (configured in column settings)
50
+ * asyncFetchOptions — async (searchTerm?) => object[] (code override, takes precedence)
51
+ * isSingle — boolean, default false (multi-select)
52
+ * fieldName — string | string[] property path(s) to use as label (default 'name')
53
+ * groupByField — string property path to group options by
54
+ * targetValue — string | string[] property path(s) to extract as final getValue() result
55
+ */
56
+
57
+ import { forwardRef, useImperativeHandle, useRef, useState, useEffect } from 'react'
58
+ import {
59
+ Chip, Box, LinearProgress, Typography, Avatar,
60
+ Checkbox, Select, MenuItem, TextField, Autocomplete,
61
+ } from '@mui/material'
62
+ import {
63
+ CheckCircleOutlined, CancelOutlined, OpenInNew,
64
+ } from '@mui/icons-material'
65
+ import { resolveIcon } from 'services/builderHelper/iconResolver'
66
+
67
+ // ─────────────────────────────────────────────────────────────────────────────
68
+ // Helpers
69
+ // ─────────────────────────────────────────────────────────────────────────────
70
+
71
+ const MUI_COLOR_MAP = {
72
+ success: 'success', error: 'error', warning: 'warning',
73
+ info: 'info', primary: 'primary', secondary: 'secondary', default: 'default',
74
+ }
75
+
76
+ function normaliseMuiColor(c) { return MUI_COLOR_MAP[c] ?? 'default' }
77
+
78
+ /**
79
+ * Normalise a cell value to a non-empty array of primitives.
80
+ * Handles: undefined, null, '', single value, array.
81
+ * Objects are skipped — use valueFormatter to extract the display string first.
82
+ */
83
+ function toArray(value) {
84
+ if (value === null || value === undefined || value === '') return []
85
+ const arr = Array.isArray(value) ? value : [value]
86
+ return arr.filter(v => v !== null && v !== undefined && v !== '' && typeof v !== 'object')
87
+ }
88
+
89
+ /**
90
+ * Resolve the display value for a renderer.
91
+ * AG Grid passes the RAW value as `value` and the valueFormatter result as `valueFormatted`.
92
+ * Prefer `valueFormatted` so formatters that return arrays of strings are honoured.
93
+ */
94
+ function resolveDisplay(value, valueFormatted) {
95
+ // If formatter returned something useful (string or array), use it
96
+ if (valueFormatted !== null && valueFormatted !== undefined && valueFormatted !== '') {
97
+ return valueFormatted
98
+ }
99
+ return value
100
+ }
101
+
102
+ // ─────────────────────────────────────────────────────────────────────────────
103
+ // ── Cell Renderers ────────────────────────────────────────────────────────────
104
+ // ─────────────────────────────────────────────────────────────────────────────
105
+
106
+ /**
107
+ * ChipRenderer
108
+ * Renders a MUI Chip whose color is looked up from `colorMap[value]`.
109
+ * colorMap values should be MUI palette keys: success | error | warning | info | primary | secondary | default
110
+ */
111
+ export function ChipRenderer({ value, valueFormatted, colDef }) {
112
+ const p = colDef?.cellRendererParams ?? {}
113
+ const items = toArray(resolveDisplay(value, valueFormatted))
114
+ if (!items.length) return null
115
+ return (
116
+ <Box sx={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 0.5, height: '100%' }}>
117
+ {items.map((item, i) => (
118
+ <Chip
119
+ key={i}
120
+ label={String(item)}
121
+ color={normaliseMuiColor(p.colorMap?.[item] ?? p.defaultColor)}
122
+ size={p.size ?? 'small'}
123
+ variant={p.variant ?? 'filled'}
124
+ />
125
+ ))}
126
+ </Box>
127
+ )
128
+ }
129
+
130
+ /**
131
+ * BooleanRenderer
132
+ * Shows a check or cross icon for truthy/falsy values.
133
+ */
134
+ export function BooleanRenderer({ value, valueFormatted, colDef }) {
135
+ const p = colDef?.cellRendererParams ?? {}
136
+ const display = resolveDisplay(value, valueFormatted)
137
+ // For arrays use the first element; an array itself is truthy so unwrap first
138
+ const scalar = Array.isArray(display) ? display[0] : display
139
+ const isTrue = Boolean(scalar)
140
+ const TrueIcon = resolveIcon(p.trueIcon ?? 'CheckCircleOutlined') ?? CheckCircleOutlined
141
+ const FalseIcon = resolveIcon(p.falseIcon ?? 'CancelOutlined') ?? CancelOutlined
142
+ const Icon = isTrue ? TrueIcon : FalseIcon
143
+ const color = isTrue ? (p.trueColor ?? 'success.main') : (p.falseColor ?? 'error.main')
144
+ return (
145
+ <Box sx={{ display: 'flex', alignItems: 'center', height: '100%' }}>
146
+ <Icon sx={{ fontSize: 18, color }} />
147
+ </Box>
148
+ )
149
+ }
150
+
151
+ /**
152
+ * LinkRenderer
153
+ * Renders the cell value as a hyperlink.
154
+ * href is resolved from: colDef.cellRendererParams.href (static)
155
+ * OR colDef.cellRendererParams.hrefField (row field name)
156
+ * OR the cell value itself (if it looks like a URL).
157
+ */
158
+ export function LinkRenderer({ value, valueFormatted, data, colDef }) {
159
+ const p = colDef?.cellRendererParams ?? {}
160
+ const display = resolveDisplay(value, valueFormatted)
161
+ // Static href / hrefField always renders a single link regardless of value type
162
+ const staticHref = p.href ?? (p.hrefField ? data?.[p.hrefField] : null)
163
+ const items = staticHref ? [{ href: staticHref, label: p.label ?? (Array.isArray(display) ? display.join(', ') : display) }]
164
+ : toArray(display).map(v => ({ href: String(v), label: p.label ?? v }))
165
+ if (!items.length) return null
166
+ return (
167
+ <Box sx={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 0.5, height: '100%' }}>
168
+ {items.map((item, i) => (
169
+ <a
170
+ key={i}
171
+ href={String(item.href)}
172
+ target={p.target ?? '_blank'}
173
+ rel='noreferrer'
174
+ style={{ display: 'inline-flex', alignItems: 'center', gap: 4, color: 'inherit', textDecoration: 'underline' }}
175
+ onClick={e => e.stopPropagation()}
176
+ >
177
+ {item.label}
178
+ {(p.target ?? '_blank') === '_blank' && <OpenInNew sx={{ fontSize: 12 }} />}
179
+ </a>
180
+ ))}
181
+ </Box>
182
+ )
183
+ }
184
+
185
+ /**
186
+ * CurrencyRenderer
187
+ * Formats the value as a number with a prefix, suffix, and decimal places.
188
+ */
189
+ export function CurrencyRenderer({ value, valueFormatted, colDef }) {
190
+ const p = colDef?.cellRendererParams ?? {}
191
+ const display = resolveDisplay(value, valueFormatted)
192
+ // Use first element if array
193
+ const scalar = Array.isArray(display) ? display[0] : display
194
+ if (scalar === null || scalar === undefined || scalar === '') return null
195
+ const num = Number(scalar)
196
+ if (isNaN(num)) return <span>{String(scalar)}</span>
197
+ const decimals = p.decimals ?? 2
198
+ const formatted = num.toLocaleString(p.locale ?? 'en-US', {
199
+ minimumFractionDigits: decimals,
200
+ maximumFractionDigits: decimals,
201
+ })
202
+ return (
203
+ <Box sx={{ display: 'flex', alignItems: 'center', height: '100%', justifyContent: 'flex-end' }}>
204
+ <span>{(p.prefix ?? '') + formatted + (p.suffix ?? '')}</span>
205
+ </Box>
206
+ )
207
+ }
208
+
209
+ /**
210
+ * DateRenderer
211
+ * Formats the value as a localised date string.
212
+ * format: 'short' | 'medium' | 'long' | 'iso' | Intl.DateTimeFormat options object
213
+ */
214
+ export function DateRenderer({ value, valueFormatted, colDef }) {
215
+ const p = colDef?.cellRendererParams ?? {}
216
+ const display = resolveDisplay(value, valueFormatted)
217
+ // Use first element if array
218
+ const scalar = Array.isArray(display) ? display[0] : display
219
+ if (!scalar) return null
220
+ try {
221
+ const date = new Date(scalar)
222
+ if (isNaN(date.getTime())) return <span>{String(scalar)}</span>
223
+
224
+ let display
225
+ const fmt = p.format ?? 'short'
226
+ if (fmt === 'iso') {
227
+ display = date.toISOString().slice(0, 10)
228
+ } else {
229
+ const presets = {
230
+ short: { year: 'numeric', month: 'short', day: '2-digit' },
231
+ medium: { year: 'numeric', month: 'long', day: '2-digit' },
232
+ long: { year: 'numeric', month: 'long', day: '2-digit', weekday: 'long' },
233
+ }
234
+ const opts = (typeof fmt === 'object' && fmt !== null) ? fmt : (presets[fmt] ?? presets.short)
235
+ display = date.toLocaleDateString(p.locale ?? undefined, opts)
236
+ }
237
+ return (
238
+ <Box sx={{ display: 'flex', alignItems: 'center', height: '100%' }}>
239
+ <span>{display}</span>
240
+ </Box>
241
+ )
242
+ } catch {
243
+ return <span>{String(scalar)}</span>
244
+ }
245
+ }
246
+
247
+ /**
248
+ * ProgressRenderer
249
+ * Renders value as a LinearProgress bar (0–max, default max=100).
250
+ */
251
+ export function ProgressRenderer({ value, valueFormatted, colDef }) {
252
+ const p = colDef?.cellRendererParams ?? {}
253
+ const max = p.max ?? 100
254
+ const display = resolveDisplay(value, valueFormatted)
255
+ // Use first element if array
256
+ const scalar = Array.isArray(display) ? display[0] : display
257
+ const num = Math.min(Math.max(Number(scalar) || 0, 0), max)
258
+ const pct = (num / max) * 100
259
+ const color = p.color ?? 'primary'
260
+ return (
261
+ <Box sx={{ display: 'flex', alignItems: 'center', height: '100%', gap: 1, width: '100%', pr: 1 }}>
262
+ <LinearProgress
263
+ variant='determinate'
264
+ value={pct}
265
+ color={color}
266
+ sx={{ flexGrow: 1, borderRadius: 1, height: 6 }}
267
+ />
268
+ {p.showLabel !== false && (
269
+ <Typography variant='caption' sx={{ whiteSpace: 'nowrap', minWidth: 32, textAlign: 'right' }}>
270
+ {num}{p.unit ?? ''}
271
+ </Typography>
272
+ )}
273
+ </Box>
274
+ )
275
+ }
276
+
277
+ /**
278
+ * AvatarRenderer
279
+ * Renders an Avatar: image from `srcField` row property, or initials from value.
280
+ */
281
+ export function AvatarRenderer({ value, valueFormatted, data, colDef }) {
282
+ const p = colDef?.cellRendererParams ?? {}
283
+ const src = p.srcField ? data?.[p.srcField] : null
284
+ const size = p.size ?? 28
285
+ const display = resolveDisplay(value, valueFormatted)
286
+ // Use first element if array
287
+ const scalar = Array.isArray(display) ? display[0] : display
288
+ const initials = scalar
289
+ ? String(scalar).split(' ').slice(0, 2).map(w => w[0]).join('').toUpperCase()
290
+ : '?'
291
+ return (
292
+ <Box sx={{ display: 'flex', alignItems: 'center', height: '100%', gap: 1 }}>
293
+ <Avatar
294
+ src={src ?? undefined}
295
+ sx={{
296
+ width: size, height: size, fontSize: size * 0.4,
297
+ borderRadius: p.shape === 'square' ? 1 : '50%',
298
+ }}
299
+ >
300
+ {!src && initials}
301
+ </Avatar>
302
+ {scalar && <span>{String(scalar)}</span>}
303
+ </Box>
304
+ )
305
+ }
306
+
307
+ /**
308
+ * IconRenderer
309
+ * Renders an MUI icon whose name is the cell value.
310
+ * e.g. value = 'CheckCircle' renders the CheckCircle icon.
311
+ */
312
+ export function IconRenderer({ value, valueFormatted, colDef }) {
313
+ const p = colDef?.cellRendererParams ?? {}
314
+ const items = toArray(resolveDisplay(value, valueFormatted))
315
+ if (!items.length) return null
316
+ return (
317
+ <Box sx={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 0.5, height: '100%' }}>
318
+ {items.map((item, i) => {
319
+ const Icon = resolveIcon(String(item))
320
+ return Icon
321
+ ? <Icon key={i} fontSize={p.size ?? 'small'} color={p.color ?? 'inherit'} />
322
+ : <span key={i}>{String(item)}</span>
323
+ })}
324
+ </Box>
325
+ )
326
+ }
327
+
328
+ // ─────────────────────────────────────────────────────────────────────────────
329
+ // ── Cell Editors ─────────────────────────────────────────────────────────────
330
+ // ─────────────────────────────────────────────────────────────────────────────
331
+
332
+ /**
333
+ * SelectEditor
334
+ * A MUI Select populated from cellEditorParams.options.
335
+ * options: string[] | { value, label }[]
336
+ */
337
+ export const SelectEditor = forwardRef(function SelectEditor(props, ref) {
338
+ const p = props.colDef?.cellEditorParams ?? {}
339
+ const rawOptions = p.options ?? []
340
+ const options = rawOptions.map(o =>
341
+ typeof o === 'object' && o !== null ? o : { value: o, label: String(o) }
342
+ )
343
+
344
+ const [value, setValue] = useState(props.value ?? '')
345
+
346
+ useImperativeHandle(ref, () => ({
347
+ getValue() { return value },
348
+ isCancelBeforeStart() { return false },
349
+ }))
350
+
351
+ return (
352
+ <Select
353
+ value={value}
354
+ onChange={e => setValue(e.target.value)}
355
+ size='small'
356
+ autoFocus
357
+ open
358
+ displayEmpty
359
+ sx={{ width: '100%', height: '100%', '& .MuiSelect-select': { py: 0.5 } }}
360
+ >
361
+ {p.placeholder && <MenuItem value=''><em>{p.placeholder}</em></MenuItem>}
362
+ {options.map(o => (
363
+ <MenuItem key={o.value} value={o.value}>{o.label}</MenuItem>
364
+ ))}
365
+ </Select>
366
+ )
367
+ })
368
+
369
+ /**
370
+ * AutocompleteEditor
371
+ * A MUI Autocomplete (searchable) populated from cellEditorParams.options.
372
+ */
373
+ export const AutocompleteEditor = forwardRef(function AutocompleteEditor(props, ref) {
374
+ const p = props.colDef?.cellEditorParams ?? {}
375
+ const rawOptions = p.options ?? []
376
+ const options = rawOptions.map(o =>
377
+ typeof o === 'object' && o !== null ? o : { value: o, label: String(o) }
378
+ )
379
+
380
+ const initialOpt = options.find(o => o.value === props.value) ?? { value: props.value ?? '', label: String(props.value ?? '') }
381
+ const [selected, setSelected] = useState(initialOpt)
382
+ const inputRef = useRef(null)
383
+
384
+ useEffect(() => { setTimeout(() => inputRef.current?.focus(), 0) }, [])
385
+
386
+ useImperativeHandle(ref, () => ({
387
+ getValue() { return selected?.value ?? '' },
388
+ isCancelBeforeStart() { return false },
389
+ }))
390
+
391
+ return (
392
+ <Autocomplete
393
+ options={options}
394
+ value={selected}
395
+ onChange={(_, newVal) => setSelected(newVal ?? { value: '', label: '' })}
396
+ getOptionLabel={o => o?.label ?? ''}
397
+ isOptionEqualToValue={(o, v) => o?.value === v?.value}
398
+ openOnFocus
399
+ disableClearable
400
+ size='small'
401
+ sx={{ width: '100%' }}
402
+ renderInput={params => (
403
+ <TextField
404
+ {...params}
405
+ inputRef={inputRef}
406
+ placeholder={p.placeholder ?? 'Search...'}
407
+ variant='outlined'
408
+ size='small'
409
+ sx={{ '& .MuiInputBase-root': { height: '100%' } }}
410
+ />
411
+ )}
412
+ />
413
+ )
414
+ })
415
+
416
+ /**
417
+ * CheckboxEditor
418
+ * Toggles a boolean value in-cell.
419
+ */
420
+ export const CheckboxEditor = forwardRef(function CheckboxEditor(props, ref) {
421
+ const p = props.colDef?.cellEditorParams ?? {}
422
+ const [checked, setChecked] = useState(Boolean(props.value))
423
+
424
+ useImperativeHandle(ref, () => ({
425
+ getValue() { return checked },
426
+ isCancelBeforeStart() { return false },
427
+ }))
428
+
429
+ return (
430
+ <Box sx={{ display: 'flex', alignItems: 'center', height: '100%', px: 0.5 }}>
431
+ <Checkbox
432
+ checked={checked}
433
+ onChange={e => setChecked(e.target.checked)}
434
+ color={p.color ?? 'primary'}
435
+ size='small'
436
+ autoFocus
437
+ />
438
+ </Box>
439
+ )
440
+ })
441
+
442
+ /**
443
+ * DateEditor
444
+ * Native date input — lightweight, no extra MUI dependency.
445
+ * Stores value as ISO date string (YYYY-MM-DD).
446
+ */
447
+ export const DateEditor = forwardRef(function DateEditor(props, ref) {
448
+ const p = props.colDef?.cellEditorParams ?? {}
449
+ // Normalise stored value to YYYY-MM-DD for the input
450
+ const toInputValue = v => {
451
+ if (!v) return ''
452
+ try {
453
+ const d = new Date(v)
454
+ if (isNaN(d.getTime())) return v
455
+ return d.toISOString().slice(0, 10)
456
+ } catch { return v }
457
+ }
458
+
459
+ const [value, setValue] = useState(toInputValue(props.value))
460
+ const inputRef = useRef(null)
461
+ useEffect(() => { inputRef.current?.focus() }, [])
462
+
463
+ useImperativeHandle(ref, () => ({
464
+ getValue() { return value },
465
+ isCancelBeforeStart() { return false },
466
+ }))
467
+
468
+ return (
469
+ <input
470
+ ref={inputRef}
471
+ type='date'
472
+ value={value}
473
+ min={p.min ?? undefined}
474
+ max={p.max ?? undefined}
475
+ onChange={e => setValue(e.target.value)}
476
+ style={{
477
+ width: '100%', height: '100%', border: 'none', outline: 'none',
478
+ padding: '0 8px', fontSize: 13, background: 'transparent',
479
+ boxSizing: 'border-box', cursor: 'pointer',
480
+ }}
481
+ />
482
+ )
483
+ })
484
+
485
+ /**
486
+ * NumberEditor
487
+ * Numeric text input with optional min / max / step / decimals.
488
+ */
489
+ export const NumberEditor = forwardRef(function NumberEditor(props, ref) {
490
+ const p = props.colDef?.cellEditorParams ?? {}
491
+ const [value, setValue] = useState(props.value ?? '')
492
+ const inputRef = useRef(null)
493
+ useEffect(() => { inputRef.current?.focus(); inputRef.current?.select() }, [])
494
+
495
+ useImperativeHandle(ref, () => ({
496
+ getValue() {
497
+ const num = parseFloat(value)
498
+ if (isNaN(num)) return props.value ?? null
499
+ const dec = p.decimals ?? null
500
+ return dec !== null ? parseFloat(num.toFixed(dec)) : num
501
+ },
502
+ isCancelBeforeStart() { return false },
503
+ }))
504
+
505
+ return (
506
+ <input
507
+ ref={inputRef}
508
+ type='number'
509
+ value={value}
510
+ min={p.min ?? undefined}
511
+ max={p.max ?? undefined}
512
+ step={p.step ?? 'any'}
513
+ onChange={e => setValue(e.target.value)}
514
+ style={{
515
+ width: '100%', height: '100%', border: 'none', outline: 'none',
516
+ padding: '0 8px', fontSize: 13, background: 'transparent',
517
+ boxSizing: 'border-box', textAlign: 'right',
518
+ }}
519
+ />
520
+ )
521
+ })
522
+
523
+ /**
524
+ * MultiSelectEditor
525
+ *
526
+ * Rendered as an AG Grid popup editor (isPopup = true).
527
+ * AG Grid's popup mode means it does NOT close the editor when the user clicks
528
+ * inside it — no event propagation fights needed.
529
+ *
530
+ * cellEditorParams shape:
531
+ * options string[] | object[] static options
532
+ * asyncFetchOptions async (search?: string) => [] dynamic options (takes precedence)
533
+ * isSingle boolean single vs multi default: false
534
+ * fieldName string | string[] label path default: 'name'
535
+ * groupByField string group-by path
536
+ * targetValue string | string[] getValue() extraction path
537
+ */
538
+ export const MultiSelectEditor = forwardRef(function MultiSelectEditor(props, ref) {
539
+ const rawCep = props.colDef?.cellEditorParams
540
+ const cepObj = (rawCep && typeof rawCep === 'object' && typeof rawCep !== 'function') ? rawCep : {}
541
+
542
+ // Params come from props root when cellEditorParams was a function (AG Grid merges result),
543
+ // or from cepObj when it was a plain object.
544
+ const asyncFetchOptions = props.asyncFetchOptions ?? cepObj.asyncFetchOptions ?? null
545
+ const isSingle = props.isSingle ?? cepObj.isSingle ?? false
546
+ const fieldName = props.fieldName ?? cepObj.fieldName ?? 'name'
547
+ const targetValue = props.targetValue ?? cepObj.targetValue ?? null
548
+ const groupByField = props.groupByField ?? cepObj.groupByField ?? null
549
+ const staticOptions = props.options ?? cepObj.options ?? []
550
+
551
+ // getViewerContext() returns the latest viewerContext from DataGridRenderer —
552
+ // used to provide fresh data / setData / reportRefs to asyncFetchOptions.
553
+ const getViewerContext = props.context?.getViewerContext ?? (() => ({}))
554
+
555
+ const initialValue = props.value ?? (isSingle ? null : [])
556
+ const selectedRef = useRef(initialValue) // sync ref for getValue()
557
+ const [selected, setSelected] = useState(initialValue)
558
+ const [options, setOptions] = useState(staticOptions)
559
+ const [search, setSearch] = useState('')
560
+ const [debSearch, setDebSearch] = useState('')
561
+ const [loading, setLoading] = useState(false)
562
+ const searchRef = useRef(null)
563
+
564
+ // Build the second-arg scope for asyncFetchOptions — mirrors what convertStringToFunction injects.
565
+ // This lets users write: async (search, { data, setData, dataRef, reportRefs }) => { ... }
566
+ // and get live values even when called without the second argument.
567
+ const buildAsyncScope = () => {
568
+ const vCtx = getViewerContext()
569
+ return {
570
+ data: vCtx.data ?? {},
571
+ setData: vCtx.setData ?? (() => {}),
572
+ dataRef: vCtx.dataRef ?? { current: {} },
573
+ reportRefs: vCtx.reportRefs ?? { current: {} },
574
+ }
575
+ }
576
+
577
+ useEffect(() => { setTimeout(() => searchRef.current?.focus(), 0) }, [])
578
+
579
+ // Debounce search
580
+ useEffect(() => {
581
+ const t = setTimeout(() => setDebSearch(search), 300)
582
+ return () => clearTimeout(t)
583
+ }, [search])
584
+
585
+ // Initial async fetch
586
+ useEffect(() => {
587
+ if (!asyncFetchOptions) return
588
+ setLoading(true)
589
+ Promise.resolve(asyncFetchOptions('', buildAsyncScope()))
590
+ .then(res => setOptions(Array.isArray(res) ? res : []))
591
+ .catch(e => console.error('[MultiSelectEditor] asyncFetchOptions error:', e))
592
+ .finally(() => setLoading(false))
593
+ }, []) // eslint-disable-line react-hooks/exhaustive-deps
594
+
595
+ // Re-fetch on debounced search (async only; static filtered client-side below)
596
+ useEffect(() => {
597
+ if (!asyncFetchOptions || debSearch === '') return
598
+ setLoading(true)
599
+ Promise.resolve(asyncFetchOptions(debSearch, buildAsyncScope()))
600
+ .then(res => setOptions(Array.isArray(res) ? res : []))
601
+ .catch(e => console.error('[MultiSelectEditor] asyncFetchOptions search error:', e))
602
+ .finally(() => setLoading(false))
603
+ }, [debSearch]) // eslint-disable-line react-hooks/exhaustive-deps
604
+
605
+ function getNestedProperty(obj, path) {
606
+ if (!path || !obj) return obj
607
+ if (Array.isArray(path)) {
608
+ return path.map(k => k.split('.').reduce((a, p) => a?.[p], obj)).filter(Boolean).join(' - ')
609
+ }
610
+ return path.split('.').reduce((a, k) => a?.[k], obj)
611
+ }
612
+
613
+ function getLabel(opt) {
614
+ if (opt === null || opt === undefined) return ''
615
+ if (typeof opt !== 'object') return String(opt)
616
+ const label = Array.isArray(fieldName)
617
+ ? fieldName.map(f => getNestedProperty(opt, f)).filter(Boolean).join(' - ')
618
+ : (getNestedProperty(opt, fieldName) ?? opt?.name ?? '')
619
+ return label != null ? String(label) : ''
620
+ }
621
+
622
+ function optionId(opt) {
623
+ return opt?.id ?? JSON.stringify(opt)
624
+ }
625
+
626
+ function isOptSelected(opt) {
627
+ if (isSingle) return optionId(selectedRef.current) === optionId(opt)
628
+ return (Array.isArray(selectedRef.current) ? selectedRef.current : [])
629
+ .some(s => optionId(s) === optionId(opt))
630
+ }
631
+
632
+ // Compute the final committed value — mirrors what getValue() exposes via the ref.
633
+ // Called directly inside commit() because AG Grid v33 React destroys the popup
634
+ // component before invoking getValue() through the ref, so we can't rely on that path.
635
+ const getEditorValue = () => {
636
+ const val = selectedRef.current
637
+ if (targetValue != null && val != null) {
638
+ if (Array.isArray(val)) return val.map(v => getNestedProperty(v, targetValue))
639
+ return getNestedProperty(val, targetValue)
640
+ }
641
+ return val
642
+ }
643
+
644
+ useImperativeHandle(ref, () => ({
645
+ // Kept for AG Grid compatibility — may be called in non-popup scenarios.
646
+ getValue() {
647
+ const result = getEditorValue()
648
+ console.log('[MultiSelectEditor] getValue() via ref → returning:', result)
649
+ return result
650
+ },
651
+ isCancelBeforeStart() { return false },
652
+ isPopup() { return true },
653
+ getPopupPosition() { return 'under' },
654
+ }))
655
+
656
+ const commit = () => {
657
+ const value = getEditorValue()
658
+ console.log('[MultiSelectEditor] commit() — final value:', value, 'field:', props.colDef?.field)
659
+
660
+ // AG Grid v33 React destroys popup editors before calling getValue() through the ref.
661
+ // Work around by setting the data value directly, which triggers valueSetter +
662
+ // onCellValueChanged exactly the same as the normal AG Grid commit flow.
663
+ if (props.node && props.colDef?.field) {
664
+ props.node.setDataValue(props.colDef.field, value)
665
+ }
666
+
667
+ // Temporarily remove valueSetter before stopEditing(true) so AG Grid's cancel/revert
668
+ // path does not call it with the old (pre-edit) value and overwrite what we just committed.
669
+ // The revert call is synchronous, so restoring immediately after is safe.
670
+ const savedVS = props.colDef?.valueSetter
671
+ if (props.colDef) delete props.colDef.valueSetter
672
+
673
+ if (typeof props.stopEditing === 'function') {
674
+ props.stopEditing(true)
675
+ } else {
676
+ props.api?.stopEditing?.(true)
677
+ }
678
+
679
+ if (props.colDef && savedVS) props.colDef.valueSetter = savedVS
680
+ }
681
+
682
+ const handleSelect = (opt) => {
683
+ let next
684
+ if (isSingle) {
685
+ next = opt
686
+ } else {
687
+ const cur = Array.isArray(selectedRef.current) ? selectedRef.current : []
688
+ next = isOptSelected(opt)
689
+ ? cur.filter(s => optionId(s) !== optionId(opt))
690
+ : [...cur, opt]
691
+ }
692
+ selectedRef.current = next
693
+ setSelected(next)
694
+ console.log('[MultiSelectEditor] handleSelect → next:', next, 'isSingle:', isSingle)
695
+ if (isSingle) setTimeout(commit, 0)
696
+ }
697
+
698
+ // Static options: filter client-side; async options: server filters via debSearch
699
+ const visibleOptions = asyncFetchOptions
700
+ ? options
701
+ : options.filter(opt => getLabel(opt).toLowerCase().includes(search.toLowerCase()))
702
+
703
+ const grouped = groupByField
704
+ ? visibleOptions.reduce((acc, opt) => {
705
+ const g = getNestedProperty(opt, groupByField) ?? 'Other'
706
+ ;(acc[g] = acc[g] ?? []).push(opt)
707
+ return acc
708
+ }, {})
709
+ : null
710
+
711
+ const selectedArr = Array.isArray(selected) ? selected : []
712
+
713
+ return (
714
+ <Box
715
+ sx={{
716
+ width: 260,
717
+ maxHeight: 340,
718
+ bgcolor: '#fff',
719
+ border: '1px solid #e0e0e0',
720
+ borderRadius: 1,
721
+ boxShadow: '0 4px 16px rgba(0,0,0,0.18)',
722
+ display: 'flex',
723
+ flexDirection: 'column',
724
+ overflow: 'hidden',
725
+ }}
726
+ >
727
+ {/* Search */}
728
+ <Box sx={{ p: 0.75, borderBottom: '1px solid #f0f0f0' }}>
729
+ <input
730
+ ref={searchRef}
731
+ value={search}
732
+ onChange={e => setSearch(e.target.value)}
733
+ placeholder='Search…'
734
+ style={{
735
+ width: '100%', border: '1px solid #e0e0e0', borderRadius: 4,
736
+ padding: '4px 8px', fontSize: 13, outline: 'none', boxSizing: 'border-box',
737
+ }}
738
+ />
739
+ </Box>
740
+
741
+ {/* Options */}
742
+ <Box sx={{ overflowY: 'auto', flex: 1 }}>
743
+ {loading && <Typography sx={{ p: 1, fontSize: 12, color: '#999' }}>Loading…</Typography>}
744
+ {!loading && visibleOptions.length === 0 && (
745
+ <Typography sx={{ p: 1, fontSize: 12, color: '#999' }}>No options</Typography>
746
+ )}
747
+ {!loading && (grouped
748
+ ? Object.entries(grouped).map(([group, opts]) => (
749
+ <Box key={group}>
750
+ <Typography sx={{ px: 1.5, py: 0.5, fontSize: 11, fontWeight: 700, color: '#888', textTransform: 'uppercase', letterSpacing: '0.05em', bgcolor: '#fafafa' }}>
751
+ {group}
752
+ </Typography>
753
+ {opts.map((opt, i) => (
754
+ <OptionRow key={optionId(opt) ?? i} opt={opt} selected={isOptSelected(opt)} label={getLabel(opt)} isSingle={isSingle} onSelect={handleSelect} />
755
+ ))}
756
+ </Box>
757
+ ))
758
+ : visibleOptions.map((opt, i) => (
759
+ <OptionRow key={optionId(opt) ?? i} opt={opt} selected={isOptSelected(opt)} label={getLabel(opt)} isSingle={isSingle} onSelect={handleSelect} />
760
+ ))
761
+ )}
762
+ </Box>
763
+
764
+ {/* Footer — multi only */}
765
+ {!isSingle && (
766
+ <Box sx={{ p: 0.75, borderTop: '1px solid #f0f0f0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
767
+ <Typography sx={{ fontSize: 11, color: '#888' }}>{selectedArr.length} selected</Typography>
768
+ <Box
769
+ component='button'
770
+ onClick={commit}
771
+ sx={{
772
+ px: 1.5, py: 0.4, fontSize: 12, fontWeight: 600,
773
+ bgcolor: 'primary.main', color: '#fff', border: 'none',
774
+ borderRadius: 1, cursor: 'pointer',
775
+ '&:hover': { bgcolor: 'primary.dark' },
776
+ }}
777
+ >
778
+ Confirm
779
+ </Box>
780
+ </Box>
781
+ )}
782
+ </Box>
783
+ )
784
+ })
785
+
786
+ function OptionRow({ opt, selected, label, isSingle, onSelect }) {
787
+ return (
788
+ <Box
789
+ onClick={() => onSelect(opt)}
790
+ sx={{
791
+ display: 'flex', alignItems: 'center', gap: 1,
792
+ px: 1.5, py: 0.6, cursor: 'pointer', fontSize: 13,
793
+ bgcolor: selected ? '#e8f0fe' : 'transparent',
794
+ '&:hover': { bgcolor: selected ? '#d2e3fc' : '#f5f5f5' },
795
+ }}
796
+ >
797
+ {!isSingle && <Checkbox checked={selected} size='small' sx={{ p: 0 }} readOnly tabIndex={-1} />}
798
+ {label}
799
+ </Box>
800
+ )
801
+ }
802
+
803
+ // ─────────────────────────────────────────────────────────────────────────────
804
+ // AG Grid components map — pass this to <AgGridReact components={AG_COMPONENTS}>
805
+ // ─────────────────────────────────────────────────────────────────────────────
806
+
807
+ export const AG_COMPONENTS = {
808
+ // Renderers
809
+ ChipRenderer,
810
+ BooleanRenderer,
811
+ LinkRenderer,
812
+ CurrencyRenderer,
813
+ DateRenderer,
814
+ ProgressRenderer,
815
+ AvatarRenderer,
816
+ IconRenderer,
817
+ // Editors
818
+ SelectEditor,
819
+ AutocompleteEditor,
820
+ CheckboxEditor,
821
+ DateEditor,
822
+ NumberEditor,
823
+ MultiSelectEditor,
824
+ }