Skip to content

Commit

Permalink
[4522] Restore contribution of custom tools to the diagram palette
Browse files Browse the repository at this point in the history
Bug: #4522
Signed-off-by: Florian ROUËNÉ <[email protected]>
  • Loading branch information
frouene committed Feb 11, 2025
1 parent e8c7f27 commit 11d8396
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 53 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ Now they are executed for some data if the data was coming from a studio too.
- https://github.com/eclipse-sirius/sirius-web/issues/4390[#4390] [form] Fix an issue displaying irrelevant help text and diagnostics
- [diagram] Replace `requestIdleCallback` with `setTimeout` for browser compatibility given the fact that `requestIdleCallback` is still a working draft
- [sirius-web] Fix a recently introduced bug in which the semantic data of a project could remain after the deletion of the project
- https://github.com/eclipse-sirius/sirius-web/issues/4522[#4522] [diagram] Fix an issue where custom tools were no longer contributed to the diagram palette


=== New Features
Expand Down
55 changes: 55 additions & 0 deletions integration-tests/cypress/e2e/project/diagrams/custom-tool.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*******************************************************************************
* Copyright (c) 2025 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 { Explorer } from '../../../workbench/Explorer';
import { Diagram } from '../../../workbench/Diagram';
import { Papaya } from '../../../usecases/Papaya';
import { Project } from '../../../pages/Project';

describe('Custom tools', () => {
context('Given a papaya blank project', () => {
let projectId: string = '';
beforeEach(() => {
new Papaya().createPapayaBlankProject().then((createdProjectData) => {
projectId = createdProjectData.projectId;
const project = new Project();
project.visit(projectId);
const explorer = new Explorer();
explorer.expandWithDoubleClick('Papaya');
explorer.expandWithDoubleClick('Project Project');
explorer.expandWithDoubleClick('Component Component');
explorer.createRepresentation('Component Component', 'Component Diagram', 'diagram');
});
});

afterEach(() => cy.deleteProject(projectId));

it('Check diagram custom tool exist', () => {
const diagram = new Diagram();
diagram.getDiagram('diagram').should('exist');
cy.getByTestId('rf__wrapper').should('exist').rightclick(100, 100).rightclick(100, 100);
diagram.getPalette().should('exist');
cy.getByTestId('coordinates-tool').should('exist');
});

it('Check diagram element custom tool exist', () => {
const diagram = new Diagram();
diagram.getDiagram('diagram').should('exist');
cy.getByTestId('rf__wrapper').should('exist').rightclick(100, 100).rightclick(100, 100);
diagram.getPalette().should('exist');
cy.getByTestId('tool-New component').should('exist').click();
diagram.fitToScreen();
diagram.getNodes('diagram', 'Component').should('exist').rightclick();
cy.getByTestId('label-detail').should('exist');
});
});
});
34 changes: 4 additions & 30 deletions integration-tests/cypress/usecases/Papaya.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* Copyright (c) 2024, 2025 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
Expand All @@ -10,47 +10,21 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
import { Project } from '../pages/Project';
import { isCreateProjectSuccessPayload } from '../support/server/createProjectCommand';
import { isCreateProjectFromTemplateSuccessPayload } from '../support/server/createProjectFromTemplateCommand';
import { Explorer } from '../workbench/Explorer';
import { Workbench } from '../workbench/Workbench';
import { CreatedProjectData } from './Papaya.types';

export class Papaya {
static readonly PAPAYA_NATURE = 'siriusComponents://nature?kind=papaya';

public createPapayaStudioProject(): Cypress.Chainable<CreatedProjectData> {
return cy.createProjectFromTemplate('papaya-studio-template').then((res) => {
public createPapayaBlankProject(): Cypress.Chainable<CreatedProjectData> {
return cy.createProjectFromTemplate('papaya-empty').then((res) => {
const payload = res.body.data.createProjectFromTemplate;
if (isCreateProjectFromTemplateSuccessPayload(payload)) {
const projectId = payload.project.id;
const data: CreatedProjectData = { projectId };
return cy.wrap(data);
} else {
throw new Error(`The project papaya studio has not been created`);
}
});
}

public createPapayaInstanceProject(name: string): Cypress.Chainable<CreatedProjectData> {
return cy.createProject(name, [Papaya.PAPAYA_NATURE]).then((res) => {
const payload = res.body.data.createProject;
if (isCreateProjectSuccessPayload(payload)) {
const projectId = payload.project.id;

new Project().visit(projectId);

const workbench = new Workbench();
workbench.performAction('Others...');

const explorer = new Explorer();
explorer.createRootObject('Others...', 'papaya_core', 'Root');

const data: CreatedProjectData = { projectId };
return cy.wrap(data);
} else {
throw new Error(`The project "${name}" has not been created`);
throw new Error(`The project papaya blank has not been created`);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2023, 2024 Obeo.
* Copyright (c) 2023, 2025 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
Expand All @@ -15,7 +15,7 @@ import { Edge, Node } from '@xyflow/react';
import { EdgeData, NodeData } from '../../DiagramRenderer.types';

export interface DiagramPaletteToolContributionProps {
canHandle: (element: Node<NodeData> | Edge<EdgeData>) => boolean;
canHandle: (element: Node<NodeData> | Edge<EdgeData> | null) => boolean;
component: React.ComponentType<DiagramPaletteToolContributionComponentProps>;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* Copyright (c) 2024, 2025 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
Expand All @@ -25,6 +25,7 @@ import { FadeElementTool } from './FadeElementTool';
import { PaletteQuickAccessToolBarProps } from './PaletteQuickAccessToolBar.types';
import { PinUnPinTool } from './PinUnPinTool';
import { ResetEditedEdgePathTool } from './ResetEditedEdgePathTool';

const isPinnable = (diagramElement: Node<NodeData> | Edge<EdgeData>): diagramElement is Node<NodeData> => {
return !!diagramElement.data && 'pinned' in diagramElement.data;
};
Expand Down Expand Up @@ -91,25 +92,25 @@ export const PaletteQuickAccessToolBar = ({
quickAccessToolComponents.push(
<AdjustSizeTool diagramElementId={diagramElementId} key={'tool_adjustSizeTool'}></AdjustSizeTool>
);
}

const paletteToolData: DataExtension<DiagramPaletteToolContributionProps[]> = useData(
diagramPaletteToolExtensionPoint
);
const paletteToolData: DataExtension<DiagramPaletteToolContributionProps[]> = useData(
diagramPaletteToolExtensionPoint
);

paletteToolData.data
.filter((data) => data.canHandle(diagramElement))
.map((data) => data.component)
.forEach((PaletteToolComponent, index) =>
quickAccessToolComponents.push(
<PaletteToolComponent
x={x}
y={y}
diagramElementId={diagramElementId}
key={'paletteToolComponents_' + index.toString()}
/>
)
);
}
paletteToolData.data
.filter((data) => data.canHandle(diagramElement ?? null))
.map((data) => data.component)
.forEach((PaletteToolComponent, index) =>
quickAccessToolComponents.push(
<PaletteToolComponent
x={x}
y={y}
diagramElementId={diagramElementId}
key={'paletteToolComponents_' + index.toString()}
/>
)
);

if (quickAccessToolComponents.length > 0) {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import Typography from '@mui/material/Typography';
import { Edge, Node, ReactFlowProps } from '@xyflow/react';
import { PapayaDiagramInformationPanel } from './diagrams/PapayaDiagramInformationPanel';
import { PapayaDiagramLegendPanel } from './diagrams/PapayaDiagramLegendPanel';
import { PapayaComponentDiagramToolContribution } from './tools/PapayaComponentDiagramToolContribution';
import { PapayaComponentLabelDetailToolContribution } from './tools/PapayaComponentLabelDetailToolContribution';

const papayaExtensionRegistry = new ExtensionRegistry();
Expand Down Expand Up @@ -82,13 +83,17 @@ const papayaDiagramPanelExtension: DataExtension<Array<ReactFlowPropsCustomizer>
papayaExtensionRegistry.putData(diagramRendererReactFlowPropsCustomizerExtensionPoint, papayaDiagramPanelExtension);
const diagramPaletteToolContributions: DiagramPaletteToolContributionProps[] = [
{
canHandle: (diagamElement: Node<NodeData> | Edge<EdgeData>) => {
return diagamElement.data
? diagamElement.data.targetObjectKind.startsWith('siriusComponents://semantic?domain=papaya&entity=Component')
canHandle: (diagramElement: Node<NodeData> | Edge<EdgeData> | null) => {
return diagramElement?.data
? diagramElement.data.targetObjectKind.startsWith('siriusComponents://semantic?domain=papaya&entity=Component')
: false;
},
component: PapayaComponentLabelDetailToolContribution,
},
{
canHandle: (diagramElement: Node<NodeData> | Edge<EdgeData> | null) => diagramElement === null,
component: PapayaComponentDiagramToolContribution,
},
];
papayaExtensionRegistry.putData<DiagramPaletteToolContributionProps[]>(diagramPaletteToolExtensionPoint, {
identifier: `papaya_${diagramPaletteToolExtensionPoint.identifier}`,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*******************************************************************************
* Copyright (c) 2025 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 RadarIcon from '@mui/icons-material/Radar';
import Dialog from '@mui/material/Dialog';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import IconButton from '@mui/material/IconButton';
import { Fragment, useState } from 'react';
import { makeStyles } from 'tss-react/mui';

const useToolStyle = makeStyles()(() => ({
tool: {
width: '36px',
},
}));

type Modal = 'dialog';
export const PapayaComponentDiagramToolContribution = ({ x, y }) => {
const [modal, setModal] = useState<Modal | null>(null);
const { classes } = useToolStyle();

const onClose = () => {
setModal(null);
};

let modalElement: JSX.Element | null = null;
if (modal === 'dialog') {
modalElement = (
<>
<Dialog open={true} onClose={onClose} fullWidth>
<DialogContent>
<DialogContentText>
x: {x}, y:{y}
</DialogContentText>
</DialogContent>
</Dialog>
</>
);
}

return (
<Fragment key="coordinates-modal-contribution">
<IconButton
className={classes.tool}
size="small"
color="inherit"
aria-label="Coordinates"
title="Coordinates"
onClick={() => setModal('dialog')}
data-testid="coordinates-tool">
<RadarIcon />
</IconButton>
{modalElement}
</Fragment>
);
};

0 comments on commit 11d8396

Please sign in to comment.