From 170b74c812ab3de263acbe19f2a7e84e451d7480 Mon Sep 17 00:00:00 2001 From: Axel RICHARD Date: Mon, 11 Dec 2023 11:30:09 +0100 Subject: [PATCH] [2804] Add the ability to declare custom nodes with the sirius-web-application package Bug: https://github.com/eclipse-sirius/sirius-web/issues/2804 Signed-off-by: Axel RICHARD --- CHANGELOG.adoc | 13 +++ .../src/index.ts | 2 +- .../src/application/SiriusWebApplication.tsx | 24 ++++-- .../DiagramRepresentationConfiguration.tsx | 26 ++++++ ...iagramRepresentationConfiguration.types.ts | 30 +++++++ .../sirius-web-application/src/index.ts | 1 + .../views/edit-project/EditProjectView.tsx | 84 +++++++------------ .../frontend/sirius-web/src/index.tsx | 26 +++++- .../src/nodes/EllipseNode.tsx | 0 .../src/nodes/EllipseNode.types.ts | 0 .../src/nodes/EllipseNodeConverterHandler.ts | 0 .../src/nodes/EllipseNodeLayoutHandler.ts | 0 12 files changed, 146 insertions(+), 60 deletions(-) create mode 100644 packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramRepresentationConfiguration.tsx create mode 100644 packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramRepresentationConfiguration.types.ts rename packages/sirius-web/frontend/{sirius-web-application => sirius-web}/src/nodes/EllipseNode.tsx (100%) rename packages/sirius-web/frontend/{sirius-web-application => sirius-web}/src/nodes/EllipseNode.types.ts (100%) rename packages/sirius-web/frontend/{sirius-web-application => sirius-web}/src/nodes/EllipseNodeConverterHandler.ts (100%) rename packages/sirius-web/frontend/{sirius-web-application => sirius-web}/src/nodes/EllipseNodeLayoutHandler.ts (100%) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 900c8c52f6..0b6c824708 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -54,6 +54,18 @@ info: { }, ... ``` +- https://github.com/eclipse-sirius/sirius-web/issues/2804[#2804] [sirius-web] Add the ability to declare custom nodes while using the `sirius-web-application` frontend package. +A new optional component named `DiagramRepresentationConfiguration` has been introduced. +If you want to add some custom nodes, this new component must be declared under `SiriusWebApplication`: +```ts +const nodeTypeRegistry: NodeTypeRegistry = { + ... +}; + + + +``` + === Dependency update @@ -83,6 +95,7 @@ info: { - https://github.com/eclipse-sirius/sirius-web/issues/2766[#2766] [tree] Tree representations (including the explorer) now support dragging any kind of element (not just semantic elements). It is the responsibility of the drop targets (e.g. a diagram) to validate the dropped element(s) type and ignore the one it does not support. - https://github.com/eclipse-sirius/sirius-web/issues/2772[#2772] Improve performance of the Palette +- https://github.com/eclipse-sirius/sirius-web/issues/2804[#2804] [sirius-web] Add the ability to declare custom nodes while using the `sirius-web-application` frontend package. == v2023.12.0 diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/index.ts b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/index.ts index c9775367a6..1fded784bf 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/index.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/index.ts @@ -12,7 +12,7 @@ *******************************************************************************/ export { NodeTypeContext } from './contexts/NodeContext'; -export type { NodeTypeContextValue } from './contexts/NodeContext.types'; +export type { NodeTypeContextValue, NodeTypeContributionElement } from './contexts/NodeContext.types'; export type { IConvertEngine, INodeConverterHandler } from './converter/ConvertEngine.types'; export { convertLabelStyle, convertLineStyle } from './converter/convertDiagram'; export { AlignmentMap } from './converter/convertDiagram.types'; diff --git a/packages/sirius-web/frontend/sirius-web-application/src/application/SiriusWebApplication.tsx b/packages/sirius-web/frontend/sirius-web-application/src/application/SiriusWebApplication.tsx index 2baf2baeda..1e6f92597c 100644 --- a/packages/sirius-web/frontend/sirius-web-application/src/application/SiriusWebApplication.tsx +++ b/packages/sirius-web/frontend/sirius-web-application/src/application/SiriusWebApplication.tsx @@ -12,12 +12,18 @@ *******************************************************************************/ import { ApolloProvider } from '@apollo/client'; import { ServerContext } from '@eclipse-sirius/sirius-components-core'; +import { NodeTypeContext, NodeTypeContextValue } from '@eclipse-sirius/sirius-components-diagrams-reactflow'; import CssBaseline from '@material-ui/core/CssBaseline'; import { Theme, ThemeProvider } from '@material-ui/core/styles'; import React, { useMemo } from 'react'; import { BrowserRouter } from 'react-router-dom'; import { ToastProvider } from '../../src/toast/ToastProvider'; import { createApolloGraphQLClient } from '../ApolloGraphQLClient'; +import { + DiagramRepresentationConfiguration, + defaultNodeTypeRegistry, +} from '../diagrams/DiagramRepresentationConfiguration'; +import { DiagramRepresentationConfigurationProps } from '../diagrams/DiagramRepresentationConfiguration.types'; import { RepresentationContextProvider } from '../representations/RepresentationContextProvider'; import { Router } from '../router/Router'; import { siriusWebTheme as defaultTheme } from '../theme/siriusWebTheme'; @@ -40,6 +46,7 @@ export const SiriusWebApplication = ({ httpOrigin, wsOrigin, theme, children }: const apolloClient = useMemo(() => createApolloGraphQLClient(httpOrigin, wsOrigin), [httpOrigin, wsOrigin]); const value: ViewsContextValue = { ...defaultValue }; + let nodeTypeRegistryValue: NodeTypeContextValue = { ...defaultNodeTypeRegistry }; React.Children.forEach(children, (child) => { if (React.isValidElement(child) && child.type === Views) { const { applicationIcon, applicationBarMenu } = child.props as ViewsProps; @@ -49,6 +56,11 @@ export const SiriusWebApplication = ({ httpOrigin, wsOrigin, theme, children }: if (applicationBarMenu) { value.applicationBarMenu = applicationBarMenu; } + } else if (React.isValidElement(child) && child.type === DiagramRepresentationConfiguration) { + const { nodeTypeRegistry } = child.props as DiagramRepresentationConfigurationProps; + if (nodeTypeRegistry) { + nodeTypeRegistryValue = nodeTypeRegistry; + } } }); @@ -60,11 +72,13 @@ export const SiriusWebApplication = ({ httpOrigin, wsOrigin, theme, children }: - -
- -
-
+ + +
+ +
+
+
diff --git a/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramRepresentationConfiguration.tsx b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramRepresentationConfiguration.tsx new file mode 100644 index 0000000000..19efab5e69 --- /dev/null +++ b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramRepresentationConfiguration.tsx @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2023 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ + +import { NodeTypeContextValue } from '@eclipse-sirius/sirius-components-diagrams-reactflow'; +import { DiagramRepresentationConfigurationProps } from './DiagramRepresentationConfiguration.types'; + +export const defaultNodeTypeRegistry: NodeTypeContextValue = { + nodeConverterHandlers: [], + nodeLayoutHandlers: [], + graphQLNodeStyleFragments: [], + nodeTypeContributions: [], +}; + +export const DiagramRepresentationConfiguration = ({}: DiagramRepresentationConfigurationProps) => { + return null; +}; diff --git a/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramRepresentationConfiguration.types.ts b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramRepresentationConfiguration.types.ts new file mode 100644 index 0000000000..956ad705e1 --- /dev/null +++ b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramRepresentationConfiguration.types.ts @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2023 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +import { + GraphQLNodeStyleFragment, + INodeConverterHandler, + INodeLayoutHandler, + NodeData, + NodeTypeContributionElement, +} from '@eclipse-sirius/sirius-components-diagrams-reactflow'; + +export interface DiagramRepresentationConfigurationProps { + nodeTypeRegistry: NodeTypeRegistry; +} + +export interface NodeTypeRegistry { + graphQLNodeStyleFragments: GraphQLNodeStyleFragment[]; + nodeLayoutHandlers: INodeLayoutHandler[]; + nodeConverterHandlers: INodeConverterHandler[]; + nodeTypeContributions: NodeTypeContributionElement[]; +} diff --git a/packages/sirius-web/frontend/sirius-web-application/src/index.ts b/packages/sirius-web/frontend/sirius-web-application/src/index.ts index 11c4a03c11..668c71c477 100644 --- a/packages/sirius-web/frontend/sirius-web-application/src/index.ts +++ b/packages/sirius-web/frontend/sirius-web-application/src/index.ts @@ -12,4 +12,5 @@ *******************************************************************************/ export { SiriusWebApplication } from './application/SiriusWebApplication'; +export { DiagramRepresentationConfiguration } from './diagrams/DiagramRepresentationConfiguration'; export { Views } from './views/Views'; diff --git a/packages/sirius-web/frontend/sirius-web-application/src/views/edit-project/EditProjectView.tsx b/packages/sirius-web/frontend/sirius-web-application/src/views/edit-project/EditProjectView.tsx index 430f00d61d..d05d7d921c 100644 --- a/packages/sirius-web/frontend/sirius-web-application/src/views/edit-project/EditProjectView.tsx +++ b/packages/sirius-web/frontend/sirius-web-application/src/views/edit-project/EditProjectView.tsx @@ -17,9 +17,6 @@ import { DiagramPaletteToolContextValue, DiagramPaletteToolContribution, NodeData, - NodeTypeContext, - NodeTypeContextValue, - NodeTypeContribution, } from '@eclipse-sirius/sirius-components-diagrams-reactflow'; import { DetailsView, RelatedElementsView, RepresentationsView } from '@eclipse-sirius/sirius-components-forms'; import { @@ -46,9 +43,6 @@ import { useEffect } from 'react'; import { generatePath, useHistory, useParams, useRouteMatch } from 'react-router-dom'; import { useNodes } from 'reactflow'; import { NavigationBar } from '../../navigationBar/NavigationBar'; -import { EllipseNode } from '../../nodes/EllipseNode'; -import { EllipseNodeConverterHandler } from '../../nodes/EllipseNodeConverterHandler'; -import { EllipseNodeLayoutHandler } from '../../nodes/EllipseNodeLayoutHandler'; import { OnboardArea } from '../../onboarding/OnboardArea'; import { DiagramTreeItemContextMenuContribution } from './DiagramTreeItemContextMenuContribution'; import { DocumentTreeItemContextMenuContribution } from './DocumentTreeItemContextMenuContribution'; @@ -194,56 +188,42 @@ export const EditProjectView = () => { />, ]; - const nodeTypeRegistryValue: NodeTypeContextValue = { - graphQLNodeStyleFragments: [ - { - type: 'EllipseNodeStyle', - fields: `borderColor borderSize borderStyle color`, - }, - ], - nodeLayoutHandlers: [new EllipseNodeLayoutHandler()], - nodeConverterHandlers: [new EllipseNodeConverterHandler()], - nodeTypeContributions: [], - }; - main = ( - - - } - component={ExplorerView} - /> - } - component={ValidationView} - /> - } component={DetailsView} /> - } - component={RepresentationsView} - /> - } - component={RelatedElementsView} - /> - - + + } + component={ExplorerView} + /> + } + component={ValidationView} + /> + } component={DetailsView} /> + } + component={RepresentationsView} + /> + } + component={RelatedElementsView} + /> + diff --git a/packages/sirius-web/frontend/sirius-web/src/index.tsx b/packages/sirius-web/frontend/sirius-web/src/index.tsx index d114095f17..89b6066026 100644 --- a/packages/sirius-web/frontend/sirius-web/src/index.tsx +++ b/packages/sirius-web/frontend/sirius-web/src/index.tsx @@ -11,6 +11,7 @@ * Obeo - initial API and implementation *******************************************************************************/ import { loadDevMessages, loadErrorMessages } from '@apollo/client/dev'; +import { NodeTypeContribution } from '@eclipse-sirius/sirius-components-diagrams-reactflow'; import { GQLWidget, PropertySectionComponent, @@ -25,10 +26,17 @@ import { ReferencePreview, ReferencePropertySection, } from '@eclipse-sirius/sirius-components-widget-reference'; -import { SiriusWebApplication } from '@eclipse-sirius/sirius-web-application'; +import { + DiagramRepresentationConfiguration, + NodeTypeRegistry, + SiriusWebApplication, +} from '@eclipse-sirius/sirius-web-application'; import LinearScaleOutlinedIcon from '@material-ui/icons/LinearScaleOutlined'; import ReactDOM from 'react-dom'; import { httpOrigin, wsOrigin } from './core/URL'; +import { EllipseNode } from './nodes/EllipseNode'; +import { EllipseNodeConverterHandler } from './nodes/EllipseNodeConverterHandler'; +import { EllipseNodeLayoutHandler } from './nodes/EllipseNodeLayoutHandler'; import { GQLSlider } from './widgets/SliderFragment.types'; import { SliderPreview } from './widgets/SliderPreview'; import { SliderPropertySection } from './widgets/SliderPropertySection'; @@ -106,9 +114,23 @@ const propertySectionRegistryValue: PropertySectionContextValue = { propertySectionsRegistry, }; +const nodeTypeRegistry: NodeTypeRegistry = { + graphQLNodeStyleFragments: [ + { + type: 'EllipseNodeStyle', + fields: `borderColor borderSize borderStyle color`, + }, + ], + nodeLayoutHandlers: [new EllipseNodeLayoutHandler()], + nodeConverterHandlers: [new EllipseNodeConverterHandler()], + nodeTypeContributions: [], +}; + ReactDOM.render( - + + + , document.getElementById('root') ); diff --git a/packages/sirius-web/frontend/sirius-web-application/src/nodes/EllipseNode.tsx b/packages/sirius-web/frontend/sirius-web/src/nodes/EllipseNode.tsx similarity index 100% rename from packages/sirius-web/frontend/sirius-web-application/src/nodes/EllipseNode.tsx rename to packages/sirius-web/frontend/sirius-web/src/nodes/EllipseNode.tsx diff --git a/packages/sirius-web/frontend/sirius-web-application/src/nodes/EllipseNode.types.ts b/packages/sirius-web/frontend/sirius-web/src/nodes/EllipseNode.types.ts similarity index 100% rename from packages/sirius-web/frontend/sirius-web-application/src/nodes/EllipseNode.types.ts rename to packages/sirius-web/frontend/sirius-web/src/nodes/EllipseNode.types.ts diff --git a/packages/sirius-web/frontend/sirius-web-application/src/nodes/EllipseNodeConverterHandler.ts b/packages/sirius-web/frontend/sirius-web/src/nodes/EllipseNodeConverterHandler.ts similarity index 100% rename from packages/sirius-web/frontend/sirius-web-application/src/nodes/EllipseNodeConverterHandler.ts rename to packages/sirius-web/frontend/sirius-web/src/nodes/EllipseNodeConverterHandler.ts diff --git a/packages/sirius-web/frontend/sirius-web-application/src/nodes/EllipseNodeLayoutHandler.ts b/packages/sirius-web/frontend/sirius-web/src/nodes/EllipseNodeLayoutHandler.ts similarity index 100% rename from packages/sirius-web/frontend/sirius-web-application/src/nodes/EllipseNodeLayoutHandler.ts rename to packages/sirius-web/frontend/sirius-web/src/nodes/EllipseNodeLayoutHandler.ts