UNPKG

@finos/legend-studio

Version:
149 lines 12 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } 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 { MultiplicityBadge } from '../../../shared/MultiplicityBadge.js'; import { PurePropertyMappingEditor } from './PurePropertyMappingEditor.js'; import { getElementIcon } from '../../../shared/ElementIconUtils.js'; import { MappingEditorState, } from '../../../../stores/editor-state/element-editor-state/mapping/MappingEditorState.js'; import { PurePropertyMappingState, PureInstanceSetImplementationState, } from '../../../../stores/editor-state/element-editor-state/mapping/PureInstanceSetImplementationState.js'; import { clsx, ArrowCircleRightIcon } from '@finos/legend-art'; import { guaranteeType, UnsupportedOperationError } from '@finos/legend-shared'; import { FlatDataInstanceSetImplementationState, } from '../../../../stores/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.js'; import { FlatDataPropertyMappingEditor } from './FlatDataPropertyMappingEditor.js'; import { RelationalPropertyMappingEditor } from './relational/RelationalPropertyMappingEditor.js'; import { useEditorStore } from '../../EditorStoreProvider.js'; import { getRootSetImplementation, Class, SetImplementation, PrimitiveType, PureInstanceSetImplementation, EmbeddedFlatDataPropertyMapping, OperationSetImplementation, } from '@finos/legend-graph'; import { useApplicationStore } from '@finos/legend-application'; import { setImpl_nominateRoot, setImpl_setRoot, } from '../../../../stores/graphModifier/DSLMapping_GraphModifierHelper.js'; import { CLASS_PROPERTY_TYPE, getClassPropertyType, SET_IMPLEMENTATION_TYPE, } from '../../../../stores/shared/ModelUtil.js'; export const getExpectedReturnType = (targetSetImplementation) => { if (targetSetImplementation instanceof PureInstanceSetImplementation) { return targetSetImplementation.srcClass?.value; } else if (targetSetImplementation instanceof OperationSetImplementation) { return targetSetImplementation.class.value; } else { return undefined; } }; export const PropertyMappingsEditor = observer((props) => { const { instanceSetImplementationState, property, isReadOnly } = props; const editorStore = useEditorStore(); const applicationStore = useApplicationStore(); const mappingEditorState = editorStore.getCurrentEditorState(MappingEditorState); const propertyRawType = property.genericType.value.rawType; const propertyBasicType = getClassPropertyType(propertyRawType); const instanceSetImplementationType = editorStore.graphState.getSetImplementationType(instanceSetImplementationState.setImplementation); const isEmbedded = instanceSetImplementationState.setImplementation._isEmbedded; // Parser Error const propertyMappingStates = instanceSetImplementationState.propertyMappingStates.filter((pm) => pm.propertyMapping.property.value === property); const propertyHasParserError = Boolean(propertyMappingStates.find((pm) => pm.parserError)); const setImplementationHasParserError = Boolean(instanceSetImplementationState.propertyMappingStates.find((pm) => pm.parserError)); // Walker // TODO: revisit this behavior now that we have more types of property mapping to support // e.g. embedded, target set implementation, etc. // See https://github.com/finos/legend-studio/issues/310 const visitOrCreateMappingElement = () => { if (propertyRawType instanceof Class) { if (instanceSetImplementationState.mappingElement instanceof PureInstanceSetImplementation) { const rootMappingElement = getRootSetImplementation(mappingEditorState.mapping, propertyRawType); if (rootMappingElement) { if (!rootMappingElement.root.value) { setImpl_setRoot(rootMappingElement, true); } const parent = rootMappingElement._PARENT; if (parent !== mappingEditorState.element) { // TODO: think more about this flow. Right now we open the mapping element in the parent mapping editorStore.openElement(parent); editorStore .getCurrentEditorState(MappingEditorState) .openMappingElement(rootMappingElement, false); } { mappingEditorState.openMappingElement(rootMappingElement, true); } } else { if (!isReadOnly) { mappingEditorState.createMappingElement({ target: property.genericType.value.rawType, showTarget: false, openInAdjacentTab: true, postSubmitAction: (newSetImpl) => { // Make this set implementation the new root if (newSetImpl instanceof SetImplementation) { setImpl_nominateRoot(newSetImpl); } }, }); } } } else if (instanceSetImplementationState instanceof FlatDataInstanceSetImplementationState) { if (propertyMappingStates.length === 1 && propertyMappingStates[0]?.propertyMapping instanceof EmbeddedFlatDataPropertyMapping) { mappingEditorState.openMappingElement(propertyMappingStates[0].propertyMapping, true); } else if (!propertyMappingStates.length) { const embedded = instanceSetImplementationState.addEmbeddedPropertyMapping(property); mappingEditorState.openMappingElement(embedded, true); } } else { applicationStore.notifyWarning(`Can't visit mapping element for type '${propertyRawType.name}'`); } } }; return (_jsxs("div", { className: clsx('property-mapping-editor', { backdrop__element: propertyHasParserError, }), children: [_jsxs("div", { className: "property-mapping-editor__metadata", children: [_jsx("div", { className: "property-mapping-editor__name", children: property.name }), _jsxs("div", { className: "property-mapping-editor__info", children: [_jsxs("div", { className: clsx('property-mapping-editor__type', `background--${propertyBasicType.toLowerCase()}`, { 'property-mapping-editor__type--has-visit-btn': propertyBasicType === CLASS_PROPERTY_TYPE.CLASS, }), title: propertyRawType instanceof PrimitiveType ? undefined : propertyRawType.path, children: [propertyBasicType !== CLASS_PROPERTY_TYPE.PRIMITIVE && (_jsx("div", { className: "property-mapping-editor__type__abbr", children: getElementIcon(editorStore, propertyRawType) })), _jsx("div", { className: "property-mapping-editor__type__label", children: propertyRawType.name }), propertyBasicType === CLASS_PROPERTY_TYPE.CLASS && (_jsx("button", { className: "property-mapping-editor__type__visit-btn", onClick: visitOrCreateMappingElement, tabIndex: -1, title: 'Visit mapping element', children: _jsx(ArrowCircleRightIcon, {}) }))] }), _jsx("div", { className: "property-mapping-editor__multiplicity", children: _jsx(MultiplicityBadge, { multiplicity: property.multiplicity }) })] })] }), _jsxs("div", { className: "property-mapping-editor__content", children: [propertyMappingStates.map((propertyMappingState) => { switch (instanceSetImplementationType) { case SET_IMPLEMENTATION_TYPE.PUREINSTANCE: { return (_jsx(PurePropertyMappingEditor, { isReadOnly: isReadOnly, pureInstanceSetImplementationState: guaranteeType(instanceSetImplementationState, PureInstanceSetImplementationState), purePropertyMappingState: guaranteeType(propertyMappingState, PurePropertyMappingState), setImplementationHasParserError: setImplementationHasParserError }, propertyMappingState.uuid)); } case SET_IMPLEMENTATION_TYPE.FLAT_DATA: case SET_IMPLEMENTATION_TYPE.EMBEDDED_FLAT_DATA: { return (_jsx(FlatDataPropertyMappingEditor, { isReadOnly: isReadOnly, flatDataInstanceSetImplementationState: instanceSetImplementationState, flatDataPropertyMappingState: propertyMappingState, setImplementationHasParserError: setImplementationHasParserError }, propertyMappingState.uuid)); } case SET_IMPLEMENTATION_TYPE.RELATIONAL: { return (_jsx(RelationalPropertyMappingEditor, { isReadOnly: isReadOnly, relationalInstanceSetImplementationState: instanceSetImplementationState, relationalPropertyMappingState: propertyMappingState, setImplementationHasParserError: setImplementationHasParserError }, propertyMappingState.uuid)); } default: { const extraPropertyMappingEditorRenderers = editorStore.pluginManager .getApplicationPlugins() .flatMap((plugin) => plugin.getExtraPropertyMappingEditorRenderers?.() ?? []); for (const renderer of extraPropertyMappingEditorRenderers) { const renderedPropertyMappingEditor = renderer(instanceSetImplementationState, propertyMappingState); if (renderedPropertyMappingEditor) { return renderedPropertyMappingEditor; } } throw new UnsupportedOperationError(`Can't render property mapping editor: no compatible renderer available from plugins`); } } }), propertyBasicType === CLASS_PROPERTY_TYPE.CLASS && !propertyMappingStates.length && (_jsxs(_Fragment, { children: [isEmbedded && (_jsxs("div", { className: "property-mapping-editor__entry--empty", children: ["Click", _jsx("button", { className: "property-mapping-editor__entry--empty__visit-btn", onClick: visitOrCreateMappingElement, tabIndex: -1, title: 'Create mapping element', children: _jsx(ArrowCircleRightIcon, {}) }), `to create an embedded class mapping for property '${property.name}'.`] })), !isEmbedded && (_jsxs("div", { className: "property-mapping-editor__entry--empty", children: ["No set implementation found. Click", _jsx("button", { className: "property-mapping-editor__entry--empty__visit-btn", onClick: visitOrCreateMappingElement, tabIndex: -1, title: 'Create mapping element', children: _jsx(ArrowCircleRightIcon, {}) }), `to create a root class mapping for '${propertyRawType.name}'.`] }))] }))] })] })); }); //# sourceMappingURL=PropertyMappingsEditor.js.map