@finos/legend-application-studio
Version:
Legend Studio application core
252 lines • 12 kB
TypeScript
/**
* 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 { ElementEditorState } from './ElementEditorState.js';
import { type GeneratorFn } from '@finos/legend-shared';
import { type Column, Database, type Filter, type Join, type PackageableElement, type Table, type View } from '@finos/legend-graph';
import type { EditorStore } from '../../EditorStore.js';
/**
* Top-level tabs inside the Database form-mode editor. `VIEW` shows the ERD
* canvas; `GRAMMAR` shows a read-only preview of the same Pure DSL grammar
* that the global Text Mode would render.
*/
export declare enum DATABASE_EDITOR_TAB {
VIEW = "VIEW",
GRAMMAR = "GRAMMAR"
}
/**
* Stable id for an element of the schema tree. We use a string id (rather than
* holding object references) so the side-panel's expand/collapse state can
* survive reprocessing without any cross-instance bookkeeping.
*
* Tables and Views share the same id namespace because they share the same
* `<schema>.<name>` qualifier — the metamodel doesn't allow a table and a view
* to collide on name within a schema.
*/
export declare const getSchemaNodeId: (schemaName: string) => string;
export declare const getRelationNodeId: (schemaName: string, relationName: string) => string;
/**
* Stable key used to look up the Pure-code formula for a single view column
* inside `DatabaseEditorState.viewColumnFormulas`. Joins schema, view, and
* column so it survives reprocessing and can't collide across schemas.
*/
export declare const getViewColumnFormulaKey: (schemaName: string, viewName: string, columnName: string) => string;
/**
* Stable key used to look up the Pure-code formula for a single filter inside
* `DatabaseEditorState.filterFormulas`. Filter names are unique within a
* Database (they live as a flat `Database.filters: Filter[]`), so the name
* alone is sufficient — no schema qualifier needed.
*/
export declare const getFilterFormulaKey: (filterName: string) => string;
/**
* Stable key used to look up the Pure-code formula for a single join. Join
* names are unique within a Database (they live as a flat
* `Database.joins: Join[]`), so the name alone is sufficient. Mirrors the
* filter helper above.
*/
export declare const getJoinFormulaKey: (joinName: string) => string;
/**
* Stable key used to look up the Pure-code formula for a single view's
* groupBy column expression. Views are scoped to a schema and groupBy
* positions matter (the engine renders them in declaration order), so the
* key includes both the schema-qualified view name and the position index.
*/
export declare const getViewGroupByFormulaKey: (schemaName: string, viewName: string, index: number) => string;
/**
* View-only form mode for `Database` elements. Renders an ERD-style canvas
* (tables as nodes, joins as edges) plus a side-panel tree of schemas/tables/
* columns. A second tab shows the same grammar that Text Mode would show.
*
* Layout positions are derived per-render via dagre and not persisted yet —
* persistence + edit support are intended follow-ups.
*/
export declare class DatabaseEditorState extends ElementEditorState {
selectedTab: DATABASE_EDITOR_TAB;
selectedRelation: Table | View | undefined;
selectedColumn: Column | undefined;
selectedJoin: Join | undefined;
selectedFilter: Filter | undefined;
selectedViewColumnName: string | undefined;
expandedSchemaIds: Set<string>;
expandedRelationIds: Set<string>;
panToSelectedRequestCounter: number;
fitAllRequestCounter: number;
resetLayoutRequestCounter: number;
searchText: string;
viewColumnFormulas: Map<string, string>;
isLoadingViewColumnFormulas: boolean;
filterFormulas: Map<string, string>;
isLoadingFilterFormulas: boolean;
joinFormulas: Map<string, string>;
isLoadingJoinFormulas: boolean;
viewGroupByFormulas: Map<string, string>;
isLoadingViewGroupByFormulas: boolean;
isSidePanelCollapsed: boolean;
theme: 'dark' | 'light';
constructor(editorStore: EditorStore, element: PackageableElement);
get database(): Database;
setSelectedTab(tab: DATABASE_EDITOR_TAB): void;
/**
* Generate the Pure grammar for the underlying Database element and store
* it in `textContent`. Mirrors `generateElementGrammar()` from the base
* class but is kept local so the consumer doesn't need to know about the
* inherited flow.
*/
generateGrammarText(): ReturnType<DatabaseEditorState['generateElementGrammar']>;
/**
* Render every view column-mapping's relational operation as Pure code, in
* a single batched engine call.
*
* Strategy: rather than transform metamodel `RelationalOperationElement`
* instances by hand (the V1 transformer isn't a public export), we rely on
* `elementToEntity(database)` which serializes the Database to its V1 JSON
* form synchronously. The resulting `entity.content` already contains the
* raw operations under
* `schemas[].views[].columnMappings[].operation`
* — exactly the shape `relationalOperationElementToPureCode` expects. We
* walk that JSON, build a Map keyed by `<schema>.<view>.<column>`, and let
* the engine return the rendered Pure code.
*
* On any failure (network/server/serialization), the partial map (possibly
* empty) stays in place and consumers fall back to the placeholder.
*/
loadViewColumnFormulas(): GeneratorFn<void>;
/**
* Render every database-level filter's relational operation as Pure code, in
* a single batched engine call.
*
* Same strategy as `loadViewColumnFormulas`: serialize the database to its
* V1 JSON via `elementToEntity` and walk the `filters[]` array on the root
* for `{ name, operation }` pairs. Filter names are unique within a
* Database, so the lookup key is just the filter name.
*
* On any failure (network/server/serialization), the partial map (possibly
* empty) stays in place and consumers fall back to the placeholder.
*/
loadFilterFormulas(): GeneratorFn<void>;
/**
* Render every join's relational operation as Pure code, in a single
* batched engine call. Same strategy as `loadFilterFormulas`: serialize
* the database to its V1 JSON via `elementToEntity` and walk the
* `joins[]` array on the root for `{ name, operation }` pairs. Join
* names are unique within a Database, so the lookup key is just the
* join name.
*
* On any failure (network/server/serialization), the partial map
* (possibly empty) stays in place and consumers fall back to the
* placeholder.
*/
loadJoinFormulas(): GeneratorFn<void>;
/**
* Render every view's groupBy column expressions as Pure code, in a
* single batched engine call. Same strategy as `loadViewColumnFormulas`:
* serialize the database to its V1 JSON via `elementToEntity` and walk
* the `schemas[].views[].groupBy.columns[]` arrays for raw operations.
*
* Skips the round-trip entirely when no view declares a groupBy. On any
* failure the partial map (possibly empty) stays in place and consumers
* fall back to the static placeholder.
*/
loadViewGroupByFormulas(): GeneratorFn<void>;
/**
* Plain relation selection — used when the user clicks directly on a node
* on the canvas. Doesn't trigger a pan because the user is already looking
* at the node they clicked. Clears any active join/filter selection
* (selecting a relation moves us out of those focus modes).
*/
setSelectedRelation(relation: Table | View | undefined): void;
/**
* Side-panel relation click — selects the relation AND requests a pan so
* the canvas centers on it. Works identically for tables and views.
*/
focusOnRelation(relation: Table | View): void;
/**
* Side-panel column click — selects the parent table, the specific column,
* and requests a pan. Inside the table-node component this drives the
* single-row highlight. Only meaningful for tables; view column-mappings
* use `focusOnRelation` for now.
*/
focusOnColumn(table: Table, column: Column): void;
/**
* Side-panel view column-mapping click \u2014 selects the parent view AND
* the specific column-mapping by name (views don't have `Column` refs).
* Drives the per-row highlight inside the view's canvas node, mirroring
* how `focusOnColumn` works for tables.
*/
focusOnViewColumn(view: View, columnMappingName: string): void;
/**
* Side-panel join click (or canvas edge click) — selects the join and
* requests a pan that fits BOTH endpoint relations in view. We clear the
* relation/column selection because join-mode is its own focus state with
* its own visual treatment (yellow rings on the two endpoints rather than
* a single blue ring on one).
*/
focusOnJoin(join: Join): void;
/**
* Side-panel filter click — selects the filter. Filters don't have a
* canvas representation in the MVP (they live at the database level rather
* than tied to a specific table/edge), so this only highlights the row in
* the side panel; no pan is requested. Other selection axes are cleared so
* the highlight states stay mutually exclusive.
*/
focusOnFilter(filter: Filter): void;
/**
* Clear all selections. Called from the canvas pane click handler so that
* clicking empty space deselects everything regardless of which selection
* axis is active.
*/
clearSelection(): void;
toggleSchemaExpanded(id: string): void;
toggleRelationExpanded(id: string): void;
expandAllSchemas(): void;
collapseAll(): void;
/**
* Set the side panel's collapsed state directly. Useful for syncing the
* state when the user drags the splitter all the way down (i.e., the
* panel sets itself to collapsed in response to a resize event).
*/
setSidePanelCollapsed(collapsed: boolean): void;
/**
* Flip the side panel's collapsed state. Driven by the explicit toggle
* button in the panel header (and the chevron rendered when collapsed).
*/
toggleSidePanelCollapsed(): void;
/**
* Flip the editor's local theme between dark (the Studio default) and
* light. Scoped to this editor only — the rest of Studio remains in its
* configured theme. The toggle is exposed via a button in the editor's
* tab header. The new value is persisted to `UserDataService` so the
* choice survives reloads.
*/
toggleTheme(): void;
/**
* Set the tree search/filter text. Empty string means \u201cno filter\u201d.
* The schema-tree consumer derives a lowercase form per render rather
* than computing it here so identical successive sets stay cheap.
*/
setSearchText(text: string): void;
/**
* Bump the fit-all counter. The canvas observes this and runs
* `fitView()` over the full graph (no `nodes` filter).
*/
requestFitAll(): void;
/**
* Bump the reset-layout counter. The canvas observes this and re-runs
* dagre over the current nodes/edges, undoing any user-initiated drags.
*/
requestResetLayout(): void;
reprocess(newElement: Database, editorStore: EditorStore): DatabaseEditorState;
}
//# sourceMappingURL=DatabaseEditorState.d.ts.map