From 013ae29fd45b079606414ad887856070fc119d7f Mon Sep 17 00:00:00 2001 From: Pierre-Charles David Date: Wed, 27 May 2026 14:05:09 +0200 Subject: [PATCH 1/3] [2119] Display expressions values in the Details view Bug: https://github.com/eclipse-syson/syson/issues/2119 Signed-off-by: Pierre-Charles David --- CHANGELOG.adoc | 4 +- .../SysMLv2PropertiesConfigurer.java | 25 +++ .../services/DetailsViewService.java | 46 ++++- .../MetamodelQueryElementService.java | 18 ++ .../assets/images/expression-details.png | Bin 0 -> 116392 bytes .../pages/features/expressions.adoc | 4 + .../pages/release-notes/2026.7.0.adoc | 5 + .../SysONExtensionRegistryMergeStrategy.ts | 16 +- .../expressions/ExpressionPropertySection.tsx | 187 ++++++++++++++++++ ...Registry.ts => SysONExtensionRegistry.tsx} | 26 +++ .../cypress/e2e/project/details/details.cy.ts | 13 +- .../cypress/workbench/Explorer.ts | 7 +- 12 files changed, 343 insertions(+), 8 deletions(-) create mode 100644 doc/content/modules/user-manual/assets/images/expression-details.png create mode 100644 frontend/syson-components/src/extensions/expressions/ExpressionPropertySection.tsx rename frontend/syson-components/src/extensions/registry/{SysONExtensionRegistry.ts => SysONExtensionRegistry.tsx} (89%) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 49088b0e3..f3d9aa30d 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -26,11 +26,11 @@ - https://github.com/eclipse-syson/syson/issues/2198[#2198] [diagrams] Improve diagram-to-diagram drag and drop to support dropping multiple graphical nodes at once, leveraging Sirius Web's `droppedNodes` and `droppedElements` variables. - https://github.com/eclipse-syson/syson/issues/2194[#2194] [diagrams] Properly report feedback messages to user when using _ISysMLMoveElementService_. -- https://github.com/eclipse-syson/syson/issues/2182[#2182] [services] Provide a way for downstream applications to extend _ISysMLMoveElementService_; +- https://github.com/eclipse-syson/syson/issues/2182[#2182] [services] Provide a way for downstream applications to extend _ISysMLMoveElementService_. - https://github.com/eclipse-syson/syson/issues/2240[#2240] [diagrams] Update the choice of _timeslice_ and _snapshot_ elements that can be created in the selection dialog of tools creating _timeslice_ and _snapshot_ elements. Before, the selection dialog option with selection allowed choosing between all _timeslice/snapshot_ types. Now, the choice is restricted to the _timeslice/snapshot_ type that match the graphical node type on which the tool is applied. - +- https://github.com/eclipse-syson/syson/issues/2119[#2119] [details] Display expressions values in the _Details_ view and allow to edit them from there. === New features diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java index ddbf1b316..e10f7201d 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java @@ -79,6 +79,8 @@ @Configuration public class SysMLv2PropertiesConfigurer implements IPropertiesDescriptionRegistryConfigurer { + private static final String CUSTOM_EXPRESSION_WIDGET_KEY = "syson:expression-value-widget"; + private static final String CORE_PROPERTIES = "Core Properties"; private static final String ADVANCED_PROPERTIES = "Advanced Properties"; @@ -189,6 +191,7 @@ private FormDescription createDetailsViewForElement() { pageCore.getGroups().add(this.createExtraAcceptActionUsagePropertiesGroup()); pageCore.getGroups().add(this.createExtraTransitionSourceTargetPropertiesGroup()); pageCore.getGroups().add(this.createFeatureValuePropertiesGroup()); + pageCore.getGroups().add(this.createExpressionPropertiesGroup()); PageDescription pageAdvanced = FormFactory.eINSTANCE.createPageDescription(); pageAdvanced.setName("SysON-DetailsView-Advanced"); @@ -203,6 +206,28 @@ private FormDescription createDetailsViewForElement() { return form; } + /** + * Creates a group to display the value of an Expression. + * + * @return a {@link GroupDescription} + */ + private GroupDescription createExpressionPropertiesGroup() { + GroupDescription group = FormFactory.eINSTANCE.createGroupDescription(); + group.setDisplayMode(GroupDisplayMode.LIST); + group.setName("Expression Value"); + group.setLabelExpression(""); + group.setSemanticCandidatesExpression(ServiceMethod.of0(DetailsViewService::getExpression).aqlSelf()); + + TextAreaDescription expressionWidget = FormFactory.eINSTANCE.createTextAreaDescription(); + expressionWidget.setName("Expression"); + expressionWidget.setLabelExpression(CUSTOM_EXPRESSION_WIDGET_KEY); + expressionWidget.setValueExpression(ServiceMethod.of0(DetailsViewService::getExpressionTextualRepresentation).aqlSelf()); + expressionWidget.setIsEnabledExpression(AQLConstants.AQL_FALSE); + + group.getChildren().add(expressionWidget); + + return group; + } /** * Creates a group to display the value of a Feature or FeatureValue. diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/DetailsViewService.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/DetailsViewService.java index def9195d8..a7c338ce1 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/DetailsViewService.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/services/DetailsViewService.java @@ -44,6 +44,7 @@ import org.eclipse.syson.sysml.Annotation; import org.eclipse.syson.sysml.Comment; import org.eclipse.syson.sysml.ConjugatedPortDefinition; +import org.eclipse.syson.sysml.Definition; import org.eclipse.syson.sysml.Documentation; import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.EndFeatureMembership; @@ -55,6 +56,7 @@ import org.eclipse.syson.sysml.FeatureValue; import org.eclipse.syson.sysml.Import; import org.eclipse.syson.sysml.Membership; +import org.eclipse.syson.sysml.Namespace; import org.eclipse.syson.sysml.ParameterMembership; import org.eclipse.syson.sysml.ReferenceSubsetting; import org.eclipse.syson.sysml.ReferenceUsage; @@ -68,6 +70,7 @@ import org.eclipse.syson.sysml.SysmlPackage; import org.eclipse.syson.sysml.TransitionUsage; import org.eclipse.syson.sysml.Type; +import org.eclipse.syson.sysml.Usage; import org.eclipse.syson.sysml.ViewUsage; import org.eclipse.syson.sysml.metamodel.services.ElementInitializerSwitch; import org.eclipse.syson.sysml.metamodel.services.MetamodelQueryElementService; @@ -570,12 +573,16 @@ public Element setNewDocumentationValue(Element self, String newValue) { * a {@link FeatureValue} or {@link Feature} * @return a {@link FeatureValue} or null */ - public Element getFeatureValue(Element self) { - Element result = null; + public FeatureValue getFeatureValue(Element self) { + FeatureValue result = null; if (self instanceof FeatureValue featureValue && featureValue.getValue() != null) { result = featureValue; } else if (self instanceof Feature feature) { - result = this.metamodelQueryElementService.getValueExpression(feature).orElse(null); + result = feature.getOwnedRelationship().stream() + .filter(FeatureValue.class::isInstance) + .map(FeatureValue.class::cast) + .findFirst() + .orElse(null); } return result; } @@ -626,6 +633,39 @@ private String getExpressionAsText(Expression expression) { return this.metamodelQueryElementService.getExpressionTextualRepresentation(expression); } + /** + * Gets the {@link ResultExpressionMembership} from a {@link Namespace} or a {@link ResultExpressionMembership}. + * + * @param self + * a {@link Namespace} or a {@link ResultExpressionMembership}. + * @return a {@link ResultExpressionMembership} or null + */ + public Element getResultExpression(Element self) { + Element result = null; + if (self instanceof ResultExpressionMembership expressionMembership && expressionMembership.getOwnedResultExpression() != null) { + result = expressionMembership; + } else if (self instanceof Namespace namespace && this.metamodelQueryElementService.getResultExpressionMembership(namespace) != null + && this.metamodelQueryElementService.getResultExpressionMembership(namespace).getOwnedResultExpression() != null) { + result = this.metamodelQueryElementService.getResultExpressionMembership(namespace); + } + return result; + } + + /** + * Gets the {@link ResultExpressionMembership} from a {@link Namespace} or a {@link ResultExpressionMembership}. + * + * @param self + * a {@link Namespace} or a {@link ResultExpressionMembership}. + * @return a {@link ResultExpressionMembership} or null + */ + public Element getExpression(Element self) { + if (self instanceof Expression && !(self instanceof Usage) && !(self instanceof Definition)) { + return self; + } else { + return null; + } + } + /** * Returns the element that owns the visibility feature of the given element. * diff --git a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/MetamodelQueryElementService.java b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/MetamodelQueryElementService.java index 54b3fb429..373bf1965 100644 --- a/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/MetamodelQueryElementService.java +++ b/backend/services/syson-sysml-metamodel-services/src/main/java/org/eclipse/syson/sysml/metamodel/services/MetamodelQueryElementService.java @@ -27,9 +27,11 @@ import org.eclipse.syson.sysml.Feature; import org.eclipse.syson.sysml.FeatureValue; import org.eclipse.syson.sysml.FramedConcernMembership; +import org.eclipse.syson.sysml.Namespace; import org.eclipse.syson.sysml.OwningMembership; import org.eclipse.syson.sysml.PartUsage; import org.eclipse.syson.sysml.ReferenceUsage; +import org.eclipse.syson.sysml.ResultExpressionMembership; import org.eclipse.syson.sysml.StakeholderMembership; import org.eclipse.syson.sysml.SubjectMembership; import org.eclipse.syson.sysml.SysmlFactory; @@ -306,4 +308,20 @@ public ConcernUsage getFramedConcernTarget(FramedConcernMembership framedConcern } return null; } + + /** + * Get the {@link ResultExpressionMembership} contained inside a given {@link Namespace}. + * + * @param namespace + * a given {@link Namespace}. + * @return a {@link ResultExpressionMembership}, or null if not found. + */ + public ResultExpressionMembership getResultExpressionMembership(Namespace namespace) { + return namespace.getOwnedMembership().stream() + .filter(ResultExpressionMembership.class::isInstance) + .map(ResultExpressionMembership.class::cast) + .findFirst() + .orElse(null); + } + } diff --git a/doc/content/modules/user-manual/assets/images/expression-details.png b/doc/content/modules/user-manual/assets/images/expression-details.png new file mode 100644 index 0000000000000000000000000000000000000000..b7ba2f23776035886d67a6735e79fdb36cc1e285 GIT binary patch literal 116392 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%0DsG0Hpo>{&c+_K7-&pvRz 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 NuA;46p=c5Oe*pe+P3Hgr literal 0 HcmV?d00001 diff --git a/doc/content/modules/user-manual/pages/features/expressions.adoc b/doc/content/modules/user-manual/pages/features/expressions.adoc index dd516a555..ca3724d25 100644 --- a/doc/content/modules/user-manual/pages/features/expressions.adoc +++ b/doc/content/modules/user-manual/pages/features/expressions.adoc @@ -19,6 +19,10 @@ a|image::explorer-expression-internals-hidden.png[Internals hidden (default)] a|image::explorer-expression-internals-visible.png[Internals visible] |=== +When an `Expression` element is selected(for example from the {explorer} view), the {details}} view displays its textual representation, with a button to open the expression edition modal (see below) directly on it: ++ +image::expression-details.png[Expression value displayed in the _Details_ veiw, width=80%] + == Creation To _create_ an expression, invoke the _New expression_ context menu action on a compatible element (supported elements are `Attributes`, `Constraints` and `Transitions`). diff --git a/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc b/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc index d3b23905f..b94323cd7 100644 --- a/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc +++ b/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc @@ -63,6 +63,11 @@ To _edit_ an existing expression, simply invoke the _Edit expression_ context me + To _delete_ an existing expression, you can simply invoke the normal _Delete_ menu item action on the expression itself or the new _Delete expression_ on its parent element. +* In the _Details_ view: + +** When an `Expression` element is selected (for example from the _Explorer_ view), the _Details_ view displays its textual representation, with a button to open the expression edition modal (see above) directly on it: ++ +image::expression-details.png[Expression value displayed in the _Details_ veiw, width=80%] == Bug fixes diff --git a/frontend/syson-components/src/extensions/SysONExtensionRegistryMergeStrategy.ts b/frontend/syson-components/src/extensions/SysONExtensionRegistryMergeStrategy.ts index f2dfab167..97fe7e724 100644 --- a/frontend/syson-components/src/extensions/SysONExtensionRegistryMergeStrategy.ts +++ b/frontend/syson-components/src/extensions/SysONExtensionRegistryMergeStrategy.ts @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 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 @@ -12,6 +12,7 @@ *******************************************************************************/ import { DataExtension, ExtensionRegistryMergeStrategy } from '@eclipse-sirius/sirius-components-core'; +import { widgetContributionExtensionPoint } from '@eclipse-sirius/sirius-components-forms'; import { omniboxCommandOverrideContributionExtensionPoint } from '@eclipse-sirius/sirius-components-omnibox'; import { treeItemContextMenuEntryOverrideExtensionPoint } from '@eclipse-sirius/sirius-components-trees'; import { @@ -37,6 +38,9 @@ export class SysONExtensionRegistryMergeStrategy if (identifier === treeItemContextMenuEntryOverrideExtensionPoint.identifier) { return this.mergeTreeItemContributions(existingValues, newValues); } + if (identifier === widgetContributionExtensionPoint.identifier) { + return this.mergeWidgetContributions(existingValues, newValues); + } return newValues; } @@ -69,4 +73,14 @@ export class SysONExtensionRegistryMergeStrategy data: [...existingContributions.data, ...newContributions.data], }; } + + private mergeWidgetContributions( + existingContributions: DataExtension, + newContributions: DataExtension + ): DataExtension { + return { + identifier: `syson_${widgetContributionExtensionPoint.identifier}`, + data: [...existingContributions.data, ...newContributions.data], + }; + } } diff --git a/frontend/syson-components/src/extensions/expressions/ExpressionPropertySection.tsx b/frontend/syson-components/src/extensions/expressions/ExpressionPropertySection.tsx new file mode 100644 index 000000000..d45041e5f --- /dev/null +++ b/frontend/syson-components/src/extensions/expressions/ExpressionPropertySection.tsx @@ -0,0 +1,187 @@ +/******************************************************************************* + * Copyright (c) 2026 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 { getCSSColor } from '@eclipse-sirius/sirius-components-core'; +import { + GQLTextarea, + GQLTextfield, + PropertySectionComponent, + PropertySectionComponentProps, + PropertySectionLabel, + TextfieldStyleProps, +} from '@eclipse-sirius/sirius-components-forms'; + +import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; +import IconButton from '@mui/material/IconButton'; +import InputAdornment from '@mui/material/InputAdornment'; +import TextField from '@mui/material/TextField'; +import Tooltip from '@mui/material/Tooltip'; +import { useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; +import { EditSysMLExpressionModal } from './EditSysMLExpressionModal'; + +const useStyle = makeStyles()( + (theme, { backgroundColor, foregroundColor, fontSize, italic, bold, gridLayout }) => { + const { + gridTemplateColumns, + gridTemplateRows, + labelGridColumn, + labelGridRow, + widgetGridColumn, + widgetGridRow, + gap, + } = { + ...gridLayout, + }; + return { + style: { + backgroundColor: backgroundColor ? getCSSColor(backgroundColor, theme) : undefined, + color: foregroundColor ? getCSSColor(foregroundColor, theme) : undefined, + fontSize: fontSize ? fontSize : undefined, + fontStyle: italic ? 'italic' : undefined, + fontWeight: bold ? 'bold' : undefined, + }, + input: { + paddingTop: theme.spacing(0.5), + paddingBottom: theme.spacing(0.5), + }, + textfield: { + marginTop: theme.spacing(0.5), + marginBottom: theme.spacing(0.5), + }, + formControl: {}, + propertySection: { + display: 'grid', + gridTemplateColumns, + gridTemplateRows, + alignItems: 'center', + gap: gap ?? '', + }, + propertySectionLabel: { + gridColumn: labelGridColumn, + gridRow: labelGridRow, + display: 'flex', + flexDirection: 'row', + gap: theme.spacing(2), + alignItems: 'center', + }, + propertySectionWidget: { + gridColumn: widgetGridColumn, + gridRow: widgetGridRow, + }, + }; + } +); + +// Extracts the UUID from the string of the form "details://?objectIds=[c5f78f3a-8b39-4cb0-903a-cedd8e6e71f6]" if it contains a single UUID, otherwise returns null. +const extractObjectIdFromDetailsString = (detailsString: string): string | null => { + const regex = /objectIds=\[([0-9a-fA-F-]{36})\]/; + const match = detailsString.match(regex); + return match && match[1] ? match[1] : null; +}; + +type ExpressionPropertySectionState = { + state: 'idle' | 'modal'; +}; + +export const ExpressionPropertySection: PropertySectionComponent = ({ + editingContextId, + formId, + widget, +}: PropertySectionComponentProps) => { + const props: TextfieldStyleProps = { + backgroundColor: widget.style?.backgroundColor ?? null, + foregroundColor: widget.style?.foregroundColor ?? null, + fontSize: widget.style?.fontSize ?? null, + italic: widget.style?.italic ?? null, + bold: widget.style?.bold ?? null, + underline: widget.style?.underline ?? null, + strikeThrough: widget.style?.strikeThrough ?? null, + gridLayout: widget.style?.widgetGridLayout ?? null, + }; + const { classes } = useStyle(props); + const [state, setState] = useState({ + state: 'idle', + }); + const onCloseModal = () => { + setState((prevState) => ({ ...prevState, state: 'idle' })); + }; + const onEditExpression = () => { + setState((prevState) => ({ ...prevState, state: 'modal' })); + }; + + const targetObjectId = extractObjectIdFromDetailsString(formId); + + let modalElement: JSX.Element | null = null; + if (state.state === 'modal' && targetObjectId !== null) { + modalElement = ( + + ); + } + + const labelOverride = 'Expression value'; + const widgetForLabel = { ...widget, label: labelOverride }; + return ( +
+
+ +
+ 0} + helperText={widget.diagnostics[0]?.message} + className={classes.textfield} + InputProps={ + widget.style + ? { + className: classes.style, + } + : {} + } + inputProps={{ + 'data-testid': `input-${labelOverride}`, + className: classes.input, + }} + slotProps={{ + input: { + endAdornment: ( + + + + + + + + ), + }, + }} + /> + {modalElement} +
+ ); +}; diff --git a/frontend/syson-components/src/extensions/registry/SysONExtensionRegistry.ts b/frontend/syson-components/src/extensions/registry/SysONExtensionRegistry.tsx similarity index 89% rename from frontend/syson-components/src/extensions/registry/SysONExtensionRegistry.ts rename to frontend/syson-components/src/extensions/registry/SysONExtensionRegistry.tsx index 9f6e48a70..4d8468138 100644 --- a/frontend/syson-components/src/extensions/registry/SysONExtensionRegistry.ts +++ b/frontend/syson-components/src/extensions/registry/SysONExtensionRegistry.tsx @@ -10,6 +10,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ + import { ExtensionRegistry } from '@eclipse-sirius/sirius-components-core'; import { diagramToolbarActionExtensionPoint, @@ -21,6 +22,11 @@ import { paletteAppearanceSectionExtensionPoint, RectangularNodeAppearanceSection, } from '@eclipse-sirius/sirius-components-diagrams'; +import { + GQLWidget, + PropertySectionComponent, + widgetContributionExtensionPoint, +} from '@eclipse-sirius/sirius-components-forms'; import { OmniboxCommand, OmniboxCommandOverrideContribution, @@ -37,6 +43,7 @@ import { ImportLibraryCommand, navigationBarMenuIconExtensionPoint, } from '@eclipse-sirius/sirius-web-application'; +import QuestionMarkOutlinedIcon from '@mui/icons-material/QuestionMarkOutlined'; import { Edge, Node, useStoreApi } from '@xyflow/react'; import { SysMLImportedPackageNodePaletteAppearanceSection } from '../../nodes/imported_package/SysMLImportedPackageNodePaletteAppearanceSection'; import { SysMLNoteNodePaletteAppearanceSection } from '../../nodes/note/SysMLNoteNodePaletteAppearanceSection'; @@ -45,6 +52,7 @@ import { sysMLNodesStyleDocumentTransform } from '../../nodes/SysMLNodesDocument import { SysMLViewFrameNodePaletteAppearanceSection } from '../../nodes/view_frame/SysMLViewFrameNodePaletteAppearanceSection'; import { DeleteSysMLExpressionMenuContribution } from '../expressions/DeleteSysMLExpressionMenuContribution'; import { EditSysMLExpressionMenuContribution } from '../expressions/EditSysMLExpressionMenuContribution'; +import { ExpressionPropertySection } from '../expressions/ExpressionPropertySection'; import { NewSysMLExpressionMenuContribution } from '../expressions/NewSysMLExpressionMenuContribution'; import { InsertTextualSysMLMenuContribution } from '../InsertTextualSysMLv2MenuContribution'; import { SysONNavigationBarMenuIcon } from '../navigationBarMenu/SysONNavigationBarMenuIcon'; @@ -215,4 +223,22 @@ sysONExtensionRegistry.putData(pale data: customNodePaletteAppearanceSectionContribution, }); +sysONExtensionRegistry.putData(widgetContributionExtensionPoint, { + identifier: `syson_${widgetContributionExtensionPoint.identifier}`, + data: [ + { + name: 'ExpressionValuePropertySectionOverride', + icon: , + previewComponent: () => null, + component: (widget: GQLWidget): PropertySectionComponent | null => { + let propertySectionComponent: PropertySectionComponent | null = null; + if (widget.__typename == 'Textarea' && widget.label.startsWith('syson:expression-value-widget')) { + propertySectionComponent = ExpressionPropertySection as PropertySectionComponent; + } + return propertySectionComponent; + }, + }, + ], +}); + export { sysONExtensionRegistry }; diff --git a/integration-tests-cypress/cypress/e2e/project/details/details.cy.ts b/integration-tests-cypress/cypress/e2e/project/details/details.cy.ts index e9d0b3eaf..842c340f7 100644 --- a/integration-tests-cypress/cypress/e2e/project/details/details.cy.ts +++ b/integration-tests-cypress/cypress/e2e/project/details/details.cy.ts @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 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 @@ -85,5 +85,16 @@ describe('Details View Tests', () => { details.getReferenceWidgetSelectedValue('Specializes', 'Power').should('exist'); }); }); + context('When we select an Expression', () => { + beforeEach(() => { + explorer.select('VehicleMaxSpeed'); + explorer.expandAll('VehicleMaxSpeed'); + explorer.select('vehicle.actualSpeed <= maxSpeed'); + }); + it("Then the Details view shows the expression's textual value", () => { + details.getTextField('Expression value').should('exist'); + details.getTextField('Expression value').should('have.value', 'vehicle.actualSpeed <= maxSpeed'); + }); + }); }); }); diff --git a/integration-tests-cypress/cypress/workbench/Explorer.ts b/integration-tests-cypress/cypress/workbench/Explorer.ts index 4963437a6..291ce4183 100644 --- a/integration-tests-cypress/cypress/workbench/Explorer.ts +++ b/integration-tests-cypress/cypress/workbench/Explorer.ts @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024, 2025 Obeo. + * Copyright (c) 2024, 2026 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 @@ -70,6 +70,11 @@ export class Explorer { cy.getByTestId('treeitem-contextmenu').findByTestId('delete').click(); } + public expandAll(treeItemLabel: string): void { + this.getTreeItemByLabel(treeItemLabel).find('button').click(); + cy.getByTestId('treeitem-contextmenu').findByTestId('expand-all').click(); + } + public dragTreeItem(treeItemLabel: string, dataTransfer: DataTransfer): void { this.getTreeItemByLabel(treeItemLabel).trigger('dragstart', { dataTransfer }); } From 0b27e4eb9e7d5604d5b0fa54cd50f42321a57289 Mon Sep 17 00:00:00 2001 From: Pierre-Charles David Date: Tue, 2 Jun 2026 16:18:21 +0200 Subject: [PATCH 2/3] [2251] Allow expression-related operations on their parent element Bug: https://github.com/eclipse-syson/syson/issues/2251 Signed-off-by: Pierre-Charles David --- CHANGELOG.adoc | 1 + .../SysMLv2PropertiesConfigurer.java | 26 +++++++- ...sionTextualRepresentationEventHandler.java | 33 ++++++++-- ...xpressionsControllersIntegrationTests.java | 11 ++-- .../syson/sysml/dto/EditExpressionInput.java | 2 +- .../services/EditExpressionEventHandler.java | 66 +++++++++++++++++-- .../resources/schema/syson-import.graphqls | 2 +- ...lorerTreeItemContextMenuEntryProvider.java | 3 +- .../pages/features/expressions.adoc | 4 +- .../pages/release-notes/2026.7.0.adoc | 4 +- .../expressions/useEditExpression.ts | 4 +- .../expressions/useEditExpression.types.ts | 2 +- 12 files changed, 132 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index f3d9aa30d..06eb60588 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -31,6 +31,7 @@ Before, the selection dialog option with selection allowed choosing between all _timeslice/snapshot_ types. Now, the choice is restricted to the _timeslice/snapshot_ type that match the graphical node type on which the tool is applied. - https://github.com/eclipse-syson/syson/issues/2119[#2119] [details] Display expressions values in the _Details_ view and allow to edit them from there. +- https://github.com/eclipse-syson/syson/issues/2251[#2251] [explorer] Allow expression-related operations on their parent element === New features diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java index e10f7201d..9c51c98d1 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysMLv2PropertiesConfigurer.java @@ -192,6 +192,7 @@ private FormDescription createDetailsViewForElement() { pageCore.getGroups().add(this.createExtraTransitionSourceTargetPropertiesGroup()); pageCore.getGroups().add(this.createFeatureValuePropertiesGroup()); pageCore.getGroups().add(this.createExpressionPropertiesGroup()); + pageCore.getGroups().add(this.createResultExpressionPropertiesGroup()); PageDescription pageAdvanced = FormFactory.eINSTANCE.createPageDescription(); pageAdvanced.setName("SysON-DetailsView-Advanced"); @@ -243,7 +244,7 @@ private GroupDescription createFeatureValuePropertiesGroup() { TextAreaDescription expressionWidget = FormFactory.eINSTANCE.createTextAreaDescription(); expressionWidget.setName("ValueExpression"); - expressionWidget.setLabelExpression("Value"); + expressionWidget.setLabelExpression(CUSTOM_EXPRESSION_WIDGET_KEY); expressionWidget.setValueExpression(ServiceMethod.of0(DetailsViewService::getValueExpressionTextualRepresentation).aqlSelf()); expressionWidget.setIsEnabledExpression(AQLConstants.AQL_FALSE); @@ -252,6 +253,29 @@ private GroupDescription createFeatureValuePropertiesGroup() { return group; } + /** + * Creates a group to display the value of a ResultExpression. + * + * @return a {@link GroupDescription} + */ + private GroupDescription createResultExpressionPropertiesGroup() { + GroupDescription group = FormFactory.eINSTANCE.createGroupDescription(); + group.setDisplayMode(GroupDisplayMode.LIST); + group.setName("Result"); + group.setLabelExpression(""); + group.setSemanticCandidatesExpression(ServiceMethod.of0(DetailsViewService::getResultExpression).aqlSelf()); + + TextAreaDescription expressionWidget = FormFactory.eINSTANCE.createTextAreaDescription(); + expressionWidget.setName("ResultExpression"); + expressionWidget.setLabelExpression(CUSTOM_EXPRESSION_WIDGET_KEY); + expressionWidget.setValueExpression(ServiceMethod.of0(DetailsViewService::getResultExpressionTextualRepresentation).aqlSelf()); + expressionWidget.setIsEnabledExpression(AQLConstants.AQL_FALSE); + + group.getChildren().add(expressionWidget); + + return group; + } + private GroupDescription createCorePropertiesGroup() { GroupDescription group = FormFactory.eINSTANCE.createGroupDescription(); group.setDisplayMode(GroupDisplayMode.LIST); diff --git a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/expressions/services/ExpressionTextualRepresentationEventHandler.java b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/expressions/services/ExpressionTextualRepresentationEventHandler.java index 63ece7f61..ec8fe45fe 100644 --- a/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/expressions/services/ExpressionTextualRepresentationEventHandler.java +++ b/backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/expressions/services/ExpressionTextualRepresentationEventHandler.java @@ -23,6 +23,7 @@ import org.eclipse.sirius.components.core.api.IPayload; import org.eclipse.syson.application.expressions.dto.ExpressionTextualRepresentationInput; import org.eclipse.syson.application.expressions.dto.ExpressionTextualRepresentationPayload; +import org.eclipse.syson.sysml.Element; import org.eclipse.syson.sysml.Expression; import org.eclipse.syson.sysml.metamodel.services.MetamodelQueryElementService; import org.springframework.stereotype.Service; @@ -55,14 +56,38 @@ public boolean canHandle(IEditingContext editingContext, IInput input) { public void handle(Sinks.One payloadSink, Sinks.Many changeDescriptionSink, IEditingContext editingContext, IInput input) { String textualRepresentation = ""; if (input instanceof ExpressionTextualRepresentationInput expressionTextualRepresentationInput) { - Optional optionalExpression = this.objectSearchService.getObject(editingContext, expressionTextualRepresentationInput.elementId()) - .filter(Expression.class::isInstance) - .map(Expression.class::cast) - .filter(this.metamodelQueryElementService::isTopLevelExpression); + String elementId = expressionTextualRepresentationInput.elementId(); + Optional optionalExpression = this.getExpression(editingContext, elementId); if (optionalExpression.isPresent()) { textualRepresentation = this.metamodelQueryElementService.getExpressionTextualRepresentation(optionalExpression.get()); } } payloadSink.tryEmitValue(new ExpressionTextualRepresentationPayload(input.id(), textualRepresentation)); } + + /** + * Finds the {@link Expression} element to consider given the provided {@code elementId}. + * + * @param editingContext + * the editing context. + * @param elementId + * either to id of an actual {@link Expression} element, or of the parent {@link Element} of a single + * {@code Expression}. + * @return the directly of indirectly designated {@link Expression}. + */ + private Optional getExpression(IEditingContext editingContext, String elementId) { + Optional result = Optional.empty(); + Optional optionalElement = this.objectSearchService.getObject(editingContext, elementId) + .filter(Element.class::isInstance) + .map(Element.class::cast); + if (optionalElement.isPresent()) { + Element element = optionalElement.get(); + if (element instanceof Expression expression && this.metamodelQueryElementService.isTopLevelExpression(expression)) { + result = optionalElement.map(Expression.class::cast); + } else { + result = this.metamodelQueryElementService.findSingleExpressionDefinition(element); + } + } + return result; + } } diff --git a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/expressions/ExpressionsControllersIntegrationTests.java b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/expressions/ExpressionsControllersIntegrationTests.java index a63ae0383..c1441dbd6 100644 --- a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/expressions/ExpressionsControllersIntegrationTests.java +++ b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/expressions/ExpressionsControllersIntegrationTests.java @@ -553,18 +553,21 @@ public void topLevelExpressionTextualRepresentation() { treeId.set(tree.getId()); }); - // The Tank part and its attribute are not themselves expressions => "" + // The Tank part is not an expression => "" var checkTank = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.TANK_ID, ""); - var checkTankAttribute = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.TANK_MAX_VOLUME_ATTRIBUTE_ID, ""); + // The Tank's attribute is not an expression itself either, but it owns a single, non-ambiguous expression to + // can act as a "shortcut" to interact with id. + var checkTankAttribute = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.TANK_MAX_VOLUME_ATTRIBUTE_ID, "100.0 * minVolume"); // The actual attribute default value expression however should be correctly represented var checkTankAttributeValueExpression = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.TANK_MAX_VOLUME_ATTRIBUTE_VALUE_ID, "100.0 * minVolume"); var checkPerformanceConcern = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.PERFORMANCE_CONCERN_ID, ""); // A ConstaintUsage *is* an Expression from the point of view of SysML's type hierarchy, but not a top-level - // Expression, so we expect "" here. + // Expression. However if it contains a single expression, it an act as a "shortcut" to it. var checkPerformanceConcernAssumeConstraint = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.PERFORMANCE_CONCERN_ASSUME_ID, ""); - var checkPerformanceConcernRequireConstraint = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.PERFORMANCE_CONCERN_REQUIRE_ID, ""); + var checkPerformanceConcernRequireConstraint = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.PERFORMANCE_CONCERN_REQUIRE_ID, + "s.samplingRate >= 50.0 & s.currentValue != 0.0 | s.errorCount == 0"); // require s.samplingRate >= 50.0 & s.currentValue != 0.0 | s.errorCount == 0 var checkPerformanceConcernRequireConstraintExpression = this.checkExpressiontTextualRepresentation(editingContextId, ExpressionSamplesProjectData.SemanticIds.PERFORMANCE_CONCERN_REQUIRE_EXPRESSION_ID, "s.samplingRate >= 50.0 & s.currentValue != 0.0 | s.errorCount == 0"); diff --git a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/dto/EditExpressionInput.java b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/dto/EditExpressionInput.java index dac6921c0..ca0d50bda 100644 --- a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/dto/EditExpressionInput.java +++ b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/dto/EditExpressionInput.java @@ -21,5 +21,5 @@ * * @author pcdavid */ -public record EditExpressionInput(UUID id, String editingContextId, String expressionElementId, String newExpressionText) implements IInput { +public record EditExpressionInput(UUID id, String editingContextId, String elementId, String newExpressionText) implements IInput { } diff --git a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/services/EditExpressionEventHandler.java b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/services/EditExpressionEventHandler.java index 02d6077ab..2c11c5214 100644 --- a/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/services/EditExpressionEventHandler.java +++ b/backend/application/syson-sysml-import/src/main/java/org/eclipse/syson/sysml/services/EditExpressionEventHandler.java @@ -31,6 +31,7 @@ import org.eclipse.syson.sysml.Expression; import org.eclipse.syson.sysml.dto.EditExpressionInput; import org.eclipse.syson.sysml.dto.EditExpressionSuccessPayload; +import org.eclipse.syson.sysml.metamodel.services.MetamodelQueryElementService; import org.eclipse.syson.sysml.services.api.ISysMLExpressionEditor; import org.springframework.stereotype.Service; @@ -54,6 +55,8 @@ public class EditExpressionEventHandler implements IEditingContextEventHandler { private final ISysMLExpressionEditor expressionEditor; + private final MetamodelQueryElementService metamodelQueryElementService; + private final Counter counter; public EditExpressionEventHandler(IObjectSearchService objectSearchService, IIdentityService identityService, ICollaborativeMessageService messageService, ISysMLExpressionEditor expressionEditor, @@ -62,6 +65,7 @@ public EditExpressionEventHandler(IObjectSearchService objectSearchService, IIde this.identityService = Objects.requireNonNull(identityService); this.messageService = Objects.requireNonNull(messageService); this.expressionEditor = Objects.requireNonNull(expressionEditor); + this.metamodelQueryElementService = new MetamodelQueryElementService(); this.counter = Counter.builder(Monitoring.EVENT_HANDLER) .tag(Monitoring.NAME, this.getClass().getSimpleName()) .register(meterRegistry); @@ -79,13 +83,8 @@ public void handle(Sinks.One payloadSink, Sinks.Many optionalExpression = this.objectSearchService.getObject(editingContext, editExpressionInput.expressionElementId()) - .filter(Expression.class::isInstance) - .map(Expression.class::cast); - Optional optionalParent = Optional.empty(); - if (optionalExpression.isPresent()) { - optionalParent = Optional.ofNullable(optionalExpression.get().getOwner()); - } + var optionalParent = this.getExpressionParent(emfEditingContext, editExpressionInput.elementId()); + var optionalExpression = this.getExpression(emfEditingContext, editExpressionInput.elementId()); if (optionalParent.isPresent() && optionalExpression.isPresent()) { var result = this.expressionEditor.editExpression(emfEditingContext, optionalParent.get(), optionalExpression.get(), editExpressionInput.newExpressionText()); @@ -108,4 +107,57 @@ public void handle(Sinks.One payloadSink, Sinks.Many getExpression(IEditingContext editingContext, String elementId) { + Optional result = Optional.empty(); + Optional optionalElement = this.objectSearchService.getObject(editingContext, elementId) + .filter(Element.class::isInstance) + .map(Element.class::cast); + if (optionalElement.isPresent()) { + Element element = optionalElement.get(); + if (element instanceof Expression expression && this.metamodelQueryElementService.isTopLevelExpression(expression)) { + result = optionalElement.map(Expression.class::cast); + } else { + result = this.metamodelQueryElementService.findSingleExpressionDefinition(element); + } + } + return result; + } + + /** + * Finds the {@link Expression} element to consider given the provided {@code elementId}. + * + * @param editingContext + * the editing context. + * @param elementId + * either to id of an actual {@link Expression} element, or of the parent {@link Element} of a single + * {@code Expression}. + * @return the directly of indirectly designated {@link Expression}. + */ + private Optional getExpressionParent(IEditingContext editingContext, String elementId) { + Optional result = Optional.empty(); + + Optional optionalElement = this.objectSearchService.getObject(editingContext, elementId) + .filter(Element.class::isInstance) + .map(Element.class::cast); + if (optionalElement.isPresent()) { + Element element = optionalElement.get(); + if (element instanceof Expression expression && this.metamodelQueryElementService.isTopLevelExpression(expression)) { + result = optionalElement.map(Element::getOwner); + } else { + result = optionalElement; + } + } + return result; + } } diff --git a/backend/application/syson-sysml-import/src/main/resources/schema/syson-import.graphqls b/backend/application/syson-sysml-import/src/main/resources/schema/syson-import.graphqls index a2df45eca..3eb3b4ada 100644 --- a/backend/application/syson-sysml-import/src/main/resources/schema/syson-import.graphqls +++ b/backend/application/syson-sysml-import/src/main/resources/schema/syson-import.graphqls @@ -34,7 +34,7 @@ type CreateExpressionSuccessPayload { input EditExpressionInput { id: ID! editingContextId: ID! - expressionElementId: ID! + elementId: ID! newExpressionText: String! } diff --git a/backend/views/syson-tree-explorer-view/src/main/java/org/eclipse/syson/tree/explorer/view/menu/context/SysONExplorerTreeItemContextMenuEntryProvider.java b/backend/views/syson-tree-explorer-view/src/main/java/org/eclipse/syson/tree/explorer/view/menu/context/SysONExplorerTreeItemContextMenuEntryProvider.java index 9e4dee378..65ef1f374 100644 --- a/backend/views/syson-tree-explorer-view/src/main/java/org/eclipse/syson/tree/explorer/view/menu/context/SysONExplorerTreeItemContextMenuEntryProvider.java +++ b/backend/views/syson-tree-explorer-view/src/main/java/org/eclipse/syson/tree/explorer/view/menu/context/SysONExplorerTreeItemContextMenuEntryProvider.java @@ -192,7 +192,8 @@ private void addExpressionEditionEntries(List entries expressionEntries.add(EDIT_EXPRESSION_MENU_ENTRY_CONTRIBUTION_ID); } else if (this.metamodelQueryElementService.hasSingleExpressionDefinition(element) && !this.metamodelQueryElementService.hasSingleExpressionDefinition(element.getOwner())) { - // "Delete expression" on the owner of a root Expression element + // "Edit expression" and "Delete expression" on the owner of a root Expression element + expressionEntries.add(EDIT_EXPRESSION_MENU_ENTRY_CONTRIBUTION_ID); expressionEntries.add(DELETE_EXPRESSION_MENU_ENTRY_CONTRIBUTION_ID); } diff --git a/doc/content/modules/user-manual/pages/features/expressions.adoc b/doc/content/modules/user-manual/pages/features/expressions.adoc index ca3724d25..8d9e3c19e 100644 --- a/doc/content/modules/user-manual/pages/features/expressions.adoc +++ b/doc/content/modules/user-manual/pages/features/expressions.adoc @@ -19,7 +19,7 @@ a|image::explorer-expression-internals-hidden.png[Internals hidden (default)] a|image::explorer-expression-internals-visible.png[Internals visible] |=== -When an `Expression` element is selected(for example from the {explorer} view), the {details}} view displays its textual representation, with a button to open the expression edition modal (see below) directly on it: +When an `Expression` element or an `Element` which contains a single `Expression` element is selected (for example from the {explorer} view), the {details}} view displays the textual representation of the expression, with a button to open the expression edition modal (see below) directly on it: + image::expression-details.png[Expression value displayed in the _Details_ veiw, width=80%] @@ -39,7 +39,7 @@ image::edit-expression-modal-error.png[Edit expression modal showing an error me == Edition -To edit an already existing expression, invoke the _Edit expression_ context menu action directly on the existing expression. +To edit an already existing expression, invoke the _Edit expression_ context menu action directly on the existing expression or on its parent element. The same modal as for expression creation will open, but with the current textual representation of the expression pre-filled. Edit the textual representation of the expression as required, and click on the _Update_ button to validate. diff --git a/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc b/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc index b94323cd7..5f83f66a1 100644 --- a/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc +++ b/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc @@ -59,13 +59,13 @@ Fix any error reported before clicking on _Update_ again (or canceling the opera image::edit-expression-modal.png[Edit expression modal, width=80%] image::edit-expression-modal-error.png[Edit expression modal showing an error message if the new expression is invalid, width=80%] + -To _edit_ an existing expression, simply invoke the _Edit expression_ context menu action directly on the existing expression; the same modal will open but with the current textual representation of the expression pre-filled. +To _edit_ an existing expression, simply invoke the _Edit expression_ context menu action directly on the existing expression or on its parent element; the same modal will open but with the current textual representation of the expression pre-filled. + To _delete_ an existing expression, you can simply invoke the normal _Delete_ menu item action on the expression itself or the new _Delete expression_ on its parent element. * In the _Details_ view: -** When an `Expression` element is selected (for example from the _Explorer_ view), the _Details_ view displays its textual representation, with a button to open the expression edition modal (see above) directly on it: +** When an `Expression` element or an `Element` which contains a single `Expression` element is selected (for example from the _Explorer_ view), the _Details_ view displays the textual representation of the `Expression`, with a button to open the expression edition modal (see above) directly on it: + image::expression-details.png[Expression value displayed in the _Details_ veiw, width=80%] diff --git a/frontend/syson-components/src/extensions/expressions/useEditExpression.ts b/frontend/syson-components/src/extensions/expressions/useEditExpression.ts index 32d72890b..6cc80e48b 100644 --- a/frontend/syson-components/src/extensions/expressions/useEditExpression.ts +++ b/frontend/syson-components/src/extensions/expressions/useEditExpression.ts @@ -52,11 +52,11 @@ export const useEditExpression = (): UseEditExpressionValue => { GQLEditExpressionVariables >(editExpressionMutation); - const editExpression = (editingContextId: string, expressionElementId: string, newExpressionText: string) => { + const editExpression = (editingContextId: string, elementId: string, newExpressionText: string) => { const input: GQLEditExpressionInput = { id: crypto.randomUUID(), editingContextId, - expressionElementId, + elementId: elementId, newExpressionText, }; diff --git a/frontend/syson-components/src/extensions/expressions/useEditExpression.types.ts b/frontend/syson-components/src/extensions/expressions/useEditExpression.types.ts index 448b57a2d..a7fbd4be3 100644 --- a/frontend/syson-components/src/extensions/expressions/useEditExpression.types.ts +++ b/frontend/syson-components/src/extensions/expressions/useEditExpression.types.ts @@ -27,7 +27,7 @@ export interface GQLEditExpressionVariables { export interface GQLEditExpressionInput { id: string; editingContextId: string; - expressionElementId: string; + elementId: string; newExpressionText: string; } From 6e8a95c5806f45a259d4b6787fcf1560039ac252 Mon Sep 17 00:00:00 2001 From: Pierre-Charles David Date: Thu, 4 Jun 2026 09:43:14 +0200 Subject: [PATCH 3/3] [enh] Improve the expression modal UX - Make sure it gets the keyboard focus on open so that the user can start typing immediatly. - Add support for Ctrl-RET to apply/update directly from the keyboard. Signed-off-by: Pierre-Charles David --- .../pages/features/expressions.adoc | 2 +- .../pages/release-notes/2026.7.0.adoc | 2 +- .../expressions/EditSysMLExpressionModal.tsx | 23 ++++++++++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/doc/content/modules/user-manual/pages/features/expressions.adoc b/doc/content/modules/user-manual/pages/features/expressions.adoc index 8d9e3c19e..b4cb3b750 100644 --- a/doc/content/modules/user-manual/pages/features/expressions.adoc +++ b/doc/content/modules/user-manual/pages/features/expressions.adoc @@ -42,7 +42,7 @@ image::edit-expression-modal-error.png[Edit expression modal showing an error me To edit an already existing expression, invoke the _Edit expression_ context menu action directly on the existing expression or on its parent element. The same modal as for expression creation will open, but with the current textual representation of the expression pre-filled. -Edit the textual representation of the expression as required, and click on the _Update_ button to validate. +Edit the textual representation of the expression as required, and click on the _Update_ button or hit _Ctrl-RET_ to validate. As for expression creation, the change will only be applied if there are no errors detected; otherwise the modal will display any errors (e.g. names used in the expression that can not be resolve to existing elements) so that you can fix the input. diff --git a/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc b/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc index 5f83f66a1..f6fec0724 100644 --- a/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc +++ b/doc/content/modules/user-manual/pages/release-notes/2026.7.0.adoc @@ -51,7 +51,7 @@ In both cases, to display the `FramedConcernMembership`, deactivate the `Hide Me ** It is now possible to create, edit and delete _Expressions_ using their textual syntax from the _Explorer_ view. To _create_ an expression, invoke the _New expression_ context menu action on a compatible element (supported elements are `Attributes`, `Constraints` and `Transitions`). A modal will open where you can enter the textual representation of the expression to create. -Click on the _Update_ button to validate. +Click on the _Update_ button or hit _Ctrl-RET_ to validate. If the entered expression is valid, it will be created and the modal will automatically close. If the entered expression is _not_ valid, the modal will remain open and show the error(s) in an expandable accordion. Fix any error reported before clicking on _Update_ again (or canceling the operation). diff --git a/frontend/syson-components/src/extensions/expressions/EditSysMLExpressionModal.tsx b/frontend/syson-components/src/extensions/expressions/EditSysMLExpressionModal.tsx index 544e1454d..b176008da 100644 --- a/frontend/syson-components/src/extensions/expressions/EditSysMLExpressionModal.tsx +++ b/frontend/syson-components/src/extensions/expressions/EditSysMLExpressionModal.tsx @@ -28,7 +28,7 @@ import InputAdornment from '@mui/material/InputAdornment'; import { Theme } from '@mui/material/styles'; import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { makeStyles } from 'tss-react/mui'; import { EditSysMLExpressionModalProps, EditSysMLExpressionModalState } from './EditSysMLExpressionModal.types'; import { useCreateExpression } from './useCreateExpression'; @@ -96,6 +96,8 @@ export const EditSysMLExpressionModal = ({ const validationStatus = computeValidationStatus(state.validationResult); const busy = state.operationInProgress !== null; + const inputRef = useRef(null); + const { textualRepresentation, loading } = useExpressionTextualRepresentation(editingContextId, elementId); useEffect(() => { if (loading) { @@ -110,12 +112,21 @@ export const EditSysMLExpressionModal = ({ } }, [textualRepresentation, loading]); + const fieldReady = !busy && state.textualContent !== null; + useEffect(() => { + if (fieldReady) { + const timeoutId = window.setTimeout(() => inputRef.current?.focus()); + return () => window.clearTimeout(timeoutId); + } + return undefined; + }, [fieldReady]); + const { createExpression, loading: creationInProgress, messages: postCreationMessages } = useCreateExpression(); const { editExpression, loading: editionInProgress, messages: postEditionMessages } = useEditExpression(); const { deleteExpression } = useDeleteExpression(); - const onUpdate = (event: React.MouseEvent) => { - event.preventDefault(); + const onUpdate = (event: React.MouseEvent | null) => { + event?.preventDefault(); if (state.textualContent !== null) { if (mode === 'create' && state.textualContent.trim() !== '') { setState((prevState) => ({ ...prevState, operationInProgress: 'creating' })); @@ -169,6 +180,7 @@ export const EditSysMLExpressionModal = ({ id="edit-sysml-expression-modal-textarea" data-testid="edit-sysml-expression-modal-textarea" disabled={busy || state.textualContent === null} + inputRef={inputRef} className={classes.textarea} autoFocus multiline @@ -180,6 +192,11 @@ export const EditSysMLExpressionModal = ({ onChange={(event) => setState((prevState) => ({ ...prevState, textualContent: event.target.value, validationResult: null })) } + onKeyUp={(event) => { + if (event.ctrlKey && event.key === 'Enter') { + onUpdate(null); + } + }} slotProps={{ input: { endAdornment: ,