@solidstarters/solid-core-ui 1.1.211 → 1.1.212
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Svg/DevDocs.tsx +9 -0
- package/dist/components/Svg/DocsSvg.tsx +9 -0
- package/dist/components/Svg/ExcelSvg.tsx +15 -0
- package/dist/components/Svg/FieldSvg.tsx +9 -0
- package/dist/components/Svg/FileSvg.tsx +18 -0
- package/dist/components/Svg/HomePageModuleSvg.tsx +179 -0
- package/dist/components/Svg/ModelSvg.tsx +9 -0
- package/dist/components/Svg/ModuleSvg.tsx +9 -0
- package/dist/components/Svg/PDFSvg.tsx +15 -0
- package/dist/components/Svg/RightArrowSvg.tsx +9 -0
- package/dist/components/Svg/SettingsSvg.tsx +9 -0
- package/dist/components/auth/AuthLayout.tsx +223 -0
- package/dist/components/auth/ForgotPasswordThankYou.tsx +33 -0
- package/dist/components/auth/GoogleAuthChecking.tsx +63 -0
- package/dist/components/auth/SolidChangeForcePassword.tsx +222 -0
- package/dist/components/auth/SolidForgotPassword.tsx +127 -0
- package/dist/components/auth/SolidInitialLoginOtp.tsx +271 -0
- package/dist/components/auth/SolidInitiateRegisterOtp.tsx +218 -0
- package/dist/components/auth/SolidLogin.d.ts.map +1 -1
- package/dist/components/auth/SolidLogin.js +14 -8
- package/dist/components/auth/SolidLogin.js.map +1 -1
- package/dist/components/auth/SolidLogin.tsx +428 -0
- package/dist/components/auth/SolidOTPVerify.tsx +133 -0
- package/dist/components/auth/SolidRegister.tsx +454 -0
- package/dist/components/auth/SolidResetPassword.tsx +194 -0
- package/dist/components/common/AuthBanner.tsx +41 -0
- package/dist/components/common/AutoCompleteField.tsx +79 -0
- package/dist/components/common/BackButton.tsx +72 -0
- package/dist/components/common/CancelButton.tsx +61 -0
- package/dist/components/common/CodeEditor.tsx +38 -0
- package/dist/components/common/CreateButton.tsx +17 -0
- package/dist/components/common/DownloadProgressToast.tsx +55 -0
- package/dist/components/common/DropzonePlaceholder.tsx +31 -0
- package/dist/components/common/DropzoneUpload.tsx +11 -0
- package/dist/components/common/FileReaderExt.tsx +20 -0
- package/dist/components/common/GeneralSettings.tsx +1225 -0
- package/dist/components/common/HeaderDynamicTitles.tsx +13 -0
- package/dist/components/common/MarkdownViewer.tsx +84 -0
- package/dist/components/common/MultipleSelectAutoCompleteField.tsx +64 -0
- package/dist/components/common/NotFound.tsx +22 -0
- package/dist/components/common/SingleSelectAutoCompleteField.tsx +73 -0
- package/dist/components/common/SocialMediaLogin.tsx +53 -0
- package/dist/components/common/SolidAdmin.tsx +6 -0
- package/dist/components/common/SolidBreadcrumb.tsx +129 -0
- package/dist/components/common/SolidExport.tsx +563 -0
- package/dist/components/common/SolidExportStepper.tsx +135 -0
- package/dist/components/common/SolidFieldTooltip.tsx +23 -0
- package/dist/components/common/SolidFormHeader.tsx +25 -0
- package/dist/components/common/SolidFormStepper.tsx +350 -0
- package/dist/components/common/SolidModuleHome.tsx +128 -0
- package/dist/components/common/SolidPopupContainer.tsx +37 -0
- package/dist/components/common/SolidSettings/LlmSettings/AnthropicProviderComponent.tsx +45 -0
- package/dist/components/common/SolidSettings/LlmSettings/OpenAiProviderComponent.tsx +45 -0
- package/dist/components/common/SolidSettings/SettingDropzoneActivePlaceholder.tsx +20 -0
- package/dist/components/common/SolidSettings/SettingsImageRemoveButton.tsx +15 -0
- package/dist/components/common/SolidSettings/SolidUploadedImage.tsx +16 -0
- package/dist/components/common/SolidThemeLink.tsx +6 -0
- package/dist/components/common/SolidThemeProvider.tsx +44 -0
- package/dist/components/common/StepperArrows/ActiveArrowStep.tsx +18 -0
- package/dist/components/common/StepperArrows/ActiveBeforeStepArrow.tsx +18 -0
- package/dist/components/common/StepperArrows/InactiveStepArrow.tsx +19 -0
- package/dist/components/common/error.tsx +30 -0
- package/dist/components/common/useHandleFormCustomButtonClick.ts +40 -0
- package/dist/components/common/useHandleListCustomButtonClick.ts +42 -0
- package/dist/components/core/chatter/SolidChatter.tsx +248 -0
- package/dist/components/core/chatter/SolidChatterAuditMessage.tsx +35 -0
- package/dist/components/core/chatter/SolidChatterCustomMessage.tsx +46 -0
- package/dist/components/core/chatter/SolidChatterDateDivider.tsx +16 -0
- package/dist/components/core/chatter/SolidChatterHeader.tsx +218 -0
- package/dist/components/core/chatter/SolidChatterMessageBox.tsx +163 -0
- package/dist/components/core/chatter/SolidMessageComposer.tsx +146 -0
- package/dist/components/core/common/AvatarWidget.tsx +55 -0
- package/dist/components/core/common/DateFieldViewComponent.tsx +36 -0
- package/dist/components/core/common/FilterComponent.tsx +458 -0
- package/dist/components/core/common/LoadDynamicJsxComponent.tsx +70 -0
- package/dist/components/core/common/PDFViewer.tsx +117 -0
- package/dist/components/core/common/SolidAccountSettings/SolidAccountSettings.tsx +89 -0
- package/dist/components/core/common/SolidAccountSettings/SolidChangePassword.tsx +188 -0
- package/dist/components/core/common/SolidAccountSettings/SolidNotifications.tsx +139 -0
- package/dist/components/core/common/SolidAccountSettings/SolidPersonalInfo.tsx +311 -0
- package/dist/components/core/common/SolidCreateButton.tsx +48 -0
- package/dist/components/core/common/SolidGenericImport/DocumentSvg.tsx +15 -0
- package/dist/components/core/common/SolidGenericImport/SolidGenericImport.tsx +64 -0
- package/dist/components/core/common/SolidGenericImport/SolidImportDropzone.tsx +125 -0
- package/dist/components/core/common/SolidGenericImport/SolidImportInstructions.tsx +122 -0
- package/dist/components/core/common/SolidGenericImport/SolidImportStepper.tsx +217 -0
- package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.tsx +205 -0
- package/dist/components/core/common/SolidGenericImport/SolidImportTransactionStatus.tsx +158 -0
- package/dist/components/core/common/SolidGenericImport/SolidImportWrapper.tsx +29 -0
- package/dist/components/core/common/SolidGlobalSearchElement.tsx +1470 -0
- package/dist/components/core/common/SolidLayoutViews.tsx +87 -0
- package/dist/components/core/common/SolidListViewOptions.tsx +31 -0
- package/dist/components/core/common/SolidLoaders/SolidCircularLoader.tsx +7 -0
- package/dist/components/core/common/SolidPasswordHelperText.tsx +34 -0
- package/dist/components/core/common/SolidSaveCustomFilterForm.tsx +75 -0
- package/dist/components/core/common/SolidSearchBox.tsx +17 -0
- package/dist/components/core/common/SolidViewLayoutManager.ts +421 -0
- package/dist/components/core/common/SolidXAiIframe.tsx +77 -0
- package/dist/components/core/dashboard/SolidDashboard.tsx +332 -0
- package/dist/components/core/dashboard/SolidDashboardBody.tsx +117 -0
- package/dist/components/core/dashboard/SolidDashboardFilterRequired.tsx +28 -0
- package/dist/components/core/dashboard/SolidDashboardHeader.tsx +10 -0
- package/dist/components/core/dashboard/SolidDashboardLoading.tsx +55 -0
- package/dist/components/core/dashboard/SolidDashboardNotAvailable.tsx +32 -0
- package/dist/components/core/dashboard/SolidDashboardRenderError.tsx +29 -0
- package/dist/components/core/dashboard/SolidDashboardVariable.tsx +256 -0
- package/dist/components/core/dashboard/SolidQuestionRenderer.tsx +78 -0
- package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.tsx +18 -0
- package/dist/components/core/dashboard/chart-renderers/PrimeReactDatatableRenderer.tsx +54 -0
- package/dist/components/core/dashboard/chart-renderers/init-chartjs.ts +25 -0
- package/dist/components/core/dashboard/dashboard-utils.ts +39 -0
- package/dist/components/core/extension/solid-core/CustomIcon/StatusIcon.tsx +17 -0
- package/dist/components/core/extension/solid-core/dashboardQuestion/ChartFormPreviewWidget.tsx +36 -0
- package/dist/components/core/extension/solid-core/emailTemplate/emailFormTypeChangeHandler.ts +18 -0
- package/dist/components/core/extension/solid-core/emailTemplate/emailFormTypeLoad.ts +18 -0
- package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.tsx +114 -0
- package/dist/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction.tsx +213 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/DeleteModuleRowAction.tsx +138 -0
- package/dist/components/core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction.tsx +209 -0
- package/dist/components/core/extension/solid-core/roleMetadata/RolePermissionsManyToManyFieldWidget.tsx +131 -0
- package/dist/components/core/field/FieldListViewData.tsx +313 -0
- package/dist/components/core/filter/SolidBooleanFilterElement.tsx +30 -0
- package/dist/components/core/filter/SolidFilterFields.tsx +131 -0
- package/dist/components/core/filter/SolidManyToManyFilterElement.tsx +64 -0
- package/dist/components/core/filter/SolidManyToOneFilterElement.tsx +61 -0
- package/dist/components/core/filter/SolidSelectionDynamicFilterElement.tsx +50 -0
- package/dist/components/core/filter/SolidSelectionStaticFilterElement.tsx +32 -0
- package/dist/components/core/filter/SolidVarInputsFilterElement.tsx +209 -0
- package/dist/components/core/filter/fields/SolidBigintField.tsx +9 -0
- package/dist/components/core/filter/fields/SolidBooleanField.tsx +68 -0
- package/dist/components/core/filter/fields/SolidComputedField.tsx +23 -0
- package/dist/components/core/filter/fields/SolidDateField.tsx +63 -0
- package/dist/components/core/filter/fields/SolidDatetimeField.tsx +54 -0
- package/dist/components/core/filter/fields/SolidDecimalField.tsx +9 -0
- package/dist/components/core/filter/fields/SolidExternalIdField.tsx +52 -0
- package/dist/components/core/filter/fields/SolidFloatField.tsx +9 -0
- package/dist/components/core/filter/fields/SolidIdField.tsx +46 -0
- package/dist/components/core/filter/fields/SolidIntField.tsx +61 -0
- package/dist/components/core/filter/fields/SolidLongTextField.tsx +9 -0
- package/dist/components/core/filter/fields/SolidMediaMultipleField.tsx +60 -0
- package/dist/components/core/filter/fields/SolidMediaSingleField.tsx +62 -0
- package/dist/components/core/filter/fields/SolidRelationField.tsx +17 -0
- package/dist/components/core/filter/fields/SolidRichTextField.tsx +9 -0
- package/dist/components/core/filter/fields/SolidSelectionDynamicField.tsx +52 -0
- package/dist/components/core/filter/fields/SolidSelectionStaticField.tsx +54 -0
- package/dist/components/core/filter/fields/SolidShortTextField.tsx +60 -0
- package/dist/components/core/filter/fields/SolidTimeField.tsx +48 -0
- package/dist/components/core/filter/fields/SolidUuidField.tsx +51 -0
- package/dist/components/core/filter/fields/relations/SolidRelationManyToManyField.tsx +62 -0
- package/dist/components/core/filter/fields/relations/SolidRelationManyToOneField.tsx +84 -0
- package/dist/components/core/form/SolidFormActionHeader.tsx +497 -0
- package/dist/components/core/form/SolidFormFieldRender.tsx +53 -0
- package/dist/components/core/form/SolidFormFieldRenderExtension.tsx +26 -0
- package/dist/components/core/form/SolidFormFooter.tsx +162 -0
- package/dist/components/core/form/SolidFormLayouts.tsx +104 -0
- package/dist/components/core/form/SolidFormUserViewLayout.tsx +84 -0
- package/dist/components/core/form/SolidFormView.tsx +1856 -0
- package/dist/components/core/form/SolidFormViewContextMenuHeaderButton.tsx +52 -0
- package/dist/components/core/form/SolidFormViewNormalHeaderButton.tsx +52 -0
- package/dist/components/core/form/SolidFormViewShimmerLoading.tsx +109 -0
- package/dist/components/core/form/fields/ISolidField.tsx +71 -0
- package/dist/components/core/form/fields/SolidBooleanField.tsx +434 -0
- package/dist/components/core/form/fields/SolidDateField.tsx +247 -0
- package/dist/components/core/form/fields/SolidDateTimeField.tsx +229 -0
- package/dist/components/core/form/fields/SolidDecimalField.tsx +171 -0
- package/dist/components/core/form/fields/SolidEmailField.tsx +176 -0
- package/dist/components/core/form/fields/SolidIntegerField.tsx +282 -0
- package/dist/components/core/form/fields/SolidJsonField.tsx +185 -0
- package/dist/components/core/form/fields/SolidLongTextField.tsx +618 -0
- package/dist/components/core/form/fields/SolidMediaMultipleField.tsx +663 -0
- package/dist/components/core/form/fields/SolidMediaSingleField.tsx +547 -0
- package/dist/components/core/form/fields/SolidPasswordField.tsx +390 -0
- package/dist/components/core/form/fields/SolidRelationField.tsx +56 -0
- package/dist/components/core/form/fields/SolidRichTextField.tsx +188 -0
- package/dist/components/core/form/fields/SolidSelectionDynamicField.tsx +340 -0
- package/dist/components/core/form/fields/SolidSelectionStaticField.tsx +462 -0
- package/dist/components/core/form/fields/SolidShortTextField.tsx +399 -0
- package/dist/components/core/form/fields/SolidTimeField.tsx +245 -0
- package/dist/components/core/form/fields/relations/SolidRelationManyToManyField.tsx +453 -0
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.tsx +1036 -0
- package/dist/components/core/form/fields/relations/SolidRelationOneToManyField.tsx +627 -0
- package/dist/components/core/form/fields/relations/widgets/helpers/InlineRelationEntityDialog.tsx +38 -0
- package/dist/components/core/form/fields/relations/widgets/helpers/useRelationEntityHandler.ts +64 -0
- package/dist/components/core/form/fields/widgets/SolidAiInteractionMessageFieldFormWidget.tsx +135 -0
- package/dist/components/core/form/fields/widgets/SolidAiInteractionMetadataFieldFormWidget.tsx +144 -0
- package/dist/components/core/form/fields/widgets/SolidIconEditWidget.tsx +265 -0
- package/dist/components/core/form/fields/widgets/SolidIconViewWidget.tsx +32 -0
- package/dist/components/core/form/fields/widgets/SolidRelationFieldAvatarFormWidget.tsx +50 -0
- package/dist/components/core/form/fields/widgets/SolidS3FileViewerWidget.tsx +222 -0
- package/dist/components/core/form/fields/widgets/SolidShortTextFieldAvatarWidget.tsx +70 -0
- package/dist/components/core/form/widgets/CustomHtml.tsx +20 -0
- package/dist/components/core/kanban/KanbanBoard.tsx +150 -0
- package/dist/components/core/kanban/KanbanCard.tsx +279 -0
- package/dist/components/core/kanban/KanbanColumn.tsx +139 -0
- package/dist/components/core/kanban/KanbanUserViewLayout.tsx +84 -0
- package/dist/components/core/kanban/SolidKanbanView.tsx +894 -0
- package/dist/components/core/kanban/SolidKanbanViewConfigure.tsx +154 -0
- package/dist/components/core/kanban/SolidKanbanViewFields.tsx +164 -0
- package/dist/components/core/kanban/SolidManyToOneFilterElement.tsx +59 -0
- package/dist/components/core/kanban/SolidSelectionDynamicFilterElement.tsx +50 -0
- package/dist/components/core/kanban/SolidSelectionStaticFilterElement.tsx +32 -0
- package/dist/components/core/kanban/SolidVarInputsFilterElement.tsx +184 -0
- package/dist/components/core/kanban/kanban-fields/SolidBigintKanbanField.tsx +9 -0
- package/dist/components/core/kanban/kanban-fields/SolidBooleanKanbanField.tsx +16 -0
- package/dist/components/core/kanban/kanban-fields/SolidComputedKanbanField.tsx +23 -0
- package/dist/components/core/kanban/kanban-fields/SolidDateKanbanField.tsx +14 -0
- package/dist/components/core/kanban/kanban-fields/SolidDatetimeKanbanField.tsx +13 -0
- package/dist/components/core/kanban/kanban-fields/SolidDecimalKanbanField.tsx +9 -0
- package/dist/components/core/kanban/kanban-fields/SolidExternalIdKanbanField.tsx +12 -0
- package/dist/components/core/kanban/kanban-fields/SolidFloatKanbanField.tsx +9 -0
- package/dist/components/core/kanban/kanban-fields/SolidIdKanbanField.tsx +14 -0
- package/dist/components/core/kanban/kanban-fields/SolidIntKanbanField.tsx +20 -0
- package/dist/components/core/kanban/kanban-fields/SolidLongTextKanbanField.tsx +9 -0
- package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.tsx +140 -0
- package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.tsx +164 -0
- package/dist/components/core/kanban/kanban-fields/SolidRelationKanbanField.tsx +13 -0
- package/dist/components/core/kanban/kanban-fields/SolidRichTextKanbanField.tsx +9 -0
- package/dist/components/core/kanban/kanban-fields/SolidSelectionDynamicKanbanField.tsx +14 -0
- package/dist/components/core/kanban/kanban-fields/SolidSelectionStaticKanbanField.tsx +14 -0
- package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.tsx +121 -0
- package/dist/components/core/kanban/kanban-fields/SolidTimeKanbanField.tsx +12 -0
- package/dist/components/core/kanban/kanban-fields/SolidUuidKanbanField.tsx +13 -0
- package/dist/components/core/kanban/kanban-fields/relations/SolidRelationManyToOneKanbanField.tsx +16 -0
- package/dist/components/core/list/ListViewRowActionPopup.tsx +41 -0
- package/dist/components/core/list/SolidColumnSelector/SolidListColumnSelector.tsx +242 -0
- package/dist/components/core/list/SolidEmptyListViewPlaceholder.tsx +111 -0
- package/dist/components/core/list/SolidListView.tsx +2007 -0
- package/dist/components/core/list/SolidListViewColumn.tsx +165 -0
- package/dist/components/core/list/SolidListViewConfigure.tsx +339 -0
- package/dist/components/core/list/SolidListViewHeaderButton.tsx +31 -0
- package/dist/components/core/list/SolidListViewHeaderContextMenuButton.tsx +30 -0
- package/dist/components/core/list/SolidListViewRowButtonContextMenu.tsx +41 -0
- package/dist/components/core/list/SolidListViewShimmerLoading.tsx +78 -0
- package/dist/components/core/list/SolidListingHeader.tsx +42 -0
- package/dist/components/core/list/SolidManyToOneFilterElement.tsx +60 -0
- package/dist/components/core/list/SolidSelectionDynamicFilterElement.tsx +50 -0
- package/dist/components/core/list/SolidSelectionStaticFilterElement.tsx +32 -0
- package/dist/components/core/list/SolidTableRowCell.tsx +35 -0
- package/dist/components/core/list/SolidVarInputsFilterElement.tsx +184 -0
- package/dist/components/core/list/columns/SolidBigintColumn.tsx +9 -0
- package/dist/components/core/list/columns/SolidBooleanColumn.tsx +90 -0
- package/dist/components/core/list/columns/SolidComputedColumn.tsx +27 -0
- package/dist/components/core/list/columns/SolidDateColumn.tsx +90 -0
- package/dist/components/core/list/columns/SolidDatetimeColumn.tsx +79 -0
- package/dist/components/core/list/columns/SolidDecimalColumn.tsx +9 -0
- package/dist/components/core/list/columns/SolidExternalIdColumn.tsx +80 -0
- package/dist/components/core/list/columns/SolidFloatColumn.tsx +9 -0
- package/dist/components/core/list/columns/SolidIdColumn.tsx +79 -0
- package/dist/components/core/list/columns/SolidIntColumn.tsx +87 -0
- package/dist/components/core/list/columns/SolidLongTextColumn.tsx +9 -0
- package/dist/components/core/list/columns/SolidMediaMultipleColumn.tsx +301 -0
- package/dist/components/core/list/columns/SolidMediaSingleColumn.tsx +170 -0
- package/dist/components/core/list/columns/SolidRelationColumn.tsx +21 -0
- package/dist/components/core/list/columns/SolidRichTextColumn.tsx +9 -0
- package/dist/components/core/list/columns/SolidSelectionDynamicColumn.tsx +80 -0
- package/dist/components/core/list/columns/SolidSelectionStaticColumn.tsx +81 -0
- package/dist/components/core/list/columns/SolidShortTextColumn.tsx +160 -0
- package/dist/components/core/list/columns/SolidTimeColumn.tsx +78 -0
- package/dist/components/core/list/columns/SolidUuidColumn.tsx +79 -0
- package/dist/components/core/list/columns/relations/SolidRelationManyToManyColumn.tsx +106 -0
- package/dist/components/core/list/columns/relations/SolidRelationManyToOneColumn.tsx +117 -0
- package/dist/components/core/list/columns/relations/SolidRelationOneToManyColumn.tsx +110 -0
- package/dist/components/core/list/widgets/SolidManyToManyRelationAvatarListWidget.tsx +30 -0
- package/dist/components/core/list/widgets/SolidManyToOneRelationAvatarListWidget.tsx +30 -0
- package/dist/components/core/list/widgets/SolidShortTextAvatarWidget.tsx +70 -0
- package/dist/components/core/list/widgets/SolidShortTextFieldImageRenderModeWidget.tsx +21 -0
- package/dist/components/core/locales/SolidChatterLocaleTabView.tsx +91 -0
- package/dist/components/core/locales/SolidLocale.tsx +127 -0
- package/dist/components/core/model/CreateModel.tsx +495 -0
- package/dist/components/core/model/FieldMetaData.tsx +263 -0
- package/dist/components/core/model/FieldMetaDataForm.tsx +3509 -0
- package/dist/components/core/model/FieldSelector.tsx +62 -0
- package/dist/components/core/model/ModelListViewData.tsx +384 -0
- package/dist/components/core/model/ModelMetaData.tsx +921 -0
- package/dist/components/core/module/CreateModule.tsx +617 -0
- package/dist/components/core/module/ModuleListViewData.tsx +431 -0
- package/dist/components/core/solid-ai/SolidAiMainWrapper.tsx +8 -0
- package/dist/components/core/solid-ai/SolidXAIIcon.tsx +37 -0
- package/dist/components/core/users/CreateUser.tsx +467 -0
- package/dist/components/core/users/CreateUserRole.tsx +212 -0
- package/dist/components/core/users/UserListView.tsx +376 -0
- package/dist/components/layout/AdminLayout.tsx +57 -0
- package/dist/components/layout/AdminSidebar.tsx +65 -0
- package/dist/components/layout/AppConfig.tsx +104 -0
- package/dist/components/layout/AppSidebar.tsx +232 -0
- package/dist/components/layout/ButtonLoader.tsx +7 -0
- package/dist/components/layout/CustomPagination.tsx +55 -0
- package/dist/components/layout/DashboardHeader.tsx +89 -0
- package/dist/components/layout/FilterMenu.tsx +122 -0
- package/dist/components/layout/Footer.tsx +13 -0
- package/dist/components/layout/GlobalSearch.tsx +37 -0
- package/dist/components/layout/Header.tsx +8 -0
- package/dist/components/layout/Layout.tsx +205 -0
- package/dist/components/layout/ListingHeader.tsx +204 -0
- package/dist/components/layout/Loader.tsx +16 -0
- package/dist/components/layout/UserSidebar.tsx +53 -0
- package/dist/components/layout/context/layoutcontext.tsx +52 -0
- package/dist/components/layout/navbar-one.tsx +258 -0
- package/dist/components/layout/navbar-two-menu.tsx +72 -0
- package/dist/components/layout/navbar-two.tsx +37 -0
- package/dist/components/layout/user-profile-menu.tsx +213 -0
- package/dist/components/layout/user-profile.tsx +7 -0
- package/dist/components/modelsComponents/filterIcon.tsx +9 -0
- package/dist/constants/error-messages.ts +238 -0
- package/dist/declarations.d.ts +22 -0
- package/dist/helpers/AppTitle.tsx +12 -0
- package/dist/helpers/ToastContainer.tsx +94 -0
- package/dist/helpers/autoCompleteVirtualScroll.ts +41 -0
- package/dist/helpers/countries.tsx +260 -0
- package/dist/helpers/downloadFileWithProgress.ts +91 -0
- package/dist/helpers/downloadMediaFile.tsx +21 -0
- package/dist/helpers/getAcceptedFileTypes.tsx +22 -0
- package/dist/helpers/getRandomColors.tsx +68 -0
- package/dist/helpers/helpers.ts +61 -0
- package/dist/helpers/hydrateRelationRules.ts +120 -0
- package/dist/helpers/permissions.ts +7 -0
- package/dist/helpers/registry.ts +337 -0
- package/dist/helpers/resendOtpHelper.tsx +5 -0
- package/dist/helpers/revalidate.ts +7 -0
- package/dist/helpers/rolesHelper.ts +17 -0
- package/dist/helpers/solidIcons.tsx +1831 -0
- package/dist/helpers/updatePasswordField.ts +41 -0
- package/dist/index.ts +421 -0
- package/dist/nextAuth/authProviders.d.ts.map +1 -1
- package/dist/nextAuth/authProviders.js +6 -5
- package/dist/nextAuth/authProviders.js.map +1 -1
- package/dist/nextAuth/authProviders.tsx +232 -0
- package/dist/nextAuth/handleLogout.tsx +39 -0
- package/dist/nextAuth/refreshAccessToken.tsx +28 -0
- package/dist/redux/api/aiInteractionApi.ts +59 -0
- package/dist/redux/api/authApi.ts +131 -0
- package/dist/redux/api/dashboardApi.ts +56 -0
- package/dist/redux/api/dashboardQuestionApi.ts +17 -0
- package/dist/redux/api/exportTemplateApi.tsx +59 -0
- package/dist/redux/api/fetchBaseQuery.tsx +118 -0
- package/dist/redux/api/fieldApi.ts +86 -0
- package/dist/redux/api/importTransactionApi.tsx +69 -0
- package/dist/redux/api/mediaApi.ts +55 -0
- package/dist/redux/api/mediaStorageProviderApi.ts +55 -0
- package/dist/redux/api/modelApi.ts +80 -0
- package/dist/redux/api/moduleApi.ts +72 -0
- package/dist/redux/api/permissionApi.ts +32 -0
- package/dist/redux/api/pincodeApi.tsx +56 -0
- package/dist/redux/api/roleApi.ts +58 -0
- package/dist/redux/api/solidActionApi.ts +66 -0
- package/dist/redux/api/solidChatterMessageApi.ts +25 -0
- package/dist/redux/api/solidEntityApi.tsx +164 -0
- package/dist/redux/api/solidMenuApi.ts +71 -0
- package/dist/redux/api/solidServiceApi.ts +31 -0
- package/dist/redux/api/solidSettingsApi.tsx +83 -0
- package/dist/redux/api/solidViewApi.ts +73 -0
- package/dist/redux/api/stateApi.tsx +56 -0
- package/dist/redux/api/testApi.ts +21 -0
- package/dist/redux/api/userApi.ts +135 -0
- package/dist/redux/features/authSlice.ts +19 -0
- package/dist/redux/features/dataViewSlice.ts +26 -0
- package/dist/redux/features/navbarSlice.ts +21 -0
- package/dist/redux/features/popupSlice.ts +37 -0
- package/dist/redux/features/settingsSlice.ts +60 -0
- package/dist/redux/features/themeSlice.ts +17 -0
- package/dist/redux/features/userSlice.ts +28 -0
- package/dist/redux/hooks/useSolidPopup.ts +20 -0
- package/dist/redux/store/defaultStoreConfig.ts +62 -0
- package/dist/styles.ts +4 -0
- package/dist/types/handlebars.d.ts +4 -0
- package/dist/types/index.d.ts +76 -0
- package/dist/types/layout.d.ts +94 -0
- package/dist/types/next-auth.d.ts +0 -0
- package/dist/types/next.d.ts +46 -0
- package/dist/types/solid-core.d.ts +320 -0
- package/package.json +1 -1
- package/src/components/auth/SolidLogin.tsx +26 -13
- package/src/nextAuth/authProviders.tsx +9 -5
|
@@ -0,0 +1,1856 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { permissionExpression } from "../../../helpers/permissions";
|
|
4
|
+
import { createSolidEntityApi } from "../../../redux/api/solidEntityApi";
|
|
5
|
+
import { useGetSolidViewLayoutQuery } from "../../../redux/api/solidViewApi";
|
|
6
|
+
import { useLazyCheckIfPermissionExistsQuery } from "../../../redux/api/userApi";
|
|
7
|
+
import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query";
|
|
8
|
+
import { useFormik } from "formik";
|
|
9
|
+
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
|
10
|
+
import "primeflex/primeflex.css";
|
|
11
|
+
import { Button } from "primereact/button";
|
|
12
|
+
import { Dialog } from "primereact/dialog";
|
|
13
|
+
import { TabPanel, TabView } from "primereact/tabview";
|
|
14
|
+
import { Toast } from "primereact/toast";
|
|
15
|
+
import qs from "qs";
|
|
16
|
+
import React, { ChangeEvent, useEffect, useMemo, useRef, useState } from "react";
|
|
17
|
+
import * as Yup from "yup";
|
|
18
|
+
import { FormikObject, ISolidField, SolidFieldProps } from "./fields/ISolidField";
|
|
19
|
+
import { SolidBooleanField } from "./fields/SolidBooleanField";
|
|
20
|
+
import { SolidDateField } from "./fields/SolidDateField";
|
|
21
|
+
import { SolidDateTimeField } from "./fields/SolidDateTimeField";
|
|
22
|
+
import { SolidDecimalField } from "./fields/SolidDecimalField";
|
|
23
|
+
import { SolidIntegerField } from "./fields/SolidIntegerField";
|
|
24
|
+
import { SolidJsonField } from "./fields/SolidJsonField";
|
|
25
|
+
import { SolidLongTextField } from "./fields/SolidLongTextField";
|
|
26
|
+
import { SolidMediaMultipleField } from "./fields/SolidMediaMultipleField";
|
|
27
|
+
import { SolidMediaSingleField } from "./fields/SolidMediaSingleField";
|
|
28
|
+
import { SolidRelationField } from "./fields/SolidRelationField";
|
|
29
|
+
import { SolidRichTextField } from "./fields/SolidRichTextField";
|
|
30
|
+
import { SolidSelectionDynamicField } from "./fields/SolidSelectionDynamicField";
|
|
31
|
+
import { SolidSelectionStaticField } from "./fields/SolidSelectionStaticField";
|
|
32
|
+
import { SolidShortTextField } from "./fields/SolidShortTextField";
|
|
33
|
+
import { SolidTimeField } from "./fields/SolidTimeField";
|
|
34
|
+
import { SolidUiEvent } from "../../../types";
|
|
35
|
+
import { getExtensionComponent, getExtensionFunction } from "../../../helpers/registry";
|
|
36
|
+
import { SolidFormWidgetProps, SolidLoadForm, SolidUiEventResponse } from "../../../types/solid-core";
|
|
37
|
+
import { SolidPasswordField } from "./fields/SolidPasswordField";
|
|
38
|
+
import { SolidEmailField } from "./fields/SolidEmailField";
|
|
39
|
+
import { Panel } from "primereact/panel";
|
|
40
|
+
import { SolidFormUserViewLayout } from "./SolidFormUserViewLayout";
|
|
41
|
+
import Lightbox from "yet-another-react-lightbox";
|
|
42
|
+
import Counter from "yet-another-react-lightbox/plugins/counter";
|
|
43
|
+
import Download from "yet-another-react-lightbox/plugins/download";
|
|
44
|
+
import Video from "yet-another-react-lightbox/plugins/video";
|
|
45
|
+
import "yet-another-react-lightbox/styles.css";
|
|
46
|
+
import "yet-another-react-lightbox/plugins/counter.css";
|
|
47
|
+
import { SolidFormActionHeader } from "./SolidFormActionHeader";
|
|
48
|
+
import { SolidFormViewShimmerLoading } from "./SolidFormViewShimmerLoading";
|
|
49
|
+
import { useSelector } from "react-redux";
|
|
50
|
+
import { hasAnyRole } from "../../../helpers/rolesHelper";
|
|
51
|
+
import SolidChatterLocaleTabView from "../locales/SolidChatterLocaleTabView";
|
|
52
|
+
import { ConfirmDialog } from "primereact/confirmdialog";
|
|
53
|
+
import { SolidXAIIcon } from "../solid-ai/SolidXAIIcon";
|
|
54
|
+
import { ERROR_MESSAGES } from "../../../constants/error-messages";
|
|
55
|
+
import { useLazyGetMcpUrlQuery, useLazyGetSolidSettingsQuery } from "../../../redux/api/solidSettingsApi";
|
|
56
|
+
import { SolidFormFooter } from "./SolidFormFooter";
|
|
57
|
+
|
|
58
|
+
export type SolidFormViewProps = {
|
|
59
|
+
moduleName: string;
|
|
60
|
+
modelName: string;
|
|
61
|
+
id: string;
|
|
62
|
+
embeded: boolean;
|
|
63
|
+
handlePopupClose?: any,
|
|
64
|
+
customCreateHandler?: any
|
|
65
|
+
inlineCreateAutoSave?: boolean,
|
|
66
|
+
customLayout?: any,
|
|
67
|
+
parentData?: any,
|
|
68
|
+
redirectToPath?: string,
|
|
69
|
+
onEmbeddedFormSave?: () => void,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
interface ErrorResponseData {
|
|
74
|
+
message: string;
|
|
75
|
+
statusCode: number;
|
|
76
|
+
error: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const getLayoutFields = (node: any): any => {
|
|
80
|
+
let fields = [];
|
|
81
|
+
|
|
82
|
+
if (node.type === "field") {
|
|
83
|
+
fields.push(node);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (node.children && Array.isArray(node.children)) {
|
|
87
|
+
for (const child of node.children) {
|
|
88
|
+
fields = fields.concat(getLayoutFields(child));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return fields;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export const getLayoutFieldsAsObject = (layout: any[]): any => {
|
|
96
|
+
const allFields = layout.flatMap(getLayoutFields);
|
|
97
|
+
return allFields.reduce((result, field) => {
|
|
98
|
+
if (field.attrs.name) {
|
|
99
|
+
result[field.attrs.name] = { ...field };
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}, {});
|
|
103
|
+
}
|
|
104
|
+
export const getActualFieldMetadata = (key: string, solidFieldsMetadata: Record<string, any>) => {
|
|
105
|
+
if (solidFieldsMetadata[key]) {
|
|
106
|
+
return solidFieldsMetadata[key];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (key.endsWith("Confirm")) {
|
|
110
|
+
const baseKey = key.slice(0, -"Confirm".length); // Remove "Confirm"
|
|
111
|
+
if (solidFieldsMetadata[baseKey]) {
|
|
112
|
+
return solidFieldsMetadata[baseKey];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return null; // or handle fallback
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
const fieldFactory = (type: string, fieldContext: SolidFieldProps, setLightboxUrls?: any, setOpenLightbox?: any): ISolidField | null => {
|
|
121
|
+
if (type === 'shortText') {
|
|
122
|
+
return new SolidShortTextField(fieldContext);
|
|
123
|
+
}
|
|
124
|
+
if (type === 'longText') {
|
|
125
|
+
return new SolidLongTextField(fieldContext);
|
|
126
|
+
}
|
|
127
|
+
if (type === 'int' || type === 'bigint') {
|
|
128
|
+
return new SolidIntegerField(fieldContext);
|
|
129
|
+
}
|
|
130
|
+
if (type === 'decimal' || type === 'float') {
|
|
131
|
+
return new SolidDecimalField(fieldContext);
|
|
132
|
+
}
|
|
133
|
+
if (type === 'boolean') {
|
|
134
|
+
return new SolidBooleanField(fieldContext);
|
|
135
|
+
}
|
|
136
|
+
if (type === 'richText') {
|
|
137
|
+
return new SolidRichTextField(fieldContext);
|
|
138
|
+
}
|
|
139
|
+
if (type === 'date') {
|
|
140
|
+
return new SolidDateField(fieldContext);
|
|
141
|
+
}
|
|
142
|
+
if (type === 'datetime') {
|
|
143
|
+
return new SolidDateTimeField(fieldContext);
|
|
144
|
+
}
|
|
145
|
+
if (type === 'time') {
|
|
146
|
+
return new SolidTimeField(fieldContext);
|
|
147
|
+
}
|
|
148
|
+
if (type === 'json') {
|
|
149
|
+
return new SolidJsonField(fieldContext);
|
|
150
|
+
}
|
|
151
|
+
if (type === 'selectionStatic') {
|
|
152
|
+
return new SolidSelectionStaticField(fieldContext);
|
|
153
|
+
}
|
|
154
|
+
if (type === 'selectionDynamic') {
|
|
155
|
+
return new SolidSelectionDynamicField(fieldContext);
|
|
156
|
+
}
|
|
157
|
+
if (type === 'relation') {
|
|
158
|
+
return new SolidRelationField(fieldContext);
|
|
159
|
+
}
|
|
160
|
+
if (type === 'mediaSingle') {
|
|
161
|
+
return new SolidMediaSingleField(fieldContext, setLightboxUrls, setOpenLightbox);
|
|
162
|
+
}
|
|
163
|
+
if (type === 'mediaMultiple') {
|
|
164
|
+
return new SolidMediaMultipleField(fieldContext, setLightboxUrls, setOpenLightbox);
|
|
165
|
+
}
|
|
166
|
+
if (type === 'password') {
|
|
167
|
+
return new SolidPasswordField(fieldContext);
|
|
168
|
+
}
|
|
169
|
+
if (type === 'email') {
|
|
170
|
+
return new SolidEmailField(fieldContext);
|
|
171
|
+
}
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// solidFieldsMetadata={solidFieldsMetadata} solidView={solidView}
|
|
176
|
+
const SolidField = ({ formik, field, fieldMetadata, initialEntityData, solidFormViewMetaData, modelName, readOnly, viewMode, onChange, onBlur, parentData, setLightboxUrls, setOpenLightbox, onEmbeddedFormSave }: any) => {
|
|
177
|
+
const fieldContext: SolidFieldProps = {
|
|
178
|
+
// field metadata - coming from the field-metadata table.
|
|
179
|
+
fieldMetadata: fieldMetadata,
|
|
180
|
+
// field layout - coming from view.layout
|
|
181
|
+
field: field,
|
|
182
|
+
// initial data
|
|
183
|
+
data: initialEntityData,
|
|
184
|
+
// complete form view metadata - this includes layout of the whole form & metadata about all fields in the corresponding model.
|
|
185
|
+
solidFormViewMetaData: solidFormViewMetaData,
|
|
186
|
+
modelName: modelName,
|
|
187
|
+
readOnly: readOnly,
|
|
188
|
+
viewMode: viewMode,
|
|
189
|
+
onChange: onChange,
|
|
190
|
+
onBlur: onBlur
|
|
191
|
+
}
|
|
192
|
+
if (parentData) {
|
|
193
|
+
fieldContext.parentData = parentData;
|
|
194
|
+
}
|
|
195
|
+
if (onEmbeddedFormSave) {
|
|
196
|
+
fieldContext.onEmbeddedFormSave = onEmbeddedFormSave;
|
|
197
|
+
}
|
|
198
|
+
const solidField = fieldFactory(fieldMetadata?.type, fieldContext, setLightboxUrls, setOpenLightbox);
|
|
199
|
+
|
|
200
|
+
return solidField?.render(formik);
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const SolidGroup = ({ children, attrs }: any) => {
|
|
204
|
+
|
|
205
|
+
const className = attrs.className;
|
|
206
|
+
|
|
207
|
+
return (
|
|
208
|
+
<div className={className}>
|
|
209
|
+
{attrs.label && <p>{attrs.label}</p>}
|
|
210
|
+
<div className="grid">{children}</div>
|
|
211
|
+
</div>
|
|
212
|
+
// <div className={className}>
|
|
213
|
+
// <div className="s_group">
|
|
214
|
+
// <fieldset>
|
|
215
|
+
// {attrs.label && <p className="s_group_heading">{attrs.label}</p>}
|
|
216
|
+
// <div className="grid">{children}</div>
|
|
217
|
+
// </fieldset>
|
|
218
|
+
// </div>
|
|
219
|
+
|
|
220
|
+
// </div>
|
|
221
|
+
// <div className="formgrid grid">
|
|
222
|
+
// {children}
|
|
223
|
+
// </div>
|
|
224
|
+
);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const SolidRow = ({ children, attrs }: any) => {
|
|
228
|
+
|
|
229
|
+
const className = attrs.className;
|
|
230
|
+
|
|
231
|
+
return (
|
|
232
|
+
// <div className={`row ${className}`}>
|
|
233
|
+
|
|
234
|
+
// <div className="s_group">
|
|
235
|
+
// <fieldset>
|
|
236
|
+
// {attrs.label && <p className="s_group_heading">{attrs.label}</p>}
|
|
237
|
+
// <div className="grid">{children}</div>
|
|
238
|
+
// </fieldset>
|
|
239
|
+
// </div>
|
|
240
|
+
|
|
241
|
+
// </div>
|
|
242
|
+
<div className={`row ${className}`}>
|
|
243
|
+
{attrs.label && <p >{attrs.label}</p>}
|
|
244
|
+
<div className="grid">{children}</div>
|
|
245
|
+
</div>
|
|
246
|
+
// <div>{children}</div>
|
|
247
|
+
);
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const SolidColumn = ({ children, attrs }: any) => {
|
|
251
|
+
const className = attrs.className;
|
|
252
|
+
|
|
253
|
+
return (
|
|
254
|
+
// first fieldset ui
|
|
255
|
+
|
|
256
|
+
// <div className={`${className}`}>
|
|
257
|
+
// <div className="s_group">
|
|
258
|
+
// <fieldset>
|
|
259
|
+
// {attrs.label && <p className="s_group_heading">{attrs.label}</p>}
|
|
260
|
+
// <div className="grid">{children}</div>
|
|
261
|
+
// </fieldset>
|
|
262
|
+
// </div>
|
|
263
|
+
// </div>
|
|
264
|
+
|
|
265
|
+
//second fieldset ui
|
|
266
|
+
// <div className={`${className}`}>
|
|
267
|
+
// {attrs.label && <p>{attrs.label}</p>}
|
|
268
|
+
// <div className="grid">{children}</div>
|
|
269
|
+
// </div>
|
|
270
|
+
|
|
271
|
+
//figma fieldset ui
|
|
272
|
+
attrs.label ?
|
|
273
|
+
<div className={`${className}`}>
|
|
274
|
+
<Panel header={attrs.label} className="solid-column-panel">
|
|
275
|
+
<div className="grid">{children}</div>
|
|
276
|
+
</Panel>
|
|
277
|
+
{/* <div className="p-fieldset">
|
|
278
|
+
<div className="solid-fieldset-header">
|
|
279
|
+
<div>{attrs.label}</div>
|
|
280
|
+
</div>
|
|
281
|
+
<div className="grid solid-fieldset-content">{children}</div>
|
|
282
|
+
</div> */}
|
|
283
|
+
</div>
|
|
284
|
+
:
|
|
285
|
+
<div className={`${className}`}>
|
|
286
|
+
<div className="grid">{children}</div>
|
|
287
|
+
</div>
|
|
288
|
+
);
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
const SolidSheet = ({ children }: any) => (
|
|
292
|
+
<div className="p-fluid p-grid">
|
|
293
|
+
{children}
|
|
294
|
+
</div>
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
const SolidNotebook = ({ children, activeTab, embeded }: any) => {
|
|
298
|
+
// const childrenArray = children;
|
|
299
|
+
// const childrenArray = React.Children.toArray(children).filter(Boolean);
|
|
300
|
+
const childrenArray = React.Children.toArray(children).filter(child => !!child);
|
|
301
|
+
|
|
302
|
+
const router = useRouter();
|
|
303
|
+
|
|
304
|
+
// Local state to manage active tab in embedded context
|
|
305
|
+
const [localActiveTab, setLocalActiveTab] = useState(activeTab);
|
|
306
|
+
|
|
307
|
+
const activeIndex = useMemo(() => {
|
|
308
|
+
return childrenArray.findIndex((child: any) => {
|
|
309
|
+
return child.key === (embeded ? localActiveTab : activeTab);
|
|
310
|
+
});
|
|
311
|
+
}, [childrenArray, activeTab, localActiveTab, embeded]);
|
|
312
|
+
|
|
313
|
+
const handleTabChange = (e: any) => {
|
|
314
|
+
const selectedChild = childrenArray[e.index] as any;
|
|
315
|
+
const newTabLabel = selectedChild?.key;
|
|
316
|
+
|
|
317
|
+
if (newTabLabel) {
|
|
318
|
+
if (!embeded) {
|
|
319
|
+
const currentUrl = new URL(window.location.href);
|
|
320
|
+
currentUrl.searchParams.set('activeTab', newTabLabel);
|
|
321
|
+
const updatedPath = currentUrl.toString();
|
|
322
|
+
router.push(updatedPath);
|
|
323
|
+
} else {
|
|
324
|
+
// Update the active tab state locally for embedded view
|
|
325
|
+
setLocalActiveTab(newTabLabel);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
return (
|
|
332
|
+
<div className="solid-tab-view w-full">
|
|
333
|
+
<TabView activeIndex={activeIndex >= 0 ? activeIndex : 0} onTabChange={handleTabChange}>
|
|
334
|
+
{/* {children} */}
|
|
335
|
+
{childrenArray}
|
|
336
|
+
</TabView>
|
|
337
|
+
</div>
|
|
338
|
+
)
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
const SolidDynamicWidget = ({ widgetName, formik, field, solidFormViewMetaData, solidFormViewData }: any) => {
|
|
342
|
+
const solidView = solidFormViewMetaData.data.solidView;
|
|
343
|
+
const solidFieldsMetadata = solidFormViewMetaData.data.solidFieldsMetadata;
|
|
344
|
+
|
|
345
|
+
let DynamicWidget = getExtensionComponent(widgetName);
|
|
346
|
+
|
|
347
|
+
const widgetProps: SolidFormWidgetProps = {
|
|
348
|
+
formData: formik.values,
|
|
349
|
+
field: field,
|
|
350
|
+
fieldsMetadata: solidFieldsMetadata,
|
|
351
|
+
viewMetadata: solidView,
|
|
352
|
+
formViewData: solidFormViewData
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return (
|
|
356
|
+
<div className="solid-tab-view w-full">
|
|
357
|
+
{DynamicWidget && <DynamicWidget {...widgetProps} />}
|
|
358
|
+
</div>
|
|
359
|
+
)
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
const SolidPage = ({ attrs, children, key, formik, fields }: any) => {
|
|
364
|
+
const fieldsName = fields.map((f: any) => f.attrs.name);
|
|
365
|
+
const errorCount = formik.submitCount > 0 ? fieldsName.filter((name: any) => !!formik.errors[name]).length : 0;
|
|
366
|
+
const label = (
|
|
367
|
+
<span style={{ color: errorCount > 0 ? 'red' : 'inherit' }}>
|
|
368
|
+
{attrs.label}{errorCount > 0 && ` (${errorCount})`}
|
|
369
|
+
</span>
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
return (
|
|
374
|
+
|
|
375
|
+
<TabPanel key={key} header={label} >
|
|
376
|
+
<div className="p-fluid">{children}</div>
|
|
377
|
+
</TabPanel>
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
// Original code...
|
|
383
|
+
// const addLevelToGroups = (layout: any, level = 1) => {
|
|
384
|
+
// return layout.map((element: any) => {
|
|
385
|
+
// if (element.type === "group") {
|
|
386
|
+
// // Add the level to the group's attrs
|
|
387
|
+
// element.attrs = {
|
|
388
|
+
// ...element.attrs,
|
|
389
|
+
// level: level, // Add level information to the attrs
|
|
390
|
+
// // className: level === 1 ? 'col-12' : 'col-6', // Assign className based on level
|
|
391
|
+
// };
|
|
392
|
+
// } else {
|
|
393
|
+
// element.children = addLevelToGroups(element.children, level);
|
|
394
|
+
// }
|
|
395
|
+
// // If the element has children, recursively apply this logic
|
|
396
|
+
// // if (element.children) {
|
|
397
|
+
// // element.children = addLevelToGroups(element.children, level + 1);
|
|
398
|
+
// // }
|
|
399
|
+
|
|
400
|
+
// return element;
|
|
401
|
+
// });
|
|
402
|
+
// };
|
|
403
|
+
|
|
404
|
+
// Fix for immutable objects.
|
|
405
|
+
// const addLevelToGroups = (layout: any, level = 1): any[] => {
|
|
406
|
+
// return layout.map((element: any) => {
|
|
407
|
+
// // Create a new object for immutability
|
|
408
|
+
// const updatedElement = { ...element };
|
|
409
|
+
|
|
410
|
+
// if (updatedElement.type === "group") {
|
|
411
|
+
// // Add level to attrs, creating a new object for immutability
|
|
412
|
+
// updatedElement.attrs = {
|
|
413
|
+
// ...updatedElement.attrs,
|
|
414
|
+
// level: level, // Add level information
|
|
415
|
+
// };
|
|
416
|
+
// }
|
|
417
|
+
|
|
418
|
+
// // If the element has children, recursively apply this logic
|
|
419
|
+
// if (updatedElement.children) {
|
|
420
|
+
// updatedElement.children = addLevelToGroups(updatedElement.children, level + 1);
|
|
421
|
+
// }
|
|
422
|
+
|
|
423
|
+
// return updatedElement;
|
|
424
|
+
// });
|
|
425
|
+
// };
|
|
426
|
+
|
|
427
|
+
const SolidFormView = (params: SolidFormViewProps) => {
|
|
428
|
+
const { user } = useSelector((state: any) => state.auth);
|
|
429
|
+
const pathname = usePathname();
|
|
430
|
+
const router = useRouter();
|
|
431
|
+
const toast = useRef<Toast>(null);
|
|
432
|
+
const searchParams = useSearchParams();
|
|
433
|
+
const [confirmVisible, setConfirmVisible] = useState(false);
|
|
434
|
+
const confirmResolveRef = useRef<(value: boolean) => void>();
|
|
435
|
+
const [redirectToList, setRedirectToList] = useState(false);
|
|
436
|
+
const [selectedLocale, setSelectedLocale] = useState<string | null>('en');
|
|
437
|
+
const [defaultEntityLocaleId, setDefaultEntityLocaleId] = useState<string | null>(null);
|
|
438
|
+
const [isDeleteDialogVisible, setDeleteDialogVisible] = useState(false);
|
|
439
|
+
const [isLayoutDialogVisible, setLayoutDialogVisible] = useState(false);
|
|
440
|
+
const [published, setPublished] = useState<string | null>(null);
|
|
441
|
+
const [actionsAllowed, setActionsAllowed] = useState<string[]>([]);
|
|
442
|
+
const [viewMode, setViewMode] = useState<"view" | "edit">(params.embeded === true ? "edit" : "view");
|
|
443
|
+
const [createMode, setCreateMode] = useState<boolean>(false);
|
|
444
|
+
const [openLightbox, setOpenLightbox] = useState(false);
|
|
445
|
+
const [lightboxUrls, setLightboxUrls] = useState([]);
|
|
446
|
+
const [isShowChatter, setShowChatter] = useState(false);
|
|
447
|
+
const [chatterLocaleWidth, setChatterLocaleWidth] = useState(380); // default width
|
|
448
|
+
const [isResizingChatterLocale, setIsResizingChatterLocale] = useState(false);
|
|
449
|
+
|
|
450
|
+
const [solidWorkflowFieldValue, setSolidWorkflowFieldValue] = useState<string>("");
|
|
451
|
+
const [defaultTabViewOptionIndex, setDefaultTabViewOptionIndex] = useState<number>(1);
|
|
452
|
+
const errorFields: string[] = [];
|
|
453
|
+
|
|
454
|
+
const [triggerCheckIfPermissionExists] = useLazyCheckIfPermissionExistsQuery();
|
|
455
|
+
|
|
456
|
+
const [mcpUrl, setMcpUrl] = useState<string | null>(null);
|
|
457
|
+
const [getMcpUrl] = useLazyGetMcpUrlQuery();
|
|
458
|
+
|
|
459
|
+
// when rendering the form view we will optionally get action params...
|
|
460
|
+
// these we can bubble up in the event that is being raised onFormLayoutLoad, onFormDataLoad & onFormLoad
|
|
461
|
+
const actionName = searchParams.get('actionName');
|
|
462
|
+
const actionType = searchParams.get('actionType');
|
|
463
|
+
const actionContext = searchParams.get('actionContext');
|
|
464
|
+
|
|
465
|
+
const [trigger, { data: solidSettingsData }] = useLazyGetSolidSettingsQuery();
|
|
466
|
+
useEffect(() => {
|
|
467
|
+
trigger("") // Fetch settings on mount
|
|
468
|
+
}, [])
|
|
469
|
+
|
|
470
|
+
useEffect(() => {
|
|
471
|
+
if (solidSettingsData?.data?.mcpEnabled && solidSettingsData?.data?.mcpServerUrl) {
|
|
472
|
+
enableSolidXAiPanel();
|
|
473
|
+
}
|
|
474
|
+
}, [solidSettingsData]);
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
const enableSolidXAiPanel = async () => {
|
|
478
|
+
try {
|
|
479
|
+
const queryData = {
|
|
480
|
+
showHeader: "false",
|
|
481
|
+
inListView: "false"
|
|
482
|
+
};
|
|
483
|
+
const queryString = qs.stringify({ ...queryData }, { encodeValuesOnly: true });
|
|
484
|
+
const response = await getMcpUrl(queryString).unwrap();
|
|
485
|
+
console.log("response", response);
|
|
486
|
+
if (response && response?.data?.mcpUrl) {
|
|
487
|
+
setMcpUrl(response?.data?.mcpUrl);
|
|
488
|
+
}
|
|
489
|
+
} catch (error) {
|
|
490
|
+
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const op = useRef(null);
|
|
495
|
+
useEffect(() => {
|
|
496
|
+
const stored = localStorage.getItem('chatter_locale_width');
|
|
497
|
+
if (stored) {
|
|
498
|
+
setChatterLocaleWidth(parseInt(stored, 10));
|
|
499
|
+
}
|
|
500
|
+
}, []);
|
|
501
|
+
useEffect(() => {
|
|
502
|
+
const handleMouseMove = (e: MouseEvent) => {
|
|
503
|
+
if (!isResizingChatterLocale) return;
|
|
504
|
+
const newWidth = window.innerWidth - e.clientX;
|
|
505
|
+
const clampedWidth = Math.max(280, Math.min(newWidth, 700));
|
|
506
|
+
setChatterLocaleWidth(clampedWidth);
|
|
507
|
+
localStorage.setItem('chatter_locale_width', clampedWidth.toString());
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
const handleMouseUp = () => {
|
|
511
|
+
setIsResizingChatterLocale(false);
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
if (isResizingChatterLocale) {
|
|
515
|
+
window.addEventListener('mousemove', handleMouseMove);
|
|
516
|
+
window.addEventListener('mouseup', handleMouseUp);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return () => {
|
|
520
|
+
window.removeEventListener('mousemove', handleMouseMove);
|
|
521
|
+
window.removeEventListener('mouseup', handleMouseUp);
|
|
522
|
+
};
|
|
523
|
+
}, [isResizingChatterLocale]);
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
useEffect(() => {
|
|
527
|
+
const mode = searchParams.get('viewMode');
|
|
528
|
+
const locale = searchParams.get('locale');
|
|
529
|
+
const defaultEntityLocaleIdn = searchParams.get('defaultEntityLocaleId');
|
|
530
|
+
if (params.id === 'new' && !locale) {
|
|
531
|
+
setViewMode('edit');
|
|
532
|
+
setCreateMode(true);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
if (locale) {
|
|
537
|
+
setSelectedLocale(locale);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (defaultEntityLocaleIdn) {
|
|
541
|
+
setDefaultEntityLocaleId(defaultEntityLocaleIdn);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Set the viewMode based on the URL
|
|
545
|
+
if (mode === 'view' || mode === 'edit') {
|
|
546
|
+
setViewMode(mode);
|
|
547
|
+
} else {
|
|
548
|
+
setViewMode('view'); // Default to 'view' if no valid mode is provided
|
|
549
|
+
}
|
|
550
|
+
}, [searchParams, params.id]);
|
|
551
|
+
|
|
552
|
+
// function that updates view mode
|
|
553
|
+
const updateViewMode = (newMode: "view" | "edit") => {
|
|
554
|
+
setViewMode(newMode);
|
|
555
|
+
const params = new URLSearchParams(searchParams.toString());
|
|
556
|
+
params.set("viewMode", newMode);
|
|
557
|
+
router.push(`${pathname}?${params.toString()}`, { scroll: false });
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
useEffect(() => {
|
|
561
|
+
const fetchPermissions = async () => {
|
|
562
|
+
if (params.modelName) {
|
|
563
|
+
const permissionNames = [
|
|
564
|
+
permissionExpression(params.modelName, 'create'),
|
|
565
|
+
permissionExpression(params.modelName, 'delete'),
|
|
566
|
+
permissionExpression(params.modelName, 'update'),
|
|
567
|
+
permissionExpression(params.modelName, 'findOne'),
|
|
568
|
+
permissionExpression(params.modelName, 'publish'),
|
|
569
|
+
permissionExpression(params.modelName, 'unpublish'),
|
|
570
|
+
permissionExpression('chatterMessage', 'findMany')
|
|
571
|
+
]
|
|
572
|
+
const queryData = {
|
|
573
|
+
permissionNames: permissionNames
|
|
574
|
+
};
|
|
575
|
+
const queryString = qs.stringify(queryData, {
|
|
576
|
+
encodeValuesOnly: true
|
|
577
|
+
});
|
|
578
|
+
const response = await triggerCheckIfPermissionExists(queryString);
|
|
579
|
+
setActionsAllowed(response.data.data);
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
fetchPermissions();
|
|
583
|
+
}, [params.modelName]);
|
|
584
|
+
|
|
585
|
+
// Create the RTK slices for this entitor (const id of fieldValue) {
|
|
586
|
+
// if (!isInt(id)) {
|
|
587
|
+
// errors.push({ field: this.fieldMetadata.name, error: `Invalid ids in ${ commandFieldName } ` });
|
|
588
|
+
// }
|
|
589
|
+
// }y
|
|
590
|
+
const entityApi = createSolidEntityApi(params.modelName);
|
|
591
|
+
const {
|
|
592
|
+
useCreateSolidEntityMutation,
|
|
593
|
+
useDeleteSolidEntityMutation,
|
|
594
|
+
useGetSolidEntityByIdQuery,
|
|
595
|
+
useUpdateSolidEntityMutation,
|
|
596
|
+
usePatchUpdateSolidEntityMutation,
|
|
597
|
+
usePublishSolidEntityMutation,
|
|
598
|
+
useUnpublishSolidEntityMutation
|
|
599
|
+
} = entityApi;
|
|
600
|
+
|
|
601
|
+
const [
|
|
602
|
+
createEntity,
|
|
603
|
+
{ isSuccess: isEntityCreateSuccess, isError: isEntityCreateError, error: entityCreateError },
|
|
604
|
+
] = useCreateSolidEntityMutation();
|
|
605
|
+
|
|
606
|
+
const [
|
|
607
|
+
updateEntity,
|
|
608
|
+
{ isSuccess: isEntityUpdateSuceess, isError: isEntityUpdateError, error: entityUpdateError },
|
|
609
|
+
] = useUpdateSolidEntityMutation();
|
|
610
|
+
|
|
611
|
+
const [
|
|
612
|
+
deleteEntity,
|
|
613
|
+
{ isSuccess: isEntityDeleteSuceess, isError: isEntityDeleteError, error: entityDeleteError },
|
|
614
|
+
] = useDeleteSolidEntityMutation();
|
|
615
|
+
|
|
616
|
+
const [
|
|
617
|
+
patchEntity,
|
|
618
|
+
{ isSuccess: isEntityPatchSuceess, isError: isEntityPatchError, error: entityPatchError },
|
|
619
|
+
] = usePatchUpdateSolidEntityMutation();
|
|
620
|
+
|
|
621
|
+
const [
|
|
622
|
+
publishSolidEntity,
|
|
623
|
+
{ isSuccess: isEntityPublishedSuccess, isError: isEntityPublishedError, error: entityPublishedError },
|
|
624
|
+
] = usePublishSolidEntityMutation();
|
|
625
|
+
|
|
626
|
+
const [
|
|
627
|
+
unpublishSolidEntity,
|
|
628
|
+
{ isSuccess: isEntityUnpublishedSuccess, isError: isEntityUnpublishedError, error: entityUnpublishedError },
|
|
629
|
+
] = useUnpublishSolidEntityMutation();
|
|
630
|
+
|
|
631
|
+
// - - - - - - - - - - - -- - - - - - - - - - - - METADATA here
|
|
632
|
+
// Get the form view layout & metadata first.
|
|
633
|
+
const formViewMetaDataQs = qs.stringify({ ...params, viewType: 'form', defaultEntityLocaleId: defaultEntityLocaleId }, {
|
|
634
|
+
encodeValuesOnly: true,
|
|
635
|
+
});
|
|
636
|
+
const [formViewMetaData, setFormViewMetaData] = useState({});
|
|
637
|
+
const [formViewLayout, setFormViewLayout] = useState<any>(null);
|
|
638
|
+
const {
|
|
639
|
+
data: solidFormViewMetaData,
|
|
640
|
+
isLoading: solidFormViewMetaDataIsLoading
|
|
641
|
+
} = useGetSolidViewLayoutQuery(formViewMetaDataQs);
|
|
642
|
+
const [refreshChatterMessage, setRefreshChatterMessage] = useState<boolean>(true);
|
|
643
|
+
useEffect(() => {
|
|
644
|
+
if (
|
|
645
|
+
isEntityCreateSuccess == true ||
|
|
646
|
+
isEntityUpdateSuceess == true ||
|
|
647
|
+
isEntityDeleteSuceess == true ||
|
|
648
|
+
isEntityPatchSuceess == true ||
|
|
649
|
+
isEntityPublishedSuccess == true ||
|
|
650
|
+
isEntityUnpublishedSuccess == true
|
|
651
|
+
) {
|
|
652
|
+
setRefreshChatterMessage(true);
|
|
653
|
+
if (params.embeded == true && params.onEmbeddedFormSave) {
|
|
654
|
+
params.onEmbeddedFormSave();
|
|
655
|
+
}
|
|
656
|
+
// Close The pop in case the form is used in embeded form
|
|
657
|
+
if (params.embeded == true) {
|
|
658
|
+
params.handlePopupClose()
|
|
659
|
+
}
|
|
660
|
+
if (redirectToList === true) {
|
|
661
|
+
if (params.redirectToPath) {
|
|
662
|
+
router.push(params.redirectToPath);
|
|
663
|
+
window.location.reload();
|
|
664
|
+
} else {
|
|
665
|
+
const segments = pathname.split('/').filter(Boolean); // Split and filter empty segments
|
|
666
|
+
const newPath = '/' + segments.slice(0, -2).join('/') + '/list'; // Remove last segment and add "/all"
|
|
667
|
+
router.push(newPath);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}, [isEntityCreateSuccess, isEntityUpdateSuceess, isEntityDeleteSuceess, isEntityPatchSuceess, isEntityPublishedSuccess, isEntityUnpublishedSuccess]);
|
|
672
|
+
|
|
673
|
+
useEffect(() => {
|
|
674
|
+
|
|
675
|
+
if (solidFormViewMetaData?.data?.solidView?.model?.internationalisation) {
|
|
676
|
+
setDefaultTabViewOptionIndex(0)
|
|
677
|
+
const matchedLocale = solidFormViewMetaData?.data?.applicableLocales?.find((x: any) => x.isDefault === 'yes');
|
|
678
|
+
//this is to attach default locale when adding data in popup view where relations exists
|
|
679
|
+
if (!selectedLocale && matchedLocale && !searchParams.get('locale')) {
|
|
680
|
+
setSelectedLocale(matchedLocale.locale);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
}, [params.modelName, solidFormViewMetaData])
|
|
685
|
+
|
|
686
|
+
function isFetchBaseQueryErrorWithErrorResponse(error: any): error is FetchBaseQueryError & { data: ErrorResponseData } {
|
|
687
|
+
return error && typeof error === 'object' && 'data' in error && 'message' in error.data;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
useEffect(() => {
|
|
691
|
+
const handleError = (errorToast: any) => {
|
|
692
|
+
let errorMessage: any = [ERROR_MESSAGES.ERROR_OCCURED];
|
|
693
|
+
|
|
694
|
+
if (isFetchBaseQueryErrorWithErrorResponse(errorToast)) {
|
|
695
|
+
errorMessage = errorToast.data.message;
|
|
696
|
+
} else {
|
|
697
|
+
errorMessage = [ERROR_MESSAGES.SOMETHING_WRONG];
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
toast.current?.show({
|
|
701
|
+
severity: 'error',
|
|
702
|
+
summary: 'Error',
|
|
703
|
+
detail: errorMessage,
|
|
704
|
+
sticky: true,
|
|
705
|
+
//@ts-ignore
|
|
706
|
+
content: () => (
|
|
707
|
+
<div className="flex flex-column align-items-left" style={{ flex: "1" }}>
|
|
708
|
+
{Array.isArray(errorMessage) ? (
|
|
709
|
+
errorMessage.map((message, index) => (
|
|
710
|
+
<div className="flex align-items-center gap-2" key={index}>
|
|
711
|
+
<span className="font-bold text-900">{message.trim()}</span>
|
|
712
|
+
</div>
|
|
713
|
+
))
|
|
714
|
+
) : (
|
|
715
|
+
<div className="flex align-items-center gap-2">
|
|
716
|
+
<span className="font-bold text-900">{errorMessage?.trim()}</span>
|
|
717
|
+
</div>
|
|
718
|
+
)}
|
|
719
|
+
</div>
|
|
720
|
+
),
|
|
721
|
+
});
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
// Check and handle errors from each API operation
|
|
725
|
+
if (isEntityCreateError) {
|
|
726
|
+
handleError(entityCreateError);
|
|
727
|
+
} else if (isEntityDeleteError) {
|
|
728
|
+
handleError(entityDeleteError);
|
|
729
|
+
} else if (isEntityUpdateError) {
|
|
730
|
+
handleError(entityUpdateError);
|
|
731
|
+
} else if (isEntityPatchError) {
|
|
732
|
+
handleError(entityPatchError);
|
|
733
|
+
} else if (isEntityPublishedError) {
|
|
734
|
+
handleError(entityPublishedError);
|
|
735
|
+
} else if (isEntityUnpublishedError) {
|
|
736
|
+
handleError(entityUnpublishedError);
|
|
737
|
+
}
|
|
738
|
+
}, [
|
|
739
|
+
isEntityCreateError,
|
|
740
|
+
isEntityDeleteError,
|
|
741
|
+
isEntityUpdateError,
|
|
742
|
+
isEntityPatchError,
|
|
743
|
+
isEntityPublishedError,
|
|
744
|
+
isEntityUnpublishedError
|
|
745
|
+
]);
|
|
746
|
+
|
|
747
|
+
const showToast = (severity: "success" | "error", summary: string, detail: string) => {
|
|
748
|
+
toast.current?.show({
|
|
749
|
+
severity,
|
|
750
|
+
summary,
|
|
751
|
+
detail,
|
|
752
|
+
...(severity === "error"
|
|
753
|
+
? { sticky: true } // stays until user closes
|
|
754
|
+
: { life: 3000 }),
|
|
755
|
+
});
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
const confirmDialogWithPromise = () => {
|
|
759
|
+
return new Promise<boolean>((resolve) => {
|
|
760
|
+
confirmResolveRef.current = resolve;
|
|
761
|
+
setConfirmVisible(true);
|
|
762
|
+
});
|
|
763
|
+
};
|
|
764
|
+
|
|
765
|
+
const onFormikSubmit = async (values: any) => {
|
|
766
|
+
const solidView = solidFormViewMetaData.data.solidView;
|
|
767
|
+
const solidFieldsMetadata = solidFormViewMetaData.data.solidFieldsMetadata;
|
|
768
|
+
const layoutFieldsObj = getLayoutFieldsAsObject([formViewLayout]);
|
|
769
|
+
try {
|
|
770
|
+
let formData = new FormData();
|
|
771
|
+
|
|
772
|
+
// Iterate through the keys in the values object
|
|
773
|
+
Object.entries(values).forEach(([key, value]) => {
|
|
774
|
+
|
|
775
|
+
const fieldMetadata = solidFieldsMetadata[key];
|
|
776
|
+
// const fieldMetadata = getActualFieldMetadata(key, solidFieldsMetadata);
|
|
777
|
+
const fieldContext: SolidFieldProps = {
|
|
778
|
+
fieldMetadata: fieldMetadata,
|
|
779
|
+
field: layoutFieldsObj[key],
|
|
780
|
+
data: initialEntityData,
|
|
781
|
+
solidFormViewMetaData: solidFormViewMetaData,
|
|
782
|
+
modelName: params.modelName
|
|
783
|
+
}
|
|
784
|
+
let solidField = fieldFactory(fieldMetadata?.type, fieldContext);
|
|
785
|
+
// Append each field to the FormData
|
|
786
|
+
if (value !== undefined && value !== null && solidField) {
|
|
787
|
+
solidField.updateFormData(value, formData);
|
|
788
|
+
}
|
|
789
|
+
if (value !== undefined && value !== null && key.endsWith("Confirm")) {
|
|
790
|
+
formData.append(key, String(value))
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
let solidWorkflowField = solidFormViewMetaData?.data?.solidView?.layout?.attrs?.workflowField;
|
|
796
|
+
if (params.id !== "new") {
|
|
797
|
+
if (solidFormViewMetaData?.data?.solidFormViewWorkflowData) {
|
|
798
|
+
if (solidFormViewMetaData?.data?.solidFieldsMetadata?.[solidWorkflowField]?.type === "selectionStatic") {
|
|
799
|
+
formData.append(solidWorkflowField, solidWorkflowFieldValue);
|
|
800
|
+
}
|
|
801
|
+
if (solidFormViewMetaData?.data?.solidFieldsMetadata?.[solidWorkflowField]?.type === "many-to-one") {
|
|
802
|
+
formData.append(`${solidWorkflowField}Id`, solidWorkflowFieldValue);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
if (solidFormViewMetaData?.data?.solidView?.model?.internationalisation) {
|
|
807
|
+
if (selectedLocale && !formData.has('localeName')) {
|
|
808
|
+
formData.append('localeName', selectedLocale);
|
|
809
|
+
}
|
|
810
|
+
if (defaultEntityLocaleId) {
|
|
811
|
+
formData.append('defaultEntityLocaleId', defaultEntityLocaleId.toString());
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
if (solidFormViewMetaData?.data?.solidView?.model?.draftPublishWorkflow) {
|
|
815
|
+
if (published) {
|
|
816
|
+
formData.append('publishedAt', published);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
if (params.inlineCreateAutoSave === true) {
|
|
820
|
+
params.customCreateHandler(formData);
|
|
821
|
+
} else {
|
|
822
|
+
if (params.id === 'new') {
|
|
823
|
+
// default locale
|
|
824
|
+
const result = await createEntity(formData).unwrap();
|
|
825
|
+
showToast("success", ERROR_MESSAGES.FORM_SAVED, ERROR_MESSAGES.FORM_SAVED_SUCCESSFULLY);
|
|
826
|
+
// if (!params.embeded && result?.data?.id) {
|
|
827
|
+
// const newPathname = pathname.replace(/new$/, result.data.id);
|
|
828
|
+
|
|
829
|
+
// const params = new URLSearchParams(searchParams.toString());
|
|
830
|
+
// params.set("viewMode", "view");
|
|
831
|
+
|
|
832
|
+
// const updatedUrl = `${newPathname}?${params.toString()}`;
|
|
833
|
+
// await router.push(updatedUrl, { scroll: false });
|
|
834
|
+
|
|
835
|
+
// setViewMode("view")
|
|
836
|
+
// }
|
|
837
|
+
if (!params.embeded) {
|
|
838
|
+
const currentUrl = new URL(window.location.href);
|
|
839
|
+
currentUrl.pathname = currentUrl.pathname.replace(/new$/, result?.data?.id);
|
|
840
|
+
currentUrl.searchParams.set('viewMode', 'view');
|
|
841
|
+
const updatedUrl = currentUrl.toString();
|
|
842
|
+
router.push(updatedUrl);
|
|
843
|
+
setViewMode("view")
|
|
844
|
+
}
|
|
845
|
+
return result;
|
|
846
|
+
}
|
|
847
|
+
else {
|
|
848
|
+
// updateEntity({ id: +params.id, data: formData });
|
|
849
|
+
const result = await updateEntity({ id: +params.id, data: formData }).unwrap();
|
|
850
|
+
// const result = await updateEntity({ id: +params.id, data: formData }).unwrap();
|
|
851
|
+
if (!params.embeded) {
|
|
852
|
+
showToast("success", ERROR_MESSAGES.FORM_UPDATE, ERROR_MESSAGES.FORM_UPDATE_SUCCESSFULLY);
|
|
853
|
+
if (result?.statusCode === 200) {
|
|
854
|
+
updateViewMode("view")
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
return result;
|
|
858
|
+
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
} catch (err) {
|
|
863
|
+
console.error(ERROR_MESSAGES.ENTITY_FAILED, err);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
const showFieldError = () => {
|
|
868
|
+
if (errorFields?.length === 0) return;
|
|
869
|
+
errorFields.forEach((error) => {
|
|
870
|
+
toast?.current?.show({
|
|
871
|
+
severity: "error",
|
|
872
|
+
summary: "Metadata Error",
|
|
873
|
+
detail: error,
|
|
874
|
+
life: 3000,
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
// errorFields.length = 0;
|
|
880
|
+
};
|
|
881
|
+
useEffect(() => {
|
|
882
|
+
if (errorFields?.length > 0) {
|
|
883
|
+
showFieldError();
|
|
884
|
+
}
|
|
885
|
+
}, [errorFields])
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
// - - - - - - - - - - - -- - - - - - - - - - - - DATA here
|
|
889
|
+
// Fetch the actual data here.
|
|
890
|
+
// This is the initial value of this form, will come from an API call in the case of edit.
|
|
891
|
+
let layoutFields = [];
|
|
892
|
+
let toPopulate = [];
|
|
893
|
+
let toPopulateMedia = [];
|
|
894
|
+
if (solidFormViewMetaData && formViewLayout) {
|
|
895
|
+
const solidView = solidFormViewMetaData.data.solidView;
|
|
896
|
+
const solidFieldsMetadata = solidFormViewMetaData.data.solidFieldsMetadata;
|
|
897
|
+
layoutFields = [formViewLayout].flatMap(getLayoutFields);
|
|
898
|
+
for (let i = 0; i < layoutFields?.length; i++) {
|
|
899
|
+
const formLayoutField = layoutFields[i];
|
|
900
|
+
const fieldMetadata = solidFieldsMetadata[formLayoutField.attrs.name];
|
|
901
|
+
if (fieldMetadata?.type === 'relation') {
|
|
902
|
+
toPopulate.push(fieldMetadata.name);
|
|
903
|
+
}
|
|
904
|
+
if (fieldMetadata?.type === 'mediaSingle' || fieldMetadata?.type === 'mediaMultiple') {
|
|
905
|
+
toPopulateMedia.push(fieldMetadata.name);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
if (formViewLayout.attrs?.workflowField && solidFieldsMetadata[formViewLayout.attrs.workflowField]?.type === 'relation' && solidFieldsMetadata[formViewLayout.attrs.workflowField]?.relationType === 'many-to-one') {
|
|
909
|
+
toPopulate.push(solidFieldsMetadata[formViewLayout.attrs.workflowField].name);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
// TODO: Possible optimisation here, we are firing 2 queries to load the form view data object.
|
|
913
|
+
// once without populate & populateMedia and then again once after that.
|
|
914
|
+
const formViewDataQs = qs.stringify({ populate: toPopulate, populateMedia: toPopulateMedia }, {
|
|
915
|
+
encodeValuesOnly: true,
|
|
916
|
+
});
|
|
917
|
+
const [initialEntityData, setInitialEntityData] = useState({});
|
|
918
|
+
const {
|
|
919
|
+
data: solidFormViewData,
|
|
920
|
+
isLoading: solidFormViewDataIsLoading,
|
|
921
|
+
refetch: refetchSolidFormViewData,
|
|
922
|
+
} = useGetSolidEntityByIdQuery({ id: params.id, qs: formViewDataQs }, {
|
|
923
|
+
skip: params.id === 'new'
|
|
924
|
+
});
|
|
925
|
+
useEffect(() => {
|
|
926
|
+
if (params.id !== 'new') {
|
|
927
|
+
refetchSolidFormViewData()
|
|
928
|
+
}
|
|
929
|
+
}, [formViewDataQs])
|
|
930
|
+
|
|
931
|
+
useEffect(() => {
|
|
932
|
+
if (solidFormViewMetaData) {
|
|
933
|
+
if (params.customLayout) {
|
|
934
|
+
setFormViewLayout(params.customLayout);
|
|
935
|
+
} else {
|
|
936
|
+
setFormViewLayout(solidFormViewMetaData?.data?.solidView?.layout);
|
|
937
|
+
}
|
|
938
|
+
setPublished(solidFormViewData?.data?.publishedAt);
|
|
939
|
+
setFormViewMetaData(solidFormViewMetaData);
|
|
940
|
+
}
|
|
941
|
+
}, [solidFormViewMetaData]);
|
|
942
|
+
|
|
943
|
+
// useEffect(() => {
|
|
944
|
+
// const handleOnFormLayoutLoadEvent = async () => {
|
|
945
|
+
// if (solidFormViewMetaData) {
|
|
946
|
+
// // let formLayout = solidFormViewMetaData;
|
|
947
|
+
// // let customLayout = params?.customLayout;
|
|
948
|
+
// const onFormLayoutLoadHandlerExtensionFunction = solidFormViewMetaData?.data?.solidView?.layout?.onFormLayoutLoad;
|
|
949
|
+
// // let dynamicExtensionFunction = null;
|
|
950
|
+
// let formLayout = solidFormViewMetaData?.data?.solidView?.layout;
|
|
951
|
+
// if (params.customLayout) {
|
|
952
|
+
// formLayout = params.customLayout;
|
|
953
|
+
// }
|
|
954
|
+
// const event: SolidLoadForm = {
|
|
955
|
+
// parentData: params?.parentData,
|
|
956
|
+
// fieldsMetadata: solidFormViewMetaData,
|
|
957
|
+
// formData: solidFormViewData?.data,
|
|
958
|
+
// type: 'onFormLayoutLoad',
|
|
959
|
+
// viewMetadata: solidFormViewMetaData?.data?.solidView,
|
|
960
|
+
// formViewLayout: formLayout,
|
|
961
|
+
// queryParams: {
|
|
962
|
+
// actionName,
|
|
963
|
+
// actionType,
|
|
964
|
+
// actionContext
|
|
965
|
+
// }
|
|
966
|
+
// }
|
|
967
|
+
// if (onFormLayoutLoadHandlerExtensionFunction) {
|
|
968
|
+
// const dynamicExtensionFunction = getExtensionFunction(onFormLayoutLoadHandlerExtensionFunction);
|
|
969
|
+
// if (dynamicExtensionFunction) {
|
|
970
|
+
// try {
|
|
971
|
+
// const updatedFormLayout: SolidUiEventResponse = await dynamicExtensionFunction(event);
|
|
972
|
+
// if (updatedFormLayout && updatedFormLayout?.layoutChanged && updatedFormLayout?.newLayout) {
|
|
973
|
+
// setFormViewLayout(updatedFormLayout.newLayout);
|
|
974
|
+
// // const newFormLayout = {
|
|
975
|
+
// // ...formLayout,
|
|
976
|
+
// // data: {
|
|
977
|
+
// // ...formLayout.data,
|
|
978
|
+
// // solidView: {
|
|
979
|
+
// // ...formLayout.data.solidView,
|
|
980
|
+
// // layout: updatedFormLayout.newLayout
|
|
981
|
+
// // }
|
|
982
|
+
// // }
|
|
983
|
+
// // };
|
|
984
|
+
// // formLayout = newFormLayout;
|
|
985
|
+
// // customLayout = updatedFormLayout.newLayout;
|
|
986
|
+
// }
|
|
987
|
+
// } catch (error) {
|
|
988
|
+
// console.error(ERROR_MESSAGES.DYNAMIC_FUNCTION_ERROR, error);
|
|
989
|
+
// }
|
|
990
|
+
// }
|
|
991
|
+
// }
|
|
992
|
+
// // setFormViewMetaData(formLayout);
|
|
993
|
+
// // if (params.customLayout) {
|
|
994
|
+
// // setFormViewLayout(customLayout);
|
|
995
|
+
// // } else {
|
|
996
|
+
// // setFormViewLayout(formLayout.data.solidView.layout);
|
|
997
|
+
// // }
|
|
998
|
+
// }
|
|
999
|
+
// };
|
|
1000
|
+
// const handleOnFormDataLoadEvent = async () => {
|
|
1001
|
+
// const onFormDataLoadHandlerExtensionFunction = solidFormViewMetaData?.data?.solidView?.layout?.onFormDataLoad;
|
|
1002
|
+
// // let dynamicExtensionFunction = null;
|
|
1003
|
+
// let formViewData = solidFormViewData?.data;
|
|
1004
|
+
|
|
1005
|
+
// let formLayout = solidFormViewMetaData?.data?.solidView?.layout;
|
|
1006
|
+
// if (params.customLayout) {
|
|
1007
|
+
// formLayout = params.customLayout;
|
|
1008
|
+
// }
|
|
1009
|
+
|
|
1010
|
+
// const event: SolidLoadForm = {
|
|
1011
|
+
// fieldsMetadata: solidFormViewMetaData,
|
|
1012
|
+
// formData: solidFormViewData?.data,
|
|
1013
|
+
// type: "onFormDataLoad",
|
|
1014
|
+
// viewMetadata: solidFormViewMetaData?.data?.solidView,
|
|
1015
|
+
// formViewLayout: formLayout,
|
|
1016
|
+
// queryParams: {
|
|
1017
|
+
// actionName,
|
|
1018
|
+
// actionType,
|
|
1019
|
+
// actionContext
|
|
1020
|
+
// }
|
|
1021
|
+
// };
|
|
1022
|
+
// if (onFormDataLoadHandlerExtensionFunction) {
|
|
1023
|
+
// const dynamicExtensionFunction = getExtensionFunction(onFormDataLoadHandlerExtensionFunction);
|
|
1024
|
+
// if (dynamicExtensionFunction) {
|
|
1025
|
+
// const updatedFormData: SolidUiEventResponse = await dynamicExtensionFunction(event);
|
|
1026
|
+
|
|
1027
|
+
// if (updatedFormData && updatedFormData?.dataChanged && updatedFormData?.newFormData) {
|
|
1028
|
+
// formViewData = updatedFormData.newFormData;
|
|
1029
|
+
// }
|
|
1030
|
+
// }
|
|
1031
|
+
// if (formViewData) {
|
|
1032
|
+
// setInitialEntityData(formViewData);
|
|
1033
|
+
// }
|
|
1034
|
+
// }
|
|
1035
|
+
// };
|
|
1036
|
+
// const handleOnFormLoadEvent = async () => {
|
|
1037
|
+
// const onFormLoadHandlerExtensionFunction = solidFormViewMetaData?.data?.solidView?.layout?.onFormLoad;
|
|
1038
|
+
// // let dynamicExtensionFunction = null;
|
|
1039
|
+
// let localFormViewMetadata = solidFormViewMetaData;
|
|
1040
|
+
// // let customLayout = params?.customLayout;
|
|
1041
|
+
// let formViewData = solidFormViewData?.data;
|
|
1042
|
+
|
|
1043
|
+
// let formLayout = solidFormViewMetaData?.data?.solidView?.layout;
|
|
1044
|
+
// if (params.customLayout) {
|
|
1045
|
+
// formLayout = params.customLayout;
|
|
1046
|
+
// }
|
|
1047
|
+
|
|
1048
|
+
// const event: SolidLoadForm = {
|
|
1049
|
+
// parentData: params?.parentData,
|
|
1050
|
+
// fieldsMetadata: solidFormViewMetaData,
|
|
1051
|
+
// formData: solidFormViewData?.data,
|
|
1052
|
+
// type: 'onFormLoad',
|
|
1053
|
+
// viewMetadata: solidFormViewMetaData?.data?.solidView,
|
|
1054
|
+
// formViewLayout: formViewLayout,
|
|
1055
|
+
// queryParams: {
|
|
1056
|
+
// actionName,
|
|
1057
|
+
// actionType,
|
|
1058
|
+
// actionContext
|
|
1059
|
+
// }
|
|
1060
|
+
// };
|
|
1061
|
+
|
|
1062
|
+
// if (onFormLoadHandlerExtensionFunction) {
|
|
1063
|
+
// const dynamicExtensionFunction = getExtensionFunction(onFormLoadHandlerExtensionFunction);
|
|
1064
|
+
// if (dynamicExtensionFunction) {
|
|
1065
|
+
// try {
|
|
1066
|
+
// const result: SolidUiEventResponse = await dynamicExtensionFunction(event);
|
|
1067
|
+
// if (result && result?.layoutChanged && result?.newLayout) {
|
|
1068
|
+
// // const newLocalFormViewMetadata = {
|
|
1069
|
+
// // ...localFormViewMetadata,
|
|
1070
|
+
// // data: {
|
|
1071
|
+
// // ...localFormViewMetadata.data,
|
|
1072
|
+
// // solidView: {
|
|
1073
|
+
// // ...localFormViewMetadata.data.solidView,
|
|
1074
|
+
// // layout: result.newLayout
|
|
1075
|
+
// // }
|
|
1076
|
+
// // }
|
|
1077
|
+
// // };
|
|
1078
|
+
// // localFormViewMetadata = newLocalFormViewMetadata;
|
|
1079
|
+
// // customLayout = result.newLayout;
|
|
1080
|
+
// // setFormViewMetaData(localFormViewMetadata);
|
|
1081
|
+
|
|
1082
|
+
// setFormViewLayout(result.newLayout);
|
|
1083
|
+
// // if (params.customLayout) {
|
|
1084
|
+
// // setFormViewLayout(customLayout);
|
|
1085
|
+
// // } else {
|
|
1086
|
+
// // setFormViewLayout(localFormViewMetadata.data.solidView.layout);
|
|
1087
|
+
// // }
|
|
1088
|
+
// }
|
|
1089
|
+
// if (result && result?.dataChanged && result?.newFormData) {
|
|
1090
|
+
// formViewData = result.newFormData;
|
|
1091
|
+
// setInitialEntityData(formViewData);
|
|
1092
|
+
// }
|
|
1093
|
+
// } catch (error) {
|
|
1094
|
+
// console.error(ERROR_MESSAGES.ON_FORM_LOAD, error);
|
|
1095
|
+
// }
|
|
1096
|
+
// }
|
|
1097
|
+
// }
|
|
1098
|
+
// };
|
|
1099
|
+
|
|
1100
|
+
// handleOnFormLayoutLoadEvent();
|
|
1101
|
+
// handleOnFormDataLoadEvent();
|
|
1102
|
+
// handleOnFormLoadEvent();
|
|
1103
|
+
// }, [solidFormViewMetaData, solidFormViewData]);
|
|
1104
|
+
|
|
1105
|
+
|
|
1106
|
+
useEffect(() => {
|
|
1107
|
+
const runFormEvents = async () => {
|
|
1108
|
+
if (!solidFormViewMetaData) return;
|
|
1109
|
+
|
|
1110
|
+
/** ----------------------------
|
|
1111
|
+
* 1. Initialize working state
|
|
1112
|
+
* ----------------------------- */
|
|
1113
|
+
let workingLayout = params.customLayout ?? solidFormViewMetaData?.data?.solidView?.layout;
|
|
1114
|
+
let workingFormData = solidFormViewData?.data;
|
|
1115
|
+
const baseEvent = {
|
|
1116
|
+
parentData: params?.parentData,
|
|
1117
|
+
fieldsMetadata: solidFormViewMetaData,
|
|
1118
|
+
viewMetadata: solidFormViewMetaData?.data?.solidView,
|
|
1119
|
+
queryParams: {
|
|
1120
|
+
actionName,
|
|
1121
|
+
actionType,
|
|
1122
|
+
actionContext,
|
|
1123
|
+
},
|
|
1124
|
+
};
|
|
1125
|
+
|
|
1126
|
+
/** ----------------------------
|
|
1127
|
+
* 2. onFormLayoutLoad
|
|
1128
|
+
* ----------------------------- */
|
|
1129
|
+
const onFormLayoutLoadFn =
|
|
1130
|
+
solidFormViewMetaData?.data?.solidView?.layout?.onFormLayoutLoad;
|
|
1131
|
+
|
|
1132
|
+
if (onFormLayoutLoadFn) {
|
|
1133
|
+
const fn = getExtensionFunction(onFormLayoutLoadFn);
|
|
1134
|
+
if (fn) {
|
|
1135
|
+
try {
|
|
1136
|
+
const result: SolidUiEventResponse = await fn({
|
|
1137
|
+
...baseEvent,
|
|
1138
|
+
type: "onFormLayoutLoad",
|
|
1139
|
+
formData: workingFormData,
|
|
1140
|
+
formViewLayout: workingLayout,
|
|
1141
|
+
});
|
|
1142
|
+
|
|
1143
|
+
if (result?.layoutChanged && result?.newLayout) {
|
|
1144
|
+
workingLayout = result.newLayout;
|
|
1145
|
+
}
|
|
1146
|
+
} catch (e) {
|
|
1147
|
+
console.error(ERROR_MESSAGES.DYNAMIC_FUNCTION_ERROR, e);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
/** ----------------------------
|
|
1153
|
+
* 3. onFormDataLoad
|
|
1154
|
+
* ----------------------------- */
|
|
1155
|
+
const onFormDataLoadFn =
|
|
1156
|
+
solidFormViewMetaData?.data?.solidView?.layout?.onFormDataLoad;
|
|
1157
|
+
|
|
1158
|
+
if (onFormDataLoadFn) {
|
|
1159
|
+
const fn = getExtensionFunction(onFormDataLoadFn);
|
|
1160
|
+
if (fn) {
|
|
1161
|
+
try {
|
|
1162
|
+
const result: SolidUiEventResponse = await fn({
|
|
1163
|
+
...baseEvent,
|
|
1164
|
+
type: "onFormDataLoad",
|
|
1165
|
+
formData: workingFormData,
|
|
1166
|
+
formViewLayout: workingLayout, // ✅ UPDATED layout
|
|
1167
|
+
});
|
|
1168
|
+
|
|
1169
|
+
if (result?.dataChanged && result?.newFormData) {
|
|
1170
|
+
workingFormData = result.newFormData;
|
|
1171
|
+
}
|
|
1172
|
+
} catch (e) {
|
|
1173
|
+
console.error(ERROR_MESSAGES.DYNAMIC_FUNCTION_ERROR, e);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
/** ----------------------------
|
|
1179
|
+
* 4. onFormLoad
|
|
1180
|
+
* ----------------------------- */
|
|
1181
|
+
const onFormLoadFn =
|
|
1182
|
+
solidFormViewMetaData?.data?.solidView?.layout?.onFormLoad;
|
|
1183
|
+
|
|
1184
|
+
if (onFormLoadFn) {
|
|
1185
|
+
const fn = getExtensionFunction(onFormLoadFn);
|
|
1186
|
+
if (fn) {
|
|
1187
|
+
try {
|
|
1188
|
+
const result: SolidUiEventResponse = await fn({
|
|
1189
|
+
...baseEvent,
|
|
1190
|
+
type: "onFormLoad",
|
|
1191
|
+
formData: workingFormData,
|
|
1192
|
+
formViewLayout: workingLayout, // ✅ FINAL layout
|
|
1193
|
+
});
|
|
1194
|
+
|
|
1195
|
+
if (result?.layoutChanged && result?.newLayout) {
|
|
1196
|
+
workingLayout = result.newLayout;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
if (result?.dataChanged && result?.newFormData) {
|
|
1200
|
+
workingFormData = result.newFormData;
|
|
1201
|
+
}
|
|
1202
|
+
} catch (e) {
|
|
1203
|
+
console.error(ERROR_MESSAGES.ON_FORM_LOAD, e);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
/** ----------------------------
|
|
1209
|
+
* 5. Commit once to React state
|
|
1210
|
+
* ----------------------------- */
|
|
1211
|
+
if (workingLayout) {
|
|
1212
|
+
setFormViewLayout(workingLayout);
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
if (workingFormData) {
|
|
1216
|
+
setInitialEntityData(workingFormData);
|
|
1217
|
+
}
|
|
1218
|
+
};
|
|
1219
|
+
|
|
1220
|
+
runFormEvents();
|
|
1221
|
+
}, [solidFormViewMetaData, solidFormViewData]);
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
useEffect(() => {
|
|
1225
|
+
if (solidFormViewData) {
|
|
1226
|
+
setInitialEntityData(solidFormViewData.data);
|
|
1227
|
+
}
|
|
1228
|
+
}, [solidFormViewData]);
|
|
1229
|
+
|
|
1230
|
+
let formik: FormikObject;
|
|
1231
|
+
|
|
1232
|
+
// If either the metadata or the data of this form is loading, then we simply render a loading screen...
|
|
1233
|
+
if (solidFormViewMetaDataIsLoading || solidFormViewDataIsLoading || !formViewLayout) {
|
|
1234
|
+
formik = useFormik({
|
|
1235
|
+
initialValues: {},
|
|
1236
|
+
validationSchema: Yup.object(),
|
|
1237
|
+
enableReinitialize: true,
|
|
1238
|
+
onSubmit: onFormikSubmit,
|
|
1239
|
+
});
|
|
1240
|
+
|
|
1241
|
+
return <SolidFormViewShimmerLoading />;
|
|
1242
|
+
}
|
|
1243
|
+
// At this point everything required to render the form is loaded, so we go ahead and start rendering things dynamically...
|
|
1244
|
+
else {
|
|
1245
|
+
|
|
1246
|
+
// Initialize formik...
|
|
1247
|
+
const solidView = solidFormViewMetaData.data.solidView;
|
|
1248
|
+
const solidFieldsMetadata = solidFormViewMetaData.data.solidFieldsMetadata;
|
|
1249
|
+
|
|
1250
|
+
const validationSchema = {};
|
|
1251
|
+
const initialValues = {};
|
|
1252
|
+
|
|
1253
|
+
for (let i = 0; i < layoutFields?.length; i++) {
|
|
1254
|
+
const formLayoutField = layoutFields[i];
|
|
1255
|
+
const fieldMetadata = solidFieldsMetadata[formLayoutField.attrs.name];
|
|
1256
|
+
const fieldContext: SolidFieldProps = {
|
|
1257
|
+
fieldMetadata: fieldMetadata,
|
|
1258
|
+
field: formLayoutField,
|
|
1259
|
+
data: initialEntityData,
|
|
1260
|
+
solidFormViewMetaData: solidFormViewMetaData,
|
|
1261
|
+
modelName: params.modelName
|
|
1262
|
+
}
|
|
1263
|
+
if (params.parentData) {
|
|
1264
|
+
fieldContext.parentData = params.parentData;
|
|
1265
|
+
}
|
|
1266
|
+
let solidField = fieldFactory(fieldMetadata?.type, fieldContext);
|
|
1267
|
+
if (!fieldMetadata?.type) {
|
|
1268
|
+
const errorMessage = formLayoutField?.attrs?.label ? formLayoutField?.attrs?.label : formLayoutField.attrs.name;
|
|
1269
|
+
if (!errorFields.includes(errorMessage)) {
|
|
1270
|
+
// errorFields.push(errorMessage);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
if (solidField) {
|
|
1274
|
+
// @ts-ignore
|
|
1275
|
+
validationSchema[formLayoutField.attrs.name] = solidField.validationSchema();
|
|
1276
|
+
// @ts-ignore
|
|
1277
|
+
initialValues[formLayoutField.attrs.name] = solidField.initialValue();
|
|
1278
|
+
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
formik = useFormik({
|
|
1283
|
+
initialValues: initialValues,
|
|
1284
|
+
validationSchema: Yup.object(validationSchema),
|
|
1285
|
+
enableReinitialize: true,
|
|
1286
|
+
onSubmit: onFormikSubmit,
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1289
|
+
const formFieldOnXXX = async (event: ChangeEvent<HTMLInputElement>, eventType: string) => {
|
|
1290
|
+
|
|
1291
|
+
// Invoke the formik change
|
|
1292
|
+
if (eventType === 'onFieldChange') {
|
|
1293
|
+
formik.handleChange(event);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
// get details from the form event
|
|
1297
|
+
const { name: fieldName, value, type, checked } = event.target;
|
|
1298
|
+
|
|
1299
|
+
// TODO: check if there is a change handler registered with this form view, load it and fire it.
|
|
1300
|
+
let changeHandler = solidView.layout.attrs[eventType];
|
|
1301
|
+
if (!changeHandler) {
|
|
1302
|
+
changeHandler = solidView.layout[eventType];
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
if (changeHandler) {
|
|
1306
|
+
// Get hold of the dynamic module...
|
|
1307
|
+
// const dynamicChangeHandler = await loadDynamicModule(changeHandler);
|
|
1308
|
+
const dynamicChangeHandler = getExtensionFunction(changeHandler);
|
|
1309
|
+
|
|
1310
|
+
// Invoke the dynamic module...
|
|
1311
|
+
if (dynamicChangeHandler) {
|
|
1312
|
+
const event: SolidUiEvent = {
|
|
1313
|
+
fieldsMetadata: solidFieldsMetadata,
|
|
1314
|
+
formData: formik.values,
|
|
1315
|
+
modifiedField: fieldName,
|
|
1316
|
+
modifiedFieldValue: value,
|
|
1317
|
+
// @ts-ignore
|
|
1318
|
+
// TODO: HP & OR: This will be fixed once we figure out how to get types exported from solid-core-ui
|
|
1319
|
+
type: eventType,
|
|
1320
|
+
viewMetadata: solidView,
|
|
1321
|
+
formViewLayout: formViewLayout,
|
|
1322
|
+
queryParams: {
|
|
1323
|
+
actionName,
|
|
1324
|
+
actionContext,
|
|
1325
|
+
actionType
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
// Invoke the dynamic change handler:
|
|
1330
|
+
// TODO: encapsulate in try/catch, catch the exception render in the UI as an error & stop form rendering.
|
|
1331
|
+
const updatedFormInfo: SolidUiEventResponse = await dynamicChangeHandler(event);
|
|
1332
|
+
|
|
1333
|
+
// If dataChanged is true, update Formik values
|
|
1334
|
+
if (updatedFormInfo?.dataChanged && updatedFormInfo.newFormData) {
|
|
1335
|
+
// This does one field at a time.
|
|
1336
|
+
// TODO: does the below fire change events again?
|
|
1337
|
+
Object.entries(updatedFormInfo.newFormData).forEach(([key, newValue]) => {
|
|
1338
|
+
formik.setFieldValue(key, newValue);
|
|
1339
|
+
});
|
|
1340
|
+
|
|
1341
|
+
// This does all at once.
|
|
1342
|
+
// formik.setValues({
|
|
1343
|
+
// ...formik.values,
|
|
1344
|
+
// ...updatedFormInfo.newFormData
|
|
1345
|
+
// });
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
// if layout has changed then we need to re-render.
|
|
1349
|
+
if (updatedFormInfo?.layoutChanged && updatedFormInfo.newLayout) {
|
|
1350
|
+
// setFormViewMetaData({ ...formViewMetaData, layout: updatedFormInfo.newLayout });
|
|
1351
|
+
|
|
1352
|
+
// TODO: this will trigger a useEffect dependent on formViewMetadata that invokes setFormViewLayout,
|
|
1353
|
+
// TODO: which means that this will not work if custom layout has been injected as a prop.
|
|
1354
|
+
setFormViewLayout(updatedFormInfo.newLayout);
|
|
1355
|
+
// setFormViewMetaData((prevMetaData: any) => {
|
|
1356
|
+
// const updatedFormViewMetadata = {
|
|
1357
|
+
// ...prevMetaData,
|
|
1358
|
+
// data: {
|
|
1359
|
+
// ...prevMetaData.data,
|
|
1360
|
+
// solidView: {
|
|
1361
|
+
// ...prevMetaData.data.solidView,
|
|
1362
|
+
// layout: updatedFormInfo.newLayout,
|
|
1363
|
+
// },
|
|
1364
|
+
// },
|
|
1365
|
+
// };
|
|
1366
|
+
// return updatedFormViewMetadata;
|
|
1367
|
+
// });
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
else {
|
|
1371
|
+
// TODO: Show an error popup and stop form rendering ideallly...
|
|
1372
|
+
console.log(ERROR_MESSAGES.UNABLE_LOAD_DYNAMIC_MODULE, changeHandler);
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
// Now render the form dynamically...
|
|
1378
|
+
const renderFormElementDynamically: any = (element: any, recursiveFVMD: any) => {
|
|
1379
|
+
let { type, attrs, body, children } = element;
|
|
1380
|
+
|
|
1381
|
+
// const key = attrs?.name ?? generateRandomKey();
|
|
1382
|
+
const key = attrs?.label;
|
|
1383
|
+
let visible = attrs?.visible;
|
|
1384
|
+
if (visible === undefined || visible === null) {
|
|
1385
|
+
visible = true;
|
|
1386
|
+
}
|
|
1387
|
+
// console.log(`Resolved visibility of form element ${ key } to ${ visible } `);
|
|
1388
|
+
// console.log(`Form element ${ key }: `, attrs);
|
|
1389
|
+
const visibleToRole = attrs?.roles || [];
|
|
1390
|
+
|
|
1391
|
+
if (visibleToRole.length > 0) {
|
|
1392
|
+
if (!hasAnyRole(user?.user?.roles, visibleToRole)) {
|
|
1393
|
+
return <></>
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
switch (type) {
|
|
1398
|
+
case "form":
|
|
1399
|
+
if (!children)
|
|
1400
|
+
children = [];
|
|
1401
|
+
return <div key={key}>{children.map((element: any) => renderFormElementDynamically(element, recursiveFVMD, formik))}</div>;
|
|
1402
|
+
case "div":
|
|
1403
|
+
if (!children)
|
|
1404
|
+
children = [];
|
|
1405
|
+
return <div key={key} {...attrs}>{children.map((element: any) => renderFormElementDynamically(element, recursiveFVMD, formik))}</div>
|
|
1406
|
+
case "span":
|
|
1407
|
+
return <span key={key} {...attrs}>{body}</span>
|
|
1408
|
+
case "p":
|
|
1409
|
+
return <p key={key} className={attrs?.className} {...attrs}>{body}</p>
|
|
1410
|
+
case "h1":
|
|
1411
|
+
return <h1 key={key} {...attrs}>{body}</h1>
|
|
1412
|
+
case "h2":
|
|
1413
|
+
return <h2 key={key} {...attrs}>{body}</h2>
|
|
1414
|
+
case "ul":
|
|
1415
|
+
if (!children)
|
|
1416
|
+
children = [];
|
|
1417
|
+
return <ul key={key} {...attrs}>{children.map((element: any) => renderFormElementDynamically(element, recursiveFVMD, formik))}</ul>
|
|
1418
|
+
case "li":
|
|
1419
|
+
return <li key={key} {...attrs}>{body}</li>
|
|
1420
|
+
case "sheet":
|
|
1421
|
+
return <SolidSheet key={key}>{children.map((element: any) => renderFormElementDynamically(element, recursiveFVMD, formik))}</SolidSheet>;
|
|
1422
|
+
case "group":
|
|
1423
|
+
if (visible === true) {
|
|
1424
|
+
return <SolidGroup key={key} attrs={attrs}>{children.map((element: any) => renderFormElementDynamically(element, recursiveFVMD, formik))}</SolidGroup>;
|
|
1425
|
+
}
|
|
1426
|
+
case "row":
|
|
1427
|
+
if (visible === true) {
|
|
1428
|
+
return <SolidRow key={key} attrs={attrs}>{children.map((element: any) => renderFormElementDynamically(element, recursiveFVMD, formik))}</SolidRow>;
|
|
1429
|
+
}
|
|
1430
|
+
case "column":
|
|
1431
|
+
if (visible === true) {
|
|
1432
|
+
return <SolidColumn key={key} attrs={attrs}>{children.map((element: any) => renderFormElementDynamically(element, recursiveFVMD, formik))}</SolidColumn>;
|
|
1433
|
+
}
|
|
1434
|
+
case "field": {
|
|
1435
|
+
if (visible === true) {
|
|
1436
|
+
|
|
1437
|
+
// const fieldMetadata = solidFieldsMetadata[attrs.name];
|
|
1438
|
+
const fieldMetadata = recursiveFVMD.data.solidFieldsMetadata[attrs.name];
|
|
1439
|
+
// Read only permission if there is no update permission on model and router doesnt contains new
|
|
1440
|
+
const readOnlyPermission = !actionsAllowed.includes(`${permissionExpression(params.modelName, 'update')}`) && params.id !== "new";
|
|
1441
|
+
return <SolidField
|
|
1442
|
+
key={attrs.name}
|
|
1443
|
+
field={element}
|
|
1444
|
+
formik={formik}
|
|
1445
|
+
fieldMetadata={fieldMetadata}
|
|
1446
|
+
initialEntityData={solidFormViewData ? solidFormViewData.data : {}}
|
|
1447
|
+
solidFormViewMetaData={recursiveFVMD}
|
|
1448
|
+
modelName={params.modelName}
|
|
1449
|
+
readOnly={readOnlyPermission}
|
|
1450
|
+
viewMode={viewMode}
|
|
1451
|
+
onChange={formFieldOnXXX}
|
|
1452
|
+
onBlur={formFieldOnXXX}
|
|
1453
|
+
setLightboxUrls={setLightboxUrls}
|
|
1454
|
+
setOpenLightbox={setOpenLightbox}
|
|
1455
|
+
parentData={params.parentData}
|
|
1456
|
+
onEmbeddedFormSave={() => setRefreshChatterMessage(true)}
|
|
1457
|
+
/>;
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
case "notebook":
|
|
1461
|
+
if (visible === true) {
|
|
1462
|
+
return <SolidNotebook key={key} activeTab={searchParams.get("activeTab") || ""} embeded={params.embeded}>{children.map((element: any) => renderFormElementDynamically(element, recursiveFVMD, formik))}</SolidNotebook>;
|
|
1463
|
+
}
|
|
1464
|
+
case "page":
|
|
1465
|
+
if (visible === true) {
|
|
1466
|
+
const fields = children.flatMap((child: any) => getLayoutFields(child));
|
|
1467
|
+
const pageChildren = children.map((element: any) => renderFormElementDynamically(element, recursiveFVMD));
|
|
1468
|
+
return SolidPage({ children: pageChildren, attrs: attrs, key: key, formik: formik, fields });
|
|
1469
|
+
}
|
|
1470
|
+
case "custom":
|
|
1471
|
+
if (visible === true) {
|
|
1472
|
+
const widgetName = attrs?.widget;
|
|
1473
|
+
const fieldMetadata = recursiveFVMD.data.solidFieldsMetadata[attrs.name];
|
|
1474
|
+
|
|
1475
|
+
if (widgetName) {
|
|
1476
|
+
// widgetName, formik, field, fieldMetadata, solidFormViewMetaData
|
|
1477
|
+
return <SolidDynamicWidget
|
|
1478
|
+
key={key}
|
|
1479
|
+
widgetName={widgetName}
|
|
1480
|
+
field={element}
|
|
1481
|
+
formik={formik}
|
|
1482
|
+
fieldMetadata={fieldMetadata}
|
|
1483
|
+
solidFormViewMetaData={recursiveFVMD}
|
|
1484
|
+
solidFormViewData={solidFormViewData}
|
|
1485
|
+
/>
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
default:
|
|
1490
|
+
return null;
|
|
1491
|
+
}
|
|
1492
|
+
};
|
|
1493
|
+
|
|
1494
|
+
const renderFormDynamically = (recursiveFVMD: any, formViewLayout: any) => {
|
|
1495
|
+
if (!recursiveFVMD) {
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1498
|
+
if (!recursiveFVMD.data) {
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
const solidView = recursiveFVMD.data.solidView;
|
|
1502
|
+
const solidFieldsMetadata = recursiveFVMD.data.solidFieldsMetadata;
|
|
1503
|
+
if (!solidView || !solidFieldsMetadata) {
|
|
1504
|
+
return;
|
|
1505
|
+
}
|
|
1506
|
+
const updatedLayout = [formViewLayout];
|
|
1507
|
+
const dynamicForm = updatedLayout.map((element: any) => renderFormElementDynamically(element, recursiveFVMD));
|
|
1508
|
+
|
|
1509
|
+
return dynamicForm;
|
|
1510
|
+
};
|
|
1511
|
+
|
|
1512
|
+
const handleDeleteEntity = async () => {
|
|
1513
|
+
deleteEntity(solidFormViewData.data.id);
|
|
1514
|
+
setDeleteDialogVisible(false);
|
|
1515
|
+
if (params.embeded == true) {
|
|
1516
|
+
setRedirectToList(false)
|
|
1517
|
+
|
|
1518
|
+
} else {
|
|
1519
|
+
setRedirectToList(true)
|
|
1520
|
+
|
|
1521
|
+
}
|
|
1522
|
+
// router.back();
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
const onDeleteClose = () => {
|
|
1526
|
+
setDeleteDialogVisible(false);
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
const dynamicHeader = solidView.layout?.header;
|
|
1530
|
+
let DynamicHeaderComponent = null;
|
|
1531
|
+
if (dynamicHeader) {
|
|
1532
|
+
DynamicHeaderComponent = getExtensionComponent(dynamicHeader);
|
|
1533
|
+
}
|
|
1534
|
+
const customFormComponentEdit = solidView.layout.attrs.customFormComponentEdit;
|
|
1535
|
+
const customFormComponentNew = solidView.layout.attrs.customFormComponentNew;
|
|
1536
|
+
let DynamicFormComponentEdit = null;
|
|
1537
|
+
let DynamicFormComponentNew = null;
|
|
1538
|
+
if (customFormComponentEdit) {
|
|
1539
|
+
DynamicFormComponentEdit = getExtensionComponent(customFormComponentEdit);
|
|
1540
|
+
}
|
|
1541
|
+
if (customFormComponentNew) {
|
|
1542
|
+
DynamicFormComponentNew = getExtensionComponent(customFormComponentNew);
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
const handleChatterExpandClick = (option?: string) => {
|
|
1546
|
+
setShowChatter(true);
|
|
1547
|
+
if (option === 'info') {
|
|
1548
|
+
setDefaultTabViewOptionIndex(0);
|
|
1549
|
+
} else if (option === 'chatter') {
|
|
1550
|
+
setDefaultTabViewOptionIndex(1);
|
|
1551
|
+
setRefreshChatterMessage(true);
|
|
1552
|
+
} else {
|
|
1553
|
+
setDefaultTabViewOptionIndex(2);
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1556
|
+
|
|
1557
|
+
//en 4 null
|
|
1558
|
+
const handleLocaleChangeRedirect = (
|
|
1559
|
+
locale: string,
|
|
1560
|
+
defaultEntityLocaleId: string,
|
|
1561
|
+
viewMode: string,
|
|
1562
|
+
) => {
|
|
1563
|
+
let newViewMode = viewMode;
|
|
1564
|
+
const defaultApplicableLocales = solidFormViewMetaData?.data?.applicableLocales || [];
|
|
1565
|
+
//fr 4
|
|
1566
|
+
const matchingLocale = defaultApplicableLocales.find(
|
|
1567
|
+
(loc: any) =>
|
|
1568
|
+
loc.defaultEntityLocaleId &&
|
|
1569
|
+
loc.entityId &&
|
|
1570
|
+
loc.locale === locale
|
|
1571
|
+
);
|
|
1572
|
+
// Extract the base path from the current pathname, removing query params if any
|
|
1573
|
+
const basePath = pathname.split('?')[0];
|
|
1574
|
+
|
|
1575
|
+
// Determine entity part of the path (new or existing entityId)
|
|
1576
|
+
const entityPart = matchingLocale?.entityId ?? 'new';
|
|
1577
|
+
if (entityPart === 'new' && viewMode === 'view') {
|
|
1578
|
+
newViewMode = 'edit'
|
|
1579
|
+
} else if (entityPart !== 'new' && viewMode === 'view') {
|
|
1580
|
+
newViewMode = 'view'
|
|
1581
|
+
} else {
|
|
1582
|
+
newViewMode = 'edit'
|
|
1583
|
+
}
|
|
1584
|
+
// Construct new pathname using existing basePath and replacing entity segment
|
|
1585
|
+
const updatedPath = basePath.replace(/\/form\/[^/]+/, `/form/${entityPart}`);
|
|
1586
|
+
|
|
1587
|
+
const queryParams = new URLSearchParams({
|
|
1588
|
+
viewMode: newViewMode,
|
|
1589
|
+
locale,
|
|
1590
|
+
defaultEntityLocaleId,
|
|
1591
|
+
});
|
|
1592
|
+
|
|
1593
|
+
router.push(`${updatedPath}?${queryParams.toString()}`, { scroll: false });
|
|
1594
|
+
};
|
|
1595
|
+
|
|
1596
|
+
const handleConfirmAccept = () => {
|
|
1597
|
+
confirmResolveRef.current?.(true);
|
|
1598
|
+
setConfirmVisible(false);
|
|
1599
|
+
};
|
|
1600
|
+
|
|
1601
|
+
const handleConfirmReject = () => {
|
|
1602
|
+
confirmResolveRef.current?.(false);
|
|
1603
|
+
setConfirmVisible(false);
|
|
1604
|
+
};
|
|
1605
|
+
const handleDraftPublishWorkFlow = async (type: "publish" | "unpublish") => {
|
|
1606
|
+
const userChoice = await confirmDialogWithPromise();
|
|
1607
|
+
if (!userChoice) return;
|
|
1608
|
+
|
|
1609
|
+
// const finalPublishedValue =
|
|
1610
|
+
// type === "publish" ? new Date().toISOString() : "";
|
|
1611
|
+
|
|
1612
|
+
// setPublished(finalPublishedValue);
|
|
1613
|
+
|
|
1614
|
+
// const formdata = new FormData();
|
|
1615
|
+
// formdata.append("publishedAt", finalPublishedValue);
|
|
1616
|
+
|
|
1617
|
+
let result;
|
|
1618
|
+
|
|
1619
|
+
if (type === "publish") {
|
|
1620
|
+
result = await publishSolidEntity(params.id).unwrap();
|
|
1621
|
+
showToast("success", ERROR_MESSAGES.SAVED, ERROR_MESSAGES.MARK_PUBLISH);
|
|
1622
|
+
} else {
|
|
1623
|
+
result = await unpublishSolidEntity(params.id).unwrap();
|
|
1624
|
+
showToast("success", ERROR_MESSAGES.SAVED, ERROR_MESSAGES.MARK_UNPUBLISH);
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
console.log("publish/unpublish result", result);
|
|
1628
|
+
|
|
1629
|
+
// Set updated publish value from API response
|
|
1630
|
+
setPublished(result?.data?.publishedAt);
|
|
1631
|
+
};
|
|
1632
|
+
|
|
1633
|
+
|
|
1634
|
+
const isVideoOrAudio = (url: string) => {
|
|
1635
|
+
// Remove query params if present
|
|
1636
|
+
const cleanUrl = url.split("?")[0];
|
|
1637
|
+
const ext = cleanUrl.split(".").pop()?.toLowerCase();
|
|
1638
|
+
|
|
1639
|
+
// Combined list of supported media extensions
|
|
1640
|
+
const mediaExt = ["mp4", "webm", "ogg", "mov", "mp3", "wav", "m4a", "aac"];
|
|
1641
|
+
|
|
1642
|
+
return ext ? mediaExt.includes(ext) : false;
|
|
1643
|
+
};
|
|
1644
|
+
|
|
1645
|
+
const controlsList = ["nodownload", "nofullscreen", "noremoteplayback"];
|
|
1646
|
+
const slides = lightboxUrls.map((item: any) => {
|
|
1647
|
+
const url = item.src || item.downloadUrl || "";
|
|
1648
|
+
if (isVideoOrAudio(url)) {
|
|
1649
|
+
return {
|
|
1650
|
+
type: "video" as const,
|
|
1651
|
+
sources: [{ src: url, type: "video/mp4", }],
|
|
1652
|
+
};
|
|
1653
|
+
}
|
|
1654
|
+
return { src: url };
|
|
1655
|
+
});
|
|
1656
|
+
|
|
1657
|
+
const hasMedia = slides.some((s) => s.type === "video");
|
|
1658
|
+
|
|
1659
|
+
|
|
1660
|
+
|
|
1661
|
+
return (
|
|
1662
|
+
<div className="solid-form-wrapper">
|
|
1663
|
+
<Toast ref={toast} />
|
|
1664
|
+
<div className="solid-form-section" style={{ borderRight: params.embeded !== true ? '1px solid var(--primary-light-color)' : '' }} >
|
|
1665
|
+
<form style={{ width: '100%' }} onSubmit={formik.handleSubmit}>
|
|
1666
|
+
<SolidFormActionHeader
|
|
1667
|
+
formik={formik}
|
|
1668
|
+
formData={solidFormViewData?.data}
|
|
1669
|
+
params={params}
|
|
1670
|
+
actionsAllowed={actionsAllowed}
|
|
1671
|
+
formViewLayout={formViewLayout}
|
|
1672
|
+
solidView={solidView}
|
|
1673
|
+
solidFormViewMetaData={solidFormViewMetaData}
|
|
1674
|
+
initialEntityData={solidFormViewData ? solidFormViewData.data : {}}
|
|
1675
|
+
setDeleteDialogVisible={setDeleteDialogVisible}
|
|
1676
|
+
setLayoutDialogVisible={setLayoutDialogVisible}
|
|
1677
|
+
setRedirectToList={setRedirectToList}
|
|
1678
|
+
viewMode={viewMode}
|
|
1679
|
+
setViewMode={setViewMode}
|
|
1680
|
+
solidWorkflowFieldValue={solidWorkflowFieldValue}
|
|
1681
|
+
setSolidWorkflowFieldValue={setSolidWorkflowFieldValue}
|
|
1682
|
+
draftEnabled={solidFormViewMetaData?.data?.solidView?.model?.draftPublishWorkflow}
|
|
1683
|
+
publish={published}
|
|
1684
|
+
internationalisationEnabled={solidFormViewMetaData?.data?.solidView?.model?.internationalisation}
|
|
1685
|
+
handleDraftPublishWorkFlow={handleDraftPublishWorkFlow}
|
|
1686
|
+
onStepperUpdate={() => setRefreshChatterMessage(true)}
|
|
1687
|
+
/>
|
|
1688
|
+
<div className={`px-4 py-3 md:p-4 solid-form-content ${params.embeded === true ? 'h-auto' : ''}`} style={{ maxHeight: params.embeded === true ? '80vh' : '', overflowY: 'auto' }}>
|
|
1689
|
+
{DynamicHeaderComponent && <DynamicHeaderComponent />}
|
|
1690
|
+
{params.id === 'new' && DynamicFormComponentNew ? (
|
|
1691
|
+
<DynamicFormComponentNew params={params} />
|
|
1692
|
+
) : params.id !== 'new' && DynamicFormComponentEdit ? (
|
|
1693
|
+
<DynamicFormComponentEdit params={params} />
|
|
1694
|
+
) : (
|
|
1695
|
+
renderFormDynamically(formViewMetaData, formViewLayout)
|
|
1696
|
+
)}
|
|
1697
|
+
</div>
|
|
1698
|
+
|
|
1699
|
+
</form>
|
|
1700
|
+
<SolidFormFooter params={params}></SolidFormFooter>
|
|
1701
|
+
</div>
|
|
1702
|
+
{params.embeded !== true &&
|
|
1703
|
+
<div className={`chatter-section ${isShowChatter === false ? 'collapsed' : 'open'}`} style={{ width: chatterLocaleWidth }}>
|
|
1704
|
+
{isShowChatter && (
|
|
1705
|
+
<div
|
|
1706
|
+
style={{
|
|
1707
|
+
width: 5,
|
|
1708
|
+
cursor: 'col-resize',
|
|
1709
|
+
position: 'absolute',
|
|
1710
|
+
left: 0,
|
|
1711
|
+
top: 0,
|
|
1712
|
+
bottom: 0,
|
|
1713
|
+
zIndex: 9,
|
|
1714
|
+
}}
|
|
1715
|
+
onMouseDown={() => setIsResizingChatterLocale(true)}
|
|
1716
|
+
/>
|
|
1717
|
+
)}
|
|
1718
|
+
{isShowChatter === true &&
|
|
1719
|
+
<Button
|
|
1720
|
+
icon="pi pi-angle-double-right"
|
|
1721
|
+
size="small"
|
|
1722
|
+
text
|
|
1723
|
+
className="chatter-collapse-btn"
|
|
1724
|
+
style={{ width: 30, height: 30, aspectRatio: '1/1' }}
|
|
1725
|
+
onClick={() => setShowChatter(false)}
|
|
1726
|
+
/>
|
|
1727
|
+
}
|
|
1728
|
+
{isShowChatter === false ?
|
|
1729
|
+
<div className="flex flex-column gap-2 justify-content-center p-2">
|
|
1730
|
+
{/*if solidview Internationalisation is enabled then show the locale tab */}
|
|
1731
|
+
{solidFormViewMetaData?.data?.solidView?.model?.draftPublishWorkflow &&
|
|
1732
|
+
<div className="chatter-collapsed-content" onClick={() => handleChatterExpandClick('info')}>
|
|
1733
|
+
Info
|
|
1734
|
+
</div>}
|
|
1735
|
+
<div className="chatter-collapsed-content" onClick={() => handleChatterExpandClick('chatter')}>
|
|
1736
|
+
Audit Trail
|
|
1737
|
+
</div>
|
|
1738
|
+
{
|
|
1739
|
+
mcpUrl &&
|
|
1740
|
+
(
|
|
1741
|
+
<div className="chatter-collapsed-content" onClick={() => handleChatterExpandClick('solidx-ai')}>
|
|
1742
|
+
<div className="flex gap-2"> <SolidXAIIcon /> SolidX AI </div>
|
|
1743
|
+
</div>
|
|
1744
|
+
)
|
|
1745
|
+
}
|
|
1746
|
+
<Button
|
|
1747
|
+
icon="pi pi-chevron-left"
|
|
1748
|
+
size="small"
|
|
1749
|
+
className="px-0"
|
|
1750
|
+
style={{ width: 30 }}
|
|
1751
|
+
onClick={() => handleChatterExpandClick('default')}
|
|
1752
|
+
/>
|
|
1753
|
+
</div>
|
|
1754
|
+
:
|
|
1755
|
+
<SolidChatterLocaleTabView
|
|
1756
|
+
createMode={createMode}
|
|
1757
|
+
setSelectedLocale={setSelectedLocale}
|
|
1758
|
+
selectedLocale={selectedLocale}
|
|
1759
|
+
solidFormViewMetaData={solidFormViewMetaData}
|
|
1760
|
+
id={params.id}
|
|
1761
|
+
refreshChatterMessage={refreshChatterMessage}
|
|
1762
|
+
setRefreshChatterMessage={setRefreshChatterMessage}
|
|
1763
|
+
activeTab={defaultTabViewOptionIndex}
|
|
1764
|
+
viewMode={viewMode}
|
|
1765
|
+
defaultEntityLocaleId={defaultEntityLocaleId}
|
|
1766
|
+
handleLocaleChangeRedirect={handleLocaleChangeRedirect}
|
|
1767
|
+
solidFormViewData={solidFormViewData}
|
|
1768
|
+
published={published}
|
|
1769
|
+
actionsAllowed={actionsAllowed}
|
|
1770
|
+
mcpUrl={mcpUrl}
|
|
1771
|
+
/>
|
|
1772
|
+
}
|
|
1773
|
+
</div>
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
<Dialog
|
|
1777
|
+
visible={isDeleteDialogVisible}
|
|
1778
|
+
header="Confirm Delete"
|
|
1779
|
+
className="solid-confirm-dialog"
|
|
1780
|
+
modal
|
|
1781
|
+
footer={() => (
|
|
1782
|
+
<div className="flex justify-content-center">
|
|
1783
|
+
<Button label="Yes" icon="pi pi-check" className='small-button' severity="danger" autoFocus onClick={() => handleDeleteEntity()} />
|
|
1784
|
+
<Button label="No" icon="pi pi-times" className='small-button' onClick={onDeleteClose} />
|
|
1785
|
+
</div>
|
|
1786
|
+
)}
|
|
1787
|
+
onHide={() => setDeleteDialogVisible(false)}
|
|
1788
|
+
>
|
|
1789
|
+
<p>Are you sure you want to delete?</p>
|
|
1790
|
+
</Dialog>
|
|
1791
|
+
<Dialog
|
|
1792
|
+
visible={isLayoutDialogVisible}
|
|
1793
|
+
header="Change Form Layout"
|
|
1794
|
+
modal
|
|
1795
|
+
onHide={() => setLayoutDialogVisible(false)}
|
|
1796
|
+
style={{ width: '50vw' }}
|
|
1797
|
+
breakpoints={{
|
|
1798
|
+
'960px': '80vw',
|
|
1799
|
+
'641px': '95vw'
|
|
1800
|
+
}}
|
|
1801
|
+
contentClassName="p-3 pt-0 lg:p-4"
|
|
1802
|
+
>
|
|
1803
|
+
<SolidFormUserViewLayout solidFormViewMetaData={solidFormViewMetaData} setLayoutDialogVisible={setLayoutDialogVisible} />
|
|
1804
|
+
</Dialog>
|
|
1805
|
+
{openLightbox &&
|
|
1806
|
+
<Lightbox
|
|
1807
|
+
open={openLightbox}
|
|
1808
|
+
plugins={
|
|
1809
|
+
hasMedia
|
|
1810
|
+
? [Counter, Download, Video] // add Video plugin if needed
|
|
1811
|
+
: [Counter, Download]
|
|
1812
|
+
}
|
|
1813
|
+
close={() => setOpenLightbox(false)}
|
|
1814
|
+
slides={[...slides]}
|
|
1815
|
+
{...(hasMedia && {
|
|
1816
|
+
video: {
|
|
1817
|
+
controls: true,
|
|
1818
|
+
playsInline: true,
|
|
1819
|
+
autoPlay: false,
|
|
1820
|
+
loop: false,
|
|
1821
|
+
muted: false,
|
|
1822
|
+
disablePictureInPicture: false,
|
|
1823
|
+
disableRemotePlayback: false,
|
|
1824
|
+
controlsList: controlsList.join(" "),
|
|
1825
|
+
crossOrigin: "anonymous",
|
|
1826
|
+
preload: "auto",
|
|
1827
|
+
},
|
|
1828
|
+
})}
|
|
1829
|
+
/>
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
<ConfirmDialog
|
|
1833
|
+
visible={confirmVisible}
|
|
1834
|
+
onHide={() => setConfirmVisible(false)}
|
|
1835
|
+
header="Confirmation"
|
|
1836
|
+
acceptLabel="Yes, confrim"
|
|
1837
|
+
rejectLabel="No, cancel"
|
|
1838
|
+
acceptClassName="p-button-danger"
|
|
1839
|
+
rejectClassName="p-button-text"
|
|
1840
|
+
position="center"
|
|
1841
|
+
accept={handleConfirmAccept}
|
|
1842
|
+
reject={handleConfirmReject}
|
|
1843
|
+
message={
|
|
1844
|
+
<div className="flex flex-col items-center justify-center text-center space-y-3">
|
|
1845
|
+
<p className="text-gray-800 text-base">
|
|
1846
|
+
Are you sure you want to {published !== null ? 'unpublish' : 'publish'}?
|
|
1847
|
+
</p>
|
|
1848
|
+
</div>
|
|
1849
|
+
}
|
|
1850
|
+
/>
|
|
1851
|
+
</div>
|
|
1852
|
+
);
|
|
1853
|
+
}
|
|
1854
|
+
};
|
|
1855
|
+
|
|
1856
|
+
export default SolidFormView;
|