@finos/legend-application-studio
Version:
Legend Studio application core
126 lines • 10.7 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
* 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 } 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 { DatabaseSchemaExplorer } from './DatabaseSchemaExplorer.js';
import { DataGrid, } from '@finos/legend-lego/data-grid';
const QueryResultCellRenderer = observer((params) => {
const cellValue = params.value;
return (_jsx("div", { className: clsx('query-builder__result__values__table__cell'), children: _jsx("span", { children: cellValue }) }));
});
const QueryBuilderGridResult = observer((props) => {
const { executionResult } = props;
const applicationStore = useApplicationStore();
const darkMode = !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled;
const rowData = executionResult.result.rows.map((_row, rowIdx) => {
const row = {};
const cols = executionResult.result.columns;
_row.values.forEach((value, colIdx) => {
row[cols[colIdx]] = isBoolean(value) ? String(value) : value;
});
row.rowNumber = rowIdx;
return row;
});
return (_jsx("div", { className: "query-builder__result__values__table", children: _jsx("div", { className: clsx('query-builder__result__tds-grid', {
'ag-theme-balham': !darkMode,
'ag-theme-balham-dark': darkMode,
}), children: _jsx(DataGrid, { rowData: rowData, gridOptions: {
suppressScrollOnNewData: true,
getRowId: (data) => `${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,
},
})) }) }) }));
});
export const DatabaseBuilderModalContent = observer((props) => {
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 = (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 (_jsxs(ModalBody, { className: "database-builder__content", children: [_jsx(PanelLoadingIndicator, { isLoading: isExecutingAction }), _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 450, children: _jsxs(ResizablePanelGroup, { children: [_jsx(ResizablePanel, { children: _jsxs("div", { className: "database-builder__config", children: [_jsx(PanelHeader, { title: "schema explorer" }), _jsx(PanelContent, { className: "database-builder__config__content", children: schemaExplorerState.treeData && (_jsx(DatabaseSchemaExplorer, { treeData: schemaExplorerState.treeData, isReadOnly: false, schemaExplorerState: databaseBuilderState.schemaExplorerState })) })] }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: 'var(--color-dark-grey-250)' }) }), _jsx(ResizablePanel, { children: _jsxs("div", { className: "database-builder__config", children: [_jsx(PanelHeader, { title: "preview" }), _jsx(PanelContent, { className: "database-builder__config__content", children: databaseBuilderState.schemaExplorerState.previewer && (_jsx(QueryBuilderGridResult, { executionResult: databaseBuilderState.schemaExplorerState.previewer })) })] }) })] }) }), _jsx(ResizablePanelSplitter, {}), _jsx(ResizablePanel, { children: _jsxs(Panel, { className: "database-builder__model", children: [_jsx(PanelHeader, { title: "database model" }), _jsx(PanelContent, { children: _jsxs("div", { className: "database-builder__modeler", children: [_jsxs("div", { className: "panel__content__form__section database-builder__modeler__path", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Target Database Path" }), _jsx(InputWithInlineValidation, { className: "panel__content__form__section__input", spellCheck: false, onChange: onTargetPathChange, disabled: schemaExplorerState.makeTargetDatabasePathEditable
? false
: !isCreatingNewDatabase, value: schemaExplorerState.makeTargetDatabasePathEditable ||
isCreatingNewDatabase
? schemaExplorerState.targetDatabasePath
: schemaExplorerState.database.path, error: elementAlreadyExistsMessage, showEditableIcon: true })] }), _jsxs("div", { className: "database-builder__modeler__preview", children: [_jsx("div", { className: "database-builder__modeler__preview__header", children: "readonly" }), databaseBuilderState.databaseGrammarCode && (_jsx(CodeEditor, { language: CODE_EDITOR_LANGUAGE.PURE, inputValue: databaseBuilderState.databaseGrammarCode, isReadOnly: true })), !databaseBuilderState.databaseGrammarCode && (_jsx(BlankPanelContent, { children: "No database preview" }))] })] }) })] }) })] })] }));
});
export const DatabaseBuilderWizard = observer((props) => {
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 = () => {
databaseBuilderState.setShowModal(false);
databaseBuilderState.editorStore.explorerTreeState.setDatabaseBuilderState(undefined);
};
const isExecutingAction = schemaExplorerState.isGeneratingDatabase ||
schemaExplorerState.isUpdatingDatabase ||
schemaExplorerState.previewDataState.isInProgress;
return (_jsx(Dialog, { open: databaseBuilderState.showModal, onClose: noop, classes: { container: 'search-modal__container' }, slotProps: {
paper: {
classes: {
root: 'search-modal__inner-container database-builder__container',
},
},
}, children: _jsxs(Modal, { darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, className: "database-builder", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { title: "Database Builder" }), _jsx(ModalHeaderActions, { children: _jsx("button", { className: "modal__header__action", tabIndex: -1, onClick: closeModal, children: _jsx(TimesIcon, {}) }) })] }), _jsx(DatabaseBuilderModalContent, { databaseBuilderState: databaseBuilderState }), _jsxs(ModalFooter, { children: [_jsx(ModalFooterButton, { className: "database-builder__action--btn", disabled: isReadOnly || isExecutingAction, onClick: preview, title: "Preview database model...", children: "Preview" }), _jsx(ModalFooterButton, { className: "database-builder__action--btn", disabled: isReadOnly ||
isExecutingAction ||
Boolean(elementAlreadyExistsMessage), onClick: updateDatabase, children: "Update Database" })] })] }) }));
});
//# sourceMappingURL=DatabaseBuilderWizard.js.map