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.
- package/INTEGRATION.md +1586 -0
- package/README.md +928 -0
- package/RoboByteBuilder_User_Manual.docx +0 -0
- package/next.config.js +19 -48
- package/package.json +42 -86
- package/src/context/BuilderContext.jsx +191 -7
- package/src/context/SystemContext.js +2 -2
- package/src/hooks/useGlobalStore.js +36 -0
- package/src/hooks/useTimerEngine.js +54 -0
- package/src/lib/index.js +11 -3
- package/src/lib/layouts/BlankLayout.jsx +13 -0
- package/src/lib/providers/RoboByteFrontBuilderProvider.jsx +61 -7
- package/src/lib/themes/builderTheme.js +41 -0
- package/src/pages/_app.js +32 -134
- package/src/pages/api/ai.js +107 -0
- package/src/pages/builders/report/index.js +1 -0
- package/src/pages/builders/report/list/index.js +1 -0
- package/src/pages/builders/report/viewer/index.js +1 -0
- package/src/pages/index.js +88 -37
- package/src/pages/printBuilder/index.jsx +263 -0
- package/src/pages/printBuilder/layouts/index.jsx +298 -0
- package/src/pages/reportModule/reportBuilder/index.js +8 -6
- package/src/pages/reportModule/reportBuilder/reportViewer/index.js +92 -25
- package/src/pages/reportModule/reportBuilder/reports/index.js +3 -5
- package/src/pages/reportModule/reportBuilder/reportsPermissions/index.js +2 -3
- package/src/pages/viewBuilder/index.jsx +117 -32
- package/src/pages/viewBuilder/views/index.js +3 -3
- package/src/pages/viewer/[id]/index.js +2 -1
- package/src/services/DeleteService.js +31 -60
- package/src/services/Endpoints/PrintLayoutEndpoints.js +42 -0
- package/src/services/Endpoints/ReportBuilderEndpoints.js +7 -7
- package/src/services/Endpoints.js +2 -0
- package/src/services/GetService.js +33 -54
- package/src/services/PatchService.js +38 -65
- package/src/services/PostService.js +37 -63
- package/src/services/UpdateService.js +39 -65
- package/src/services/builderHelper/actionExecutor.js +141 -25
- package/src/services/builderHelper/builderHelper.js +92 -0
- package/src/services/builderHelper/colorSchema.js +95 -0
- package/src/services/builderHelper/iconResolver.js +50 -0
- package/src/services/builderHelper/jsExecutor.js +212 -46
- package/src/services/builderHelper/nodeFactory.js +32 -15
- package/src/services/builderHelper/numberFormat.js +123 -0
- package/src/services/builderHelper/resolveProps.js +73 -4
- package/src/services/builderHelper/thresholdEngine.js +77 -0
- package/src/services/builderHelper/tree.js +31 -0
- package/src/services/components/agGridAutoComplete.js +5 -9
- package/src/services/config.js +9 -1
- package/src/services/globalStore.js +80 -0
- package/src/services/helper/multiSelectEditor.js +5 -9
- package/src/services/helper/multiSelectEditorByBuilder.js +5 -9
- package/src/services/reportData/fetchReportData.js +69 -28
- package/src/services/routerRef.js +35 -0
- package/src/services/sessionLog.js +171 -0
- package/src/views/ConfirmDialog.js +2 -2
- package/src/views/builder/JSEditor.js +105 -107
- package/src/views/builder/SessionLogDialog.jsx +350 -0
- package/src/views/builder/UnsavedChangesGuard.jsx +103 -0
- package/src/views/builder/inspector/Inspector.jsx +6 -9
- package/src/views/builder/inspector/Tabs/ComponentActionsTab.jsx +7 -13
- package/src/views/builder/inspector/Tabs/MainTab.jsx +143 -25
- package/src/views/builder/inspector/Tabs/RulesTab.jsx +9 -24
- package/src/views/builder/inspector/Tabs/StyleTab.jsx +9 -24
- package/src/views/builder/inspector/definitions/autocomplete/main.js +4 -6
- package/src/views/builder/inspector/definitions/banner/actions.js +7 -0
- package/src/views/builder/inspector/definitions/banner/main.js +22 -0
- package/src/views/builder/inspector/definitions/banner/rules.js +1 -0
- package/src/views/builder/inspector/definitions/banner/style.js +1 -0
- package/src/views/builder/inspector/definitions/breadcrumb/main.js +43 -6
- package/src/views/builder/inspector/definitions/button/main.js +11 -12
- package/src/views/builder/inspector/definitions/button/style.js +18 -30
- package/src/views/builder/inspector/definitions/checkbox/actions.js +3 -1
- package/src/views/builder/inspector/definitions/checkbox/main.js +4 -6
- package/src/views/builder/inspector/definitions/common/main.js +13 -2
- package/src/views/builder/inspector/definitions/dataGrid/main.js +23 -0
- package/src/views/builder/inspector/definitions/dataTableViewer/main.js +46 -0
- package/src/views/builder/inspector/definitions/datepicker/actions.js +3 -1
- package/src/views/builder/inspector/definitions/datepicker/main.js +6 -14
- package/src/views/builder/inspector/definitions/dialog/main.js +36 -0
- package/src/views/builder/inspector/definitions/dropdown/main.js +5 -8
- package/src/views/builder/inspector/definitions/excelUpload/actions.js +23 -0
- package/src/views/builder/inspector/definitions/excelUpload/main.js +17 -0
- package/src/views/builder/inspector/definitions/excelUpload/rules.js +1 -0
- package/src/views/builder/inspector/definitions/excelUpload/style.js +45 -0
- package/src/views/builder/inspector/definitions/header/main.js +10 -1
- package/src/views/builder/inspector/definitions/index.js +106 -19
- package/src/views/builder/inspector/definitions/input/actions.js +4 -1
- package/src/views/builder/inspector/definitions/input/main.js +20 -11
- package/src/views/builder/inspector/definitions/kpi/avatarGroup.js +22 -0
- package/src/views/builder/inspector/definitions/kpi/badge.js +17 -0
- package/src/views/builder/inspector/definitions/kpi/bulletChart.js +47 -0
- package/src/views/builder/inspector/definitions/kpi/chart.js +55 -0
- package/src/views/builder/inspector/definitions/kpi/colorScale.js +60 -0
- package/src/views/builder/inspector/definitions/kpi/comparisonBars.js +41 -0
- package/src/views/builder/inspector/definitions/kpi/countdown.js +46 -0
- package/src/views/builder/inspector/definitions/kpi/donut.js +51 -0
- package/src/views/builder/inspector/definitions/kpi/funnel.js +25 -0
- package/src/views/builder/inspector/definitions/kpi/gauge.js +39 -0
- package/src/views/builder/inspector/definitions/kpi/heatmapGrid.js +96 -0
- package/src/views/builder/inspector/definitions/kpi/iconBox.js +20 -0
- package/src/views/builder/inspector/definitions/kpi/metric.js +45 -0
- package/src/views/builder/inspector/definitions/kpi/rating.js +27 -0
- package/src/views/builder/inspector/definitions/kpi/statusDot.js +18 -0
- package/src/views/builder/inspector/definitions/kpi/stepStage.js +65 -0
- package/src/views/builder/inspector/definitions/kpi/tagList.js +32 -0
- package/src/views/builder/inspector/definitions/kpi/timeline.js +80 -0
- package/src/views/builder/inspector/definitions/kpi/trend.js +20 -0
- package/src/views/builder/inspector/definitions/label/main.js +10 -1
- package/src/views/builder/inspector/definitions/layout/main.js +27 -3
- package/src/views/builder/inspector/definitions/number/main.js +6 -14
- package/src/views/builder/inspector/definitions/pageNumber/main.js +21 -0
- package/src/views/builder/inspector/definitions/popover/main.js +71 -0
- package/src/views/builder/inspector/definitions/radio/main.js +5 -8
- package/src/views/builder/inspector/definitions/repeater/main.js +31 -0
- package/src/views/builder/inspector/definitions/reportViewer/main.js +28 -1
- package/src/views/builder/inspector/definitions/richtext/main.js +5 -8
- package/src/views/builder/inspector/definitions/signature/main.js +4 -1
- package/src/views/builder/inspector/definitions/tag/main.js +5 -8
- package/src/views/builder/inspector/definitions/textarea/actions.js +4 -1
- package/src/views/builder/inspector/definitions/textarea/main.js +5 -7
- package/src/views/builder/inspector/definitions/time/main.js +5 -8
- package/src/views/builder/inspector/definitions/toggle/main.js +5 -19
- package/src/views/builder/inspector/definitions/treeView/main.js +61 -0
- package/src/views/builder/inspector/definitions/viewRenderer/main.js +53 -0
- package/src/views/builder/inspector/definitions/wizard/main.js +68 -0
- package/src/views/builder/inspector/definitions/wizard-step/main.js +25 -0
- package/src/views/builder/inspector/fields/ActionsConfigEditor.jsx +426 -0
- package/src/views/builder/inspector/fields/ColorSchemaField.jsx +140 -0
- package/src/views/builder/inspector/fields/ColumnFunctionEditor.jsx +238 -0
- package/src/views/builder/inspector/fields/ColumnMappingEditor.jsx +105 -0
- package/src/views/builder/inspector/fields/ColumnsConfigEditor.jsx +506 -0
- package/src/views/builder/inspector/fields/DonutRingsEditorField.jsx +337 -0
- package/src/views/builder/inspector/fields/ExtraColsEditor.jsx +618 -0
- package/src/views/builder/inspector/fields/FunctionHelpPopover.jsx +295 -0
- package/src/views/builder/inspector/fields/IconEditor.jsx +64 -0
- package/src/views/builder/inspector/fields/KpiActionField.jsx +223 -0
- package/src/views/builder/inspector/fields/MarkersEditorField.jsx +173 -0
- package/src/views/builder/inspector/fields/SelectEditor.jsx +9 -5
- package/src/views/builder/inspector/fields/SeriesEditorField.jsx +363 -0
- package/src/views/builder/inspector/fields/TableColumnsEditor.jsx +104 -0
- package/src/views/builder/inspector/fields/ThresholdsEditor.jsx +247 -0
- package/src/views/builder/inspector/fields/ValueFunctionsRefPanel.jsx +217 -0
- package/src/views/builder/inspector/fields/columnEditorShared.jsx +217 -0
- package/src/views/builder/sidebar/Sidebar.jsx +4 -2
- package/src/views/builder/sidebar/SidebarTabs.jsx +28 -17
- package/src/views/builder/sidebar/tabs/ActionsTab.jsx +7 -3
- package/src/views/builder/sidebar/tabs/AiTab/AiPreviewDialog.jsx +193 -0
- package/src/views/builder/sidebar/tabs/AiTab/aiProvider.js +53 -0
- package/src/views/builder/sidebar/tabs/AiTab/index.jsx +409 -0
- package/src/views/builder/sidebar/tabs/AiTab/schemaTransformer.js +167 -0
- package/src/views/builder/sidebar/tabs/AiTab/schemaValidator.js +64 -0
- package/src/views/builder/sidebar/tabs/AiTab/systemPrompt.js +1151 -0
- package/src/views/builder/sidebar/tabs/AiTab/trainingExport.js +131 -0
- package/src/views/builder/sidebar/tabs/Components/ComponentsTab.jsx +31 -31
- package/src/views/builder/sidebar/tabs/Components/componentCatalog.js +43 -21
- package/src/views/builder/sidebar/tabs/Components/printComponentCatalog.js +81 -0
- package/src/views/builder/sidebar/tabs/TimersTab.jsx +338 -0
- package/src/views/builder/sidebar/tabs/TreeTab.jsx +13 -4
- package/src/views/builder/sidebar/tabs/ViewTab.jsx +173 -13
- package/src/views/builder/viewer/AdornedLabel.jsx +82 -0
- package/src/views/builder/viewer/ComponentRenderer.jsx +98 -24
- package/src/views/builder/viewer/DialogsZone.jsx +259 -0
- package/src/views/builder/viewer/FieldLabel.jsx +106 -0
- package/src/views/builder/viewer/PrintDialog.jsx +481 -0
- package/src/views/builder/viewer/ProductionViewer.jsx +80 -5
- package/src/views/builder/viewer/Viewer.jsx +106 -8
- package/src/views/builder/viewer/ViewerComponentWrapper.jsx +70 -9
- package/src/views/builder/viewer/ViewerToolbar.jsx +285 -56
- package/src/views/builder/viewer/renderers/AutoCompleteRenderer.jsx +26 -22
- package/src/views/builder/viewer/renderers/AvatarGroupRenderer.jsx +112 -0
- package/src/views/builder/viewer/renderers/BadgeRenderer.jsx +79 -0
- package/src/views/builder/viewer/renderers/BannerRenderer.jsx +62 -0
- package/src/views/builder/viewer/renderers/BreadcrumbRenderer.jsx +203 -15
- package/src/views/builder/viewer/renderers/BulletChartRenderer.jsx +147 -0
- package/src/views/builder/viewer/renderers/ButtonRenderer.jsx +98 -39
- package/src/views/builder/viewer/renderers/CardRenderer.jsx +1 -1
- package/src/views/builder/viewer/renderers/ChartRenderer.jsx +388 -0
- package/src/views/builder/viewer/renderers/CheckboxRenderer.jsx +17 -9
- package/src/views/builder/viewer/renderers/ColorScaleRenderer.jsx +300 -0
- package/src/views/builder/viewer/renderers/ComparisonBarsRenderer.jsx +133 -0
- package/src/views/builder/viewer/renderers/ContainerRenderer.jsx +3 -1
- package/src/views/builder/viewer/renderers/CountdownRenderer.jsx +249 -0
- package/src/views/builder/viewer/renderers/DataGridRenderer.jsx +380 -0
- package/src/views/builder/viewer/renderers/DataTableViewerRenderer.jsx +240 -0
- package/src/views/builder/viewer/renderers/DatePickerRenderer.jsx +25 -24
- package/src/views/builder/viewer/renderers/DialogRenderer.jsx +327 -0
- package/src/views/builder/viewer/renderers/DividerRenderer.jsx +1 -1
- package/src/views/builder/viewer/renderers/DonutRenderer.jsx +294 -0
- package/src/views/builder/viewer/renderers/DropdownRenderer.jsx +36 -44
- package/src/views/builder/viewer/renderers/ExcelUploadRenderer.jsx +639 -0
- package/src/views/builder/viewer/renderers/FunnelRenderer.jsx +93 -0
- package/src/views/builder/viewer/renderers/GaugeRenderer.jsx +159 -0
- package/src/views/builder/viewer/renderers/HeaderRenderer.jsx +31 -9
- package/src/views/builder/viewer/renderers/HeatmapGridRenderer.jsx +432 -0
- package/src/views/builder/viewer/renderers/IconBoxRenderer.jsx +59 -0
- package/src/views/builder/viewer/renderers/ImageRenderer.jsx +1 -1
- package/src/views/builder/viewer/renderers/InputRenderer.jsx +75 -18
- package/src/views/builder/viewer/renderers/LabelRenderer.jsx +35 -9
- package/src/views/builder/viewer/renderers/LayoutCellRenderer.jsx +102 -40
- package/src/views/builder/viewer/renderers/LayoutContextMenu.jsx +8 -8
- package/src/views/builder/viewer/renderers/LayoutRenderer.jsx +48 -6
- package/src/views/builder/viewer/renderers/LinkRenderer.jsx +1 -1
- package/src/views/builder/viewer/renderers/MenuRenderer.jsx +2 -2
- package/src/views/builder/viewer/renderers/MetricRenderer.jsx +80 -0
- package/src/views/builder/viewer/renderers/NumberFormatRenderer.jsx +21 -30
- package/src/views/builder/viewer/renderers/PageNumberRenderer.jsx +76 -0
- package/src/views/builder/viewer/renderers/PopoverRenderer.jsx +350 -0
- package/src/views/builder/viewer/renderers/ProgressCircleRenderer.jsx +1 -1
- package/src/views/builder/viewer/renderers/ProgressLineRenderer.jsx +1 -1
- package/src/views/builder/viewer/renderers/RadioGroupRenderer.jsx +28 -39
- package/src/views/builder/viewer/renderers/RatingRenderer.jsx +80 -0
- package/src/views/builder/viewer/renderers/RepeaterRenderer.jsx +297 -38
- package/src/views/builder/viewer/renderers/ReportViewerRenderer.jsx +263 -5
- package/src/views/builder/viewer/renderers/RichTextRenderer.jsx +60 -66
- package/src/views/builder/viewer/renderers/RowActionsCell.jsx +308 -0
- package/src/views/builder/viewer/renderers/SignatureRenderer.jsx +33 -62
- package/src/views/builder/viewer/renderers/StatusDotRenderer.jsx +75 -0
- package/src/views/builder/viewer/renderers/StepStageRenderer.jsx +348 -0
- package/src/views/builder/viewer/renderers/TagListRenderer.jsx +115 -0
- package/src/views/builder/viewer/renderers/TagPickerRenderer.jsx +31 -45
- package/src/views/builder/viewer/renderers/TextAreaRenderer.jsx +25 -18
- package/src/views/builder/viewer/renderers/TextRenderer.jsx +7 -1
- package/src/views/builder/viewer/renderers/TimePickerRenderer.jsx +25 -24
- package/src/views/builder/viewer/renderers/TimelineRenderer.jsx +525 -0
- package/src/views/builder/viewer/renderers/ToggleRenderer.jsx +21 -27
- package/src/views/builder/viewer/renderers/TreeViewRenderer.jsx +832 -0
- package/src/views/builder/viewer/renderers/TrendRenderer.jsx +66 -0
- package/src/views/builder/viewer/renderers/ViewRendererRenderer.jsx +315 -0
- package/src/views/builder/viewer/renderers/WizardRenderer.jsx +380 -64
- package/src/views/builder/viewer/renderers/WizardStepRenderer.jsx +21 -12
- package/src/views/builder/viewer/renderers/dataGridComponents.jsx +824 -0
- package/src/views/customFilter/CustomFilterDialog.js +1023 -660
- package/src/views/customFilter/FixedFilterDialog.js +649 -0
- package/src/views/customFilter/SearchFilterDialog.js +248 -0
- package/src/views/genericTable/BuilderExpressionParams.js +3 -3
- package/src/views/genericTable/ColumnConfiguratorDialog.js +33 -24
- package/src/views/genericTable/FixedFilterDialog.js +3 -2
- package/src/views/genericTable/FormattingSettingsDialog.js +8 -3
- package/src/views/genericTable/SGrid.js +821 -448
- package/src/views/genericTable/SearchFilterDialog.js +3 -2
- package/src/views/genericTable/cellEditors/autocompleteEditor.js +5 -9
- package/src/views/genericTable/convertStringFunctions.js +274 -138
- package/src/views/genericTable/statusBar/rowCountStatusBar.js +3 -1
- package/src/views/genericTable/updateRefHelpers.js +9 -6
- package/src/views/printBuilder/PrintBuilderViewer.jsx +627 -0
- package/src/views/printBuilder/PrintPreviewCanvas.jsx +157 -0
- package/src/views/rolePermissions/UpdateReportPermissionDialog.js +3 -2
- package/src/@core/components/auth/AclGuard.js +0 -55
- package/src/@core/components/auth/AuthGuard.js +0 -40
- package/src/@core/components/auth/GuestGuard.js +0 -30
- package/src/@core/components/custom-inputs/Horizontal.jsx +0 -143
- package/src/@core/components/custom-inputs/Image.jsx +0 -78
- package/src/@core/components/custom-inputs/Vertical.jsx +0 -113
- package/src/@core/components/customizer/index.jsx +0 -470
- package/src/@core/components/customizer/styles.module.css +0 -169
- package/src/@core/components/mui/Avatar.jsx +0 -41
- package/src/@core/components/mui/Badge.jsx +0 -20
- package/src/@core/components/mui/IconButton.jsx +0 -74
- package/src/@core/components/mui/TabList.jsx +0 -60
- package/src/@core/components/option-menu/index.jsx +0 -137
- package/src/@core/components/scroll-to-top/index.jsx +0 -43
- package/src/@core/components/spinner/index.js +0 -26
- package/src/@core/components/window-wrapper/index.js +0 -27
- package/src/@core/contexts/settingsContext.jsx +0 -98
- package/src/@core/hooks/useBgColor.js +0 -63
- package/src/@core/hooks/useImageVariant.js +0 -27
- package/src/@core/hooks/useLayoutInit.js +0 -37
- package/src/@core/hooks/useObjectCookie.js +0 -18
- package/src/@core/hooks/useSettings.jsx +0 -15
- package/src/@core/layouts/BlankLayout.js +0 -37
- package/src/@core/layouts/BlankLayoutWithAppBar.js +0 -51
- package/src/@core/layouts/HorizontalLayout.jsx +0 -151
- package/src/@core/layouts/Layout.js +0 -39
- package/src/@core/layouts/VerticalLayout.jsx +0 -124
- package/src/@core/layouts/components/blank-layout-with-appBar/index.js +0 -115
- package/src/@core/layouts/components/horizontal/app-bar-content/index.js +0 -67
- package/src/@core/layouts/components/horizontal/navigation/HorizontalNavGroup.js +0 -352
- package/src/@core/layouts/components/horizontal/navigation/HorizontalNavItems.js +0 -21
- package/src/@core/layouts/components/horizontal/navigation/HorizontalNavLink.js +0 -195
- package/src/@core/layouts/components/horizontal/navigation/index.js +0 -31
- package/src/@core/layouts/components/shared-components/LanguageDropdown.js +0 -96
- package/src/@core/layouts/components/shared-components/ModeToggler.js +0 -32
- package/src/@core/layouts/components/shared-components/NotificationDropdown.js +0 -226
- package/src/@core/layouts/components/shared-components/UserDropdown.js +0 -177
- package/src/@core/layouts/components/shared-components/footer/FooterContent.js +0 -46
- package/src/@core/layouts/components/shared-components/footer/index.js +0 -61
- package/src/@core/layouts/components/vertical/appBar/index.js +0 -74
- package/src/@core/layouts/components/vertical/navigation/Drawer.js +0 -122
- package/src/@core/layouts/components/vertical/navigation/VerticalNavGroup.js +0 -435
- package/src/@core/layouts/components/vertical/navigation/VerticalNavHeader.js +0 -180
- package/src/@core/layouts/components/vertical/navigation/VerticalNavItems.js +0 -26
- package/src/@core/layouts/components/vertical/navigation/VerticalNavLink.js +0 -258
- package/src/@core/layouts/components/vertical/navigation/VerticalNavSectionTitle.js +0 -102
- package/src/@core/layouts/components/vertical/navigation/index.js +0 -169
- package/src/@core/layouts/utils.js +0 -69
- package/src/@core/styles/Table.module.css +0 -93
- package/src/@core/styles/horizontal/menuItemStyles.js +0 -100
- package/src/@core/styles/horizontal/menuRootStyles.js +0 -19
- package/src/@core/styles/libs/fullcalendar/index.js +0 -461
- package/src/@core/styles/libs/keen-slider/index.js +0 -111
- package/src/@core/styles/libs/react-apexcharts/index.js +0 -107
- package/src/@core/styles/libs/react-cleave/index.js +0 -33
- package/src/@core/styles/libs/react-credit-cards/index.js +0 -11
- package/src/@core/styles/libs/react-datepicker/index.js +0 -388
- package/src/@core/styles/libs/react-draft-wysiwyg/index.js +0 -144
- package/src/@core/styles/libs/react-dropzone/index.js +0 -76
- package/src/@core/styles/libs/react-hot-toast/index.js +0 -37
- package/src/@core/styles/libs/recharts/index.js +0 -47
- package/src/@core/styles/stepper.js +0 -103
- package/src/@core/styles/vertical/menuItemStyles.js +0 -138
- package/src/@core/styles/vertical/menuSectionStyles.js +0 -54
- package/src/@core/styles/vertical/navigationCustomStyles.js +0 -62
- package/src/@core/svg/ContentCompact.jsx +0 -17
- package/src/@core/svg/ContentWide.jsx +0 -17
- package/src/@core/svg/DirectionLtr.jsx +0 -93
- package/src/@core/svg/DirectionRtl.jsx +0 -93
- package/src/@core/svg/LayoutCollapsed.jsx +0 -59
- package/src/@core/svg/LayoutHorizontal.jsx +0 -42
- package/src/@core/svg/LayoutVertical.jsx +0 -59
- package/src/@core/svg/Logo.jsx +0 -76
- package/src/@core/svg/SkinBordered.jsx +0 -54
- package/src/@core/svg/SkinDefault.jsx +0 -59
- package/src/@core/tailwind/plugin.js +0 -78
- package/src/@core/theme/ThemeComponent.js +0 -63
- package/src/@core/theme/ThemeOptions.js +0 -71
- package/src/@core/theme/breakpoints/index.js +0 -11
- package/src/@core/theme/colorSchemes.js +0 -326
- package/src/@core/theme/customShadows.js +0 -11
- package/src/@core/theme/globalStyles.js +0 -81
- package/src/@core/theme/index.js +0 -42
- package/src/@core/theme/overrides/accordion.js +0 -51
- package/src/@core/theme/overrides/accordion.jsx +0 -85
- package/src/@core/theme/overrides/alerts.js +0 -110
- package/src/@core/theme/overrides/alerts.jsx +0 -180
- package/src/@core/theme/overrides/autocomplete.js +0 -14
- package/src/@core/theme/overrides/autocomplete.jsx +0 -68
- package/src/@core/theme/overrides/avatar.js +0 -38
- package/src/@core/theme/overrides/avatars.js +0 -27
- package/src/@core/theme/overrides/backdrop.js +0 -22
- package/src/@core/theme/overrides/badges.js +0 -16
- package/src/@core/theme/overrides/breadcrumbs.js +0 -11
- package/src/@core/theme/overrides/button-group.js +0 -84
- package/src/@core/theme/overrides/button.js +0 -93
- package/src/@core/theme/overrides/buttonGroup.js +0 -9
- package/src/@core/theme/overrides/card.js +0 -83
- package/src/@core/theme/overrides/checkbox.jsx +0 -95
- package/src/@core/theme/overrides/chip.js +0 -72
- package/src/@core/theme/overrides/dataGrid.js +0 -114
- package/src/@core/theme/overrides/dateTimePicker.js +0 -65
- package/src/@core/theme/overrides/dialog.js +0 -120
- package/src/@core/theme/overrides/divider.js +0 -13
- package/src/@core/theme/overrides/drawer.js +0 -20
- package/src/@core/theme/overrides/fab.js +0 -13
- package/src/@core/theme/overrides/form-control-label.js +0 -19
- package/src/@core/theme/overrides/icon-button.js +0 -145
- package/src/@core/theme/overrides/index.js +0 -103
- package/src/@core/theme/overrides/input.js +0 -72
- package/src/@core/theme/overrides/link.js +0 -9
- package/src/@core/theme/overrides/list.js +0 -44
- package/src/@core/theme/overrides/menu.js +0 -25
- package/src/@core/theme/overrides/pagination.js +0 -41
- package/src/@core/theme/overrides/paper.js +0 -9
- package/src/@core/theme/overrides/popover.js +0 -16
- package/src/@core/theme/overrides/progress.js +0 -38
- package/src/@core/theme/overrides/radio.jsx +0 -80
- package/src/@core/theme/overrides/rating.js +0 -16
- package/src/@core/theme/overrides/rating.jsx +0 -32
- package/src/@core/theme/overrides/select.js +0 -19
- package/src/@core/theme/overrides/select.jsx +0 -52
- package/src/@core/theme/overrides/slider.js +0 -97
- package/src/@core/theme/overrides/snackbar.js +0 -19
- package/src/@core/theme/overrides/switch.js +0 -73
- package/src/@core/theme/overrides/switches.js +0 -25
- package/src/@core/theme/overrides/table-pagination.js +0 -39
- package/src/@core/theme/overrides/table.js +0 -81
- package/src/@core/theme/overrides/tabs.js +0 -30
- package/src/@core/theme/overrides/timeline.js +0 -80
- package/src/@core/theme/overrides/toggle-button.js +0 -33
- package/src/@core/theme/overrides/toggleButton.js +0 -16
- package/src/@core/theme/overrides/tooltip.js +0 -21
- package/src/@core/theme/overrides/typography.js +0 -13
- package/src/@core/theme/palette/index.js +0 -107
- package/src/@core/theme/shadows/index.js +0 -61
- package/src/@core/theme/shadows.js +0 -12
- package/src/@core/theme/spacing/index.js +0 -3
- package/src/@core/theme/spacing.js +0 -5
- package/src/@core/theme/typography/index.js +0 -65
- package/src/@core/theme/typography.js +0 -84
- package/src/@core/utils/create-emotion-cache.js +0 -5
- package/src/@core/utils/hex-to-rgba.js +0 -11
- package/src/@core/utils/serverHelpers.js +0 -45
- package/src/@menu/components/RouterLink.jsx +0 -18
- package/src/@menu/components/horizontal-menu/HorizontalNav.jsx +0 -88
- package/src/@menu/components/horizontal-menu/Menu.jsx +0 -83
- package/src/@menu/components/horizontal-menu/MenuButton.jsx +0 -100
- package/src/@menu/components/horizontal-menu/MenuItem.jsx +0 -183
- package/src/@menu/components/horizontal-menu/SubMenu.jsx +0 -418
- package/src/@menu/components/horizontal-menu/SubMenuContent.jsx +0 -41
- package/src/@menu/components/horizontal-menu/VerticalNavInHorizontal.jsx +0 -20
- package/src/@menu/components/vertical-menu/Menu.jsx +0 -161
- package/src/@menu/components/vertical-menu/MenuButton.jsx +0 -95
- package/src/@menu/components/vertical-menu/MenuItem.jsx +0 -180
- package/src/@menu/components/vertical-menu/MenuSection.jsx +0 -124
- package/src/@menu/components/vertical-menu/NavCollapseIcons.jsx +0 -70
- package/src/@menu/components/vertical-menu/NavHeader.jsx +0 -39
- package/src/@menu/components/vertical-menu/SubMenu.jsx +0 -420
- package/src/@menu/components/vertical-menu/SubMenuContent.jsx +0 -101
- package/src/@menu/components/vertical-menu/VerticalNav.jsx +0 -216
- package/src/@menu/contexts/horizontalNavContext.jsx +0 -29
- package/src/@menu/contexts/verticalNavContext.jsx +0 -65
- package/src/@menu/defaultConfigs.js +0 -12
- package/src/@menu/hooks/useHorizontalMenu.jsx +0 -19
- package/src/@menu/hooks/useHorizontalNav.jsx +0 -19
- package/src/@menu/hooks/useMediaQuery.jsx +0 -29
- package/src/@menu/hooks/useVerticalMenu.jsx +0 -19
- package/src/@menu/hooks/useVerticalNav.jsx +0 -19
- package/src/@menu/horizontal-menu/index.jsx +0 -8
- package/src/@menu/styles/StyledBackdrop.jsx +0 -15
- package/src/@menu/styles/StyledMenuIcon.jsx +0 -12
- package/src/@menu/styles/StyledMenuLabel.jsx +0 -16
- package/src/@menu/styles/StyledMenuPrefix.jsx +0 -10
- package/src/@menu/styles/StyledMenuSectionLabel.jsx +0 -21
- package/src/@menu/styles/StyledMenuSuffix.jsx +0 -10
- package/src/@menu/styles/StyledSubMenuContent.jsx +0 -43
- package/src/@menu/styles/horizontal/StyledHorizontalMenu.jsx +0 -13
- package/src/@menu/styles/horizontal/StyledHorizontalMenuItem.jsx +0 -26
- package/src/@menu/styles/horizontal/StyledHorizontalNav.jsx +0 -11
- package/src/@menu/styles/horizontal/StyledHorizontalNavExpandIcon.jsx +0 -33
- package/src/@menu/styles/horizontal/StyledHorizontalSubMenuContent.jsx +0 -18
- package/src/@menu/styles/horizontal/StyledHorizontalSubMenuContentWrapper.jsx +0 -10
- package/src/@menu/styles/horizontal/horizontalUl.module.css +0 -15
- package/src/@menu/styles/styles.module.css +0 -5
- package/src/@menu/styles/vertical/StyledVerticalMenu.jsx +0 -16
- package/src/@menu/styles/vertical/StyledVerticalMenuItem.jsx +0 -28
- package/src/@menu/styles/vertical/StyledVerticalMenuSection.jsx +0 -23
- package/src/@menu/styles/vertical/StyledVerticalNav.jsx +0 -67
- package/src/@menu/styles/vertical/StyledVerticalNavBgColorContainer.jsx +0 -15
- package/src/@menu/styles/vertical/StyledVerticalNavContainer.jsx +0 -23
- package/src/@menu/styles/vertical/StyledVerticalNavExpandIcon.jsx +0 -25
- package/src/@menu/styles/vertical/verticalNavBgImage.module.css +0 -10
- package/src/@menu/svg/ChevronRight.jsx +0 -9
- package/src/@menu/svg/Close.jsx +0 -12
- package/src/@menu/svg/RadioCircle.jsx +0 -12
- package/src/@menu/svg/RadioCircleMarked.jsx +0 -13
- package/src/@menu/utils/menuClasses.js +0 -44
- package/src/@menu/utils/menuUtils.jsx +0 -145
- package/src/@menu/vertical-menu/index.jsx +0 -11
- package/src/configs/acl.js +0 -115
- package/src/configs/auth.js +0 -5
- package/src/configs/aws-exports.js +0 -30
- package/src/configs/firebase.js +0 -25
- package/src/configs/i18n.js +0 -34
- package/src/configs/primaryColorConfig.js +0 -35
- package/src/configs/themeConfig.js +0 -44
- package/src/layouts/UserLayout.js +0 -94
- package/src/layouts/UserThemeOptions.js +0 -191
- package/src/layouts/components/Direction.js +0 -30
- package/src/layouts/components/HtmlTooltip.js +0 -15
- package/src/layouts/components/Translations.js +0 -11
- package/src/layouts/components/UserDropdown.js +0 -217
- package/src/layouts/components/UserIcon.js +0 -40
- package/src/layouts/components/acl/Can.js +0 -6
- package/src/layouts/components/acl/CanViewNavGroup.js +0 -36
- package/src/layouts/components/acl/CanViewNavLink.js +0 -17
- package/src/layouts/components/acl/CanViewNavSectionTitle.js +0 -17
- package/src/layouts/components/horizontal/AppBarContent.js +0 -39
- package/src/layouts/components/horizontal/ServerSideNavItems.js +0 -44
- package/src/layouts/components/mui/StepperComps.js +0 -55
- package/src/layouts/components/vertical/AppBarContent.js +0 -35
- package/src/layouts/components/vertical/ServerSideNavItems.js +0 -44
- package/src/libs/ApexCharts.jsx +0 -5
- package/src/libs/ReactPlayer.jsx +0 -5
- package/src/libs/Recharts.jsx +0 -4
- package/src/libs/auth.js +0 -124
- package/src/libs/styles/AppFullCalendar.js +0 -505
- package/src/libs/styles/AppKeenSlider.js +0 -116
- package/src/libs/styles/AppReactApexCharts.jsx +0 -110
- package/src/libs/styles/AppReactDatepicker.jsx +0 -470
- package/src/libs/styles/AppReactDropzone.js +0 -76
- package/src/libs/styles/AppReactToastify.jsx +0 -108
- package/src/libs/styles/AppRecharts.js +0 -55
- package/src/libs/styles/inputOtp.module.css +0 -39
- package/src/libs/styles/tiptapEditor.css +0 -72
- package/src/navigation/horizontal/index.js +0 -246
- package/src/navigation/vertical/index.js +0 -253
- package/src/pages/401.js +0 -70
- package/src/pages/404.js +0 -67
- package/src/pages/500.js +0 -68
- package/src/pages/[slug].js +0 -115
- package/src/pages/_document.js +0 -72
- package/src/pages/api/navigation/regenerate-registry.js +0 -116
- package/src/pages/api/navigation/save.js +0 -218
- package/src/pages/authModule/acl/index.js +0 -48
- package/src/pages/authModule/forgot-password/index.js +0 -228
- package/src/pages/authModule/permissions/rolePermissions/[id]/rolePermissionsUser/index.js +0 -392
- package/src/pages/authModule/permissions/rolePermissions/index.js +0 -343
- package/src/pages/authModule/permissions/systemPermissions/index.js +0 -354
- package/src/pages/authModule/privacy/index.js +0 -721
- package/src/pages/authModule/users/index.js +0 -210
- package/src/pages/login/index.js +0 -328
- package/src/pages/mainHome/index.js +0 -181
- package/src/views/builder/inspector/definitions/cell/main.js +0 -4
- package/src/views/builder/inspector/definitions/column/main.js +0 -9
- package/src/views/builder/inspector/definitions/column-group/main.js +0 -18
- package/src/views/builder/inspector/definitions/header-cell/main.js +0 -5
- package/src/views/builder/inspector/definitions/table/main.js +0 -9
- package/src/views/builder/viewer/renderers/CellRenderer.jsx +0 -71
- package/src/views/builder/viewer/renderers/ColumnGroupRenderer.jsx +0 -96
- package/src/views/builder/viewer/renderers/ColumnRenderer.jsx +0 -71
- package/src/views/builder/viewer/renderers/HeaderCellRenderer.jsx +0 -78
- package/src/views/builder/viewer/renderers/TabRenderer.jsx +0 -82
- package/src/views/builder/viewer/renderers/TableRenderer.jsx +0 -92
- package/src/views/pages/auth/FooterIllustrationsV2.js +0 -40
- package/src/views/pages/misc/FooterIllustrations.js +0 -47
- package/src/views/pages/misc/muiTable/CustomPagination.js +0 -34
- package/src/views/pages/users/UserManageDialog.js +0 -283
- package/src/views/pages/users/UserViewPage.js +0 -199
- package/src/views/users/AddUserNameDialog.js +0 -162
- package/src/views/users/ContactManage.js +0 -449
- 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 = '/
|
|
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
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
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
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
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
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
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
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
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
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
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
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
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
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
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
|
-
|
|
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: '
|
|
2622
|
-
icon: '<span class="ag-icon ag-icon-
|
|
3007
|
+
name: 'Clone Update Ref (Backup)',
|
|
3008
|
+
icon: '<span class="ag-icon ag-icon-copy" unselectable="on" role="presentation"></span>',
|
|
2623
3009
|
action: () => {
|
|
2624
|
-
|
|
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
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
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
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
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
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
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
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
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 (
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
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
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
params.
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
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 =>
|
|
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={
|
|
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
|
|