Skip to content

Commit

Permalink
[889] Remove New Object/Representation menu entries for libraries
Browse files Browse the repository at this point in the history
Bug: #889
Signed-off-by: Gwendal Daniel <gwendal.daniel@obeosoft.com>
  • Loading branch information
gdaniel committed Dec 18, 2024
1 parent e7d9e6a commit 923112a
Show file tree
Hide file tree
Showing 10 changed files with 378 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ The explorer now contains the following directories for libraries:
** _User Libraries_: User-imported libraries
- https://github.com/eclipse-syson/syson/issues/888[#888] [explorer] Remove 'New objects from text' contextual menu entry for libraries.
- https://github.com/eclipse-syson/syson/issues/901[#901] [import] Allow to import `.kerml` textual files.
- https://github.com/eclipse-syson/syson/issues/889[#889] [explorer] Remove 'New object' and 'New representation' contextual menu entries for libraries.

=== New features

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ image::release-notes-libraries-directories.png[Libraries Directories in the expl

- Remove 'New objects from text' contextual menu entry for libraries.
- Allow to import `.kerml` textual files.
- Remove 'New object' and 'New representation' contextual menu entries for libraries.

== New features

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*******************************************************************************
* 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 { Selection, ServerContext, ServerContextValue, useSelection } from '@eclipse-sirius/sirius-components-core';
import { TreeItemContextMenuComponentProps } from '@eclipse-sirius/sirius-components-trees';
import AddIcon from '@mui/icons-material/Add';
import GetAppIcon from '@mui/icons-material/GetApp';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import MenuItem from '@mui/material/MenuItem';
import { Fragment, forwardRef, useContext, useState } from 'react';
import { NewRootObjectModal } from '@eclipse-sirius/sirius-web-application';

type Modal = 'CreateNewRootObject';

export const SysONDocumentTreeItemContextMenuContribution = forwardRef(
(
{ editingContextId, treeId, item, readOnly, expandItem, onClose }: TreeItemContextMenuComponentProps,
ref: React.ForwardedRef<HTMLLIElement>
) => {
const { httpOrigin } = useContext<ServerContextValue>(ServerContext);
const [modal, setModal] = useState<Modal | null>(null);
const { setSelection } = useSelection();

if (!treeId.startsWith('explorer://') || !item.kind.startsWith('siriusWeb://document')) {
return null;
}

const onObjectCreated = (selection: Selection) => {
setSelection(selection);
expandItem();
onClose();
};

let modalElement = null;
if (modal === 'CreateNewRootObject') {
modalElement = (
<NewRootObjectModal
editingContextId={editingContextId}
item={item}
onObjectCreated={onObjectCreated}
onClose={onClose}
/>
);
}

let menuItems = [];
if (item.editable) {
menuItems.push(
<MenuItem
key="new-object"
data-testid="new-object"
onClick={() => setModal('CreateNewRootObject')}
ref={ref}
disabled={readOnly}
aria-disabled>
<ListItemIcon>
<AddIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="New object" />
</MenuItem>
);
}
menuItems.push(
<MenuItem
key="download"
divider
onClick={onClose}
component="a"
href={`${httpOrigin}/api/editingcontexts/${editingContextId}/documents/${item.id}`}
type="application/octet-stream"
data-testid="download"
aria-disabled>
<ListItemIcon>
<GetAppIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="Download" aria-disabled />
</MenuItem>
);

return (
<Fragment key="document-tree-item-context-menu-contribution">
{menuItems}
{modalElement}
</Fragment>
);
}
);
Original file line number Diff line number Diff line change
@@ -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 { ComponentExtension, ExtensionRegistryMergeStrategy } from '@eclipse-sirius/sirius-components-core';
import { DefaultExtensionRegistryMergeStrategy } from '@eclipse-sirius/sirius-web-application';
import { treeItemContextMenuEntryExtensionPoint } from '@eclipse-sirius/sirius-components-trees';

export class SysONExtensionRegistryMergeStrategy
extends DefaultExtensionRegistryMergeStrategy
implements ExtensionRegistryMergeStrategy
{
public override mergeComponentExtensions(
_identifier: string,
existingValues: ComponentExtension<any>[],
newValues: ComponentExtension<any>[]
): ComponentExtension<any>[] {
if (_identifier === treeItemContextMenuEntryExtensionPoint.identifier) {
return super.mergeComponentExtensions(
_identifier,
existingValues.filter((contribution) => {
// Discard default versions of these extensions, we want to replace them with our own.
return (
contribution.identifier !== `siriusweb_${treeItemContextMenuEntryExtensionPoint.identifier}_object` &&
contribution.identifier !== `siriusweb_${treeItemContextMenuEntryExtensionPoint.identifier}_document`
);
}),
newValues
);
}
return super.mergeComponentExtensions(_identifier, existingValues, newValues);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*******************************************************************************
* Copyright (c) 2021, 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 { Selection, useSelection } from '@eclipse-sirius/sirius-components-core';
import { TreeItemContextMenuComponentProps } from '@eclipse-sirius/sirius-components-trees';
import AddIcon from '@mui/icons-material/Add';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import MenuItem from '@mui/material/MenuItem';
import { Fragment, forwardRef, useState } from 'react';
import { NewObjectModal } from '@eclipse-sirius/sirius-web-application';
import { NewRepresentationModal } from '@eclipse-sirius/sirius-web-application';

type Modal = 'CreateNewObject' | 'CreateNewRepresentation';

export const SysONObjectTreeItemContextMenuContribution = forwardRef(
(
{ editingContextId, treeId, item, readOnly, expandItem, onClose }: TreeItemContextMenuComponentProps,
ref: React.ForwardedRef<HTMLLIElement>
) => {
const [modal, setModal] = useState<Modal>(null);
const { setSelection } = useSelection();

if (!treeId.startsWith('explorer://') || !item.kind.startsWith('siriusComponents://semantic')) {
return null;
}

const onObjectCreated = (selection: Selection) => {
setSelection(selection);
expandItem();
onClose();
};

let modalElement = null;
if (modal === 'CreateNewObject') {
modalElement = (
<NewObjectModal
editingContextId={editingContextId}
item={item}
onObjectCreated={onObjectCreated}
onClose={onClose}
/>
);
} else if (modal === 'CreateNewRepresentation') {
modalElement = (
<NewRepresentationModal
editingContextId={editingContextId}
item={item}
onRepresentationCreated={onObjectCreated}
onClose={onClose}
/>
);
}

let menuItems = [];
if (item.editable) {
menuItems.push(
<MenuItem
key="new-object"
onClick={() => setModal('CreateNewObject')}
data-testid="new-object"
disabled={readOnly}
ref={ref}
aria-disabled>
<ListItemIcon>
<AddIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="New object" />
</MenuItem>
);
menuItems.push(
<MenuItem
key="new-representation"
onClick={() => setModal('CreateNewRepresentation')}
data-testid="new-representation"
disabled={readOnly}
aria-disabled>
<ListItemIcon>
<AddIcon fontSize="small" />
</ListItemIcon>
<ListItemText primary="New representation" />
</MenuItem>
);
}

return (
<Fragment key="object-tree-item-context-menu-contribution">
{menuItems}
{modalElement}
</Fragment>
);
}
);
14 changes: 14 additions & 0 deletions frontend/syson/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,13 @@ import { httpOrigin, wsOrigin } from './core/URL';
import { referenceWidgetDocumentTransform } from './extensions/ReferenceWidgetDocumentTransform';
import { SysONFooter } from './extensions/SysONFooter';
import { sysonTheme } from './theme/sysonTheme';
import { SysONObjectTreeItemContextMenuContribution } from './extensions/SysONObjectTreeItemContextMenuContribution';
import { SysONDocumentTreeItemContextMenuContribution } from './extensions/SysONDocumentTreeItemContextMenuContribution';

import './fonts.css';
import './reset.css';
import './variables.css';
import { SysONExtensionRegistryMergeStrategy } from './extensions/SysONExtensionRegistryMergeStrategy';

if (process.env.NODE_ENV !== 'production') {
loadDevMessages();
Expand Down Expand Up @@ -109,6 +112,16 @@ extensionRegistry.addComponent(diagramPanelActionExtensionPoint, {
Component: SysONDiagramPanelMenu,
});

extensionRegistry.addComponent(treeItemContextMenuEntryExtensionPoint, {
identifier: `siriusweb_${treeItemContextMenuEntryExtensionPoint.identifier}_object`,
Component: SysONObjectTreeItemContextMenuContribution,
});

extensionRegistry.addComponent(treeItemContextMenuEntryExtensionPoint, {
identifier: `siriusweb_${treeItemContextMenuEntryExtensionPoint.identifier}_document`,
Component: SysONDocumentTreeItemContextMenuContribution,
});

extensionRegistry.addComponent(treeItemContextMenuEntryExtensionPoint, {
identifier: `syson${treeItemContextMenuEntryExtensionPoint.identifier}_insertTextualSysML`,
Component: InsertTextualSysMLMenuContribution,
Expand Down Expand Up @@ -147,6 +160,7 @@ root.render(
httpOrigin={httpOrigin}
wsOrigin={wsOrigin}
theme={sysonTheme}
extensionRegistryMergeStrategy={new SysONExtensionRegistryMergeStrategy()}
extensionRegistry={extensionRegistry}>
<DiagramRepresentationConfiguration nodeTypeRegistry={nodeTypeRegistry} />
</SiriusWebApplication>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,56 @@ describe('Diagram Creation Tests', () => {
diagram.getDiagram('actionFlowView').should('exist');
});
});

context('When we select the Libraries directory in the explorer', () => {
it('Then we cannot create a new representation in it', () => {
const explorer = new Explorer();
explorer.getTreeItemByLabel(sysmlv2.getLibrariesLabel()).first().find('button').click();
cy.getByTestId('new-representation').should('not.exist');
});
});

context('When we select the KerML directory in the explorer', () => {
it('Then we cannot create a new representation in it', () => {
const explorer = new Explorer();
explorer.expand(sysmlv2.getLibrariesLabel());
explorer.getTreeItemByLabel(sysmlv2.getKerMLLabel()).first().find('button').click();
cy.getByTestId('new-representation').should('not.exist');
});
});

context('When we select the SysML directory in the explorer', () => {
it('Then we cannot create a new representation in it', () => {
const explorer = new Explorer();
explorer.expand(sysmlv2.getLibrariesLabel());
explorer.getTreeItemByLabel(sysmlv2.getSysMLLabel()).first().find('button').click();
cy.getByTestId('new-representation').should('not.exist');
});
});

context('When we select the Base KerML model in the explorer', () => {
it('Then we cannot create a new representation in it', () => {
const explorer = new Explorer();
explorer.expand(sysmlv2.getLibrariesLabel());
explorer.expand(sysmlv2.getKerMLLabel());
explorer.getTreeItemByLabel('Base').first().find('button').click();
cy.getByTestId('new-representation').should('not.exist');
});
});

context('When we select the Base KerML model top-level element in the explorer', () => {
it('Then we cannot create a new representation in it', () => {
const explorer = new Explorer();
explorer.expand(sysmlv2.getLibrariesLabel());
explorer.expand(sysmlv2.getKerMLLabel());
explorer.expand('Base');
explorer
.getTreeItemByLabelAndKind('Base', 'siriusComponents://semantic?domain=sysml&entity=LibraryPackage')
.first()
.find('button')
.click();
cy.getByTestId('new-representation').should('not.exist');
});
});
});
});
Loading

0 comments on commit 923112a

Please sign in to comment.