Skip to content

Commit 7886233

Browse files
committed
[6336] Move the retrieval of the connector tools in a dedicated hook
Bug: #6336 Signed-off-by: Michaël Charfadi <michael.charfadi@obeosoft.com>
1 parent 6a1e320 commit 7886233

File tree

5 files changed

+166
-104
lines changed

5 files changed

+166
-104
lines changed

CHANGELOG.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ It will require contributors to specify the persons involved in the decision pro
6161
To perform the refresh of the representation event processor, an instance of `IRepresentationRefresher` will be required.
6262
A new provisional method `IHierarchyEventProcessor#update` is available to update the state of the hierarchy event processor and publish a new hierarchy to the subscribers.
6363
- https://github.com/eclipse-sirius/sirius-web/issues/6334[#6334] [diagram] Use a dedicated hook to improve temporary edge rendering
64+
- https://github.com/eclipse-sirius/sirius-web/issues/6336[#6336] [diagram] Move the retrieval of the connector tools in a dedicated hook.
6465

6566

6667

packages/diagrams/frontend/sirius-components-diagrams/src/renderer/connector/ConnectorContextualMenu.tsx

Lines changed: 8 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -11,69 +11,24 @@
1111
* Obeo - initial API and implementation
1212
*******************************************************************************/
1313

14-
import { gql, useQuery } from '@apollo/client';
1514
import { IconOverlay, useMultiToast } from '@eclipse-sirius/sirius-components-core';
1615
import ListItemIcon from '@mui/material/ListItemIcon';
1716
import Menu from '@mui/material/Menu';
1817
import MenuItem from '@mui/material/MenuItem';
1918
import Typography from '@mui/material/Typography';
2019
import { Edge, Node, useReactFlow } from '@xyflow/react';
21-
import { memo, useContext, useEffect } from 'react';
22-
import { DiagramContext } from '../../contexts/DiagramContext';
23-
import { DiagramContextValue } from '../../contexts/DiagramContext.types';
20+
import { memo, useEffect } from 'react';
2421
import { EdgeData, NodeData } from '../DiagramRenderer.types';
25-
import {
26-
ConnectorContextualMenuProps,
27-
GetConnectorToolsData,
28-
GetConnectorToolsVariables,
29-
GQLDiagramDescription,
30-
GQLRepresentationDescription,
31-
GQLTool,
32-
} from './ConnectorContextualMenu.types';
22+
import { ConnectorContextualMenuProps, GQLTool } from './ConnectorContextualMenu.types';
3323
import { useConnector } from './useConnector';
24+
import { useConnectorPaletteContents } from './useConnectorPaletteContents';
3425
import { useSingleClickOnTwoDiagramElementTool } from './useSingleClickOnTwoDiagramElementTool';
3526
import { useTemporaryEdge } from './useTemporaryEdge';
3627

37-
export const getConnectorToolsQuery = gql`
38-
query getConnectorTools(
39-
$editingContextId: ID!
40-
$representationId: ID!
41-
$sourceDiagramElementId: ID!
42-
$targetDiagramElementId: ID!
43-
) {
44-
viewer {
45-
editingContext(editingContextId: $editingContextId) {
46-
representation(representationId: $representationId) {
47-
description {
48-
... on DiagramDescription {
49-
connectorTools(
50-
sourceDiagramElementId: $sourceDiagramElementId
51-
targetDiagramElementId: $targetDiagramElementId
52-
) {
53-
id
54-
label
55-
iconURL
56-
... on SingleClickOnTwoDiagramElementsTool {
57-
dialogDescriptionId
58-
}
59-
}
60-
}
61-
}
62-
}
63-
}
64-
}
65-
}
66-
`;
67-
68-
const isDiagramDescription = (
69-
representationDescription: GQLRepresentationDescription
70-
): representationDescription is GQLDiagramDescription => representationDescription.__typename === 'DiagramDescription';
71-
7228
const ConnectorContextualMenuComponent = memo(({}: ConnectorContextualMenuProps) => {
73-
const { editingContextId, diagramId } = useContext<DiagramContextValue>(DiagramContext);
7429
const { connection, position, onConnectorContextualMenuClose } = useConnector();
7530
const { addTempConnectionLine, removeTempConnectionLine } = useTemporaryEdge();
76-
const { addMessages, addErrorMessage } = useMultiToast();
31+
const { addMessages } = useMultiToast();
7732
const { screenToFlowPosition } = useReactFlow<Node<NodeData>, Edge<EdgeData>>();
7833
const { invokeConnectorTool, data: invokeSingleClickOnTwoDiagramElementToolCalled } =
7934
useSingleClickOnTwoDiagramElementTool();
@@ -89,29 +44,7 @@ const ConnectorContextualMenuComponent = memo(({}: ConnectorContextualMenuProps)
8944
const sourceDiagramElementId = connectionSource?.dataset.id ?? '';
9045
const targetDiagramElementId = connectionTarget?.dataset.id ?? '';
9146

92-
const variables: GetConnectorToolsVariables = {
93-
editingContextId,
94-
representationId: diagramId,
95-
sourceDiagramElementId,
96-
targetDiagramElementId,
97-
};
98-
const { loading, data, error } = useQuery<GetConnectorToolsData, GetConnectorToolsVariables>(getConnectorToolsQuery, {
99-
variables,
100-
skip: !connectionSource || !connectionTarget,
101-
});
102-
103-
useEffect(() => {
104-
if (error) {
105-
addErrorMessage(error.message);
106-
}
107-
}, [error]);
108-
109-
const connectorTools: GQLTool[] = [];
110-
const representationDescription: GQLRepresentationDescription | null | undefined =
111-
data?.viewer.editingContext?.representation?.description;
112-
if (representationDescription && isDiagramDescription(representationDescription)) {
113-
representationDescription.connectorTools.forEach((tool) => connectorTools.push(tool));
114-
}
47+
const { connectorTools, loading } = useConnectorPaletteContents(sourceDiagramElementId, targetDiagramElementId);
11548

11649
useEffect(() => {
11750
if (connectorTools.length > 1) {
@@ -120,11 +53,10 @@ const ConnectorContextualMenuComponent = memo(({}: ConnectorContextualMenuProps)
12053
}, [connection, connectorTools.length]);
12154

12255
useEffect(() => {
123-
if (!loading && connection && data && connectorTools.length === 0) {
124-
onConnectorContextualMenuClose();
56+
if (!loading && connection && connectorTools.length === 0) {
12557
addMessages([{ body: 'No edge found between source and target selected', level: 'WARNING' }]);
12658
}
127-
}, [loading, data, connection, connectorTools.length]);
59+
}, [loading, connectorTools, connection, connectorTools.length]);
12860

12961
useEffect(() => {
13062
return () => removeTempConnectionLine();
@@ -141,7 +73,7 @@ const ConnectorContextualMenuComponent = memo(({}: ConnectorContextualMenuProps)
14173
invokeConnectorTool(tool, sourceDiagramElementId, targetDiagramElementId, cursorPositionX, cursorPositionY);
14274
};
14375

144-
if (!data || connectorTools.length <= 1) {
76+
if (!connectorTools || connectorTools.length <= 1) {
14577
return null;
14678
}
14779

packages/diagrams/frontend/sirius-components-diagrams/src/renderer/connector/ConnectorContextualMenu.types.ts

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2023, 2025 Obeo.
2+
* Copyright (c) 2023, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -20,6 +20,10 @@ export interface ConnectorContextualMenuState {
2020
tool: GQLSingleClickOnTwoDiagramElementsTool | null;
2121
}
2222

23+
export interface GQLInvokeSingleClickOnTwoDiagramElementsToolVariables {
24+
input: GQLInvokeSingleClickOnTwoDiagramElementsToolInput;
25+
}
26+
2327
export interface GetConnectorToolsVariables {
2428
editingContextId: string;
2529
representationId: string;
@@ -42,33 +46,6 @@ export interface GQLToolVariable {
4246

4347
export type GQLToolVariableType = 'STRING' | 'OBJECT_ID' | 'OBJECT_ID_ARRAY';
4448

45-
export interface GetConnectorToolsData {
46-
viewer: GQLViewer;
47-
}
48-
49-
export interface GQLViewer {
50-
editingContext: GQLEditingContext | null;
51-
}
52-
53-
export interface GQLEditingContext {
54-
representation: GQLRepresentationMetadata | null;
55-
}
56-
57-
export interface GQLRepresentationMetadata {
58-
description: GQLRepresentationDescription;
59-
}
60-
61-
export interface GQLRepresentationDescription {
62-
__typename: string;
63-
}
64-
65-
export interface GQLDiagramDescription extends GQLRepresentationDescription {
66-
connectorTools: GQLTool[];
67-
}
68-
69-
export interface GQLInvokeSingleClickOnTwoDiagramElementsToolVariables {
70-
input: GQLInvokeSingleClickOnTwoDiagramElementsToolInput;
71-
}
7249
export interface GQLInvokeSingleClickOnTwoDiagramElementsToolInput {
7350
id: string;
7451
editingContextId: string;
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Obeo.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Obeo - initial API and implementation
12+
*******************************************************************************/
13+
14+
import { gql, useQuery } from '@apollo/client';
15+
import { useContext, useEffect } from 'react';
16+
17+
import { useMultiToast } from '@eclipse-sirius/sirius-components-core';
18+
import { DiagramContext } from '../../contexts/DiagramContext';
19+
import { DiagramContextValue } from '../../contexts/DiagramContext.types';
20+
import {
21+
GetConnectorToolsData,
22+
GetConnectorToolsVariables,
23+
GQLDiagramDescription,
24+
GQLRepresentationDescription,
25+
GQLTool,
26+
UseConnectorPaletteContentValue,
27+
} from './useConnectorPaletteContents.types';
28+
29+
export const getConnectorToolsQuery = gql`
30+
query getConnectorTools(
31+
$editingContextId: ID!
32+
$representationId: ID!
33+
$sourceDiagramElementId: ID!
34+
$targetDiagramElementId: ID!
35+
) {
36+
viewer {
37+
editingContext(editingContextId: $editingContextId) {
38+
representation(representationId: $representationId) {
39+
description {
40+
... on DiagramDescription {
41+
connectorTools(
42+
sourceDiagramElementId: $sourceDiagramElementId
43+
targetDiagramElementId: $targetDiagramElementId
44+
) {
45+
id
46+
label
47+
iconURL
48+
... on SingleClickOnTwoDiagramElementsTool {
49+
dialogDescriptionId
50+
}
51+
}
52+
}
53+
}
54+
}
55+
}
56+
}
57+
}
58+
`;
59+
60+
const isDiagramDescription = (
61+
representationDescription: GQLRepresentationDescription
62+
): representationDescription is GQLDiagramDescription => representationDescription.__typename === 'DiagramDescription';
63+
64+
export const useConnectorPaletteContents = (
65+
sourceDiagramElementId: string,
66+
targetDiagramElementId: string
67+
): UseConnectorPaletteContentValue => {
68+
const { diagramId, editingContextId } = useContext<DiagramContextValue>(DiagramContext);
69+
const { addErrorMessage } = useMultiToast();
70+
71+
const {
72+
data,
73+
loading,
74+
error: paletteError,
75+
} = useQuery<GetConnectorToolsData, GetConnectorToolsVariables>(getConnectorToolsQuery, {
76+
variables: {
77+
editingContextId,
78+
representationId: diagramId,
79+
sourceDiagramElementId,
80+
targetDiagramElementId,
81+
},
82+
});
83+
84+
const description: GQLRepresentationDescription | undefined =
85+
data?.viewer.editingContext?.representation?.description;
86+
87+
const connectorTools: GQLTool[] | null =
88+
description && isDiagramDescription(description) ? description.connectorTools : [];
89+
90+
useEffect(() => {
91+
if (paletteError) {
92+
addErrorMessage(paletteError.message);
93+
}
94+
}, [paletteError]);
95+
96+
return { connectorTools, loading };
97+
};
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Obeo.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Obeo - initial API and implementation
12+
*******************************************************************************/
13+
14+
export interface GetConnectorToolsVariables {
15+
editingContextId: string;
16+
representationId: string;
17+
sourceDiagramElementId: string;
18+
targetDiagramElementId: string;
19+
}
20+
21+
export interface UseConnectorPaletteContentValue {
22+
connectorTools: GQLTool[];
23+
loading: boolean;
24+
}
25+
26+
export interface GetConnectorToolsData {
27+
viewer: GQLViewer;
28+
}
29+
30+
export interface GQLViewer {
31+
editingContext: GQLEditingContext | null;
32+
}
33+
34+
export interface GQLEditingContext {
35+
representation: GQLRepresentationMetadata | null;
36+
}
37+
38+
export interface GQLRepresentationMetadata {
39+
description: GQLRepresentationDescription;
40+
}
41+
42+
export interface GQLRepresentationDescription {
43+
__typename: string;
44+
}
45+
46+
export interface GQLDiagramDescription extends GQLRepresentationDescription {
47+
connectorTools: GQLTool[];
48+
}
49+
50+
export interface GQLTool {
51+
id: string;
52+
label: string;
53+
iconURL: string[];
54+
__typename: string;
55+
}

0 commit comments

Comments
 (0)