UNPKG

@finos/legend-studio

Version:
206 lines 16.5 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 { useState, useCallback } from 'react'; import { observer } from 'mobx-react-lite'; import { UMLEditorState, UML_EDITOR_TAB, } from '../../../../stores/editor-state/element-editor-state/UMLEditorState.js'; import { useDrop } from 'react-dnd'; import { CORE_DND_TYPE, } from '../../../../stores/shared/DnDUtil.js'; import { prettyCONSTName } from '@finos/legend-shared'; import { BlankPanelContent, clsx, getControlledResizablePanelProps, InputWithInlineValidation, ResizablePanel, ResizablePanelGroup, ResizablePanelSplitter, ResizablePanelSplitterLine, PlusIcon, TimesIcon, LongArrowRightIcon, LockIcon, FireIcon, StickArrowCircleRightIcon, } from '@finos/legend-art'; import { LEGEND_STUDIO_TEST_ID } from '../../../LegendStudioTestID.js'; import { StereotypeSelector } from './StereotypeSelector.js'; import { TaggedValueEditor } from './TaggedValueEditor.js'; import { useEditorStore } from '../../EditorStoreProvider.js'; import { Profile, StereotypeExplicitReference, stub_TaggedValue, stub_Tag, stub_Profile, stub_Stereotype, stub_Enum, } from '@finos/legend-graph'; import { enum_setName, annotatedElement_deleteStereotype, annotatedElement_addStereotype, annotatedElement_addTaggedValue, annotatedElement_deleteTaggedValue, enum_deleteValue, enum_addValue, } from '../../../../stores/graphModifier/DomainGraphModifierHelper.js'; import { useApplicationNavigationContext } from '@finos/legend-application'; import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../../stores/LegendStudioApplicationNavigationContext.js'; const EnumBasicEditor = observer((props) => { const { _enum, selectValue, deleteValue, isReadOnly } = props; const changeValue = (event) => { enum_setName(_enum, event.target.value); }; const isEnumValueDuplicated = (val) => _enum._OWNER.values.filter((value) => value.name === val.name).length >= 2; return (_jsxs("div", { className: "enum-basic-editor", children: [_jsx(InputWithInlineValidation, { className: "enum-basic-editor__name input-group__input", spellCheck: false, disabled: isReadOnly, value: _enum.name, onChange: changeValue, placeholder: `Enum name`, validationErrorMessage: isEnumValueDuplicated(_enum) ? 'Duplicated enum' : undefined }), _jsx("button", { className: "uml-element-editor__basic__detail-btn", onClick: selectValue, tabIndex: -1, title: 'See detail', children: _jsx(LongArrowRightIcon, {}) }), !isReadOnly && (_jsx("button", { className: "uml-element-editor__remove-btn", disabled: isReadOnly, onClick: deleteValue, tabIndex: -1, title: 'Remove', children: _jsx(TimesIcon, {}) }))] })); }); const EnumEditor = observer((props) => { const { _enum, deselectValue, isReadOnly } = props; // Tab const [selectedTab, setSelectedTab] = useState(UML_EDITOR_TAB.TAGGED_VALUES); const tabs = [UML_EDITOR_TAB.TAGGED_VALUES, UML_EDITOR_TAB.STEREOTYPES]; const changeTab = (tab) => () => setSelectedTab(tab); // Tagged value and Stereotype let addButtonTitle = ''; switch (selectedTab) { case UML_EDITOR_TAB.TAGGED_VALUES: addButtonTitle = 'Add tagged value'; break; case UML_EDITOR_TAB.STEREOTYPES: addButtonTitle = 'Add stereotype'; break; default: break; } const addValue = () => { if (!isReadOnly) { if (selectedTab === UML_EDITOR_TAB.TAGGED_VALUES) { annotatedElement_addTaggedValue(_enum, stub_TaggedValue(stub_Tag(stub_Profile()))); } else if (selectedTab === UML_EDITOR_TAB.STEREOTYPES) { annotatedElement_addStereotype(_enum, StereotypeExplicitReference.create(stub_Stereotype(stub_Profile()))); } } }; const _deleteStereotype = (val) => () => annotatedElement_deleteStereotype(_enum, val); const _deleteTaggedValue = (val) => () => annotatedElement_deleteTaggedValue(_enum, val); // Drag and Drop const handleDropTaggedValue = useCallback((item) => { if (!isReadOnly && item.data.packageableElement instanceof Profile) { annotatedElement_addTaggedValue(_enum, stub_TaggedValue(stub_Tag(item.data.packageableElement))); } }, [_enum, isReadOnly]); const [{ isTaggedValueDragOver }, dropTaggedValueRef] = useDrop(() => ({ accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE], drop: (item) => handleDropTaggedValue(item), collect: (monitor) => ({ isTaggedValueDragOver: monitor.isOver({ shallow: true }), }), }), [handleDropTaggedValue]); const handleDropStereotype = useCallback((item) => { if (!isReadOnly && item.data.packageableElement instanceof Profile) { annotatedElement_addStereotype(_enum, StereotypeExplicitReference.create(stub_Stereotype(item.data.packageableElement))); } }, [_enum, isReadOnly]); const [{ isStereotypeDragOver }, dropStereotypeRef] = useDrop(() => ({ accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE], drop: (item) => handleDropStereotype(item), collect: (monitor) => ({ isStereotypeDragOver: monitor.isOver({ shallow: true }), }), }), [handleDropStereotype]); return (_jsx("div", { className: "uml-element-editor enum-editor", children: _jsxs("div", { "data-testid": LEGEND_STUDIO_TEST_ID.PANEL, className: "panel", children: [_jsxs("div", { className: "panel__header", children: [_jsxs("div", { className: "panel__header__title", children: [isReadOnly && (_jsx("div", { className: "uml-element-editor__header__lock", children: _jsx(LockIcon, {}) })), _jsx("div", { className: "panel__header__title__label", children: "enum" }), _jsx("div", { className: "panel__header__title__content", children: _enum.name })] }), _jsx("div", { className: "panel__header__actions", children: _jsx("button", { className: "panel__header__action", onClick: deselectValue, tabIndex: -1, title: 'Close', children: _jsx(TimesIcon, {}) }) })] }), _jsxs("div", { "data-testid": LEGEND_STUDIO_TEST_ID.UML_ELEMENT_EDITOR__TABS_HEADER, className: "panel__header uml-element-editor__tabs__header", children: [_jsx("div", { className: "uml-element-editor__tabs", children: tabs.map((tab) => (_jsx("div", { onClick: changeTab(tab), className: clsx('uml-element-editor__tab', { 'uml-element-editor__tab--active': tab === selectedTab, }), children: prettyCONSTName(tab) }, tab))) }), _jsx("div", { className: "panel__header__actions", children: _jsx("button", { className: "panel__header__action", disabled: isReadOnly, onClick: addValue, tabIndex: -1, title: addButtonTitle, children: _jsx(PlusIcon, {}) }) })] }), _jsxs("div", { className: "panel__content", children: [selectedTab === UML_EDITOR_TAB.TAGGED_VALUES && (_jsx("div", { ref: dropTaggedValueRef, className: clsx('panel__content__lists', { 'panel__content__lists--dnd-over': isTaggedValueDragOver && !isReadOnly, }), children: _enum.taggedValues.map((taggedValue) => (_jsx(TaggedValueEditor, { taggedValue: taggedValue, deleteValue: _deleteTaggedValue(taggedValue), isReadOnly: isReadOnly }, taggedValue._UUID))) })), selectedTab === UML_EDITOR_TAB.STEREOTYPES && (_jsx("div", { ref: dropStereotypeRef, className: clsx('panel__content__lists', { 'panel__content__lists--dnd-over': isStereotypeDragOver && !isReadOnly, }), children: _enum.stereotypes.map((stereotype) => (_jsx(StereotypeSelector, { stereotype: stereotype, deleteStereotype: _deleteStereotype(stereotype), isReadOnly: isReadOnly }, stereotype.value._UUID))) }))] })] }) })); }); export const EnumerationEditor = observer((props) => { const { enumeration } = props; const editorStore = useEditorStore(); const editorState = editorStore.getCurrentEditorState(UMLEditorState); const isReadOnly = editorState.isReadOnly; // Selected enum value const [selectedEnum, setSelectedEnum] = useState(); const deselectValue = () => setSelectedEnum(undefined); const selectValue = (val) => () => setSelectedEnum(val); // Tab const selectedTab = editorState.selectedTab; const tabs = [ UML_EDITOR_TAB.ENUM_VALUES, UML_EDITOR_TAB.TAGGED_VALUES, UML_EDITOR_TAB.STEREOTYPES, ]; const changeTab = (tab) => () => { editorState.setSelectedTab(tab); setSelectedEnum(undefined); }; // Tagged value and Stereotype let addButtonTitle = ''; switch (selectedTab) { case UML_EDITOR_TAB.ENUM_VALUES: addButtonTitle = 'Add enum value'; break; case UML_EDITOR_TAB.TAGGED_VALUES: addButtonTitle = 'Add tagged value'; break; case UML_EDITOR_TAB.STEREOTYPES: addButtonTitle = 'Add stereotype'; break; default: break; } const add = () => { if (!isReadOnly) { if (selectedTab === UML_EDITOR_TAB.ENUM_VALUES) { enum_addValue(enumeration, stub_Enum(enumeration)); } else if (selectedTab === UML_EDITOR_TAB.TAGGED_VALUES) { annotatedElement_addTaggedValue(enumeration, stub_TaggedValue(stub_Tag(stub_Profile()))); } else if (selectedTab === UML_EDITOR_TAB.STEREOTYPES) { annotatedElement_addStereotype(enumeration, StereotypeExplicitReference.create(stub_Stereotype(stub_Profile()))); } } }; const deleteValue = (val) => () => { enum_deleteValue(enumeration, val); if (val === selectedEnum) { setSelectedEnum(undefined); } }; const _deleteStereotype = (val) => () => annotatedElement_deleteStereotype(enumeration, val); const _deleteTaggedValue = (val) => () => annotatedElement_deleteTaggedValue(enumeration, val); // Drag and Drop const handleDropTaggedValue = useCallback((item) => { if (!isReadOnly && item.data.packageableElement instanceof Profile) { annotatedElement_addTaggedValue(enumeration, stub_TaggedValue(stub_Tag(item.data.packageableElement))); } }, [enumeration, isReadOnly]); const [{ isTaggedValueDragOver }, dropTaggedValueRef] = useDrop(() => ({ accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE], drop: (item) => handleDropTaggedValue(item), collect: (monitor) => ({ isTaggedValueDragOver: monitor.isOver({ shallow: true }), }), }), [handleDropTaggedValue]); const handleDropStereotype = useCallback((item) => { if (!isReadOnly && item.data.packageableElement instanceof Profile) { annotatedElement_addStereotype(enumeration, StereotypeExplicitReference.create(stub_Stereotype(item.data.packageableElement))); } }, [enumeration, isReadOnly]); const [{ isStereotypeDragOver }, dropStereotypeRef] = useDrop(() => ({ accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE], drop: (item) => handleDropStereotype(item), collect: (monitor) => ({ isStereotypeDragOver: monitor.isOver({ shallow: true }), }), }), [handleDropStereotype]); // Generation const generationParentElementPath = editorStore.graphState.graphGenerationState.findGenerationParentPath(enumeration.path); const generationParentElement = generationParentElementPath ? editorStore.graphManagerState.graph.getNullableElement(generationParentElementPath) : undefined; const visitGenerationParentElement = () => { if (generationParentElement) { editorStore.openElement(generationParentElement); } }; useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.ENUMERATION_EDITOR); return (_jsx("div", { "data-testid": LEGEND_STUDIO_TEST_ID.ENUMERATION_EDITOR, className: "uml-element-editor enumeration-editor", children: _jsxs(ResizablePanelGroup, { orientation: "horizontal", children: [_jsx(ResizablePanel, { minSize: 56, children: _jsxs("div", { className: "panel", children: [_jsxs("div", { className: "panel__header", children: [_jsxs("div", { className: "panel__header__title", children: [_jsx("div", { className: "panel__header__title__label", children: "enumeration" }), _jsx("div", { className: "panel__header__title__content", children: enumeration.name })] }), _jsx("div", { className: "panel__header__actions", children: generationParentElement && (_jsxs("button", { className: "uml-element-editor__header__generation-origin", onClick: visitGenerationParentElement, tabIndex: -1, title: `Visit generation parent '${generationParentElement.path}'`, children: [_jsx("div", { className: "uml-element-editor__header__generation-origin__label", children: _jsx(FireIcon, {}) }), _jsx("div", { className: "uml-element-editor__header__generation-origin__parent-name", children: generationParentElement.name }), _jsx("div", { className: "uml-element-editor__header__generation-origin__visit-btn", children: _jsx(StickArrowCircleRightIcon, {}) })] })) })] }), _jsxs("div", { "data-testid": LEGEND_STUDIO_TEST_ID.UML_ELEMENT_EDITOR__TABS_HEADER, className: "panel__header uml-element-editor__tabs__header", children: [_jsx("div", { className: "uml-element-editor__tabs", children: tabs.map((tab) => (_jsx("div", { onClick: changeTab(tab), className: clsx('uml-element-editor__tab', { 'uml-element-editor__tab--active': tab === selectedTab, }), children: prettyCONSTName(tab) }, tab))) }), _jsx("div", { className: "panel__header__actions", children: _jsx("button", { className: "panel__header__action", onClick: add, tabIndex: -1, title: addButtonTitle, children: _jsx(PlusIcon, {}) }) })] }), _jsxs("div", { className: "panel__content", children: [selectedTab === UML_EDITOR_TAB.ENUM_VALUES && (_jsx("div", { className: "panel__content__lists", children: enumeration.values.map((enumValue) => (_jsx(EnumBasicEditor, { _enum: enumValue, deleteValue: deleteValue(enumValue), selectValue: selectValue(enumValue), isReadOnly: isReadOnly }, enumValue._UUID))) })), selectedTab === UML_EDITOR_TAB.TAGGED_VALUES && (_jsx("div", { ref: dropTaggedValueRef, className: clsx('panel__content__lists', { 'panel__content__lists--dnd-over': isTaggedValueDragOver && !isReadOnly, }), children: enumeration.taggedValues.map((taggedValue) => (_jsx(TaggedValueEditor, { taggedValue: taggedValue, deleteValue: _deleteTaggedValue(taggedValue), isReadOnly: isReadOnly }, taggedValue._UUID))) })), selectedTab === UML_EDITOR_TAB.STEREOTYPES && (_jsx("div", { ref: dropStereotypeRef, className: clsx('panel__content__lists', { 'panel__content__lists--dnd-over': isStereotypeDragOver && !isReadOnly, }), children: enumeration.stereotypes.map((stereotype) => (_jsx(StereotypeSelector, { stereotype: stereotype, deleteStereotype: _deleteStereotype(stereotype), isReadOnly: isReadOnly }, stereotype.value._UUID))) }))] })] }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-light-grey-200)" }) }), _jsx(ResizablePanel, { ...getControlledResizablePanelProps(!selectedEnum, { size: 250, }), direction: -1, children: selectedEnum ? (_jsx(EnumEditor, { _enum: selectedEnum, deselectValue: deselectValue, isReadOnly: isReadOnly })) : (_jsx("div", { className: "uml-element-editor__sub-editor", children: _jsx(BlankPanelContent, { children: "No enum selected" }) })) })] }) })); }); //# sourceMappingURL=EnumerationEditor.js.map