/** * Copyright (c) 2020-present, Goldman Sachs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ResizablePanelGroup, ResizablePanel, Panel, BaseStepper, PanelContent, Modal, ModalBody, InputWithInlineValidation, PanelHeader, PanelLoadingIndicator, ResizablePanelSplitter, EyeIcon, BlankPanelContent, } from '@finos/legend-art'; import { observer } from 'mobx-react-lite'; import { useEffect, useMemo } from 'react'; import { RelationalConnectionGeneralEditor } from '../connection-editor/RelationalDatabaseConnectionEditor.js'; import { flowResult } from 'mobx'; import { useApplicationStore } from '@finos/legend-application'; import { DatabaseBuilderModalContent } from '../connection-editor/DatabaseBuilderWizard.js'; import { debounce, guaranteeNonNullable } from '@finos/legend-shared'; import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor'; import { CodeEditor } from '@finos/legend-lego/code-editor'; import type { DatabaseBuilderWizardState } from '../../../../stores/editor/editor-state/element-editor-state/connection/DatabaseBuilderWizardState.js'; import { DatabaseModelPackageInput, DatabaseModelPreviewEditor, } from '../connection-editor/DatabaseModelBuilder.js'; import { ConnectionValueStepperState, DatabaseBuilderStepperState, DatabaseGrammarEditorStepperState, DatabaseModelBuilderStepperState, QUERY_CONNECTION_WORKFLOW_STEPS, QueryConnectionConfirmationAndGrammarEditorStepperState, type QueryConnectionEndToEndWorkflowEditorState, } from '../../../../stores/editor/editor-state/end-to-end-workflow-state/QueryConnectionEndToEndWorkflowEditorState.js'; export const QueryConnectionRelationalConnectionEditor = observer( (props: { queryConnectionEndToEndWorkflowState: QueryConnectionEndToEndWorkflowEditorState; connectionValueStepperState: ConnectionValueStepperState; }) => { const { queryConnectionEndToEndWorkflowState, connectionValueStepperState, } = props; const elementAlreadyExistsMessage = queryConnectionEndToEndWorkflowState.editorStore.graphManagerState.graph.allElements .map((s) => s.path) .includes(connectionValueStepperState.targetConnectionPath) ? 'Element with same path already exists' : undefined; const onTargetPathChange: React.ChangeEventHandler = ( event, ) => { connectionValueStepperState.setTargetConnectionPath(event.target.value); }; return (
Target Connection Path
); }, ); export const QueryConnectionDatabaseBuilderEditor = observer( (props: { databaseBuilderState: DatabaseBuilderWizardState }) => { const { databaseBuilderState } = props; const applicationStore = useApplicationStore(); const preview = applicationStore.guardUnhandledError(() => flowResult(databaseBuilderState.previewDatabaseModel()), ); return (
); }, ); export const QueryConnectionDatabaseGrammarEditor = observer( (props: { queryConnectionEndToEndWorkflowState: QueryConnectionEndToEndWorkflowEditorState; databaseGrammarEditorStepperState: DatabaseGrammarEditorStepperState; }) => { const { queryConnectionEndToEndWorkflowState, databaseGrammarEditorStepperState, } = props; const applicationStore = useApplicationStore(); const compile = (): void => { flowResult( databaseGrammarEditorStepperState.compileDatabaseGrammarCode(), ).catch(applicationStore.alertUnhandledError); }; const updateDatabaseGrammar = (val: string): void => { queryConnectionEndToEndWorkflowState.setDatabaseGrammarCode(val); }; return (
Joins could be added manually and please be aware that only one database is supported in this flow
); }, ); export const QueryConnectionModelsEditor = observer( (props: { databaseModelBuilderStepperState: DatabaseModelBuilderStepperState; queryConnectionEndToEndWorkflowState: QueryConnectionEndToEndWorkflowEditorState; }) => { const { databaseModelBuilderStepperState, queryConnectionEndToEndWorkflowState, } = props; const applicationStore = useApplicationStore(); const runtimeElementAlreadyExistsMessage = queryConnectionEndToEndWorkflowState.editorStore.graphManagerState.graph.allElements .map((s) => s.path) .includes(queryConnectionEndToEndWorkflowState.targetRuntimePath) ? 'Element with same path already exists or must contain ::' : undefined; const debouncedRegenerateRuntime = useMemo( () => debounce( (val: string) => { if (val !== '') { queryConnectionEndToEndWorkflowState.updateRuntime(val); } }, 500, ), [queryConnectionEndToEndWorkflowState], ); const changeTargetRuntimePackage: React.ChangeEventHandler< HTMLInputElement > = (event) => { queryConnectionEndToEndWorkflowState.setTargetRuntimePath( event.target.value, ); debouncedRegenerateRuntime(event.target.value); }; useEffect(() => { flowResult( databaseModelBuilderStepperState.databaseModelBuilderState.previewDatabaseModels(), ) .then(() => databaseModelBuilderStepperState.updateGraphWithModels( guaranteeNonNullable( databaseModelBuilderStepperState.databaseModelBuilderState .entities, ), ), ) .catch(applicationStore.alertUnhandledError); }, [ applicationStore, databaseModelBuilderStepperState, databaseModelBuilderStepperState.databaseModelBuilderState, databaseModelBuilderStepperState.databaseModelBuilderState.targetPackage, queryConnectionEndToEndWorkflowState, ]); return (
Target Runtime Path
Target path for runtime
); }, ); export const QueryConnectionConfirmationAndGrammarEditor = observer( (props: { queryConnectionEndToEndWorkflowState: QueryConnectionEndToEndWorkflowEditorState; queryConnectionConfirmationAndGrammarEditorStepperState: QueryConnectionConfirmationAndGrammarEditorStepperState; }) => { const { queryConnectionEndToEndWorkflowState, queryConnectionConfirmationAndGrammarEditorStepperState, } = props; const applicationStore = useApplicationStore(); const compile = (): void => { flowResult( queryConnectionConfirmationAndGrammarEditorStepperState.compile(), ).catch(applicationStore.alertUnhandledError); }; const updateInput = (val: string): void => { queryConnectionEndToEndWorkflowState.setFinalGrammarCode(val); }; return (
Please confirm models below will be added to the project and click query to open query builder
); }, ); export const QueryConnectionWorflowEditor = observer( (props: { connectionToQueryWorkflowState: QueryConnectionEndToEndWorkflowEditorState; }) => { const { connectionToQueryWorkflowState } = props; const applicationStore = useApplicationStore(); const stepLabel = connectionToQueryWorkflowState.activeStepToStepLabel.get( connectionToQueryWorkflowState.activeStep, ); const increaseActiveStep = (): void => { if (connectionToQueryWorkflowState.isValid) { connectionToQueryWorkflowState.setActiveStep( connectionToQueryWorkflowState.activeStep + 1, ); } }; const handleNext = (): void => { if (stepLabel) { flowResult( connectionToQueryWorkflowState.activeStepToBaseStepperState .get(stepLabel) ?.handleNext(), ) .then(() => increaseActiveStep()) .catch(applicationStore.alertUnhandledError); } }; const handleBack = (): void => { connectionToQueryWorkflowState.setCompileError(undefined); connectionToQueryWorkflowState.setActiveStep( connectionToQueryWorkflowState.activeStep - 1, ); }; const renderStepContent = (): React.ReactNode => { if (stepLabel) { const currentState = connectionToQueryWorkflowState.activeStepToBaseStepperState.get( stepLabel, ); if (currentState instanceof ConnectionValueStepperState) { return ( ); } else if (currentState instanceof DatabaseBuilderStepperState) { return ( ); } else if (currentState instanceof DatabaseGrammarEditorStepperState) { return ( ); } else if (currentState instanceof DatabaseModelBuilderStepperState) { return ( ); } else if ( currentState instanceof QueryConnectionConfirmationAndGrammarEditorStepperState ) { return ( ); } } return ; }; return (
{renderStepContent()}
); }, );