From 92b4de2ff36a3535e50d97bcf86433950ab0b581 Mon Sep 17 00:00:00 2001 From: Pierre-Charles David Date: Tue, 2 May 2023 16:48:06 +0200 Subject: [PATCH] [1914] Add support for custom widgets Bug: https://github.com/eclipse-sirius/sirius-components/issues/1914 Signed-off-by: Pierre-Charles David --- CHANGELOG.adoc | 2 + .../properties/FormRendererTests.java | 4 +- ...ionEventProcessorFactoryConfiguration.java | 60 +++++++++++++++++ .../DiagramEventProcessorFactory.java | 14 ++-- .../FormDescriptionEditorCreationService.java | 14 +++- ...escriptionEditorEventProcessorFactory.java | 17 +++-- .../handlers/AddWidgetEventHandler.java | 25 +++++-- .../handlers/AddWidgetEventHandlerTests.java | 3 +- .../IWidgetDescriptionProvider.java | 26 ++++++++ .../IWidgetPreviewConverterProvider.java | 27 ++++++++ .../FormDescriptionEditorComponent.java | 7 +- .../FormDescriptionEditorComponentProps.java | 21 +++++- .../FormDescriptionEditorGroupComponent.java | 15 ++++- ...mDescriptionEditorGroupComponentProps.java | 21 +++++- .../FormDescriptionEditorPageComponent.java | 2 +- ...rmDescriptionEditorPageComponentProps.java | 9 ++- ...wFormDescriptionEditorConverterSwitch.java | 14 +++- ...criptionEditorComponentPropsValidator.java | 7 +- .../FormDescriptionEditorElementFactory.java | 5 +- ...scriptionEditorInstancePropsValidator.java | 9 ++- .../FormDescriptionEditorRenderer.java | 8 ++- ...DescriptionEditorConverterSwitchTests.java | 4 +- .../src/CustomWidget.tsx | 66 +++++++++++++++++++ .../src/CustomWidget.types.ts | 17 +++++ .../src/FlexboxContainerWidget.tsx | 10 +-- .../src/FormDescriptionEditorEventFragment.ts | 8 +-- .../FormDescriptionEditorRepresentation.tsx | 31 +++++++-- .../src/Group.tsx | 9 +-- .../src/ToolbarActionWidget.tsx | 8 ++- .../src/ToolbarActions.tsx | 4 +- .../src/WidgetEntry.tsx | 35 +++++++++- .../src/WidgetEntry.types.ts | 2 +- .../src/index.ts | 3 +- .../forms/FormEventProcessor.java | 20 +++--- .../forms/FormEventProcessorFactory.java | 24 ++++--- .../PropertiesEventProcessorFactory.java | 17 +++-- .../RelatedElementsEventProcessorFactory.java | 18 +++-- .../RepresentationsEventProcessorFactory.java | 4 +- .../forms/FormEventProcessorTests.java | 6 +- .../components/FlexboxContainerComponent.java | 4 +- .../FlexboxContainerComponentProps.java | 14 +++- .../forms/components/ForComponent.java | 4 +- .../forms/components/ForComponentProps.java | 14 +++- .../forms/components/FormComponent.java | 2 +- .../forms/components/FormComponentProps.java | 13 +++- .../forms/components/GroupComponent.java | 8 ++- .../forms/components/GroupComponentProps.java | 13 +++- .../forms/components/IfComponent.java | 4 +- .../forms/components/IfComponentProps.java | 14 +++- .../forms/components/PageComponent.java | 2 +- .../forms/components/PageComponentProps.java | 13 +++- .../forms/components/WidgetComponent.java | 18 +++-- .../components/WidgetComponentProps.java | 13 +++- .../renderer/FormComponentPropsValidator.java | 18 ++++- .../forms/renderer/FormElementFactory.java | 55 ++++++++++------ .../renderer/FormInstancePropsValidator.java | 17 ++++- .../forms/renderer/FormRenderer.java | 7 +- .../forms/renderer/IWidgetDescriptor.java | 41 ++++++++++++ .../forms/render/RenderTextfieldTest.java | 4 +- .../src/form/Form.types.ts | 22 ++++++- .../src/form/FormContext.ts | 30 +++++++++ .../src/form/FormContext.types.ts | 31 +++++++++ .../src/form/FormEventFragments.ts | 32 +++++++-- .../sirius-components-forms/src/index.ts | 8 ++- .../src/propertysections/PropertySection.tsx | 22 ++++++- .../representations/FormRepresentation.tsx | 60 +++++++++-------- .../src/views/FormBasedView.tsx | 22 ++++--- .../src/views/RepresentationsView.tsx | 62 +++++++++-------- .../SelectionEventProcessorFactory.java | 15 ++--- .../ViewDetailsRenderingIntegrationTests.java | 4 +- .../emf/form/IWidgetConverterProvider.java | 28 ++++++++ .../form/ViewFormDescriptionConverter.java | 20 ++++-- .../ViewFormDescriptionConverterSwitch.java | 12 +++- .../view/emf/view/DynamicFormsTests.java | 6 +- 74 files changed, 979 insertions(+), 269 deletions(-) create mode 100644 packages/core/backend/sirius-components-collaborative/src/main/java/org/eclipse/sirius/components/collaborative/api/RepresentationEventProcessorFactoryConfiguration.java create mode 100644 packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/IWidgetDescriptionProvider.java create mode 100644 packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/IWidgetPreviewConverterProvider.java create mode 100644 packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/CustomWidget.tsx create mode 100644 packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/CustomWidget.types.ts create mode 100644 packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/IWidgetDescriptor.java create mode 100644 packages/forms/frontend/sirius-components-forms/src/form/FormContext.ts create mode 100644 packages/forms/frontend/sirius-components-forms/src/form/FormContext.types.ts create mode 100644 packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/IWidgetConverterProvider.java diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 33861daebf..3d011f877d 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -69,6 +69,8 @@ All visible tree items containing the value typed in the filter bar will be high The filter button inside the filter bar allows to filter (hide) all visible tree items not containing the value typed in the filter bar. + image:doc/screenshots/filterBarFilterButton.png[Filter Bar Filter Button,30%,30%] +- https://github.com/eclipse-sirius/sirius-components/issues/1914[#1914] [form] It is now possible for applications to provide their own custom widgets without forking Sirius Components. +See link:how-to/contribute-custom-widget.adoc[the documentation] for more details. - https://github.com/eclipse-sirius/sirius-components/issues/1830[#1830] [layout] This feature is experimental and can be activated on a diagram by adding "__EXPERIMENTAL" to its name. The new algorithm does the minimum possible to place node without overlap. - https://github.com/eclipse-sirius/sirius-components/issues/1985[|#1985] [sirius-web] It is now possible to use in-memory View-based representations by registering them in the new `InMemoryViewRegistry`. diff --git a/packages/compatibility/backend/sirius-components-compatibility-emf/src/test/java/org/eclipse/sirius/components/compatibility/emf/compatibility/properties/FormRendererTests.java b/packages/compatibility/backend/sirius-components-compatibility-emf/src/test/java/org/eclipse/sirius/components/compatibility/emf/compatibility/properties/FormRendererTests.java index 00af8f873e..cc6a02d8cf 100644 --- a/packages/compatibility/backend/sirius-components-compatibility-emf/src/test/java/org/eclipse/sirius/components/compatibility/emf/compatibility/properties/FormRendererTests.java +++ b/packages/compatibility/backend/sirius-components-compatibility-emf/src/test/java/org/eclipse/sirius/components/compatibility/emf/compatibility/properties/FormRendererTests.java @@ -237,8 +237,8 @@ private void checkResult(FormDescription description) { VariableManager variableManager = new VariableManager(); variableManager.put(VariableManager.SELF, List.of(EcorePackage.eINSTANCE)); - FormRenderer formRenderer = new FormRenderer(); - FormComponentProps props = new FormComponentProps(variableManager, description); + FormRenderer formRenderer = new FormRenderer(List.of()); + FormComponentProps props = new FormComponentProps(variableManager, description, List.of()); Element element = new Element(FormComponent.class, props); Form form = formRenderer.render(element); diff --git a/packages/core/backend/sirius-components-collaborative/src/main/java/org/eclipse/sirius/components/collaborative/api/RepresentationEventProcessorFactoryConfiguration.java b/packages/core/backend/sirius-components-collaborative/src/main/java/org/eclipse/sirius/components/collaborative/api/RepresentationEventProcessorFactoryConfiguration.java new file mode 100644 index 0000000000..8299bdfe7d --- /dev/null +++ b/packages/core/backend/sirius-components-collaborative/src/main/java/org/eclipse/sirius/components/collaborative/api/RepresentationEventProcessorFactoryConfiguration.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2023 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.collaborative.api; + +import java.util.Objects; + +import org.eclipse.sirius.components.core.api.IRepresentationDescriptionSearchService; +import org.springframework.stereotype.Service; + +/** + * Bundles the common dependencies that most {@link IRepresentationEventProcessorFactory} implementations need into a + * single object for convenience. + * + * @author pcdavid + */ +@Service +public class RepresentationEventProcessorFactoryConfiguration { + + private final IRepresentationDescriptionSearchService representationDescriptionSearchService; + + private final IRepresentationSearchService representationSearchService; + + private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; + + private final ISubscriptionManagerFactory subscriptionManagerFactory; + + public RepresentationEventProcessorFactoryConfiguration(IRepresentationDescriptionSearchService representationDescriptionSearchService, IRepresentationSearchService representationSearchService, + IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry, ISubscriptionManagerFactory subscriptionManagerFactory) { + this.representationDescriptionSearchService = Objects.requireNonNull(representationDescriptionSearchService); + this.representationSearchService = Objects.requireNonNull(representationSearchService); + this.representationRefreshPolicyRegistry = Objects.requireNonNull(representationRefreshPolicyRegistry); + this.subscriptionManagerFactory = Objects.requireNonNull(subscriptionManagerFactory); + } + + public IRepresentationDescriptionSearchService getRepresentationDescriptionSearchService() { + return this.representationDescriptionSearchService; + } + + public IRepresentationSearchService getRepresentationSearchService() { + return this.representationSearchService; + } + + public IRepresentationRefreshPolicyRegistry getRepresentationRefreshPolicyRegistry() { + return this.representationRefreshPolicyRegistry; + } + + public ISubscriptionManagerFactory getSubscriptionManagerFactory() { + return this.subscriptionManagerFactory; + } +} diff --git a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/DiagramEventProcessorFactory.java b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/DiagramEventProcessorFactory.java index 76e7f94392..d2fd681a13 100644 --- a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/DiagramEventProcessorFactory.java +++ b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/DiagramEventProcessorFactory.java @@ -23,6 +23,7 @@ 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.diagrams.api.DiagramConfiguration; import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramCreationService; import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramEventHandler; @@ -54,16 +55,15 @@ public class DiagramEventProcessorFactory implements IRepresentationEventProcess private final IRepresentationPersistenceService representationPersistenceService; - public DiagramEventProcessorFactory(IRepresentationSearchService representationSearchService, IDiagramCreationService diagramCreationService, List diagramEventHandlers, - ISubscriptionManagerFactory subscriptionManagerFactory, IRepresentationDescriptionSearchService representationDescriptionSearchService, - IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry, IRepresentationPersistenceService representationPersistenceService) { - this.representationSearchService = Objects.requireNonNull(representationSearchService); + public DiagramEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, IDiagramCreationService diagramCreationService, + List diagramEventHandlers, IRepresentationPersistenceService representationPersistenceService) { + this.representationSearchService = Objects.requireNonNull(configuration.getRepresentationSearchService()); this.diagramCreationService = Objects.requireNonNull(diagramCreationService); this.diagramEventHandlers = Objects.requireNonNull(diagramEventHandlers); - this.subscriptionManagerFactory = Objects.requireNonNull(subscriptionManagerFactory); - this.representationDescriptionSearchService = Objects.requireNonNull(representationDescriptionSearchService); - this.representationRefreshPolicyRegistry = Objects.requireNonNull(representationRefreshPolicyRegistry); this.representationPersistenceService = Objects.requireNonNull(representationPersistenceService); + this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory()); + this.representationDescriptionSearchService = Objects.requireNonNull(configuration.getRepresentationDescriptionSearchService()); + this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry()); } @Override diff --git a/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/FormDescriptionEditorCreationService.java b/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/FormDescriptionEditorCreationService.java index 6ec0448a3a..49eec18e3e 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/FormDescriptionEditorCreationService.java +++ b/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/FormDescriptionEditorCreationService.java @@ -27,10 +27,12 @@ import org.eclipse.sirius.components.core.api.IObjectService; import org.eclipse.sirius.components.core.api.IRepresentationDescriptionSearchService; import org.eclipse.sirius.components.formdescriptioneditors.FormDescriptionEditor; +import org.eclipse.sirius.components.formdescriptioneditors.IWidgetPreviewConverterProvider; import org.eclipse.sirius.components.formdescriptioneditors.components.FormDescriptionEditorComponent; import org.eclipse.sirius.components.formdescriptioneditors.components.FormDescriptionEditorComponentProps; import org.eclipse.sirius.components.formdescriptioneditors.description.FormDescriptionEditorDescription; import org.eclipse.sirius.components.formdescriptioneditors.renderer.FormDescriptionEditorRenderer; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.Element; import org.eclipse.sirius.components.representations.VariableManager; import org.springframework.stereotype.Service; @@ -52,13 +54,19 @@ public class FormDescriptionEditorCreationService implements IFormDescriptionEdi private final IObjectService objectService; + private final List widgetDescriptors; + + private final List customWidgetConverterProviders; + private final Timer timer; public FormDescriptionEditorCreationService(IRepresentationDescriptionSearchService representationDescriptionSearchService, IRepresentationPersistenceService representationPersistenceService, - IObjectService objectService, MeterRegistry meterRegistry) { + IObjectService objectService, List widgetDescriptors, List customWidgetConverterProviders, MeterRegistry meterRegistry) { this.representationDescriptionSearchService = Objects.requireNonNull(representationDescriptionSearchService); this.representationPersistenceService = Objects.requireNonNull(representationPersistenceService); this.objectService = Objects.requireNonNull(objectService); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); + this.customWidgetConverterProviders = Objects.requireNonNull(customWidgetConverterProviders); this.timer = Timer.builder(Monitoring.REPRESENTATION_EVENT_PROCESSOR_REFRESH) .tag(Monitoring.NAME, "formdescriptioneditor") @@ -109,10 +117,10 @@ private FormDescriptionEditor doRender(String label, Object targetObject, IEditi Optional optionalPreviousFormDescriptionEditor = optionalFormDescriptionEditorContext.map(IFormDescriptionEditorContext::getFormDescriptionEditor); - var formDescriptionEditorComponentProps = new FormDescriptionEditorComponentProps(variableManager, formDescriptionEditorDescription, optionalPreviousFormDescriptionEditor); + var formDescriptionEditorComponentProps = new FormDescriptionEditorComponentProps(variableManager, formDescriptionEditorDescription, optionalPreviousFormDescriptionEditor, this.widgetDescriptors, this.customWidgetConverterProviders); Element element = new Element(FormDescriptionEditorComponent.class, formDescriptionEditorComponentProps); - FormDescriptionEditor newFormDescriptionEditor = new FormDescriptionEditorRenderer().render(element); + FormDescriptionEditor newFormDescriptionEditor = new FormDescriptionEditorRenderer(this.widgetDescriptors).render(element); long end = System.currentTimeMillis(); this.timer.record(end - start, TimeUnit.MILLISECONDS); diff --git a/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/FormDescriptionEditorEventProcessorFactory.java b/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/FormDescriptionEditorEventProcessorFactory.java index a95fc0bfac..57434eb2c7 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/FormDescriptionEditorEventProcessorFactory.java +++ b/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/FormDescriptionEditorEventProcessorFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo. + * Copyright (c) 2022, 2023 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 @@ -22,6 +22,7 @@ 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.formdescriptioneditors.api.FormDescriptionEditorConfiguration; import org.eclipse.sirius.components.collaborative.formdescriptioneditors.api.IFormDescriptionEditorCreationService; import org.eclipse.sirius.components.collaborative.formdescriptioneditors.api.IFormDescriptionEditorEventHandler; @@ -51,16 +52,14 @@ public class FormDescriptionEditorEventProcessorFactory implements IRepresentati private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; - public FormDescriptionEditorEventProcessorFactory(IRepresentationDescriptionSearchService representationDescriptionSearchService, - IFormDescriptionEditorCreationService formDescriptionEditormCreationService, IRepresentationSearchService representationSearchService, - List formDescriptionEditorEventHandlers, ISubscriptionManagerFactory subscriptionManagerFactory, - IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry) { - this.representationDescriptionSearchService = Objects.requireNonNull(representationDescriptionSearchService); + public FormDescriptionEditorEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, IFormDescriptionEditorCreationService formDescriptionEditormCreationService, + List formDescriptionEditorEventHandlers) { + this.representationDescriptionSearchService = Objects.requireNonNull(configuration.getRepresentationDescriptionSearchService()); this.formDescriptionEditormCreationService = Objects.requireNonNull(formDescriptionEditormCreationService); - this.representationSearchService = Objects.requireNonNull(representationSearchService); + this.representationSearchService = Objects.requireNonNull(configuration.getRepresentationSearchService()); this.formDescriptionEditorEventHandlers = Objects.requireNonNull(formDescriptionEditorEventHandlers); - this.subscriptionManagerFactory = Objects.requireNonNull(subscriptionManagerFactory); - this.representationRefreshPolicyRegistry = Objects.requireNonNull(representationRefreshPolicyRegistry); + this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory()); + this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry()); } @Override diff --git a/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/handlers/AddWidgetEventHandler.java b/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/handlers/AddWidgetEventHandler.java index 9dfe083fc1..71c987f818 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/handlers/AddWidgetEventHandler.java +++ b/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/handlers/AddWidgetEventHandler.java @@ -12,12 +12,14 @@ *******************************************************************************/ package org.eclipse.sirius.components.collaborative.formdescriptioneditors.handlers; +import java.util.List; import java.util.Objects; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.sirius.components.collaborative.api.ChangeDescription; import org.eclipse.sirius.components.collaborative.api.ChangeKind; import org.eclipse.sirius.components.collaborative.api.Monitoring; @@ -31,6 +33,7 @@ import org.eclipse.sirius.components.core.api.IObjectService; import org.eclipse.sirius.components.core.api.IPayload; import org.eclipse.sirius.components.core.api.SuccessPayload; +import org.eclipse.sirius.components.formdescriptioneditors.IWidgetDescriptionProvider; import org.eclipse.sirius.components.view.FlexDirection; import org.eclipse.sirius.components.view.FlexboxContainerDescription; import org.eclipse.sirius.components.view.GroupDescription; @@ -56,11 +59,14 @@ public class AddWidgetEventHandler implements IFormDescriptionEditorEventHandler private final ICollaborativeFormDescriptionEditorMessageService messageService; + private final List widgetDescriptionProviders; + private final Counter counter; - public AddWidgetEventHandler(IObjectService objectService, ICollaborativeFormDescriptionEditorMessageService messageService, MeterRegistry meterRegistry) { + public AddWidgetEventHandler(IObjectService objectService, ICollaborativeFormDescriptionEditorMessageService messageService, List widgetDescriptionProviders, MeterRegistry meterRegistry) { this.objectService = Objects.requireNonNull(objectService); this.messageService = Objects.requireNonNull(messageService); + this.widgetDescriptionProviders = Objects.requireNonNull(widgetDescriptionProviders); // @formatter:off this.counter = Counter.builder(Monitoring.EVENT_HANDLER) @@ -103,9 +109,9 @@ private boolean addWidget(IEditingContext editingContext, IFormDescriptionEditor var optionalSelf = this.objectService.getObject(editingContext, containerId); if (optionalSelf.isPresent()) { Object container = optionalSelf.get(); - EClassifier eClassifier = ViewPackage.eINSTANCE.getEClassifier(kind + "Description"); - if (eClassifier instanceof EClass) { - var widgetDescription = ViewFactory.eINSTANCE.create((EClass) eClassifier); + EClassifier eClassifier = this.getWidgetDescriptionType(kind); + if (eClassifier instanceof EClass eClass) { + var widgetDescription = EcoreUtil.create(eClass); if (widgetDescription instanceof FlexboxContainerDescription) { ((FlexboxContainerDescription) widgetDescription).setFlexDirection(FlexDirection.get(kind)); } @@ -124,6 +130,17 @@ private boolean addWidget(IEditingContext editingContext, IFormDescriptionEditor return success; } + + private EClassifier getWidgetDescriptionType(String kind) { + for (IWidgetDescriptionProvider widgetDescriptionProvider : this.widgetDescriptionProviders) { + var optionalType = widgetDescriptionProvider.getWidgetDescriptionType(kind); + if (optionalType.isPresent()) { + return optionalType.get(); + } + } + return ViewPackage.eINSTANCE.getEClassifier(kind + "Description"); + } + private void createStyle(WidgetDescription widgetDescription) { EStructuralFeature styleFeature = widgetDescription.eClass().getEStructuralFeature("style"); if (styleFeature instanceof EReference) { diff --git a/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/test/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/handlers/AddWidgetEventHandlerTests.java b/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/test/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/handlers/AddWidgetEventHandlerTests.java index bf0e576417..ef71b81ae5 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/test/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/handlers/AddWidgetEventHandlerTests.java +++ b/packages/formdescriptioneditors/backend/sirius-components-collaborative-formdescriptioneditors/src/test/java/org/eclipse/sirius/components/collaborative/formdescriptioneditors/handlers/AddWidgetEventHandlerTests.java @@ -14,6 +14,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.util.List; import java.util.Optional; import java.util.UUID; @@ -50,7 +51,7 @@ public Optional getObject(IEditingContext editingContext, String objectI return Optional.of(ViewFactory.eINSTANCE.createFlexboxContainerDescription()); } }; - var handler = new AddWidgetEventHandler(objectService, new ICollaborativeFormDescriptionEditorMessageService.NoOp(), new SimpleMeterRegistry()); + var handler = new AddWidgetEventHandler(objectService, new ICollaborativeFormDescriptionEditorMessageService.NoOp(), List.of(), new SimpleMeterRegistry()); var input = new AddWidgetInput(UUID.randomUUID(), "editingContextId", "representationId", "containerId", "Checkbox", 0); assertThat(handler.canHandle(input)).isTrue(); diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/IWidgetDescriptionProvider.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/IWidgetDescriptionProvider.java new file mode 100644 index 0000000000..8b070a5165 --- /dev/null +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/IWidgetDescriptionProvider.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2023 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.formdescriptioneditors; + +import java.util.Optional; + +import org.eclipse.emf.ecore.EClass; + +/** + * Provides the EClass to use to represent a given kind of widget in a Form Description Editor. + * + * @author pcdavid + */ +public interface IWidgetDescriptionProvider { + Optional getWidgetDescriptionType(String widgetKind); +} diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/IWidgetPreviewConverterProvider.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/IWidgetPreviewConverterProvider.java new file mode 100644 index 0000000000..8e8b3e709a --- /dev/null +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/IWidgetPreviewConverterProvider.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2023 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.formdescriptioneditors; + +import org.eclipse.emf.ecore.util.Switch; +import org.eclipse.sirius.components.formdescriptioneditors.description.FormDescriptionEditorDescription; +import org.eclipse.sirius.components.forms.description.AbstractWidgetDescription; +import org.eclipse.sirius.components.representations.VariableManager; + +/** + * Provides a switch to convert View-based custom widget descriptions into their API equivalent "preview widget" in a Form Description Editor. + * + * @author pcdavid + */ +public interface IWidgetPreviewConverterProvider { + Switch getWidgetConverter(FormDescriptionEditorDescription formDescriptionEditorDescription, VariableManager variableManager); +} diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorComponent.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorComponent.java index 7a9e40f03d..9608e79c61 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorComponent.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorComponent.java @@ -48,8 +48,7 @@ public Element render() { String id = optionalPreviousFormDescriptionEditor.map(FormDescriptionEditor::getId).orElseGet(() -> UUID.randomUUID().toString()); String label = optionalPreviousFormDescriptionEditor.map(FormDescriptionEditor::getLabel) - .orElseGet(() -> variableManager.get(FormDescriptionEditor.LABEL, String.class) - .orElse("Form Description Editor")); + .orElseGet(() -> variableManager.get(FormDescriptionEditor.LABEL, String.class).orElse("Form Description Editor")); Function targetObjectIdProvider = formDescriptionEditorDescription.getTargetObjectIdProvider(); String targetObjectId = targetObjectIdProvider.apply(variableManager); @@ -59,7 +58,9 @@ public Element render() { VariableManager childVariableManager = variableManager.createChild(); childVariableManager.put(VariableManager.SELF, viewPageDescription); FormDescriptionEditorPageComponentProps formDescriptionEditorPageComponentProps = new FormDescriptionEditorPageComponentProps(childVariableManager, - this.props.getFormDescriptionEditorDescription()); + this.props.getFormDescriptionEditorDescription(), + this.props.getWidgetDescriptors(), + this.props.getCustomWidgetConverterProviders()); childrenWidgets.add(new Element(FormDescriptionEditorPageComponent.class, formDescriptionEditorPageComponentProps)); }); diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorComponentProps.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorComponentProps.java index 12fe90cb27..cc6d6ac59c 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorComponentProps.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorComponentProps.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo. + * Copyright (c) 2022, 2023 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,11 +12,14 @@ *******************************************************************************/ package org.eclipse.sirius.components.formdescriptioneditors.components; +import java.util.List; import java.util.Objects; import java.util.Optional; import org.eclipse.sirius.components.formdescriptioneditors.FormDescriptionEditor; +import org.eclipse.sirius.components.formdescriptioneditors.IWidgetPreviewConverterProvider; import org.eclipse.sirius.components.formdescriptioneditors.description.FormDescriptionEditorDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IProps; import org.eclipse.sirius.components.representations.VariableManager; @@ -33,11 +36,17 @@ public class FormDescriptionEditorComponentProps implements IProps { private final Optional optionalPreviousFormDescriptionEditor; + private final List widgetDescriptors; + + private final List customWidgetConverterProviders; + public FormDescriptionEditorComponentProps(VariableManager variableManager, FormDescriptionEditorDescription formDescriptionEditorDescription, - Optional optionalPreviousFormDescriptionEditor) { + Optional optionalPreviousFormDescriptionEditor, List widgetDescriptors, List customWidgetConverterProviders) { this.variableManager = Objects.requireNonNull(variableManager); this.formDescriptionEditorDescription = Objects.requireNonNull(formDescriptionEditorDescription); this.optionalPreviousFormDescriptionEditor = Objects.requireNonNull(optionalPreviousFormDescriptionEditor); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); + this.customWidgetConverterProviders = Objects.requireNonNull(customWidgetConverterProviders); } public VariableManager getVariableManager() { @@ -51,4 +60,12 @@ public FormDescriptionEditorDescription getFormDescriptionEditorDescription() { public Optional getOptionalPreviousFormDescriptionEditor() { return this.optionalPreviousFormDescriptionEditor; } + + public List getCustomWidgetConverterProviders() { + return this.customWidgetConverterProviders; + } + + public List getWidgetDescriptors() { + return this.widgetDescriptors; + } } diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorGroupComponent.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorGroupComponent.java index 73ce1f13d0..456e93ebf4 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorGroupComponent.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorGroupComponent.java @@ -13,8 +13,11 @@ package org.eclipse.sirius.components.formdescriptioneditors.components; import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import org.eclipse.emf.ecore.util.ComposedSwitch; +import org.eclipse.emf.ecore.util.Switch; import org.eclipse.sirius.components.forms.GroupDisplayMode; import org.eclipse.sirius.components.forms.components.ToolbarActionComponent; import org.eclipse.sirius.components.forms.components.ToolbarActionComponentProps; @@ -39,11 +42,17 @@ public class FormDescriptionEditorGroupComponent implements IComponent { private final FormDescriptionEditorGroupComponentProps props; - private final ViewFormDescriptionEditorConverterSwitch converter; + private final Switch converter; public FormDescriptionEditorGroupComponent(FormDescriptionEditorGroupComponentProps props) { this.props = props; - this.converter = new ViewFormDescriptionEditorConverterSwitch(props.getFormDescriptionEditorDescription(), props.getVariableManager()); + List> widgetConverters = this.props.getCustomWidgetConverterProviders().stream() + .map(provider -> provider.getWidgetConverter(props.getFormDescriptionEditorDescription(), props.getVariableManager())) + .toList(); + Collection> switches = new ArrayList<>(); + switches.add(new ViewFormDescriptionEditorConverterSwitch(props.getFormDescriptionEditorDescription(), props.getVariableManager(), new ComposedSwitch<>(widgetConverters))); + switches.addAll(widgetConverters); + this.converter = new ComposedSwitch<>(switches); } @Override @@ -68,7 +77,7 @@ public Element render() { VariableManager childVariableManager = variableManager.createChild(); childVariableManager.put(VariableManager.SELF, viewWidgetDescription); AbstractWidgetDescription widgetDescription = this.converter.doSwitch(viewWidgetDescription); - WidgetComponentProps widgetComponentProps = new WidgetComponentProps(childVariableManager, widgetDescription); + WidgetComponentProps widgetComponentProps = new WidgetComponentProps(childVariableManager, widgetDescription, this.props.getWidgetDescriptors()); childrenWidgets.add(new Element(WidgetComponent.class, widgetComponentProps)); }); diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorGroupComponentProps.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorGroupComponentProps.java index 5155270189..0dddc0117b 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorGroupComponentProps.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorGroupComponentProps.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo. + * Copyright (c) 2022, 2023 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,9 +12,12 @@ *******************************************************************************/ package org.eclipse.sirius.components.formdescriptioneditors.components; +import java.util.List; import java.util.Objects; +import org.eclipse.sirius.components.formdescriptioneditors.IWidgetPreviewConverterProvider; import org.eclipse.sirius.components.formdescriptioneditors.description.FormDescriptionEditorDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IProps; import org.eclipse.sirius.components.representations.VariableManager; @@ -29,9 +32,15 @@ public class FormDescriptionEditorGroupComponentProps implements IProps { private final FormDescriptionEditorDescription formDescriptionEditorDescription; - public FormDescriptionEditorGroupComponentProps(VariableManager variableManager, FormDescriptionEditorDescription formDescriptionEditorDescription) { + private final List widgetDescriptors; + + private final List customWidgetConverterProviders; + + public FormDescriptionEditorGroupComponentProps(VariableManager variableManager, FormDescriptionEditorDescription formDescriptionEditorDescription, List widgetDescriptors, List customWidgetConverterProviders) { this.variableManager = Objects.requireNonNull(variableManager); this.formDescriptionEditorDescription = Objects.requireNonNull(formDescriptionEditorDescription); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); + this.customWidgetConverterProviders = Objects.requireNonNull(customWidgetConverterProviders); } public VariableManager getVariableManager() { @@ -41,4 +50,12 @@ public VariableManager getVariableManager() { public FormDescriptionEditorDescription getFormDescriptionEditorDescription() { return this.formDescriptionEditorDescription; } + + public List getCustomWidgetConverterProviders() { + return this.customWidgetConverterProviders; + } + + public List getWidgetDescriptors() { + return this.widgetDescriptors; + } } diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorPageComponent.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorPageComponent.java index 58548917c1..94edd19743 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorPageComponent.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorPageComponent.java @@ -48,7 +48,7 @@ public Element render() { pageDescription.getGroups().forEach(viewGroupDescription -> { VariableManager childVariableManager = variableManager.createChild(); childVariableManager.put(VariableManager.SELF, viewGroupDescription); - FormDescriptionEditorGroupComponentProps fdeGroupComponentProps = new FormDescriptionEditorGroupComponentProps(childVariableManager, this.props.formDescriptionEditorDescription()); + FormDescriptionEditorGroupComponentProps fdeGroupComponentProps = new FormDescriptionEditorGroupComponentProps(childVariableManager, this.props.formDescriptionEditorDescription(), this.props.widgetDescriptors(), this.props.customWidgetConverterProviders()); childrenWidgets.add(new Element(FormDescriptionEditorGroupComponent.class, fdeGroupComponentProps)); }); diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorPageComponentProps.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorPageComponentProps.java index dbb9e17be3..4b2b3a456b 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorPageComponentProps.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorPageComponentProps.java @@ -12,9 +12,12 @@ *******************************************************************************/ package org.eclipse.sirius.components.formdescriptioneditors.components; +import java.util.List; import java.util.Objects; +import org.eclipse.sirius.components.formdescriptioneditors.IWidgetPreviewConverterProvider; import org.eclipse.sirius.components.formdescriptioneditors.description.FormDescriptionEditorDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IProps; import org.eclipse.sirius.components.representations.VariableManager; @@ -23,10 +26,12 @@ * * @author arichard */ -public record FormDescriptionEditorPageComponentProps(VariableManager variableManager, FormDescriptionEditorDescription formDescriptionEditorDescription) implements IProps { +public record FormDescriptionEditorPageComponentProps(VariableManager variableManager, FormDescriptionEditorDescription formDescriptionEditorDescription, List widgetDescriptors, List customWidgetConverterProviders) implements IProps { - public FormDescriptionEditorPageComponentProps(VariableManager variableManager, FormDescriptionEditorDescription formDescriptionEditorDescription) { + public FormDescriptionEditorPageComponentProps(VariableManager variableManager, FormDescriptionEditorDescription formDescriptionEditorDescription, List widgetDescriptors, List customWidgetConverterProviders) { this.variableManager = Objects.requireNonNull(variableManager); this.formDescriptionEditorDescription = Objects.requireNonNull(formDescriptionEditorDescription); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); + this.customWidgetConverterProviders = Objects.requireNonNull(customWidgetConverterProviders); } } diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/ViewFormDescriptionEditorConverterSwitch.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/ViewFormDescriptionEditorConverterSwitch.java index 4ec05c8ff6..72acb9c2df 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/ViewFormDescriptionEditorConverterSwitch.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/ViewFormDescriptionEditorConverterSwitch.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo. + * Copyright (c) 2022, 2023 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 @@ -18,6 +18,7 @@ import java.util.UUID; import java.util.function.Function; +import org.eclipse.emf.ecore.util.Switch; import org.eclipse.sirius.components.charts.barchart.components.BarChartStyle; import org.eclipse.sirius.components.charts.barchart.descriptions.BarChartDescription; import org.eclipse.sirius.components.charts.descriptions.IChartDescription; @@ -64,6 +65,7 @@ import org.eclipse.sirius.components.view.SelectDescriptionStyle; import org.eclipse.sirius.components.view.TextareaDescriptionStyle; import org.eclipse.sirius.components.view.TextfieldDescriptionStyle; +import org.eclipse.sirius.components.view.WidgetDescription; import org.eclipse.sirius.components.view.util.ViewSwitch; /** @@ -79,9 +81,12 @@ public class ViewFormDescriptionEditorConverterSwitch extends ViewSwitch customWidgetConverter; + + public ViewFormDescriptionEditorConverterSwitch(FormDescriptionEditorDescription formDescriptionEditorDescription, VariableManager variableManager, Switch customWidgetConverter) { this.formDescriptionEditorDescription = formDescriptionEditorDescription; this.variableManager = variableManager; + this.customWidgetConverter = customWidgetConverter; } @Override @@ -505,6 +510,11 @@ private AbstractWidgetDescription createChartWidgetDescription(org.eclipse.siriu // @formatter:on } + @Override + public AbstractWidgetDescription caseWidgetDescription(WidgetDescription widgetDescription) { + return ViewFormDescriptionEditorConverterSwitch.this.customWidgetConverter.doSwitch(widgetDescription); + } + public String getWidgetLabel(org.eclipse.sirius.components.view.WidgetDescription widgetDescription, String defaultLabel) { String widgetLabel = defaultLabel; String name = widgetDescription.getName(); diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorComponentPropsValidator.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorComponentPropsValidator.java index 1bfaf8045e..c8478eb29a 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorComponentPropsValidator.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorComponentPropsValidator.java @@ -12,6 +12,8 @@ *******************************************************************************/ package org.eclipse.sirius.components.formdescriptioneditors.renderer; +import java.util.List; + import org.eclipse.sirius.components.formdescriptioneditors.components.FormDescriptionEditorComponent; import org.eclipse.sirius.components.formdescriptioneditors.components.FormDescriptionEditorComponentProps; import org.eclipse.sirius.components.formdescriptioneditors.components.FormDescriptionEditorGroupComponent; @@ -19,6 +21,7 @@ import org.eclipse.sirius.components.formdescriptioneditors.components.FormDescriptionEditorPageComponent; import org.eclipse.sirius.components.formdescriptioneditors.components.FormDescriptionEditorPageComponentProps; import org.eclipse.sirius.components.forms.renderer.FormComponentPropsValidator; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IComponentPropsValidator; import org.eclipse.sirius.components.representations.IProps; @@ -31,8 +34,8 @@ public class FormDescriptionEditorComponentPropsValidator implements IComponentP private final FormComponentPropsValidator formComponentPropsValidator; - public FormDescriptionEditorComponentPropsValidator() { - this.formComponentPropsValidator = new FormComponentPropsValidator(); + public FormDescriptionEditorComponentPropsValidator(List widgetDescriptors) { + this.formComponentPropsValidator = new FormComponentPropsValidator(widgetDescriptors); } @Override diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorElementFactory.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorElementFactory.java index 17367883b6..7237353273 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorElementFactory.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorElementFactory.java @@ -18,6 +18,7 @@ import org.eclipse.sirius.components.formdescriptioneditors.elements.FormDescriptionEditorElementProps; import org.eclipse.sirius.components.forms.Page; import org.eclipse.sirius.components.forms.renderer.FormElementFactory; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IElementFactory; import org.eclipse.sirius.components.representations.IProps; @@ -30,8 +31,8 @@ public class FormDescriptionEditorElementFactory implements IElementFactory { private final FormElementFactory formElementFactory; - public FormDescriptionEditorElementFactory() { - this.formElementFactory = new FormElementFactory(); + public FormDescriptionEditorElementFactory(List widgetDescriptors) { + this.formElementFactory = new FormElementFactory(widgetDescriptors); } @Override diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorInstancePropsValidator.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorInstancePropsValidator.java index 4253791e5e..635892806e 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorInstancePropsValidator.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorInstancePropsValidator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo. + * Copyright (c) 2022, 2023 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,8 +12,11 @@ *******************************************************************************/ package org.eclipse.sirius.components.formdescriptioneditors.renderer; +import java.util.List; + import org.eclipse.sirius.components.formdescriptioneditors.elements.FormDescriptionEditorElementProps; import org.eclipse.sirius.components.forms.renderer.FormInstancePropsValidator; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IInstancePropsValidator; import org.eclipse.sirius.components.representations.IProps; @@ -26,8 +29,8 @@ public class FormDescriptionEditorInstancePropsValidator implements IInstancePro private final FormInstancePropsValidator formInstancePropsValidator; - public FormDescriptionEditorInstancePropsValidator() { - this.formInstancePropsValidator = new FormInstancePropsValidator(); + public FormDescriptionEditorInstancePropsValidator(List widgetDescriptors) { + this.formInstancePropsValidator = new FormInstancePropsValidator(widgetDescriptors); } @Override diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorRenderer.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorRenderer.java index 4aa8cd78c2..ad2e71bf61 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorRenderer.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/renderer/FormDescriptionEditorRenderer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo. + * Copyright (c) 2022, 2023 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,9 +12,11 @@ *******************************************************************************/ package org.eclipse.sirius.components.formdescriptioneditors.renderer; +import java.util.List; import java.util.Optional; import org.eclipse.sirius.components.formdescriptioneditors.FormDescriptionEditor; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.BaseRenderer; import org.eclipse.sirius.components.representations.Element; @@ -32,8 +34,8 @@ public class FormDescriptionEditorRenderer { private final BaseRenderer baseRenderer; - public FormDescriptionEditorRenderer() { - this.baseRenderer = new BaseRenderer(new FormDescriptionEditorInstancePropsValidator(), new FormDescriptionEditorComponentPropsValidator(), new FormDescriptionEditorElementFactory()); + public FormDescriptionEditorRenderer(List widgetDescriptors) { + this.baseRenderer = new BaseRenderer(new FormDescriptionEditorInstancePropsValidator(widgetDescriptors), new FormDescriptionEditorComponentPropsValidator(widgetDescriptors), new FormDescriptionEditorElementFactory(widgetDescriptors)); } public FormDescriptionEditor render(Element element) { diff --git a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/test/java/org/eclipse/sirius/components/formdescriptioneditors/components/ViewFormDescriptionEditorConverterSwitchTests.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/test/java/org/eclipse/sirius/components/formdescriptioneditors/components/ViewFormDescriptionEditorConverterSwitchTests.java index 614ec30571..87ccd55373 100644 --- a/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/test/java/org/eclipse/sirius/components/formdescriptioneditors/components/ViewFormDescriptionEditorConverterSwitchTests.java +++ b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/test/java/org/eclipse/sirius/components/formdescriptioneditors/components/ViewFormDescriptionEditorConverterSwitchTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo. + * Copyright (c) 2022, 2023 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 @@ -97,7 +97,7 @@ private String callGetWidgetLabel(String name, String labelExpression) { ImageDescription viewWidgetDescription = ViewFactory.eINSTANCE.createImageDescription(); viewWidgetDescription.setName(name); viewWidgetDescription.setLabelExpression(labelExpression); - ViewFormDescriptionEditorConverterSwitch converter = new ViewFormDescriptionEditorConverterSwitch(null, null); + ViewFormDescriptionEditorConverterSwitch converter = new ViewFormDescriptionEditorConverterSwitch(null, null, null); return converter.getWidgetLabel(viewWidgetDescription, DEFAULT_LABEL); } } diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/CustomWidget.tsx b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/CustomWidget.tsx new file mode 100644 index 0000000000..ccb6493f12 --- /dev/null +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/CustomWidget.tsx @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2023 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 Typography from '@material-ui/core/Typography'; +import { Theme, makeStyles } from '@material-ui/core/styles'; +import ExtensionIcon from '@material-ui/icons/Extension'; +import { useEffect, useRef, useState } from 'react'; +import { CustomWidgetProps } from './CustomWidget.types'; + +type CustomWidgetStyleProps = {}; +const useStyles = makeStyles((theme) => ({ + style: { + color: theme.palette.secondary.main, + }, + selected: { + color: theme.palette.primary.main, + }, +})); + +/** + * Generic fallback component to display custom widgets which do not provide a more + * specific implementation. This allows them to still be created/displayed/selected/moved + * in a Form Description Editor, but they will be represented by a generic icon. + */ +export const CustomWidget = ({ widget, selection }: CustomWidgetProps) => { + const props: CustomWidgetStyleProps = {}; + const classes = useStyles(props); + + const [selected, setSelected] = useState(false); + + const ref = useRef(null); + + useEffect(() => { + if (ref.current && selection.entries.find((entry) => entry.id === widget.id)) { + ref.current.focus(); + setSelected(true); + } else { + setSelected(false); + } + }, [selection, widget]); + + return ( +
+ + {widget.label} + +
setSelected(true)} + onBlur={() => setSelected(false)} + tabIndex={0} + className={classes.style}> + +
+
+ ); +}; diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/CustomWidget.types.ts b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/CustomWidget.types.ts new file mode 100644 index 0000000000..67ceecc423 --- /dev/null +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/CustomWidget.types.ts @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2023 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 { GQLWidget } from '@eclipse-sirius/sirius-components-forms'; +import { WidgetProps } from './WidgetEntry.types'; + +export type CustomWidgetProps = WidgetProps; diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FlexboxContainerWidget.tsx b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FlexboxContainerWidget.tsx index d64d120d01..328f625ed7 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FlexboxContainerWidget.tsx +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FlexboxContainerWidget.tsx @@ -11,13 +11,13 @@ * Obeo - initial API and implementation *******************************************************************************/ import { useMutation } from '@apollo/client'; -import { GQLWidget } from '@eclipse-sirius/sirius-components-forms'; +import { GQLWidget, PropertySectionContext } from '@eclipse-sirius/sirius-components-forms'; import IconButton from '@material-ui/core/IconButton'; import Snackbar from '@material-ui/core/Snackbar'; -import { makeStyles, Theme } from '@material-ui/core/styles'; import Typography from '@material-ui/core/Typography'; +import { Theme, makeStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useContext, useEffect, useRef, useState } from 'react'; import { FlexboxContainerWidgetState, FlexboxContainerWidgetStyleProps } from './FlexboxContainerWidget.types'; import { addWidgetMutation, moveWidgetMutation } from './FormDescriptionEditorEventFragment'; import { @@ -163,6 +163,7 @@ export const FlexboxContainerWidget = ({ event.preventDefault(); event.currentTarget.classList.remove(classes.dragOver); }; + const { propertySectionsRegistry } = useContext(PropertySectionContext); const handleDrop: React.DragEventHandler = (event) => { event.preventDefault(); event.currentTarget.classList.remove(classes.dragOver); @@ -174,8 +175,7 @@ export const FlexboxContainerWidget = ({ } let index = widget.children.length; - - if (isKind(id)) { + if (isKind(id) || propertySectionsRegistry.getWidgetContributions().find((contrib) => contrib.name === id)) { const addWidgetInput: GQLAddWidgetInput = { id: crypto.randomUUID(), editingContextId, diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FormDescriptionEditorEventFragment.ts b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FormDescriptionEditorEventFragment.ts index 9a79f9953b..3dd82c72a7 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FormDescriptionEditorEventFragment.ts +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FormDescriptionEditorEventFragment.ts @@ -11,11 +11,11 @@ * Obeo - initial API and implementation *******************************************************************************/ import { gql } from '@apollo/client'; -import { flexboxContainerFields, widgetFields } from '@eclipse-sirius/sirius-components-forms'; +import { WidgetContribution, flexboxContainerFields, widgetFields } from '@eclipse-sirius/sirius-components-forms'; -export const formDescriptionEditorEventSubscription = gql` - ${widgetFields} - ${flexboxContainerFields} +export const formDescriptionEditorEventSubscription = (contributions: Array) => ` + ${widgetFields(contributions)} + ${flexboxContainerFields(contributions)} subscription formDescriptionEditorEvent($input: FormDescriptionEditorEventInput!) { formDescriptionEditorEvent(input: $input) { __typename diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FormDescriptionEditorRepresentation.tsx b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FormDescriptionEditorRepresentation.tsx index 59b181bb54..230de961e5 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FormDescriptionEditorRepresentation.tsx +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FormDescriptionEditorRepresentation.tsx @@ -10,14 +10,15 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -import { useSubscription } from '@apollo/client'; +import { gql, useSubscription } from '@apollo/client'; import { RepresentationComponentProps } from '@eclipse-sirius/sirius-components-core'; +import { PropertySectionContext } from '@eclipse-sirius/sirius-components-forms'; import Avatar from '@material-ui/core/Avatar'; import IconButton from '@material-ui/core/IconButton'; import Snackbar from '@material-ui/core/Snackbar'; -import { makeStyles } from '@material-ui/core/styles'; import Tooltip from '@material-ui/core/Tooltip'; import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; import ArrowDropDownCircleIcon from '@material-ui/icons/ArrowDropDownCircle'; import BarChartIcon from '@material-ui/icons/BarChart'; import CheckBoxIcon from '@material-ui/icons/CheckBox'; @@ -34,7 +35,7 @@ import ViewAgendaIcon from '@material-ui/icons/ViewAgenda'; import ViewColumnIcon from '@material-ui/icons/ViewColumn'; import WebIcon from '@material-ui/icons/Web'; import { useMachine } from '@xstate/react'; -import React, { useEffect } from 'react'; +import React, { useContext, useEffect } from 'react'; import { formDescriptionEditorEventSubscription } from './FormDescriptionEditorEventFragment'; import { GQLFormDescriptionEditorEventInput, @@ -44,15 +45,15 @@ import { import { FormDescriptionEditorRepresentationContext, FormDescriptionEditorRepresentationEvent, - formDescriptionEditorRepresentationMachine, HandleSubscriptionResultEvent, HideToastEvent, InitializeRepresentationEvent, SchemaValue, ShowToastEvent, + formDescriptionEditorRepresentationMachine, } from './FormDescriptionEditorRepresentationMachine'; -import { Button } from './icons/Button'; import { PageList } from './PageList'; +import { Button } from './icons/Button'; const useFormDescriptionEditorStyles = makeStyles((theme) => ({ formDescriptionEditor: { @@ -160,9 +161,9 @@ export const FormDescriptionEditorRepresentation = ({ formDescriptionEditorId: representationId, }; const variables: GQLFormDescriptionEditorEventVariables = { input }; - + const { propertySectionsRegistry } = useContext(PropertySectionContext); const { error } = useSubscription( - formDescriptionEditorEventSubscription, + gql(formDescriptionEditorEventSubscription(propertySectionsRegistry.getWidgetContributions())), { variables, fetchPolicy: 'no-cache', @@ -409,6 +410,22 @@ export const FormDescriptionEditorRepresentation = ({ Textfield + {propertySectionsRegistry.getWidgetContributions().map((customWidget) => { + return ( +
+ {customWidget.icon} + + {customWidget.name} + +
+ ); + })}
diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/Group.tsx b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/Group.tsx index 3b02b07d66..37a57ab281 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/Group.tsx +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/Group.tsx @@ -12,16 +12,16 @@ *******************************************************************************/ import { useMutation } from '@apollo/client'; import { Selection } from '@eclipse-sirius/sirius-components-core'; -import { GQLWidget } from '@eclipse-sirius/sirius-components-forms'; +import { GQLWidget, PropertySectionContext } from '@eclipse-sirius/sirius-components-forms'; import IconButton from '@material-ui/core/IconButton'; import Snackbar from '@material-ui/core/Snackbar'; -import { makeStyles, Theme, withStyles } from '@material-ui/core/styles'; import Tooltip from '@material-ui/core/Tooltip'; import Typography from '@material-ui/core/Typography'; +import { Theme, makeStyles, withStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; import ToggleButton from '@material-ui/lab/ToggleButton'; import ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useContext, useEffect, useRef, useState } from 'react'; import { addGroupMutation, addWidgetMutation, @@ -329,6 +329,7 @@ export const Group = ({ event.preventDefault(); event.currentTarget.classList.remove(classes.dragOver); }; + const { propertySectionsRegistry } = useContext(PropertySectionContext); const handleDrop: React.DragEventHandler = (event: React.DragEvent) => { event.preventDefault(); event.currentTarget.classList.remove(classes.dragOver); @@ -388,7 +389,7 @@ export const Group = ({ let widgetIndex = group.widgets.length; - if (isKind(id)) { + if (isKind(id) || propertySectionsRegistry.getWidgetContributions().find((contrib) => contrib.name === id)) { const addWidgetInput: GQLAddWidgetInput = { id: crypto.randomUUID(), editingContextId, diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActionWidget.tsx b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActionWidget.tsx index 83e4c4eed6..2fb2f8883e 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActionWidget.tsx +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActionWidget.tsx @@ -14,14 +14,16 @@ import { useMutation } from '@apollo/client'; import { Selection, ServerContext, ServerContextValue } from '@eclipse-sirius/sirius-components-core'; import { ButtonStyleProps, - getTextDecorationLineValue, GQLButton, GQLToolbarAction, + GQLWidget, + PropertySectionContext, + getTextDecorationLineValue, } from '@eclipse-sirius/sirius-components-forms'; import Button from '@material-ui/core/Button'; import IconButton from '@material-ui/core/IconButton'; import Snackbar from '@material-ui/core/Snackbar'; -import { makeStyles, Theme } from '@material-ui/core/styles'; +import { Theme, makeStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; import React, { useContext, useEffect, useRef, useState } from 'react'; import { deleteToolbarActionMutation, moveToolbarActionMutation } from './FormDescriptionEditorEventFragment'; @@ -278,7 +280,7 @@ export const ToolbarActionWidget = ({ event.currentTarget.classList.remove(classes.dragOver); onDropBefore(event, toolbarAction); }; - + const { propertySectionsRegistry } = useContext(PropertySectionContext); const onDropBefore = (event: React.DragEvent, toolbarAction: GQLButton) => { const id: string = event.dataTransfer.getData('draggedElementId'); // We only accept a drop of ToolbarAction diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActions.tsx b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActions.tsx index 745635558c..635cf31811 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActions.tsx +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActions.tsx @@ -15,8 +15,8 @@ import { useMutation } from '@apollo/client'; import { GQLToolbarAction } from '@eclipse-sirius/sirius-components-forms'; import IconButton from '@material-ui/core/IconButton'; import Snackbar from '@material-ui/core/Snackbar'; -import { makeStyles, Theme } from '@material-ui/core/styles'; import Tooltip from '@material-ui/core/Tooltip'; +import { Theme, makeStyles } from '@material-ui/core/styles'; import AddIcon from '@material-ui/icons/Add'; import CloseIcon from '@material-ui/icons/Close'; import { useEffect, useState } from 'react'; @@ -32,8 +32,8 @@ import { GQLMoveToolbarActionMutationVariables, GQLMoveToolbarActionPayload, } from './FormDescriptionEditorEventFragment.types'; -import { ToolbarActionsProps } from './ToolbarActions.types'; import { ToolbarActionWidget } from './ToolbarActionWidget'; +import { ToolbarActionsProps } from './ToolbarActions.types'; const useToolbarActionsStyles = makeStyles((theme: Theme) => ({ toolbar: { diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.tsx b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.tsx index 923ff5ef43..1685acea5d 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.tsx +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.tsx @@ -29,16 +29,18 @@ import { GQLTextarea, GQLTextfield, GQLWidget, + PropertySectionContext, } from '@eclipse-sirius/sirius-components-forms'; import IconButton from '@material-ui/core/IconButton'; import Snackbar from '@material-ui/core/Snackbar'; -import { makeStyles, Theme, withStyles } from '@material-ui/core/styles'; import Tooltip from '@material-ui/core/Tooltip'; +import { Theme, makeStyles, withStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { BarChartWidget } from './BarChartWidget'; import { ButtonWidget } from './ButtonWidget'; import { CheckboxWidget } from './CheckboxWidget'; +import { CustomWidget } from './CustomWidget'; import { FlexboxContainerWidget } from './FlexboxContainerWidget'; import { addWidgetMutation, deleteWidgetMutation, moveWidgetMutation } from './FormDescriptionEditorEventFragment'; import { @@ -135,6 +137,8 @@ export const WidgetEntry = ({ const [state, setState] = useState(initialState); const { message } = state; + const { propertySectionsRegistry } = useContext(PropertySectionContext); + const [addWidget, { loading: addWidgetLoading, data: addWidgetData, error: addWidgetError }] = useMutation< GQLAddWidgetMutationData, GQLAddWidgetMutationVariables @@ -274,7 +278,7 @@ export const WidgetEntry = ({ index = 0; } - if (isKind(id)) { + if (isKind(id) || propertySectionsRegistry.getWidgetContributions().find((contrib) => contrib.name === id)) { const addWidgetInput: GQLAddWidgetInput = { id: crypto.randomUUID(), editingContextId, @@ -461,6 +465,31 @@ export const WidgetEntry = ({ /> ); } + } else { + const PreviewComponent = propertySectionsRegistry.getPreviewComponent(widget); + if (PreviewComponent) { + widgetElement = ( + + ); + } else if (propertySectionsRegistry.getComponent(widget)) { + widgetElement = ( + + ); + } else { + console.error(`Unsupported widget type ${widget.__typename}`); + } } return ( diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.types.ts b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.types.ts index b59467e4cc..db36b56524 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.types.ts +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.types.ts @@ -47,7 +47,7 @@ export interface WidgetEntryProps { flexGrow: number; } -interface WidgetProps { +export interface WidgetProps { widget: WidgetType; selection: Selection; setSelection: (newSelection: Selection) => void; diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/index.ts b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/index.ts index 06fbb1f19f..6e606f6ae4 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/index.ts +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/index.ts @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo and others. + * Copyright (c) 2022, 2023 Obeo and others. * 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 @@ -11,3 +11,4 @@ * Obeo - initial API and implementation *******************************************************************************/ export * from './FormDescriptionEditorRepresentation'; +export * from './WidgetEntry.types'; diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessor.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessor.java index f5168ae038..39c9a08f53 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessor.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessor.java @@ -40,6 +40,7 @@ import org.eclipse.sirius.components.forms.components.FormComponent; import org.eclipse.sirius.components.forms.components.FormComponentProps; import org.eclipse.sirius.components.forms.renderer.FormRenderer; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.Element; import org.eclipse.sirius.components.representations.GetOrCreateRandomIdProvider; import org.eclipse.sirius.components.representations.IRepresentation; @@ -68,6 +69,8 @@ public class FormEventProcessor implements IFormEventProcessor { private final FormCreationParameters formCreationParameters; + private final List widgetDescriptors; + private final List formEventHandlers; private final ISubscriptionManager subscriptionManager; @@ -80,12 +83,13 @@ public class FormEventProcessor implements IFormEventProcessor { private final AtomicReference
currentForm = new AtomicReference<>(); - public FormEventProcessor(IEditingContext editingContext, FormCreationParameters formCreationParameters, List formEventHandlers, ISubscriptionManager subscriptionManager, - IWidgetSubscriptionManager widgetSubscriptionManager, IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry) { + public FormEventProcessor(IEditingContext editingContext, FormCreationParameters formCreationParameters, List widgetDescriptors, List formEventHandlers, + ISubscriptionManager subscriptionManager, IWidgetSubscriptionManager widgetSubscriptionManager, IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry) { this.logger.trace("Creating the form event processor {}", formCreationParameters.getId()); this.editingContext = Objects.requireNonNull(editingContext); this.formCreationParameters = Objects.requireNonNull(formCreationParameters); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); this.formEventHandlers = Objects.requireNonNull(formEventHandlers); this.subscriptionManager = Objects.requireNonNull(subscriptionManager); this.widgetSubscriptionManager = Objects.requireNonNull(widgetSubscriptionManager); @@ -172,9 +176,9 @@ private Form refreshForm() { variableManager.put(GetOrCreateRandomIdProvider.PREVIOUS_REPRESENTATION_ID, this.formCreationParameters.getId()); variableManager.put(IEditingContext.EDITING_CONTEXT, this.formCreationParameters.getEditingContext()); - FormComponentProps formComponentProps = new FormComponentProps(variableManager, this.formCreationParameters.getFormDescription()); + FormComponentProps formComponentProps = new FormComponentProps(variableManager, this.formCreationParameters.getFormDescription(), this.widgetDescriptors); Element element = new Element(FormComponent.class, formComponentProps); - Form form = new FormRenderer().render(element); + Form form = new FormRenderer(this.widgetDescriptors).render(element); this.logger.trace("Form refreshed: {}", form.getId()); @@ -188,10 +192,10 @@ public Flux getOutputEvents(IInput input) { // @formatter:off return Flux.merge( - refreshEventFlux, - this.widgetSubscriptionManager.getFlux(input), - this.subscriptionManager.getFlux(input) - ); + refreshEventFlux, + this.widgetSubscriptionManager.getFlux(input), + this.subscriptionManager.getFlux(input) + ); // @formatter:on } diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorFactory.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorFactory.java index c69b225d9e..a0ad0bd1f3 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorFactory.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2022 Obeo. + * Copyright (c) 2019, 2023 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 @@ -22,6 +22,7 @@ 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.api.FormConfiguration; import org.eclipse.sirius.components.collaborative.forms.api.FormCreationParameters; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; @@ -32,6 +33,7 @@ import org.eclipse.sirius.components.core.api.IRepresentationDescriptionSearchService; import org.eclipse.sirius.components.forms.Form; import org.eclipse.sirius.components.forms.description.FormDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.springframework.stereotype.Service; /** @@ -49,6 +51,8 @@ public class FormEventProcessorFactory implements IRepresentationEventProcessorF private final IRepresentationSearchService representationSearchService; + private final List widgetDescriptors; + private final List formEventHandlers; private final ISubscriptionManagerFactory subscriptionManagerFactory; @@ -57,16 +61,16 @@ public class FormEventProcessorFactory implements IRepresentationEventProcessorF private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; - public FormEventProcessorFactory(IRepresentationDescriptionSearchService representationDescriptionSearchService, IObjectService objectService, - IRepresentationSearchService representationSearchService, List formEventHandlers, ISubscriptionManagerFactory subscriptionManagerFactory, - IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory, IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry) { - this.representationDescriptionSearchService = Objects.requireNonNull(representationDescriptionSearchService); + public FormEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, IObjectService objectService, List widgetDescriptors, + List formEventHandlers, IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory) { + this.representationDescriptionSearchService = Objects.requireNonNull(configuration.getRepresentationDescriptionSearchService()); + this.representationSearchService = Objects.requireNonNull(configuration.getRepresentationSearchService()); + this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory()); this.objectService = Objects.requireNonNull(objectService); - this.representationSearchService = Objects.requireNonNull(representationSearchService); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); this.formEventHandlers = Objects.requireNonNull(formEventHandlers); - this.subscriptionManagerFactory = Objects.requireNonNull(subscriptionManagerFactory); this.widgetSubscriptionManagerFactory = Objects.requireNonNull(widgetSubscriptionManagerFactory); - this.representationRefreshPolicyRegistry = Objects.requireNonNull(representationRefreshPolicyRegistry); + this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry()); } @Override @@ -101,8 +105,8 @@ public Optional createRepresentatio .build(); // @formatter:on - IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, this.formEventHandlers, this.subscriptionManagerFactory.create(), - this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry); + IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, this.widgetDescriptors, this.formEventHandlers, + this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry); // @formatter:off return Optional.of(formEventProcessor) diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/PropertiesEventProcessorFactory.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/PropertiesEventProcessorFactory.java index 8513f75d44..78782043c7 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/PropertiesEventProcessorFactory.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/PropertiesEventProcessorFactory.java @@ -22,6 +22,7 @@ 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.api.FormCreationParameters; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor; @@ -32,6 +33,7 @@ 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.springframework.stereotype.Service; /** @@ -49,6 +51,8 @@ public class PropertiesEventProcessorFactory implements IRepresentationEventProc private final IObjectService objectService; + private final List widgetDescriptors; + private final List formEventHandlers; private final ISubscriptionManagerFactory subscriptionManagerFactory; @@ -58,15 +62,16 @@ public class PropertiesEventProcessorFactory implements IRepresentationEventProc private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; public PropertiesEventProcessorFactory(IPropertiesDescriptionService propertiesDescriptionService, IPropertiesDefaultDescriptionProvider propertiesDefaultDescriptionProvider, - IObjectService objectService, List formEventHandlers, ISubscriptionManagerFactory subscriptionManagerFactory, - IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory, IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry) { + IObjectService objectService, List widgetDescriptors, List formEventHandlers, RepresentationEventProcessorFactoryConfiguration configuration, + IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory) { this.propertiesDescriptionService = Objects.requireNonNull(propertiesDescriptionService); this.propertiesDefaultDescriptionProvider = Objects.requireNonNull(propertiesDefaultDescriptionProvider); this.objectService = Objects.requireNonNull(objectService); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); this.formEventHandlers = Objects.requireNonNull(formEventHandlers); - this.subscriptionManagerFactory = Objects.requireNonNull(subscriptionManagerFactory); + this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory()); this.widgetSubscriptionManagerFactory = Objects.requireNonNull(widgetSubscriptionManagerFactory); - this.representationRefreshPolicyRegistry = Objects.requireNonNull(representationRefreshPolicyRegistry); + this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry()); } @Override @@ -102,8 +107,8 @@ public Optional createRepresentatio .build(); // @formatter:on - IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, this.formEventHandlers, this.subscriptionManagerFactory.create(), - this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry); + IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, this.widgetDescriptors, this.formEventHandlers, + this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry); // @formatter:off return Optional.of(formEventProcessor) diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RelatedElementsEventProcessorFactory.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RelatedElementsEventProcessorFactory.java index fdbce63ab4..471aac5631 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RelatedElementsEventProcessorFactory.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RelatedElementsEventProcessorFactory.java @@ -21,6 +21,7 @@ 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.api.FormCreationParameters; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler; import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor; @@ -30,6 +31,7 @@ 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.springframework.stereotype.Service; /** @@ -44,6 +46,8 @@ public class RelatedElementsEventProcessorFactory implements IRepresentationEven private final IObjectService objectService; + private final List widgetDescriptors; + private final List formEventHandlers; private final ISubscriptionManagerFactory subscriptionManagerFactory; @@ -52,15 +56,15 @@ public class RelatedElementsEventProcessorFactory implements IRepresentationEven private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; - public RelatedElementsEventProcessorFactory(IRelatedElementsDescriptionProvider relatedElementsDescriptionProvider, IObjectService objectService, List formEventHandlers, - ISubscriptionManagerFactory subscriptionManagerFactory, IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory, - IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry) { + public RelatedElementsEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, IRelatedElementsDescriptionProvider relatedElementsDescriptionProvider, + IObjectService objectService, List widgetDescriptors, List formEventHandlers, IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory) { this.relatedElementsDescriptionProvider = Objects.requireNonNull(relatedElementsDescriptionProvider); this.objectService = Objects.requireNonNull(objectService); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); this.formEventHandlers = Objects.requireNonNull(formEventHandlers); - this.subscriptionManagerFactory = Objects.requireNonNull(subscriptionManagerFactory); + this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory()); this.widgetSubscriptionManagerFactory = Objects.requireNonNull(widgetSubscriptionManagerFactory); - this.representationRefreshPolicyRegistry = Objects.requireNonNull(representationRefreshPolicyRegistry); + this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry()); } @Override @@ -90,8 +94,8 @@ public Optional createRepresentatio .build(); // @formatter:on - IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, this.formEventHandlers, this.subscriptionManagerFactory.create(), - this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry); + IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, this.widgetDescriptors, this.formEventHandlers, + this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry); // @formatter:off return Optional.of(formEventProcessor) diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RepresentationsEventProcessorFactory.java b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RepresentationsEventProcessorFactory.java index af9a59ea6d..f61acd94cc 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RepresentationsEventProcessorFactory.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/main/java/org/eclipse/sirius/components/collaborative/forms/RepresentationsEventProcessorFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021, 2022 Obeo. + * Copyright (c) 2021, 2023 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 @@ -86,7 +86,7 @@ public Optional createRepresentatio .build(); // @formatter:on - FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, this.formEventHandlers, this.subscriptionManagerFactory.create(), + FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, List.of(), this.formEventHandlers, this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry); // @formatter:off diff --git a/packages/forms/backend/sirius-components-collaborative-forms/src/test/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorTests.java b/packages/forms/backend/sirius-components-collaborative-forms/src/test/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorTests.java index 19bb59da63..06c678741e 100644 --- a/packages/forms/backend/sirius-components-collaborative-forms/src/test/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorTests.java +++ b/packages/forms/backend/sirius-components-collaborative-forms/src/test/java/org/eclipse/sirius/components/collaborative/forms/FormEventProcessorTests.java @@ -76,7 +76,7 @@ public void testEmitFormOnSubscription() { .build(); // @formatter:on - FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, List.of(), new SubscriptionManager(), new WidgetSubscriptionManager(), + FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, List.of(), List.of(), new SubscriptionManager(), new WidgetSubscriptionManager(), new RepresentationRefreshPolicyRegistry()); // @formatter:off @@ -100,7 +100,7 @@ public void testEmitFormOnRefresh() { .build(); // @formatter:on - FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, List.of(), new SubscriptionManager(), new WidgetSubscriptionManager(), + FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, List.of(), List.of(), new SubscriptionManager(), new WidgetSubscriptionManager(), new RepresentationRefreshPolicyRegistry()); Runnable performRefresh = () -> formEventProcessor.refresh(new ChangeDescription(ChangeKind.SEMANTIC_CHANGE, input.formId(), input)); @@ -128,7 +128,7 @@ public void testCompleteOnDispose() { .build(); // @formatter:on - FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, List.of(), new SubscriptionManager(), new WidgetSubscriptionManager(), + FormEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, List.of(), List.of(), new SubscriptionManager(), new WidgetSubscriptionManager(), new RepresentationRefreshPolicyRegistry()); Runnable disposeFormEventProcessor = () -> formEventProcessor.dispose(); diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FlexboxContainerComponent.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FlexboxContainerComponent.java index 6bed22f0b7..7cc5b1ebda 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FlexboxContainerComponent.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FlexboxContainerComponent.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo. + * Copyright (c) 2022, 2023 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 @@ -59,7 +59,7 @@ public Element render() { if (optionalSelf.isPresent()) { VariableManager childVariableManager = variableManager.createChild(); childVariableManager.put(VariableManager.SELF, optionalSelf.get()); - childrenWidgets.add(new Element(WidgetComponent.class, new WidgetComponentProps(childVariableManager, widget))); + childrenWidgets.add(new Element(WidgetComponent.class, new WidgetComponentProps(childVariableManager, widget, this.props.getWidgetDescriptors()))); } }); diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FlexboxContainerComponentProps.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FlexboxContainerComponentProps.java index adb3e26069..98eae7ed8f 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FlexboxContainerComponentProps.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FlexboxContainerComponentProps.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo. + * Copyright (c) 2022, 2023 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,9 +12,11 @@ *******************************************************************************/ package org.eclipse.sirius.components.forms.components; +import java.util.List; import java.util.Objects; import org.eclipse.sirius.components.forms.description.FlexboxContainerDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IProps; import org.eclipse.sirius.components.representations.VariableManager; @@ -28,9 +30,12 @@ public class FlexboxContainerComponentProps implements IProps { private final FlexboxContainerDescription flexboxContainerDescription; - public FlexboxContainerComponentProps(VariableManager variableManager, FlexboxContainerDescription flexboxContainerDescription) { + private final List widgetDescriptors; + + public FlexboxContainerComponentProps(VariableManager variableManager, FlexboxContainerDescription flexboxContainerDescription, List widgetDescriptors) { this.variableManager = Objects.requireNonNull(variableManager); this.flexboxContainerDescription = Objects.requireNonNull(flexboxContainerDescription); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); } public VariableManager getVariableManager() { @@ -40,4 +45,9 @@ public VariableManager getVariableManager() { public FlexboxContainerDescription getFlexboxContainerDescription() { return this.flexboxContainerDescription; } + + public List getWidgetDescriptors() { + return this.widgetDescriptors; + } + } diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/ForComponent.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/ForComponent.java index 621a4f20b8..97f984d34a 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/ForComponent.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/ForComponent.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 Obeo. + * Copyright (c) 2019, 2023 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 @@ -53,7 +53,7 @@ public Element render() { List ifDescriptions = forDescription.getIfDescriptions(); for (IfDescription ifDescription : ifDescriptions) { - IfComponentProps ifComponentProps = new IfComponentProps(childVariableManager, ifDescription); + IfComponentProps ifComponentProps = new IfComponentProps(childVariableManager, ifDescription, this.props.getWidgetDescriptors()); forChildren.add(new Element(IfComponent.class, ifComponentProps)); } diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/ForComponentProps.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/ForComponentProps.java index b510e9d7b9..2d1e74ddc4 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/ForComponentProps.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/ForComponentProps.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 Obeo. + * Copyright (c) 2019, 2023 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,9 +12,11 @@ *******************************************************************************/ package org.eclipse.sirius.components.forms.components; +import java.util.List; import java.util.Objects; import org.eclipse.sirius.components.forms.description.ForDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IProps; import org.eclipse.sirius.components.representations.VariableManager; @@ -29,9 +31,13 @@ public class ForComponentProps implements IProps { private ForDescription forDescription; - public ForComponentProps(VariableManager variableManager, ForDescription forDescription) { + private final List widgetDescriptors; + + public ForComponentProps(VariableManager variableManager, ForDescription forDescription, List widgetDescriptors) { this.variableManager = Objects.requireNonNull(variableManager); this.forDescription = Objects.requireNonNull(forDescription); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); + } public VariableManager getVariableManager() { @@ -41,4 +47,8 @@ public VariableManager getVariableManager() { public ForDescription getForDescription() { return this.forDescription; } + + public List getWidgetDescriptors() { + return this.widgetDescriptors; + } } diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FormComponent.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FormComponent.java index d280a01b7d..09ad218e36 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FormComponent.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FormComponent.java @@ -72,7 +72,7 @@ public Element render() { childVariableManager.put(WIDGET_ID_PROVIDER_COUNTER, widgetIdCounter); return childVariableManager; }).flatMap(childVariableManager -> pageDescriptions.stream().map(pageDescription -> { - PageComponentProps pageComponentProps = new PageComponentProps(childVariableManager, pageDescription); + PageComponentProps pageComponentProps = new PageComponentProps(childVariableManager, pageDescription, this.props.getWidgetDescriptors()); return new Element(PageComponent.class, pageComponentProps); })).toList(); diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FormComponentProps.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FormComponentProps.java index 4478350624..c2978646da 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FormComponentProps.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/FormComponentProps.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 Obeo. + * Copyright (c) 2019, 2023 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,9 +12,11 @@ *******************************************************************************/ package org.eclipse.sirius.components.forms.components; +import java.util.List; import java.util.Objects; import org.eclipse.sirius.components.forms.description.FormDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IProps; import org.eclipse.sirius.components.representations.VariableManager; @@ -28,9 +30,12 @@ public class FormComponentProps implements IProps { private final FormDescription formDescription; - public FormComponentProps(VariableManager variableManager, FormDescription formDescription) { + private final List widgetDescriptors; + + public FormComponentProps(VariableManager variableManager, FormDescription formDescription, List widgetDescriptors) { this.variableManager = Objects.requireNonNull(variableManager); this.formDescription = Objects.requireNonNull(formDescription); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); } public VariableManager getVariableManager() { @@ -40,4 +45,8 @@ public VariableManager getVariableManager() { public FormDescription getFormDescription() { return this.formDescription; } + + public List getWidgetDescriptors() { + return this.widgetDescriptors; + } } diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/GroupComponent.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/GroupComponent.java index 713314ba4c..e8e6cdd6f3 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/GroupComponent.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/GroupComponent.java @@ -1,5 +1,9 @@ /******************************************************************************* +<<<<<<< HEAD * Copyright (c) 2019, 2023 Obeo. +======= + * Copyright (c) 2019, 2020, 2023 Obeo. +>>>>>>> 0ce6e6e31 ([1914] Add support for custom widgets) * 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 @@ -68,10 +72,10 @@ public Element render() { List controlDescriptions = groupDescription.getControlDescriptions(); for (AbstractControlDescription controlDescription : controlDescriptions) { if (controlDescription instanceof AbstractWidgetDescription widgetDescription) { - WidgetComponentProps widgetComponentProps = new WidgetComponentProps(groupVariableManager, widgetDescription); + WidgetComponentProps widgetComponentProps = new WidgetComponentProps(groupVariableManager, widgetDescription, this.props.getWidgetDescriptors()); groupChildren.add(new Element(WidgetComponent.class, widgetComponentProps)); } else if (controlDescription instanceof ForDescription forDescription) { - ForComponentProps forComponentProps = new ForComponentProps(groupVariableManager, forDescription); + ForComponentProps forComponentProps = new ForComponentProps(groupVariableManager, forDescription, this.props.getWidgetDescriptors()); groupChildren.add(new Element(ForComponent.class, forComponentProps)); } } diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/GroupComponentProps.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/GroupComponentProps.java index 82fba286e6..291feb507a 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/GroupComponentProps.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/GroupComponentProps.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 Obeo. + * Copyright (c) 2019, 2023 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,9 +12,11 @@ *******************************************************************************/ package org.eclipse.sirius.components.forms.components; +import java.util.List; import java.util.Objects; import org.eclipse.sirius.components.forms.description.GroupDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IProps; import org.eclipse.sirius.components.representations.VariableManager; @@ -28,9 +30,12 @@ public class GroupComponentProps implements IProps { private GroupDescription groupDescription; - public GroupComponentProps(VariableManager variableManager, GroupDescription groupDescription) { + private final List widgetDescriptors; + + public GroupComponentProps(VariableManager variableManager, GroupDescription groupDescription, List widgetDescriptors) { this.variableManager = Objects.requireNonNull(variableManager); this.groupDescription = Objects.requireNonNull(groupDescription); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); } public VariableManager getVariableManager() { @@ -40,4 +45,8 @@ public VariableManager getVariableManager() { public GroupDescription getGroupDescription() { return this.groupDescription; } + + public List getWidgetDescriptors() { + return this.widgetDescriptors; + } } diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/IfComponent.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/IfComponent.java index bc75fc4be4..6e59883aab 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/IfComponent.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/IfComponent.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 Obeo. + * Copyright (c) 2019, 2023 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 @@ -36,7 +36,7 @@ public Element render() { IfDescription ifDescription = this.props.getIfDescription(); Boolean result = ifDescription.getPredicate().apply(variableManager); if (result.booleanValue()) { - WidgetComponentProps widgetComponentProps = new WidgetComponentProps(variableManager, ifDescription.getWidgetDescription()); + WidgetComponentProps widgetComponentProps = new WidgetComponentProps(variableManager, ifDescription.getWidgetDescription(), this.props.getWidgetDescriptors()); return new Element(WidgetComponent.class, widgetComponentProps); } return null; diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/IfComponentProps.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/IfComponentProps.java index 8496a2e61c..5ca9068196 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/IfComponentProps.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/IfComponentProps.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 Obeo. + * Copyright (c) 2019, 2023 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,9 +12,11 @@ *******************************************************************************/ package org.eclipse.sirius.components.forms.components; +import java.util.List; import java.util.Objects; import org.eclipse.sirius.components.forms.description.IfDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IProps; import org.eclipse.sirius.components.representations.VariableManager; @@ -28,9 +30,13 @@ public class IfComponentProps implements IProps { private IfDescription ifDescription; - public IfComponentProps(VariableManager variableManager, IfDescription ifDescription) { + private final List widgetDescriptors; + + public IfComponentProps(VariableManager variableManager, IfDescription ifDescription, List widgetDescriptors) { this.variableManager = Objects.requireNonNull(variableManager); this.ifDescription = Objects.requireNonNull(ifDescription); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); + } public VariableManager getVariableManager() { @@ -40,4 +46,8 @@ public VariableManager getVariableManager() { public IfDescription getIfDescription() { return this.ifDescription; } + + public List getWidgetDescriptors() { + return this.widgetDescriptors; + } } diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/PageComponent.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/PageComponent.java index 41321c4de4..b745bdef51 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/PageComponent.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/PageComponent.java @@ -55,7 +55,7 @@ public Element render() { // @formatter:off List groupComponents = pageDescription.getGroupDescriptions().stream() .map(groupDescription -> { - GroupComponentProps groupComponentProps = new GroupComponentProps(pageVariableManager, groupDescription); + GroupComponentProps groupComponentProps = new GroupComponentProps(pageVariableManager, groupDescription, this.props.getWidgetDescriptors()); return new Element(GroupComponent.class, groupComponentProps); }) .toList(); diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/PageComponentProps.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/PageComponentProps.java index 604909af91..84c26aefb7 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/PageComponentProps.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/PageComponentProps.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 Obeo. + * Copyright (c) 2019, 2023 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,9 +12,11 @@ *******************************************************************************/ package org.eclipse.sirius.components.forms.components; +import java.util.List; import java.util.Objects; import org.eclipse.sirius.components.forms.description.PageDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IProps; import org.eclipse.sirius.components.representations.VariableManager; @@ -28,9 +30,12 @@ public class PageComponentProps implements IProps { private PageDescription pageDescription; - public PageComponentProps(VariableManager variableManager, PageDescription pageDescription) { + private final List widgetDescriptors; + + public PageComponentProps(VariableManager variableManager, PageDescription pageDescription, List widgetDescriptors) { this.variableManager = Objects.requireNonNull(variableManager); this.pageDescription = Objects.requireNonNull(pageDescription); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); } public VariableManager getVariableManager() { @@ -40,4 +45,8 @@ public VariableManager getVariableManager() { public PageDescription getPageDescription() { return this.pageDescription; } + + public List getWidgetDescriptors() { + return this.widgetDescriptors; + } } diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/WidgetComponent.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/WidgetComponent.java index 2d426d52a1..f17e292356 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/WidgetComponent.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/WidgetComponent.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2022 Obeo. + * Copyright (c) 2019, 2023 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 @@ -30,6 +30,7 @@ import org.eclipse.sirius.components.forms.description.TextareaDescription; import org.eclipse.sirius.components.forms.description.TextfieldDescription; import org.eclipse.sirius.components.forms.description.TreeDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.Element; import org.eclipse.sirius.components.representations.IComponent; import org.eclipse.sirius.components.representations.VariableManager; @@ -92,7 +93,7 @@ public Element render() { ChartWidgetComponentProps chartComponentProps = new ChartWidgetComponentProps(variableManager, (ChartWidgetDescription) widgetDescription); element = new Element(ChartWidgetComponent.class, chartComponentProps); } else if (widgetDescription instanceof FlexboxContainerDescription) { - FlexboxContainerComponentProps flexboxContainerProps = new FlexboxContainerComponentProps(variableManager, (FlexboxContainerDescription) widgetDescription); + FlexboxContainerComponentProps flexboxContainerProps = new FlexboxContainerComponentProps(variableManager, (FlexboxContainerDescription) widgetDescription, this.props.getWidgetDescriptors()); element = new Element(FlexboxContainerComponent.class, flexboxContainerProps); } else if (widgetDescription instanceof TreeDescription) { TreeComponentProps treeComponentProps = new TreeComponentProps(variableManager, (TreeDescription) widgetDescription); @@ -104,8 +105,17 @@ public Element render() { RichTextComponentProps richTextComponentProps = new RichTextComponentProps(variableManager, (RichTextDescription) widgetDescription); element = new Element(RichTextComponent.class, richTextComponentProps); } else { - String pattern = "Unsupported widget description: {}"; - this.logger.warn(pattern, widgetDescription.getClass().getSimpleName()); + for (IWidgetDescriptor widgetDescriptor : this.props.getWidgetDescriptors()) { + var optionalElement = widgetDescriptor.createElement(variableManager, widgetDescription); + if (optionalElement.isPresent()) { + element = optionalElement.get(); + break; + } + } + if (element == null) { + String pattern = "Unsupported widget description: {}"; + this.logger.warn(pattern, widgetDescription.getClass().getSimpleName()); + } } return element; } diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/WidgetComponentProps.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/WidgetComponentProps.java index a1a01223fa..fc6a374296 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/WidgetComponentProps.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/components/WidgetComponentProps.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 Obeo. + * Copyright (c) 2019, 2023 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,9 +12,11 @@ *******************************************************************************/ package org.eclipse.sirius.components.forms.components; +import java.util.List; import java.util.Objects; import org.eclipse.sirius.components.forms.description.AbstractWidgetDescription; +import org.eclipse.sirius.components.forms.renderer.IWidgetDescriptor; import org.eclipse.sirius.components.representations.IProps; import org.eclipse.sirius.components.representations.VariableManager; @@ -28,9 +30,12 @@ public class WidgetComponentProps implements IProps { private AbstractWidgetDescription widgetDescription; - public WidgetComponentProps(VariableManager variableManager, AbstractWidgetDescription widgetDescription) { + private final List widgetDescriptors; + + public WidgetComponentProps(VariableManager variableManager, AbstractWidgetDescription widgetDescription, List widgetDescriptors) { this.variableManager = Objects.requireNonNull(variableManager); this.widgetDescription = Objects.requireNonNull(widgetDescription); + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); } public VariableManager getVariableManager() { @@ -40,4 +45,8 @@ public VariableManager getVariableManager() { public AbstractWidgetDescription getWidgetDescription() { return this.widgetDescription; } + + public List getWidgetDescriptors() { + return this.widgetDescriptors; + } } diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormComponentPropsValidator.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormComponentPropsValidator.java index f8b5f136e3..9e73f9ae25 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormComponentPropsValidator.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormComponentPropsValidator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2022 Obeo. + * Copyright (c) 2019, 2023 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,9 @@ *******************************************************************************/ package org.eclipse.sirius.components.forms.renderer; +import java.util.List; +import java.util.Objects; + import org.eclipse.sirius.components.charts.barchart.components.BarChartComponent; import org.eclipse.sirius.components.charts.barchart.components.BarChartComponentProps; import org.eclipse.sirius.components.charts.piechart.components.PieChartComponent; @@ -71,6 +74,11 @@ * @author sbegaudeau */ public class FormComponentPropsValidator implements IComponentPropsValidator { + private final List widgetDescriptors; + + public FormComponentPropsValidator(List widgetDescriptors) { + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); + } @Override @SuppressWarnings("checkstyle:JavaNCSS") @@ -127,9 +135,13 @@ public boolean validateComponentProps(Class componentType, IProps props) { checkValidProps = props instanceof RichTextComponentProps; } else if (ToolbarActionComponent.class.equals(componentType)) { checkValidProps = props instanceof ToolbarActionComponentProps; + } else { + checkValidProps = this.widgetDescriptors.stream() + .filter(widgetDescriptor -> Objects.equals(componentType, widgetDescriptor.getComponentClass())) + .findFirst() + .map(descriptor -> descriptor.getComponentPropsClass().isInstance(props)) + .orElse(false); } - return checkValidProps; } - } diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormElementFactory.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormElementFactory.java index b8dd4d1367..1f8b1940e8 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormElementFactory.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormElementFactory.java @@ -14,6 +14,8 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; +import java.util.Optional; import org.eclipse.sirius.components.charts.IChart; import org.eclipse.sirius.components.charts.barchart.BarChart; @@ -72,6 +74,11 @@ * @author sbegaudeau */ public class FormElementFactory implements IElementFactory { + private final List widgetDescriptors; + + public FormElementFactory(List widgetDescriptors) { + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); + } @Override @SuppressWarnings("checkstyle:JavaNCSS") @@ -121,6 +128,16 @@ public Object instantiateElement(String type, IProps props, List childre object = this.instantiateRichText((RichTextElementProps) props, children); } else if (ToolbarActionElementProps.TYPE.equals(type) && props instanceof ToolbarActionElementProps) { object = this.instantiateToolbarAction((ToolbarActionElementProps) props, children); + } else { + for (IWidgetDescriptor widgetDescriptor : this.widgetDescriptors) { + if (widgetDescriptor.getWidgetType().equals(type) && widgetDescriptor.getInstancePropsClass().isInstance(props)) { + Optional optionalInstance = widgetDescriptor.instanciate(props, children); + if (optionalInstance.isPresent()) { + object = optionalInstance.get(); + break; + } + } + } } return object; @@ -404,9 +421,9 @@ private Link instantiateLink(LinkElementProps props, List children) { // @formatter:off Link.Builder linkbuilder = Link.newLink(props.getId()) - .label(props.getLabel()) - .url(props.getUrl()) - .diagnostics(diagnostics); + .label(props.getLabel()) + .url(props.getUrl()) + .diagnostics(diagnostics); // @formatter:on if (props.getStyle() != null) { @@ -423,9 +440,9 @@ private Button instantiateButton(ButtonElementProps props, List children // @formatter:off Button.Builder buttonBuilder = Button.newButton(props.getId()) - .label(props.getLabel()) - .pushButtonHandler(props.getPushButtonHandler()) - .diagnostics(diagnostics); + .label(props.getLabel()) + .pushButtonHandler(props.getPushButtonHandler()) + .diagnostics(diagnostics); // @formatter:on if (props.getIconURL() != null) { buttonBuilder.iconURL(props.getIconURL()); @@ -448,9 +465,9 @@ private ToolbarAction instantiateToolbarAction(ToolbarActionElementProps props, // @formatter:off ToolbarAction.Builder buttonBuilder = ToolbarAction.newToolbarAction(props.getId()) - .label(props.getLabel()) - .pushButtonHandler(props.getPushButtonHandler()) - .diagnostics(diagnostics); + .label(props.getLabel()) + .pushButtonHandler(props.getPushButtonHandler()) + .diagnostics(diagnostics); // @formatter:on if (props.getIconURL() != null) { buttonBuilder.iconURL(props.getIconURL()); @@ -515,13 +532,13 @@ private FlexboxContainer instantiateFlexboxContainer(FlexboxContainerElementProp .toList(); return FlexboxContainer.newFlexboxContainer(props.getId()) - .label(props.getLabel()) - .flexDirection(props.getFlexDirection().toString()) - .flexWrap("wrap") - .flexGrow(1) - .children(widgets) - .diagnostics(diagnostics) - .build(); + .label(props.getLabel()) + .flexDirection(props.getFlexDirection().toString()) + .flexWrap("wrap") + .flexGrow(1) + .children(widgets) + .diagnostics(diagnostics) + .build(); // @formatter:on } @@ -544,9 +561,9 @@ private Image instantiateImage(ImageElementProps props, List children) { // @formatter:off Image.Builder imagebuilder = Image.newImage(props.getId()) - .label(props.getLabel()) - .url(props.getUrl()) - .diagnostics(diagnostics); + .label(props.getLabel()) + .url(props.getUrl()) + .diagnostics(diagnostics); // @formatter:on if (props.getIconURL() != null) { diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormInstancePropsValidator.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormInstancePropsValidator.java index 0cc3e3b994..eb44079ac1 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormInstancePropsValidator.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormInstancePropsValidator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2022 Obeo. + * Copyright (c) 2019, 2023 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,9 @@ *******************************************************************************/ package org.eclipse.sirius.components.forms.renderer; +import java.util.List; +import java.util.Objects; + import org.eclipse.sirius.components.charts.barchart.elements.BarChartElementProps; import org.eclipse.sirius.components.charts.piechart.elements.PieChartElementProps; import org.eclipse.sirius.components.forms.elements.ButtonElementProps; @@ -44,6 +47,12 @@ */ public class FormInstancePropsValidator implements IInstancePropsValidator { + private final List widgetDescriptors; + + public FormInstancePropsValidator(List widgetDescriptors) { + this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors); + } + @Override @SuppressWarnings("checkstyle:JavaNCSS") public boolean validateInstanceProps(String type, IProps props) { @@ -93,6 +102,12 @@ public boolean validateInstanceProps(String type, IProps props) { checkValidProps = props instanceof RichTextElementProps; } else if (ToolbarActionElementProps.TYPE.equals(type)) { checkValidProps = props instanceof ToolbarActionElementProps; + } else { + checkValidProps = this.widgetDescriptors.stream() + .filter(widgetDescriptor -> Objects.equals(type, widgetDescriptor.getWidgetType())) + .findFirst() + .map(descriptor -> descriptor.getInstancePropsClass().isInstance(props)) + .orElse(false); } return checkValidProps; diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormRenderer.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormRenderer.java index 1d076892de..b7174226da 100644 --- a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormRenderer.java +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/FormRenderer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2021 Obeo. + * Copyright (c) 2019, 2023 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 @@ *******************************************************************************/ package org.eclipse.sirius.components.forms.renderer; +import java.util.List; import java.util.Optional; import org.eclipse.sirius.components.forms.Form; @@ -33,8 +34,8 @@ public class FormRenderer { private final BaseRenderer baseRenderer; - public FormRenderer() { - this.baseRenderer = new BaseRenderer(new FormInstancePropsValidator(), new FormComponentPropsValidator(), new FormElementFactory()); + public FormRenderer(List widgetDescriptors) { + this.baseRenderer = new BaseRenderer(new FormInstancePropsValidator(widgetDescriptors), new FormComponentPropsValidator(widgetDescriptors), new FormElementFactory(widgetDescriptors)); } public Form render(Element element) { diff --git a/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/IWidgetDescriptor.java b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/IWidgetDescriptor.java new file mode 100644 index 0000000000..0892b60621 --- /dev/null +++ b/packages/forms/backend/sirius-components-forms/src/main/java/org/eclipse/sirius/components/forms/renderer/IWidgetDescriptor.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2023 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.renderer; + +import java.util.List; +import java.util.Optional; + +import org.eclipse.sirius.components.forms.description.AbstractWidgetDescription; +import org.eclipse.sirius.components.representations.Element; +import org.eclipse.sirius.components.representations.IComponent; +import org.eclipse.sirius.components.representations.IProps; +import org.eclipse.sirius.components.representations.VariableManager; + +/** + * A descriptor for a custom widget type so that it can be rendered. + * + * @author pcdavid + */ +public interface IWidgetDescriptor { + String getWidgetType(); + + Class getComponentClass(); + + Class getInstancePropsClass(); + + Class getComponentPropsClass(); + + Optional instanciate(IProps elementProps, List children); + + Optional createElement(VariableManager variableManager, AbstractWidgetDescription widgetDescription); +} diff --git a/packages/forms/backend/sirius-components-forms/src/test/java/org/eclipse/sirius/components/forms/render/RenderTextfieldTest.java b/packages/forms/backend/sirius-components-forms/src/test/java/org/eclipse/sirius/components/forms/render/RenderTextfieldTest.java index d2a87f9dde..243f9cb6e2 100644 --- a/packages/forms/backend/sirius-components-forms/src/test/java/org/eclipse/sirius/components/forms/render/RenderTextfieldTest.java +++ b/packages/forms/backend/sirius-components-forms/src/test/java/org/eclipse/sirius/components/forms/render/RenderTextfieldTest.java @@ -121,8 +121,8 @@ public void testRenderTextfieldWithProposalProvider() { private Form renderForm(FormDescription formDescription) { VariableManager variableManager = new VariableManager(); variableManager.put(VariableManager.SELF, this.self); - FormComponentProps props = new FormComponentProps(variableManager, formDescription); - Form form = new FormRenderer().render(new Element(FormComponent.class, props)); + FormComponentProps props = new FormComponentProps(variableManager, formDescription, List.of()); + Form form = new FormRenderer(List.of()).render(new Element(FormComponent.class, props)); return form; } diff --git a/packages/forms/frontend/sirius-components-forms/src/form/Form.types.ts b/packages/forms/frontend/sirius-components-forms/src/form/Form.types.ts index 8757d4a65e..d8d5f34a51 100644 --- a/packages/forms/frontend/sirius-components-forms/src/form/Form.types.ts +++ b/packages/forms/frontend/sirius-components-forms/src/form/Form.types.ts @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021, 2022 Obeo. + * Copyright (c) 2021, 2023 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 @@ -11,7 +11,7 @@ * Obeo - initial API and implementation *******************************************************************************/ import { Selection } from '@eclipse-sirius/sirius-components-core'; -import { GQLForm, GQLPage, GQLWidgetSubscription } from './FormEventFragments.types'; +import { GQLForm, GQLPage, GQLSubscriber, GQLWidget, GQLWidgetSubscription } from './FormEventFragments.types'; export interface FormProps { editingContextId: string; @@ -25,3 +25,21 @@ export interface FormState { selectedPage: GQLPage; pages: GQLPage[]; } + +export type PropertySectionComponentProps = { + editingContextId: string; + formId: string; + widget: W; + subscribers: GQLSubscriber[]; + readOnly: boolean; +}; + +export type PropertySectionComponent = ( + props: PropertySectionComponentProps +) => JSX.Element | null; + +export interface WidgetContribution { + name: string; + fields: string; + icon: JSX.Element; +} diff --git a/packages/forms/frontend/sirius-components-forms/src/form/FormContext.ts b/packages/forms/frontend/sirius-components-forms/src/form/FormContext.ts new file mode 100644 index 0000000000..bd6616432c --- /dev/null +++ b/packages/forms/frontend/sirius-components-forms/src/form/FormContext.ts @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2023 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 React from 'react'; +import { PropertySectionComponentRegistry } from './FormContext.types'; +import { GQLWidget } from './FormEventFragments.types'; + +const propertySectionsRegistry: PropertySectionComponentRegistry = { + getComponent: (widget: GQLWidget) => { + return null; + }, + getPreviewComponent: (widget: GQLWidget) => { + return null; + }, + getWidgetContributions: () => [], +}; + +const value = { + propertySectionsRegistry, +}; +export const PropertySectionContext = React.createContext(value); diff --git a/packages/forms/frontend/sirius-components-forms/src/form/FormContext.types.ts b/packages/forms/frontend/sirius-components-forms/src/form/FormContext.types.ts new file mode 100644 index 0000000000..9c7ad1db46 --- /dev/null +++ b/packages/forms/frontend/sirius-components-forms/src/form/FormContext.types.ts @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2023 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 } from '@eclipse-sirius/sirius-components-core'; +import { PropertySectionComponent, WidgetContribution } from './Form.types'; +import { GQLWidget } from './FormEventFragments.types'; + +interface PreviewWidgetProps { + widget: GQLWidget; + selection: Selection; + setSelection: (newSelection: Selection) => void; + onDropBefore: (event: React.DragEvent, widget: GQLWidget) => void; +} + +type PreviewWidgetComponent = (props: PreviewWidgetProps) => JSX.Element | null; + +export type PropertySectionComponentRegistry = { + getComponent: (widget: GQLWidget) => PropertySectionComponent | null; + getPreviewComponent: (widget: GQLWidget) => PreviewWidgetComponent | null; + getWidgetContributions: () => WidgetContribution[]; +}; diff --git a/packages/forms/frontend/sirius-components-forms/src/form/FormEventFragments.ts b/packages/forms/frontend/sirius-components-forms/src/form/FormEventFragments.ts index 404b922672..98cbf8c47b 100644 --- a/packages/forms/frontend/sirius-components-forms/src/form/FormEventFragments.ts +++ b/packages/forms/frontend/sirius-components-forms/src/form/FormEventFragments.ts @@ -11,6 +11,8 @@ * Obeo - initial API and implementation *******************************************************************************/ +import { WidgetContribution } from './Form.types'; + export const subscribersUpdatedEventPayloadFragment = ` fragment subscribersUpdatedEventPayloadFragment on SubscribersUpdatedEventPayload { id @@ -44,7 +46,7 @@ export const commonFields = ` } `; -export const widgetFields = ` +export const widgetFields = (contributions: Array) => ` ${commonFields} fragment textfieldFields on Textfield { @@ -296,6 +298,15 @@ export const widgetFields = ` stringValue: value } + ${contributions.map( + (widget) => + ` + fragment ${widget.name.toLowerCase()}Fields on ${widget.name} { + ${widget.fields} + } + ` + )} + fragment widgetFields on Widget { ...commonFields ... on Textfield { @@ -343,12 +354,21 @@ export const widgetFields = ` ... on RichText { ...richTextFields } + + ${contributions.map( + (widget) => + ` + ... on ${widget.name} { + ...${widget.name.toLowerCase()}Fields + } + ` + )} } `; -export const flexboxContainerFields = ` +export const flexboxContainerFields = (contributions: Array) => ` ${commonFields} - ${widgetFields} + ${widgetFields(contributions)} fragment flexboxContainerFields on FlexboxContainer { ...commonFields label @@ -381,9 +401,9 @@ export const flexboxContainerFields = ` } `; -export const formRefreshedEventPayloadFragment = ` - ${widgetFields} - ${flexboxContainerFields} +export const formRefreshedEventPayloadFragment = (contributions: Array) => ` + ${widgetFields(contributions)} + ${flexboxContainerFields(contributions)} fragment formRefreshedEventPayloadFragment on FormRefreshedEventPayload { id form { diff --git a/packages/forms/frontend/sirius-components-forms/src/index.ts b/packages/forms/frontend/sirius-components-forms/src/index.ts index 3563391037..456d116d36 100644 --- a/packages/forms/frontend/sirius-components-forms/src/index.ts +++ b/packages/forms/frontend/sirius-components-forms/src/index.ts @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo and others. + * Copyright (c) 2022, 2023 Obeo and others. * 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 @@ -10,19 +10,23 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ +export * from './form/Form.types'; +export * from './form/FormContext'; +export * from './form/FormContext.types'; export * from './form/FormEventFragments'; export * from './form/FormEventFragments.types'; export type { ButtonStyleProps } from './propertysections/ButtonPropertySection.types'; export type { CheckboxStyleProps } from './propertysections/CheckboxPropertySection.types'; -export * from './propertysections/getTextDecorationLineValue'; export type { ImageStyleProps } from './propertysections/ImagePropertySection.types'; export type { LabelStyleProps } from './propertysections/LabelWidgetPropertySection.types'; export type { LinkStyleProps } from './propertysections/LinkPropertySection.types'; export type { ListStyleProps } from './propertysections/ListPropertySection.types'; export type { MultiSelectStyleProps } from './propertysections/MultiSelectPropertySection.types'; +export * from './propertysections/PropertySectionLabel'; export type { RadioStyleProps } from './propertysections/RadioPropertySection.types'; export type { SelectStyleProps } from './propertysections/SelectPropertySection.types'; export type { TextfieldStyleProps } from './propertysections/TextfieldPropertySection.types'; +export * from './propertysections/getTextDecorationLineValue'; export * from './representations/FormRepresentation'; export * from './views/DetailsView'; export * from './views/RelatedElementsView'; diff --git a/packages/forms/frontend/sirius-components-forms/src/propertysections/PropertySection.tsx b/packages/forms/frontend/sirius-components-forms/src/propertysections/PropertySection.tsx index 3e3dd4f4cc..2035d07b3e 100644 --- a/packages/forms/frontend/sirius-components-forms/src/propertysections/PropertySection.tsx +++ b/packages/forms/frontend/sirius-components-forms/src/propertysections/PropertySection.tsx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Obeo. + * Copyright (c) 2022, 2023 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 @@ -10,6 +10,8 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ +import { useContext } from 'react'; +import { PropertySectionContext } from '../form/FormContext'; import { GQLButton, GQLChartWidget, @@ -71,6 +73,8 @@ export const PropertySection = ({ }: PropertySectionProps) => { let subscribers = []; + const { propertySectionsRegistry } = useContext(PropertySectionContext); + widgetSubscriptions .filter((subscription) => subscription.widgetId === widget.id) .forEach((subscription) => subscribers.push(...subscription.subscribers)); @@ -190,7 +194,21 @@ export const PropertySection = ({ /> ); } else { - console.error(`Unsupported widget type ${widget.__typename}`); + const CustomWidgetComponent = propertySectionsRegistry.getComponent(widget); + if (CustomWidgetComponent) { + propertySection = ( + + ); + } else { + console.error(`Unsupported widget type ${widget.__typename}`); + } } return propertySection; }; diff --git a/packages/forms/frontend/sirius-components-forms/src/representations/FormRepresentation.tsx b/packages/forms/frontend/sirius-components-forms/src/representations/FormRepresentation.tsx index 506550a1c6..5d633779fc 100644 --- a/packages/forms/frontend/sirius-components-forms/src/representations/FormRepresentation.tsx +++ b/packages/forms/frontend/sirius-components-forms/src/representations/FormRepresentation.tsx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2022 Obeo. + * Copyright (c) 2019, 2023 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 @@ -14,12 +14,14 @@ import { gql, useSubscription } from '@apollo/client'; import { RepresentationComponentProps } from '@eclipse-sirius/sirius-components-core'; import IconButton from '@material-ui/core/IconButton'; import Snackbar from '@material-ui/core/Snackbar'; -import { makeStyles } from '@material-ui/core/styles'; import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; import { useMachine } from '@xstate/react'; -import { useEffect } from 'react'; +import { useContext, useEffect } from 'react'; import { Form } from '../form/Form'; +import { WidgetContribution } from '../form/Form.types'; +import { PropertySectionContext } from '../form/FormContext'; import { formRefreshedEventPayloadFragment, subscribersUpdatedEventPayloadFragment, @@ -30,16 +32,17 @@ import { Page } from '../pages/Page'; import { FormRepresentationContext, FormRepresentationEvent, - formRepresentationMachine, HandleCompleteEvent, HandleSubscriptionResultEvent, HideToastEvent, SchemaValue, ShowToastEvent, SwitchFormEvent, + formRepresentationMachine, } from './FormRepresentationMachine'; -const formEventSubscription = gql(` +const formEventSubscription = (contributions: Array) => + gql(` subscription formEvent($input: FormEventInput!) { formEvent(input: $input) { __typename @@ -56,7 +59,7 @@ const formEventSubscription = gql(` } ${subscribersUpdatedEventPayloadFragment} ${widgetSubscriptionsUpdatedEventPayloadFragment} - ${formRefreshedEventPayloadFragment} + ${formRefreshedEventPayloadFragment(contributions)} `); const useFormRepresentationStyles = makeStyles((theme) => ({ @@ -103,27 +106,32 @@ export const FormRepresentation = ({ } }, [representationId, formId, dispatch]); - const { error } = useSubscription(formEventSubscription, { - variables: { - input: { - id, - editingContextId, - formId: representationId, + const { propertySectionsRegistry } = useContext(PropertySectionContext); + + const { error } = useSubscription( + formEventSubscription(propertySectionsRegistry.getWidgetContributions()), + { + variables: { + input: { + id, + editingContextId, + formId: representationId, + }, + }, + fetchPolicy: 'no-cache', + onSubscriptionData: ({ subscriptionData }) => { + const handleDataEvent: HandleSubscriptionResultEvent = { + type: 'HANDLE_SUBSCRIPTION_RESULT', + result: subscriptionData, + }; + dispatch(handleDataEvent); + }, + onSubscriptionComplete: () => { + const completeEvent: HandleCompleteEvent = { type: 'HANDLE_COMPLETE' }; + dispatch(completeEvent); }, - }, - fetchPolicy: 'no-cache', - onSubscriptionData: ({ subscriptionData }) => { - const handleDataEvent: HandleSubscriptionResultEvent = { - type: 'HANDLE_SUBSCRIPTION_RESULT', - result: subscriptionData, - }; - dispatch(handleDataEvent); - }, - onSubscriptionComplete: () => { - const completeEvent: HandleCompleteEvent = { type: 'HANDLE_COMPLETE' }; - dispatch(completeEvent); - }, - }); + } + ); useEffect(() => { if (error) { diff --git a/packages/forms/frontend/sirius-components-forms/src/views/FormBasedView.tsx b/packages/forms/frontend/sirius-components-forms/src/views/FormBasedView.tsx index c21fc52406..e10dfc590e 100644 --- a/packages/forms/frontend/sirius-components-forms/src/views/FormBasedView.tsx +++ b/packages/forms/frontend/sirius-components-forms/src/views/FormBasedView.tsx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2022 Obeo. + * Copyright (c) 2019, 2023 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 @@ -13,12 +13,14 @@ import { gql, useSubscription } from '@apollo/client'; import IconButton from '@material-ui/core/IconButton'; import Snackbar from '@material-ui/core/Snackbar'; -import { makeStyles } from '@material-ui/core/styles'; import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; import { useMachine } from '@xstate/react'; -import { useEffect } from 'react'; +import { useContext, useEffect } from 'react'; import { Form } from '../form/Form'; +import { WidgetContribution } from '../form/Form.types'; +import { PropertySectionContext } from '../form/FormContext'; import { formRefreshedEventPayloadFragment, subscribersUpdatedEventPayloadFragment, @@ -33,16 +35,16 @@ import { FormBasedViewProps } from './FormBasedView.types'; import { FormBasedViewContext, FormBasedViewEvent, - formBasedViewMachine, HandleCompleteEvent, HandleSubscriptionResultEvent, HideToastEvent, SchemaValue, ShowToastEvent, SwitchSelectionEvent, + formBasedViewMachine, } from './FormBasedViewMachine'; -export const getFormEventSubscription = (subscriptionName: string) => { +export const getFormEventSubscription = (subscriptionName: string, contributions: Array) => { return ` subscription ${subscriptionName}($input: PropertiesEventInput!) { ${subscriptionName}(input: $input) { @@ -60,7 +62,7 @@ export const getFormEventSubscription = (subscriptionName: string) => { } ${subscribersUpdatedEventPayloadFragment} ${widgetSubscriptionsUpdatedEventPayloadFragment} - ${formRefreshedEventPayloadFragment} + ${formRefreshedEventPayloadFragment(contributions)} `; }; @@ -110,9 +112,13 @@ export const FormBasedView = ({ objectIds: currentSelection?.entries.map((entry) => entry.id), }; const variables: GQLPropertiesEventVariables = { input }; - + const { propertySectionsRegistry } = useContext(PropertySectionContext); + const formSubscription = getFormEventSubscription( + subscriptionName, + propertySectionsRegistry.getWidgetContributions() + ); const { error } = useSubscription( - gql(getFormEventSubscription(subscriptionName)), + gql(formSubscription), { variables, fetchPolicy: 'no-cache', diff --git a/packages/forms/frontend/sirius-components-forms/src/views/RepresentationsView.tsx b/packages/forms/frontend/sirius-components-forms/src/views/RepresentationsView.tsx index dee013d64d..b99c99eca9 100644 --- a/packages/forms/frontend/sirius-components-forms/src/views/RepresentationsView.tsx +++ b/packages/forms/frontend/sirius-components-forms/src/views/RepresentationsView.tsx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021, 2022 Obeo and others. + * Copyright (c) 2021, 2023 Obeo and others. * 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 @@ -15,11 +15,13 @@ import { gql, useSubscription } from '@apollo/client'; import { WorkbenchViewComponentProps } from '@eclipse-sirius/sirius-components-core'; import IconButton from '@material-ui/core/IconButton'; import Snackbar from '@material-ui/core/Snackbar'; -import { makeStyles } from '@material-ui/core/styles'; import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; import { useMachine } from '@xstate/react'; -import { useEffect } from 'react'; +import { useContext, useEffect } from 'react'; +import { WidgetContribution } from '../form/Form.types'; +import { PropertySectionContext } from '../form/FormContext'; import { formRefreshedEventPayloadFragment, subscribersUpdatedEventPayloadFragment, @@ -32,13 +34,14 @@ import { HideToastEvent, RepresentationsViewContext, RepresentationsViewEvent, - representationsViewMachine, SchemaValue, ShowToastEvent, SwitchSelectionEvent, + representationsViewMachine, } from './RepresentationsViewMachine'; -const representationsEventSubscription = gql(` +const representationsEventSubscription = (contributions: Array) => + gql(` subscription representationsEvent($input: RepresentationsEventInput!) { representationsEvent(input: $input) { __typename @@ -55,7 +58,7 @@ const representationsEventSubscription = gql(` } ${subscribersUpdatedEventPayloadFragment} ${widgetSubscriptionsUpdatedEventPayloadFragment} - ${formRefreshedEventPayloadFragment} + ${formRefreshedEventPayloadFragment(contributions)} `); const useRepresentationsViewStyles = makeStyles((theme) => ({ @@ -88,29 +91,32 @@ export const RepresentationsView = ({ dispatch(switchSelectionEvent); } }, [currentSelection, selection, dispatch]); - - const { error } = useSubscription(representationsEventSubscription, { - variables: { - input: { - id, - editingContextId, - objectId: currentSelection?.id, + const { propertySectionsRegistry } = useContext(PropertySectionContext); + const { error } = useSubscription( + representationsEventSubscription(propertySectionsRegistry.getWidgetContributions()), + { + variables: { + input: { + id, + editingContextId, + objectId: currentSelection?.id, + }, }, - }, - fetchPolicy: 'no-cache', - skip: representationsView === 'empty' || representationsView === 'unsupportedSelection', - onSubscriptionData: ({ subscriptionData }) => { - const handleDataEvent: HandleSubscriptionResultEvent = { - type: 'HANDLE_SUBSCRIPTION_RESULT', - result: subscriptionData, - }; - dispatch(handleDataEvent); - }, - onSubscriptionComplete: () => { - const completeEvent: HandleCompleteEvent = { type: 'HANDLE_COMPLETE' }; - dispatch(completeEvent); - }, - }); + fetchPolicy: 'no-cache', + skip: representationsView === 'empty' || representationsView === 'unsupportedSelection', + onSubscriptionData: ({ subscriptionData }) => { + const handleDataEvent: HandleSubscriptionResultEvent = { + type: 'HANDLE_SUBSCRIPTION_RESULT', + result: subscriptionData, + }; + dispatch(handleDataEvent); + }, + onSubscriptionComplete: () => { + const completeEvent: HandleCompleteEvent = { type: 'HANDLE_COMPLETE' }; + dispatch(completeEvent); + }, + } + ); useEffect(() => { if (error) { diff --git a/packages/selection/backend/sirius-components-collaborative-selection/src/main/java/org/eclipse/sirius/components/collaborative/selection/SelectionEventProcessorFactory.java b/packages/selection/backend/sirius-components-collaborative-selection/src/main/java/org/eclipse/sirius/components/collaborative/selection/SelectionEventProcessorFactory.java index af8bc33cdd..ece061700b 100644 --- a/packages/selection/backend/sirius-components-collaborative-selection/src/main/java/org/eclipse/sirius/components/collaborative/selection/SelectionEventProcessorFactory.java +++ b/packages/selection/backend/sirius-components-collaborative-selection/src/main/java/org/eclipse/sirius/components/collaborative/selection/SelectionEventProcessorFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021 Obeo. + * Copyright (c) 2021, 2023 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 @@ -20,6 +20,7 @@ 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.selection.api.ISelectionEventProcessor; import org.eclipse.sirius.components.collaborative.selection.api.SelectionConfiguration; import org.eclipse.sirius.components.core.api.IEditingContext; @@ -44,12 +45,11 @@ public class SelectionEventProcessorFactory implements IRepresentationEventProce private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; - public SelectionEventProcessorFactory(IRepresentationDescriptionSearchService representationDescriptionSearchService, IObjectService objectService, - ISubscriptionManagerFactory subscriptionManagerFactory, IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry) { - this.representationDescriptionSearchService = Objects.requireNonNull(representationDescriptionSearchService); + public SelectionEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, IObjectService objectService) { + this.representationDescriptionSearchService = Objects.requireNonNull(configuration.getRepresentationDescriptionSearchService()); this.objectService = Objects.requireNonNull(objectService); - this.subscriptionManagerFactory = Objects.requireNonNull(subscriptionManagerFactory); - this.representationRefreshPolicyRegistry = Objects.requireNonNull(representationRefreshPolicyRegistry); + this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory()); + this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry()); } @Override @@ -60,8 +60,7 @@ public boolean canHandle(Class repr @Override public Optional createRepresentationEventProcessor(Class representationEventProcessorClass, IRepresentationConfiguration configuration, IEditingContext editingContext) { - if (ISelectionEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof SelectionConfiguration) { - SelectionConfiguration selectionConfiguration = (SelectionConfiguration) configuration; + if (ISelectionEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof SelectionConfiguration selectionConfiguration) { // @formatter:off Optional optionalSelectionDescription = this.representationDescriptionSearchService diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/test/java/org/eclipse/sirius/web/sample/tests/ViewDetailsRenderingIntegrationTests.java b/packages/sirius-web/backend/sirius-web-sample-application/src/test/java/org/eclipse/sirius/web/sample/tests/ViewDetailsRenderingIntegrationTests.java index 977244028a..b40d5d6407 100644 --- a/packages/sirius-web/backend/sirius-web-sample-application/src/test/java/org/eclipse/sirius/web/sample/tests/ViewDetailsRenderingIntegrationTests.java +++ b/packages/sirius-web/backend/sirius-web-sample-application/src/test/java/org/eclipse/sirius/web/sample/tests/ViewDetailsRenderingIntegrationTests.java @@ -212,8 +212,8 @@ private Form renderForm(EObject eObject, FormDescription formDescription) { variableManager.put(VariableManager.SELF, List.of(eObject)); variableManager.put(IEditingContext.EDITING_CONTEXT, this.editingContext); - FormRenderer formRenderer = new FormRenderer(); - FormComponentProps props = new FormComponentProps(variableManager, formDescription); + FormRenderer formRenderer = new FormRenderer(List.of()); + FormComponentProps props = new FormComponentProps(variableManager, formDescription, List.of()); Element element = new Element(FormComponent.class, props); Form form = formRenderer.render(element); return form; diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/IWidgetConverterProvider.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/IWidgetConverterProvider.java new file mode 100644 index 0000000000..66ca7f553e --- /dev/null +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/IWidgetConverterProvider.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2023 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.view.emf.form; + +import org.eclipse.emf.ecore.util.Switch; +import org.eclipse.sirius.components.core.api.IEditService; +import org.eclipse.sirius.components.core.api.IObjectService; +import org.eclipse.sirius.components.forms.description.AbstractWidgetDescription; +import org.eclipse.sirius.components.interpreter.AQLInterpreter; + +/** + * Provides a switch to convert View-based custom widget descriptions into their API equivalent given an execution context. + * + * @author pcdavid + */ +public interface IWidgetConverterProvider { + Switch getWidgetConverter(AQLInterpreter interpreter, IEditService editService, IObjectService objectService); +} diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverter.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverter.java index 063d9a5236..d578af7bac 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverter.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverter.java @@ -20,12 +20,15 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.ComposedSwitch; import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.util.Switch; import org.eclipse.sirius.components.compatibility.emf.DomainClassPredicate; import org.eclipse.sirius.components.core.api.IEditService; import org.eclipse.sirius.components.core.api.IObjectService; import org.eclipse.sirius.components.forms.GroupDisplayMode; import org.eclipse.sirius.components.forms.description.AbstractControlDescription; +import org.eclipse.sirius.components.forms.description.AbstractWidgetDescription; import org.eclipse.sirius.components.forms.description.ButtonDescription; import org.eclipse.sirius.components.forms.description.FormDescription; import org.eclipse.sirius.components.forms.description.GroupDescription; @@ -60,10 +63,14 @@ public class ViewFormDescriptionConverter implements IRepresentationDescriptionC private final IEditService editService; private final IFormIdProvider formIdProvider; - public ViewFormDescriptionConverter(IObjectService objectService, IEditService editService, IFormIdProvider formIdProvider) { + + private final List customWidgetConverterProviders; + + public ViewFormDescriptionConverter(IObjectService objectService, IEditService editService, IFormIdProvider formIdProvider, List customWidgetConverterProviders) { this.objectService = Objects.requireNonNull(objectService); this.editService = Objects.requireNonNull(editService); this.formIdProvider = Objects.requireNonNull(formIdProvider); + this.customWidgetConverterProviders = Objects.requireNonNull(customWidgetConverterProviders); } @Override @@ -74,7 +81,8 @@ public boolean canConvert(RepresentationDescription representationDescription) { @Override public IRepresentationDescription convert(RepresentationDescription representationDescription, List allRepresentationDescriptions, AQLInterpreter interpreter) { org.eclipse.sirius.components.view.FormDescription viewFormDescription = (org.eclipse.sirius.components.view.FormDescription) representationDescription; - ViewFormDescriptionConverterSwitch dispatcher = new ViewFormDescriptionConverterSwitch(interpreter, this.editService, this.objectService); + List> widgetConverters = this.customWidgetConverterProviders.stream().map(provider -> provider.getWidgetConverter(interpreter, this.editService, this.objectService)).toList(); + Switch dispatcher = new ViewFormDescriptionConverterSwitch(interpreter, this.editService, this.objectService, new ComposedSwitch<>(widgetConverters)); List pageDescriptions = viewFormDescription.getPages() .stream() @@ -98,7 +106,7 @@ public IRepresentationDescription convert(RepresentationDescription representati .build(); } - private PageDescription instantiatePage(org.eclipse.sirius.components.view.PageDescription viewPageDescription, ViewFormDescriptionConverterSwitch dispatcher, + private PageDescription instantiatePage(org.eclipse.sirius.components.view.PageDescription viewPageDescription, Switch dispatcher, AQLInterpreter interpreter) { List groupDescriptions = viewPageDescription.getGroups().stream() @@ -107,7 +115,7 @@ private PageDescription instantiatePage(org.eclipse.sirius.components.view.PageD String descriptionId = this.getDescriptionId(viewPageDescription); return PageDescription.newPageDescription(descriptionId) - .idProvider(getIdProvider(descriptionId)) + .idProvider(this.getIdProvider(descriptionId)) .labelProvider(variableManager -> this.computePageLabel(viewPageDescription, variableManager, interpreter)) .semanticElementsProvider(variableManager -> this.getSemanticElementsProvider(viewPageDescription, variableManager, interpreter)) .canCreatePredicate(variableManager -> this.canCreatePage(viewPageDescription, variableManager, interpreter)) @@ -115,7 +123,7 @@ private PageDescription instantiatePage(org.eclipse.sirius.components.view.PageD .build(); } - private GroupDescription instantiateGroup(org.eclipse.sirius.components.view.GroupDescription viewGroupDescription, ViewFormDescriptionConverterSwitch dispatcher, AQLInterpreter interpreter) { + private GroupDescription instantiateGroup(org.eclipse.sirius.components.view.GroupDescription viewGroupDescription, Switch dispatcher, AQLInterpreter interpreter) { List controlDescriptions = viewGroupDescription.getWidgets().stream() .map(dispatcher::doSwitch) .filter(Objects::nonNull) @@ -131,7 +139,7 @@ private GroupDescription instantiateGroup(org.eclipse.sirius.components.view.Gro String descriptionId = this.getDescriptionId(viewGroupDescription); return GroupDescription.newGroupDescription(descriptionId) - .idProvider(getIdProvider(descriptionId)) + .idProvider(this.getIdProvider(descriptionId)) .labelProvider(variableManager -> this.computeGroupLabel(viewGroupDescription, variableManager, interpreter)) .semanticElementsProvider(variableManager -> this.getSemanticElementsProvider(viewGroupDescription, variableManager, interpreter)) .controlDescriptions(controlDescriptions) diff --git a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverterSwitch.java b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverterSwitch.java index 3601cc10d7..2aeab2e5e3 100644 --- a/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverterSwitch.java +++ b/packages/view/backend/sirius-components-view-emf/src/main/java/org/eclipse/sirius/components/view/emf/form/ViewFormDescriptionConverterSwitch.java @@ -23,6 +23,7 @@ import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.util.Switch; import org.eclipse.sirius.components.charts.barchart.components.BarChartStyle; import org.eclipse.sirius.components.charts.barchart.descriptions.BarChartDescription; import org.eclipse.sirius.components.charts.descriptions.IChartDescription; @@ -82,6 +83,7 @@ import org.eclipse.sirius.components.view.TextAreaDescription; import org.eclipse.sirius.components.view.TextareaDescriptionStyle; import org.eclipse.sirius.components.view.TextfieldDescriptionStyle; +import org.eclipse.sirius.components.view.WidgetDescription; import org.eclipse.sirius.components.view.emf.OperationInterpreter; import org.eclipse.sirius.components.view.util.ViewSwitch; @@ -98,10 +100,13 @@ public class ViewFormDescriptionConverterSwitch extends ViewSwitch customWidgetConverters; + + public ViewFormDescriptionConverterSwitch(AQLInterpreter interpreter, IEditService editService, IObjectService objectService, Switch customWidgetConverters) { this.interpreter = Objects.requireNonNull(interpreter); this.editService = Objects.requireNonNull(editService); this.objectService = Objects.requireNonNull(objectService); + this.customWidgetConverters = Objects.requireNonNull(customWidgetConverters); } @Override @@ -599,6 +604,11 @@ public AbstractWidgetDescription caseImageDescription(org.eclipse.sirius.compone // @formatter:on } + @Override + public AbstractWidgetDescription caseWidgetDescription(WidgetDescription widgetDescription) { + return this.customWidgetConverters.doSwitch(widgetDescription); + } + private IStatus handleItemDeletion(VariableManager variableManager) { variableManager.get(ListComponent.CANDIDATE_VARIABLE, Object.class).ifPresent(this.editService::delete); return new Success(ChangeKind.SEMANTIC_CHANGE, Map.of()); diff --git a/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicFormsTests.java b/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicFormsTests.java index 21657f7144..33e5f6183d 100644 --- a/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicFormsTests.java +++ b/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicFormsTests.java @@ -1281,7 +1281,7 @@ public Optional getObject(IEditingContext editingContext, String objectI IEditService.NoOp editService = new IEditService.NoOp() { }; - ViewFormDescriptionConverter formDescriptionConverter = new ViewFormDescriptionConverter(objectService, editService, new IFormIdProvider.NoOp()); + ViewFormDescriptionConverter formDescriptionConverter = new ViewFormDescriptionConverter(objectService, editService, new IFormIdProvider.NoOp(), List.of()); var viewConverter = new ViewConverter(List.of(), List.of(formDescriptionConverter), new StaticApplicationContext()); List conversionResult = viewConverter.convert(List.of(view), List.of(EcorePackage.eINSTANCE)); assertThat(conversionResult).hasSize(1); @@ -1294,8 +1294,8 @@ public Optional getObject(IEditingContext editingContext, String objectI IEditingContext editingContext = new IEditingContext.NoOp(); variableManager.put(IEditingContext.EDITING_CONTEXT, editingContext); - FormRenderer formRenderer = new FormRenderer(); - FormComponentProps props = new FormComponentProps(variableManager, convertedFormDescription); + FormRenderer formRenderer = new FormRenderer(List.of()); + FormComponentProps props = new FormComponentProps(variableManager, convertedFormDescription, List.of()); Element element = new Element(FormComponent.class, props); return formRenderer.render(element);