@solidxai/core-ui 0.1.12-beta.3 → 0.1.12-beta.5
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/auth/AuthLayout.d.ts.map +1 -1
- package/dist/components/auth/AuthLayout.js +7 -3
- package/dist/components/auth/AuthLayout.js.map +1 -1
- package/dist/components/auth/AuthLayout.tsx +9 -2
- package/dist/components/auth/AuthSettingsContext.js +1 -1
- package/dist/components/auth/AuthSettingsContext.js.map +1 -1
- package/dist/components/auth/AuthSettingsContext.tsx +1 -1
- package/dist/components/core/chatter/SolidChatterHeader.d.ts.map +1 -1
- package/dist/components/core/chatter/SolidChatterHeader.js +18 -4
- package/dist/components/core/chatter/SolidChatterHeader.js.map +1 -1
- package/dist/components/core/chatter/SolidChatterHeader.tsx +17 -3
- package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.d.ts.map +1 -1
- package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.js +12 -2
- package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.js.map +1 -1
- package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.tsx +12 -1
- package/dist/components/core/extension/solid-core/metadata/MetadataExplorerFormWidget.d.ts +2 -0
- package/dist/components/core/extension/solid-core/metadata/MetadataExplorerFormWidget.d.ts.map +1 -1
- package/dist/components/core/extension/solid-core/metadata/MetadataExplorerFormWidget.js +4 -2
- package/dist/components/core/extension/solid-core/metadata/MetadataExplorerFormWidget.js.map +1 -1
- package/dist/components/core/extension/solid-core/metadata/MetadataExplorerFormWidget.tsx +11 -3
- package/dist/components/core/json/SolidJsonEditor.css +7 -0
- package/dist/components/core/list/SolidDataTable.js +1 -1
- package/dist/components/core/list/SolidDataTable.js.map +1 -1
- package/dist/components/core/list/SolidDataTable.tsx +1 -1
- package/dist/components/core/list/SolidListView.d.ts.map +1 -1
- package/dist/components/core/list/SolidListView.js +58 -58
- package/dist/components/core/list/SolidListView.js.map +1 -1
- package/dist/components/core/list/SolidListView.tsx +5 -4
- package/dist/components/core/module/CreateModule.css +60 -6
- package/dist/components/core/module/CreateModule.d.ts.map +1 -1
- package/dist/components/core/module/CreateModule.js +2 -2
- package/dist/components/core/module/CreateModule.js.map +1 -1
- package/dist/components/core/module/CreateModule.tsx +56 -37
- package/dist/components/layout/AdminTopHeader.js +1 -1
- package/dist/components/layout/AdminTopHeader.js.map +1 -1
- package/dist/components/layout/AdminTopHeader.tsx +2 -2
- package/dist/helpers/modelViewPersistence.d.ts.map +1 -1
- package/dist/helpers/modelViewPersistence.js +3 -2
- package/dist/helpers/modelViewPersistence.js.map +1 -1
- package/dist/helpers/modelViewPersistence.ts +3 -2
- package/dist/helpers/modulePackageResumeState.d.ts +6 -0
- package/dist/helpers/modulePackageResumeState.d.ts.map +1 -0
- package/dist/helpers/modulePackageResumeState.js +46 -0
- package/dist/helpers/modulePackageResumeState.js.map +1 -0
- package/dist/helpers/modulePackageResumeState.ts +57 -0
- package/dist/redux/api/datasourceIntrospectionApi.d.ts +42 -1
- package/dist/redux/api/datasourceIntrospectionApi.d.ts.map +1 -1
- package/dist/redux/api/datasourceIntrospectionApi.js +34 -1
- package/dist/redux/api/datasourceIntrospectionApi.js.map +1 -1
- package/dist/redux/api/datasourceIntrospectionApi.ts +60 -0
- package/dist/redux/store/defaultStoreConfig.d.ts +11 -0
- package/dist/redux/store/defaultStoreConfig.d.ts.map +1 -1
- package/dist/resources/shadcn-base.css +70 -16
- package/dist/resources/solid-custom.css +3 -86
- package/dist/resources/solid-tailwind-generated.css +1 -1
- package/dist/resources/themes/solid-dark-purple/theme-variables.css +226 -0
- package/dist/resources/themes/solid-dark-purple/theme.css +1 -185
- package/dist/resources/themes/solid-light-purple/theme-variables.css +237 -0
- package/dist/resources/themes/solid-light-purple/theme.css +1 -206
- package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.css +384 -31
- package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.js +577 -150
- package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.js.map +1 -1
- package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.tsx +1088 -423
- package/package.json +1 -1
- package/dist/components/auth/SolidOTPVerify.d.ts +0 -3
- package/dist/components/auth/SolidOTPVerify.d.ts.map +0 -1
- package/dist/components/auth/SolidOTPVerify.js +0 -67
- package/dist/components/auth/SolidOTPVerify.js.map +0 -1
- package/dist/components/auth/SolidOTPVerify.tsx +0 -133
- package/dist/components/common/AuthBanner.d.ts +0 -3
- package/dist/components/common/AuthBanner.d.ts.map +0 -1
- package/dist/components/common/AuthBanner.js +0 -15
- package/dist/components/common/AuthBanner.js.map +0 -1
- package/dist/components/common/AuthBanner.tsx +0 -41
- package/dist/components/common/SingleSelectAutoCompleteField.d.ts +0 -2
- package/dist/components/common/SingleSelectAutoCompleteField.d.ts.map +0 -1
- package/dist/components/common/SingleSelectAutoCompleteField.js +0 -92
- package/dist/components/common/SingleSelectAutoCompleteField.js.map +0 -1
- package/dist/components/common/SingleSelectAutoCompleteField.tsx +0 -73
- package/dist/components/common/SolidExportStepper.d.ts +0 -12
- package/dist/components/common/SolidExportStepper.d.ts.map +0 -1
- package/dist/components/common/SolidExportStepper.js +0 -30
- package/dist/components/common/SolidExportStepper.js.map +0 -1
- package/dist/components/common/SolidExportStepper.tsx +0 -135
- package/dist/components/core/common/LoadDynamicJsxComponent.d.ts +0 -2
- package/dist/components/core/common/LoadDynamicJsxComponent.d.ts.map +0 -1
- package/dist/components/core/common/LoadDynamicJsxComponent.js +0 -50
- package/dist/components/core/common/LoadDynamicJsxComponent.js.map +0 -1
- package/dist/components/core/common/LoadDynamicJsxComponent.tsx +0 -70
- package/dist/components/core/common/SolidGenericImport/SolidImportWrapper.d.ts +0 -2
- package/dist/components/core/common/SolidGenericImport/SolidImportWrapper.d.ts.map +0 -1
- package/dist/components/core/common/SolidGenericImport/SolidImportWrapper.js +0 -16
- package/dist/components/core/common/SolidGenericImport/SolidImportWrapper.js.map +0 -1
- package/dist/components/core/common/SolidGenericImport/SolidImportWrapper.tsx +0 -29
- package/dist/components/core/dashboard/DashboardFilter.d.ts +0 -13
- package/dist/components/core/dashboard/DashboardFilter.d.ts.map +0 -1
- package/dist/components/core/dashboard/DashboardFilter.js +0 -299
- package/dist/components/core/dashboard/DashboardFilter.js.map +0 -1
- package/dist/components/core/dashboard/DashboardFilter.tsx +0 -348
- package/dist/components/core/dashboard/PrimeDataTableWrapper.d.ts +0 -3
- package/dist/components/core/dashboard/PrimeDataTableWrapper.d.ts.map +0 -1
- package/dist/components/core/dashboard/PrimeDataTableWrapper.js +0 -21
- package/dist/components/core/dashboard/PrimeDataTableWrapper.js.map +0 -1
- package/dist/components/core/dashboard/PrimeDataTableWrapper.tsx +0 -40
- package/dist/components/core/dashboard/SolidDashboard.d.ts +0 -28
- package/dist/components/core/dashboard/SolidDashboard.d.ts.map +0 -1
- package/dist/components/core/dashboard/SolidDashboard.js +0 -183
- package/dist/components/core/dashboard/SolidDashboard.js.map +0 -1
- package/dist/components/core/dashboard/SolidDashboard.module.css +0 -83
- package/dist/components/core/dashboard/SolidDashboard.tsx +0 -263
- package/dist/components/core/dashboard/SolidDashboardBody.d.ts +0 -24
- package/dist/components/core/dashboard/SolidDashboardBody.d.ts.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardBody.js +0 -162
- package/dist/components/core/dashboard/SolidDashboardBody.js.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardBody.tsx +0 -168
- package/dist/components/core/dashboard/SolidDashboardFilterRequired.d.ts +0 -2
- package/dist/components/core/dashboard/SolidDashboardFilterRequired.d.ts.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardFilterRequired.js +0 -11
- package/dist/components/core/dashboard/SolidDashboardFilterRequired.js.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardFilterRequired.tsx +0 -28
- package/dist/components/core/dashboard/SolidDashboardHeader.d.ts +0 -3
- package/dist/components/core/dashboard/SolidDashboardHeader.d.ts.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardHeader.js +0 -6
- package/dist/components/core/dashboard/SolidDashboardHeader.js.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardHeader.tsx +0 -10
- package/dist/components/core/dashboard/SolidDashboardLoading.d.ts +0 -2
- package/dist/components/core/dashboard/SolidDashboardLoading.d.ts.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardLoading.js +0 -10
- package/dist/components/core/dashboard/SolidDashboardLoading.js.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardLoading.tsx +0 -61
- package/dist/components/core/dashboard/SolidDashboardNotAvailable.d.ts +0 -3
- package/dist/components/core/dashboard/SolidDashboardNotAvailable.d.ts.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardNotAvailable.js +0 -12
- package/dist/components/core/dashboard/SolidDashboardNotAvailable.js.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardNotAvailable.tsx +0 -32
- package/dist/components/core/dashboard/SolidDashboardRenderError.d.ts +0 -2
- package/dist/components/core/dashboard/SolidDashboardRenderError.d.ts.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardRenderError.js +0 -11
- package/dist/components/core/dashboard/SolidDashboardRenderError.js.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardRenderError.tsx +0 -28
- package/dist/components/core/dashboard/SolidDashboardVariable.d.ts +0 -19
- package/dist/components/core/dashboard/SolidDashboardVariable.d.ts.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardVariable.js +0 -171
- package/dist/components/core/dashboard/SolidDashboardVariable.js.map +0 -1
- package/dist/components/core/dashboard/SolidDashboardVariable.tsx +0 -259
- package/dist/components/core/dashboard/SolidQuestionRenderer.d.ts +0 -9
- package/dist/components/core/dashboard/SolidQuestionRenderer.d.ts.map +0 -1
- package/dist/components/core/dashboard/SolidQuestionRenderer.js +0 -42
- package/dist/components/core/dashboard/SolidQuestionRenderer.js.map +0 -1
- package/dist/components/core/dashboard/SolidQuestionRenderer.tsx +0 -99
- package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.d.ts +0 -9
- package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.d.ts.map +0 -1
- package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.js +0 -35
- package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.js.map +0 -1
- package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.tsx +0 -48
- package/dist/components/core/dashboard/chart-renderers/PrimeReactDatatableRenderer.d.ts +0 -7
- package/dist/components/core/dashboard/chart-renderers/PrimeReactDatatableRenderer.d.ts.map +0 -1
- package/dist/components/core/dashboard/chart-renderers/PrimeReactDatatableRenderer.js +0 -22
- package/dist/components/core/dashboard/chart-renderers/PrimeReactDatatableRenderer.js.map +0 -1
- package/dist/components/core/dashboard/chart-renderers/PrimeReactDatatableRenderer.tsx +0 -51
- package/dist/components/core/dashboard/chart-renderers/init-chartjs.d.ts +0 -2
- package/dist/components/core/dashboard/chart-renderers/init-chartjs.d.ts.map +0 -1
- package/dist/components/core/dashboard/chart-renderers/init-chartjs.js +0 -4
- package/dist/components/core/dashboard/chart-renderers/init-chartjs.js.map +0 -1
- package/dist/components/core/dashboard/chart-renderers/init-chartjs.ts +0 -25
- package/dist/components/core/dashboard/dashboard-utils.d.ts +0 -2
- package/dist/components/core/dashboard/dashboard-utils.d.ts.map +0 -1
- package/dist/components/core/dashboard/dashboard-utils.js +0 -38
- package/dist/components/core/dashboard/dashboard-utils.js.map +0 -1
- package/dist/components/core/dashboard/dashboard-utils.ts +0 -39
- package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.d.ts +0 -10
- package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.d.ts.map +0 -1
- package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.js +0 -16
- package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.js.map +0 -1
- package/dist/components/core/extension/solid-core/dashboard/dashboardFormViewChangeHandler.ts +0 -19
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.d.ts +0 -8
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.d.ts.map +0 -1
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.js +0 -64
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.js.map +0 -1
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionFieldChangeHandler.ts +0 -30
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.d.ts +0 -8
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.d.ts.map +0 -1
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.js +0 -62
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.js.map +0 -1
- package/dist/components/core/extension/solid-core/dashboard/dashboardQuestionOnFormLoadHandler.ts +0 -29
- package/dist/components/core/extension/solid-core/dashboardQuestion/ChartFormPreviewWidget.d.ts +0 -4
- package/dist/components/core/extension/solid-core/dashboardQuestion/ChartFormPreviewWidget.d.ts.map +0 -1
- package/dist/components/core/extension/solid-core/dashboardQuestion/ChartFormPreviewWidget.js +0 -23
- package/dist/components/core/extension/solid-core/dashboardQuestion/ChartFormPreviewWidget.js.map +0 -1
- package/dist/components/core/extension/solid-core/dashboardQuestion/ChartFormPreviewWidget.tsx +0 -36
- package/dist/components/core/form/fields/widgets/SolidChatterMessageCoModelEntityIdFormViewWidget.d.ts +0 -3
- package/dist/components/core/form/fields/widgets/SolidChatterMessageCoModelEntityIdFormViewWidget.d.ts.map +0 -1
- package/dist/components/core/form/fields/widgets/SolidChatterMessageCoModelEntityIdFormViewWidget.js +0 -92
- package/dist/components/core/form/fields/widgets/SolidChatterMessageCoModelEntityIdFormViewWidget.js.map +0 -1
- package/dist/components/core/form/fields/widgets/SolidChatterMessageCoModelEntityIdFormViewWidget.tsx +0 -68
- package/dist/components/core/form/fields/widgets/SolidLovTypeChangeFormEditWidget.d.ts +0 -3
- package/dist/components/core/form/fields/widgets/SolidLovTypeChangeFormEditWidget.d.ts.map +0 -1
- package/dist/components/core/form/fields/widgets/SolidLovTypeChangeFormEditWidget.js +0 -111
- package/dist/components/core/form/fields/widgets/SolidLovTypeChangeFormEditWidget.js.map +0 -1
- package/dist/components/core/form/fields/widgets/SolidLovTypeChangeFormEditWidget.tsx +0 -122
- package/dist/components/core/kanban/SolidKanbanViewFields.d.ts +0 -12
- package/dist/components/core/kanban/SolidKanbanViewFields.d.ts.map +0 -1
- package/dist/components/core/kanban/SolidKanbanViewFields.js +0 -145
- package/dist/components/core/kanban/SolidKanbanViewFields.js.map +0 -1
- package/dist/components/core/kanban/SolidKanbanViewFields.tsx +0 -164
- package/dist/components/core/kanban/SolidManyToOneFilterElement.d.ts +0 -2
- package/dist/components/core/kanban/SolidManyToOneFilterElement.d.ts.map +0 -1
- package/dist/components/core/kanban/SolidManyToOneFilterElement.js +0 -87
- package/dist/components/core/kanban/SolidManyToOneFilterElement.js.map +0 -1
- package/dist/components/core/kanban/SolidManyToOneFilterElement.tsx +0 -59
- package/dist/components/core/kanban/SolidSelectionDynamicFilterElement.d.ts +0 -2
- package/dist/components/core/kanban/SolidSelectionDynamicFilterElement.d.ts.map +0 -1
- package/dist/components/core/kanban/SolidSelectionDynamicFilterElement.js +0 -73
- package/dist/components/core/kanban/SolidSelectionDynamicFilterElement.js.map +0 -1
- package/dist/components/core/kanban/SolidSelectionDynamicFilterElement.tsx +0 -50
- package/dist/components/core/kanban/SolidSelectionStaticFilterElement.d.ts +0 -2
- package/dist/components/core/kanban/SolidSelectionStaticFilterElement.d.ts.map +0 -1
- package/dist/components/core/kanban/SolidSelectionStaticFilterElement.js +0 -20
- package/dist/components/core/kanban/SolidSelectionStaticFilterElement.js.map +0 -1
- package/dist/components/core/kanban/SolidSelectionStaticFilterElement.tsx +0 -32
- package/dist/components/core/kanban/SolidVarInputsFilterElement.d.ts +0 -12
- package/dist/components/core/kanban/SolidVarInputsFilterElement.d.ts.map +0 -1
- package/dist/components/core/kanban/SolidVarInputsFilterElement.js +0 -81
- package/dist/components/core/kanban/SolidVarInputsFilterElement.js.map +0 -1
- package/dist/components/core/kanban/SolidVarInputsFilterElement.tsx +0 -184
- package/dist/components/core/kanban/kanban-fields/SolidBigintKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidBigintKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidBigintKanbanField.js +0 -7
- package/dist/components/core/kanban/kanban-fields/SolidBigintKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidBigintKanbanField.tsx +0 -9
- package/dist/components/core/kanban/kanban-fields/SolidBooleanKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidBooleanKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidBooleanKanbanField.js +0 -8
- package/dist/components/core/kanban/kanban-fields/SolidBooleanKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidBooleanKanbanField.tsx +0 -16
- package/dist/components/core/kanban/kanban-fields/SolidComputedKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidComputedKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidComputedKanbanField.js +0 -21
- package/dist/components/core/kanban/kanban-fields/SolidComputedKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidComputedKanbanField.tsx +0 -23
- package/dist/components/core/kanban/kanban-fields/SolidDateKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidDateKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidDateKanbanField.js +0 -8
- package/dist/components/core/kanban/kanban-fields/SolidDateKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidDateKanbanField.tsx +0 -14
- package/dist/components/core/kanban/kanban-fields/SolidDatetimeKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidDatetimeKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidDatetimeKanbanField.js +0 -8
- package/dist/components/core/kanban/kanban-fields/SolidDatetimeKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidDatetimeKanbanField.tsx +0 -13
- package/dist/components/core/kanban/kanban-fields/SolidDecimalKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidDecimalKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidDecimalKanbanField.js +0 -7
- package/dist/components/core/kanban/kanban-fields/SolidDecimalKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidDecimalKanbanField.tsx +0 -9
- package/dist/components/core/kanban/kanban-fields/SolidExternalIdKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidExternalIdKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidExternalIdKanbanField.js +0 -8
- package/dist/components/core/kanban/kanban-fields/SolidExternalIdKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidExternalIdKanbanField.tsx +0 -12
- package/dist/components/core/kanban/kanban-fields/SolidFloatKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidFloatKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidFloatKanbanField.js +0 -7
- package/dist/components/core/kanban/kanban-fields/SolidFloatKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidFloatKanbanField.tsx +0 -9
- package/dist/components/core/kanban/kanban-fields/SolidIdKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidIdKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidIdKanbanField.js +0 -8
- package/dist/components/core/kanban/kanban-fields/SolidIdKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidIdKanbanField.tsx +0 -14
- package/dist/components/core/kanban/kanban-fields/SolidIntKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidIntKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidIntKanbanField.js +0 -16
- package/dist/components/core/kanban/kanban-fields/SolidIntKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidIntKanbanField.tsx +0 -20
- package/dist/components/core/kanban/kanban-fields/SolidLongTextKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidLongTextKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidLongTextKanbanField.js +0 -7
- package/dist/components/core/kanban/kanban-fields/SolidLongTextKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidLongTextKanbanField.tsx +0 -9
- package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.js +0 -56
- package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.tsx +0 -140
- package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.js +0 -42
- package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.tsx +0 -164
- package/dist/components/core/kanban/kanban-fields/SolidRelationKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidRelationKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidRelationKanbanField.js +0 -11
- package/dist/components/core/kanban/kanban-fields/SolidRelationKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidRelationKanbanField.tsx +0 -13
- package/dist/components/core/kanban/kanban-fields/SolidRichTextKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidRichTextKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidRichTextKanbanField.js +0 -7
- package/dist/components/core/kanban/kanban-fields/SolidRichTextKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidRichTextKanbanField.tsx +0 -9
- package/dist/components/core/kanban/kanban-fields/SolidSelectionDynamicKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidSelectionDynamicKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidSelectionDynamicKanbanField.js +0 -8
- package/dist/components/core/kanban/kanban-fields/SolidSelectionDynamicKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidSelectionDynamicKanbanField.tsx +0 -14
- package/dist/components/core/kanban/kanban-fields/SolidSelectionStaticKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidSelectionStaticKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidSelectionStaticKanbanField.js +0 -8
- package/dist/components/core/kanban/kanban-fields/SolidSelectionStaticKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidSelectionStaticKanbanField.tsx +0 -14
- package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.js +0 -37
- package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.tsx +0 -121
- package/dist/components/core/kanban/kanban-fields/SolidTimeKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidTimeKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidTimeKanbanField.js +0 -8
- package/dist/components/core/kanban/kanban-fields/SolidTimeKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidTimeKanbanField.tsx +0 -12
- package/dist/components/core/kanban/kanban-fields/SolidUuidKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/SolidUuidKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidUuidKanbanField.js +0 -8
- package/dist/components/core/kanban/kanban-fields/SolidUuidKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/SolidUuidKanbanField.tsx +0 -13
- package/dist/components/core/kanban/kanban-fields/relations/SolidRelationManyToOneKanbanField.d.ts +0 -4
- package/dist/components/core/kanban/kanban-fields/relations/SolidRelationManyToOneKanbanField.d.ts.map +0 -1
- package/dist/components/core/kanban/kanban-fields/relations/SolidRelationManyToOneKanbanField.js +0 -7
- package/dist/components/core/kanban/kanban-fields/relations/SolidRelationManyToOneKanbanField.js.map +0 -1
- package/dist/components/core/kanban/kanban-fields/relations/SolidRelationManyToOneKanbanField.tsx +0 -16
- package/dist/components/core/list/SolidListViewRowButtonContextMenu.d.ts +0 -2
- package/dist/components/core/list/SolidListViewRowButtonContextMenu.d.ts.map +0 -1
- package/dist/components/core/list/SolidListViewRowButtonContextMenu.js +0 -39
- package/dist/components/core/list/SolidListViewRowButtonContextMenu.js.map +0 -1
- package/dist/components/core/list/SolidListViewRowButtonContextMenu.tsx +0 -40
- package/dist/components/core/list/SolidVarInputsFilterElement.d.ts +0 -12
- package/dist/components/core/list/SolidVarInputsFilterElement.d.ts.map +0 -1
- package/dist/components/core/list/SolidVarInputsFilterElement.js +0 -81
- package/dist/components/core/list/SolidVarInputsFilterElement.js.map +0 -1
- package/dist/components/core/list/SolidVarInputsFilterElement.tsx +0 -184
- package/dist/components/core/list/widgets/SolidChatterMessageCoModelEntityIdListViewWidget.d.ts +0 -3
- package/dist/components/core/list/widgets/SolidChatterMessageCoModelEntityIdListViewWidget.d.ts.map +0 -1
- package/dist/components/core/list/widgets/SolidChatterMessageCoModelEntityIdListViewWidget.js +0 -87
- package/dist/components/core/list/widgets/SolidChatterMessageCoModelEntityIdListViewWidget.js.map +0 -1
- package/dist/components/core/list/widgets/SolidChatterMessageCoModelEntityIdListViewWidget.tsx +0 -70
- package/dist/components/core/list/widgets/SolidMqMessageStageListViewWidget.d.ts +0 -3
- package/dist/components/core/list/widgets/SolidMqMessageStageListViewWidget.d.ts.map +0 -1
- package/dist/components/core/list/widgets/SolidMqMessageStageListViewWidget.js +0 -33
- package/dist/components/core/list/widgets/SolidMqMessageStageListViewWidget.js.map +0 -1
- package/dist/components/core/list/widgets/SolidMqMessageStageListViewWidget.tsx +0 -50
- package/dist/components/core/list/widgets/SolidSummarizeListHeaderActionMqMessages.d.ts +0 -3
- package/dist/components/core/list/widgets/SolidSummarizeListHeaderActionMqMessages.d.ts.map +0 -1
- package/dist/components/core/list/widgets/SolidSummarizeListHeaderActionMqMessages.js +0 -158
- package/dist/components/core/list/widgets/SolidSummarizeListHeaderActionMqMessages.js.map +0 -1
- package/dist/components/core/list/widgets/SolidSummarizeListHeaderActionMqMessages.tsx +0 -185
- package/dist/components/layout/DashboardHeader.d.ts +0 -3
- package/dist/components/layout/DashboardHeader.d.ts.map +0 -1
- package/dist/components/layout/DashboardHeader.js +0 -20
- package/dist/components/layout/DashboardHeader.js.map +0 -1
- package/dist/components/layout/DashboardHeader.tsx +0 -94
- package/dist/helpers/# no such endpoints exist, need to calle +0 -3
- package/dist/helpers/ToastContainer.d.ts +0 -4
- package/dist/helpers/ToastContainer.d.ts.map +0 -1
- package/dist/helpers/ToastContainer.js +0 -49
- package/dist/helpers/ToastContainer.js.map +0 -1
- package/dist/helpers/ToastContainer.tsx +0 -94
- package/dist/helpers/showToast.d.ts +0 -5
- package/dist/helpers/showToast.d.ts.map +0 -1
- package/dist/helpers/showToast.js +0 -17
- package/dist/helpers/showToast.js.map +0 -1
- package/dist/helpers/showToast.ts +0 -13
- package/dist/helpers/studioSandbox.d.ts +0 -31
- package/dist/helpers/studioSandbox.d.ts.map +0 -1
- package/dist/helpers/studioSandbox.js +0 -104
- package/dist/helpers/studioSandbox.js.map +0 -1
- package/dist/helpers/studioSandbox.ts +0 -117
- package/dist/nextAuth/authProviders.d.ts +0 -4
- package/dist/nextAuth/authProviders.d.ts.map +0 -1
- package/dist/nextAuth/authProviders.js +0 -198
- package/dist/nextAuth/authProviders.js.map +0 -1
- package/dist/nextAuth/authProviders.tsx +0 -232
- package/dist/nextAuth/handleLogout.d.ts +0 -2
- package/dist/nextAuth/handleLogout.d.ts.map +0 -1
- package/dist/nextAuth/handleLogout.js +0 -36
- package/dist/nextAuth/handleLogout.js.map +0 -1
- package/dist/nextAuth/handleLogout.tsx +0 -39
- package/dist/nextAuth/refreshAccessToken.d.ts +0 -2
- package/dist/nextAuth/refreshAccessToken.d.ts.map +0 -1
- package/dist/nextAuth/refreshAccessToken.js +0 -24
- package/dist/nextAuth/refreshAccessToken.js.map +0 -1
- package/dist/nextAuth/refreshAccessToken.tsx +0 -28
- package/dist/redux/api/dashboardApi.d.ts +0 -23
- package/dist/redux/api/dashboardApi.d.ts.map +0 -1
- package/dist/redux/api/dashboardApi.js +0 -35
- package/dist/redux/api/dashboardApi.js.map +0 -1
- package/dist/redux/api/dashboardApi.ts +0 -56
- package/dist/redux/api/dashboardLayoutApi.d.ts +0 -24
- package/dist/redux/api/dashboardLayoutApi.d.ts.map +0 -1
- package/dist/redux/api/dashboardLayoutApi.js +0 -34
- package/dist/redux/api/dashboardLayoutApi.js.map +0 -1
- package/dist/redux/api/dashboardLayoutApi.ts +0 -55
- package/dist/redux/api/dashboardQuestionApi.d.ts +0 -5
- package/dist/redux/api/dashboardQuestionApi.d.ts.map +0 -1
- package/dist/redux/api/dashboardQuestionApi.js +0 -18
- package/dist/redux/api/dashboardQuestionApi.js.map +0 -1
- package/dist/redux/api/dashboardQuestionApi.ts +0 -17
- package/dist/redux/features/settingsSlice.d.ts +0 -20
- package/dist/redux/features/settingsSlice.d.ts.map +0 -1
- package/dist/redux/features/settingsSlice.js +0 -39
- package/dist/redux/features/settingsSlice.js.map +0 -1
- package/dist/redux/features/settingsSlice.ts +0 -60
- package/dist/resources/images/Footerbg.png +0 -0
- package/dist/resources/images/LoginBanner.png +0 -0
- package/dist/resources/images/dashboard/Ellipse 1.svg +0 -10
- package/dist/resources/images/dashboard/Rectangle 17.svg +0 -10
- package/dist/resources/images/dashboard/Rectangle 25.svg +0 -11
- package/dist/resources/images/dashboard/image 5.svg +0 -9
- package/dist/resources/images/loginhero.png +0 -0
- package/dist/resources/images/logo.png +0 -0
- package/dist/resources/images/radix-logo-white.png +0 -0
- package/dist/resources/images/radix-logo.png +0 -0
- package/dist/resources/images/signupBanner.png +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ArrowLeft,
|
|
3
|
+
Check,
|
|
2
4
|
Cog,
|
|
3
5
|
Database,
|
|
4
6
|
ExternalLink,
|
|
@@ -11,10 +13,11 @@ import {
|
|
|
11
13
|
import { camelCase, startCase } from "lodash";
|
|
12
14
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
13
15
|
import { useDispatch } from "react-redux";
|
|
14
|
-
import { useParams } from "react-router-dom";
|
|
16
|
+
import { useNavigate, useParams } from "react-router-dom";
|
|
15
17
|
import { showToast } from "../../../../redux/features/toastSlice";
|
|
16
18
|
import { SolidJsonEditor } from "../../../../components/core/json/SolidJsonEditor";
|
|
17
19
|
import { Column, SolidDataTable } from "../../../../components/core/list/SolidDataTable";
|
|
20
|
+
import { waitForBackendAvailability } from "../../../../helpers/waitForBackendAvailability";
|
|
18
21
|
import {
|
|
19
22
|
SolidButton,
|
|
20
23
|
SolidCheckbox,
|
|
@@ -38,11 +41,16 @@ import {
|
|
|
38
41
|
type DatasourceIntrospectionMappingPreview,
|
|
39
42
|
type DatasourceIntrospectionMappingRequest,
|
|
40
43
|
type DatasourceIntrospectionTableRecord,
|
|
44
|
+
type DatasourceIntrospectionApplyResponse,
|
|
45
|
+
type DatasourceIntrospectionCreateMigrationResponse,
|
|
41
46
|
useApplyDatasourceIntrospectionMappingMutation,
|
|
47
|
+
useCreateDatasourceIntrospectionMigrationArtifactsMutation,
|
|
48
|
+
useGenerateDatasourceIntrospectionCodeMutation,
|
|
42
49
|
useGetDatasourceIntrospectionBootstrapQuery,
|
|
43
50
|
useGetDatasourceIntrospectionTableDetailQuery,
|
|
44
51
|
useGetDatasourceIntrospectionTablesQuery,
|
|
45
52
|
usePreviewDatasourceIntrospectionMappingMutation,
|
|
53
|
+
useRunDatasourceIntrospectionMigrationMutation,
|
|
46
54
|
} from "../../../../redux/api/datasourceIntrospectionApi";
|
|
47
55
|
import { useGetmodelByIdQuery } from "../../../../redux/api/modelApi";
|
|
48
56
|
import "./DatasourceIntrospectionPage.css";
|
|
@@ -52,9 +60,17 @@ type SessionSettings = {
|
|
|
52
60
|
prioritizeUnmappedTables: boolean;
|
|
53
61
|
};
|
|
54
62
|
|
|
63
|
+
type WorkspaceStep =
|
|
64
|
+
| "configure"
|
|
65
|
+
| "review-json"
|
|
66
|
+
| "generate-code"
|
|
67
|
+
| "create-migrations"
|
|
68
|
+
| "run-migration";
|
|
69
|
+
|
|
55
70
|
type DrawerColumnDraft = {
|
|
56
71
|
columnName: string;
|
|
57
72
|
fieldName: string;
|
|
73
|
+
displayName: string;
|
|
58
74
|
dataType: string;
|
|
59
75
|
solidFieldType: string;
|
|
60
76
|
ormType: string;
|
|
@@ -65,6 +81,7 @@ type DrawerColumnDraft = {
|
|
|
65
81
|
numericScale: number | null;
|
|
66
82
|
ordinalPosition: number | null;
|
|
67
83
|
isAutoGenerated: boolean;
|
|
84
|
+
isDetectedPrimaryKey: boolean;
|
|
68
85
|
handledBySuperclass: boolean;
|
|
69
86
|
superclassFieldName: string | null;
|
|
70
87
|
fieldId: number | null;
|
|
@@ -121,6 +138,49 @@ const scalarFieldTypeOptions = [
|
|
|
121
138
|
];
|
|
122
139
|
|
|
123
140
|
const scalarFieldTypeValueSet = new Set(scalarFieldTypeOptions.map((option) => option.value));
|
|
141
|
+
const mappingStrategyOptions = [
|
|
142
|
+
{ value: "generated_id", label: "Legacy generated id" },
|
|
143
|
+
{ value: "existing_id", label: "Legacy existing id" },
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
function getBaseClassNameForLegacyType(value: "none" | "existing_id" | "generated_id") {
|
|
147
|
+
return value === "existing_id"
|
|
148
|
+
? "LegacyCommonEntityWithExistingId"
|
|
149
|
+
: "LegacyCommonEntityWithGeneratedId";
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function getSuperclassFieldNameForLegacyType(columnName: string, legacyTableType: "none" | "existing_id" | "generated_id") {
|
|
153
|
+
const normalized = columnName.toLowerCase();
|
|
154
|
+
const legacyFieldMap: Record<string, string> = {
|
|
155
|
+
ss_created_at: "createdAt",
|
|
156
|
+
ss_updated_at: "updatedAt",
|
|
157
|
+
ss_deleted_at: "deletedAt",
|
|
158
|
+
ss_deleted_tracker: "deletedTracker",
|
|
159
|
+
ss_published_at: "publishedAt",
|
|
160
|
+
ss_locale_name: "localeName",
|
|
161
|
+
ss_default_entity_locale_id: "defaultEntityLocaleId",
|
|
162
|
+
ss_created_by_id: "createdBy",
|
|
163
|
+
ss_updated_by_id: "updatedBy",
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
if (normalized === "ss_id" && legacyTableType === "generated_id") {
|
|
167
|
+
return "id";
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return legacyFieldMap[normalized] ?? null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function getSuggestedFieldNameForLegacyType(column: Pick<DrawerColumnDraft, "columnName" | "isAutoGenerated">, legacyTableType: "none" | "existing_id" | "generated_id") {
|
|
174
|
+
if (legacyTableType === "existing_id" && column.isAutoGenerated) {
|
|
175
|
+
return "id";
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (legacyTableType === "generated_id" && column.columnName.toLowerCase() === "id") {
|
|
179
|
+
return "legacyId";
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return camelCase(column.columnName.replace(/^ss_/i, ""));
|
|
183
|
+
}
|
|
124
184
|
|
|
125
185
|
function getDefaultOrmTypeForSolidFieldType(dataSourceType: string, solidFieldType: string) {
|
|
126
186
|
const normalizedDatasourceType = dataSourceType.toLowerCase();
|
|
@@ -179,12 +239,6 @@ function getDefaultOrmTypeForSolidFieldType(dataSourceType: string, solidFieldTy
|
|
|
179
239
|
return ormTypesByDatasource[normalizedDatasourceType]?.[solidFieldType] ?? "varchar";
|
|
180
240
|
}
|
|
181
241
|
|
|
182
|
-
function legacyTypeLabel(value: string) {
|
|
183
|
-
if (value === "generated_id") return "Legacy generated id";
|
|
184
|
-
if (value === "existing_id") return "Legacy existing id";
|
|
185
|
-
return "Legacy generated id";
|
|
186
|
-
}
|
|
187
|
-
|
|
188
242
|
function statusLabel(record: DatasourceIntrospectionTableRecord) {
|
|
189
243
|
return record.mapped ? "Mapped" : "Ready to map";
|
|
190
244
|
}
|
|
@@ -198,6 +252,30 @@ function readQueryError(error: any) {
|
|
|
198
252
|
);
|
|
199
253
|
}
|
|
200
254
|
|
|
255
|
+
function isRecoverableGenerateCodeError(error: any) {
|
|
256
|
+
const status = error?.status ?? error?.originalStatus;
|
|
257
|
+
const message = [
|
|
258
|
+
error?.error,
|
|
259
|
+
error?.message,
|
|
260
|
+
error?.data?.message,
|
|
261
|
+
error?.data?.error,
|
|
262
|
+
]
|
|
263
|
+
.filter(Boolean)
|
|
264
|
+
.join(" ")
|
|
265
|
+
.toLowerCase();
|
|
266
|
+
|
|
267
|
+
if (status === "FETCH_ERROR" || status === "TIMEOUT_ERROR" || status === "PARSING_ERROR") {
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return (
|
|
272
|
+
message.includes("failed to fetch")
|
|
273
|
+
|| message.includes("network")
|
|
274
|
+
|| message.includes("load failed")
|
|
275
|
+
|| message.includes("fetch")
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
201
279
|
function normalizeName(value: string) {
|
|
202
280
|
return value.trim().toLowerCase();
|
|
203
281
|
}
|
|
@@ -249,6 +327,7 @@ function buildDrawerDraft(
|
|
|
249
327
|
return {
|
|
250
328
|
columnName: column.columnName,
|
|
251
329
|
fieldName: matchingField?.name ?? column.fieldName,
|
|
330
|
+
displayName: matchingField?.displayName ?? column.displayName,
|
|
252
331
|
dataType: column.dataType,
|
|
253
332
|
solidFieldType: matchingField?.type ?? column.solidFieldType,
|
|
254
333
|
ormType: matchingField?.ormType ?? column.ormType,
|
|
@@ -259,12 +338,13 @@ function buildDrawerDraft(
|
|
|
259
338
|
numericScale: column.numericScale,
|
|
260
339
|
ordinalPosition: column.ordinalPosition,
|
|
261
340
|
isAutoGenerated: column.isAutoGenerated,
|
|
341
|
+
isDetectedPrimaryKey: column.isPrimaryKey,
|
|
262
342
|
handledBySuperclass: column.handledBySuperclass,
|
|
263
343
|
superclassFieldName: column.superclassFieldName,
|
|
264
344
|
fieldId: matchingField?.id ?? null,
|
|
265
345
|
include: column.handledBySuperclass ? false : Boolean(matchingField) || !selectedTable.mapped,
|
|
266
346
|
matched: Boolean(matchingField),
|
|
267
|
-
isPrimaryKey: Boolean(matchingField?.isPrimaryKey) || (column.isAutoGenerated && column.fieldName === "id"),
|
|
347
|
+
isPrimaryKey: Boolean(matchingField?.isPrimaryKey) || column.isPrimaryKey || (column.isAutoGenerated && column.fieldName === "id"),
|
|
268
348
|
};
|
|
269
349
|
});
|
|
270
350
|
|
|
@@ -319,6 +399,11 @@ function getDrawerValidationErrors(draft: DrawerDraft) {
|
|
|
319
399
|
continue;
|
|
320
400
|
}
|
|
321
401
|
|
|
402
|
+
if (!column.displayName.trim()) {
|
|
403
|
+
errors.push(`Field label is required for column "${column.columnName}".`);
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
|
|
322
407
|
if (!scalarFieldTypeValueSet.has(column.solidFieldType)) {
|
|
323
408
|
errors.push(`SolidX type "${column.solidFieldType}" is not allowed in step 1 for column "${column.columnName}".`);
|
|
324
409
|
continue;
|
|
@@ -377,6 +462,7 @@ function buildMappingRequest(
|
|
|
377
462
|
columns: draft.columns.map((column) => ({
|
|
378
463
|
columnName: column.columnName,
|
|
379
464
|
fieldName: column.fieldName,
|
|
465
|
+
displayName: column.displayName,
|
|
380
466
|
dataType: column.dataType,
|
|
381
467
|
solidFieldType: column.solidFieldType,
|
|
382
468
|
ormType: column.ormType,
|
|
@@ -541,6 +627,7 @@ function parseAndValidateReviewedModelJson(
|
|
|
541
627
|
|
|
542
628
|
export function DatasourceIntrospectionPage() {
|
|
543
629
|
const params = useParams();
|
|
630
|
+
const navigate = useNavigate();
|
|
544
631
|
const dispatch = useDispatch();
|
|
545
632
|
const moduleId = Number(params.moduleId ?? 0);
|
|
546
633
|
const isValidModuleId = Number.isFinite(moduleId) && moduleId > 0;
|
|
@@ -556,16 +643,25 @@ export function DatasourceIntrospectionPage() {
|
|
|
556
643
|
});
|
|
557
644
|
|
|
558
645
|
const [selectedDatasource, setSelectedDatasource] = useState("");
|
|
559
|
-
const [
|
|
646
|
+
const [selectedRows, setSelectedRows] = useState<DatasourceIntrospectionTableRecord[]>([]);
|
|
647
|
+
const [workspaceTableKey, setWorkspaceTableKey] = useState("");
|
|
560
648
|
const [tableSearch, setTableSearch] = useState("");
|
|
561
649
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
562
650
|
const [settingsTab, setSettingsTab] = useState("datasource-info");
|
|
563
|
-
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
564
651
|
const [drawerDraft, setDrawerDraft] = useState<DrawerDraft | null>(null);
|
|
565
652
|
const [drawerTab, setDrawerTab] = useState("general-info");
|
|
566
|
-
const [
|
|
567
|
-
const [reviewTab, setReviewTab] = useState("metadata-json");
|
|
653
|
+
const [workspaceStep, setWorkspaceStep] = useState<WorkspaceStep>("configure");
|
|
568
654
|
const [mappingPreview, setMappingPreview] = useState<DatasourceIntrospectionMappingPreview | null>(null);
|
|
655
|
+
const [persistedMappingResult, setPersistedMappingResult] = useState<DatasourceIntrospectionApplyResponse | null>(null);
|
|
656
|
+
const [migrationArtifactsResult, setMigrationArtifactsResult] = useState<DatasourceIntrospectionCreateMigrationResponse | null>(null);
|
|
657
|
+
const [generateCodeOutput, setGenerateCodeOutput] = useState("");
|
|
658
|
+
const [isGeneratingCodeWorkflow, setIsGeneratingCodeWorkflow] = useState(false);
|
|
659
|
+
const [generateCodeStatusMessage, setGenerateCodeStatusMessage] = useState("");
|
|
660
|
+
const [generateCodeTimeoutMessage, setGenerateCodeTimeoutMessage] = useState<string | null>(null);
|
|
661
|
+
const [generateCodeReady, setGenerateCodeReady] = useState(false);
|
|
662
|
+
const [hasAttemptedGenerateCode, setHasAttemptedGenerateCode] = useState(false);
|
|
663
|
+
const [runMigrationOutput, setRunMigrationOutput] = useState("");
|
|
664
|
+
const [runMigrationCompleted, setRunMigrationCompleted] = useState(false);
|
|
569
665
|
const [reviewedMetadataJsonValue, setReviewedMetadataJsonValue] = useState<any>(null);
|
|
570
666
|
const [metadataJsonText, setMetadataJsonText] = useState("");
|
|
571
667
|
const [metadataJsonValidationError, setMetadataJsonValidationError] = useState<string | null>(null);
|
|
@@ -578,15 +674,6 @@ export function DatasourceIntrospectionPage() {
|
|
|
578
674
|
const [draftSessionSettings, setDraftSessionSettings] = useState<SessionSettings>(sessionSettings);
|
|
579
675
|
const drawerBootstrapTimerRef = useRef<number | null>(null);
|
|
580
676
|
|
|
581
|
-
const scrollDrawerBodyToTop = () => {
|
|
582
|
-
if (typeof document === "undefined") return;
|
|
583
|
-
|
|
584
|
-
window.requestAnimationFrame(() => {
|
|
585
|
-
const drawerBody = document.querySelector<HTMLDivElement>(".sdix-drawer-body");
|
|
586
|
-
drawerBody?.scrollTo({ top: 0, left: 0 });
|
|
587
|
-
});
|
|
588
|
-
};
|
|
589
|
-
|
|
590
677
|
const [
|
|
591
678
|
previewMapping,
|
|
592
679
|
{ isLoading: isPreviewMappingLoading },
|
|
@@ -596,8 +683,21 @@ export function DatasourceIntrospectionPage() {
|
|
|
596
683
|
applyMapping,
|
|
597
684
|
{ isLoading: isApplyMappingLoading },
|
|
598
685
|
] = useApplyDatasourceIntrospectionMappingMutation();
|
|
686
|
+
const [
|
|
687
|
+
createMigrationArtifacts,
|
|
688
|
+
{ isLoading: isCreateMigrationArtifactsLoading },
|
|
689
|
+
] = useCreateDatasourceIntrospectionMigrationArtifactsMutation();
|
|
690
|
+
const [
|
|
691
|
+
generateCode,
|
|
692
|
+
{ isLoading: isGenerateCodeLoading },
|
|
693
|
+
] = useGenerateDatasourceIntrospectionCodeMutation();
|
|
694
|
+
const [
|
|
695
|
+
runMigration,
|
|
696
|
+
{ isLoading: isRunMigrationLoading },
|
|
697
|
+
] = useRunDatasourceIntrospectionMigrationMutation();
|
|
599
698
|
|
|
600
699
|
const isSavingMapping = isApplyMappingLoading;
|
|
700
|
+
const isCreatingMigrationArtifacts = isCreateMigrationArtifactsLoading;
|
|
601
701
|
|
|
602
702
|
useEffect(() => {
|
|
603
703
|
if (!bootstrap) return;
|
|
@@ -608,13 +708,22 @@ export function DatasourceIntrospectionPage() {
|
|
|
608
708
|
}, [bootstrap, selectedDatasource]);
|
|
609
709
|
|
|
610
710
|
useEffect(() => {
|
|
611
|
-
|
|
711
|
+
setSelectedRows([]);
|
|
712
|
+
setWorkspaceTableKey("");
|
|
612
713
|
setDrawerDraft(null);
|
|
613
|
-
setDrawerOpen(false);
|
|
614
714
|
setTableSearch("");
|
|
615
|
-
|
|
616
|
-
setReviewTab("metadata-json");
|
|
715
|
+
setWorkspaceStep("configure");
|
|
617
716
|
setMappingPreview(null);
|
|
717
|
+
setPersistedMappingResult(null);
|
|
718
|
+
setMigrationArtifactsResult(null);
|
|
719
|
+
setGenerateCodeOutput("");
|
|
720
|
+
setIsGeneratingCodeWorkflow(false);
|
|
721
|
+
setGenerateCodeStatusMessage("");
|
|
722
|
+
setGenerateCodeTimeoutMessage(null);
|
|
723
|
+
setGenerateCodeReady(false);
|
|
724
|
+
setHasAttemptedGenerateCode(false);
|
|
725
|
+
setRunMigrationOutput("");
|
|
726
|
+
setRunMigrationCompleted(false);
|
|
618
727
|
setReviewedMetadataJsonValue(null);
|
|
619
728
|
setMetadataJsonText("");
|
|
620
729
|
setMetadataJsonValidationError(null);
|
|
@@ -627,11 +736,6 @@ export function DatasourceIntrospectionPage() {
|
|
|
627
736
|
}
|
|
628
737
|
}, []);
|
|
629
738
|
|
|
630
|
-
useEffect(() => {
|
|
631
|
-
if (!drawerOpen) return;
|
|
632
|
-
scrollDrawerBodyToTop();
|
|
633
|
-
}, [drawerOpen, drawerStep, drawerTab, reviewTab, selectedTableKey]);
|
|
634
|
-
|
|
635
739
|
const datasourceOptions = useMemo(
|
|
636
740
|
() => (bootstrap?.datasources ?? []).map((datasource) => ({
|
|
637
741
|
label: `${datasource.displayName} (${providerLabel(datasource.type)})`,
|
|
@@ -653,9 +757,13 @@ export function DatasourceIntrospectionPage() {
|
|
|
653
757
|
},
|
|
654
758
|
);
|
|
655
759
|
|
|
760
|
+
const selectedListRow = selectedRows[0] ?? null;
|
|
761
|
+
const selectedListRowKey = selectedListRow ? `${selectedListRow.schema ?? ""}::${selectedListRow.tableName}` : "";
|
|
762
|
+
const isWorkspaceMode = Boolean(workspaceTableKey);
|
|
763
|
+
|
|
656
764
|
const selectedTable = useMemo(
|
|
657
|
-
() => tablesResponse?.records?.find((record) => `${record.schema ?? ""}::${record.tableName}` ===
|
|
658
|
-
[tablesResponse,
|
|
765
|
+
() => tablesResponse?.records?.find((record) => `${record.schema ?? ""}::${record.tableName}` === workspaceTableKey) ?? null,
|
|
766
|
+
[tablesResponse, workspaceTableKey],
|
|
659
767
|
);
|
|
660
768
|
|
|
661
769
|
const {
|
|
@@ -672,7 +780,7 @@ export function DatasourceIntrospectionPage() {
|
|
|
672
780
|
schema: selectedTable?.schema ?? undefined,
|
|
673
781
|
},
|
|
674
782
|
{
|
|
675
|
-
skip: !
|
|
783
|
+
skip: !isWorkspaceMode || !isValidModuleId || !selectedDatasource || !selectedTable || !!tablesResponse?.synchronizeBlocked,
|
|
676
784
|
},
|
|
677
785
|
);
|
|
678
786
|
|
|
@@ -682,7 +790,7 @@ export function DatasourceIntrospectionPage() {
|
|
|
682
790
|
isFetching: isMappedModelFetching,
|
|
683
791
|
error: mappedModelError,
|
|
684
792
|
} = useGetmodelByIdQuery(selectedTable?.mappedModelId ?? 0, {
|
|
685
|
-
skip: !
|
|
793
|
+
skip: !isWorkspaceMode || !selectedTable?.mapped || !selectedTable?.mappedModelId,
|
|
686
794
|
});
|
|
687
795
|
|
|
688
796
|
const mappedModelData = mappedModelResponse?.data;
|
|
@@ -700,7 +808,43 @@ export function DatasourceIntrospectionPage() {
|
|
|
700
808
|
);
|
|
701
809
|
|
|
702
810
|
useEffect(() => {
|
|
703
|
-
if (!
|
|
811
|
+
if (!isWorkspaceMode) {
|
|
812
|
+
setDrawerDraft(null);
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
if (drawerBootstrapTimerRef.current) {
|
|
817
|
+
window.clearTimeout(drawerBootstrapTimerRef.current);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
setDrawerDraft(null);
|
|
821
|
+
setDrawerTab("general-info");
|
|
822
|
+
setWorkspaceStep("configure");
|
|
823
|
+
setMappingPreview(null);
|
|
824
|
+
setPersistedMappingResult(null);
|
|
825
|
+
setMigrationArtifactsResult(null);
|
|
826
|
+
setGenerateCodeOutput("");
|
|
827
|
+
setIsGeneratingCodeWorkflow(false);
|
|
828
|
+
setGenerateCodeStatusMessage("");
|
|
829
|
+
setGenerateCodeTimeoutMessage(null);
|
|
830
|
+
setGenerateCodeReady(false);
|
|
831
|
+
setHasAttemptedGenerateCode(false);
|
|
832
|
+
setRunMigrationOutput("");
|
|
833
|
+
setRunMigrationCompleted(false);
|
|
834
|
+
setReviewedMetadataJsonValue(null);
|
|
835
|
+
setMetadataJsonText("");
|
|
836
|
+
setMetadataJsonValidationError(null);
|
|
837
|
+
setMetadataJsonResetToken(`table-${workspaceTableKey}-${Date.now()}`);
|
|
838
|
+
setDrawerBootstrapping(true);
|
|
839
|
+
}, [isWorkspaceMode, workspaceTableKey]);
|
|
840
|
+
|
|
841
|
+
useEffect(() => {
|
|
842
|
+
if (!isWorkspaceMode || !selectedTable) return;
|
|
843
|
+
setSelectedRows([selectedTable]);
|
|
844
|
+
}, [isWorkspaceMode, selectedTable]);
|
|
845
|
+
|
|
846
|
+
useEffect(() => {
|
|
847
|
+
if (!isWorkspaceMode || !selectedTable || !tableDetail) return;
|
|
704
848
|
if (selectedTable.mapped && (!mappedModelData || mappedModelData.id !== selectedTable.mappedModelId)) return;
|
|
705
849
|
|
|
706
850
|
if (drawerBootstrapTimerRef.current) {
|
|
@@ -715,7 +859,7 @@ export function DatasourceIntrospectionPage() {
|
|
|
715
859
|
drawerBootstrapTimerRef.current = window.setTimeout(() => {
|
|
716
860
|
setDrawerBootstrapping(false);
|
|
717
861
|
}, 150);
|
|
718
|
-
}, [
|
|
862
|
+
}, [isWorkspaceMode, selectedTable, tableDetail, mappedModelData, mappedModelResponse]);
|
|
719
863
|
|
|
720
864
|
const filteredRecords = useMemo(() => {
|
|
721
865
|
const records = [...(tablesResponse?.records ?? [])];
|
|
@@ -723,7 +867,7 @@ export function DatasourceIntrospectionPage() {
|
|
|
723
867
|
|
|
724
868
|
const filtered = searchNeedle
|
|
725
869
|
? records.filter((record) => {
|
|
726
|
-
const haystack = `${record.tableName} ${record.schema ?? ""} ${record.mappedModelSingularName ?? ""} ${record.mappedModelDisplayName ?? ""}`.toLowerCase();
|
|
870
|
+
const haystack = `${record.tableName} ${record.schema ?? ""} ${record.mappedModelSingularName ?? ""} ${record.mappedModelDisplayName ?? ""} ${record.mappedModuleName ?? ""} ${record.mappedModuleDisplayName ?? ""}`.toLowerCase();
|
|
727
871
|
return haystack.includes(searchNeedle);
|
|
728
872
|
})
|
|
729
873
|
: records;
|
|
@@ -848,28 +992,45 @@ export function DatasourceIntrospectionPage() {
|
|
|
848
992
|
if (selectedDatasource) {
|
|
849
993
|
await refetchTables();
|
|
850
994
|
}
|
|
851
|
-
if (selectedTable) {
|
|
995
|
+
if (isWorkspaceMode && selectedTable) {
|
|
852
996
|
await refetchTableDetail();
|
|
853
997
|
}
|
|
854
998
|
};
|
|
855
999
|
|
|
856
|
-
const
|
|
1000
|
+
const startMappingForRecord = (record: DatasourceIntrospectionTableRecord) => {
|
|
857
1001
|
if (drawerBootstrapTimerRef.current) {
|
|
858
1002
|
window.clearTimeout(drawerBootstrapTimerRef.current);
|
|
859
1003
|
}
|
|
860
1004
|
|
|
861
|
-
|
|
1005
|
+
setSelectedRows([record]);
|
|
1006
|
+
setWorkspaceTableKey(`${record.schema ?? ""}::${record.tableName}`);
|
|
1007
|
+
};
|
|
1008
|
+
|
|
1009
|
+
const leaveWorkspace = () => {
|
|
1010
|
+
if (drawerBootstrapTimerRef.current) {
|
|
1011
|
+
window.clearTimeout(drawerBootstrapTimerRef.current);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
setWorkspaceTableKey("");
|
|
862
1015
|
setDrawerDraft(null);
|
|
1016
|
+
setWorkspaceStep("configure");
|
|
863
1017
|
setDrawerTab("general-info");
|
|
864
|
-
setDrawerStep("edit");
|
|
865
|
-
setReviewTab("metadata-json");
|
|
866
1018
|
setMappingPreview(null);
|
|
1019
|
+
setPersistedMappingResult(null);
|
|
1020
|
+
setMigrationArtifactsResult(null);
|
|
1021
|
+
setGenerateCodeOutput("");
|
|
1022
|
+
setIsGeneratingCodeWorkflow(false);
|
|
1023
|
+
setGenerateCodeStatusMessage("");
|
|
1024
|
+
setGenerateCodeTimeoutMessage(null);
|
|
1025
|
+
setGenerateCodeReady(false);
|
|
1026
|
+
setHasAttemptedGenerateCode(false);
|
|
1027
|
+
setRunMigrationOutput("");
|
|
1028
|
+
setRunMigrationCompleted(false);
|
|
867
1029
|
setReviewedMetadataJsonValue(null);
|
|
868
1030
|
setMetadataJsonText("");
|
|
869
1031
|
setMetadataJsonValidationError(null);
|
|
870
|
-
setMetadataJsonResetToken(`
|
|
871
|
-
setDrawerBootstrapping(
|
|
872
|
-
setDrawerOpen(true);
|
|
1032
|
+
setMetadataJsonResetToken(`workspace-closed-${Date.now()}`);
|
|
1033
|
+
setDrawerBootstrapping(false);
|
|
873
1034
|
};
|
|
874
1035
|
|
|
875
1036
|
const applyDraftSettings = () => {
|
|
@@ -879,6 +1040,15 @@ export function DatasourceIntrospectionPage() {
|
|
|
879
1040
|
|
|
880
1041
|
const updateDrawerDraft = (updater: (current: DrawerDraft) => DrawerDraft) => {
|
|
881
1042
|
setMappingPreview(null);
|
|
1043
|
+
setPersistedMappingResult(null);
|
|
1044
|
+
setMigrationArtifactsResult(null);
|
|
1045
|
+
setGenerateCodeOutput("");
|
|
1046
|
+
setIsGeneratingCodeWorkflow(false);
|
|
1047
|
+
setGenerateCodeStatusMessage("");
|
|
1048
|
+
setGenerateCodeTimeoutMessage(null);
|
|
1049
|
+
setGenerateCodeReady(false);
|
|
1050
|
+
setHasAttemptedGenerateCode(false);
|
|
1051
|
+
setRunMigrationOutput("");
|
|
882
1052
|
setDrawerDraft((current) => (current ? updater(current) : current));
|
|
883
1053
|
};
|
|
884
1054
|
|
|
@@ -891,7 +1061,16 @@ export function DatasourceIntrospectionPage() {
|
|
|
891
1061
|
...current,
|
|
892
1062
|
columns: current.columns.map((column) => {
|
|
893
1063
|
if (column.columnName !== columnName) return column;
|
|
894
|
-
|
|
1064
|
+
|
|
1065
|
+
const previousSuggestedLabel = startCase(column.fieldName);
|
|
1066
|
+
const nextNormalizedFieldName = camelCase(nextFieldName);
|
|
1067
|
+
return {
|
|
1068
|
+
...column,
|
|
1069
|
+
fieldName: nextNormalizedFieldName,
|
|
1070
|
+
displayName: !column.displayName.trim() || column.displayName === previousSuggestedLabel
|
|
1071
|
+
? startCase(nextNormalizedFieldName)
|
|
1072
|
+
: column.displayName,
|
|
1073
|
+
};
|
|
895
1074
|
}),
|
|
896
1075
|
userKeyField: current.userKeyField === current.columns.find((column) => column.columnName === columnName)?.fieldName
|
|
897
1076
|
? camelCase(nextFieldName)
|
|
@@ -899,6 +1078,17 @@ export function DatasourceIntrospectionPage() {
|
|
|
899
1078
|
}));
|
|
900
1079
|
};
|
|
901
1080
|
|
|
1081
|
+
const updateColumnDisplayName = (columnName: string, nextDisplayName: string) => {
|
|
1082
|
+
updateDrawerDraft((current) => ({
|
|
1083
|
+
...current,
|
|
1084
|
+
columns: current.columns.map((column) => (
|
|
1085
|
+
column.columnName === columnName
|
|
1086
|
+
? { ...column, displayName: nextDisplayName }
|
|
1087
|
+
: column
|
|
1088
|
+
)),
|
|
1089
|
+
}));
|
|
1090
|
+
};
|
|
1091
|
+
|
|
902
1092
|
const updateColumnSolidFieldType = (columnName: string, nextSolidFieldType: string) => {
|
|
903
1093
|
updateDrawerDraft((current) => ({
|
|
904
1094
|
...current,
|
|
@@ -915,6 +1105,55 @@ export function DatasourceIntrospectionPage() {
|
|
|
915
1105
|
}));
|
|
916
1106
|
};
|
|
917
1107
|
|
|
1108
|
+
const updateLegacyTableType = (legacyTableType: "none" | "existing_id" | "generated_id") => {
|
|
1109
|
+
updateDrawerDraft((current) => {
|
|
1110
|
+
const renamedUserKeyColumns = new Map<string, string>();
|
|
1111
|
+
|
|
1112
|
+
const columns = current.columns.map((column) => {
|
|
1113
|
+
const nextSuperclassFieldName = getSuperclassFieldNameForLegacyType(column.columnName, legacyTableType);
|
|
1114
|
+
const nextHandledBySuperclass = Boolean(nextSuperclassFieldName);
|
|
1115
|
+
const nextSuggestedFieldName = getSuggestedFieldNameForLegacyType(column, legacyTableType);
|
|
1116
|
+
const shouldRebuildFieldName = column.handledBySuperclass !== nextHandledBySuperclass
|
|
1117
|
+
|| (legacyTableType === "existing_id" && column.isAutoGenerated && (column.fieldName === "id" || column.fieldName === "legacyId"))
|
|
1118
|
+
|| (legacyTableType === "generated_id" && column.columnName.toLowerCase() === "id");
|
|
1119
|
+
const nextFieldName = shouldRebuildFieldName ? nextSuggestedFieldName : column.fieldName;
|
|
1120
|
+
const nextDisplayName = !column.displayName.trim() || column.displayName === startCase(column.fieldName)
|
|
1121
|
+
? startCase(nextFieldName)
|
|
1122
|
+
: column.displayName;
|
|
1123
|
+
const nextInclude = nextHandledBySuperclass
|
|
1124
|
+
? false
|
|
1125
|
+
: (legacyTableType === "existing_id" && column.isAutoGenerated ? true : column.include);
|
|
1126
|
+
const nextIsPrimaryKey = (
|
|
1127
|
+
legacyTableType === "existing_id" && column.isAutoGenerated && nextFieldName === "id"
|
|
1128
|
+
) || (
|
|
1129
|
+
legacyTableType === "generated_id" && column.isDetectedPrimaryKey
|
|
1130
|
+
);
|
|
1131
|
+
|
|
1132
|
+
if (current.userKeyField === column.fieldName && current.userKeyField !== nextFieldName) {
|
|
1133
|
+
renamedUserKeyColumns.set(column.fieldName, nextFieldName);
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
return {
|
|
1137
|
+
...column,
|
|
1138
|
+
fieldName: nextFieldName,
|
|
1139
|
+
displayName: nextDisplayName,
|
|
1140
|
+
handledBySuperclass: nextHandledBySuperclass,
|
|
1141
|
+
superclassFieldName: nextSuperclassFieldName,
|
|
1142
|
+
include: nextInclude,
|
|
1143
|
+
isPrimaryKey: nextIsPrimaryKey,
|
|
1144
|
+
};
|
|
1145
|
+
});
|
|
1146
|
+
|
|
1147
|
+
return {
|
|
1148
|
+
...current,
|
|
1149
|
+
legacyTableType,
|
|
1150
|
+
baseClassName: getBaseClassNameForLegacyType(legacyTableType),
|
|
1151
|
+
columns,
|
|
1152
|
+
userKeyField: renamedUserKeyColumns.get(current.userKeyField) ?? current.userKeyField,
|
|
1153
|
+
};
|
|
1154
|
+
});
|
|
1155
|
+
};
|
|
1156
|
+
|
|
918
1157
|
const setColumnIncluded = (columnName: string, include: boolean) => {
|
|
919
1158
|
updateDrawerDraft((current) => ({
|
|
920
1159
|
...current,
|
|
@@ -956,7 +1195,7 @@ export function DatasourceIntrospectionPage() {
|
|
|
956
1195
|
window.open(`/admin/core/solid-core/model-metadata/form/${targetModelId}`, "_blank", "noopener,noreferrer");
|
|
957
1196
|
};
|
|
958
1197
|
|
|
959
|
-
const
|
|
1198
|
+
const reviewMappingJson = async () => {
|
|
960
1199
|
if (!drawerDraft || !bootstrap?.module?.id) return;
|
|
961
1200
|
|
|
962
1201
|
const validationErrors = getDrawerValidationErrors(drawerDraft);
|
|
@@ -978,8 +1217,11 @@ export function DatasourceIntrospectionPage() {
|
|
|
978
1217
|
setMetadataJsonText(JSON.stringify(preview.metadataJson.model, null, 2));
|
|
979
1218
|
setMetadataJsonValidationError(null);
|
|
980
1219
|
setMetadataJsonResetToken(`preview-${preview.metadataJson.filePath}-${Date.now()}`);
|
|
981
|
-
|
|
982
|
-
|
|
1220
|
+
setPersistedMappingResult(null);
|
|
1221
|
+
setMigrationArtifactsResult(null);
|
|
1222
|
+
setGenerateCodeOutput("");
|
|
1223
|
+
setRunMigrationOutput("");
|
|
1224
|
+
setWorkspaceStep("review-json");
|
|
983
1225
|
} catch (error: any) {
|
|
984
1226
|
dispatch(showToast({
|
|
985
1227
|
severity: "error",
|
|
@@ -989,7 +1231,7 @@ export function DatasourceIntrospectionPage() {
|
|
|
989
1231
|
}
|
|
990
1232
|
};
|
|
991
1233
|
|
|
992
|
-
const
|
|
1234
|
+
const persistMappingArtifacts = async () => {
|
|
993
1235
|
if (!drawerDraft || !bootstrap?.module?.id) return;
|
|
994
1236
|
|
|
995
1237
|
const validationErrors = getDrawerValidationErrors(drawerDraft);
|
|
@@ -997,15 +1239,14 @@ export function DatasourceIntrospectionPage() {
|
|
|
997
1239
|
validationErrors.forEach((detail) => {
|
|
998
1240
|
dispatch(showToast({ severity: "error", summary: "Validation", detail }));
|
|
999
1241
|
});
|
|
1000
|
-
|
|
1242
|
+
setWorkspaceStep("configure");
|
|
1001
1243
|
return;
|
|
1002
1244
|
}
|
|
1003
1245
|
|
|
1004
1246
|
const reviewedModelValidation = parseAndValidateReviewedModelJson(metadataJsonText, drawerDraft);
|
|
1005
1247
|
if (reviewedModelValidation.error || !reviewedModelValidation.parsed) {
|
|
1006
1248
|
setMetadataJsonValidationError(reviewedModelValidation.error ?? "Metadata JSON is invalid.");
|
|
1007
|
-
|
|
1008
|
-
setDrawerStep("review");
|
|
1249
|
+
setWorkspaceStep("review-json");
|
|
1009
1250
|
dispatch(showToast({
|
|
1010
1251
|
severity: "error",
|
|
1011
1252
|
summary: "Validation",
|
|
@@ -1027,28 +1268,179 @@ export function DatasourceIntrospectionPage() {
|
|
|
1027
1268
|
|
|
1028
1269
|
dispatch(showToast({
|
|
1029
1270
|
severity: "success",
|
|
1030
|
-
summary: "
|
|
1271
|
+
summary: "Mapping saved",
|
|
1272
|
+
detail: drawerDraft.mapped
|
|
1273
|
+
? "The model mapping metadata was updated successfully."
|
|
1274
|
+
: "The model mapping metadata was created successfully.",
|
|
1275
|
+
}));
|
|
1276
|
+
|
|
1277
|
+
setPersistedMappingResult(response);
|
|
1278
|
+
setMigrationArtifactsResult(null);
|
|
1279
|
+
setGenerateCodeOutput("");
|
|
1280
|
+
setIsGeneratingCodeWorkflow(false);
|
|
1281
|
+
setGenerateCodeStatusMessage("");
|
|
1282
|
+
setGenerateCodeTimeoutMessage(null);
|
|
1283
|
+
setGenerateCodeReady(false);
|
|
1284
|
+
setHasAttemptedGenerateCode(false);
|
|
1285
|
+
setRunMigrationOutput("");
|
|
1286
|
+
setRunMigrationCompleted(false);
|
|
1287
|
+
setDrawerDraft((current) => (
|
|
1288
|
+
current
|
|
1289
|
+
? {
|
|
1290
|
+
...current,
|
|
1291
|
+
mapped: true,
|
|
1292
|
+
modelId: response.modelId,
|
|
1293
|
+
}
|
|
1294
|
+
: current
|
|
1295
|
+
));
|
|
1296
|
+
setWorkspaceStep("generate-code");
|
|
1297
|
+
} catch (error: any) {
|
|
1298
|
+
dispatch(showToast({
|
|
1299
|
+
severity: "error",
|
|
1300
|
+
summary: "Save failed",
|
|
1301
|
+
detail: readQueryError(error),
|
|
1302
|
+
}));
|
|
1303
|
+
}
|
|
1304
|
+
};
|
|
1305
|
+
|
|
1306
|
+
const handleGenerateCode = async () => {
|
|
1307
|
+
if (!bootstrap?.module?.id) return;
|
|
1308
|
+
|
|
1309
|
+
setHasAttemptedGenerateCode(true);
|
|
1310
|
+
setRunMigrationCompleted(false);
|
|
1311
|
+
setIsGeneratingCodeWorkflow(true);
|
|
1312
|
+
setGenerateCodeStatusMessage("Submitting module generate-code request...");
|
|
1313
|
+
setGenerateCodeTimeoutMessage(null);
|
|
1314
|
+
setGenerateCodeReady(false);
|
|
1315
|
+
let responseMessage = "";
|
|
1316
|
+
|
|
1317
|
+
try {
|
|
1318
|
+
const response = await generateCode({ moduleId: bootstrap.module.id }).unwrap();
|
|
1319
|
+
responseMessage = response.output || response.message || "";
|
|
1320
|
+
setGenerateCodeOutput(responseMessage);
|
|
1321
|
+
setGenerateCodeStatusMessage("Waiting briefly for the backend restart window...");
|
|
1322
|
+
} catch (error: any) {
|
|
1323
|
+
if (!isRecoverableGenerateCodeError(error)) {
|
|
1324
|
+
setIsGeneratingCodeWorkflow(false);
|
|
1325
|
+
setGenerateCodeStatusMessage("");
|
|
1326
|
+
setGenerateCodeTimeoutMessage(null);
|
|
1327
|
+
setGenerateCodeReady(false);
|
|
1328
|
+
dispatch(showToast({
|
|
1329
|
+
severity: "error",
|
|
1330
|
+
summary: "Generate code failed",
|
|
1331
|
+
detail: readQueryError(error),
|
|
1332
|
+
}));
|
|
1333
|
+
return;
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
setGenerateCodeStatusMessage("The API connection dropped during restart. Waiting for the backend to come back online...");
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
await new Promise((resolve) => window.setTimeout(resolve, 5000));
|
|
1340
|
+
setGenerateCodeStatusMessage("Checking if the backend is back online...");
|
|
1341
|
+
|
|
1342
|
+
const isBackendAvailable = await waitForBackendAvailability({
|
|
1343
|
+
retries: 40,
|
|
1344
|
+
delayMs: 1500,
|
|
1345
|
+
});
|
|
1346
|
+
|
|
1347
|
+
setIsGeneratingCodeWorkflow(false);
|
|
1348
|
+
|
|
1349
|
+
if (!isBackendAvailable) {
|
|
1350
|
+
setGenerateCodeTimeoutMessage(
|
|
1351
|
+
"Code generation took longer than expected. The backend did not come back within 60 seconds, so there may be a compilation failure or another startup issue. Please review the generated code manually and check the API logs before continuing.",
|
|
1352
|
+
);
|
|
1353
|
+
dispatch(showToast({
|
|
1354
|
+
severity: "warn",
|
|
1355
|
+
summary: "Backend restart taking too long",
|
|
1356
|
+
detail: "The generate-code request completed, but the backend did not come back within 60 seconds.",
|
|
1357
|
+
}));
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
setGenerateCodeStatusMessage("Backend is back online. You can continue.");
|
|
1362
|
+
setGenerateCodeReady(true);
|
|
1363
|
+
setMigrationArtifactsResult(null);
|
|
1364
|
+
setRunMigrationOutput("");
|
|
1365
|
+
dispatch(showToast({
|
|
1366
|
+
severity: "success",
|
|
1367
|
+
summary: "Code generated",
|
|
1368
|
+
detail: responseMessage || "The backend is back online. You can continue to the migration artifacts step.",
|
|
1369
|
+
}));
|
|
1370
|
+
};
|
|
1371
|
+
|
|
1372
|
+
const handleCreateMigrationArtifacts = async () => {
|
|
1373
|
+
if (!drawerDraft || !bootstrap?.module?.id || !persistedMappingResult?.modelId) return;
|
|
1374
|
+
|
|
1375
|
+
const reviewedModelValidation = parseAndValidateReviewedModelJson(metadataJsonText, drawerDraft);
|
|
1376
|
+
if (reviewedModelValidation.error || !reviewedModelValidation.parsed) {
|
|
1377
|
+
setMetadataJsonValidationError(reviewedModelValidation.error ?? "Metadata JSON is invalid.");
|
|
1378
|
+
setWorkspaceStep("review-json");
|
|
1379
|
+
dispatch(showToast({
|
|
1380
|
+
severity: "error",
|
|
1381
|
+
summary: "Validation",
|
|
1382
|
+
detail: reviewedModelValidation.error ?? "Metadata JSON is invalid.",
|
|
1383
|
+
}));
|
|
1384
|
+
return;
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
try {
|
|
1388
|
+
const response = await createMigrationArtifacts({
|
|
1389
|
+
moduleId: bootstrap.module.id,
|
|
1390
|
+
payload: {
|
|
1391
|
+
...buildMappingRequest(
|
|
1392
|
+
{
|
|
1393
|
+
...drawerDraft,
|
|
1394
|
+
mapped: true,
|
|
1395
|
+
modelId: persistedMappingResult.modelId,
|
|
1396
|
+
},
|
|
1397
|
+
mappingPreview?.migration.timestamp ?? null,
|
|
1398
|
+
),
|
|
1399
|
+
reviewedModel: reviewedModelValidation.parsed,
|
|
1400
|
+
},
|
|
1401
|
+
}).unwrap();
|
|
1402
|
+
|
|
1403
|
+
setMigrationArtifactsResult(response);
|
|
1404
|
+
setWorkspaceStep("run-migration");
|
|
1405
|
+
dispatch(showToast({
|
|
1406
|
+
severity: "success",
|
|
1407
|
+
summary: "Migration artifacts created",
|
|
1031
1408
|
detail: response.migration.written
|
|
1032
|
-
? "The
|
|
1033
|
-
:
|
|
1034
|
-
|
|
1035
|
-
|
|
1409
|
+
? "The migration file and datasource registration were written successfully."
|
|
1410
|
+
: "No migration file was required, but the datasource registration was updated successfully.",
|
|
1411
|
+
}));
|
|
1412
|
+
} catch (error: any) {
|
|
1413
|
+
dispatch(showToast({
|
|
1414
|
+
severity: "error",
|
|
1415
|
+
summary: "Create migration artifacts failed",
|
|
1416
|
+
detail: readQueryError(error),
|
|
1417
|
+
}));
|
|
1418
|
+
}
|
|
1419
|
+
};
|
|
1420
|
+
|
|
1421
|
+
const handleRunMigration = async () => {
|
|
1422
|
+
if (!bootstrap?.module?.id || !selectedDatasource) return;
|
|
1423
|
+
|
|
1424
|
+
try {
|
|
1425
|
+
const response = await runMigration({
|
|
1426
|
+
moduleId: bootstrap.module.id,
|
|
1427
|
+
datasource: selectedDatasource,
|
|
1428
|
+
}).unwrap();
|
|
1429
|
+
|
|
1430
|
+
setRunMigrationOutput(response.output || response.message || "");
|
|
1431
|
+
setRunMigrationCompleted(true);
|
|
1432
|
+
dispatch(showToast({
|
|
1433
|
+
severity: "success",
|
|
1434
|
+
summary: "Migration complete",
|
|
1435
|
+
detail: response.message || `Migrations ran successfully for datasource "${selectedDatasource}".`,
|
|
1036
1436
|
}));
|
|
1037
1437
|
|
|
1038
|
-
setDrawerOpen(false);
|
|
1039
|
-
setDrawerDraft(null);
|
|
1040
|
-
setMappingPreview(null);
|
|
1041
|
-
setReviewedMetadataJsonValue(null);
|
|
1042
|
-
setMetadataJsonText("");
|
|
1043
|
-
setMetadataJsonValidationError(null);
|
|
1044
|
-
setMetadataJsonResetToken(`saved-${Date.now()}`);
|
|
1045
|
-
setDrawerStep("edit");
|
|
1046
1438
|
await refetchTables();
|
|
1047
1439
|
await refetchBootstrap();
|
|
1048
1440
|
} catch (error: any) {
|
|
1049
1441
|
dispatch(showToast({
|
|
1050
1442
|
severity: "error",
|
|
1051
|
-
summary: "
|
|
1443
|
+
summary: "Run migration failed",
|
|
1052
1444
|
detail: readQueryError(error),
|
|
1053
1445
|
}));
|
|
1054
1446
|
}
|
|
@@ -1066,6 +1458,65 @@ export function DatasourceIntrospectionPage() {
|
|
|
1066
1458
|
);
|
|
1067
1459
|
}
|
|
1068
1460
|
|
|
1461
|
+
const stepSequence: WorkspaceStep[] = [
|
|
1462
|
+
"configure",
|
|
1463
|
+
"review-json",
|
|
1464
|
+
"generate-code",
|
|
1465
|
+
"create-migrations",
|
|
1466
|
+
"run-migration",
|
|
1467
|
+
];
|
|
1468
|
+
const currentStepIndex = stepSequence.indexOf(workspaceStep);
|
|
1469
|
+
const stepperItems = [
|
|
1470
|
+
{
|
|
1471
|
+
key: "configure" as const,
|
|
1472
|
+
label: "Configure Mapping",
|
|
1473
|
+
complete: currentStepIndex > 0,
|
|
1474
|
+
active: workspaceStep === "configure",
|
|
1475
|
+
disabled: false,
|
|
1476
|
+
onClick: () => setWorkspaceStep("configure"),
|
|
1477
|
+
},
|
|
1478
|
+
{
|
|
1479
|
+
key: "review-json" as const,
|
|
1480
|
+
label: "Review Mapping JSON",
|
|
1481
|
+
complete: currentStepIndex > 1,
|
|
1482
|
+
active: workspaceStep === "review-json",
|
|
1483
|
+
disabled: !mappingPreview,
|
|
1484
|
+
onClick: () => {
|
|
1485
|
+
if (mappingPreview) setWorkspaceStep("review-json");
|
|
1486
|
+
},
|
|
1487
|
+
},
|
|
1488
|
+
{
|
|
1489
|
+
key: "generate-code" as const,
|
|
1490
|
+
label: "Generate Code",
|
|
1491
|
+
complete: currentStepIndex > 2,
|
|
1492
|
+
active: workspaceStep === "generate-code",
|
|
1493
|
+
disabled: !persistedMappingResult,
|
|
1494
|
+
onClick: () => {
|
|
1495
|
+
if (persistedMappingResult) setWorkspaceStep("generate-code");
|
|
1496
|
+
},
|
|
1497
|
+
},
|
|
1498
|
+
{
|
|
1499
|
+
key: "create-migrations" as const,
|
|
1500
|
+
label: "Create Migrations",
|
|
1501
|
+
complete: currentStepIndex > 3,
|
|
1502
|
+
active: workspaceStep === "create-migrations",
|
|
1503
|
+
disabled: !hasAttemptedGenerateCode,
|
|
1504
|
+
onClick: () => {
|
|
1505
|
+
if (hasAttemptedGenerateCode) setWorkspaceStep("create-migrations");
|
|
1506
|
+
},
|
|
1507
|
+
},
|
|
1508
|
+
{
|
|
1509
|
+
key: "run-migration" as const,
|
|
1510
|
+
label: "Run Migration",
|
|
1511
|
+
complete: false,
|
|
1512
|
+
active: workspaceStep === "run-migration",
|
|
1513
|
+
disabled: !migrationArtifactsResult,
|
|
1514
|
+
onClick: () => {
|
|
1515
|
+
if (migrationArtifactsResult) setWorkspaceStep("run-migration");
|
|
1516
|
+
},
|
|
1517
|
+
},
|
|
1518
|
+
];
|
|
1519
|
+
|
|
1069
1520
|
const selectableUnmappedColumns = drawerDraft?.columns.filter(
|
|
1070
1521
|
(column) => !column.handledBySuperclass && !column.matched && !column.isPrimaryKey,
|
|
1071
1522
|
) ?? [];
|
|
@@ -1107,19 +1558,20 @@ export function DatasourceIntrospectionPage() {
|
|
|
1107
1558
|
</div>
|
|
1108
1559
|
<div className="sdix-form-field">
|
|
1109
1560
|
<label htmlFor="sdix-user-key-field">User Key Field</label>
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1561
|
+
<SolidSelect
|
|
1562
|
+
id="sdix-user-key-field"
|
|
1563
|
+
value={drawerDraft.userKeyField}
|
|
1564
|
+
options={drawerUserKeyOptions}
|
|
1565
|
+
placeholder="Select user key field"
|
|
1115
1566
|
onChange={(event) => changeUserKeyField(event.value)}
|
|
1116
1567
|
/>
|
|
1117
1568
|
</div>
|
|
1118
1569
|
<div className="sdix-form-field sdix-form-field--full">
|
|
1119
1570
|
<label htmlFor="sdix-description">Description</label>
|
|
1120
1571
|
<SolidTextarea
|
|
1572
|
+
className="sdix-description-textarea"
|
|
1121
1573
|
id="sdix-description"
|
|
1122
|
-
rows={
|
|
1574
|
+
rows={2}
|
|
1123
1575
|
value={drawerDraft.description}
|
|
1124
1576
|
onChange={(event) => updateGeneralField("description", event.target.value)}
|
|
1125
1577
|
/>
|
|
@@ -1163,20 +1615,16 @@ export function DatasourceIntrospectionPage() {
|
|
|
1163
1615
|
/>
|
|
1164
1616
|
</div>
|
|
1165
1617
|
<div className="sdix-form-field">
|
|
1166
|
-
<label htmlFor="sdix-legacy-type">
|
|
1167
|
-
<
|
|
1618
|
+
<label htmlFor="sdix-legacy-type">Mapping Strategy</label>
|
|
1619
|
+
<SolidSelect
|
|
1168
1620
|
id="sdix-legacy-type"
|
|
1169
|
-
value={
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
</div>
|
|
1173
|
-
<div className="sdix-form-field">
|
|
1174
|
-
<label htmlFor="sdix-base-class">Superclass</label>
|
|
1175
|
-
<SolidInput
|
|
1176
|
-
id="sdix-base-class"
|
|
1177
|
-
value={drawerDraft.baseClassName}
|
|
1178
|
-
disabled
|
|
1621
|
+
value={drawerDraft.legacyTableType}
|
|
1622
|
+
options={mappingStrategyOptions}
|
|
1623
|
+
onChange={(event) => updateLegacyTableType(event.value)}
|
|
1179
1624
|
/>
|
|
1625
|
+
<small className="sdix-inline-note">
|
|
1626
|
+
This will use <strong>{drawerDraft.baseClassName}</strong> for the generated entity.
|
|
1627
|
+
</small>
|
|
1180
1628
|
</div>
|
|
1181
1629
|
</div>
|
|
1182
1630
|
</section>
|
|
@@ -1196,10 +1644,6 @@ export function DatasourceIntrospectionPage() {
|
|
|
1196
1644
|
</div>
|
|
1197
1645
|
<div className="sdix-column-table">
|
|
1198
1646
|
<div className="sdix-column-row sdix-column-row--head sdix-column-row--mapping">
|
|
1199
|
-
<span>Column</span>
|
|
1200
|
-
<span>Field</span>
|
|
1201
|
-
<span>Database</span>
|
|
1202
|
-
<span>SolidX</span>
|
|
1203
1647
|
<span className="sdix-column-select-header">
|
|
1204
1648
|
{selectableUnmappedColumns.length ? (
|
|
1205
1649
|
<SolidCheckbox
|
|
@@ -1211,11 +1655,17 @@ export function DatasourceIntrospectionPage() {
|
|
|
1211
1655
|
"Include"
|
|
1212
1656
|
)}
|
|
1213
1657
|
</span>
|
|
1658
|
+
<span>Column</span>
|
|
1659
|
+
<span>Field</span>
|
|
1660
|
+
<span>Label</span>
|
|
1661
|
+
<span>Database</span>
|
|
1662
|
+
<span>SolidX</span>
|
|
1214
1663
|
<span>Status</span>
|
|
1215
1664
|
<span>Action</span>
|
|
1216
1665
|
</div>
|
|
1217
1666
|
{drawerDraft.columns.map((column) => {
|
|
1218
1667
|
const isUserKey = drawerDraft.userKeyField === column.fieldName;
|
|
1668
|
+
const isPrimaryKeyField = column.isPrimaryKey;
|
|
1219
1669
|
const statusClassName = column.handledBySuperclass
|
|
1220
1670
|
? "is-superclass"
|
|
1221
1671
|
: column.include
|
|
@@ -1236,6 +1686,20 @@ export function DatasourceIntrospectionPage() {
|
|
|
1236
1686
|
|
|
1237
1687
|
return (
|
|
1238
1688
|
<div key={column.columnName} className="sdix-column-row sdix-column-row--mapping">
|
|
1689
|
+
<span className="sdix-column-include">
|
|
1690
|
+
{column.handledBySuperclass ? (
|
|
1691
|
+
<span className="sdix-column-placeholder">-</span>
|
|
1692
|
+
) : column.matched ? (
|
|
1693
|
+
<span className="sdix-column-placeholder">-</span>
|
|
1694
|
+
) : column.isPrimaryKey ? (
|
|
1695
|
+
<SolidCheckbox checked disabled aria-label="Required included column" />
|
|
1696
|
+
) : (
|
|
1697
|
+
<SolidCheckbox
|
|
1698
|
+
checked={column.include}
|
|
1699
|
+
onChange={(event) => setColumnIncluded(column.columnName, event.target.checked)}
|
|
1700
|
+
/>
|
|
1701
|
+
)}
|
|
1702
|
+
</span>
|
|
1239
1703
|
<span className="sdix-column-meta">
|
|
1240
1704
|
<strong>{column.columnName}</strong>
|
|
1241
1705
|
{column.isAutoGenerated ? <small>Generated id column</small> : null}
|
|
@@ -1246,7 +1710,19 @@ export function DatasourceIntrospectionPage() {
|
|
|
1246
1710
|
disabled={column.handledBySuperclass}
|
|
1247
1711
|
onChange={(event) => updateColumnFieldName(column.columnName, event.target.value)}
|
|
1248
1712
|
/>
|
|
1249
|
-
{isUserKey
|
|
1713
|
+
{isUserKey || isPrimaryKeyField ? (
|
|
1714
|
+
<div className="sdix-inline-note-stack">
|
|
1715
|
+
{isUserKey ? <small className="sdix-inline-note">User key</small> : null}
|
|
1716
|
+
{isPrimaryKeyField ? <small className="sdix-inline-note">Primary key</small> : null}
|
|
1717
|
+
</div>
|
|
1718
|
+
) : null}
|
|
1719
|
+
</span>
|
|
1720
|
+
<span>
|
|
1721
|
+
<SolidInput
|
|
1722
|
+
value={column.displayName}
|
|
1723
|
+
disabled={column.handledBySuperclass}
|
|
1724
|
+
onChange={(event) => updateColumnDisplayName(column.columnName, event.target.value)}
|
|
1725
|
+
/>
|
|
1250
1726
|
</span>
|
|
1251
1727
|
<span className="sdix-column-meta">
|
|
1252
1728
|
<strong>{column.dataType}</strong>
|
|
@@ -1262,30 +1738,16 @@ export function DatasourceIntrospectionPage() {
|
|
|
1262
1738
|
/>
|
|
1263
1739
|
)}
|
|
1264
1740
|
</span>
|
|
1265
|
-
<span className="sdix-column-include">
|
|
1266
|
-
{column.handledBySuperclass ? (
|
|
1267
|
-
<span className="sdix-column-placeholder">-</span>
|
|
1268
|
-
) : column.matched ? (
|
|
1269
|
-
<span className="sdix-column-placeholder">-</span>
|
|
1270
|
-
) : column.isPrimaryKey ? (
|
|
1271
|
-
<SolidCheckbox checked disabled label="Required" />
|
|
1272
|
-
) : (
|
|
1273
|
-
<SolidCheckbox
|
|
1274
|
-
checked={column.include}
|
|
1275
|
-
onChange={(event) => setColumnIncluded(column.columnName, event.target.checked)}
|
|
1276
|
-
/>
|
|
1277
|
-
)}
|
|
1278
|
-
</span>
|
|
1279
1741
|
<span>
|
|
1280
1742
|
<span className={`sdix-status-badge ${statusClassName}`}>{statusText}</span>
|
|
1281
1743
|
</span>
|
|
1282
1744
|
<span className="sdix-column-action">
|
|
1283
1745
|
{column.handledBySuperclass ? (
|
|
1284
|
-
<SolidButton size="small" variant="outline" disabled>
|
|
1746
|
+
<SolidButton size="small" variant="outline" disabled className="sdix-column-action-chip sdix-column-action-chip--managed">
|
|
1285
1747
|
Managed
|
|
1286
1748
|
</SolidButton>
|
|
1287
1749
|
) : column.isPrimaryKey ? (
|
|
1288
|
-
<SolidButton size="small" variant="outline" disabled>
|
|
1750
|
+
<SolidButton size="small" variant="outline" disabled className="sdix-column-action-chip sdix-column-action-chip--required">
|
|
1289
1751
|
Required
|
|
1290
1752
|
</SolidButton>
|
|
1291
1753
|
) : column.matched ? (
|
|
@@ -1321,120 +1783,223 @@ export function DatasourceIntrospectionPage() {
|
|
|
1321
1783
|
},
|
|
1322
1784
|
] : [];
|
|
1323
1785
|
|
|
1324
|
-
const
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1786
|
+
const reviewJsonPanel = mappingPreview ? (
|
|
1787
|
+
<div className="sdix-review-panel sdix-review-panel--metadata">
|
|
1788
|
+
<div className="sdix-review-meta sdix-review-meta--compact">
|
|
1789
|
+
<span>Target file</span>
|
|
1790
|
+
<strong>{mappingPreview.metadataJson.filePath}</strong>
|
|
1791
|
+
</div>
|
|
1792
|
+
<SolidJsonEditor
|
|
1793
|
+
className="sdix-json-editor"
|
|
1794
|
+
value={reviewedMetadataJsonValue ?? mappingPreview.metadataJson.model}
|
|
1795
|
+
resetToken={metadataJsonResetToken}
|
|
1796
|
+
onValueChange={(nextValue) => {
|
|
1797
|
+
setReviewedMetadataJsonValue(nextValue);
|
|
1798
|
+
if (metadataJsonValidationError) {
|
|
1799
|
+
setMetadataJsonValidationError(null);
|
|
1800
|
+
}
|
|
1801
|
+
}}
|
|
1802
|
+
onTextChange={(nextText) => {
|
|
1803
|
+
setMetadataJsonText(nextText);
|
|
1804
|
+
}}
|
|
1805
|
+
onErrorChange={setMetadataJsonValidationError}
|
|
1806
|
+
/>
|
|
1807
|
+
{metadataJsonValidationError ? (
|
|
1808
|
+
<div className="sdix-json-validation-error">
|
|
1809
|
+
<span>{metadataJsonValidationError}</span>
|
|
1810
|
+
</div>
|
|
1811
|
+
) : null}
|
|
1812
|
+
</div>
|
|
1813
|
+
) : null;
|
|
1814
|
+
|
|
1815
|
+
const createMigrationsPanel = mappingPreview ? (
|
|
1816
|
+
<div className="sdix-review-panel sdix-review-panel--migration">
|
|
1817
|
+
{mappingPreview.migration.willGenerate && mappingPreview.migration.filePath ? (
|
|
1818
|
+
<>
|
|
1330
1819
|
<div className="sdix-review-meta sdix-review-meta--compact">
|
|
1331
1820
|
<span>Target file</span>
|
|
1332
|
-
<strong>{mappingPreview.
|
|
1821
|
+
<strong>{mappingPreview.migration.filePath}</strong>
|
|
1333
1822
|
</div>
|
|
1334
|
-
<
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
setReviewedMetadataJsonValue(nextValue);
|
|
1340
|
-
if (metadataJsonValidationError) {
|
|
1341
|
-
setMetadataJsonValidationError(null);
|
|
1342
|
-
}
|
|
1343
|
-
}}
|
|
1344
|
-
onTextChange={(nextText) => {
|
|
1345
|
-
setMetadataJsonText(nextText);
|
|
1346
|
-
}}
|
|
1347
|
-
onErrorChange={setMetadataJsonValidationError}
|
|
1348
|
-
/>
|
|
1349
|
-
{metadataJsonValidationError ? (
|
|
1350
|
-
<div className="sdix-json-validation-error">
|
|
1351
|
-
<span>{metadataJsonValidationError}</span>
|
|
1352
|
-
</div>
|
|
1823
|
+
<p className="sdix-review-note">
|
|
1824
|
+
This migration preview is generated from the current mapping and stays read-only here. Moving ahead writes the migration file to disk and updates the datasource registration now that the entity code already exists.
|
|
1825
|
+
</p>
|
|
1826
|
+
{mappingPreview.migration.content ? (
|
|
1827
|
+
<pre className="sdix-ddl-code sdix-ddl-code--fill"><code>{mappingPreview.migration.content}</code></pre>
|
|
1353
1828
|
) : null}
|
|
1829
|
+
</>
|
|
1830
|
+
) : (
|
|
1831
|
+
<div className="sdix-empty-state is-inline sdix-ddl-empty">
|
|
1832
|
+
<Database size={18} />
|
|
1833
|
+
<p>{mappingPreview.migration.note}</p>
|
|
1354
1834
|
</div>
|
|
1355
|
-
)
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
</>
|
|
1375
|
-
) : (
|
|
1376
|
-
<div className="sdix-empty-state is-inline sdix-ddl-empty">
|
|
1377
|
-
<Database size={18} />
|
|
1378
|
-
<p>{mappingPreview.migration.note}</p>
|
|
1379
|
-
</div>
|
|
1380
|
-
)}
|
|
1835
|
+
)}
|
|
1836
|
+
</div>
|
|
1837
|
+
) : null;
|
|
1838
|
+
|
|
1839
|
+
const generateCodePanel = (
|
|
1840
|
+
<div className="sdix-stage-panel">
|
|
1841
|
+
<div className="sdix-stage-panel__header">
|
|
1842
|
+
<span className="sdix-stage-panel__eyebrow">Step 3</span>
|
|
1843
|
+
<h3>Generate module code</h3>
|
|
1844
|
+
<p>The reviewed metadata JSON is now persisted. Run the normal SolidX module generation flow next so the entity, DTOs, repository, service, controller, and UI code are refreshed before we register the entity on the datasource and write the migration.</p>
|
|
1845
|
+
</div>
|
|
1846
|
+
<div className="sdix-stage-panel__body">
|
|
1847
|
+
<div className="sdix-stage-panel__card">
|
|
1848
|
+
<div className="sdix-stage-panel__card-title">What happens here</div>
|
|
1849
|
+
<ul className="sdix-stage-panel__list">
|
|
1850
|
+
<li>The module generate-code pipeline runs for <strong>{bootstrap?.module?.displayName}</strong>.</li>
|
|
1851
|
+
<li>The newly mapped model entity is generated inside the module source folder.</li>
|
|
1852
|
+
<li>Any existing generated assets for this module may be refreshed.</li>
|
|
1853
|
+
</ul>
|
|
1381
1854
|
</div>
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
<Search size={15} />
|
|
1392
|
-
<SolidInput
|
|
1393
|
-
value={tableSearch}
|
|
1394
|
-
onChange={(event) => setTableSearch(event.target.value)}
|
|
1395
|
-
placeholder="Search tables"
|
|
1396
|
-
disabled={!selectedDatasource}
|
|
1397
|
-
/>
|
|
1398
|
-
</div>
|
|
1855
|
+
<div className="sdix-stage-panel__actions">
|
|
1856
|
+
<SolidButton
|
|
1857
|
+
leftIcon={<Sparkles size={14} />}
|
|
1858
|
+
loading={isGenerateCodeLoading || isGeneratingCodeWorkflow}
|
|
1859
|
+
disabled={isGenerateCodeLoading || isGeneratingCodeWorkflow}
|
|
1860
|
+
onClick={() => void handleGenerateCode()}
|
|
1861
|
+
>
|
|
1862
|
+
Generate Code
|
|
1863
|
+
</SolidButton>
|
|
1399
1864
|
</div>
|
|
1865
|
+
{isGeneratingCodeWorkflow ? (
|
|
1866
|
+
<div className="sdix-empty-state is-inline sdix-stage-progress">
|
|
1867
|
+
<SolidSpinner size={30} />
|
|
1868
|
+
<h3>Generating code</h3>
|
|
1869
|
+
<p>{generateCodeStatusMessage || "Waiting for the backend to finish restarting..."}</p>
|
|
1870
|
+
</div>
|
|
1871
|
+
) : null}
|
|
1872
|
+
{!isGeneratingCodeWorkflow && generateCodeTimeoutMessage ? (
|
|
1873
|
+
<div className="sdix-error is-inline sdix-stage-progress sdix-stage-progress--warning">
|
|
1874
|
+
<ShieldAlert size={22} />
|
|
1875
|
+
<h3>Manual review recommended</h3>
|
|
1876
|
+
<p>{generateCodeTimeoutMessage}</p>
|
|
1877
|
+
</div>
|
|
1878
|
+
) : null}
|
|
1879
|
+
{generateCodeOutput ? (
|
|
1880
|
+
<pre className="sdix-ddl-code sdix-ddl-code--fill"><code>{generateCodeOutput}</code></pre>
|
|
1881
|
+
) : null}
|
|
1882
|
+
</div>
|
|
1883
|
+
</div>
|
|
1884
|
+
);
|
|
1400
1885
|
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
className="sdix-toolbar-select sdix-toolbar-select--compact"
|
|
1413
|
-
onChange={(event) => setSelectedDatasource(event.value)}
|
|
1414
|
-
/>
|
|
1415
|
-
<SolidButton
|
|
1416
|
-
size="small"
|
|
1417
|
-
className="sdix-icon-button"
|
|
1418
|
-
leftIcon={<RefreshCw size={16} />}
|
|
1419
|
-
onClick={() => void handleRefresh()}
|
|
1420
|
-
tooltip="Refresh"
|
|
1421
|
-
aria-label="Refresh"
|
|
1422
|
-
/>
|
|
1423
|
-
<SolidButton
|
|
1424
|
-
size="small"
|
|
1425
|
-
className="sdix-icon-button"
|
|
1426
|
-
leftIcon={<Cog size={16} />}
|
|
1427
|
-
onClick={() => {
|
|
1428
|
-
setDraftSessionSettings(sessionSettings);
|
|
1429
|
-
setSettingsTab("datasource-info");
|
|
1430
|
-
setSettingsOpen(true);
|
|
1431
|
-
}}
|
|
1432
|
-
tooltip="Session settings"
|
|
1433
|
-
aria-label="Session settings"
|
|
1434
|
-
/>
|
|
1886
|
+
const runMigrationPanel = (
|
|
1887
|
+
<div className="sdix-stage-panel">
|
|
1888
|
+
<div className="sdix-stage-panel__header">
|
|
1889
|
+
<span className="sdix-stage-panel__eyebrow">Step 5</span>
|
|
1890
|
+
<h3>Run datasource migration</h3>
|
|
1891
|
+
<p>With the datasource file updated and module code generated, SolidX can now run the TypeORM migration for the selected datasource and apply the missing system fields to the legacy table.</p>
|
|
1892
|
+
</div>
|
|
1893
|
+
<div className="sdix-stage-panel__body">
|
|
1894
|
+
<div className="sdix-stage-panel__card">
|
|
1895
|
+
<div className="sdix-stage-panel__card-title">Command</div>
|
|
1896
|
+
<pre className="sdix-stage-panel__command"><code>{`npx @solidxai/solidctl@latest migration -d ${selectedDatasource} run`}</code></pre>
|
|
1435
1897
|
</div>
|
|
1898
|
+
{runMigrationCompleted ? (
|
|
1899
|
+
<div className="sdix-empty-state is-inline sdix-stage-progress">
|
|
1900
|
+
<Check size={24} />
|
|
1901
|
+
<h3>Migration finished</h3>
|
|
1902
|
+
<p>Review the output below. When you are satisfied, click Finish to return to the model list.</p>
|
|
1903
|
+
</div>
|
|
1904
|
+
) : null}
|
|
1905
|
+
{runMigrationOutput ? (
|
|
1906
|
+
<pre className="sdix-ddl-code sdix-ddl-code--fill"><code>{runMigrationOutput}</code></pre>
|
|
1907
|
+
) : null}
|
|
1436
1908
|
</div>
|
|
1909
|
+
</div>
|
|
1910
|
+
);
|
|
1911
|
+
|
|
1912
|
+
const workspaceContent = drawerDraft ? (() => {
|
|
1913
|
+
switch (workspaceStep) {
|
|
1914
|
+
case "review-json":
|
|
1915
|
+
return reviewJsonPanel;
|
|
1916
|
+
case "create-migrations":
|
|
1917
|
+
return createMigrationsPanel;
|
|
1918
|
+
case "generate-code":
|
|
1919
|
+
return generateCodePanel;
|
|
1920
|
+
case "run-migration":
|
|
1921
|
+
return runMigrationPanel;
|
|
1922
|
+
case "configure":
|
|
1923
|
+
default:
|
|
1924
|
+
return (
|
|
1925
|
+
<SolidTabGroup
|
|
1926
|
+
tabs={drawerTabs}
|
|
1927
|
+
value={drawerTab}
|
|
1928
|
+
onValueChange={setDrawerTab}
|
|
1929
|
+
className="sdix-drawer-tabs sdix-wizard-tabs"
|
|
1930
|
+
panelClassName="sdix-drawer-tab-panel sdix-wizard-tab-panel"
|
|
1931
|
+
/>
|
|
1932
|
+
);
|
|
1933
|
+
}
|
|
1934
|
+
})() : null;
|
|
1935
|
+
|
|
1936
|
+
const workspaceMeta = drawerDraft ? (() => {
|
|
1937
|
+
switch (workspaceStep) {
|
|
1938
|
+
case "review-json":
|
|
1939
|
+
return (
|
|
1940
|
+
<span>
|
|
1941
|
+
Review the generated metadata JSON before it is written to the module metadata file.
|
|
1942
|
+
</span>
|
|
1943
|
+
);
|
|
1944
|
+
case "generate-code":
|
|
1945
|
+
return persistedMappingResult ? (
|
|
1946
|
+
<span>
|
|
1947
|
+
Metadata JSON has been saved for
|
|
1948
|
+
{" "}
|
|
1949
|
+
<strong>{drawerDraft.displayName || drawerDraft.singularName}</strong>
|
|
1950
|
+
. Generate the module code next so the entity file exists before datasource registration is updated. Continue stays disabled until you attempt code generation at least once.
|
|
1951
|
+
</span>
|
|
1952
|
+
) : (
|
|
1953
|
+
<span>Save the metadata JSON before generating code.</span>
|
|
1954
|
+
);
|
|
1955
|
+
case "create-migrations":
|
|
1956
|
+
return mappingPreview ? (
|
|
1957
|
+
<span>
|
|
1958
|
+
Create the migration artifacts for
|
|
1959
|
+
{" "}
|
|
1960
|
+
<strong>{mappingPreview.summary.includedColumnNames.length}</strong>
|
|
1961
|
+
{" "}
|
|
1962
|
+
mapped columns
|
|
1963
|
+
{mappingPreview.summary.generatedSystemColumnCount
|
|
1964
|
+
? ` and ${mappingPreview.summary.generatedSystemColumnCount} SolidX system column migration changes`
|
|
1965
|
+
: ""}
|
|
1966
|
+
.
|
|
1967
|
+
</span>
|
|
1968
|
+
) : null;
|
|
1969
|
+
case "run-migration":
|
|
1970
|
+
return runMigrationCompleted ? (
|
|
1971
|
+
<span>
|
|
1972
|
+
The datasource migration has completed for
|
|
1973
|
+
{" "}
|
|
1974
|
+
<strong>{selectedDatasource}</strong>
|
|
1975
|
+
. Review the output below and click Finish when you are ready to return to the model list.
|
|
1976
|
+
</span>
|
|
1977
|
+
) : (
|
|
1978
|
+
<span>
|
|
1979
|
+
Run the datasource migration for
|
|
1980
|
+
{" "}
|
|
1981
|
+
<strong>{selectedDatasource}</strong>
|
|
1982
|
+
{" "}
|
|
1983
|
+
to apply the SolidX system columns on the legacy table.
|
|
1984
|
+
</span>
|
|
1985
|
+
);
|
|
1986
|
+
case "configure":
|
|
1987
|
+
default:
|
|
1988
|
+
return drawerDraft.mapped ? (
|
|
1989
|
+
<span>
|
|
1990
|
+
Editing mapped model
|
|
1991
|
+
{" "}
|
|
1992
|
+
<strong>{selectedTable?.mappedModelDisplayName || selectedTable?.mappedModelSingularName}</strong>
|
|
1993
|
+
{drawerDraft.mappedModuleLabel ? ` in ${drawerDraft.mappedModuleLabel}` : ""}
|
|
1994
|
+
</span>
|
|
1995
|
+
) : (
|
|
1996
|
+
<span>Configure the field mapping draft before generating the metadata JSON preview.</span>
|
|
1997
|
+
);
|
|
1998
|
+
}
|
|
1999
|
+
})() : null;
|
|
1437
2000
|
|
|
2001
|
+
return (
|
|
2002
|
+
<div className="sdix-page">
|
|
1438
2003
|
{isBootstrapLoading ? (
|
|
1439
2004
|
<div className="sdix-loading">
|
|
1440
2005
|
<SolidSpinner size={28} />
|
|
@@ -1449,6 +2014,70 @@ export function DatasourceIntrospectionPage() {
|
|
|
1449
2014
|
</div>
|
|
1450
2015
|
) : (
|
|
1451
2016
|
<>
|
|
2017
|
+
{!isWorkspaceMode ? (
|
|
2018
|
+
<div className="sdix-toolbar">
|
|
2019
|
+
<div className="sdix-toolbar__left">
|
|
2020
|
+
<div className="sdix-toolbar-search">
|
|
2021
|
+
<Search size={15} />
|
|
2022
|
+
<SolidInput
|
|
2023
|
+
value={tableSearch}
|
|
2024
|
+
onChange={(event) => setTableSearch(event.target.value)}
|
|
2025
|
+
placeholder="Search tables"
|
|
2026
|
+
disabled={!selectedDatasource}
|
|
2027
|
+
/>
|
|
2028
|
+
</div>
|
|
2029
|
+
</div>
|
|
2030
|
+
|
|
2031
|
+
<div className="sdix-toolbar__actions">
|
|
2032
|
+
{isBootstrapFetching || isTablesFetching ? (
|
|
2033
|
+
<div className="sdix-inline-status">
|
|
2034
|
+
<SolidSpinner size={16} />
|
|
2035
|
+
<span>Refreshing</span>
|
|
2036
|
+
</div>
|
|
2037
|
+
) : null}
|
|
2038
|
+
<SolidButton
|
|
2039
|
+
size="small"
|
|
2040
|
+
leftIcon={<Sparkles size={14} />}
|
|
2041
|
+
onClick={() => {
|
|
2042
|
+
if (selectedListRow) {
|
|
2043
|
+
startMappingForRecord(selectedListRow);
|
|
2044
|
+
}
|
|
2045
|
+
}}
|
|
2046
|
+
disabled={!selectedListRow}
|
|
2047
|
+
>
|
|
2048
|
+
Start Mapping
|
|
2049
|
+
</SolidButton>
|
|
2050
|
+
<SolidSelect
|
|
2051
|
+
value={selectedDatasource}
|
|
2052
|
+
options={datasourceOptions}
|
|
2053
|
+
placeholder="Datasource"
|
|
2054
|
+
className="sdix-toolbar-select sdix-toolbar-select--compact"
|
|
2055
|
+
onChange={(event) => setSelectedDatasource(event.value)}
|
|
2056
|
+
/>
|
|
2057
|
+
<SolidButton
|
|
2058
|
+
size="small"
|
|
2059
|
+
className="sdix-icon-button"
|
|
2060
|
+
leftIcon={<RefreshCw size={16} />}
|
|
2061
|
+
onClick={() => void handleRefresh()}
|
|
2062
|
+
tooltip="Refresh"
|
|
2063
|
+
aria-label="Refresh"
|
|
2064
|
+
/>
|
|
2065
|
+
<SolidButton
|
|
2066
|
+
size="small"
|
|
2067
|
+
className="sdix-icon-button"
|
|
2068
|
+
leftIcon={<Cog size={16} />}
|
|
2069
|
+
onClick={() => {
|
|
2070
|
+
setDraftSessionSettings(sessionSettings);
|
|
2071
|
+
setSettingsTab("datasource-info");
|
|
2072
|
+
setSettingsOpen(true);
|
|
2073
|
+
}}
|
|
2074
|
+
tooltip="Session settings"
|
|
2075
|
+
aria-label="Session settings"
|
|
2076
|
+
/>
|
|
2077
|
+
</div>
|
|
2078
|
+
</div>
|
|
2079
|
+
) : null}
|
|
2080
|
+
|
|
1452
2081
|
{selectedDatasource && tablesResponse?.synchronizeBlocked ? (
|
|
1453
2082
|
<div className="sdix-blocker">
|
|
1454
2083
|
<ShieldAlert size={20} />
|
|
@@ -1459,93 +2088,261 @@ export function DatasourceIntrospectionPage() {
|
|
|
1459
2088
|
</div>
|
|
1460
2089
|
) : null}
|
|
1461
2090
|
|
|
1462
|
-
|
|
1463
|
-
<div className="sdix-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
2091
|
+
{!isWorkspaceMode ? (
|
|
2092
|
+
<div className="sdix-workbench">
|
|
2093
|
+
<div className="sdix-table-shell">
|
|
2094
|
+
{!selectedDatasource ? (
|
|
2095
|
+
<div className="sdix-empty-state is-inline">
|
|
2096
|
+
<Database size={22} />
|
|
2097
|
+
<p>Select a datasource to load its tables.</p>
|
|
2098
|
+
</div>
|
|
2099
|
+
) : isTablesLoading ? (
|
|
2100
|
+
<div className="sdix-loading is-inline">
|
|
2101
|
+
<SolidSpinner size={24} />
|
|
2102
|
+
<p>Inspecting datasource tables...</p>
|
|
2103
|
+
</div>
|
|
2104
|
+
) : tablesError ? (
|
|
2105
|
+
<div className="sdix-error is-inline">
|
|
2106
|
+
<span>{readQueryError(tablesError)}</span>
|
|
2107
|
+
<SolidButton size="small" variant="outline" onClick={() => void refetchTables()}>
|
|
2108
|
+
Retry
|
|
2109
|
+
</SolidButton>
|
|
2110
|
+
</div>
|
|
2111
|
+
) : !filteredRecords.length ? (
|
|
2112
|
+
<div className="sdix-empty-state is-inline">
|
|
2113
|
+
<Database size={22} />
|
|
2114
|
+
<p>{tableSearch ? "No tables match the current quick filter." : "No database tables were discovered for this datasource."}</p>
|
|
2115
|
+
</div>
|
|
2116
|
+
) : (
|
|
2117
|
+
<div className="sdix-table-area">
|
|
2118
|
+
<SolidDataTable
|
|
2119
|
+
value={filteredRecords}
|
|
2120
|
+
dataKey="tableName"
|
|
2121
|
+
viewportHeight="calc(100vh - 162px)"
|
|
2122
|
+
size="small"
|
|
2123
|
+
onRowClick={({ data }) => setSelectedRows([data])}
|
|
2124
|
+
rowClassName={(rowData) => `${rowData.schema ?? ""}::${rowData.tableName}` === selectedListRowKey ? "sdix-table-row-selected" : ""}
|
|
2125
|
+
emptyMessage="No datasource tables found"
|
|
2126
|
+
>
|
|
2127
|
+
<Column
|
|
2128
|
+
header=""
|
|
2129
|
+
body={(rowData: DatasourceIntrospectionTableRecord) => {
|
|
2130
|
+
const rowKey = `${rowData.schema ?? ""}::${rowData.tableName}`;
|
|
2131
|
+
return (
|
|
2132
|
+
<div className="sdix-selection-cell" data-no-row-click="true">
|
|
2133
|
+
<SolidCheckbox
|
|
2134
|
+
checked={rowKey === selectedListRowKey}
|
|
2135
|
+
onChange={(event) => setSelectedRows(event.target.checked ? [rowData] : [])}
|
|
2136
|
+
/>
|
|
2137
|
+
</div>
|
|
2138
|
+
);
|
|
2139
|
+
}}
|
|
2140
|
+
style={{ width: 52, minWidth: 52 }}
|
|
2141
|
+
/>
|
|
2142
|
+
<Column
|
|
2143
|
+
field="tableName"
|
|
2144
|
+
header="Table"
|
|
2145
|
+
body={(rowData: DatasourceIntrospectionTableRecord) => (
|
|
2146
|
+
<div className="sdix-table-primary-cell">
|
|
2147
|
+
<strong>{rowData.tableName}</strong>
|
|
2148
|
+
</div>
|
|
2149
|
+
)}
|
|
2150
|
+
style={{ minWidth: 240 }}
|
|
2151
|
+
/>
|
|
2152
|
+
<Column field="schema" header="Schema" body={(rowData: DatasourceIntrospectionTableRecord) => rowData.schema || "dbo/default"} style={{ minWidth: 120 }} />
|
|
2153
|
+
<Column
|
|
2154
|
+
header="Status"
|
|
2155
|
+
body={(rowData: DatasourceIntrospectionTableRecord) => (
|
|
2156
|
+
<span
|
|
2157
|
+
className={`sdix-status-badge ${rowData.mapped ? "is-mapped" : "is-unmapped"}`}
|
|
2158
|
+
>
|
|
2159
|
+
{statusLabel(rowData)}
|
|
2160
|
+
</span>
|
|
2161
|
+
)}
|
|
2162
|
+
style={{ minWidth: 150 }}
|
|
2163
|
+
/>
|
|
2164
|
+
<Column
|
|
2165
|
+
header="Superclass"
|
|
2166
|
+
body={(rowData: DatasourceIntrospectionTableRecord) => rowData.suggestedBaseClassName}
|
|
2167
|
+
style={{ minWidth: 220 }}
|
|
2168
|
+
/>
|
|
2169
|
+
<Column field="suggestedUserKeyField" header="User Key" style={{ minWidth: 160 }} />
|
|
2170
|
+
<Column
|
|
2171
|
+
header="Mapped Model"
|
|
2172
|
+
body={(rowData: DatasourceIntrospectionTableRecord) => (
|
|
2173
|
+
rowData.mapped
|
|
2174
|
+
? (
|
|
2175
|
+
<div className="sdix-table-primary-cell">
|
|
2176
|
+
<strong>{rowData.mappedModelDisplayName || rowData.mappedModelSingularName || "-"}</strong>
|
|
2177
|
+
{rowData.mappedModuleDisplayName || rowData.mappedModuleName ? (
|
|
2178
|
+
<span>{rowData.mappedModuleDisplayName || rowData.mappedModuleName}</span>
|
|
2179
|
+
) : null}
|
|
2180
|
+
</div>
|
|
2181
|
+
)
|
|
2182
|
+
: <span className="sdix-muted-cell">Not mapped</span>
|
|
2183
|
+
)}
|
|
2184
|
+
style={{ minWidth: 200 }}
|
|
2185
|
+
/>
|
|
2186
|
+
<Column
|
|
2187
|
+
header="System Columns"
|
|
2188
|
+
body={(rowData: DatasourceIntrospectionTableRecord) => Math.max(rowData.columnCount - rowData.physicalColumnCount, 0)}
|
|
2189
|
+
style={{ minWidth: 130 }}
|
|
2190
|
+
/>
|
|
2191
|
+
<Column
|
|
2192
|
+
header="Columns"
|
|
2193
|
+
body={(rowData: DatasourceIntrospectionTableRecord) => rowData.physicalColumnCount}
|
|
2194
|
+
style={{ minWidth: 110 }}
|
|
2195
|
+
/>
|
|
2196
|
+
</SolidDataTable>
|
|
2197
|
+
</div>
|
|
2198
|
+
)}
|
|
1473
2199
|
</div>
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
2200
|
+
</div>
|
|
2201
|
+
) : (
|
|
2202
|
+
<div className="sdix-workspace-screen">
|
|
2203
|
+
<div className="sdix-workspace-header">
|
|
2204
|
+
<SolidButton size="small" variant="outline" leftIcon={<ArrowLeft size={14} />} onClick={leaveWorkspace}>
|
|
2205
|
+
Back
|
|
1479
2206
|
</SolidButton>
|
|
2207
|
+
<div className="sdix-workspace-header__identity sdix-workspace-header__identity--right">
|
|
2208
|
+
<h2>{selectedTable?.tableName || "Mapping workspace"}</h2>
|
|
2209
|
+
<p>
|
|
2210
|
+
{selectedTable
|
|
2211
|
+
? `${selectedTable.schema || "dbo"} · ${selectedDatasourceRecord?.database || selectedDatasourceRecord?.displayName || "Datasource"}${selectedDatasourceRecord ? ` · ${providerLabel(selectedDatasourceRecord.type)}` : ""}`
|
|
2212
|
+
: "Complete the legacy table mapping in a dedicated workspace."}
|
|
2213
|
+
</p>
|
|
2214
|
+
</div>
|
|
1480
2215
|
</div>
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
<
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
size="small"
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
)
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
2216
|
+
|
|
2217
|
+
{!selectedTable && !isTablesLoading ? (
|
|
2218
|
+
<div className="sdix-error">
|
|
2219
|
+
<span>The selected table is no longer available for this datasource.</span>
|
|
2220
|
+
<SolidButton size="small" variant="outline" onClick={leaveWorkspace}>
|
|
2221
|
+
Back to table list
|
|
2222
|
+
</SolidButton>
|
|
2223
|
+
</div>
|
|
2224
|
+
) : drawerLoadingError ? (
|
|
2225
|
+
<div className="sdix-error">
|
|
2226
|
+
<span>{readQueryError(drawerLoadingError)}</span>
|
|
2227
|
+
<SolidButton size="small" variant="outline" onClick={() => void refetchTableDetail()}>
|
|
2228
|
+
Retry
|
|
2229
|
+
</SolidButton>
|
|
2230
|
+
</div>
|
|
2231
|
+
) : isDrawerBlockingLoading ? (
|
|
2232
|
+
<div className="sdix-loading sdix-workspace-loading">
|
|
2233
|
+
<SolidSpinner size={24} />
|
|
2234
|
+
<p>Preparing column mapping preview...</p>
|
|
2235
|
+
</div>
|
|
2236
|
+
) : (
|
|
2237
|
+
<div className="sdix-wizard-shell">
|
|
2238
|
+
<div className="sdix-wizard-stepper">
|
|
2239
|
+
{stepperItems.map((step, index) => (
|
|
2240
|
+
<button
|
|
2241
|
+
key={step.key}
|
|
2242
|
+
type="button"
|
|
2243
|
+
className={[
|
|
2244
|
+
"sdix-wizard-stepper-item",
|
|
2245
|
+
step.active ? "is-active" : "",
|
|
2246
|
+
step.complete ? "is-complete" : "",
|
|
2247
|
+
step.disabled ? "is-disabled" : "",
|
|
2248
|
+
].filter(Boolean).join(" ")}
|
|
2249
|
+
onClick={step.onClick}
|
|
2250
|
+
disabled={step.disabled}
|
|
1513
2251
|
>
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
2252
|
+
<span className="sdix-wizard-stepper-badge">
|
|
2253
|
+
{step.complete ? <Check size={12} /> : index + 1}
|
|
2254
|
+
</span>
|
|
2255
|
+
<span className="sdix-wizard-stepper-label">{step.label}</span>
|
|
2256
|
+
</button>
|
|
2257
|
+
))}
|
|
2258
|
+
</div>
|
|
2259
|
+
|
|
2260
|
+
<div className="sdix-wizard-panel">
|
|
2261
|
+
<div className="sdix-wizard-panel__body">
|
|
2262
|
+
{workspaceContent}
|
|
2263
|
+
</div>
|
|
2264
|
+
</div>
|
|
2265
|
+
|
|
2266
|
+
{drawerDraft ? (
|
|
2267
|
+
<div className="sdix-wizard-footer">
|
|
2268
|
+
<div className="sdix-wizard-footer__meta">{workspaceMeta}</div>
|
|
2269
|
+
<div className="sdix-wizard-footer__actions">
|
|
2270
|
+
{drawerDraft.mapped && drawerDraft.modelId ? (
|
|
2271
|
+
<SolidButton size="small" variant="outline" leftIcon={<ExternalLink size={14} />} onClick={openMappedModelForm}>
|
|
2272
|
+
Open model form
|
|
2273
|
+
</SolidButton>
|
|
2274
|
+
) : null}
|
|
2275
|
+
{workspaceStep === "configure" ? (
|
|
2276
|
+
<SolidButton
|
|
2277
|
+
size="small"
|
|
2278
|
+
leftIcon={<Save size={14} />}
|
|
2279
|
+
loading={isPreviewMappingLoading}
|
|
2280
|
+
onClick={() => void reviewMappingJson()}
|
|
2281
|
+
>
|
|
2282
|
+
Review Mapping JSON
|
|
2283
|
+
</SolidButton>
|
|
2284
|
+
) : null}
|
|
2285
|
+
{workspaceStep === "review-json" ? (
|
|
2286
|
+
<>
|
|
2287
|
+
<SolidButton size="small" variant="outline" onClick={() => setWorkspaceStep("configure")}>
|
|
2288
|
+
Back
|
|
2289
|
+
</SolidButton>
|
|
2290
|
+
<SolidButton size="small" leftIcon={<Save size={14} />} loading={isSavingMapping} onClick={() => void persistMappingArtifacts()}>
|
|
2291
|
+
Save Mapping
|
|
2292
|
+
</SolidButton>
|
|
2293
|
+
</>
|
|
2294
|
+
) : null}
|
|
2295
|
+
{workspaceStep === "generate-code" ? (
|
|
2296
|
+
<>
|
|
2297
|
+
<SolidButton size="small" variant="outline" onClick={() => setWorkspaceStep("review-json")}>
|
|
2298
|
+
Back
|
|
2299
|
+
</SolidButton>
|
|
2300
|
+
<SolidButton
|
|
2301
|
+
size="small"
|
|
2302
|
+
disabled={!hasAttemptedGenerateCode || isGenerateCodeLoading || isGeneratingCodeWorkflow}
|
|
2303
|
+
onClick={() => setWorkspaceStep("create-migrations")}
|
|
2304
|
+
>
|
|
2305
|
+
Continue
|
|
2306
|
+
</SolidButton>
|
|
2307
|
+
</>
|
|
2308
|
+
) : null}
|
|
2309
|
+
{workspaceStep === "create-migrations" ? (
|
|
2310
|
+
<>
|
|
2311
|
+
<SolidButton size="small" variant="outline" onClick={() => setWorkspaceStep("generate-code")}>
|
|
2312
|
+
Back
|
|
2313
|
+
</SolidButton>
|
|
2314
|
+
<SolidButton size="small" leftIcon={<Save size={14} />} loading={isCreatingMigrationArtifacts} onClick={() => void handleCreateMigrationArtifacts()}>
|
|
2315
|
+
Create Migration Artifacts
|
|
2316
|
+
</SolidButton>
|
|
2317
|
+
</>
|
|
2318
|
+
) : null}
|
|
2319
|
+
{workspaceStep === "run-migration" ? (
|
|
2320
|
+
runMigrationCompleted ? (
|
|
2321
|
+
<SolidButton
|
|
2322
|
+
size="small"
|
|
2323
|
+
leftIcon={<Check size={14} />}
|
|
2324
|
+
onClick={() => navigate("/admin/core/solid-core/model-metadata/list")}
|
|
2325
|
+
>
|
|
2326
|
+
Finish
|
|
2327
|
+
</SolidButton>
|
|
2328
|
+
) : (
|
|
2329
|
+
<>
|
|
2330
|
+
<SolidButton size="small" variant="outline" onClick={() => setWorkspaceStep("create-migrations")}>
|
|
2331
|
+
Back
|
|
2332
|
+
</SolidButton>
|
|
2333
|
+
<SolidButton size="small" leftIcon={<Database size={14} />} loading={isRunMigrationLoading} onClick={() => void handleRunMigration()}>
|
|
2334
|
+
Run Migration
|
|
2335
|
+
</SolidButton>
|
|
2336
|
+
</>
|
|
2337
|
+
)
|
|
2338
|
+
) : null}
|
|
2339
|
+
</div>
|
|
2340
|
+
</div>
|
|
2341
|
+
) : null}
|
|
2342
|
+
</div>
|
|
2343
|
+
)}
|
|
1547
2344
|
</div>
|
|
1548
|
-
|
|
2345
|
+
)}
|
|
1549
2346
|
|
|
1550
2347
|
<SolidDialog
|
|
1551
2348
|
open={settingsOpen}
|
|
@@ -1580,138 +2377,6 @@ export function DatasourceIntrospectionPage() {
|
|
|
1580
2377
|
</SolidButton>
|
|
1581
2378
|
</SolidDialogFooter>
|
|
1582
2379
|
</SolidDialog>
|
|
1583
|
-
|
|
1584
|
-
<SolidDialog
|
|
1585
|
-
open={drawerOpen}
|
|
1586
|
-
onOpenChange={setDrawerOpen}
|
|
1587
|
-
className="sdix-drawer"
|
|
1588
|
-
overlayClassName="sdix-drawer-overlay"
|
|
1589
|
-
dismissible
|
|
1590
|
-
>
|
|
1591
|
-
<SolidDialogHeader className="sdix-drawer-header">
|
|
1592
|
-
<div className="sdix-drawer-header__identity">
|
|
1593
|
-
<SolidDialogTitle>{selectedTable?.tableName || "Table details"}</SolidDialogTitle>
|
|
1594
|
-
<SolidDialogDescription className="sdix-drawer-header__meta">
|
|
1595
|
-
{selectedTable
|
|
1596
|
-
? `${selectedTable.schema || "default"} · ${selectedDatasourceRecord?.database || selectedDatasourceRecord?.displayName || "Datasource"}${selectedDatasourceRecord ? ` · ${providerLabel(selectedDatasourceRecord.type)}` : ""}`
|
|
1597
|
-
: "Review mapping details"}
|
|
1598
|
-
</SolidDialogDescription>
|
|
1599
|
-
</div>
|
|
1600
|
-
<SolidDialogClose />
|
|
1601
|
-
</SolidDialogHeader>
|
|
1602
|
-
<SolidDialogSeparator />
|
|
1603
|
-
<SolidDialogBody className="sdix-drawer-body">
|
|
1604
|
-
{!selectedTable ? (
|
|
1605
|
-
<div className="sdix-empty-state is-inline">
|
|
1606
|
-
<Sparkles size={22} />
|
|
1607
|
-
<p>Select a table row to review its structure.</p>
|
|
1608
|
-
</div>
|
|
1609
|
-
) : drawerLoadingError ? (
|
|
1610
|
-
<div className="sdix-error is-inline">
|
|
1611
|
-
<span>{readQueryError(drawerLoadingError)}</span>
|
|
1612
|
-
<SolidButton size="small" variant="outline" onClick={() => void refetchTableDetail()}>
|
|
1613
|
-
Retry
|
|
1614
|
-
</SolidButton>
|
|
1615
|
-
</div>
|
|
1616
|
-
) : isDrawerBlockingLoading ? (
|
|
1617
|
-
<div className="sdix-loading is-inline">
|
|
1618
|
-
<SolidSpinner size={24} />
|
|
1619
|
-
<p>Preparing column mapping preview...</p>
|
|
1620
|
-
</div>
|
|
1621
|
-
) : (
|
|
1622
|
-
<div className="sdix-drawer-stack">
|
|
1623
|
-
{drawerDraft && !drawerDraft.mapped && drawerStep === "edit" ? (
|
|
1624
|
-
<div className="sdix-detail-callout sdix-system-fields-callout">
|
|
1625
|
-
<h3>SolidX system fields are added later</h3>
|
|
1626
|
-
<p>
|
|
1627
|
-
This preview only lists the legacy table columns that already exist today.
|
|
1628
|
-
{" "}
|
|
1629
|
-
Framework system fields from the selected superclass, including the namespaced
|
|
1630
|
-
{" "}
|
|
1631
|
-
<code>ss_*</code>
|
|
1632
|
-
{" "}
|
|
1633
|
-
columns, are introduced when you save the mapping and then generate/apply the follow-up migrations.
|
|
1634
|
-
</p>
|
|
1635
|
-
</div>
|
|
1636
|
-
) : null}
|
|
1637
|
-
{drawerStep === "edit" ? (
|
|
1638
|
-
<SolidTabGroup
|
|
1639
|
-
tabs={drawerTabs}
|
|
1640
|
-
value={drawerTab}
|
|
1641
|
-
onValueChange={setDrawerTab}
|
|
1642
|
-
className="sdix-drawer-tabs"
|
|
1643
|
-
panelClassName="sdix-drawer-tab-panel"
|
|
1644
|
-
/>
|
|
1645
|
-
) : (
|
|
1646
|
-
<SolidTabGroup
|
|
1647
|
-
tabs={reviewTabs}
|
|
1648
|
-
value={reviewTab}
|
|
1649
|
-
onValueChange={setReviewTab}
|
|
1650
|
-
className="sdix-drawer-tabs"
|
|
1651
|
-
panelClassName="sdix-drawer-tab-panel"
|
|
1652
|
-
/>
|
|
1653
|
-
)}
|
|
1654
|
-
</div>
|
|
1655
|
-
)}
|
|
1656
|
-
</SolidDialogBody>
|
|
1657
|
-
{drawerDraft && !isDrawerBlockingLoading ? (
|
|
1658
|
-
<>
|
|
1659
|
-
<SolidDialogSeparator />
|
|
1660
|
-
<SolidDialogFooter className="sdix-drawer-footer">
|
|
1661
|
-
<div className="sdix-drawer-footer__meta">
|
|
1662
|
-
{drawerStep === "review" && mappingPreview ? (
|
|
1663
|
-
<span>
|
|
1664
|
-
Review the metadata update first, then save to apply
|
|
1665
|
-
{" "}
|
|
1666
|
-
<strong>{mappingPreview.summary.includedColumnNames.length}</strong>
|
|
1667
|
-
{" "}
|
|
1668
|
-
mapped columns
|
|
1669
|
-
{mappingPreview.summary.generatedSystemColumnCount
|
|
1670
|
-
? ` and ${mappingPreview.summary.generatedSystemColumnCount} SolidX system column migration changes`
|
|
1671
|
-
: ""}
|
|
1672
|
-
.
|
|
1673
|
-
</span>
|
|
1674
|
-
) : drawerDraft.mapped ? (
|
|
1675
|
-
<span>
|
|
1676
|
-
Editing mapped model
|
|
1677
|
-
{" "}
|
|
1678
|
-
<strong>{selectedTable?.mappedModelDisplayName || selectedTable?.mappedModelSingularName}</strong>
|
|
1679
|
-
{drawerDraft.mappedModuleLabel ? ` in ${drawerDraft.mappedModuleLabel}` : ""}
|
|
1680
|
-
</span>
|
|
1681
|
-
) : (
|
|
1682
|
-
<span>Saving will create the model metadata and write it to the module JSON.</span>
|
|
1683
|
-
)}
|
|
1684
|
-
</div>
|
|
1685
|
-
<div className="sdix-drawer-footer__actions">
|
|
1686
|
-
{drawerDraft.mapped && drawerDraft.modelId ? (
|
|
1687
|
-
<SolidButton size="small" variant="outline" leftIcon={<ExternalLink size={14} />} onClick={openMappedModelForm}>
|
|
1688
|
-
Open model form
|
|
1689
|
-
</SolidButton>
|
|
1690
|
-
) : null}
|
|
1691
|
-
{drawerStep === "review" ? (
|
|
1692
|
-
<>
|
|
1693
|
-
<SolidButton size="small" variant="outline" onClick={() => setDrawerStep("edit")}>
|
|
1694
|
-
Back to editing
|
|
1695
|
-
</SolidButton>
|
|
1696
|
-
<SolidButton size="small" leftIcon={<Save size={14} />} loading={isSavingMapping} onClick={() => void saveMapping()}>
|
|
1697
|
-
Save mapping
|
|
1698
|
-
</SolidButton>
|
|
1699
|
-
</>
|
|
1700
|
-
) : (
|
|
1701
|
-
<SolidButton
|
|
1702
|
-
size="small"
|
|
1703
|
-
leftIcon={<Save size={14} />}
|
|
1704
|
-
loading={isPreviewMappingLoading}
|
|
1705
|
-
onClick={() => void viewChanges()}
|
|
1706
|
-
>
|
|
1707
|
-
View Changes
|
|
1708
|
-
</SolidButton>
|
|
1709
|
-
)}
|
|
1710
|
-
</div>
|
|
1711
|
-
</SolidDialogFooter>
|
|
1712
|
-
</>
|
|
1713
|
-
) : null}
|
|
1714
|
-
</SolidDialog>
|
|
1715
2380
|
</>
|
|
1716
2381
|
)}
|
|
1717
2382
|
</div>
|