From 79cd540115b3965ac3f2d61081b05b20ddfd1cec 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 | 1 + .../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(+), 86 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 6357db6107..718f29e65c 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -126,6 +126,7 @@ To illustrate this new feature, we contribute a new tool on the _Papaya Diagram_ - https://github.com/eclipse-sirius/sirius-web/issues/2358[#2358] [form] Adds diagnostic messages to the reference widget. - https://github.com/eclipse-sirius/sirius-web/issues/2260[#2260] [diagram] Keep the layout stable over time - 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.8.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 583f684654..33c68130ac 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 158c0c9e36..9239a1bf84 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 4c43c111a2..4965046721 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 ?