Skip to content

Commit

Permalink
[4348] Move quick tools declaration on the backend
Browse files Browse the repository at this point in the history
Bug: #4348
Signed-off-by: Michaël Charfadi <michael.charfadi@obeosoft.com>
  • Loading branch information
mcharfadi committed Dec 27, 2024
1 parent 4b778e9 commit 4e44e62
Show file tree
Hide file tree
Showing 16 changed files with 782 additions and 463 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

=== Improvements

- https://github.com/eclipse-sirius/sirius-web/issues/4348[#4348] [sirius-web] Move quick tools declaration on the backend


== v2025.1.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public final class DiagramImageConstants {

public static final String REVEAL_FADED_ELEMENTS_SVG = IMAGES_ROOT_FOLDER + "/reveal-faded-elements.svg";

public static final String HIDE_SVG ="/icons/full/obj16/HideTool.svg";

private DiagramImageConstants() {
// Prevent instantiation
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export type {
DiagramPaletteToolContributionProps,
} from './renderer/palette/extensions/DiagramPaletteToolContribution.types';
export { diagramPaletteToolExtensionPoint } from './renderer/palette/extensions/DiagramPaletteToolExtensionPoints';
export type { GQLToolVariable, GQLToolVariableType } from './renderer/palette/usePalette.types';
export type { GQLToolVariable, GQLToolVariableType } from './renderer/palette/tools/useInvokeTool.types';
export type { DiagramPanelActionProps } from './renderer/panel/DiagramPanel.types';
export { diagramPanelActionExtensionPoint } from './renderer/panel/DiagramPanelExtensionPoints';
export { DiagramRepresentation } from './representation/DiagramRepresentation';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*******************************************************************************
* Copyright (c) 2023, 2024 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 { gql, useMutation } from '@apollo/client';
import { useMultiToast } from '@eclipse-sirius/sirius-components-core';
import { useCallback, useContext, useEffect } from 'react';
import { DiagramContext } from '../../contexts/DiagramContext';
import { DiagramContextValue } from '../../contexts/DiagramContext.types';
import {
GQLCollapsingState,
GQLErrorPayload,
GQLUpdateCollapsingStateData,
GQLUpdateCollapsingStateInput,
GQLUpdateCollapsingStatePayload,
GQLUpdateCollapsingStateVariables,
UseCollapseExpandElement,
} from './useCollapseExpandElement.types';

const updateCollapsingStateMutation = gql`
mutation updateCollapsingState($input: UpdateCollapsingStateInput!) {
updateCollapsingState(input: $input) {
__typename
... on SuccessPayload {
id
}
... on ErrorPayload {
message
}
}
}
`;

const isErrorPayload = (payload: GQLUpdateCollapsingStatePayload): payload is GQLErrorPayload =>
payload.__typename === 'ErrorPayload';

export const useCollapseExpandElement = (): UseCollapseExpandElement => {
const { addMessages, addErrorMessage } = useMultiToast();
const { diagramId, editingContextId } = useContext<DiagramContextValue>(DiagramContext);

const [collapseExpandMutation, { error: collpaseNodeError }] = useMutation<
GQLUpdateCollapsingStateData,
GQLUpdateCollapsingStateVariables
>(updateCollapsingStateMutation);

const collapseExpandElement = useCallback(
async (nodeId: string, collapsingState: GQLCollapsingState) => {
const input: GQLUpdateCollapsingStateInput = {
id: crypto.randomUUID(),
editingContextId,
representationId: diagramId,
diagramElementId: nodeId,
collapsingState,
};
const { data: collapseNodeData } = await collapseExpandMutation({ variables: { input } });
if (collapseNodeData) {
const { collapseExpandDiagramElement } = collapseNodeData;
if (isErrorPayload(collapseExpandDiagramElement)) {
addMessages(collapseExpandDiagramElement.messages);
}
}
},
[editingContextId, diagramId, collapseExpandMutation]
);

useEffect(() => {
if (collpaseNodeError) {
addErrorMessage('An unexpected error has occurred, please refresh the page');
}
}, [collpaseNodeError]);

return { collapseExpandElement };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright (c) 2023, 2024 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 { GQLMessage } from '../Tool.types';

export interface UseCollapseExpandElement {
collapseExpandElement: (nodeId: string, collapsingState: GQLCollapsingState) => void;
}

export interface GQLUpdateCollapsingStateData {
collapseExpandDiagramElement: GQLUpdateCollapsingStatePayload;
}

export interface GQLUpdateCollapsingStatePayload {
__typename: string;
}

export interface GQLUpdateCollapsingStateVariables {
input: GQLUpdateCollapsingStateInput;
}

export interface GQLUpdateCollapsingStateInput {
id: string;
editingContextId: string;
representationId: string;
diagramElementId: string;
collapsingState: GQLCollapsingState;
}

export enum GQLCollapsingState {
EXPANDED = 'EXPANDED',
COLLAPSED = 'COLLAPSED',
}

export interface GQLErrorPayload extends GQLUpdateCollapsingStatePayload {
message: string;
messages: GQLMessage[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,71 +10,21 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
import { gql, useMutation } from '@apollo/client';
import { useDeletionConfirmationDialog, useMultiToast } from '@eclipse-sirius/sirius-components-core';
import { useDeletionConfirmationDialog } from '@eclipse-sirius/sirius-components-core';
import { Edge, Node, useReactFlow } from '@xyflow/react';
import { useCallback, useContext, useEffect } from 'react';
import { useCallback, useContext } from 'react';
import { DiagramContext } from '../../contexts/DiagramContext';
import { DiagramContextValue } from '../../contexts/DiagramContext.types';
import { EdgeData, NodeData } from '../DiagramRenderer.types';
import {
GQLDeleteFromDiagramData,
GQLDeleteFromDiagramInput,
GQLDeleteFromDiagramPayload,
GQLDeleteFromDiagramSuccessPayload,
GQLDeleteFromDiagramVariables,
GQLDeletionPolicy,
GQLErrorPayload,
} from '../palette/usePalette.types';
import { UseDiagramDeleteValue } from './useDiagramDelete.types';

export const deleteFromDiagramMutation = gql`
mutation deleteFromDiagram($input: DeleteFromDiagramInput!) {
deleteFromDiagram(input: $input) {
__typename
... on ErrorPayload {
messages {
body
level
}
}
... on DeleteFromDiagramSuccessPayload {
messages {
body
level
}
}
}
}
`;

const isErrorPayload = (payload: GQLDeleteFromDiagramPayload): payload is GQLErrorPayload =>
payload.__typename === 'ErrorPayload';
const isSuccessPayload = (payload: GQLDeleteFromDiagramPayload): payload is GQLDeleteFromDiagramSuccessPayload =>
payload.__typename === 'DeleteFromDiagramSuccessPayload';
import { useDiagramDeleteMutation } from './useDiagramDeleteMutation';
import { GQLDeletionPolicy } from './useDiagramDeleteMutation.types';

export const useDiagramDelete = (): UseDiagramDeleteValue => {
const { addErrorMessage, addMessages } = useMultiToast();
const { showDeletionConfirmation } = useDeletionConfirmationDialog();
const { diagramId, editingContextId, readOnly } = useContext<DiagramContextValue>(DiagramContext);
const { getNodes } = useReactFlow<Node<NodeData>, Edge<EdgeData>>();

const [deleteElementsMutation, { data: deleteElementsData, error: deleteElementsError }] = useMutation<
GQLDeleteFromDiagramData,
GQLDeleteFromDiagramVariables
>(deleteFromDiagramMutation);

useEffect(() => {
if (deleteElementsError) {
addErrorMessage('An unexpected error has occurred, please refresh the page');
}
if (deleteElementsData) {
const { deleteFromDiagram } = deleteElementsData;
if (isErrorPayload(deleteFromDiagram) || isSuccessPayload(deleteFromDiagram)) {
addMessages(deleteFromDiagram.messages);
}
}
}, [deleteElementsData, deleteElementsError]);
const { diagramId, editingContextId, readOnly } = useContext<DiagramContextValue>(DiagramContext);
const { deleteElements } = useDiagramDeleteMutation();
const { showDeletionConfirmation } = useDeletionConfirmationDialog();

const onDelete = useCallback((event: React.KeyboardEvent<Element>) => {
const { key } = event;
Expand All @@ -89,16 +39,9 @@ export const useDiagramDelete = (): UseDiagramDeleteValue => {
const nodeToDeleteIds: string[] = getNodes()
.filter((node) => node.selected)
.map((node) => node.id);
const input: GQLDeleteFromDiagramInput = {
id: crypto.randomUUID(),
editingContextId,
representationId: diagramId,
nodeIds: nodeToDeleteIds,
edgeIds: [],
deletionPolicy: GQLDeletionPolicy.SEMANTIC,
};

showDeletionConfirmation(() => {
deleteElementsMutation({ variables: { input } });
deleteElements(nodeToDeleteIds, [], GQLDeletionPolicy.SEMANTIC);
});
}
}, []);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*******************************************************************************
* Copyright (c) 2023, 2024 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 { gql, useMutation } from '@apollo/client';
import { useMultiToast } from '@eclipse-sirius/sirius-components-core';
import { useCallback, useContext, useEffect } from 'react';
import { DiagramContext } from '../../contexts/DiagramContext';
import { DiagramContextValue } from '../../contexts/DiagramContext.types';
import {
GQLDeleteFromDiagramData,
GQLDeleteFromDiagramInput,
GQLDeleteFromDiagramPayload,
GQLDeleteFromDiagramSuccessPayload,
GQLDeleteFromDiagramVariables,
GQLDeletionPolicy,
GQLErrorPayload,
UseDiagramDeleteMutation,
} from './useDiagramDeleteMutation.types';

export const deleteFromDiagramMutation = gql`
mutation deleteFromDiagram($input: DeleteFromDiagramInput!) {
deleteFromDiagram(input: $input) {
__typename
... on ErrorPayload {
messages {
body
level
}
}
... on DeleteFromDiagramSuccessPayload {
messages {
body
level
}
}
}
}
`;

const isErrorPayload = (payload: GQLDeleteFromDiagramPayload): payload is GQLErrorPayload =>
payload.__typename === 'ErrorPayload';

const isSuccessPayload = (payload: GQLDeleteFromDiagramPayload): payload is GQLDeleteFromDiagramSuccessPayload =>
payload.__typename === 'DeleteFromDiagramSuccessPayload';

export const useDiagramDeleteMutation = (): UseDiagramDeleteMutation => {
const { addMessages, addErrorMessage } = useMultiToast();
const { diagramId, editingContextId } = useContext<DiagramContextValue>(DiagramContext);

const [deleteElementsMutation, { data: deleteElementsData, error: deleteElementsError }] = useMutation<
GQLDeleteFromDiagramData,
GQLDeleteFromDiagramVariables
>(deleteFromDiagramMutation);

const deleteElements = useCallback(
async (nodeIds: string[], edgesId: string[], deletePocily: GQLDeletionPolicy) => {
const input: GQLDeleteFromDiagramInput = {
id: crypto.randomUUID(),
editingContextId,
representationId: diagramId,
nodeIds: nodeIds,
edgeIds: edgesId,
deletionPolicy: deletePocily,
};

const { data } = await deleteElementsMutation({ variables: { input } });
if (data) {
const { deleteFromDiagram } = data;
if (isErrorPayload(deleteFromDiagram) || isSuccessPayload(deleteFromDiagram)) {
addMessages(deleteFromDiagram.messages);
}
}
},
[editingContextId, diagramId, deleteElementsMutation]
);

useEffect(() => {
if (deleteElementsError) {
addErrorMessage('An unexpected error has occurred, please refresh the page');
}
if (deleteElementsData) {
const { deleteFromDiagram } = deleteElementsData;
if (isErrorPayload(deleteFromDiagram) || isSuccessPayload(deleteFromDiagram)) {
addMessages(deleteFromDiagram.messages);
}
}
}, [deleteElementsData, deleteElementsError]);

return { deleteElements };
};
Loading

0 comments on commit 4e44e62

Please sign in to comment.