@finos/legend-application-studio
Version:
Legend Studio application core
78 lines • 7.63 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 { ChevronLeftIcon, ChevronRightIcon, InfoCircleIcon, LockIcon, MoonIcon, ResizablePanel, ResizablePanelGroup, ResizablePanelSplitter, ResizablePanelSplitterLine, SunIcon, clsx, getCollapsiblePanelGroupProps, } from '@finos/legend-art';
import { prettyCONSTName } from '@finos/legend-shared';
import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
import { CodeEditor } from '@finos/legend-lego/code-editor';
import { INTERNAL__LakehouseGeneratedDatabase } from '@finos/legend-graph';
import { useEditorStore } from '../../EditorStoreProvider.js';
import { DATABASE_EDITOR_TAB, DatabaseEditorState, } from '../../../../stores/editor/editor-state/element-editor-state/DatabaseEditorState.js';
import { DatabaseDiagramCanvas } from './DatabaseDiagramCanvas.js';
import { DatabaseSchemaTree } from './DatabaseSchemaTree.js';
const TABS = [
DATABASE_EDITOR_TAB.VIEW,
DATABASE_EDITOR_TAB.GRAMMAR,
];
/**
* Top-level editor for `Database` elements in form mode. Has two tabs:
* - VIEW (default): Schema → Table → Column tree (left) + React-Flow ERD
* canvas (right). The interactive form mode.
* - GRAMMAR: read-only Pure DSL preview, regenerated on tab switch by
* `setSelectedTab` so it always reflects the current metamodel state.
* Mirrors what global Text Mode would render for this element — included
* here for users who want to peek at the grammar without leaving form
* mode.
*/
export const DatabaseEditor = observer(() => {
const editorStore = useEditorStore();
const editorState = editorStore.tabManagerState.getCurrentEditorState(DatabaseEditorState);
const { selectedTab, database } = editorState;
// Resizable left panel: dragging the splitter all the way left snaps the
// panel to flex=0 (collapsed). The toggle button in the panel header (and
// the expand-rail rendered when collapsed) drives the same flag, so both
// controls stay in sync via `editorState.isSidePanelCollapsed`.
const sidePanelCollapseProps = getCollapsiblePanelGroupProps(editorState.isSidePanelCollapsed, {
// Default width when first opened (in pixels). React-reflex owns the
// exact width after the first user-drag.
size: 320,
onStopResize: (handleProps) => {
// If the user drags the splitter to (or near) zero, persist it as
// collapsed so the toggle button and rail stay in sync. Mirrors
// what `getCollapsiblePanelGroupProps` does internally for the
// styling class but lifts that signal back up to MobX.
const flexGrow = Number(handleProps.domElement.style.flexGrow);
if (flexGrow <= 0.01) {
editorState.setSidePanelCollapsed(true);
}
else if (editorState.isSidePanelCollapsed) {
editorState.setSidePanelCollapsed(false);
}
},
});
return (_jsxs("div", { className: clsx('database-editor', {
// Local light-theme opt-in. Scoped to this editor only — the rest
// of Studio remains in its configured theme. SCSS overrides hang
// off this modifier class.
'database-editor--light': editorState.theme === 'light',
}), children: [_jsxs("div", { className: "database-editor__tabs__header", children: [_jsx("div", { className: "database-editor__tabs", children: TABS.map((tab) => (_jsx("button", { type: "button", onClick: () => editorState.setSelectedTab(tab), className: clsx('database-editor__tab', {
'database-editor__tab--active': tab === selectedTab,
}), children: prettyCONSTName(tab) }, tab))) }), _jsxs("div", { className: "database-editor__read-only-badge", title: "This editor is read-only", children: [_jsx(LockIcon, {}), _jsx("span", { className: "database-editor__read-only-badge__label", children: "READ ONLY" })] }), _jsx("button", { type: "button", className: "database-editor__theme-toggle", onClick: () => editorState.toggleTheme(), title: editorState.theme === 'dark'
? 'Switch to light theme (this editor only)'
: 'Switch to dark theme', children: editorState.theme === 'dark' ? _jsx(SunIcon, {}) : _jsx(MoonIcon, {}) })] }), _jsxs("div", { className: "database-editor__content", children: [database instanceof INTERNAL__LakehouseGeneratedDatabase && (_jsxs("div", { className: "database-editor__generated-banner", title: `Generated from ${database.generatorElement.path}\nOwned by ${database.OWNER.path}`, children: [_jsx(InfoCircleIcon, {}), _jsxs("span", { className: "database-editor__generated-banner__text", children: ["This database is generated by", ' ', _jsx("span", { className: "database-editor__generated-banner__path", children: database.generatorElement.path }), ' — owned by ', _jsx("span", { className: "database-editor__generated-banner__path", children: database.OWNER.path }), "."] })] })), _jsxs("div", { className: "database-editor__content__body", children: [selectedTab === DATABASE_EDITOR_TAB.VIEW && (_jsx("div", { className: "database-diagram", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { ...sidePanelCollapseProps.collapsiblePanel, direction: 1, minSize: 0, children: _jsxs("div", { className: "database-diagram__side-panel-wrapper", children: [_jsxs("div", { className: "database-diagram__side-panel-wrapper__header", children: [_jsx("span", { className: "database-diagram__side-panel-wrapper__header__title", children: "Database" }), _jsx("button", { type: "button", className: "database-diagram__side-panel-wrapper__header__action", onClick: () => editorState.toggleSidePanelCollapsed(), title: "Collapse panel", children: _jsx(ChevronLeftIcon, {}) })] }), _jsx("div", { className: "database-diagram__side-panel-wrapper__body", children: _jsx(DatabaseSchemaTree, { editorState: editorState }) })] }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { ...sidePanelCollapseProps.remainingPanel, minSize: 200, children: _jsxs("div", { className: "database-diagram__canvas-area", children: [editorState.isSidePanelCollapsed && (_jsx("button", { type: "button", className: "database-diagram__expand-rail", onClick: () => editorState.toggleSidePanelCollapsed(), title: "Expand panel", children: _jsx(ChevronRightIcon, {}) })), _jsx("div", { className: "database-diagram__canvas-container", children: _jsx(DatabaseDiagramCanvas, { editorState: editorState }) })] }) })] }) })), selectedTab === DATABASE_EDITOR_TAB.GRAMMAR && (_jsx("div", { className: "database-editor__grammar", children: _jsx(CodeEditor, { inputValue: editorState.textContent, isReadOnly: true, language: CODE_EDITOR_LANGUAGE.PURE }) }))] })] })] }));
});
//# sourceMappingURL=DatabaseEditor.js.map