/** * 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 { observer } from 'mobx-react-lite'; import { Dialog, ResizablePanelGroup, ResizablePanel, ResizablePanelSplitter, ResizablePanelSplitterLine, PanelLoadingIndicator, PanelContent, Modal, ModalHeader, ModalBody, ModalFooter, ModalTitle, ModalHeaderActions, TimesIcon, ModalFooterButton, BlankPanelContent, PanelHeader, Panel, InputWithInlineValidation, clsx, } from '@finos/legend-art'; import { useEffect } from 'react'; import { isBoolean, noop, type PlainObject } from '@finos/legend-shared'; import { useApplicationStore, useConditionedApplicationNavigationContext, } from '@finos/legend-application'; import { flowResult } from 'mobx'; import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../../__lib__/LegendStudioApplicationNavigationContext.js'; 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 { DatabaseSchemaExplorer } from './DatabaseSchemaExplorer.js'; import { DataGrid, type DataGridCellRendererParams, type DataGridColumnDefinition, } from '@finos/legend-lego/data-grid'; import type { TDSExecutionResult } from '@finos/legend-graph'; type IQueryRendererParamsWithGridType = DataGridCellRendererParams & { tdsExecutionResult: TDSExecutionResult; }; const QueryResultCellRenderer = observer( (params: IQueryRendererParamsWithGridType) => { const cellValue = params.value as string | null | number | undefined; return (
{cellValue}
); }, ); const QueryBuilderGridResult = observer( (props: { executionResult: TDSExecutionResult }) => { const { executionResult } = props; const applicationStore = useApplicationStore(); const darkMode = !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled; const rowData = executionResult.result.rows.map((_row, rowIdx) => { const row: PlainObject = {}; const cols = executionResult.result.columns; _row.values.forEach((value, colIdx) => { row[cols[colIdx] as string] = isBoolean(value) ? String(value) : value; }); row.rowNumber = rowIdx; return row; }); return (
`${data.data.rowNumber}`, }} // NOTE: when column definition changed, we need to force refresh the cell to make sure the cell renderer is updated // See https://stackoverflow.com/questions/56341073/how-to-refresh-an-ag-grid-when-a-change-occurs-inside-a-custom-cell-renderer-com onRowDataUpdated={(params) => { params.api.refreshCells({ force: true }); }} suppressFieldDotNotation={true} columnDefs={executionResult.result.columns.map( (colName) => ({ minWidth: 50, sortable: true, resizable: true, field: colName, flex: 1, cellRenderer: QueryResultCellRenderer, cellRendererParams: { tdsExecutionResult: executionResult, }, }) as DataGridColumnDefinition, )} />
); }, ); export const DatabaseBuilderModalContent = observer( (props: { databaseBuilderState: DatabaseBuilderWizardState }) => { const { databaseBuilderState } = props; const applicationStore = useApplicationStore(); const schemaExplorerState = databaseBuilderState.schemaExplorerState; const isCreatingNewDatabase = schemaExplorerState.isCreatingNewDatabase; const elementAlreadyExistsMessage = isCreatingNewDatabase && databaseBuilderState.editorStore.graphManagerState.graph.allElements .map((s) => s.path) .includes(schemaExplorerState.targetDatabasePath) ? 'Element with same path already exists' : undefined; const isExecutingAction = schemaExplorerState.isGeneratingDatabase || schemaExplorerState.isUpdatingDatabase || schemaExplorerState.previewDataState.isInProgress; const onTargetPathChange: React.ChangeEventHandler = ( event, ) => { schemaExplorerState.setTargetDatabasePath(event.target.value); }; useEffect(() => { flowResult(schemaExplorerState.fetchDatabaseMetadata()).catch( applicationStore.alertUnhandledError, ); }, [applicationStore, schemaExplorerState]); useConditionedApplicationNavigationContext( LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.DATABASE_BUILDER, databaseBuilderState.showModal, ); return (
{schemaExplorerState.treeData && ( )}
{databaseBuilderState.schemaExplorerState.previewer && ( )}
Target Database Path
readonly
{databaseBuilderState.databaseGrammarCode && ( )} {!databaseBuilderState.databaseGrammarCode && ( No database preview )}
); }, ); export const DatabaseBuilderWizard = observer( (props: { databaseBuilderState: DatabaseBuilderWizardState; isReadOnly: boolean; }) => { const { databaseBuilderState, isReadOnly } = props; const schemaExplorerState = databaseBuilderState.schemaExplorerState; const isCreatingNewDatabase = schemaExplorerState.isCreatingNewDatabase; const elementAlreadyExistsMessage = isCreatingNewDatabase && databaseBuilderState.editorStore.graphManagerState.graph.allElements .map((s) => s.path) .includes(schemaExplorerState.targetDatabasePath) ? 'Element with same path already exists' : undefined; const applicationStore = useApplicationStore(); const preview = applicationStore.guardUnhandledError(() => flowResult(databaseBuilderState.previewDatabaseModel()), ); const updateDatabase = applicationStore.guardUnhandledError(() => flowResult(databaseBuilderState.updateDatabase()), ); const closeModal = (): void => { databaseBuilderState.setShowModal(false); databaseBuilderState.editorStore.explorerTreeState.setDatabaseBuilderState( undefined, ); }; const isExecutingAction = schemaExplorerState.isGeneratingDatabase || schemaExplorerState.isUpdatingDatabase || schemaExplorerState.previewDataState.isInProgress; return ( Preview Update Database ); }, );