From d8d770dc7f45507d33b4f6d565293b0ef1cbdb32 Mon Sep 17 00:00:00 2001 From: Gwendal Daniel Date: Wed, 24 Apr 2024 17:32:56 +0200 Subject: [PATCH] [3429] Add diagram filter view in diagram panel Bug: https://github.com/eclipse-sirius/sirius-web/issues/3429 Signed-off-by: Gwendal Daniel --- CHANGELOG.adoc | 4 + doc/screenshots/diagramFilterView.png | Bin 0 -> 16539 bytes .../diagrams/api/DiagramImageConstants.java | 10 +- .../main/resources/diagram-images/fade.svg | 1 + .../src/main/resources/diagram-images/pin.svg | 1 + .../diagram-images/reveal-faded-elements.svg | 43 +++ .../main/resources/diagram-images/unpin.svg | 1 + .../tests/navigation/DiagramNavigator.java | 8 + .../sirius-components-diagrams/src/index.ts | 2 + .../src/renderer/panel/DiagramPanel.tsx | 13 +- .../src/renderer/panel/DiagramPanel.types.ts | 5 + .../panel/DiagramPanelExtensionPoints.ts | 20 ++ .../EditTreeCheckboxMutationRunner.java | 61 ++++ .../graphql/PushButtonMutationRunner.java | 61 ++++ .../sirius-components-forms/src/index.ts | 4 + ...criptionDiagramFilterEventDataFetcher.java | 73 ++++ .../CollapseButtonDescriptionProvider.java | 91 +++++ .../DiagramFilterDescriptionProvider.java | 340 ++++++++++++++++++ .../DiagramFilterEventProcessorFactory.java | 107 ++++++ .../services/filter/DiagramFilterHelper.java | 104 ++++++ .../DiagramFilterRefreshPolicyProvider.java | 48 +++ .../ExpandButtonDescriptionProvider.java | 91 +++++ .../filter/FadeButtonDescriptionProvider.java | 81 +++++ .../filter/HideButtonDescriptionProvider.java | 80 +++++ .../filter/PinButtonDescriptionProvider.java | 82 +++++ ...adedElementsButtonDescriptionProvider.java | 81 +++++ .../filter/ShowButtonDescriptionProvider.java | 80 +++++ .../filter/UnpinButtonDescription.java | 81 +++++ .../api/DiagramFilterConfiguration.java | 49 +++ ...agramFilterActionContributionProvider.java | 26 ++ .../IDiagramFilterDescriptionProvider.java | 26 ++ .../filter/api/IDiagramFilterHelper.java | 31 ++ .../resources/schema/diagram-filter.graphqls | 3 + .../domain/services/api/IMessageService.java | 17 + .../infrastructure/i18n/MessageService.java | 40 +++ .../main/resources/i18n/messages.properties | 10 +- .../CollapseButtonDescriptionProvider.java | 91 +++++ .../DiagramFilterDescriptionProvider.java | 340 ++++++++++++++++++ .../DiagramFilterEventProcessorFactory.java | 111 ++++++ .../diagramfilter/DiagramFilterHelper.java | 110 ++++++ .../DiagramFilterRefreshPolicyProvider.java | 48 +++ .../ExpandButtonDescriptionProvider.java | 91 +++++ .../FadeButtonDescriptionProvider.java | 81 +++++ .../HideButtonDescriptionProvider.java | 80 +++++ .../PinButtonDescriptionProvider.java | 82 +++++ ...adedElementsButtonDescriptionProvider.java | 81 +++++ .../ShowButtonDescriptionProvider.java | 80 +++++ ...criptionDiagramFilterEventDataFetcher.java | 74 ++++ .../diagramfilter/UnpinButtonDescription.java | 81 +++++ .../api/DiagramFilterConfiguration.java | 49 +++ ...agramFilterActionContributionProvider.java | 26 ++ .../IDiagramFilterDescriptionProvider.java | 26 ++ .../api/IDiagramFilterHelper.java | 31 ++ .../messages/IServicesMessageService.java | 15 + .../messages/ServicesMessageService.java | 40 +++ .../messages/sirius-web-services.properties | 10 +- .../resources/schema/diagram-filter.graphqls | 3 + .../projects/NoOpServicesMessageService.java | 40 +++ .../DiagramFilterEventSubscriptionRunner.java | 50 +++ .../DiagramFilterControllerTests.java | 325 +++++++++++++++++ .../src/diagrams/DiagramFilter.tsx | 75 ++++ .../src/diagrams/DiagramFilter.types.ts | 17 + .../src/diagrams/DiagramFilterForm.tsx | 42 +++ .../src/diagrams/DiagramFilterForm.types.ts | 17 + ...iagramRepresentationConfiguration.types.ts | 3 +- .../extension/DefaultExtensionRegistry.tsx | 20 +- 66 files changed, 3904 insertions(+), 10 deletions(-) create mode 100644 doc/screenshots/diagramFilterView.png create mode 100644 packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/fade.svg create mode 100644 packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/pin.svg create mode 100644 packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/reveal-faded-elements.svg create mode 100644 packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/unpin.svg create mode 100644 packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanelExtensionPoints.ts create mode 100644 packages/forms/backend/sirius-components-forms-tests/src/main/java/org/eclipse/sirius/components/forms/tests/graphql/EditTreeCheckboxMutationRunner.java create mode 100644 packages/forms/backend/sirius-components-forms-tests/src/main/java/org/eclipse/sirius/components/forms/tests/graphql/PushButtonMutationRunner.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/controllers/SubscriptionDiagramFilterEventDataFetcher.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/CollapseButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterEventProcessorFactory.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterHelper.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterRefreshPolicyProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/ExpandButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/FadeButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/HideButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/PinButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/RevealFadedElementsButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/ShowButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/UnpinButtonDescription.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/DiagramFilterConfiguration.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterActionContributionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterHelper.java create mode 100644 packages/sirius-web/backend/sirius-web-application/src/main/resources/schema/diagram-filter.graphqls create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/CollapseButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterEventProcessorFactory.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterHelper.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterRefreshPolicyProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/ExpandButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/FadeButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/HideButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/PinButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/RevealFadedElementsButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/ShowButtonDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/SubscriptionDiagramFilterEventDataFetcher.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/UnpinButtonDescription.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/DiagramFilterConfiguration.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterActionContributionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterDescriptionProvider.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterHelper.java create mode 100644 packages/sirius-web/backend/sirius-web-services/src/main/resources/schema/diagram-filter.graphqls create mode 100644 packages/sirius-web/backend/sirius-web-tests/src/main/java/org/eclipse/sirius/web/tests/graphql/DiagramFilterEventSubscriptionRunner.java create mode 100644 packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/diagrams/DiagramFilterControllerTests.java create mode 100644 packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilter.tsx create mode 100644 packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilter.types.ts create mode 100644 packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilterForm.tsx create mode 100644 packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilterForm.types.ts diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 43892fad1d..031800075a 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -69,6 +69,10 @@ More existing APIs will be migrated to this new common pattern. - https://github.com/eclipse-sirius/sirius-web/issues/3553[#3553] [core] Add RepresentationFactory extension point - https://github.com/eclipse-sirius/sirius-web/issues/3587[#3587] [sirius-web] Add an extension point to contribute new project cards - https://github.com/eclipse-sirius/sirius-web/issues/3614[#3614] [core] Add the ability to contribute additional payloads to representation subscriptions +- https://github.com/eclipse-sirius/sirius-web/issues/3429[#3429] [diagram] Add a diagram filter dialog in the diagram panel. +This dialog presents diagram elements in a tree and allows to select them and update their visibility and status (e.g. hide, show, collapse). ++ +image:doc/screenshots/diagramFilterView.png[Diagram Filter View, 70%] === Improvements diff --git a/doc/screenshots/diagramFilterView.png b/doc/screenshots/diagramFilterView.png new file mode 100644 index 0000000000000000000000000000000000000000..f1f50d69f41189fb4f0aac5620af911d18281931 GIT binary patch literal 16539 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 literal 0 HcmV?d00001 diff --git a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/api/DiagramImageConstants.java b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/api/DiagramImageConstants.java index cb3731f7d1..08bd282b67 100644 --- a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/api/DiagramImageConstants.java +++ b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/api/DiagramImageConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022, 2023 Obeo. + * Copyright (c) 2022, 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 @@ -31,6 +31,14 @@ public final class DiagramImageConstants { public static final String GRAPHICAL_DELETE_SVG = IMAGES_ROOT_FOLDER + "/graphicalDelete.svg"; + public static final String PIN_SVG = IMAGES_ROOT_FOLDER + "/pin.svg"; + + public static final String UNPIN_SVG = IMAGES_ROOT_FOLDER + "/unpin.svg"; + + public static final String FADE_SVG = IMAGES_ROOT_FOLDER + "/fade.svg"; + + public static final String REVEAL_FADED_ELEMENTS_SVG = IMAGES_ROOT_FOLDER + "/reveal-faded-elements.svg"; + private DiagramImageConstants() { // Prevent instantiation } diff --git a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/fade.svg b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/fade.svg new file mode 100644 index 0000000000..e590c0e695 --- /dev/null +++ b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/fade.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/pin.svg b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/pin.svg new file mode 100644 index 0000000000..8ba9f03dfc --- /dev/null +++ b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/pin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/reveal-faded-elements.svg b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/reveal-faded-elements.svg new file mode 100644 index 0000000000..189c670b41 --- /dev/null +++ b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/reveal-faded-elements.svg @@ -0,0 +1,43 @@ + + + + + + + diff --git a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/unpin.svg b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/unpin.svg new file mode 100644 index 0000000000..11ed10940c --- /dev/null +++ b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/diagram-images/unpin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/diagrams/backend/sirius-components-diagrams-tests/src/main/java/org/eclipse/sirius/components/diagrams/tests/navigation/DiagramNavigator.java b/packages/diagrams/backend/sirius-components-diagrams-tests/src/main/java/org/eclipse/sirius/components/diagrams/tests/navigation/DiagramNavigator.java index 3f2e595333..ef3bea1932 100644 --- a/packages/diagrams/backend/sirius-components-diagrams-tests/src/main/java/org/eclipse/sirius/components/diagrams/tests/navigation/DiagramNavigator.java +++ b/packages/diagrams/backend/sirius-components-diagrams-tests/src/main/java/org/eclipse/sirius/components/diagrams/tests/navigation/DiagramNavigator.java @@ -41,6 +41,14 @@ public NodeNavigator nodeWithLabel(String label) { return new NodeNavigator(nodes.get(0), this.cache); } + public NodeNavigator nodeWithId(String id) { + Node node = this.cache.getIdToNode().get(id); + if (node == null) { + throw new IllegalArgumentException(MessageFormat.format("No node found with id \"{0}\"", id)); + } + return new NodeNavigator(node, this.cache); + } + public NodeNavigator nodeWithTargetObjectLabel(String targetObjectLabel) { List nodes = this.cache.getTargetObjectLabelToNodes().get(targetObjectLabel); if (nodes == null || nodes.isEmpty()) { diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/index.ts b/packages/diagrams/frontend/sirius-components-diagrams/src/index.ts index a1a58ad62c..592e31e8ed 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams/src/index.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/index.ts @@ -52,5 +52,7 @@ export type { DiagramPaletteToolContextValue } from './renderer/palette/DiagramP export { DiagramPaletteToolContext } from './renderer/palette/DiagramPaletteToolContext'; export { DiagramPaletteToolContribution } from './renderer/palette/DiagramPaletteToolContribution'; export type { DiagramPaletteToolContributionComponentProps } from './renderer/palette/DiagramPaletteToolContribution.types'; +export type { DiagramPanelActionProps } from './renderer/panel/DiagramPanel.types'; +export { diagramPanelActionExtensionPoint } from './renderer/panel/DiagramPanelExtensionPoints'; export { DiagramRepresentation } from './representation/DiagramRepresentation'; export type { GQLDiagramDescription } from './representation/DiagramRepresentation.types'; diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.tsx b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.tsx index 37a8b42a80..c43d8e9891 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.tsx +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.tsx @@ -11,9 +11,9 @@ * Obeo - initial API and implementation *******************************************************************************/ -import { ShareRepresentationModal } from '@eclipse-sirius/sirius-components-core'; -import IconButton from '@material-ui/core/IconButton'; +import { ComponentExtension, ShareRepresentationModal, useComponents } from '@eclipse-sirius/sirius-components-core'; import CircularProgress from '@material-ui/core/CircularProgress'; +import IconButton from '@material-ui/core/IconButton'; import Paper from '@material-ui/core/Paper'; import Tooltip from '@material-ui/core/Tooltip'; import AccountTreeIcon from '@material-ui/icons/AccountTree'; @@ -41,7 +41,8 @@ import { useFullscreen } from '../fullscreen/useFullscreen'; import { useHideDiagramElements } from '../hide/useHideDiagramElements'; import { useArrangeAll } from '../layout/useArrangeAll'; import { usePinDiagramElements } from '../pin/usePinDiagramElements'; -import { DiagramPanelProps, DiagramPanelState } from './DiagramPanel.types'; +import { DiagramPanelActionProps, DiagramPanelProps, DiagramPanelState } from './DiagramPanel.types'; +import { diagramPanelActionExtensionPoint } from './DiagramPanelExtensionPoints'; import { useExportToImage } from './useExportToImage'; export const DiagramPanel = memo( @@ -53,6 +54,9 @@ export const DiagramPanel = memo( }); const { readOnly } = useContext(DiagramContext); + const diagramPanelActionComponents: ComponentExtension[] = useComponents( + diagramPanelActionExtensionPoint + ); const { getNodes, getEdges, zoomIn, zoomOut, fitView } = useReactFlow(); @@ -226,6 +230,9 @@ export const DiagramPanel = memo( + {diagramPanelActionComponents.map(({ Component: DiagramPanelActionComponent }, index) => ( + + ))} {state.dialogOpen === 'Share' ? ( diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.types.ts b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.types.ts index f76bbaa4d5..537d723e7b 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.types.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.types.ts @@ -26,3 +26,8 @@ export interface DiagramPanelState { } export type DiagramPanelDialog = 'Share'; + +export interface DiagramPanelActionProps { + editingContextId: string; + diagramId: string; +} diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanelExtensionPoints.ts b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanelExtensionPoints.ts new file mode 100644 index 0000000000..28d8393753 --- /dev/null +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanelExtensionPoints.ts @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 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 { ComponentExtensionPoint } from '@eclipse-sirius/sirius-components-core'; +import { DiagramPanelActionProps } from './DiagramPanel.types'; + +export const diagramPanelActionExtensionPoint: ComponentExtensionPoint = { + identifier: 'diagramPanel#action', + FallbackComponent: () => null, +}; diff --git a/packages/forms/backend/sirius-components-forms-tests/src/main/java/org/eclipse/sirius/components/forms/tests/graphql/EditTreeCheckboxMutationRunner.java b/packages/forms/backend/sirius-components-forms-tests/src/main/java/org/eclipse/sirius/components/forms/tests/graphql/EditTreeCheckboxMutationRunner.java new file mode 100644 index 0000000000..60d460f8d6 --- /dev/null +++ b/packages/forms/backend/sirius-components-forms-tests/src/main/java/org/eclipse/sirius/components/forms/tests/graphql/EditTreeCheckboxMutationRunner.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.components.forms.tests.graphql; + +import java.util.Objects; + +import org.eclipse.sirius.components.collaborative.forms.dto.EditTreeCheckboxInput; +import org.eclipse.sirius.components.graphql.tests.api.IGraphQLRequestor; +import org.eclipse.sirius.components.graphql.tests.api.IMutationRunner; +import org.springframework.stereotype.Service; + +/** + * Used to edit a tree checkbox with the GraphQL API. + * + * @author gdaniel + */ +@Service +public class EditTreeCheckboxMutationRunner implements IMutationRunner { + + private static final String EDIT_TREE_CHECKBOX_MUTATION = """ + mutation editTreeCheckbox($input: EditTreeCheckboxInput!) { + editTreeCheckbox(input: $input) { + __typename + ... on ErrorPayload { + messages { + body + level + } + } + ... on SuccessPayload { + messages { + body + level + } + } + } + } + """; + + private final IGraphQLRequestor graphQLRequestor; + + public EditTreeCheckboxMutationRunner(IGraphQLRequestor graphQLRequestor) { + this.graphQLRequestor = Objects.requireNonNull(graphQLRequestor); + } + + @Override + public String run(EditTreeCheckboxInput input) { + return this.graphQLRequestor.execute(EDIT_TREE_CHECKBOX_MUTATION, input); + } + +} diff --git a/packages/forms/backend/sirius-components-forms-tests/src/main/java/org/eclipse/sirius/components/forms/tests/graphql/PushButtonMutationRunner.java b/packages/forms/backend/sirius-components-forms-tests/src/main/java/org/eclipse/sirius/components/forms/tests/graphql/PushButtonMutationRunner.java new file mode 100644 index 0000000000..d3a256b5fe --- /dev/null +++ b/packages/forms/backend/sirius-components-forms-tests/src/main/java/org/eclipse/sirius/components/forms/tests/graphql/PushButtonMutationRunner.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.components.forms.tests.graphql; + +import java.util.Objects; + +import org.eclipse.sirius.components.collaborative.forms.dto.PushButtonInput; +import org.eclipse.sirius.components.graphql.tests.api.IGraphQLRequestor; +import org.eclipse.sirius.components.graphql.tests.api.IMutationRunner; +import org.springframework.stereotype.Service; + +/** + * Used to push a button with the GraphQL API. + * + * @author gdaniel + */ +@Service +public class PushButtonMutationRunner implements IMutationRunner { + + private static final String PUSH_BUTTON_MUTATION = """ + mutation pushButton($input: PushButtonInput!) { + pushButton(input: $input) { + __typename + ... on ErrorPayload { + messages { + body + level + } + } + ... on SuccessPayload { + messages { + body + level + } + } + } + } + """; + + private final IGraphQLRequestor graphQLRequestor; + + public PushButtonMutationRunner(IGraphQLRequestor graphQLRequestor) { + this.graphQLRequestor = Objects.requireNonNull(graphQLRequestor); + } + + @Override + public String run(PushButtonInput input) { + return this.graphQLRequestor.execute(PUSH_BUTTON_MUTATION, input); + } + +} diff --git a/packages/forms/frontend/sirius-components-forms/src/index.ts b/packages/forms/frontend/sirius-components-forms/src/index.ts index fdcaaeb92b..7c33d13236 100644 --- a/packages/forms/frontend/sirius-components-forms/src/index.ts +++ b/packages/forms/frontend/sirius-components-forms/src/index.ts @@ -15,6 +15,8 @@ export * from './form/FormContext'; export * from './form/FormContext.types'; export * from './form/FormEventFragments'; export * from './form/FormEventFragments.types'; +export * from './groups/Group'; +export * from './groups/Group.types'; export type { ButtonStyleProps } from './propertysections/ButtonPropertySection.types'; export type { CheckboxStyleProps } from './propertysections/CheckboxPropertySection.types'; export type { DateTimeStyleProps } from './propertysections/DateTimeWidgetPropertySection.types'; @@ -33,6 +35,8 @@ export * from './representations/FormRepresentation'; export * from './views/DetailsView'; export * from './views/DetailsViewConfiguration'; export * from './views/DetailsViewConfiguration.types'; +export * from './views/FormBasedView'; +export * from './views/FormBasedView.types'; export * from './views/FormConverter.types'; export * from './views/RelatedElementsView'; export * from './views/RepresentationsView'; diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/controllers/SubscriptionDiagramFilterEventDataFetcher.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/controllers/SubscriptionDiagramFilterEventDataFetcher.java new file mode 100644 index 0000000000..6fba4cb0f7 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/controllers/SubscriptionDiagramFilterEventDataFetcher.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.controllers; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import org.eclipse.sirius.components.annotations.spring.graphql.SubscriptionDataFetcher; +import org.eclipse.sirius.components.collaborative.forms.dto.PropertiesEventInput; +import org.eclipse.sirius.components.core.api.IPayload; +import org.eclipse.sirius.components.graphql.api.IDataFetcherWithFieldCoordinates; +import org.eclipse.sirius.components.graphql.api.IEventProcessorSubscriptionProvider; +import org.eclipse.sirius.components.graphql.api.IExceptionWrapper; +import org.eclipse.sirius.components.graphql.api.LocalContextConstants; +import org.eclipse.sirius.web.application.diagram.services.filter.api.DiagramFilterConfiguration; +import org.reactivestreams.Publisher; + +import graphql.execution.DataFetcherResult; +import graphql.schema.DataFetchingEnvironment; + +/** + * The data fetcher used to send the refreshed diagram filters to a subscription. + * + * @author gdaniel + */ +@SubscriptionDataFetcher(type = "Subscription", field = "diagramFilterEvent") +public class SubscriptionDiagramFilterEventDataFetcher implements IDataFetcherWithFieldCoordinates>> { + + private static final String INPUT_ARGUMENT = "input"; + + private final ObjectMapper objectMapper; + + private final IExceptionWrapper exceptionWrapper; + + private final IEventProcessorSubscriptionProvider eventProcessorSubscriptionProvider; + + public SubscriptionDiagramFilterEventDataFetcher(ObjectMapper objectMapper, IExceptionWrapper exceptionWrapper, IEventProcessorSubscriptionProvider eventProcessorSubscriptionProvider) { + this.objectMapper = Objects.requireNonNull(objectMapper); + this.exceptionWrapper = Objects.requireNonNull(exceptionWrapper); + this.eventProcessorSubscriptionProvider = Objects.requireNonNull(eventProcessorSubscriptionProvider); + } + + @Override + public Publisher> get(DataFetchingEnvironment environment) throws Exception { + Object argument = environment.getArgument(INPUT_ARGUMENT); + var input = this.objectMapper.convertValue(argument, PropertiesEventInput.class); + var diagramFilterConfiguration = new DiagramFilterConfiguration(input.id().toString(), input.objectIds()); + + Map localContext = new HashMap<>(); + localContext.put(LocalContextConstants.EDITING_CONTEXT_ID, input.editingContextId()); + localContext.put(LocalContextConstants.REPRESENTATION_ID, diagramFilterConfiguration.getId()); + + return this.exceptionWrapper.wrapFlux(() -> this.eventProcessorSubscriptionProvider.getSubscription(input.editingContextId(), diagramFilterConfiguration, input), input) + .map(payload -> DataFetcherResult.newResult() + .data(payload) + .localContext(localContext) + .build()); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/CollapseButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/CollapseButtonDescriptionProvider.java new file mode 100644 index 0000000000..54920f09fb --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/CollapseButtonDescriptionProvider.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.UpdateCollapsingStateInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.CollapsingState; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.Failure; +import org.eclipse.sirius.components.representations.Success; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the collapse button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class CollapseButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IMessageService messageService; + + public CollapseButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/collapse") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Collapse") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Collapse") + .imageURLProvider(variableManager -> DiagramImageConstants.COLLAPSE_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + boolean hasFailure = nodeIds.stream() + .map(nodeId -> this.diagramFilterHelper.sendDiagramEvent(variableManager, new UpdateCollapsingStateInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeId, CollapsingState.COLLAPSED))) + .anyMatch(Failure.class::isInstance); + if (hasFailure) { + return new Failure("An error occurred"); + } else { + return new Success(); + } + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.collapseSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterDescriptionProvider.java new file mode 100644 index 0000000000..396bf31bca --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterDescriptionProvider.java @@ -0,0 +1,340 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Stream; + +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventProcessor; +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventProcessorRegistry; +import org.eclipse.sirius.components.collaborative.api.IRepresentationEventProcessor; +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramEventProcessor; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.CollapsingState; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.diagrams.ViewModifier; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.AbstractControlDescription; +import org.eclipse.sirius.components.forms.description.CheckboxDescription; +import org.eclipse.sirius.components.forms.description.FormDescription; +import org.eclipse.sirius.components.forms.description.GroupDescription; +import org.eclipse.sirius.components.forms.description.LabelDescription; +import org.eclipse.sirius.components.forms.description.PageDescription; +import org.eclipse.sirius.components.forms.description.SplitButtonDescription; +import org.eclipse.sirius.components.forms.description.TreeDescription; +import org.eclipse.sirius.components.representations.GetOrCreateRandomIdProvider; +import org.eclipse.sirius.components.representations.Success; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterDescriptionProvider; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterHelper; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +/** + * Provides a tree description listing diagram elements and allowing to perform actions on them. + * + * @author gdaniel + */ +@Service +public class DiagramFilterDescriptionProvider implements IDiagramFilterDescriptionProvider { + + public static final String FORM_DESCRIPTION_ID = "diagram_filter_form_description"; + + public static final String SELECTED_TREE_NODES = "selectedTreeNodes"; + + public static final String EDITING_CONTEXT_EVENT_PROCESSOR = "editingContextEventProcessor"; + + public static final String DIAGRAM_EVENT_PROCESSOR = "diagramEventProcessor"; + + public static final String DIAGRAM = "diagram"; + + private static final String GROUP_DESCRIPTION_ID = "defaultDiagramFilterGroup"; + + private static final String PAGE_DESCRIPTION_ID = "defaultDiagramFilterPage"; + + private static final String FORM_TITLE = "Diagram Filters"; + + private final IObjectService objectService; + + private final IEditingContextEventProcessorRegistry editingContextEventProcessorRegistry; + + private final List diagramFilterActionContributionProviders; + + private final IDiagramFilterHelper diagramFilterHelper; + + public DiagramFilterDescriptionProvider(IObjectService objectService, @Lazy IEditingContextEventProcessorRegistry editingContextEventProcessorRegistry, List diagramFilterActionContributionProviders, IDiagramFilterHelper diagramFilterHelper) { + this.objectService = Objects.requireNonNull(objectService); + this.editingContextEventProcessorRegistry = Objects.requireNonNull(editingContextEventProcessorRegistry); + this.diagramFilterActionContributionProviders = Objects.requireNonNull(diagramFilterActionContributionProviders); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + } + + @Override + public FormDescription getFormDescription() { + List groupDescriptions = List.of(this.getGroupDescription()); + + Function targetObjectIdProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class) + .map(this.objectService::getId) + .orElse(null); + + return FormDescription.newFormDescription(FORM_DESCRIPTION_ID) + .label(FORM_TITLE) + .idProvider(new GetOrCreateRandomIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> FORM_TITLE) + .targetObjectIdProvider(targetObjectIdProvider) + .canCreatePredicate(variableManager -> false) + .variableManagerInitializer(vm -> { + if (this.editingContextEventProcessorRegistry != null) { + String editingContextId = vm.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).map(IEditingContext::getId).orElse(""); + Optional optDiagram = vm.get(VariableManager.SELF, Object.class) + .filter(Diagram.class::isInstance) + .map(Diagram.class::cast); + String diagramId = optDiagram + .map(Diagram::getId).orElse(null); + + IEditingContextEventProcessor editingContextEventProcessor = this.editingContextEventProcessorRegistry.getEditingContextEventProcessors().stream() + .filter(processor -> processor.getEditingContextId().equals(editingContextId)) + .findFirst() + .orElse(null); + IRepresentationEventProcessor diagramEventProcessor = Optional.ofNullable(editingContextEventProcessor) + .flatMap(processor -> processor.getRepresentationEventProcessors().stream() + .filter(IDiagramEventProcessor.class::isInstance) + .map(IDiagramEventProcessor.class::cast) + .filter(p -> p.getRepresentation().getId().equals(diagramId)) + .findFirst() + ) + .orElse(null); + vm.put(SELECTED_TREE_NODES, this.getCheckMap(optDiagram.get())); + vm.put(EDITING_CONTEXT_EVENT_PROCESSOR, editingContextEventProcessor); + vm.put(DIAGRAM_EVENT_PROCESSOR, diagramEventProcessor); + vm.put(DIAGRAM, diagramEventProcessor.getRepresentation()); + } + return vm; + }) + .pageDescriptions(List.of(this.getPageDescription(groupDescriptions))) + .build(); + } + + private PageDescription getPageDescription(List groupDescriptions) { + Function idProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class) + .map(this.objectService::getId) + .orElseGet(() -> UUID.randomUUID().toString()); + + Function labelProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class) + .map(this.objectService::getLabel) + .orElse(""); + + Function> semanticElementsProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class).stream().toList(); + + return PageDescription.newPageDescription(PAGE_DESCRIPTION_ID) + .idProvider(idProvider) + .labelProvider(labelProvider) + .semanticElementsProvider(semanticElementsProvider) + .groupDescriptions(groupDescriptions) + .canCreatePredicate(variableManager -> true) + .build(); + } + + private GroupDescription getGroupDescription() { + List controlDescriptions = new ArrayList<>(); + controlDescriptions.add(this.createTreeLabelDescription()); + controlDescriptions.add(this.createTreeCheckboxDescription()); + controlDescriptions.add(this.createTreeDescription()); + controlDescriptions.add(this.createSplitButtonDescription()); + + return GroupDescription.newGroupDescription(GROUP_DESCRIPTION_ID) + .idProvider(variableManager -> FORM_TITLE) + .labelProvider(variableManager -> "Filter elements") + .semanticElementsProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).stream().toList()) + .controlDescriptions(controlDescriptions) + .build(); + } + + private LabelDescription createTreeLabelDescription() { + return LabelDescription.newLabelDescription("diagram-filter/tree-label") + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .idProvider(new WidgetIdProvider()) + .labelProvider(variableManager -> "") + .valueProvider(variableManager -> "Elements on diagram") + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> null) + .build(); + } + + private CheckboxDescription createTreeCheckboxDescription() { + return CheckboxDescription.newCheckboxDescription("diagram-filter/tree-checkbox") + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .idProvider(new WidgetIdProvider()) + .labelProvider(variableManager -> { + int selectedElementCount = this.diagramFilterHelper.getSelectedElementIds(variableManager).size(); + String element = "element"; + if (selectedElementCount > 1) { + element += "s"; + } + return selectedElementCount + " " + element + " selected"; + }) + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .valueProvider(variableManager -> this.diagramFilterHelper.getSelectedElementIds(variableManager).size() > 0) + .newValueHandler((variableManager, newValue) -> { + Map checkMap = variableManager.get(SELECTED_TREE_NODES, Map.class).get(); + checkMap.entrySet().stream() + .forEach(entry -> entry.setValue(newValue)); + return new Success(); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> null) + .build(); + } + + private TreeDescription createTreeDescription() { + return TreeDescription.newTreeDescription("diagram-filter/tree") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .labelProvider(variableManager -> "") + .nodeIdProvider(this::getNodeId) + .nodeLabelProvider(this::getNodeLabel) + .nodeIconURLProvider(vm -> List.of()) + .nodeEndIconsURLProvider(this::computeNodeEndIcons) + .nodeKindProvider(vm -> "") + .nodeSelectableProvider(vm -> true) + .childrenProvider(this::getNodeChildren) + .expandedNodeIdsProvider(vm -> List.of()) + .isCheckableProvider(variableManager -> true) + .checkedValueProvider(variableManager -> this.diagramFilterHelper.getSelectedElementIds(variableManager).contains(this.getNodeId(variableManager))) + .newCheckedValueHandler((variableManager, newValue) -> { + Map selectedTreeNodes = variableManager.get(SELECTED_TREE_NODES, Map.class).get(); + String selfId = this.getNodeId(variableManager); + selectedTreeNodes.put(selfId, newValue); + return new Success(); + }) + .build(); + } + + private SplitButtonDescription createSplitButtonDescription() { + return SplitButtonDescription.newSplitButtonDescription("diagram-filter/split-button") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> { + int selectedElementCount = this.diagramFilterHelper.getSelectedElementIds(variableManager).size(); + String element = "element"; + if (selectedElementCount > 1) { + element += "s"; + } + + return "Apply to " + selectedElementCount + " selected " + element + ": "; + }) + .diagnosticsProvider(variableManager -> List.of()) + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .actions(this.diagramFilterActionContributionProviders.stream() + .map(IDiagramFilterActionContributionProvider::getButtonDescription) + .toList() + ) + .build(); + + } + + private String getNodeId(VariableManager vm) { + var self = vm.get(VariableManager.SELF, Object.class).orElse(null); + if (self instanceof Node node) { + return node.getId(); + } else { + return ""; + } + } + + private String getNodeLabel(VariableManager vm) { + var self = vm.get(VariableManager.SELF, Object.class).orElse(null); + String result = ""; + if (self instanceof Node node) { + if (node.getInsideLabel() != null) { + result = node.getInsideLabel().getText(); + } else if (!node.getOutsideLabels().isEmpty()) { + result = node.getOutsideLabels().get(0).text(); + } else if (node.getTargetObjectLabel() != null) { + result = node.getTargetObjectLabel(); + } + } + return result; + } + + private List getNodeChildren(VariableManager vm) { + var self = vm.get(VariableManager.SELF, Object.class).orElse(null); + final List result; + if (self instanceof Diagram diagram) { + result = diagram.getNodes(); + } else if (self instanceof Node node) { + result = node.getChildNodes(); + } else { + result = List.of(); + } + return result; + } + + private List> computeNodeEndIcons(VariableManager vm) { + var node = vm.get(VariableManager.SELF, Object.class) + .filter(Node.class::isInstance) + .map(Node.class::cast) + .orElse(null); + List> result = new ArrayList<>(); + if (node.getModifiers().contains(ViewModifier.Hidden)) { + result.add(List.of("/icons/full/obj16/HideTool.svg")); + } + if (node.getModifiers().contains(ViewModifier.Faded)) { + result.add(List.of(DiagramImageConstants.FADE_SVG)); + } + if (node.getCollapsingState().equals(CollapsingState.COLLAPSED)) { + result.add(List.of(DiagramImageConstants.COLLAPSE_SVG)); + } + if (node.isPinned()) { + result.add(List.of(DiagramImageConstants.PIN_SVG)); + } + return result; + } + + private Map getCheckMap(Diagram diagram) { + Map checkMap = new HashMap<>(); + for (Node node : diagram.getNodes()) { + this.fillCheckMap(node, checkMap); + } + return checkMap; + } + + private void fillCheckMap(Node node, Map checkMap) { + checkMap.put(node.getId(), false); + Stream.concat(node.getChildNodes().stream(), node.getBorderNodes().stream()) + .forEach(n -> this.fillCheckMap(n, checkMap)); + } +} \ No newline at end of file diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterEventProcessorFactory.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterEventProcessorFactory.java new file mode 100644 index 0000000000..4da2871135 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterEventProcessorFactory.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import org.eclipse.sirius.components.collaborative.api.IRepresentationConfiguration; +import org.eclipse.sirius.components.collaborative.api.IRepresentationEventProcessor; +import org.eclipse.sirius.components.collaborative.api.IRepresentationEventProcessorFactory; +import org.eclipse.sirius.components.collaborative.api.IRepresentationRefreshPolicyRegistry; +import org.eclipse.sirius.components.collaborative.api.IRepresentationSearchService; +import org.eclipse.sirius.components.collaborative.api.ISubscriptionManagerFactory; +import org.eclipse.sirius.components.collaborative.api.RepresentationEventProcessorFactoryConfiguration; +import org.eclipse.sirius.components.collaborative.forms.FormEventProcessor; +import org.eclipse.sirius.components.collaborative.forms.api.FormCreationParameters; +import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; +import org.eclipse.sirius.components.collaborative.forms.api.IFormPostProcessor; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorConfiguration; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorFactoryConfiguration; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.forms.description.FormDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; +import org.eclipse.sirius.web.application.diagram.services.filter.api.DiagramFilterConfiguration; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterDescriptionProvider; +import org.springframework.stereotype.Service; + +/** + * Used to create the diagram filter event processors. + * + * @author gdaniel + */ +@Service +public class DiagramFilterEventProcessorFactory implements IRepresentationEventProcessorFactory { + + private final IDiagramFilterDescriptionProvider diagramFilterDescriptionProvider; + + private final IObjectService objectService; + + private final IRepresentationSearchService representationSearchService; + + private final List widgetDescriptors; + + private final List formEventHandlers; + + private final ISubscriptionManagerFactory subscriptionManagerFactory; + + private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; + + private final IFormPostProcessor formPostProcessor; + + public DiagramFilterEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, IRepresentationSearchService representationSearchService, + IDiagramFilterDescriptionProvider diagramFilterDescriptionProvider, List widgetDescriptors, + FormEventProcessorFactoryConfiguration formConfiguration) { + this.diagramFilterDescriptionProvider = Objects.requireNonNull(diagramFilterDescriptionProvider); + this.objectService = Objects.requireNonNull(formConfiguration.getObjectService()); + this.representationSearchService = Objects.requireNonNull(representationSearchService); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); + this.formEventHandlers = Objects.requireNonNull(formConfiguration.getFormEventHandlers()); + this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory()); + this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry()); + this.formPostProcessor = Objects.requireNonNull(formConfiguration.getFormPostProcessor()); + } + + @Override + public boolean canHandle(IRepresentationConfiguration configuration) { + return configuration instanceof DiagramFilterConfiguration; + } + + @Override + public Optional createRepresentationEventProcessor(IRepresentationConfiguration configuration, + IEditingContext editingContext) { + if (configuration instanceof DiagramFilterConfiguration diagramFilterConfiguration && this.diagramFilterDescriptionProvider != null) { + var objects = diagramFilterConfiguration.getObjectIds().stream() + .map(objectId -> this.objectService.getObject(editingContext, objectId)) + .flatMap(Optional::stream) + .toList(); + if (!objects.isEmpty()) { + FormDescription formDescription = this.diagramFilterDescriptionProvider.getFormDescription(); + FormCreationParameters formCreationParameters = FormCreationParameters.newFormCreationParameters(diagramFilterConfiguration.getId()) + .editingContext(editingContext) + .formDescription(formDescription) + .object(objects.get(0)) + .selection(objects) + .build(); + + var formEventProcessorConfiguration = new FormEventProcessorConfiguration(editingContext, this.objectService, formCreationParameters, this.widgetDescriptors, this.formEventHandlers); + IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(formEventProcessorConfiguration, this.subscriptionManagerFactory.create(), this.representationSearchService, this.representationRefreshPolicyRegistry, this.formPostProcessor); + + return Optional.of(formEventProcessor); + } + } + return Optional.empty(); + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterHelper.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterHelper.java new file mode 100644 index 0000000000..9f979a58c4 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterHelper.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import java.text.MessageFormat; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import org.eclipse.sirius.components.collaborative.api.ChangeDescription; +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventProcessor; +import org.eclipse.sirius.components.collaborative.api.IRepresentationEventProcessor; +import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramInput; +import org.eclipse.sirius.components.core.api.ErrorPayload; +import org.eclipse.sirius.components.core.api.IPayload; +import org.eclipse.sirius.components.core.api.SuccessPayload; +import org.eclipse.sirius.components.representations.Failure; +import org.eclipse.sirius.components.representations.IStatus; +import org.eclipse.sirius.components.representations.Success; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import reactor.core.publisher.Sinks; +import reactor.core.publisher.Sinks.EmitResult; +import reactor.core.publisher.Sinks.Many; +import reactor.core.publisher.Sinks.One; + +/** + * Utility methods for the "Diagram Filter" view. + * + * @author gdaniel + */ +@Service +public class DiagramFilterHelper implements IDiagramFilterHelper { + + private final Logger logger = LoggerFactory.getLogger(DiagramFilterHelper.class); + + @Override + public Set getSelectedElementIds(VariableManager variableManager) { + return variableManager.get(DiagramFilterDescriptionProvider.SELECTED_TREE_NODES, Map.class) + .map(checkMap -> ((Map) checkMap).entrySet().stream() + .filter(e -> e.getValue().equals(Boolean.TRUE)) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()) + ) + .orElse(Set.of()); + } + + @Override + public IStatus sendDiagramEvent(VariableManager variableManager, IDiagramInput diagramInput) { + Optional representationEventProcessor = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM_EVENT_PROCESSOR, IRepresentationEventProcessor.class); + Optional editingContextEventProcessor = variableManager.get(DiagramFilterDescriptionProvider.EDITING_CONTEXT_EVENT_PROCESSOR, IEditingContextEventProcessor.class); + + if (representationEventProcessor.isEmpty() || editingContextEventProcessor.isEmpty()) { + String errorMessage = "Cannot find the diagramEventProcessor or the editingContextEventProcessor"; + this.logger.warn(errorMessage); + return new Failure(errorMessage); + } + + One payloadSink = Sinks.one(); + Many changeDescriptions = Sinks.many().unicast().onBackpressureBuffer(); + Consumer errorConsumer = throwable -> this.logger.warn(throwable.getMessage(), throwable); + changeDescriptions.asFlux().subscribe(changeDescription -> { + editingContextEventProcessor.get().getRepresentationEventProcessors().forEach(ep -> ep.refresh(changeDescription)); + }, errorConsumer); + + representationEventProcessor.get().handle(payloadSink, changeDescriptions, diagramInput); + IPayload handlerResult = payloadSink.asMono().block(); + + final IStatus result; + + EmitResult changeDescriptionEmitResult = changeDescriptions.tryEmitComplete(); + if (changeDescriptionEmitResult.isFailure()) { + String errorMessage = MessageFormat.format("An error has occurred while marking the publisher as complete: {0}", changeDescriptionEmitResult); + this.logger.warn(errorMessage); + result = new Failure(errorMessage); + } else { + if (handlerResult instanceof SuccessPayload) { + result = new Success(); + } else if (handlerResult instanceof ErrorPayload errorPayload) { + result = new Failure(errorPayload.message()); + } else { + result = new Failure("Unknown error"); + } + } + return result; + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterRefreshPolicyProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterRefreshPolicyProvider.java new file mode 100644 index 0000000000..f248023851 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/DiagramFilterRefreshPolicyProvider.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import org.eclipse.sirius.components.collaborative.api.ChangeKind; +import org.eclipse.sirius.components.collaborative.api.IRepresentationRefreshPolicy; +import org.eclipse.sirius.components.collaborative.api.IRepresentationRefreshPolicyProvider; +import org.eclipse.sirius.components.collaborative.diagrams.DiagramChangeKind; +import org.eclipse.sirius.components.representations.IRepresentationDescription; +import org.springframework.stereotype.Service; + +/** + * The representation refresh policy provider for the "Diagram Filter" form representation. + * + * @author gdaniel + */ +@Service +public class DiagramFilterRefreshPolicyProvider implements IRepresentationRefreshPolicyProvider { + + + @Override + public boolean canHandle(IRepresentationDescription representationDescription) { + return DiagramFilterDescriptionProvider.FORM_DESCRIPTION_ID.equals(representationDescription.getId()); + } + + @Override + public IRepresentationRefreshPolicy getRepresentationRefreshPolicy(IRepresentationDescription representationDescription) { + return changeDescription -> { + boolean shouldRefresh = false; + shouldRefresh = shouldRefresh || ChangeKind.SEMANTIC_CHANGE.equals(changeDescription.getKind()); + shouldRefresh = shouldRefresh || DiagramChangeKind.DIAGRAM_LAYOUT_CHANGE.equals(changeDescription.getKind()); + shouldRefresh = shouldRefresh || DiagramChangeKind.DIAGRAM_ELEMENT_VISIBILITY_CHANGE.equals(changeDescription.getKind()); + shouldRefresh = shouldRefresh || DiagramChangeKind.DIAGRAM_ELEMENT_COLLAPSING_STATE_CHANGE.equals(changeDescription.getKind()); + return shouldRefresh; + }; + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/ExpandButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/ExpandButtonDescriptionProvider.java new file mode 100644 index 0000000000..b4cb47af1e --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/ExpandButtonDescriptionProvider.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.UpdateCollapsingStateInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.CollapsingState; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.Failure; +import org.eclipse.sirius.components.representations.Success; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the expand button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class ExpandButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IMessageService messageService; + + public ExpandButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/expand") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Expand") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Expand") + .imageURLProvider(variableManager -> DiagramImageConstants.EXPAND_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + boolean hasFailure = nodeIds.stream() + .map(nodeId -> this.diagramFilterHelper.sendDiagramEvent(variableManager, new UpdateCollapsingStateInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeId, CollapsingState.EXPANDED))) + .anyMatch(Failure.class::isInstance); + if (hasFailure) { + return new Failure("An error occurred"); + } else { + return new Success(); + } + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.expandSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/FadeButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/FadeButtonDescriptionProvider.java new file mode 100644 index 0000000000..15324d1db0 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/FadeButtonDescriptionProvider.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.FadeDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the fade button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class FadeButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IMessageService messageService; + + public FadeButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/fade") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Fade") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Fade") + .imageURLProvider(variableManager -> DiagramImageConstants.FADE_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new FadeDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, true)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.fadeSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/HideButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/HideButtonDescriptionProvider.java new file mode 100644 index 0000000000..b5a2487e55 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/HideButtonDescriptionProvider.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.dto.HideDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the hide button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class HideButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IMessageService messageService; + + public HideButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/hide") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Hide") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Hide") + .imageURLProvider(variableManager -> "/icons/full/obj16/HideTool.svg") + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new HideDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, true)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.hideSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/PinButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/PinButtonDescriptionProvider.java new file mode 100644 index 0000000000..72dbb3db05 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/PinButtonDescriptionProvider.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.PinDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the pin button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class PinButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IMessageService messageService; + + public PinButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/pin") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Pin") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Pin") + .imageURLProvider(variableManager -> DiagramImageConstants.PIN_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new PinDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, true)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.pinSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/RevealFadedElementsButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/RevealFadedElementsButtonDescriptionProvider.java new file mode 100644 index 0000000000..7dcef24942 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/RevealFadedElementsButtonDescriptionProvider.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.FadeDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the reveal faded elements button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class RevealFadedElementsButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IMessageService messageService; + + public RevealFadedElementsButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/reveal-faded-elements") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Reveal faded elements") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Reveal faded elements") + .imageURLProvider(variableManager -> DiagramImageConstants.REVEAL_FADED_ELEMENTS_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new FadeDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, false)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.revealSelectedFadedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/ShowButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/ShowButtonDescriptionProvider.java new file mode 100644 index 0000000000..873d85a7bc --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/ShowButtonDescriptionProvider.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.dto.HideDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the show button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class ShowButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IMessageService messageService; + + public ShowButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/show") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Show") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Show") + .imageURLProvider(variableManager -> "/icons/full/obj16/ShowTool.svg") + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new HideDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, false)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.showSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/UnpinButtonDescription.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/UnpinButtonDescription.java new file mode 100644 index 0000000000..eef511b6f5 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/UnpinButtonDescription.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.PinDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.application.diagram.services.filter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.domain.services.api.IMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the unpin button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class UnpinButtonDescription implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IMessageService messageService; + + public UnpinButtonDescription(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/unpin") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Unpin") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Unpin") + .imageURLProvider(variableManager -> DiagramImageConstants.UNPIN_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new PinDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, false)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.unpinSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/DiagramFilterConfiguration.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/DiagramFilterConfiguration.java new file mode 100644 index 0000000000..af524d7550 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/DiagramFilterConfiguration.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter.api; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Objects; + +import org.eclipse.sirius.components.collaborative.api.IRepresentationConfiguration; + +/** + * The configuration used to create a diagram filter event processor. + * + * @author gdaniel + */ +public class DiagramFilterConfiguration implements IRepresentationConfiguration { + + private static final String DIAGRAM_FILTER_PREFIX = "diagramFilter://"; + + private final String formId; + + private final List objectIds; + + public DiagramFilterConfiguration(String id, List objectIds) { + this.objectIds = Objects.requireNonNull(objectIds); + var encodedIds = objectIds.stream().map(objectId -> URLEncoder.encode(objectId, StandardCharsets.UTF_8)).toList(); + this.formId = DIAGRAM_FILTER_PREFIX + "?id=" + id + "&objectIds=[" + String.join(",", encodedIds) + "]"; + } + + @Override + public String getId() { + return this.formId; + } + + public List getObjectIds() { + return this.objectIds; + } +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterActionContributionProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterActionContributionProvider.java new file mode 100644 index 0000000000..378d9e7e0e --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterActionContributionProvider.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter.api; + +import org.eclipse.sirius.components.forms.description.ButtonDescription; + +/** + * Provides the description of a button for the diagram filter's split button. + * + * @author gdaniel + */ +public interface IDiagramFilterActionContributionProvider { + + ButtonDescription getButtonDescription(); + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterDescriptionProvider.java new file mode 100644 index 0000000000..c6f73921ec --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterDescriptionProvider.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter.api; + +import org.eclipse.sirius.components.forms.description.FormDescription; + +/** + * Interface used to contribute the form to display for the "Diagram Filter" view. + * + * @author gdaniel + */ +public interface IDiagramFilterDescriptionProvider { + + FormDescription getFormDescription(); + +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterHelper.java b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterHelper.java new file mode 100644 index 0000000000..82a5bc0bd4 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/java/org/eclipse/sirius/web/application/diagram/services/filter/api/IDiagramFilterHelper.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.diagram.services.filter.api; + +import java.util.Set; + +import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramInput; +import org.eclipse.sirius.components.representations.IStatus; +import org.eclipse.sirius.components.representations.VariableManager; + +/** + * Provides utility methods for the "Diagram Filter" view. + * + * @author gdaniel + */ +public interface IDiagramFilterHelper { + + Set getSelectedElementIds(VariableManager variableManager); + + IStatus sendDiagramEvent(VariableManager variableManager, IDiagramInput diagramInput); +} diff --git a/packages/sirius-web/backend/sirius-web-application/src/main/resources/schema/diagram-filter.graphqls b/packages/sirius-web/backend/sirius-web-application/src/main/resources/schema/diagram-filter.graphqls new file mode 100644 index 0000000000..730d5e666e --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-application/src/main/resources/schema/diagram-filter.graphqls @@ -0,0 +1,3 @@ +extend type Subscription { + diagramFilterEvent(input : PropertiesEventInput!): PropertiesEventPayload! +} \ No newline at end of file diff --git a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/services/api/IMessageService.java b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/services/api/IMessageService.java index 8ac6cd19e0..444e60d318 100644 --- a/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/services/api/IMessageService.java +++ b/packages/sirius-web/backend/sirius-web-domain/src/main/java/org/eclipse/sirius/web/domain/services/api/IMessageService.java @@ -18,9 +18,26 @@ * @author sbegaudeau */ public interface IMessageService { + + String revealSelectedFadedElements(); + + String collapseSelectedElements(); + + String expandSelectedElements(); + + String fadeSelectedElements(); + + String hideSelectedElements(); + String invalidName(); String notFound(); + String pinSelectedElements(); + + String showSelectedElements(); + String unexpectedError(); + + String unpinSelectedElements(); } diff --git a/packages/sirius-web/backend/sirius-web-infrastructure/src/main/java/org/eclipse/sirius/web/infrastructure/i18n/MessageService.java b/packages/sirius-web/backend/sirius-web-infrastructure/src/main/java/org/eclipse/sirius/web/infrastructure/i18n/MessageService.java index 46f9667ef1..6ad34eeb18 100644 --- a/packages/sirius-web/backend/sirius-web-infrastructure/src/main/java/org/eclipse/sirius/web/infrastructure/i18n/MessageService.java +++ b/packages/sirius-web/backend/sirius-web-infrastructure/src/main/java/org/eclipse/sirius/web/infrastructure/i18n/MessageService.java @@ -33,6 +33,31 @@ public MessageService(@Qualifier("messageSourceAccessor") MessageSourceAccessor this.messageSourceAccessor = Objects.requireNonNull(messageSourceAccessor); } + @Override + public String revealSelectedFadedElements() { + return this.messageSourceAccessor.getMessage("REVEAL_SELECTED_FADED_ELEMENTS"); + } + + @Override + public String collapseSelectedElements() { + return this.messageSourceAccessor.getMessage("COLLAPSE_SELECTED_ELEMENTS"); + } + + @Override + public String expandSelectedElements() { + return this.messageSourceAccessor.getMessage("EXPAND_SELECTED_ELEMENTS"); + } + + @Override + public String fadeSelectedElements() { + return this.messageSourceAccessor.getMessage("FADE_SELECTED_ELEMENTS"); + } + + @Override + public String hideSelectedElements() { + return this.messageSourceAccessor.getMessage("HIDE_SELECTED_ELEMENTS"); + } + @Override public String invalidName() { return this.messageSourceAccessor.getMessage("INVALID_NAME"); @@ -43,8 +68,23 @@ public String notFound() { return this.messageSourceAccessor.getMessage("NOT_FOUND"); } + @Override + public String pinSelectedElements() { + return this.messageSourceAccessor.getMessage("PIN_SELECTED_ELEMENTS"); + } + + @Override + public String showSelectedElements() { + return this.messageSourceAccessor.getMessage("SHOW_SELECTED_ELEMENTS"); + } + @Override public String unexpectedError() { return this.messageSourceAccessor.getMessage("UNEXPECTED_ERROR"); } + + @Override + public String unpinSelectedElements() { + return this.messageSourceAccessor.getMessage("UNPIN_SELECTED_ELEMENTS"); + } } diff --git a/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/i18n/messages.properties b/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/i18n/messages.properties index e736658da2..3e52c8a1ba 100644 --- a/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/i18n/messages.properties +++ b/packages/sirius-web/backend/sirius-web-infrastructure/src/main/resources/i18n/messages.properties @@ -10,6 +10,14 @@ # Contributors: # Obeo - initial API and implementation ################################################################################################ +REVEAL_SELECTED_FADED_ELEMENTS=Reveal selected faded elements +COLLAPSE_SELECTED_ELEMENTS=Collapse selected elements +EXPAND_SELECTED_ELEMENTS=Expand selected elements +FADE_SELECTED_ELEMENTS=Fade selected elements +HIDE_SELECTED_ELEMENTS=Hide selected elements INVALID_NAME=Invalid name NOT_FOUND=Not found -UNEXPECTED_ERROR=An unexpected error has occurred, please contact the server administrator \ No newline at end of file +PIN_SELECTED_ELEMENTS=Pin selected elements +SHOW_SELECTED_ELEMENTS=Show selected elements +UNEXPECTED_ERROR=An unexpected error has occurred, please contact the server administrator +UNPIN_SELECTED_ELEMENTS=Unpin selected elements \ No newline at end of file diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/CollapseButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/CollapseButtonDescriptionProvider.java new file mode 100644 index 0000000000..951b825ea8 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/CollapseButtonDescriptionProvider.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.UpdateCollapsingStateInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.CollapsingState; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.Failure; +import org.eclipse.sirius.components.representations.Success; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.services.messages.IServicesMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the collapse button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class CollapseButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IServicesMessageService messageService; + + public CollapseButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IServicesMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/collapse") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Collapse") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Collapse") + .imageURLProvider(variableManager -> DiagramImageConstants.COLLAPSE_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + boolean hasFailure = nodeIds.stream() + .map(nodeId -> this.diagramFilterHelper.sendDiagramEvent(variableManager, new UpdateCollapsingStateInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeId, CollapsingState.COLLAPSED))) + .anyMatch(Failure.class::isInstance); + if (hasFailure) { + return new Failure("An error occurred"); + } else { + return new Success(); + } + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.collapseSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterDescriptionProvider.java new file mode 100644 index 0000000000..ef2f8bca48 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterDescriptionProvider.java @@ -0,0 +1,340 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Stream; + +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventProcessor; +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventProcessorRegistry; +import org.eclipse.sirius.components.collaborative.api.IRepresentationEventProcessor; +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramEventProcessor; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.CollapsingState; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.diagrams.ViewModifier; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.AbstractControlDescription; +import org.eclipse.sirius.components.forms.description.CheckboxDescription; +import org.eclipse.sirius.components.forms.description.FormDescription; +import org.eclipse.sirius.components.forms.description.GroupDescription; +import org.eclipse.sirius.components.forms.description.LabelDescription; +import org.eclipse.sirius.components.forms.description.PageDescription; +import org.eclipse.sirius.components.forms.description.SplitButtonDescription; +import org.eclipse.sirius.components.forms.description.TreeDescription; +import org.eclipse.sirius.components.representations.GetOrCreateRandomIdProvider; +import org.eclipse.sirius.components.representations.Success; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterDescriptionProvider; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterHelper; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +/** + * Provides a tree description listing diagram elements and allowing to perform actions on them. + * + * @author gdaniel + */ +@Service +public class DiagramFilterDescriptionProvider implements IDiagramFilterDescriptionProvider { + + public static final String FORM_DESCRIPTION_ID = "diagram_filter_form_description"; + + public static final String SELECTED_TREE_NODES = "selectedTreeNodes"; + + public static final String EDITING_CONTEXT_EVENT_PROCESSOR = "editingContextEventProcessor"; + + public static final String DIAGRAM_EVENT_PROCESSOR = "diagramEventProcessor"; + + public static final String DIAGRAM = "diagram"; + + private static final String GROUP_DESCRIPTION_ID = "defaultDiagramFilterGroup"; + + private static final String PAGE_DESCRIPTION_ID = "defaultDiagramFilterPage"; + + private static final String FORM_TITLE = "Diagram Filters"; + + private final IObjectService objectService; + + private final IEditingContextEventProcessorRegistry editingContextEventProcessorRegistry; + + private final List diagramFilterActionContributionProviders; + + private final IDiagramFilterHelper diagramFilterHelper; + + public DiagramFilterDescriptionProvider(IObjectService objectService, @Lazy IEditingContextEventProcessorRegistry editingContextEventProcessorRegistry, List diagramFilterActionContributionProviders, IDiagramFilterHelper diagramFilterHelper) { + this.objectService = Objects.requireNonNull(objectService); + this.editingContextEventProcessorRegistry = Objects.requireNonNull(editingContextEventProcessorRegistry); + this.diagramFilterActionContributionProviders = Objects.requireNonNull(diagramFilterActionContributionProviders); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + } + + @Override + public FormDescription getFormDescription() { + List groupDescriptions = List.of(this.getGroupDescription()); + + Function targetObjectIdProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class) + .map(this.objectService::getId) + .orElse(null); + + return FormDescription.newFormDescription(FORM_DESCRIPTION_ID) + .label(FORM_TITLE) + .idProvider(new GetOrCreateRandomIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> FORM_TITLE) + .targetObjectIdProvider(targetObjectIdProvider) + .canCreatePredicate(variableManager -> false) + .variableManagerInitializer(vm -> { + if (this.editingContextEventProcessorRegistry != null) { + String editingContextId = vm.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).map(IEditingContext::getId).orElse(""); + Optional optDiagram = vm.get(VariableManager.SELF, Object.class) + .filter(Diagram.class::isInstance) + .map(Diagram.class::cast); + String diagramId = optDiagram + .map(Diagram::getId).orElse(null); + + IEditingContextEventProcessor editingContextEventProcessor = this.editingContextEventProcessorRegistry.getEditingContextEventProcessors().stream() + .filter(processor -> processor.getEditingContextId().equals(editingContextId)) + .findFirst() + .orElse(null); + IRepresentationEventProcessor diagramEventProcessor = Optional.ofNullable(editingContextEventProcessor) + .flatMap(processor -> processor.getRepresentationEventProcessors().stream() + .filter(IDiagramEventProcessor.class::isInstance) + .map(IDiagramEventProcessor.class::cast) + .filter(p -> p.getRepresentation().getId().equals(diagramId)) + .findFirst() + ) + .orElse(null); + vm.put(SELECTED_TREE_NODES, this.getCheckMap(optDiagram.get())); + vm.put(EDITING_CONTEXT_EVENT_PROCESSOR, editingContextEventProcessor); + vm.put(DIAGRAM_EVENT_PROCESSOR, diagramEventProcessor); + vm.put(DIAGRAM, diagramEventProcessor.getRepresentation()); + } + return vm; + }) + .pageDescriptions(List.of(this.getPageDescription(groupDescriptions))) + .build(); + } + + private PageDescription getPageDescription(List groupDescriptions) { + Function idProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class) + .map(this.objectService::getId) + .orElseGet(() -> UUID.randomUUID().toString()); + + Function labelProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class) + .map(this.objectService::getLabel) + .orElse(""); + + Function> semanticElementsProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class).stream().toList(); + + return PageDescription.newPageDescription(PAGE_DESCRIPTION_ID) + .idProvider(idProvider) + .labelProvider(labelProvider) + .semanticElementsProvider(semanticElementsProvider) + .groupDescriptions(groupDescriptions) + .canCreatePredicate(variableManager -> true) + .build(); + } + + private GroupDescription getGroupDescription() { + List controlDescriptions = new ArrayList<>(); + controlDescriptions.add(this.createTreeLabelDescription()); + controlDescriptions.add(this.createTreeCheckboxDescription()); + controlDescriptions.add(this.createTreeDescription()); + controlDescriptions.add(this.createSplitButtonDescription()); + + return GroupDescription.newGroupDescription(GROUP_DESCRIPTION_ID) + .idProvider(variableManager -> FORM_TITLE) + .labelProvider(variableManager -> "Filter elements") + .semanticElementsProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).stream().toList()) + .controlDescriptions(controlDescriptions) + .build(); + } + + private LabelDescription createTreeLabelDescription() { + return LabelDescription.newLabelDescription("diagram-filter/tree-label") + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .idProvider(new WidgetIdProvider()) + .labelProvider(variableManager -> "") + .valueProvider(variableManager -> "Elements on diagram") + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> null) + .build(); + } + + private CheckboxDescription createTreeCheckboxDescription() { + return CheckboxDescription.newCheckboxDescription("diagram-filter/tree-checkbox") + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .idProvider(new WidgetIdProvider()) + .labelProvider(variableManager -> { + int selectedElementCount = this.diagramFilterHelper.getSelectedElementIds(variableManager).size(); + String element = "element"; + if (selectedElementCount > 1) { + element += "s"; + } + return selectedElementCount + " " + element + " selected"; + }) + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .valueProvider(variableManager -> this.diagramFilterHelper.getSelectedElementIds(variableManager).size() > 0) + .newValueHandler((variableManager, newValue) -> { + Map checkMap = variableManager.get(SELECTED_TREE_NODES, Map.class).get(); + checkMap.entrySet().stream() + .forEach(entry -> entry.setValue(newValue)); + return new Success(); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> null) + .build(); + } + + private TreeDescription createTreeDescription() { + return TreeDescription.newTreeDescription("diagram-filter/tree") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .labelProvider(variableManager -> "") + .nodeIdProvider(this::getNodeId) + .nodeLabelProvider(this::getNodeLabel) + .nodeIconURLProvider(vm -> List.of()) + .nodeEndIconsURLProvider(this::computeNodeEndIcons) + .nodeKindProvider(vm -> "") + .nodeSelectableProvider(vm -> true) + .childrenProvider(this::getNodeChildren) + .expandedNodeIdsProvider(vm -> List.of()) + .isCheckableProvider(variableManager -> true) + .checkedValueProvider(variableManager -> this.diagramFilterHelper.getSelectedElementIds(variableManager).contains(this.getNodeId(variableManager))) + .newCheckedValueHandler((variableManager, newValue) -> { + Map selectedTreeNodes = variableManager.get(SELECTED_TREE_NODES, Map.class).get(); + String selfId = this.getNodeId(variableManager); + selectedTreeNodes.put(selfId, newValue); + return new Success(); + }) + .build(); + } + + private SplitButtonDescription createSplitButtonDescription() { + return SplitButtonDescription.newSplitButtonDescription("diagram-filter/split-button") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> { + int selectedElementCount = this.diagramFilterHelper.getSelectedElementIds(variableManager).size(); + String element = "element"; + if (selectedElementCount > 1) { + element += "s"; + } + + return "Apply to " + selectedElementCount + " selected " + element + ": "; + }) + .diagnosticsProvider(variableManager -> List.of()) + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .actions(this.diagramFilterActionContributionProviders.stream() + .map(IDiagramFilterActionContributionProvider::getButtonDescription) + .toList() + ) + .build(); + + } + + private String getNodeId(VariableManager vm) { + var self = vm.get(VariableManager.SELF, Object.class).orElse(null); + if (self instanceof Node node) { + return node.getId(); + } else { + return ""; + } + } + + private String getNodeLabel(VariableManager vm) { + var self = vm.get(VariableManager.SELF, Object.class).orElse(null); + String result = ""; + if (self instanceof Node node) { + if (node.getInsideLabel() != null) { + result = node.getInsideLabel().getText(); + } else if (!node.getOutsideLabels().isEmpty()) { + result = node.getOutsideLabels().get(0).text(); + } else if (node.getTargetObjectLabel() != null) { + result = node.getTargetObjectLabel(); + } + } + return result; + } + + private List getNodeChildren(VariableManager vm) { + var self = vm.get(VariableManager.SELF, Object.class).orElse(null); + final List result; + if (self instanceof Diagram diagram) { + result = diagram.getNodes(); + } else if (self instanceof Node node) { + result = node.getChildNodes(); + } else { + result = List.of(); + } + return result; + } + + private List> computeNodeEndIcons(VariableManager vm) { + var node = vm.get(VariableManager.SELF, Object.class) + .filter(Node.class::isInstance) + .map(Node.class::cast) + .orElse(null); + List> result = new ArrayList<>(); + if (node.getModifiers().contains(ViewModifier.Hidden)) { + result.add(List.of("/icons/full/obj16/HideTool.svg")); + } + if (node.getModifiers().contains(ViewModifier.Faded)) { + result.add(List.of("/icons/full/obj16/FadeTool.svg")); + } + if (node.getCollapsingState().equals(CollapsingState.COLLAPSED)) { + result.add(List.of(DiagramImageConstants.COLLAPSE_SVG)); + } + if (node.isPinned()) { + result.add(List.of(DiagramImageConstants.PIN_SVG)); + } + return result; + } + + private Map getCheckMap(Diagram diagram) { + Map checkMap = new HashMap<>(); + for (Node node : diagram.getNodes()) { + this.fillCheckMap(node, checkMap); + } + return checkMap; + } + + private void fillCheckMap(Node node, Map checkMap) { + checkMap.put(node.getId(), false); + Stream.concat(node.getChildNodes().stream(), node.getBorderNodes().stream()) + .forEach(n -> this.fillCheckMap(n, checkMap)); + } +} \ No newline at end of file diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterEventProcessorFactory.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterEventProcessorFactory.java new file mode 100644 index 0000000000..da40cd196e --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterEventProcessorFactory.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import org.eclipse.sirius.components.collaborative.api.IRepresentationConfiguration; +import org.eclipse.sirius.components.collaborative.api.IRepresentationEventProcessor; +import org.eclipse.sirius.components.collaborative.api.IRepresentationEventProcessorFactory; +import org.eclipse.sirius.components.collaborative.api.IRepresentationRefreshPolicyRegistry; +import org.eclipse.sirius.components.collaborative.api.ISubscriptionManagerFactory; +import org.eclipse.sirius.components.collaborative.api.RepresentationEventProcessorFactoryConfiguration; +import org.eclipse.sirius.components.collaborative.forms.FormEventProcessor; +import org.eclipse.sirius.components.collaborative.forms.api.FormCreationParameters; +import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; +import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor; +import org.eclipse.sirius.components.collaborative.forms.api.IFormPostProcessor; +import org.eclipse.sirius.components.collaborative.forms.api.IWidgetSubscriptionManagerFactory; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorConfiguration; +import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorFactoryConfiguration; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.forms.description.FormDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; +import org.eclipse.sirius.web.services.diagramfilter.api.DiagramFilterConfiguration; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterDescriptionProvider; +import org.springframework.stereotype.Service; + +/** + * Used to create the diagram filter event processors. + * + * @author gdaniel + */ +@Service +public class DiagramFilterEventProcessorFactory implements IRepresentationEventProcessorFactory { + + private final IDiagramFilterDescriptionProvider diagramFilterDescriptionProvider; + + private final IObjectService objectService; + + private final List widgetDescriptors; + + private final List formEventHandlers; + + private final ISubscriptionManagerFactory subscriptionManagerFactory; + + private final IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory; + + private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; + + private final IFormPostProcessor formPostProcessor; + + public DiagramFilterEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, IDiagramFilterDescriptionProvider diagramFilterDescriptionProvider, + List widgetDescriptors, FormEventProcessorFactoryConfiguration formConfiguration) { + this.diagramFilterDescriptionProvider = Objects.requireNonNull(diagramFilterDescriptionProvider); + this.objectService = Objects.requireNonNull(formConfiguration.getObjectService()); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); + this.formEventHandlers = Objects.requireNonNull(formConfiguration.getFormEventHandlers()); + this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory()); + this.widgetSubscriptionManagerFactory = Objects.requireNonNull(formConfiguration.getWidgetSubscriptionManagerFactory()); + this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry()); + this.formPostProcessor = Objects.requireNonNull(formConfiguration.getFormPostProcessor()); + } + + @Override + public boolean canHandle(Class representationEventProcessorClass, IRepresentationConfiguration configuration) { + return IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof DiagramFilterConfiguration; + } + + @Override + public Optional createRepresentationEventProcessor(Class representationEventProcessorClass, IRepresentationConfiguration configuration, + IEditingContext editingContext) { + if (IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof DiagramFilterConfiguration diagramFilterConfiguration && this.diagramFilterDescriptionProvider != null) { + + var objects = diagramFilterConfiguration.getObjectIds().stream() + .map(objectId -> this.objectService.getObject(editingContext, objectId)) + .flatMap(Optional::stream) + .toList(); + if (!objects.isEmpty()) { + FormDescription formDescription = this.diagramFilterDescriptionProvider.getFormDescription(); + FormCreationParameters formCreationParameters = FormCreationParameters.newFormCreationParameters(diagramFilterConfiguration.getId()) + .editingContext(editingContext) + .formDescription(formDescription) + .object(objects.get(0)) + .selection(objects) + .build(); + + IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(new FormEventProcessorConfiguration(editingContext, this.objectService, formCreationParameters, + this.widgetDescriptors, this.formEventHandlers), + this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry, this.formPostProcessor); + + return Optional.of(formEventProcessor) + .filter(representationEventProcessorClass::isInstance) + .map(representationEventProcessorClass::cast); + } + } + return Optional.empty(); + } +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterHelper.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterHelper.java new file mode 100644 index 0000000000..c98475d3ae --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterHelper.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import java.text.MessageFormat; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.sirius.components.collaborative.api.ChangeDescription; +import org.eclipse.sirius.components.collaborative.api.IEditingContextEventProcessor; +import org.eclipse.sirius.components.collaborative.api.IRepresentationEventProcessor; +import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramInput; +import org.eclipse.sirius.components.core.api.ErrorPayload; +import org.eclipse.sirius.components.core.api.IPayload; +import org.eclipse.sirius.components.core.api.SuccessPayload; +import org.eclipse.sirius.components.representations.Failure; +import org.eclipse.sirius.components.representations.IStatus; +import org.eclipse.sirius.components.representations.Success; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import reactor.core.publisher.Sinks; +import reactor.core.publisher.Sinks.EmitResult; +import reactor.core.publisher.Sinks.Many; +import reactor.core.publisher.Sinks.One; + +/** + * Utility methods for the "Diagram Filter" view. + * + * @author gdaniel + */ +@Service +public class DiagramFilterHelper implements IDiagramFilterHelper { + + private final Logger logger = LoggerFactory.getLogger(DiagramFilterHelper.class); + + @Override + public Set getSelectedElementIds(VariableManager variableManager) { + return variableManager.get(DiagramFilterDescriptionProvider.SELECTED_TREE_NODES, Map.class) + .map(checkMap -> { + Stream entryStream = checkMap.entrySet().stream(); + return entryStream.filter(Map.Entry.class::isInstance) + .map(Map.Entry.class::cast) + .filter(entry -> entry.getValue().equals(Boolean.TRUE)) + .map(Map.Entry::getKey) + .map(Object::toString) + .collect(Collectors.toSet()); + }) + .orElse(Set.of()); + } + + @Override + public IStatus sendDiagramEvent(VariableManager variableManager, IDiagramInput diagramInput) { + var optionalRepresentationEventProcessor = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM_EVENT_PROCESSOR, IRepresentationEventProcessor.class); + var optionalEditingContextEventProcessor = variableManager.get(DiagramFilterDescriptionProvider.EDITING_CONTEXT_EVENT_PROCESSOR, IEditingContextEventProcessor.class); + + if (optionalRepresentationEventProcessor.isPresent() && optionalEditingContextEventProcessor.isPresent()) { + var editingContextEventProcessor = optionalEditingContextEventProcessor.get(); + var representationEventProcessor = optionalRepresentationEventProcessor.get(); + + One payloadSink = Sinks.one(); + Many changeDescriptions = Sinks.many().unicast().onBackpressureBuffer(); + Consumer errorConsumer = throwable -> this.logger.warn(throwable.getMessage(), throwable); + changeDescriptions.asFlux().subscribe(changeDescription -> editingContextEventProcessor.getRepresentationEventProcessors() + .forEach(eventProcessor -> eventProcessor.refresh(changeDescription)), errorConsumer); + + representationEventProcessor.handle(payloadSink, changeDescriptions, diagramInput); + IPayload handlerResult = payloadSink.asMono().block(); + + IStatus result = null; + + EmitResult changeDescriptionEmitResult = changeDescriptions.tryEmitComplete(); + if (changeDescriptionEmitResult.isFailure()) { + String errorMessage = MessageFormat.format("An error has occurred while marking the publisher as complete: {0}", changeDescriptionEmitResult); + this.logger.warn(errorMessage); + result = new Failure(errorMessage); + } else { + if (handlerResult instanceof SuccessPayload) { + result = new Success(); + } else if (handlerResult instanceof ErrorPayload errorPayload) { + result = new Failure(errorPayload.message()); + } else { + result = new Failure("Unknown error"); + } + } + return result; + } + + String errorMessage = "Cannot find the diagramEventProcessor or the editingContextEventProcessor"; + this.logger.warn(errorMessage); + return new Failure(errorMessage); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterRefreshPolicyProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterRefreshPolicyProvider.java new file mode 100644 index 0000000000..f88d10a3c8 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/DiagramFilterRefreshPolicyProvider.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import org.eclipse.sirius.components.collaborative.api.ChangeKind; +import org.eclipse.sirius.components.collaborative.api.IRepresentationRefreshPolicy; +import org.eclipse.sirius.components.collaborative.api.IRepresentationRefreshPolicyProvider; +import org.eclipse.sirius.components.collaborative.diagrams.DiagramChangeKind; +import org.eclipse.sirius.components.representations.IRepresentationDescription; +import org.springframework.stereotype.Service; + +/** + * The representation refresh policy provider for the "Diagram Filter" form representation. + * + * @author gdaniel + */ +@Service +public class DiagramFilterRefreshPolicyProvider implements IRepresentationRefreshPolicyProvider { + + + @Override + public boolean canHandle(IRepresentationDescription representationDescription) { + return DiagramFilterDescriptionProvider.FORM_DESCRIPTION_ID.equals(representationDescription.getId()); + } + + @Override + public IRepresentationRefreshPolicy getRepresentationRefreshPolicy(IRepresentationDescription representationDescription) { + return changeDescription -> { + boolean shouldRefresh = false; + shouldRefresh = shouldRefresh || ChangeKind.SEMANTIC_CHANGE.equals(changeDescription.getKind()); + shouldRefresh = shouldRefresh || DiagramChangeKind.DIAGRAM_LAYOUT_CHANGE.equals(changeDescription.getKind()); + shouldRefresh = shouldRefresh || DiagramChangeKind.DIAGRAM_ELEMENT_VISIBILITY_CHANGE.equals(changeDescription.getKind()); + shouldRefresh = shouldRefresh || DiagramChangeKind.DIAGRAM_ELEMENT_COLLAPSING_STATE_CHANGE.equals(changeDescription.getKind()); + return shouldRefresh; + }; + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/ExpandButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/ExpandButtonDescriptionProvider.java new file mode 100644 index 0000000000..d84713a7cb --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/ExpandButtonDescriptionProvider.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.UpdateCollapsingStateInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.CollapsingState; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.Failure; +import org.eclipse.sirius.components.representations.Success; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.services.messages.IServicesMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the expand button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class ExpandButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IServicesMessageService messageService; + + public ExpandButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IServicesMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/expand") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Expand") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Expand") + .imageURLProvider(variableManager -> DiagramImageConstants.EXPAND_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + boolean hasFailure = nodeIds.stream() + .map(nodeId -> this.diagramFilterHelper.sendDiagramEvent(variableManager, new UpdateCollapsingStateInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeId, CollapsingState.EXPANDED))) + .anyMatch(Failure.class::isInstance); + if (hasFailure) { + return new Failure("An error occurred"); + } else { + return new Success(); + } + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.expandSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/FadeButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/FadeButtonDescriptionProvider.java new file mode 100644 index 0000000000..58feac98e7 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/FadeButtonDescriptionProvider.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.FadeDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.services.messages.IServicesMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the fade button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class FadeButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IServicesMessageService messageService; + + public FadeButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IServicesMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/fade") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Fade") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Fade") + .imageURLProvider(variableManager -> DiagramImageConstants.FADE_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new FadeDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, true)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.fadeSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/HideButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/HideButtonDescriptionProvider.java new file mode 100644 index 0000000000..a53ce4dadf --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/HideButtonDescriptionProvider.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.dto.HideDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.services.messages.IServicesMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the hide button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class HideButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IServicesMessageService messageService; + + public HideButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IServicesMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/hide") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Hide") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Hide") + .imageURLProvider(variableManager -> "/icons/full/obj16/HideTool.svg") + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new HideDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, true)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.hideSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/PinButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/PinButtonDescriptionProvider.java new file mode 100644 index 0000000000..3c6cd41dfd --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/PinButtonDescriptionProvider.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.PinDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.services.messages.IServicesMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the pin button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class PinButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IServicesMessageService messageService; + + public PinButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IServicesMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/pin") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Pin") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Pin") + .imageURLProvider(variableManager -> DiagramImageConstants.PIN_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new PinDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, true)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.pinSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/RevealFadedElementsButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/RevealFadedElementsButtonDescriptionProvider.java new file mode 100644 index 0000000000..eedd1459d4 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/RevealFadedElementsButtonDescriptionProvider.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.FadeDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.services.messages.IServicesMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the reveal faded elements button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class RevealFadedElementsButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IServicesMessageService messageService; + + public RevealFadedElementsButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IServicesMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/reveal-faded-elements") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Reveal faded elements") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Reveal faded elements") + .imageURLProvider(variableManager -> DiagramImageConstants.REVEAL_FADED_ELEMENTS_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new FadeDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, false)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.revealSelectedFadedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/ShowButtonDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/ShowButtonDescriptionProvider.java new file mode 100644 index 0000000000..62be838730 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/ShowButtonDescriptionProvider.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.dto.HideDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.services.messages.IServicesMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the show button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class ShowButtonDescriptionProvider implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IServicesMessageService messageService; + + public ShowButtonDescriptionProvider(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IServicesMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/show") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Show") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Show") + .imageURLProvider(variableManager -> "/icons/full/obj16/ShowTool.svg") + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new HideDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, false)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.showSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/SubscriptionDiagramFilterEventDataFetcher.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/SubscriptionDiagramFilterEventDataFetcher.java new file mode 100644 index 0000000000..adae810f98 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/SubscriptionDiagramFilterEventDataFetcher.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import org.eclipse.sirius.components.annotations.spring.graphql.SubscriptionDataFetcher; +import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor; +import org.eclipse.sirius.components.collaborative.forms.dto.PropertiesEventInput; +import org.eclipse.sirius.components.core.api.IPayload; +import org.eclipse.sirius.components.graphql.api.IDataFetcherWithFieldCoordinates; +import org.eclipse.sirius.components.graphql.api.IEventProcessorSubscriptionProvider; +import org.eclipse.sirius.components.graphql.api.IExceptionWrapper; +import org.eclipse.sirius.components.graphql.api.LocalContextConstants; +import org.eclipse.sirius.web.services.diagramfilter.api.DiagramFilterConfiguration; +import org.reactivestreams.Publisher; + +import graphql.execution.DataFetcherResult; +import graphql.schema.DataFetchingEnvironment; + +/** + * The data fetcher used to send the refreshed diagram filters to a subscription. + * + * @author gdaniel + */ +@SubscriptionDataFetcher(type = "Subscription", field = "diagramFilterEvent") +public class SubscriptionDiagramFilterEventDataFetcher implements IDataFetcherWithFieldCoordinates>> { + + private static final String INPUT_ARGUMENT = "input"; + + private final ObjectMapper objectMapper; + + private final IExceptionWrapper exceptionWrapper; + + private final IEventProcessorSubscriptionProvider eventProcessorSubscriptionProvider; + + public SubscriptionDiagramFilterEventDataFetcher(ObjectMapper objectMapper, IExceptionWrapper exceptionWrapper, IEventProcessorSubscriptionProvider eventProcessorSubscriptionProvider) { + this.objectMapper = Objects.requireNonNull(objectMapper); + this.exceptionWrapper = Objects.requireNonNull(exceptionWrapper); + this.eventProcessorSubscriptionProvider = Objects.requireNonNull(eventProcessorSubscriptionProvider); + } + + @Override + public Publisher> get(DataFetchingEnvironment environment) throws Exception { + Object argument = environment.getArgument(INPUT_ARGUMENT); + var input = this.objectMapper.convertValue(argument, PropertiesEventInput.class); + var diagramFilterConfiguration = new DiagramFilterConfiguration(input.id().toString(), input.objectIds()); + + Map localContext = new HashMap<>(); + localContext.put(LocalContextConstants.EDITING_CONTEXT_ID, input.editingContextId()); + localContext.put(LocalContextConstants.REPRESENTATION_ID, diagramFilterConfiguration.getId()); + + return this.exceptionWrapper.wrapFlux(() -> this.eventProcessorSubscriptionProvider.getSubscription(input.editingContextId(), IFormEventProcessor.class, diagramFilterConfiguration, input), input) + .map(payload -> DataFetcherResult.newResult() + .data(payload) + .localContext(localContext) + .build()); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/UnpinButtonDescription.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/UnpinButtonDescription.java new file mode 100644 index 0000000000..4375f5f8b8 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/UnpinButtonDescription.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.PinDiagramElementInput; +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.forms.ButtonStyle; +import org.eclipse.sirius.components.forms.WidgetIdProvider; +import org.eclipse.sirius.components.forms.description.ButtonDescription; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterActionContributionProvider; +import org.eclipse.sirius.web.services.diagramfilter.api.IDiagramFilterHelper; +import org.eclipse.sirius.web.services.messages.IServicesMessageService; +import org.springframework.stereotype.Service; + +/** + * Provides the description of the unpin button for the diagram filter's split button. + * + * @author gdaniel + */ +@Service +public class UnpinButtonDescription implements IDiagramFilterActionContributionProvider { + + private final IObjectService objectService; + + private final IDiagramFilterHelper diagramFilterHelper; + + private final IServicesMessageService messageService; + + public UnpinButtonDescription(IObjectService objectService, IDiagramFilterHelper diagramFilterHelper, IServicesMessageService messageService) { + this.objectService = Objects.requireNonNull(objectService); + this.diagramFilterHelper = Objects.requireNonNull(diagramFilterHelper); + this.messageService = Objects.requireNonNull(messageService); + } + + @Override + public ButtonDescription getButtonDescription() { + return ButtonDescription.newButtonDescription("diagram-filter/split-button/unpin") + .idProvider(new WidgetIdProvider()) + .targetObjectIdProvider(variableManager -> variableManager.get(VariableManager.SELF, Object.class).map(this.objectService::getId).orElse(null)) + .labelProvider(variableManager -> "Unpin") + .iconURLProvider(variableManager -> List.of()) + .isReadOnlyProvider(variableManager -> false) + .buttonLabelProvider(variableManager -> "Unpin") + .imageURLProvider(variableManager -> DiagramImageConstants.UNPIN_SVG) + .pushButtonHandler(variableManager -> { + var diagram = variableManager.get(DiagramFilterDescriptionProvider.DIAGRAM, Diagram.class).get(); + var nodeIds = this.diagramFilterHelper.getSelectedElementIds(variableManager); + var editingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).get(); + return this.diagramFilterHelper.sendDiagramEvent(variableManager, new PinDiagramElementInput(UUID.randomUUID(), editingContext.getId(), diagram.getId(), nodeIds, false)); + }) + .diagnosticsProvider(variableManager -> List.of()) + .kindProvider(variableManager -> "") + .messageProvider(variableManager -> "") + .styleProvider(variableManager -> ButtonStyle.newButtonStyle() + .backgroundColor("#ffffff") + .foregroundColor("#261E58") + .build() + ) + .helpTextProvider(variableManager -> this.messageService.unpinSelectedElements()) + .build(); + } + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/DiagramFilterConfiguration.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/DiagramFilterConfiguration.java new file mode 100644 index 0000000000..0e01e3b590 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/DiagramFilterConfiguration.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter.api; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Objects; + +import org.eclipse.sirius.components.collaborative.api.IRepresentationConfiguration; + +/** + * The configuration used to create a diagram filter event processor. + * + * @author gdaniel + */ +public class DiagramFilterConfiguration implements IRepresentationConfiguration { + + private static final String DIAGRAM_FILTER_PREFIX = "diagramFilter://"; + + private final String formId; + + private final List objectIds; + + public DiagramFilterConfiguration(String id, List objectIds) { + this.objectIds = Objects.requireNonNull(objectIds); + var encodedIds = objectIds.stream().map(objectId -> URLEncoder.encode(objectId, StandardCharsets.UTF_8)).toList(); + this.formId = DIAGRAM_FILTER_PREFIX + "?id=" + id + "&objectIds=[" + String.join(",", encodedIds) + "]"; + } + + @Override + public String getId() { + return this.formId; + } + + public List getObjectIds() { + return this.objectIds; + } +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterActionContributionProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterActionContributionProvider.java new file mode 100644 index 0000000000..08647288f8 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterActionContributionProvider.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter.api; + +import org.eclipse.sirius.components.forms.description.ButtonDescription; + +/** + * Provides the description of a button for the diagram filter's split button. + * + * @author gdaniel + */ +public interface IDiagramFilterActionContributionProvider { + + ButtonDescription getButtonDescription(); + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterDescriptionProvider.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterDescriptionProvider.java new file mode 100644 index 0000000000..5d8c882e9b --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterDescriptionProvider.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter.api; + +import org.eclipse.sirius.components.forms.description.FormDescription; + +/** + * Interface used to contribute the form to display for the "Diagram Filter" view. + * + * @author gdaniel + */ +public interface IDiagramFilterDescriptionProvider { + + FormDescription getFormDescription(); + +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterHelper.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterHelper.java new file mode 100644 index 0000000000..973fb874d1 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/diagramfilter/api/IDiagramFilterHelper.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.services.diagramfilter.api; + +import java.util.Set; + +import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramInput; +import org.eclipse.sirius.components.representations.IStatus; +import org.eclipse.sirius.components.representations.VariableManager; + +/** + * Provides utility methods for the "Diagram Filter" view. + * + * @author gdaniel + */ +public interface IDiagramFilterHelper { + + Set getSelectedElementIds(VariableManager variableManager); + + IStatus sendDiagramEvent(VariableManager variableManager, IDiagramInput diagramInput); +} diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/messages/IServicesMessageService.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/messages/IServicesMessageService.java index 1afae14128..bcb587cc3e 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/messages/IServicesMessageService.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/messages/IServicesMessageService.java @@ -21,16 +21,31 @@ */ public interface IServicesMessageService { + String revealSelectedFadedElements(); + + String collapseSelectedElements(); + + String expandSelectedElements(); + + String fadeSelectedElements(); + + String hideSelectedElements(); + String invalidInput(String expectedInputTypeName, String receivedInputTypeName); String invalidProjectName(); + String pinSelectedElements(); + String projectNotFound(); + String showSelectedElements(); + String unexpectedError(); String invalidDocumentName(String name); String stereotypeNotFound(UUID stereotypeId); + String unpinSelectedElements(); } diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/messages/ServicesMessageService.java b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/messages/ServicesMessageService.java index eb16fb65a7..de05549e1e 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/messages/ServicesMessageService.java +++ b/packages/sirius-web/backend/sirius-web-services/src/main/java/org/eclipse/sirius/web/services/messages/ServicesMessageService.java @@ -33,6 +33,31 @@ public ServicesMessageService(@Qualifier("servicesMessageSourceAccessor") Messag this.messageSourceAccessor = Objects.requireNonNull(messageSourceAccessor); } + @Override + public String revealSelectedFadedElements() { + return this.messageSourceAccessor.getMessage("REVEAL_SELECTED_FADED_ELEMENTS"); + } + + @Override + public String collapseSelectedElements() { + return this.messageSourceAccessor.getMessage("COLLAPSE_SELECTED_ELEMENTS"); + } + + @Override + public String expandSelectedElements() { + return this.messageSourceAccessor.getMessage("EXPAND_SELECTED_ELEMENTS"); + } + + @Override + public String fadeSelectedElements() { + return this.messageSourceAccessor.getMessage("FADE_SELECTED_ELEMENTS"); + } + + @Override + public String hideSelectedElements() { + return this.messageSourceAccessor.getMessage("HIDE_SELECTED_ELEMENTS"); + } + @Override public String invalidInput(String expectedInputTypeName, String receivedInputTypeName) { return this.messageSourceAccessor.getMessage("INVALID_INPUT", new Object[] { expectedInputTypeName, receivedInputTypeName }); @@ -43,11 +68,21 @@ public String invalidProjectName() { return this.messageSourceAccessor.getMessage("INVALID_PROJECT_NAME"); } + @Override + public String pinSelectedElements() { + return this.messageSourceAccessor.getMessage("PIN_SELECTED_ELEMENTS"); + } + @Override public String projectNotFound() { return this.messageSourceAccessor.getMessage("PROJECT_NOT_FOUND"); } + @Override + public String showSelectedElements() { + return this.messageSourceAccessor.getMessage("SHOW_SELECTED_ELEMENTS"); + } + @Override public String unexpectedError() { return this.messageSourceAccessor.getMessage("UNEXPECTED_ERROR"); @@ -62,4 +97,9 @@ public String invalidDocumentName(String name) { public String stereotypeNotFound(UUID stereotypeId) { return this.messageSourceAccessor.getMessage("STEREOTYPE_NOT_FOUND", new Object[] { stereotypeId }); } + + @Override + public String unpinSelectedElements() { + return this.messageSourceAccessor.getMessage("UNPIN_SELECTED_ELEMENTS"); + } } diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/resources/messages/sirius-web-services.properties b/packages/sirius-web/backend/sirius-web-services/src/main/resources/messages/sirius-web-services.properties index ad68dab4d1..5a9ac2d64f 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/main/resources/messages/sirius-web-services.properties +++ b/packages/sirius-web/backend/sirius-web-services/src/main/resources/messages/sirius-web-services.properties @@ -10,9 +10,17 @@ # Contributors: # Obeo - initial API and implementation ################################################################################################ +REVEAL_SELECTED_FADED_ELEMENTS=Reveal selected faded elements +COLLAPSE_SELECTED_ELEMENTS=Collapse selected elements +EXPAND_SELECTED_ELEMENTS=Expand selected elements +FADE_SELECTED_ELEMENTS=Fade selected elements +HIDE_SELECTED_ELEMENTS=Hide selected elements INVALID_INPUT=Invalid input type, "{0}" has been received while "{1}" was expected INVALID_PROJECT_NAME=The name must contain between 3 and 20 characters +PIN_SELECTED_ELEMENTS=Pin selected elements PROJECT_NOT_FOUND=The project does not exist +SHOW_SELECTED_ELEMENTS=Show selected elements UNEXPECTED_ERROR=An unexpected error has occurred, please contact the server administrator INVALID_DOCUMENT_NAME=You cannot create a model with the name "{0}". Please use a valid name (no spaces, at least one character) for the new model -STEREOTYPE_NOT_FOUND=The model type with id "{0}" does not exist, therefore you cannot create a model from it \ No newline at end of file +STEREOTYPE_NOT_FOUND=The model type with id "{0}" does not exist, therefore you cannot create a model from it +UNPIN_SELECTED_ELEMENTS=Unpin selected elements \ No newline at end of file diff --git a/packages/sirius-web/backend/sirius-web-services/src/main/resources/schema/diagram-filter.graphqls b/packages/sirius-web/backend/sirius-web-services/src/main/resources/schema/diagram-filter.graphqls new file mode 100644 index 0000000000..730d5e666e --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-services/src/main/resources/schema/diagram-filter.graphqls @@ -0,0 +1,3 @@ +extend type Subscription { + diagramFilterEvent(input : PropertiesEventInput!): PropertiesEventPayload! +} \ No newline at end of file diff --git a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/projects/NoOpServicesMessageService.java b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/projects/NoOpServicesMessageService.java index a72909d6df..3efe4c8811 100644 --- a/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/projects/NoOpServicesMessageService.java +++ b/packages/sirius-web/backend/sirius-web-services/src/test/java/org/eclipse/sirius/web/services/projects/NoOpServicesMessageService.java @@ -23,6 +23,31 @@ */ public class NoOpServicesMessageService implements IServicesMessageService { + @Override + public String revealSelectedFadedElements() { + return ""; + } + + @Override + public String collapseSelectedElements() { + return ""; + } + + @Override + public String expandSelectedElements() { + return ""; + } + + @Override + public String fadeSelectedElements() { + return ""; + } + + @Override + public String hideSelectedElements() { + return ""; + } + @Override public String invalidInput(String expectedInputTypeName, String receivedInputTypeName) { return ""; @@ -33,11 +58,21 @@ public String invalidProjectName() { return ""; } + @Override + public String pinSelectedElements() { + return ""; + } + @Override public String projectNotFound() { return ""; } + @Override + public String showSelectedElements() { + return ""; + } + @Override public String unexpectedError() { return ""; @@ -53,4 +88,9 @@ public String stereotypeNotFound(UUID stereotypeId) { return ""; } + @Override + public String unpinSelectedElements() { + return ""; + } + } diff --git a/packages/sirius-web/backend/sirius-web-tests/src/main/java/org/eclipse/sirius/web/tests/graphql/DiagramFilterEventSubscriptionRunner.java b/packages/sirius-web/backend/sirius-web-tests/src/main/java/org/eclipse/sirius/web/tests/graphql/DiagramFilterEventSubscriptionRunner.java new file mode 100644 index 0000000000..b29eb9aa42 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-tests/src/main/java/org/eclipse/sirius/web/tests/graphql/DiagramFilterEventSubscriptionRunner.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.tests.graphql; + +import java.util.Objects; + +import org.eclipse.sirius.components.collaborative.forms.dto.PropertiesEventInput; +import org.eclipse.sirius.components.graphql.tests.api.IGraphQLRequestor; +import org.eclipse.sirius.components.graphql.tests.api.ISubscriptionRunner; +import org.springframework.stereotype.Service; + +import reactor.core.publisher.Flux; + +/** + * Used to get the related elements event subscription with the GraphQL API. + * + * @author gdaniel + */ +@Service +public class DiagramFilterEventSubscriptionRunner implements ISubscriptionRunner { + + private static final String DIAGRAM_FILTER_EVENT_SUBSCRIPTION = """ + subscription diagramFilterEvent($input: PropertiesEventInput!) { + diagramFilterEvent(input: $input) { + __typename + } + } + """; + + private final IGraphQLRequestor graphQLRequestor; + + public DiagramFilterEventSubscriptionRunner(IGraphQLRequestor graphQLRequestor) { + this.graphQLRequestor = Objects.requireNonNull(graphQLRequestor); + } + + @Override + public Flux run(PropertiesEventInput input) { + return this.graphQLRequestor.subscribe(DIAGRAM_FILTER_EVENT_SUBSCRIPTION, input); + } +} diff --git a/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/diagrams/DiagramFilterControllerTests.java b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/diagrams/DiagramFilterControllerTests.java new file mode 100644 index 0000000000..3b37c5adf0 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/diagrams/DiagramFilterControllerTests.java @@ -0,0 +1,325 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.sirius.web.application.controllers.diagrams; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import com.jayway.jsonpath.JsonPath; + +import java.time.Duration; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import java.util.function.Predicate; + +import org.eclipse.sirius.components.collaborative.diagrams.api.DiagramImageConstants; +import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramRefreshedEventPayload; +import org.eclipse.sirius.components.collaborative.diagrams.dto.InvokeSingleClickOnDiagramElementToolInput; +import org.eclipse.sirius.components.collaborative.diagrams.dto.InvokeSingleClickOnDiagramElementToolSuccessPayload; +import org.eclipse.sirius.components.collaborative.dto.CreateRepresentationInput; +import org.eclipse.sirius.components.collaborative.forms.dto.EditTreeCheckboxInput; +import org.eclipse.sirius.components.collaborative.forms.dto.FormRefreshedEventPayload; +import org.eclipse.sirius.components.collaborative.forms.dto.PropertiesEventInput; +import org.eclipse.sirius.components.collaborative.forms.dto.PushButtonInput; +import org.eclipse.sirius.components.core.api.SuccessPayload; +import org.eclipse.sirius.components.diagrams.CollapsingState; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.diagrams.Node; +import org.eclipse.sirius.components.diagrams.ViewModifier; +import org.eclipse.sirius.components.diagrams.tests.graphql.InvokeSingleClickOnDiagramElementToolMutationRunner; +import org.eclipse.sirius.components.diagrams.tests.navigation.DiagramNavigator; +import org.eclipse.sirius.components.forms.Button; +import org.eclipse.sirius.components.forms.Form; +import org.eclipse.sirius.components.forms.SplitButton; +import org.eclipse.sirius.components.forms.TreeNode; +import org.eclipse.sirius.components.forms.TreeWidget; +import org.eclipse.sirius.components.forms.tests.graphql.EditTreeCheckboxMutationRunner; +import org.eclipse.sirius.components.forms.tests.graphql.PushButtonMutationRunner; +import org.eclipse.sirius.components.forms.tests.navigation.FormNavigator; +import org.eclipse.sirius.web.AbstractIntegrationTests; +import org.eclipse.sirius.web.data.PapayaIdentifiers; +import org.eclipse.sirius.web.services.diagrams.ExpandCollapseDiagramDescriptionProvider; +import org.eclipse.sirius.web.tests.graphql.DiagramFilterEventSubscriptionRunner; +import org.eclipse.sirius.web.tests.services.api.IGivenCreatedDiagramSubscription; +import org.eclipse.sirius.web.tests.services.api.IGivenInitialServerState; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.jdbc.SqlConfig; +import org.springframework.transaction.annotation.Transactional; + +import graphql.execution.DataFetcherResult; +import reactor.core.publisher.Flux; +import reactor.test.StepVerifier; + +/** + * Integration tests of the "Diagram Filter" view. + * + * @author gdaniel + */ +@Transactional +@SuppressWarnings("checkstyle:MultipleStringLiterals") +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { "sirius.web.test.enabled=studio" }) +public class DiagramFilterControllerTests extends AbstractIntegrationTests { + + @Autowired + private IGivenInitialServerState givenInitialServerState; + + @Autowired + private IGivenCreatedDiagramSubscription givenCreatedDiagramSubscription; + + @Autowired + private InvokeSingleClickOnDiagramElementToolMutationRunner invokeSingleClickOnDiagramElementToolMutationRunner; + + @Autowired + private EditTreeCheckboxMutationRunner editTreeCheckboxMutationRunner; + + @Autowired + private PushButtonMutationRunner pushButtonMutationRunner; + + @Autowired + private ExpandCollapseDiagramDescriptionProvider expandCollapseDiagramDescriptionProvider; + + @Autowired + private DiagramFilterEventSubscriptionRunner diagramFilterEventSubscriptionRunner; + + @BeforeEach + public void beforeEach() { + this.givenInitialServerState.initialize(); + } + + private Flux givenSubscriptionToExpandedCollapseDiagram() { + var input = new CreateRepresentationInput( + UUID.randomUUID(), + PapayaIdentifiers.PAPAYA_PROJECT.toString(), + this.expandCollapseDiagramDescriptionProvider.getRepresentationDescriptionId(), + PapayaIdentifiers.PROJECT_OBJECT.toString(), + "ExpandCollapseDiagram" + ); + return this.givenCreatedDiagramSubscription.createAndSubscribe(input); + } + + @Test + @DisplayName("Given a diagram and a diagram filter, when a tool collapsing nodes is invoked on the diagram, then the diagram filter is updated") + @Sql(scripts = {"/scripts/papaya.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenDiagramAndDiagramFilterWhenToolCollapsingNodeIsInvokedOnDiagramThenDiagramFilterIsUpdated() { + var diagramFlux = this.givenSubscriptionToExpandedCollapseDiagram(); + + AtomicReference diagramReference = new AtomicReference<>(); + AtomicReference expandedNodeId = new AtomicReference<>(); + + Consumer initialDiagramContentConsumer = payload -> Optional.of(payload) + .map(DiagramRefreshedEventPayload::diagram) + .ifPresentOrElse(diagram -> { + diagramReference.set(diagram); + diagram.getNodes().stream() + .filter(node -> node.getCollapsingState().equals(CollapsingState.EXPANDED)) + .map(Node::getId) + .findFirst() + .ifPresent(expandedNodeId::set); + }, () -> fail("Missing diagram")); + + StepVerifier.create(diagramFlux) + .consumeNextWith(initialDiagramContentConsumer) + .thenCancel() + .verify(Duration.ofSeconds(10)); + + var propertiesInput = new PropertiesEventInput(UUID.randomUUID(), PapayaIdentifiers.PAPAYA_PROJECT.toString(), List.of(diagramReference.get().getId())); + var diagramFilterFlux = this.diagramFilterEventSubscriptionRunner.run(propertiesInput); + + Predicate formContentMatcher = object -> this.refreshedForm(object) + .filter(form -> { + var diagramNavigator = new DiagramNavigator(diagramReference.get()); + var treeWidget = new FormNavigator(form) + .page("ExpandCollapseDiagram") + .group("Filter elements") + .findWidget("", TreeWidget.class); + assertThat(treeWidget.getNodes()).hasSize(diagramNavigator.findDiagramNodeCount()); + for (TreeNode treeNode : treeWidget.getNodes()) { + var node = diagramNavigator.nodeWithLabel(treeNode.getLabel()).getNode(); + this.assertThatNodeMatchesTreeNodeEndIcons(node, treeNode); + } + return true; + }) + .isPresent(); + + Runnable collapseNodes = () -> { + String collapseToolId = this.expandCollapseDiagramDescriptionProvider.getCollapseNodeToolId(); + var input = new InvokeSingleClickOnDiagramElementToolInput(UUID.randomUUID(), PapayaIdentifiers.PAPAYA_PROJECT.toString(), diagramReference.get().getId(), expandedNodeId.get(), collapseToolId, 0, 0, null); + var invokeSingleClickOnDiagramElementToolResult = this.invokeSingleClickOnDiagramElementToolMutationRunner.run(input); + + String invokeSingleClickOnDiagramElementToolResultTypename = JsonPath.read(invokeSingleClickOnDiagramElementToolResult, "$.data.invokeSingleClickOnDiagramElementTool.__typename"); + assertThat(invokeSingleClickOnDiagramElementToolResultTypename).isEqualTo(InvokeSingleClickOnDiagramElementToolSuccessPayload.class.getSimpleName()); + }; + + Consumer udpatedDiagramContentConsumer = object -> this.refreshedDiagram(object) + .ifPresentOrElse(diagram -> { + diagramReference.set(diagram); + }, () -> fail("Missing diagram")); + + var diagramAndPropertiesFlux = Flux.merge(diagramFlux, diagramFilterFlux); + + StepVerifier.create(diagramAndPropertiesFlux) + .expectNextMatches(DiagramRefreshedEventPayload.class::isInstance) + .expectNextMatches(formContentMatcher) + .then(collapseNodes) + .consumeNextWith(udpatedDiagramContentConsumer) + .expectNextMatches(formContentMatcher) + .thenCancel() + .verify(Duration.ofSeconds(10)); + } + + @Test + @DisplayName("Given a diagram and a diagram filter, when a tool collapsing nodes is invoked on the diagram filter, then the diagram is updated") + @Sql(scripts = {"/scripts/papaya.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) + @Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void givenDiagramAndDiagramFilterWhenToolCollapsingNodeIsInvokedOnDiagramFilterThenDiagramIsUpdated() { + var diagramFlux = this.givenSubscriptionToExpandedCollapseDiagram(); + AtomicReference diagramReference = new AtomicReference<>(); + AtomicReference expandedNodeId = new AtomicReference<>(); + + Consumer initialDiagramContentConsumer = payload -> Optional.of(payload) + .map(DiagramRefreshedEventPayload::diagram) + .ifPresentOrElse(diagram -> { + diagramReference.set(diagram); + diagram.getNodes().stream() + .filter(node -> node.getCollapsingState().equals(CollapsingState.EXPANDED)) + .map(Node::getId) + .findFirst() + .ifPresent(expandedNodeId::set); + }, () -> fail("Missing diagram")); + + StepVerifier.create(diagramFlux) + .consumeNextWith(initialDiagramContentConsumer) + .thenCancel() + .verify(Duration.ofSeconds(10)); + + var propertiesInput = new PropertiesEventInput(UUID.randomUUID(), PapayaIdentifiers.PAPAYA_PROJECT.toString(), List.of(diagramReference.get().getId())); + var diagramFilterFlux = this.diagramFilterEventSubscriptionRunner.run(propertiesInput); + AtomicReference formId = new AtomicReference<>(); + AtomicReference treeId = new AtomicReference<>(); + AtomicReference treeNodeToCheckId = new AtomicReference<>(); + + Predicate initialFormContentMatcher = object -> this.refreshedForm(object) + .filter(form -> { + formId.set(form.getId()); + var diagramNavigator = new DiagramNavigator(diagramReference.get()); + var treeWidget = new FormNavigator(form) + .page("ExpandCollapseDiagram") + .group("Filter elements") + .findWidget("", TreeWidget.class); + treeId.set(treeWidget.getId()); + for (TreeNode treeNode : treeWidget.getNodes()) { + var node = diagramNavigator.nodeWithLabel(treeNode.getLabel()).getNode(); + if (node.getId().equals(expandedNodeId.get())) { + treeNodeToCheckId.set(treeNode.getId()); + } + } + return true; + }) + .isPresent(); + + AtomicReference collapseActionId = new AtomicReference<>(); + + Predicate updatedFormContentMatcher = object -> this.refreshedForm(object) + .filter(form -> { + // We have to set the collapseButtonId after we check the tree node because the id of split button actions change between renders. + new FormNavigator(form) + .page("ExpandCollapseDiagram") + .group("Filter elements") + .findWidget("Apply to 1 selected element: ", SplitButton.class) + .getActions().stream() + .filter(b -> b.getButtonLabel().equals("Collapse")) + .map(Button::getId) + .findFirst() + .ifPresent(collapseActionId::set); + return true; + }) + .isPresent(); + + Runnable checkTreeNode = () -> { + var input = new EditTreeCheckboxInput(UUID.randomUUID(), PapayaIdentifiers.PAPAYA_PROJECT.toString(), formId.get(), treeId.get(), treeNodeToCheckId.get(), true); + var editTreeCheckboxMutationResult = this.editTreeCheckboxMutationRunner.run(input); + String editTreeCheckboxMutationResultTypename = JsonPath.read(editTreeCheckboxMutationResult, "$.data.editTreeCheckbox.__typename"); + assertThat(editTreeCheckboxMutationResultTypename).isEqualTo(SuccessPayload.class.getSimpleName()); + }; + + Runnable collapseNodes = () -> { + var input = new PushButtonInput(UUID.randomUUID(), PapayaIdentifiers.PAPAYA_PROJECT.toString(), formId.get(), collapseActionId.get()); + var pushButtonMutationResult = this.pushButtonMutationRunner.run(input); + String pushButtonMutationResultTypename = JsonPath.read(pushButtonMutationResult, "$.data.pushButton.__typename"); + assertThat(pushButtonMutationResultTypename).isEqualTo(SuccessPayload.class.getSimpleName()); + }; + + Predicate updatedDiagramContentMatcher = object -> this.refreshedDiagram(object) + .filter(diagram -> new DiagramNavigator(diagram) + .nodeWithId(expandedNodeId.get()) + .getNode() + .getCollapsingState().equals(CollapsingState.COLLAPSED) + ) + .isPresent(); + + var diagramAndPropertiesFlux = Flux.merge(diagramFlux, diagramFilterFlux); + StepVerifier.create(diagramAndPropertiesFlux) + .expectNextMatches(DiagramRefreshedEventPayload.class::isInstance) + .expectNextMatches(initialFormContentMatcher) + .then(checkTreeNode) + .expectNextMatches(updatedFormContentMatcher) + .expectNextMatches(DiagramRefreshedEventPayload.class::isInstance) + .then(collapseNodes) + // Skip the potential FormRefreshedEventPayload that may be sent before the DiagramRefreshedEventPayload + .thenConsumeWhile(payload -> !(payload instanceof DiagramRefreshedEventPayload)) + .expectNextMatches(updatedDiagramContentMatcher) + .thenCancel() + .verify(Duration.ofSeconds(10)); + } + + private void assertThatNodeMatchesTreeNodeEndIcons(Node node, TreeNode treeNode) { + if (node.getModifiers().contains(ViewModifier.Hidden)) { + assertThat(treeNode.getEndIconsURL()).contains(List.of("/icons/full/obj16/HideTool.svg")); + } + if (node.getModifiers().contains(ViewModifier.Faded)) { + assertThat(treeNode.getEndIconsURL()).contains(List.of(DiagramImageConstants.FADE_SVG)); + } + if (node.isPinned()) { + assertThat(treeNode.getEndIconsURL()).contains(List.of(DiagramImageConstants.PIN_SVG)); + } + if (node.getCollapsingState().equals(CollapsingState.COLLAPSED)) { + assertThat(treeNode.getEndIconsURL()).contains(List.of(DiagramImageConstants.COLLAPSE_SVG)); + } + } + + private Optional
refreshedForm(Object object) { + return Optional.of(object) + .filter(DataFetcherResult.class::isInstance) + .map(DataFetcherResult.class::cast) + .map(DataFetcherResult::getData) + .filter(FormRefreshedEventPayload.class::isInstance) + .map(FormRefreshedEventPayload.class::cast) + .map(FormRefreshedEventPayload::form); + } + + private Optional refreshedDiagram(Object object) { + return Optional.of(object) + .filter(DiagramRefreshedEventPayload.class::isInstance) + .map(DiagramRefreshedEventPayload.class::cast) + .map(DiagramRefreshedEventPayload::diagram); + } +} diff --git a/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilter.tsx b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilter.tsx new file mode 100644 index 0000000000..c083152113 --- /dev/null +++ b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilter.tsx @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 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 ClickAwayListener from '@material-ui/core/ClickAwayListener'; +import IconButton from '@material-ui/core/IconButton'; +import Paper from '@material-ui/core/Paper'; +import Popper from '@material-ui/core/Popper'; +import Tooltip from '@material-ui/core/Tooltip'; + +import { Selection, useSelection } from '@eclipse-sirius/sirius-components-core'; +import { DiagramPanelActionProps } from '@eclipse-sirius/sirius-components-diagrams'; +import FilterListIcon from '@material-ui/icons/FilterList'; +import { useRef, useState } from 'react'; +import { DiagramFilterForm } from './DiagramFilterForm'; + +export const DiagramFilter = ({ editingContextId, diagramId }: DiagramPanelActionProps) => { + const [isOpen, setIsOpen] = useState(false); + const { setSelection } = useSelection(); + + const handlePanel = () => { + const newSelection: Selection = { + entries: [ + { + id: diagramId, + label: '', + kind: '', + }, + ], + }; + setSelection(newSelection); + setIsOpen(() => true); + }; + + const anchorRef = useRef(null); + + return ( + <> + + + + + + + + setIsOpen(false)}> +
+ +
+
+
+
+ + ); +}; diff --git a/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilter.types.ts b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilter.types.ts new file mode 100644 index 0000000000..99d741cfcd --- /dev/null +++ b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilter.types.ts @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ + +export interface DiagramFilterProps { + editingContextId: string; + diagramId: string; +} diff --git a/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilterForm.tsx b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilterForm.tsx new file mode 100644 index 0000000000..f26f0b1b6b --- /dev/null +++ b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilterForm.tsx @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 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 { WorkbenchViewComponentProps } from '@eclipse-sirius/sirius-components-core'; +import { FormBasedView, GQLForm, Group } from '@eclipse-sirius/sirius-components-forms'; +import { makeStyles } from '@material-ui/core/styles'; +import { DiagramFilterFormProps } from './DiagramFilterForm.types'; + +const useDiagramFilterViewStyles = makeStyles((theme) => ({ + content: { + padding: theme.spacing(1), + }, +})); + +export const DiagramFilterForm = (props: DiagramFilterFormProps) => { + const classes = useDiagramFilterViewStyles(); + + const extractFirstGroup = (props: WorkbenchViewComponentProps, form: GQLForm): JSX.Element => { + const group = form.pages[0]?.groups[0]; + if (group) { + return ( +
+ +
+ ); + } else { + return
; + } + }; + + return ; +}; diff --git a/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilterForm.types.ts b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilterForm.types.ts new file mode 100644 index 0000000000..11f38b5814 --- /dev/null +++ b/packages/sirius-web/frontend/sirius-web-application/src/diagrams/DiagramFilterForm.types.ts @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ + +export interface DiagramFilterFormProps { + editingContextId: string; + readOnly: boolean; +} 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 index 937c3612c4..6c93cc7555 100644 --- 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 @@ -10,13 +10,14 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ + import { GraphQLNodeStyleFragment, INodeConverter, INodeLayoutHandler, NodeData, NodeTypeContributionElement, -} from '../../../../../diagrams/frontend/sirius-components-diagrams/dist'; +} from '@eclipse-sirius/sirius-components-diagrams'; export interface DiagramRepresentationConfigurationProps { nodeTypeRegistry: NodeTypeRegistry; diff --git a/packages/sirius-web/frontend/sirius-web-application/src/extension/DefaultExtensionRegistry.tsx b/packages/sirius-web/frontend/sirius-web-application/src/extension/DefaultExtensionRegistry.tsx index 1b5d9c7340..fa55a694b4 100644 --- a/packages/sirius-web/frontend/sirius-web-application/src/extension/DefaultExtensionRegistry.tsx +++ b/packages/sirius-web/frontend/sirius-web-application/src/extension/DefaultExtensionRegistry.tsx @@ -20,7 +20,7 @@ import { workbenchViewContributionExtensionPoint, } from '@eclipse-sirius/sirius-components-core'; import { DeckRepresentation } from '@eclipse-sirius/sirius-components-deck'; -import { DiagramRepresentation } from '@eclipse-sirius/sirius-components-diagrams'; +import { DiagramRepresentation, diagramPanelActionExtensionPoint } from '@eclipse-sirius/sirius-components-diagrams'; import { FormDescriptionEditorRepresentation } from '@eclipse-sirius/sirius-components-formdescriptioneditors'; import { DetailsView, @@ -37,6 +37,7 @@ import Filter from '@material-ui/icons/Filter'; import LinkIcon from '@material-ui/icons/Link'; import MenuIcon from '@material-ui/icons/Menu'; import WarningIcon from '@material-ui/icons/Warning'; +import { DiagramFilter } from '../diagrams/DiagramFilter'; import { OnboardArea } from '../onboarding/OnboardArea'; import { createProjectAreaCardExtensionPoint } from '../views/project-browser/create-projects-area/CreateProjectAreaExtensionPoints'; import { NewProjectCard } from '../views/project-browser/create-projects-area/NewProjectCard'; @@ -133,9 +134,9 @@ defaultExtensionRegistry.putData(representationFactoryExtensionPoint, { /******************************************************************************* * - * Project area cards + * Create project area cards * - * Used to register all the type of cards in the project area + * Used to register all the type of cards in the create project area * *******************************************************************************/ @@ -152,4 +153,17 @@ defaultExtensionRegistry.addComponent(createProjectAreaCardExtensionPoint, { Component: ShowAllProjectTemplatesCard, }); +/******************************************************************************* + * + * Diagram panel + * + * Used to register new components in the diagram panel + * + *******************************************************************************/ + +defaultExtensionRegistry.addComponent(diagramPanelActionExtensionPoint, { + identifier: `siriusweb_${diagramPanelActionExtensionPoint.identifier}_filter`, + Component: DiagramFilter, +}); + export { defaultExtensionRegistry };