UNPKG

@finos/legend-studio

Version:
153 lines 17.2 kB
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 { clsx, ContextMenu, ResizablePanel, ResizablePanelGroup, ResizablePanelSplitter, ResizablePanelSplitterLine, LockIcon, PlusIcon, RefreshIcon, PanelLoadingIndicator, UploadIcon, Dialog, TimesIcon, BlankPanelContent, MenuContent, MenuContentItem, } from '@finos/legend-art'; import { ExternalFormatSchema as Schema, } from '@finos/legend-graph'; import { flowResult } from 'mobx'; import { useMemo } from 'react'; import { SchemaSetEditorState, SCHEMA_SET_TAB_TYPE, } from '../../../../stores/editor-state/element-editor-state/external-format/SchemaSetEditorState.js'; import { EDITOR_LANGUAGE } from '@finos/legend-application'; import { StudioTextInputEditor } from '../../../shared/StudioTextInputEditor.js'; import { getEditorLanguageFromFormat } from '../../../../stores/editor-state/FileGenerationViewerState.js'; import { debounce, guaranteeNonNullable, prettyCONSTName, } from '@finos/legend-shared'; import { GenerationPropertyEditor } from '../element-generation-editor/FileGenerationEditor.js'; import { useEditorStore } from '../../EditorStoreProvider.js'; import { externalFormat_schemaSet_addSchema, externalFormat_schemaSet_deleteSchema, externalFormat_schema_setContent, externalFormat_schema_setId, externalFormat_schema_setLocation, } from '../../../../stores/graphModifier/DSLExternalFormat_GraphModifierHelper.js'; const SchemaLoader = observer((props) => { const { schemaSetEditorState } = props; const importState = schemaSetEditorState.importSchemaContentState; const onClose = () => importState.closeModal(); const onChange = (event) => { const fileList = event.target.files; if (fileList) { importState.setFiles(Array.from(fileList)); } }; const importSchemas = () => { if (importState.files) { importState.importSchemas(importState.files); } }; return (_jsx(Dialog, { onClose: onClose, open: importState.importSchemaModal, TransitionProps: { appear: false, // disable transition }, children: _jsxs("div", { className: "modal modal--dark modal--scrollable patch-loader", children: [_jsx("div", { className: "modal__header", children: _jsx("div", { className: "modal__title", children: _jsx("div", { className: "modal__title__label", children: "Schema Content Loader" }) }) }), _jsxs("div", { className: "modal__body", children: [_jsx(PanelLoadingIndicator, { isLoading: importState.loadingSchemaContentState.isInProgress }), _jsx("div", { children: _jsx("input", { id: "upload-file", type: "file", name: "myFiles", onChange: onChange, multiple: true }) }), importState.files && (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Schema Files" }), _jsx("div", { className: "panel__content__form__section__list", children: _jsx("div", { className: "panel__content__form__section__list__items", children: importState.files.map((value) => (_jsxs("div", { className: "panel__content__form__section__list__item", children: [_jsx("div", { className: "panel__content__form__section__list__item__value", children: value.name }), _jsx("div", { className: "panel__content__form__section__list__item__actions", children: _jsx("button", { title: "Remove change", className: "panel__content__form__section__list__item__remove-btn", onClick: () => importState.removeFile(value), tabIndex: -1, children: _jsx(TimesIcon, {}) }) })] }, value.name))) }) })] }))] }), _jsx("div", { className: "modal__footer", children: _jsx("button", { type: "button", className: "btn btn--dark blocking-alert__action--standard", onClick: importSchemas, disabled: !importState.files?.length, children: "Import Schemas" }) })] }) })); }); const SchemaBasicEditor = observer((props) => { const { schema, isReadOnly, language } = props; const changeId = (event) => externalFormat_schema_setId(schema, event.target.value); const changeLocation = (event) => externalFormat_schema_setLocation(schema, event.target.value); return (_jsxs("div", { className: "schema-editor", children: [_jsx("input", { className: "schema-editor__id", disabled: isReadOnly, value: schema.id, spellCheck: false, onChange: changeId, placeholder: `Id` }), _jsx("input", { className: "schema-editor__location", disabled: isReadOnly, value: schema.location, spellCheck: false, onChange: changeLocation, placeholder: `Location` }), _jsx("div", { className: clsx('schema-editor__content'), children: _jsx("div", { className: "schema-editor__content__input", children: _jsx(StudioTextInputEditor, { inputValue: schema.content, language: language, updateInput: (val) => { externalFormat_schema_setContent(schema, val); }, hideGutter: true }) }) })] })); }); const SchemaSetGeneralEditor = observer((props) => { const { schemaSetEditorState } = props; const schemaSet = schemaSetEditorState.schemaSet; const applicationStore = schemaSetEditorState.editorStore.applicationStore; const importSchemaContentState = schemaSetEditorState.importSchemaContentState; const currentSchema = schemaSetEditorState.currentSchema; const isReadOnly = schemaSetEditorState.isReadOnly; const description = schemaSetEditorState.schemaSetModelGenerationState.description; // TEMPROARY engine api should return `fileformat`. const language = getEditorLanguageFromFormat(description.name); const changeState = (schema) => () => { schemaSetEditorState.setCurrentSchema(schema); }; const getIndex = (value) => guaranteeNonNullable(schemaSet.schemas.findIndex((schema) => value === schema), `Can't find schema '${value}' in schema set '${schemaSet.path}'`); const addSchema = () => { if (!isReadOnly) { const schema = new Schema(); externalFormat_schema_setContent(schema, ''); externalFormat_schemaSet_addSchema(schemaSet, schema); schemaSetEditorState.setCurrentSchema(schema); } }; const openSchemaLoader = () => importSchemaContentState.setImportSchemaModal(true); const deleteSchema = (val) => () => { externalFormat_schemaSet_deleteSchema(schemaSet, val); if (schemaSet.schemas.length !== 0) { schemaSetEditorState.setCurrentSchema(schemaSet.schemas[schemaSet.schemas.length - 1]); } if (schemaSet.schemas.length === 0) { schemaSetEditorState.setCurrentSchema(undefined); } }; const validateSchema = () => { if (currentSchema) { flowResult(schemaSetEditorState.validateSchema(currentSchema)).catch(applicationStore.alertUnhandledError); } }; return (_jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { minSize: 30, size: 300, children: _jsxs("div", { className: "schema-set-panel", children: [_jsxs("div", { className: "schema-set-panel__header", children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__label", children: `${schemaSet.format} configuration` }) }), _jsxs("div", { className: "schema-set-panel__header__actions", children: [_jsx("button", { className: "schema-set-panel__header__action", onClick: openSchemaLoader, disabled: isReadOnly, tabIndex: -1, title: 'Import Schemas', children: _jsx(UploadIcon, {}) }), _jsx("button", { className: "schema-set-panel__header__action", onClick: addSchema, disabled: isReadOnly, tabIndex: -1, title: 'Add Schema', children: _jsx(PlusIcon, {}) })] })] }), schemaSet.schemas.map((schema, index) => (_jsx(ContextMenu, { className: clsx('schema-set-panel__item', { 'schema-set-panel__item--active': currentSchema === schema, }), disabled: isReadOnly, content: _jsx(MenuContent, { children: _jsx(MenuContentItem, { onClick: deleteSchema(schema), children: "Delete" }) }), menuProps: { elevation: 7 }, children: _jsx("div", { className: "schema-set-panel__item__label", onClick: changeState(schema), children: schema.id ? schema.id : `Schema${index + 1}` }) }, schema._UUID)))] }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { children: _jsxs("div", { className: "schema-set-panel", children: [_jsxs("div", { className: "schema-set-panel__header", children: [_jsxs("div", { className: "schema-set-panel__header__title", children: [isReadOnly && (_jsx("div", { className: "schema-set-panel__header__lock", children: _jsx(LockIcon, {}) })), _jsx("div", { className: "schema-set-panel__header__title__label", children: "Schema" }), _jsx("div", { className: "schema-set-panel__header__title__content", children: currentSchema !== undefined ? currentSchema.id ? currentSchema.id : `Schema${getIndex(currentSchema) + 1}` : '' })] }), _jsx("div", { className: "panel__header__actions", children: _jsx("button", { className: "btn--dark model-loader__header__load-btn", onClick: validateSchema, disabled: !currentSchema, tabIndex: -1, title: "Validate Schema", children: "Validate" }) })] }), _jsx("div", { className: "schema-set-panel__content", children: _jsxs("div", { className: "schema-set-panel__content__lists", children: [schemaSetEditorState.importSchemaContentState .importSchemaModal && (_jsx(SchemaLoader, { schemaSetEditorState: schemaSetEditorState })), currentSchema !== undefined && (_jsx(SchemaBasicEditor, { language: language, schema: currentSchema, isReadOnly: isReadOnly }, currentSchema._UUID))] }) })] }) })] })); }); const SchemaSetModelGenerationEditor = observer((props) => { const { schemaSetEditorState } = props; const applicationStore = schemaSetEditorState.editorStore.applicationStore; const schemaSet = schemaSetEditorState.schemaSet; const modelGenerationState = schemaSetEditorState.schemaSetModelGenerationState; const description = modelGenerationState.description; const properties = description.modelGenerationProperties; const isReadOnly = schemaSetEditorState.isReadOnly; const debouncedRegenerate = useMemo(() => debounce(() => flowResult(modelGenerationState.generateModel()), 500), [modelGenerationState]); const update = (generationProperty, newValue) => { debouncedRegenerate.cancel(); modelGenerationState.updateGenerationParameters(generationProperty, newValue); debouncedRegenerate()?.catch(applicationStore.alertUnhandledError); }; const regenerate = () => { modelGenerationState.generateModel(); }; const getConfigValue = (name) => modelGenerationState.getConfigValue(name); const importGeneratedElements = () => { modelGenerationState.importGrammar(); }; return (_jsx("div", { className: "panel__content file-generation-editor__content", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 250, minSize: 50, children: _jsxs("div", { className: "panel file-generation-editor__configuration", children: [_jsxs("div", { className: "panel__header", children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__label", children: `${schemaSet.format} configuration` }) }), _jsx("div", { className: "panel__header__actions", children: _jsx("button", { className: "panel__header__action file-generation-editor__configuration__reset-btn", tabIndex: -1, disabled: isReadOnly || !properties.length, onClick: regenerate, title: 'Reset to default configuration', children: _jsx(RefreshIcon, {}) }) })] }), _jsx("div", { className: "panel__content dnd__dropzone", children: _jsx("div", { className: "file-generation-editor__configuration__content", children: modelGenerationState.modelGenerationProperties.map((abstractGenerationProperty) => (_jsx(GenerationPropertyEditor, { update: update, isReadOnly: isReadOnly, getConfigValue: getConfigValue, property: abstractGenerationProperty }, abstractGenerationProperty.name))) }) })] }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { children: _jsxs("div", { className: "panel generation-result-viewer__file", children: [_jsxs("div", { className: "panel__header", children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__label", children: "result" }) }), _jsxs("div", { className: "panel__header__actions", children: [_jsx("button", { className: clsx('panel__header__action generation-result-viewer__regenerate-btn', { ' generation-result-viewer__regenerate-btn--loading': modelGenerationState.isGenerating, }), tabIndex: -1, disabled: modelGenerationState.isGenerating, onClick: regenerate, title: 'Re-generate', children: _jsx(RefreshIcon, {}) }), _jsx("button", { className: "btn--dark model-loader__header__load-btn", onClick: importGeneratedElements, disabled: modelGenerationState.generationValue === '', tabIndex: -1, title: "Import generated elements", children: "Import" })] })] }), _jsxs("div", { className: "panel__content", children: [_jsx(PanelLoadingIndicator, { isLoading: modelGenerationState.isGenerating }), _jsx(StudioTextInputEditor, { inputValue: modelGenerationState.generationValue, isReadOnly: true, language: EDITOR_LANGUAGE.PURE })] })] }) })] }) })); }); export const SchemaSetEditor = observer(() => { const editorStore = useEditorStore(); const schemaSetEditorState = editorStore.getCurrentEditorState(SchemaSetEditorState); const isReadOnly = schemaSetEditorState.isReadOnly; const schemaSet = schemaSetEditorState.schemaSet; const currentTab = schemaSetEditorState.selectedTab; const isFetchingDescriptions = editorStore.graphState.graphGenerationState.externalFormatState .fetchingDescriptionsState.isInProgress; const changeTab = (tab) => () => schemaSetEditorState.setSelectedTab(tab); const renderMainEditPanel = () => { if (isFetchingDescriptions) { return (_jsx(BlankPanelContent, { children: "Fetching format descriptions" })); } if (currentTab === SCHEMA_SET_TAB_TYPE.GENERAL) { return (_jsx(SchemaSetGeneralEditor, { schemaSetEditorState: schemaSetEditorState })); } const supportsModelGeneraiton = schemaSetEditorState.schemaSetModelGenerationState.description .supportsModelGeneration; return supportsModelGeneraiton ? (_jsx(SchemaSetModelGenerationEditor, { schemaSetEditorState: schemaSetEditorState })) : (_jsxs(BlankPanelContent, { children: ["Format ", schemaSet.format, " does not support Model Generation"] })); }; return (_jsxs("div", { className: "panel schema-set-panel", children: [_jsx("div", { className: "schema-set-panel__header", children: _jsxs("div", { className: "schema-set-panel__header__title", children: [isReadOnly && (_jsx("div", { className: "schema-set-panel__header__lock", children: _jsx(LockIcon, {}) })), _jsx("div", { className: "schema-set-panel__header__title__label", children: "Schema Set" }), _jsx("div", { className: "schema-set-panel__header__title__content", children: schemaSet.name })] }) }), _jsxs("div", { className: "panel__content", children: [_jsx(PanelLoadingIndicator, { isLoading: isFetchingDescriptions }), _jsx("div", { className: "panel__header", children: _jsx("div", { className: "uml-element-editor__tabs", children: Object.values(SCHEMA_SET_TAB_TYPE).map((tab) => (_jsx("div", { onClick: changeTab(tab), className: clsx('relational-connection-editor__tab', { 'relational-connection-editor__tab--active': tab === currentTab, }), children: prettyCONSTName(tab) }, tab))) }) }), _jsxs("div", { className: "panel__content file-generation-editor__content", children: [currentTab === SCHEMA_SET_TAB_TYPE.GENERAL && (_jsx(SchemaSetGeneralEditor, { schemaSetEditorState: schemaSetEditorState })), currentTab === SCHEMA_SET_TAB_TYPE.MODEL_GENERATION && renderMainEditPanel()] })] })] })); }); //# sourceMappingURL=SchemaSetElementEditor.js.map