From f92bda73ad298146dfc0d75e032380302267730b Mon Sep 17 00:00:00 2001 From: Guillaume Coutable Date: Fri, 25 Aug 2023 18:15:37 +0200 Subject: [PATCH] [2289] Use layout strategy to layout icon label nodes Bug: https://github.com/eclipse-sirius/sirius-web/issues/2289 Signed-off-by: Guillaume Coutable --- CHANGELOG.adoc | 2 +- .../diagram-contextual-palette.cy.js | 37 ++++++++++ .../main/resources/schema/diagram.graphqls | 11 +++ .../src/converter/convertDiagram.ts | 4 +- .../src/graphql/subscription/nodeFragment.ts | 9 +++ .../subscription/nodeFragment.types.ts | 14 ++++ .../layout/IconLabelNodeLayoutHandler.ts | 9 ++- .../renderer/layout/ImageNodeLayoutHandler.ts | 5 +- .../src/renderer/layout/LayoutEngine.ts | 5 +- .../src/renderer/layout/LayoutEngine.types.ts | 6 +- .../renderer/layout/ListNodeLayoutHandler.ts | 73 +++++++++---------- .../layout/RectangleNodeLayoutHandler.ts | 49 +++++++------ .../src/renderer/layout/layout.tsx | 17 +++-- .../src/renderer/layout/useLayout.types.ts | 4 +- .../src/renderer/node/IconLabelNode.tsx | 11 ++- .../src/renderer/node/ListNode.tsx | 2 +- 16 files changed, 171 insertions(+), 87 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 86fcfd7ab7..c406f299ae 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -40,7 +40,7 @@ As a result, the identifier of a form description created from a view model will In order to provide a first version of those capabilities, some additional coupling has been created between the reference widget and its use in Sirius Web which may prevent its use in other applications. This coupling will be removed in the near future as a consequence, the dependencies of this code will change and some APIs of the reference widget will be broken in the near future. - https://github.com/eclipse-sirius/sirius-web/issues/2288[#2288] [diagram] Make IconLabel a react flow node - +- https://github.com/eclipse-sirius/sirius-web/issues/2289[#2289] [diagram] Use the layout strategy to layout icon label nodes == v2023.10.0 diff --git a/integration-tests/cypress/e2e/project/react-flow/diagram-contextual-palette.cy.js b/integration-tests/cypress/e2e/project/react-flow/diagram-contextual-palette.cy.js index a9cea6f877..ebc9026672 100644 --- a/integration-tests/cypress/e2e/project/react-flow/diagram-contextual-palette.cy.js +++ b/integration-tests/cypress/e2e/project/react-flow/diagram-contextual-palette.cy.js @@ -11,6 +11,29 @@ * Obeo - initial API and implementation *******************************************************************************/ describe('/projects/:projectId/edit - Robot Diagram', () => { + const fadeByElementTestId = (elementTestId) => { + cy.getByTestId(elementTestId).should('have.css', 'opacity', '1'); + cy.getByTestId(elementTestId).first().click({ force: true }); + cy.wait(200); // wait for the palette to be loaded completely + cy.getByTestId('Fade-elements').should('exist').click({ force: true }); + cy.getByTestId(elementTestId).should('have.css', 'opacity', '0.4'); + }; + + const hideByElementTestId = (elementTestId) => { + cy.getByTestId(elementTestId).then((elementBefore) => { + console.log(elementTestId); + const countBefore = elementBefore.length ?? 0; + console.log(countBefore); + cy.getByTestId(elementTestId).first().click({ force: true }); + cy.wait(200); // wait for the palette to be loaded completely + cy.getByTestId('Hide-elements').should('exist').click({ force: true }); + cy.getByTestId(elementTestId).then((elementAfter) => { + console.log(elementAfter.length ?? 0); + cy.expect((elementAfter.length ?? 0) + 1).to.equal(countBefore); + }); + }); + }; + beforeEach(() => { cy.deleteAllProjects(); cy.createProject('Cypress Project').then((res) => { @@ -42,4 +65,18 @@ describe('/projects/:projectId/edit - Robot Diagram', () => { cy.getByTestId('Hide-elements').should('not.exist'); cy.getByTestId('Fade-elements').should('not.exist'); }); + + it('can fade any type of nodes', () => { + fadeByElementTestId('IconLabel - Temperature: 25'); + fadeByElementTestId('Image - Motion_Engine'); + fadeByElementTestId('Rectangle - Central_Unit'); + fadeByElementTestId('List - Description'); + }); + + it.only('can hide any type of nodes', () => { + hideByElementTestId('IconLabel - Temperature: 25'); + hideByElementTestId('Image - Motion_Engine'); + hideByElementTestId('List - Description'); + hideByElementTestId('Rectangle - Central_Unit'); + }); }); diff --git a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/schema/diagram.graphqls b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/schema/diagram.graphqls index 5a4caa3475..761b719da5 100644 --- a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/schema/diagram.graphqls +++ b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/schema/diagram.graphqls @@ -44,10 +44,21 @@ type Node { position: Position! state: ViewModifier! style: INodeStyle! + childrenLayoutStrategy: ILayoutStrategy borderNodes: [Node!]! childNodes: [Node!]! } +type FreeFormLayoutStrategy { + kind: String! +} + +type ListLayoutStrategy { + kind: String! +} + +union ILayoutStrategy = FreeFormLayoutStrategy | ListLayoutStrategy + type Label { id: ID! text: String! diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/converter/convertDiagram.ts b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/converter/convertDiagram.ts index 5c3b005ef4..c643587c00 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/converter/convertDiagram.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/converter/convertDiagram.ts @@ -279,9 +279,7 @@ const toImageNode = (gqlNode: GQLNode, gqlParentNode: GQLNode | null): Node { if (gqlNode.style.__typename === 'RectangularNodeStyle') { - const isList = - (gqlNode.childNodes ?? []).filter((gqlChildNode) => gqlChildNode.style.__typename === 'IconLabelNodeStyle') - .length > 0; + const isList = gqlNode.childrenLayoutStrategy?.kind === 'List'; if (!isList) { nodes.push(toRectangularNode(gqlNode, parentNode)); diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/graphql/subscription/nodeFragment.ts b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/graphql/subscription/nodeFragment.ts index 057a2c56a0..fc70f6b60e 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/graphql/subscription/nodeFragment.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/graphql/subscription/nodeFragment.ts @@ -44,6 +44,15 @@ fragment nodeFragment on Node { backgroundColor } } + childrenLayoutStrategy { + __typename + ... on ListLayoutStrategy { + kind + } + ... on FreeFormLayoutStrategy { + kind + } + } userResizable } `; diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/graphql/subscription/nodeFragment.types.ts b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/graphql/subscription/nodeFragment.types.ts index a3c8cf59f5..ed6bd52ec3 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/graphql/subscription/nodeFragment.types.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/graphql/subscription/nodeFragment.types.ts @@ -22,12 +22,26 @@ export interface GQLNode { state: GQLViewModifier; label: GQLLabel; style: GQLNodeStyle; + childrenLayoutStrategy?: ILayoutStrategy; borderNodes: GQLNode[] | undefined; childNodes: GQLNode[] | undefined; position: GQLPosition; size: GQLSize; } +export interface ILayoutStrategy { + __typename: string; + kind: string; +} + +export interface ListLayoutStrategy extends ILayoutStrategy { + kind: 'List'; +} + +export interface FreeFormLayoutStrategy extends ILayoutStrategy { + kind: 'FreeForm'; +} + export enum GQLViewModifier { Normal = 'Normal', Faded = 'Faded', diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/IconLabelNodeLayoutHandler.ts b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/IconLabelNodeLayoutHandler.ts index 04377a7a25..d899d1a7ff 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/IconLabelNodeLayoutHandler.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/IconLabelNodeLayoutHandler.ts @@ -16,6 +16,8 @@ import { IconLabelNodeData } from '../node/IconsLabelNode.types'; import { DiagramNodeType } from '../node/NodeTypes.types'; import { ILayoutEngine, INodeLayoutHandler } from './LayoutEngine.types'; +const rectangularNodePadding = 8; + export class IconLabelNodeLayoutHandler implements INodeLayoutHandler { canHandle(node: Node) { return node.type === 'iconLabelNode'; @@ -25,12 +27,15 @@ export class IconLabelNodeLayoutHandler implements INodeLayoutHandler, visibleNodes: Node[], - _directChildren: Node[] + _directChildren: Node[], + forceWidth?: number ) { const nodeIndex = this.findNodeIndex(visibleNodes, node.id); const labelElement = document.getElementById(`${node.id}-label-${nodeIndex}`); - node.width = labelElement?.getBoundingClientRect().width; + node.width = + forceWidth ?? + rectangularNodePadding + (labelElement?.getBoundingClientRect().width ?? 0) + rectangularNodePadding; node.height = labelElement?.getBoundingClientRect().height; } diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/ImageNodeLayoutHandler.ts b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/ImageNodeLayoutHandler.ts index 286ddd5faa..5cf411a023 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/ImageNodeLayoutHandler.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/ImageNodeLayoutHandler.ts @@ -30,9 +30,10 @@ export class ImageNodeLayoutHandler implements INodeLayoutHandler previousDiagram: Diagram | null, node: Node, _visibleNodes: Node[], - _directChildren: Node[] + _directChildren: Node[], + forceWidth?: number ) { - node.width = defaultWidth; + node.width = forceWidth ?? defaultWidth; node.height = defaultHeight; const previousNode = (previousDiagram?.nodes ?? []).find((previousNode) => previousNode.id === node.id); diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/LayoutEngine.ts b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/LayoutEngine.ts index 0775d49104..b066b5ea57 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/LayoutEngine.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/LayoutEngine.ts @@ -31,7 +31,8 @@ export class LayoutEngine implements ILayoutEngine { public layoutNodes( previousDiagram: Diagram | null, visibleNodes: Node[], - nodesToLayout: Node[] + nodesToLayout: Node[], + forceWidth?: number ) { nodesToLayout.forEach((node) => { const nodeLayoutHandler: INodeLayoutHandler | undefined = this.nodeLayoutHandlers.find((handler) => @@ -39,7 +40,7 @@ export class LayoutEngine implements ILayoutEngine { ); if (nodeLayoutHandler) { const directChildren = visibleNodes.filter((visibleNode) => visibleNode.parentNode === node.id); - nodeLayoutHandler.handle(this, previousDiagram, node, visibleNodes, directChildren); + nodeLayoutHandler.handle(this, previousDiagram, node, visibleNodes, directChildren, forceWidth); node.style = { ...node.style, diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/LayoutEngine.types.ts b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/LayoutEngine.types.ts index d064797e5e..e718ae4a6f 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/LayoutEngine.types.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/LayoutEngine.types.ts @@ -19,7 +19,8 @@ export interface ILayoutEngine { layoutNodes( previousDiagram: Diagram | null, visibleNodes: Node[], - nodesToLayout: Node[] + nodesToLayout: Node[], + forceWidth?: number ); } @@ -30,6 +31,7 @@ export interface INodeLayoutHandler { previousDiagram: Diagram | null, node: Node, visibleNodes: Node[], - directChildren: Node[] + directChildren: Node[], + forceWidth?: number ); } diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/ListNodeLayoutHandler.ts b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/ListNodeLayoutHandler.ts index a2b318000b..0c2c00adb6 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/ListNodeLayoutHandler.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/ListNodeLayoutHandler.ts @@ -17,7 +17,6 @@ import { ListNodeData } from '../node/ListNode.types'; import { DiagramNodeType } from '../node/NodeTypes.types'; import { ILayoutEngine, INodeLayoutHandler } from './LayoutEngine.types'; -const rectangularNodePadding = 8; const defaultWidth = 150; const defaultHeight = 70; @@ -31,26 +30,32 @@ export class ListNodeLayoutHandler implements INodeLayoutHandler { previousDiagram: Diagram | null, node: Node, visibleNodes: Node[], - directChildren: Node[] + directChildren: Node[], + forceWidth?: number ) { const nodeIndex = this.findNodeIndex(visibleNodes, node.id); const nodeElement = document.getElementById(`${node.id}-listNode-${nodeIndex}`)?.children[0]; const borderWidth = nodeElement ? parseFloat(window.getComputedStyle(nodeElement).borderWidth) : 0; if (directChildren.length > 0) { - this.handleParentNode(layoutEngine, previousDiagram, node, visibleNodes, directChildren, borderWidth); + this.handleParentNode(layoutEngine, previousDiagram, node, visibleNodes, directChildren, borderWidth, forceWidth); } else { - this.handleLeafNode(previousDiagram, node, visibleNodes, borderWidth); + this.handleLeafNode(previousDiagram, node, visibleNodes, borderWidth, forceWidth); } } handleLeafNode( _previousDiagram: Diagram | null, node: Node, - _visibleNodes: Node[], - _borderWidth: number + visibleNodes: Node[], + borderWidth: number, + forceWidth?: number ) { - node.width = this.getNodeOrMinWidth(undefined); - node.height = this.getNodeOrMinHeight(undefined); + const labelElement = document.getElementById(`${node.id}-label-${this.findNodeIndex(visibleNodes, node.id)}`); + + const nodeWidth = (labelElement?.getBoundingClientRect().width ?? 0) + borderWidth * 2; + const nodeHeight = (labelElement?.getBoundingClientRect().height ?? 0) + borderWidth * 2; + node.width = forceWidth ?? this.getNodeOrMinWidth(nodeWidth); + node.height = this.getNodeOrMinHeight(nodeHeight); } private handleParentNode( layoutEngine: ILayoutEngine, @@ -58,48 +63,40 @@ export class ListNodeLayoutHandler implements INodeLayoutHandler { node: Node, visibleNodes: Node[], directChildren: Node[], - borderWidth: number + borderWidth: number, + forceWidth?: number ) { - layoutEngine.layoutNodes(previousDiagram, visibleNodes, directChildren); + layoutEngine.layoutNodes(previousDiagram, visibleNodes, directChildren, forceWidth); const nodeIndex = this.findNodeIndex(visibleNodes, node.id); const labelElement = document.getElementById(`${node.id}-label-${nodeIndex}`); - const iconLabelNodes = directChildren.filter((child) => child.type === 'iconLabelNode'); - iconLabelNodes.forEach((child, index) => { + if (!forceWidth) { + const widerWidth = directChildren.reduce( + (widerWidth, child) => Math.max(child.width ?? 0, widerWidth), + labelElement?.getBoundingClientRect().width ?? 0 + ); + + layoutEngine.layoutNodes(previousDiagram, visibleNodes, directChildren, widerWidth); + } + + directChildren.forEach((child, index) => { child.position = { - x: 0, - y: (labelElement?.getBoundingClientRect().height ?? 0) + rectangularNodePadding, + x: borderWidth, + y: borderWidth + (labelElement?.getBoundingClientRect().height ?? 0), }; - const previousSibling = iconLabelNodes[index - 1]; + const previousSibling = directChildren[index - 1]; if (previousSibling) { child.position = { ...child.position, y: previousSibling.position.y + (previousSibling.height ?? 0) }; } }); - const childrenFootprint = this.getChildrenFootprint(iconLabelNodes); - const childrenAwareNodeWidth = childrenFootprint.x + childrenFootprint.width + rectangularNodePadding; - const labelOnlyWidth = - rectangularNodePadding + (labelElement?.getBoundingClientRect().width ?? 0) + rectangularNodePadding; - const nodeWidth = Math.max(childrenAwareNodeWidth, labelOnlyWidth) + borderWidth * 2; - node.width = this.getNodeOrMinWidth(nodeWidth); - node.height = this.getNodeOrMinHeight( - (labelElement?.getBoundingClientRect().height ?? 0) + - rectangularNodePadding + - childrenFootprint.height + - borderWidth * 2 - ); - - if (nodeWidth > childrenAwareNodeWidth) { - // we need to adjust the width of children - iconLabelNodes.forEach((child) => { - child.width = nodeWidth; - child.style = { - ...child.style, - width: `${nodeWidth}px`, - }; - }); - } + const childrenFootprint = this.getChildrenFootprint(directChildren); + const labelOnlyWidth = labelElement?.getBoundingClientRect().width ?? 0; + const nodeWidth = Math.max(childrenFootprint.width, labelOnlyWidth) + borderWidth * 2; + const nodeHeight = (labelElement?.getBoundingClientRect().height ?? 0) + childrenFootprint.height + borderWidth * 2; + node.width = forceWidth ?? this.getNodeOrMinWidth(nodeWidth); + node.height = this.getNodeOrMinHeight(nodeHeight); } private findNodeIndex(nodes: Node[], nodeId: string): number { diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/RectangleNodeLayoutHandler.ts b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/RectangleNodeLayoutHandler.ts index d92b499627..986508dbb7 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/RectangleNodeLayoutHandler.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/RectangleNodeLayoutHandler.ts @@ -32,16 +32,17 @@ export class RectangleNodeLayoutHandler implements INodeLayoutHandler, visibleNodes: Node[], - directChildren: Node[] + directChildren: Node[], + forceWidth?: number ) { const nodeIndex = this.findNodeIndex(visibleNodes, node.id); const nodeElement = document.getElementById(`${node.id}-rectangularNode-${nodeIndex}`)?.children[0]; const borderWidth = nodeElement ? parseFloat(window.getComputedStyle(nodeElement).borderWidth) : 0; if (directChildren.length > 0) { - this.handleParentNode(layoutEngine, previousDiagram, node, visibleNodes, directChildren, borderWidth); + this.handleParentNode(layoutEngine, previousDiagram, node, visibleNodes, directChildren, borderWidth, forceWidth); } else { - this.handleLeafNode(previousDiagram, node, visibleNodes, borderWidth); + this.handleLeafNode(previousDiagram, node, visibleNodes, borderWidth, forceWidth); } } @@ -51,7 +52,8 @@ export class RectangleNodeLayoutHandler implements INodeLayoutHandler, visibleNodes: Node[], directChildren: Node[], - borderWidth: number + borderWidth: number, + forceWidth?: number ) { layoutEngine.layoutNodes(previousDiagram, visibleNodes, directChildren); @@ -61,8 +63,12 @@ export class RectangleNodeLayoutHandler implements INodeLayoutHandler { child.position = { - x: rectangularNodePadding, - y: rectangularNodePadding + (labelElement?.getBoundingClientRect().height ?? 0) + rectangularNodePadding, + x: borderWidth + rectangularNodePadding, + y: + borderWidth + + rectangularNodePadding + + (labelElement?.getBoundingClientRect().height ?? 0) + + rectangularNodePadding, }; const previousSibling = directChildren[index - 1]; if (previousSibling) { @@ -73,26 +79,25 @@ export class RectangleNodeLayoutHandler implements INodeLayoutHandler, visibleNodes: Node[], - borderWidth: number + borderWidth: number, + forceWidth?: number ) { const nodeIndex = this.findNodeIndex(visibleNodes, node.id); const labelElement = document.getElementById(`${node.id}-label-${nodeIndex}`); @@ -104,10 +109,8 @@ export class RectangleNodeLayoutHandler implements INodeLayoutHandler previousNode.id === node.id); if (previousNode && previousNode.width && previousNode.height) { diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/layout.tsx b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/layout.tsx index dc8c63a651..5b68e0aff6 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/layout.tsx +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/layout.tsx @@ -47,11 +47,11 @@ const emptyRectangularNodeProps = { type: 'rectangularNode', }; -const elk = new ELK(); - const isListNode = (node: Node): node is Node => node.type === 'listNode'; const isRectangularNode = (node: Node): node is Node => node.type === 'rectangularNode'; +const elk = new ELK(); + export const prepareLayoutArea = (diagram: Diagram, renderCallback: () => void, httpOrigin: string): HTMLDivElement => { const hiddenContainer: HTMLDivElement = document.createElement('div'); hiddenContainer.id = 'hidden-container'; @@ -205,7 +205,10 @@ const layoutDiagram = (previousDiagram: Diagram | null, diagram: Diagram) => { }); }; -export const performDefaultAutoLayout = (nodes: Node[], edges: Edge[]): Promise<{ nodes: Node[] }> => { +export const performDefaultAutoLayout = ( + nodes: Node[], + edges: Edge[] +): Promise<{ nodes: Node[] }> => { const layoutOptions: LayoutOptions = { 'elk.algorithm': 'layered', 'elk.layered.spacing.nodeNodeBetweenLayers': '100', @@ -219,10 +222,10 @@ export const performDefaultAutoLayout = (nodes: Node[], edges: Edge[]): Promise< }; export const performAutoLayout = ( - nodes: Node[], + nodes: Node[], edges: Edge[], layoutOptions: LayoutOptions -): Promise<{ nodes: Node[] }> => { +): Promise<{ nodes: Node[] }> => { const graph: ElkNode = { id: 'root', layoutOptions, @@ -243,8 +246,8 @@ export const performAutoLayout = ( 'nodeLabels.placement': '[H_CENTER, V_TOP, INSIDE]', }, }; - if (node.type === 'rectangularNode') { - const rectangularNodeData: RectangularNodeData = node.data as RectangularNodeData; + if (isRectangularNode(node)) { + const rectangularNodeData: RectangularNodeData = node.data; const label = document.querySelector(`[data-id="${rectangularNodeData.label?.id}"]`); if (label) { diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/useLayout.types.ts b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/useLayout.types.ts index 72dcfa0b63..5d58567980 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/useLayout.types.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/layout/useLayout.types.ts @@ -12,7 +12,7 @@ *******************************************************************************/ import { Edge, Node } from 'reactflow'; -import { Diagram } from '../DiagramRenderer.types'; +import { Diagram, NodeData } from '../DiagramRenderer.types'; export interface UseLayoutValue { layout: ( @@ -20,7 +20,7 @@ export interface UseLayoutValue { diagramToLayout: Diagram, callback: (laidoutDiagram: Diagram) => void ) => void; - autoLayout: (nodes: Node[], edges: Edge[]) => Promise<{ nodes: Node[] }>; + autoLayout: (nodes: Node[], edges: Edge[]) => Promise<{ nodes: Node[] }>; } export type Step = 'INITIAL_STEP' | 'BEFORE_LAYOUT' | 'LAYOUT' | 'AFTER_LAYOUT'; diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/node/IconLabelNode.tsx b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/node/IconLabelNode.tsx index 86080d27e8..b6bf91a8e1 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/node/IconLabelNode.tsx +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/node/IconLabelNode.tsx @@ -26,7 +26,6 @@ const iconlabelStyle = ( ): React.CSSProperties => { const iconLabelNodeStyle: React.CSSProperties = { opacity: faded ? '0.4' : '', - marginLeft: '8px', ...style, }; @@ -40,9 +39,13 @@ const iconlabelStyle = ( export const IconLabelNode = memo(({ data, id, selected }: NodeProps) => { const theme = useTheme(); return ( -
- {data.label ?