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, useEffect, useCallback, useRef } from 'react';
import { observer } from 'mobx-react-lite';
import { isNonNullable, prettyCONSTName } from '@finos/legend-shared';
import { CORE_DND_TYPE, } from '../../../../stores/editor/utils/DnDUtils.js';
import { clsx, CustomSelectorInput, createFilter, ResizablePanelGroup, ResizablePanel, ResizablePanelSplitter, ResizablePanelSplitterLine, BlankPanelContent, getCollapsiblePanelGroupProps, InputWithInlineValidation, LockIcon, PlusIcon, TimesIcon, LongArrowRightIcon, ArrowCircleRightIcon, FireIcon, StickArrowCircleRightIcon, PanelEntryDragHandle, DragPreviewLayer, useDragPreviewLayer, PanelDropZone, Panel, PanelDnDEntry, PanelContentLists, InfoCircleIcon, } from '@finos/legend-art';
import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
import { PropertyEditor } from './PropertyEditor.js';
import { StereotypeSelector, StereotypeDragPreviewLayer, } from './StereotypeSelector.js';
import { TaggedValueEditor, TaggedValueDragPreviewLayer, } from './TaggedValueEditor.js';
import { UML_EDITOR_TAB } from '../../../../stores/editor/editor-state/element-editor-state/UMLEditorState.js';
import { ClassEditorState } from '../../../../stores/editor/editor-state/element-editor-state/ClassEditorState.js';
import { flowResult } from 'mobx';
import { useDrop, useDrag } from 'react-dnd';
import { useEditorStore } from '../../EditorStoreProvider.js';
import { MULTIPLICITY_INFINITE, Class, GenericType, Profile, Type, PrimitiveType, Unit, StereotypeExplicitReference, GenericTypeExplicitReference, Association, stub_TaggedValue, stub_Tag, stub_Profile, stub_Stereotype, stub_Constraint, stub_Property, stub_DerivedProperty, getAllClassProperties, getAllSuperclasses, getAllClassConstraints, getAllClassDerivedProperties, isElementReadOnly, getMultiplicityPrettyDescription, } from '@finos/legend-graph';
import { ApplicationNavigationContextData, useApplicationNavigationContext, useApplicationStore, } from '@finos/legend-application';
import { buildElementOption, getPackageableElementOptionFormatter, } from '@finos/legend-lego/graph-editor';
import { getElementIcon } from '../../../ElementIconUtils.js';
import { class_addProperty, class_deleteDerivedProperty, class_addDerivedProperty, class_addContraint, class_addSuperType, annotatedElement_addTaggedValue, annotatedElement_addStereotype, annotatedElement_deleteStereotype, annotatedElement_deleteTaggedValue, class_deleteConstraint, class_deleteSuperType, class_deleteProperty, class_deleteSubclass, class_addSubclass, constraint_setName, property_setName, property_setGenericType, property_setMultiplicity, class_swapProperties, class_swapDerivedProperties, class_swapConstraints, class_swapSuperTypes, setGenericTypeReferenceValue, } from '../../../../stores/graph-modifier/DomainGraphModifierHelper.js';
import { CLASS_PROPERTY_TYPE, getClassPropertyType, } from '../../../../stores/editor/utils/ModelClassifierUtils.js';
import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../../__lib__/LegendStudioApplicationNavigationContext.js';
import { InlineLambdaEditor } from '@finos/legend-query-builder';
const CLASS_PROPERTY_DND_TYPE = 'CLASS_PROPERTY';
const PropertyBasicEditor = observer((props) => {
    const ref = useRef(null);
    const handleRef = useRef(null);
    const { property, _class, editorState, deleteProperty, isReadOnly } = props;
    const editorStore = useEditorStore();
    const isInheritedProperty = property._OWNER instanceof Class && property._OWNER !== _class;
    const isPropertyFromAssociation = property._OWNER instanceof Association;
    const isIndirectProperty = isInheritedProperty || isPropertyFromAssociation;
    const isPropertyDuplicated = (val) => _class.properties.filter((p) => p.name === val.name).length >= 2;
    const selectProperty = () => editorState.setSelectedProperty(property);
    // Name
    const changeValue = (event) => {
        property_setName(property, event.target.value);
    };
    // Generic Type
    const [isEditingType, setIsEditingType] = useState(false);
    const propertyTypeOptions = editorStore.graphManagerState.usableClassPropertyTypes.map(buildElementOption);
    const propertyType = property.genericType.value.rawType;
    const propertyTypeName = getClassPropertyType(propertyType);
    const filterOption = createFilter({
        ignoreCase: true,
        ignoreAccents: false,
        stringify: (option) => option.data.value.path,
    });
    const selectedPropertyType = {
        value: propertyType,
        label: propertyType.name,
    };
    const changePropertyType = (val) => {
        property_setGenericType(property, new GenericType(val.value));
        setIsEditingType(false);
    };
    // Multiplicity
    const [lowerBound, setLowerBound] = useState(property.multiplicity.lowerBound);
    const [upperBound, setUpperBound] = useState(property.multiplicity.upperBound ?? MULTIPLICITY_INFINITE);
    const updateMultiplicity = (lower, upper) => {
        const lBound = typeof lower === 'number' ? lower : parseInt(lower, 10);
        const uBound = upper === MULTIPLICITY_INFINITE
            ? undefined
            : typeof upper === 'number'
                ? upper
                : parseInt(upper, 10);
        if (!isNaN(lBound) && (uBound === undefined || !isNaN(uBound))) {
            property_setMultiplicity(property, editorStore.graphManagerState.graph.getMultiplicity(lBound, uBound));
        }
    };
    const changeLowerBound = (event) => {
        setLowerBound(event.target.value);
        updateMultiplicity(event.target.value, upperBound);
    };
    const changeUpperBound = (event) => {
        setUpperBound(event.target.value);
        updateMultiplicity(lowerBound, event.target.value);
    };
    // Drag and Drop
    const handleHover = useCallback((item) => {
        const draggingProperty = item.property;
        const hoveredProperty = property;
        class_swapProperties(_class, draggingProperty, hoveredProperty);
    }, [_class, property]);
    const [{ isBeingDraggedProperty }, dropConnector] = useDrop(() => ({
        accept: [CLASS_PROPERTY_DND_TYPE],
        hover: (item) => handleHover(item),
        collect: (monitor) => ({
            isBeingDraggedProperty: monitor.getItem()?.property,
        }),
    }), [handleHover]);
    const isBeingDragged = property === isBeingDraggedProperty;
    const [, dragConnector, dragPreviewConnector] = useDrag(() => ({
        type: CLASS_PROPERTY_DND_TYPE,
        item: () => ({
            property: property,
        }),
    }), [property]);
    dragConnector(handleRef);
    dropConnector(ref);
    useDragPreviewLayer(dragPreviewConnector);
    // Other
    const openElement = () => {
        if (!(propertyType instanceof PrimitiveType)) {
            editorStore.graphEditorMode.openElement(propertyType instanceof Unit ? propertyType.measure : propertyType);
        }
    };
    // NOTE: for now we do not allow directly modifying inherited and associated properties,
    // we would make the user go to the supertype or the association where the property comes from
    const visitOwner = () => editorStore.graphEditorMode.openElement(property._OWNER);
    return (_jsxs(PanelDnDEntry, { ref: ref, placeholder: _jsx("div", { className: "dnd__placeholder--light" }), showPlaceholder: isBeingDragged, className: "property-basic-editor__container", children: [!isIndirectProperty && (_jsx(PanelEntryDragHandle, { isDragging: isBeingDragged, dragSourceConnector: handleRef })), _jsxs("div", { className: "property-basic-editor", children: [isIndirectProperty && (_jsxs("div", { className: "property-basic-editor__name property-basic-editor__name--with-lock", children: [_jsx("div", { className: "property-basic-editor__name--with-lock__icon", children: _jsx(LockIcon, {}) }), _jsx("span", { className: "property-basic-editor__name--with-lock__name", children: property.name })] })), !isIndirectProperty && (_jsx("div", { className: "input-group__input property-basic-editor__input", children: _jsx(InputWithInlineValidation, { className: "property-basic-editor__input--with-validation input-group__input", disabled: isReadOnly, value: property.name, spellCheck: false, onChange: changeValue, placeholder: "Property name", error: isPropertyDuplicated(property)
                                ? 'Duplicated property'
                                : undefined }) })), !isIndirectProperty && !isReadOnly && isEditingType && (_jsx(CustomSelectorInput, { className: "property-basic-editor__type", options: propertyTypeOptions, onChange: changePropertyType, value: selectedPropertyType, placeholder: "Choose a type...", filterOption: filterOption, formatOptionLabel: getPackageableElementOptionFormatter({}) })), !isIndirectProperty && !isReadOnly && !isEditingType && (_jsxs("div", { className: clsx('property-basic-editor__type', 'property-basic-editor__type--show-click-hint', `background--${propertyTypeName.toLowerCase()}`, {
                            'property-basic-editor__type--has-visit-btn': propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE,
                        }), children: [propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE && (_jsx("div", { className: "property-basic-editor__type__abbr", children: getElementIcon(propertyType, editorStore) })), _jsx("div", { className: "property-basic-editor__type__label", children: propertyType.name }), _jsx("div", { "data-testid": LEGEND_STUDIO_TEST_ID.PROPERTY_BASIC_EDITOR__TYPE__LABEL_HOVER, className: "property-basic-editor__type__label property-basic-editor__type__label--hover", onClick: () => setIsEditingType(true), children: "Click to edit" }), propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE && (_jsx("button", { "data-testid": LEGEND_STUDIO_TEST_ID.TYPE_VISIT, className: "property-basic-editor__type__visit-btn", onClick: openElement, tabIndex: -1, title: "Visit element", children: _jsx(ArrowCircleRightIcon, {}) }))] })), (isIndirectProperty || isReadOnly) && (_jsxs("div", { className: clsx('property-basic-editor__type', `background--${propertyTypeName.toLowerCase()}`, {
                            'property-basic-editor__type--has-visit-btn': propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE,
                        }), children: [propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE && (_jsx("div", { className: "property-basic-editor__type__abbr", children: getElementIcon(propertyType, editorStore) })), _jsx("div", { className: "property-basic-editor__type__label", children: propertyType.name }), propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE && (_jsx("button", { "data-testid": LEGEND_STUDIO_TEST_ID.TYPE_VISIT, className: "property-basic-editor__type__visit-btn", onClick: openElement, tabIndex: -1, title: "Visit element", children: _jsx(ArrowCircleRightIcon, {}) }))] })), _jsxs("div", { className: "property-basic-editor__multiplicity", children: [_jsx("input", { className: "property-basic-editor__multiplicity-bound", disabled: isIndirectProperty || isReadOnly, spellCheck: false, value: lowerBound, onChange: changeLowerBound }), _jsx("div", { className: "property-basic-editor__multiplicity__range", children: ".." }), _jsx("input", { className: "property-basic-editor__multiplicity-bound", disabled: isIndirectProperty || isReadOnly, spellCheck: false, value: upperBound, onChange: changeUpperBound }), _jsx("div", { className: "property-basic-editor__multiplicity__explanation", title: getMultiplicityPrettyDescription(property.multiplicity), children: _jsx(InfoCircleIcon, {}) })] }), !isIndirectProperty && (_jsx("button", { className: "uml-element-editor__basic__detail-btn", onClick: selectProperty, tabIndex: -1, title: "See detail", children: _jsx(LongArrowRightIcon, {}) })), isIndirectProperty && (_jsx("button", { className: "uml-element-editor__visit-parent-element-btn", onClick: visitOwner, tabIndex: -1, title: `Visit ${isInheritedProperty ? 'super type class' : 'association'} '${property._OWNER.path}'`, children: _jsx(ArrowCircleRightIcon, {}) })), isIndirectProperty && (_jsx("div", { className: "property-basic-editor__locked-property-end-block" })), !isIndirectProperty && !isReadOnly && (_jsx("button", { className: clsx('uml-element-editor__remove-btn', {
                            'uml-element-editor__remove-btn--hidden': isIndirectProperty,
                        }), onClick: deleteProperty, tabIndex: -1, title: "Remove", children: _jsx(TimesIcon, {}) }))] })] }));
});
const CLASS_DERIVED_PROPERTY_DND_TYPE = 'CLASS_DERIVED_PROPERTY';
const DerivedPropertyBasicEditor = observer((props) => {
    const ref = useRef(null);
    const handleRef = useRef(null);
    const { derivedProperty, _class, deleteDerivedProperty, editorState, isReadOnly, } = props;
    const editorStore = useEditorStore();
    const applicationStore = useApplicationStore();
    const hasParserError = editorState.classState.derivedPropertyStates.some((state) => state.parserError);
    const dpState = editorState.classState.getDerivedPropertyState(derivedProperty);
    const isInheritedProperty = derivedProperty._OWNER !== _class;
    const selectDerivedProperty = () => editorState.setSelectedProperty(derivedProperty);
    // Name
    const changeValue = (event) => property_setName(derivedProperty, event.target.value);
    // Generic Type
    const [isEditingType, setIsEditingType] = useState(false);
    const propertyTypeOptions = editorStore.graphManagerState.usableClassPropertyTypes.map(buildElementOption);
    const propertyType = derivedProperty.genericType.value.rawType;
    const propertyTypeName = getClassPropertyType(propertyType);
    const filterOption = createFilter({
        ignoreCase: true,
        ignoreAccents: false,
        stringify: (option) => option.data.value.path,
    });
    const selectedPropertyType = {
        value: propertyType,
        label: propertyType.name,
    };
    const changePropertyType = (val) => {
        property_setGenericType(derivedProperty, new GenericType(val.value));
        setIsEditingType(false);
    };
    // Multiplicity
    const [lowerBound, setLowerBound] = useState(derivedProperty.multiplicity.lowerBound);
    const [upperBound, setUpperBound] = useState(derivedProperty.multiplicity.upperBound ?? MULTIPLICITY_INFINITE);
    const updateMultiplicity = (lower, upper) => {
        const lBound = typeof lower === 'number' ? lower : parseInt(lower, 10);
        const uBound = upper === MULTIPLICITY_INFINITE
            ? undefined
            : typeof upper === 'number'
                ? upper
                : parseInt(upper, 10);
        if (!isNaN(lBound) && (uBound === undefined || !isNaN(uBound))) {
            property_setMultiplicity(derivedProperty, editorStore.graphManagerState.graph.getMultiplicity(lBound, uBound));
        }
    };
    const changeLowerBound = (event) => {
        setLowerBound(event.target.value);
        updateMultiplicity(event.target.value, upperBound);
    };
    const changeUpperBound = (event) => {
        setUpperBound(event.target.value);
        updateMultiplicity(lowerBound, event.target.value);
    };
    // Drag and Drop
    const handleHover = useCallback((item, monitor) => {
        const draggingProperty = item.derivedProperty;
        const hoveredProperty = derivedProperty;
        const dragIndex = _class.derivedProperties.findIndex((e) => e === item.derivedProperty);
        const hoverIndex = _class.derivedProperties.findIndex((e) => e === derivedProperty);
        // move the item being hovered on when the dragged item position is beyond the its middle point
        const hoverBoundingReact = ref.current?.getBoundingClientRect();
        const distanceThreshold = ((hoverBoundingReact?.bottom ?? 0) - (hoverBoundingReact?.top ?? 0)) /
            2;
        const dragDistance = (monitor.getClientOffset()?.y ?? 0) - (hoverBoundingReact?.top ?? 0);
        if (dragIndex < hoverIndex && dragDistance < distanceThreshold) {
            return;
        }
        class_swapDerivedProperties(_class, draggingProperty, hoveredProperty);
    }, [_class, derivedProperty]);
    const [{ isBeingDraggedDerivedProperty }, dropConnector] = useDrop(() => ({
        accept: [CLASS_DERIVED_PROPERTY_DND_TYPE],
        hover: (item, monitor) => handleHover(item, monitor),
        collect: (monitor) => ({
            isBeingDraggedDerivedProperty: monitor.getItem()
                ?.derivedProperty,
        }),
    }), [handleHover]);
    const isBeingDragged = derivedProperty === isBeingDraggedDerivedProperty;
    const [, dragConnector, dragPreviewConnector] = useDrag(() => ({
        type: CLASS_DERIVED_PROPERTY_DND_TYPE,
        item: () => ({
            derivedProperty: derivedProperty,
        }),
    }), [derivedProperty]);
    dragConnector(handleRef);
    dropConnector(ref);
    useDragPreviewLayer(dragPreviewConnector);
    // Action
    const onLambdaEditorFocus = () => applicationStore.navigationContextService.push(ApplicationNavigationContextData.createTransient(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.CLASS_DERIVED_PROPERTY_LAMBDA_EDITOR));
    const openElement = () => {
        if (!(propertyType instanceof PrimitiveType)) {
            editorStore.graphEditorMode.openElement(propertyType instanceof Unit ? propertyType.measure : propertyType);
        }
    };
    const visitOwner = () => editorStore.graphEditorMode.openElement(derivedProperty._OWNER);
    const remove = applicationStore.guardUnhandledError(async () => {
        await flowResult(dpState.convertLambdaObjectToGrammarString({ pretty: false }));
        deleteDerivedProperty();
    });
    return (_jsx(PanelDnDEntry, { ref: ref, placeholder: _jsx("div", { className: "uml-element-editor__dnd__placeholder" }), className: "derived-property-editor__container", showPlaceholder: isBeingDragged, children: _jsxs("div", { className: clsx('derived-property-editor', {
                backdrop__element: dpState.parserError && !isInheritedProperty && !isReadOnly,
            }), children: [_jsxs("div", { className: "property-basic-editor", children: [!isInheritedProperty && (_jsx(PanelEntryDragHandle, { dragSourceConnector: handleRef, isDragging: isBeingDragged })), isInheritedProperty && (_jsxs("div", { className: "property-basic-editor__name property-basic-editor__name--with-lock", children: [_jsx("div", { className: "property-basic-editor__name--with-lock__icon", children: _jsx(LockIcon, {}) }), _jsx("span", { className: "property-basic-editor__name--with-lock__name", children: derivedProperty.name })] })), !isInheritedProperty && (_jsx("input", { disabled: isReadOnly, spellCheck: false, className: "property-basic-editor__name property-basic-editor__qualififed-property__name", value: derivedProperty.name, placeholder: "Property name", onChange: changeValue })), !isInheritedProperty && !isReadOnly && isEditingType && (_jsx(CustomSelectorInput, { className: "property-basic-editor__type property-basic-editor__qualififed-property__type", options: propertyTypeOptions, onChange: changePropertyType, value: selectedPropertyType, placeholder: "Choose a type...", filterOption: filterOption, formatOptionLabel: getPackageableElementOptionFormatter({}) })), !isInheritedProperty && !isReadOnly && !isEditingType && (_jsxs("div", { className: clsx('property-basic-editor__type', 'property-basic-editor__type--show-click-hint', `background--${propertyTypeName.toLowerCase()}`, {
                                'property-basic-editor__type--has-visit-btn': propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE,
                            }), children: [propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE && (_jsx("div", { className: "property-basic-editor__type__abbr", children: getElementIcon(propertyType, editorStore) })), _jsx("div", { className: "property-basic-editor__type__label", children: propertyType.name }), _jsx("div", { "data-testid": LEGEND_STUDIO_TEST_ID.PROPERTY_BASIC_EDITOR__TYPE__LABEL_HOVER, className: "property-basic-editor__type__label property-basic-editor__type__label--hover", onClick: () => setIsEditingType(true), children: "Click to edit" }), propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE && (_jsx("button", { "data-testid": LEGEND_STUDIO_TEST_ID.TYPE_VISIT, className: "property-basic-editor__type__visit-btn", onClick: openElement, tabIndex: -1, title: "Visit element", children: _jsx(ArrowCircleRightIcon, {}) }))] })), (isInheritedProperty || isReadOnly) && (_jsxs("div", { className: clsx('property-basic-editor__type', `background--${propertyTypeName.toLowerCase()}`, {
                                'property-basic-editor__type--has-visit-btn': propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE,
                            }), children: [propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE && (_jsx("div", { className: "property-basic-editor__type__abbr", children: getElementIcon(propertyType, editorStore) })), _jsx("div", { className: "property-basic-editor__type__label", children: propertyType.name }), propertyTypeName !== CLASS_PROPERTY_TYPE.PRIMITIVE && (_jsx("button", { "data-testid": LEGEND_STUDIO_TEST_ID.TYPE_VISIT, className: "property-basic-editor__type__visit-btn", onClick: openElement, tabIndex: -1, title: "Visit element", children: _jsx(ArrowCircleRightIcon, {}) }))] })), _jsxs("div", { className: "property-basic-editor__multiplicity", children: [_jsx("input", { className: "property-basic-editor__multiplicity-bound", spellCheck: false, disabled: isInheritedProperty || isReadOnly, value: lowerBound, onChange: changeLowerBound }), _jsx("div", { className: "property-basic-editor__multiplicity__range", children: ".." }), _jsx("input", { className: "property-basic-editor__multiplicity-bound", spellCheck: false, disabled: isInheritedProperty || isReadOnly, value: upperBound, onChange: changeUpperBound })] }), !isInheritedProperty && (_jsx("button", { className: "uml-element-editor__basic__detail-btn", onClick: selectDerivedProperty, tabIndex: -1, title: "See detail", children: _jsx(LongArrowRightIcon, {}) })), isInheritedProperty && (_jsx("button", { className: "uml-element-editor__visit-parent-element-btn", onClick: visitOwner, tabIndex: -1, title: `Visit super type class ${derivedProperty._OWNER.path}`, children: _jsx(ArrowCircleRightIcon, {}) })), !isInheritedProperty && !isReadOnly && (_jsx("button", { className: clsx('uml-element-editor__remove-btn', {
                                'uml-element-editor__remove-btn--hidden': isInheritedProperty,
                            }), onClick: remove, tabIndex: -1, title: "Remove", children: _jsx(TimesIcon, {}) }))] }), _jsx(InlineLambdaEditor, { disabled: editorState.classState.isConvertingDerivedPropertyLambdaObjects ||
                        isInheritedProperty ||
                        isReadOnly, lambdaEditorState: dpState, forceBackdrop: hasParserError, expectedType: propertyType, onEditorFocus: onLambdaEditorFocus })] }) }));
});
const CLASS_CONSTRAINT_DND_TYPE = 'CLASS_CONSTRAINT';
const ConstraintEditor = observer((props) => {
    const ref = useRef(null);
    const handleRef = useRef(null);
    const { constraint, _class, deleteConstraint, editorState, isReadOnly } = props;
    const editorStore = useEditorStore();
    const applicationStore = useApplicationStore();
    const hasParserError = editorState.classState.constraintStates.some((state) => state.parserError);
    const isInheritedConstraint = constraint._OWNER !== _class;
    const constraintState = editorState.classState.getConstraintState(constraint);
    // Name
    const changeName = (event) => constraint_setName(constraint, event.target.value);
    // Drag and Drop
    const handleHover = useCallback((item) => {
        const draggingProperty = item.constraint;
        const hoveredProperty = constraint;
        class_swapConstraints(_class, draggingProperty, hoveredProperty);
    }, [_class, constraint]);
    const [{ isBeingDraggedConstraint }, dropConnector] = useDrop(() => ({
        accept: [CLASS_CONSTRAINT_DND_TYPE],
        hover: (item) => handleHover(item),
        collect: (monitor) => ({
            isBeingDraggedConstraint: monitor.getItem()?.constraint,
        }),
    }), [handleHover]);
    const isBeingDragged = constraint === isBeingDraggedConstraint;
    const [, dragConnector, dragPreviewConnector] = useDrag(() => ({
        type: CLASS_CONSTRAINT_DND_TYPE,
        item: () => ({
            constraint: constraint,
        }),
    }), [constraint]);
    dragConnector(handleRef);
    dropConnector(ref);
    useDragPreviewLayer(dragPreviewConnector);
    // Actions
    const onLambdaEditorFocus = () => applicationStore.navigationContextService.push(ApplicationNavigationContextData.createTransient(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.CLASS_CONTRAINT_LAMBDA_EDITOR));
    const remove = applicationStore.guardUnhandledError(async () => {
        await flowResult(constraintState.convertLambdaObjectToGrammarString({ pretty: false }));
        deleteConstraint();
    });
    const visitOwner = () => editorStore.graphEditorMode.openElement(constraint._OWNER);
    return (_jsx(PanelDnDEntry, { ref: ref, placeholder: _jsx("div", { className: "uml-element-editor__dnd__placeholder" }), className: "constraint-editor__container", showPlaceholder: isBeingDragged, children: _jsxs("div", { className: clsx('constraint-editor', {
                backdrop__element: constraintState.parserError,
            }), children: [_jsxs("div", { className: "constraint-editor__content", children: [!isInheritedConstraint && (_jsx(PanelEntryDragHandle, { dragSourceConnector: handleRef, isDragging: isBeingDragged })), isInheritedConstraint && (_jsxs("div", { className: "constraint-editor__content__name--with-lock", children: [_jsx("div", { className: "constraint-editor__content__name--with-lock__icon", children: _jsx(LockIcon, {}) }), _jsx("span", { className: "constraint-editor__content__name--with-lock__name", children: constraint.name })] })), !isInheritedConstraint && (_jsx("input", { className: "constraint-editor__content__name", spellCheck: false, disabled: isReadOnly || isInheritedConstraint, value: constraint.name, onChange: changeName, placeholder: "Constraint name" })), isInheritedConstraint && (_jsx("button", { className: "uml-element-editor__visit-parent-element-btn", onClick: visitOwner, tabIndex: -1, title: `Visit super type class ${constraint._OWNER.path}`, children: _jsx(ArrowCircleRightIcon, {}) })), !isInheritedConstraint && !isReadOnly && (_jsx("button", { className: "uml-element-editor__remove-btn", disabled: isInheritedConstraint, onClick: remove, tabIndex: -1, title: "Remove", children: _jsx(TimesIcon, {}) }))] }), _jsx(InlineLambdaEditor, { disabled: editorState.classState.isConvertingConstraintLambdaObjects ||
                        isReadOnly ||
                        isInheritedConstraint, lambdaEditorState: constraintState, forceBackdrop: hasParserError, expectedType: PrimitiveType.BOOLEAN, onEditorFocus: onLambdaEditorFocus })] }) }));
});
const CLASS_SUPER_TYPE_DND_TYPE = 'CLASS_SUPER_TYPE';
const SuperTypeEditor = observer((props) => {
    const ref = useRef(null);
    const handleRef = useRef(null);
    const { superType, _class, deleteSuperType, isReadOnly } = props;
    const editorStore = useEditorStore();
    // Type
    const superTypeOptions = editorStore.graphManagerState.usableClasses
        .filter((c) => c instanceof Class &&
        // Exclude current class
        c !== _class &&
        // Exclude super types of the class
        !getAllSuperclasses(_class).includes(c) &&
        // Ensure there is no loop (might be expensive)
        !getAllSuperclasses(c).includes(_class))
        .map(buildElementOption);
    // Drag and Drop
    const handleHover = useCallback((item) => {
        const draggingProperty = item.superType;
        const hoveredProperty = superType;
        class_swapSuperTypes(_class, draggingProperty, hoveredProperty);
    }, [_class, superType]);
    const [{ isBeingDraggedSupertype }, dropConnector] = useDrop(() => ({
        accept: [CLASS_SUPER_TYPE_DND_TYPE],
        hover: (item) => handleHover(item),
        collect: (monitor) => ({
            isBeingDraggedSupertype: monitor.getItem()?.superType,
        }),
    }), [handleHover]);
    const isBeingDragged = superType === isBeingDraggedSupertype;
    const [, dragConnector, dragPreviewConnector] = useDrag(() => ({
        type: CLASS_SUPER_TYPE_DND_TYPE,
        item: () => ({
            superType: superType,
        }),
    }), [superType]);
    dragConnector(handleRef);
    dropConnector(ref);
    useDragPreviewLayer(dragPreviewConnector);
    const rawType = superType.value.rawType;
    const filterOption = createFilter({
        ignoreCase: true,
        ignoreAccents: false,
        stringify: (option) => option.data.value.path,
    });
    const selectedType = {
        value: rawType,
        label: rawType.name,
    };
    const changeType = (val) => setGenericTypeReferenceValue(superType, new GenericType(val.value));
    const visitDerivationSource = () => editorStore.graphEditorMode.openElement(rawType);
    return (_jsxs(PanelDnDEntry, { ref: ref, placeholder: _jsx("div", { className: "uml-element-editor__dnd__placeholder" }), className: "super-type-editor__container", showPlaceholder: isBeingDragged, children: [_jsx(PanelEntryDragHandle, { dragSourceConnector: handleRef, isDragging: isBeingDragged }), _jsxs("div", { className: "super-type-editor", children: [_jsx(CustomSelectorInput, { className: "super-type-editor__class", disabled: isReadOnly, options: superTypeOptions, onChange: changeType, value: selectedType, placeholder: "Choose a class", filterOption: filterOption, formatOptionLabel: getPackageableElementOptionFormatter({}) }), _jsx("button", { className: "uml-element-editor__basic__detail-btn", onClick: visitDerivationSource, tabIndex: -1, title: "Visit super type", children: _jsx(LongArrowRightIcon, {}) }), !isReadOnly && (_jsx("button", { className: "uml-element-editor__remove-btn", disabled: isReadOnly, onClick: deleteSuperType, tabIndex: -1, title: "Remove", children: _jsx(TimesIcon, {}) }))] })] }));
});
const PropertiesEditor = observer((props) => {
    const { _class, editorState } = props;
    const isReadOnly = editorState.isReadOnly;
    const deleteProperty = (property) => () => {
        class_deleteProperty(_class, property);
        if (property === editorState.selectedProperty) {
            editorState.setSelectedProperty(undefined);
        }
    };
    const indirectProperties = getAllClassProperties(_class)
        .filter((property) => !_class.properties.includes(property))
        .sort((p1, p2) => p1.name.localeCompare(p2.name))
        .sort((p1, p2) => (p1._OWNER === _class ? 1 : 0) - (p2._OWNER === _class ? 1 : 0));
    const handleDropProperty = useCallback((item) => {
        if (!isReadOnly && item.data.packageableElement instanceof Type) {
            class_addProperty(_class, stub_Property(item.data.packageableElement, _class));
        }
    }, [_class, isReadOnly]);
    const [{ isPropertyDragOver }, dropConnector] = useDrop(() => ({
        accept: [
            CORE_DND_TYPE.PROJECT_EXPLORER_CLASS,
            CORE_DND_TYPE.PROJECT_EXPLORER_ENUMERATION,
        ],
        drop: (item) => handleDropProperty(item),
        collect: (monitor) => ({
            isPropertyDragOver: monitor.isOver({ shallow: true }),
        }),
    }), [handleDropProperty]);
    useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.CLASS_EDITOR_PROPERTIES);
    return (_jsx(PanelDropZone, { isDragOver: isPropertyDragOver && !isReadOnly, dropTargetConnector: dropConnector, children: _jsxs(PanelContentLists, { children: [_jsx(DragPreviewLayer, { labelGetter: (item) => item.property.name === '' ? '(unknown)' : item.property.name, types: [CLASS_PROPERTY_DND_TYPE] }), _class.properties.concat(indirectProperties).map((property) => (_jsx(PropertyBasicEditor, { property: property, _class: _class, editorState: editorState, deleteProperty: deleteProperty(property), isReadOnly: isReadOnly }, property._UUID)))] }) }));
});
const DerviedPropertiesEditor = observer((props) => {
    const { _class, editorState } = props;
    const isReadOnly = editorState.isReadOnly;
    const classState = editorState.classState;
    const indirectDerivedProperties = getAllClassDerivedProperties(_class)
        .filter((property) => !_class.derivedProperties.includes(property))
        .sort((p1, p2) => p1.name.localeCompare(p2.name))
        .sort((p1, p2) => (p1._OWNER === _class ? 1 : 0) - (p2._OWNER === _class ? 1 : 0));
    const deleteDerivedProperty = (dp) => () => {
        class_deleteDerivedProperty(_class, dp);
        classState.deleteDerivedPropertyState(dp);
        if (dp === editorState.selectedProperty) {
            editorState.setSelectedProperty(undefined);
        }
    };
    const handleDropDerivedProperty = useCallback((item) => {
        if (!isReadOnly && item.data.packageableElement instanceof Type) {
            const dp = stub_DerivedProperty(item.data.packageableElement, _class);
            class_addDerivedProperty(_class, dp);
            classState.addDerivedPropertyState(dp);
        }
    }, [_class, classState, isReadOnly]);
    const [{ isDerivedPropertyDragOver }, dropConnector] = useDrop(() => ({
        accept: [
            CORE_DND_TYPE.PROJECT_EXPLORER_CLASS,
            CORE_DND_TYPE.PROJECT_EXPLORER_ENUMERATION,
        ],
        drop: (item) => handleDropDerivedProperty(item),
        collect: (monitor) => ({
            isDerivedPropertyDragOver: monitor.isOver({ shallow: true }),
        }),
    }), [handleDropDerivedProperty]);
    useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.CLASS_EDITOR_DERIVED_PROPERTIES);
    return (_jsx(PanelDropZone, { isDragOver: isDerivedPropertyDragOver && !isReadOnly, dropTargetConnector: dropConnector, children: _jsxs(PanelContentLists, { children: [_jsx(DragPreviewLayer, { labelGetter: (item) => item.derivedProperty.name === ''
                        ? '(unknown)'
                        : item.derivedProperty.name, types: [CLASS_DERIVED_PROPERTY_DND_TYPE] }), _class.derivedProperties
                    .concat(indirectDerivedProperties)
                    .filter((dp) => Boolean(classState.getNullableDerivedPropertyState(dp)))
                    .map((dp) => (_jsx(DerivedPropertyBasicEditor, { derivedProperty: dp, _class: _class, editorState: editorState, deleteDerivedProperty: deleteDerivedProperty(dp), isReadOnly: isReadOnly }, dp._UUID)))] }) }));
});
const ConstraintsEditor = observer((props) => {
    const { _class, editorState } = props;
    const isReadOnly = editorState.isReadOnly;
    const classState = editorState.classState;
    const deleteConstraint = (constraint) => () => {
        class_deleteConstraint(_class, constraint);
        classState.deleteConstraintState(constraint);
    };
    const inheritedConstraints = getAllClassConstraints(_class).filter((constraint) => !_class.constraints.includes(constraint));
    useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.CLASS_EDITOR_CONSTRAINTS);
    return (_jsxs(PanelContentLists, { children: [_jsx(DragPreviewLayer, { labelGetter: (item) => item.constraint.name === '' ? '(unknown)' : item.constraint.name, types: [CLASS_CONSTRAINT_DND_TYPE] }), _class.constraints
                .concat(inheritedConstraints)
                .filter((constraint) => Boolean(classState.getNullableConstraintState(constraint)))
                .map((constraint) => (_jsx(ConstraintEditor, { constraint: constraint, _class: _class, editorState: editorState, deleteConstraint: deleteConstraint(constraint), isReadOnly: isReadOnly }, constraint._UUID)))] }));
});
const SupertypesEditor = observer((props) => {
    const { _class, editorState } = props;
    const isReadOnly = editorState.isReadOnly;
    const deleteSuperType = (superType) => () => {
        class_deleteSuperType(_class, superType);
        if (superType.value.rawType instanceof Class) {
            class_deleteSubclass(superType.value.rawType, _class);
        }
    };
    const handleDropSuperType = useCallback((item) => {
        const element = item.data.packageableElement;
        if (!isReadOnly &&
            // Have to be a class
            element instanceof Class &&
            // Must not be the same class
            element !== _class &&
            // Must not be a supertype of the current class
            !getAllSuperclasses(_class).includes(element) &&
            // Must not have the current class as a super type
            !getAllSuperclasses(element).includes(_class)) {
            class_addSuperType(_class, GenericTypeExplicitReference.create(new GenericType(element)));
            class_addSubclass(element, _class);
        }
    }, [_class, isReadOnly]);
    const [{ isSuperTypeDragOver }, dropConnector] = useDrop(() => ({
        accept: [
            CORE_DND_TYPE.PROJECT_EXPLORER_CLASS,
            CORE_DND_TYPE.PROJECT_EXPLORER_ENUMERATION,
        ],
        drop: (item) => handleDropSuperType(item),
        collect: (monitor) => ({
            isSuperTypeDragOver: monitor.isOver({ shallow: true }),
        }),
    }), [handleDropSuperType]);
    useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.CLASS_EDITOR_SUPERTYPES);
    return (_jsx(PanelDropZone, { isDragOver: isSuperTypeDragOver && !isReadOnly, dropTargetConnector: dropConnector, children: _jsxs(PanelContentLists, { children: [_jsx(DragPreviewLayer, { labelGetter: (item) => item.superType.value.rawType.name, types: [CLASS_SUPER_TYPE_DND_TYPE] }), _class.generalizations.map((superType) => (_jsx(SuperTypeEditor, { superType: superType, _class: _class, deleteSuperType: deleteSuperType(superType), isReadOnly: isReadOnly }, superType.value._UUID)))] }) }));
});
const TaggedValuesEditor = observer((props) => {
    const { _class, editorState } = props;
    const isReadOnly = editorState.isReadOnly;
    const deleteTaggedValue = (val) => () => annotatedElement_deleteTaggedValue(_class, val);
    const handleDropTaggedValue = useCallback((item) => {
        if (!isReadOnly && item.data.packageableElement instanceof Profile) {
            annotatedElement_addTaggedValue(_class, stub_TaggedValue(stub_Tag(item.data.packageableElement)));
        }
    }, [_class, isReadOnly]);
    const [{ isTaggedValueDragOver }, dropConnector] = useDrop(() => ({
        accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE],
        drop: (item) => handleDropTaggedValue(item),
        collect: (monitor) => ({
            isTaggedValueDragOver: monitor.isOver({ shallow: true }),
        }),
    }), [handleDropTaggedValue]);
    return (_jsx(PanelDropZone, { isDragOver: isTaggedValueDragOver && !isReadOnly, dropTargetConnector: dropConnector, children: _jsxs(PanelContentLists, { children: [_jsx(TaggedValueDragPreviewLayer, {}), _class.taggedValues.map((taggedValue) => (_jsx(TaggedValueEditor, { annotatedElement: _class, taggedValue: taggedValue, deleteValue: deleteTaggedValue(taggedValue), isReadOnly: isReadOnly }, taggedValue._UUID)))] }) }));
});
const StereotypesEditor = observer((props) => {
    const { _class, editorState } = props;
    const isReadOnly = editorState.isReadOnly;
    const deleteStereotype = (val) => () => annotatedElement_deleteStereotype(_class, val);
    const handleDropStereotype = useCallback((item) => {
        if (!isReadOnly && item.data.packageableElement instanceof Profile) {
            annotatedElement_addStereotype(_class, StereotypeExplicitReference.create(stub_Stereotype(item.data.packageableElement)));
        }
    }, [_class, isReadOnly]);
    const [{ isStereotypeDragOver }, dropConnector] = useDrop(() => ({
        accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE],
        drop: (item) => handleDropStereotype(item),
        collect: (monitor) => ({
            isStereotypeDragOver: monitor.isOver({ shallow: true }),
        }),
    }), [handleDropStereotype]);
    return (_jsx(PanelDropZone, { isDragOver: isStereotypeDragOver && !isReadOnly, dropTargetConnector: dropConnector, children: _jsxs(PanelContentLists, { children: [_jsx(StereotypeDragPreviewLayer, {}), _class.stereotypes.map((stereotype) => (_jsx(StereotypeSelector, { annotatedElement: _class, stereotype: stereotype, deleteStereotype: deleteStereotype(stereotype), isReadOnly: isReadOnly }, stereotype._UUID)))] }) }));
});
export const ClassFormEditor = observer((props) => {
    const { _class, editorState, onHashChange } = props;
    const editorStore = useEditorStore();
    const applicationStore = useApplicationStore();
    const classHash = isElementReadOnly(_class)
        ? undefined
        : applicationStore.notificationService.notifyAndReturnAlternativeOnError(() => _class.hashCode, undefined); // attempting to read the hashCode of immutable element will throw an error
    const classState = editorState.classState;
    const isReadOnly = editorState.isReadOnly;
    // Tab
    const selectedTab = editorState.selectedTab;
    const tabs = [
        UML_EDITOR_TAB.PROPERTIES,
        UML_EDITOR_TAB.DERIVED_PROPERTIES,
        UML_EDITOR_TAB.CONSTRAINTS,
        UML_EDITOR_TAB.SUPER_TYPES,
        UML_EDITOR_TAB.TAGGED_VALUES,
        UML_EDITOR_TAB.STEREOTYPES,
    ];
    const changeTab = (tab) => () => {
        editorState.setSelectedTab(tab);
        editorState.setSelectedProperty(undefined);
    };
    const deselectProperty = () => editorState.setSelectedProperty(undefined);
    const possibleSupertypes = editorStore.graphManagerState.graph.ownClasses.filter((superType) => 
    // Exclude current class
    superType !== _class &&
        // Exclude super types of the class
        !getAllSuperclasses(_class).includes(superType) &&
        // Ensure there is no loop (might be expensive)
        !getAllSuperclasses(superType).includes(_class));
    // Add button
    let addButtonTitle = '';
    switch (selectedTab) {
        case UML_EDITOR_TAB.PROPERTIES:
            addButtonTitle = 'Add property';
            break;
        case UML_EDITOR_TAB.DERIVED_PROPERTIES:
            addButtonTitle = 'Add derived property';
            break;
        case UML_EDITOR_TAB.CONSTRAINTS:
            addButtonTitle = 'Add constraint';
            break;
        case UML_EDITOR_TAB.SUPER_TYPES:
            addButtonTitle = 'Add super type';
            break;
        case UML_EDITOR_TAB.TAGGED_VALUES:
            addButtonTitle = 'Add tagged value';
            break;
        case UML_EDITOR_TAB.STEREOTYPES:
            addButtonTitle = 'Add stereotype';
            break;
        default:
            break;
    }
    const isAddButtonDisabled = isReadOnly ||
        (selectedTab === UML_EDITOR_TAB.SUPER_TYPES &&
            !possibleSupertypes.length);
    const add = () => {
        if (!isReadOnly) {
            if (selectedTab === UML_EDITOR_TAB.PROPERTIES) {
                class_addProperty(_class, stub_Property(PrimitiveType.STRING, _class));
            }
            else if (selectedTab === UML_EDITOR_TAB.DERIVED_PROPERTIES) {
                const dp = stub_DerivedProperty(PrimitiveType.STRING, _class);
                class_addDerivedProperty(_class, dp);
                classState.addDerivedPropertyState(dp);
            }
            else if (selectedTab === UML_EDITOR_TAB.CONSTRAINTS) {
                const constraint = stub_Constraint(_class);
                class_addContraint(_class, constraint);
                classState.addConstraintState(constraint);
            }
            else if (selectedTab === UML_EDITOR_TAB.SUPER_TYPES &&
                possibleSupertypes.length) {
                const possibleSupertype = possibleSupertypes[0];
                class_addSuperType(_class, GenericTypeExplicitReference.create(new GenericType(possibleSupertype)));
                class_addSubclass(possibleSupertype, _class);
            }
            else if (selectedTab === UML_EDITOR_TAB.TAGGED_VALUES) {
                annotatedElement_addTaggedValue(_class, stub_TaggedValue(stub_Tag(stub_Profile())));
            }
            else if (selectedTab === UML_EDITOR_TAB.STEREOTYPES) {
                annotatedElement_addStereotype(_class, StereotypeExplicitReference.create(stub_Stereotype(stub_Profile())));
            }
        }
    };
    // Generation
    const generationParentElementPath = editorStore.graphState.graphGenerationState.findGenerationParentPath(_class.path);
    const generationParentElement = generationParentElementPath
        ? editorStore.graphManagerState.graph.getNullableElement(generationParentElementPath)
        : undefined;
    const visitGenerationParentElement = () => {
        if (generationParentElement) {
            editorStore.graphEditorMode.openElement(generationParentElement);
        }
    };
    // On change handler (this is used for other editors which embeds editor)
    useEffect(() => {
        onHashChange?.();
    }, [_class, classHash, onHashChange]);
    // Decorate (add/remove states for derived properties/constraints) and convert lambda objects
    useEffect(() => {
        classState.decorate();
        flowResult(classState.convertConstraintLambdaObjects()).catch(applicationStore.alertUnhandledError);
        flowResult(classState.convertDerivedPropertyLambdaObjects()).catch(applicationStore.alertUnhandledError);
    }, [applicationStore, classState]);
    // layout
    const propertyEditorCollapsiblePanelGroupProps = getCollapsiblePanelGroupProps(!editorState.selectedProperty, {
        size: 250,
    });
    return (_jsx("div", { "data-testid": LEGEND_STUDIO_TEST_ID.CLASS_FORM_EDITOR, className: "uml-element-editor class-form-editor", children: _jsxs(ResizablePanelGroup, { orientation: "horizontal", children: [_jsx(ResizablePanel, { ...propertyEditorCollapsiblePanelGroupProps.remainingPanel, minSize: 56, children: _jsxs(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: "class" }), _jsx("div", { className: "panel__header__title__content", children: _class.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", disabled: isAddButtonDisabled, onClick: add, tabIndex: -1, title: addButtonTitle, children: _jsx(PlusIcon, {}) }) })] }), _jsxs("div", { className: clsx('panel__content', {
                                    'panel__content--with-backdrop-element': selectedTab === UML_EDITOR_TAB.DERIVED_PROPERTIES ||
                                        selectedTab === UML_EDITOR_TAB.CONSTRAINTS,
                                }), children: [selectedTab === UML_EDITOR_TAB.PROPERTIES && (_jsx(PropertiesEditor, { _class: _class, editorState: editorState })), selectedTab === UML_EDITOR_TAB.DERIVED_PROPERTIES && (_jsx(DerviedPropertiesEditor, { _class: _class, editorState: editorState })), selectedTab === UML_EDITOR_TAB.CONSTRAINTS && (_jsx(ConstraintsEditor, { _class: _class, editorState: editorState })), selectedTab === UML_EDITOR_TAB.SUPER_TYPES && (_jsx(SupertypesEditor, { _class: _class, editorState: editorState })), selectedTab === UML_EDITOR_TAB.TAGGED_VALUES && (_jsx(TaggedValuesEditor, { _class: _class, editorState: editorState })), selectedTab === UML_EDITOR_TAB.STEREOTYPES && (_jsx(StereotypesEditor, { _class: _class, editorState: editorState }))] })] }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-light-grey-200)" }) }), _jsx(ResizablePanel, { ...propertyEditorCollapsiblePanelGroupProps.collapsiblePanel, direction: -1, children: editorState.selectedProperty ? (_jsx(PropertyEditor, { property: editorState.selectedProperty, deselectProperty: deselectProperty, isReadOnly: isReadOnly })) : (_jsx("div", { className: "uml-element-editor__sub-editor", children: _jsx(BlankPanelContent, { children: "No property selected" }) })) })] }) }));
});
export const ClassEditor = observer((props) => {
    const { _class } = props;
    const editorStore = useEditorStore();
    const editorState = editorStore.tabManagerState.getCurrentEditorState(ClassEditorState);
    const classPreviewRenderers = editorStore.pluginManager
        .getApplicationPlugins()
        .flatMap((plugin) => plugin.getExtraClassPreviewRenderers?.() ?? [])
        .filter(isNonNullable);
    useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.CLASS_EDITOR);
    return (_jsxs(ResizablePanelGroup, { orientation: "vertical", className: "class-editor", children: [_jsxs(ResizablePanel, { size: 500, minSize: 450, children: [classPreviewRenderers.length !== 0 &&
                        classPreviewRenderers[0](_class), classPreviewRenderers.length === 0 && (_jsx(BlankPanelContent, { children: "No preview" }))] }), _jsx(ResizablePanelSplitter, {}), _jsx(ResizablePanel, { minSize: 450, children: _jsx(ClassFormEditor, { _class: _class, editorState: editorState }) })] }));
});
//# sourceMappingURL=ClassEditor.js.map