From f25fb696ef64cf363db282fbd33439071f3e93f4 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 | 15 ++--- .../handlers/AddWidgetEventHandler.java | 25 +++++-- .../IWidgetDescriptionProvider.java | 26 +++++++ .../IWidgetPreviewConverterProvider.java | 27 ++++++++ .../FormDescriptionEditorComponent.java | 4 +- .../FormDescriptionEditorComponentProps.java | 21 +++++- .../FormDescriptionEditorGroupComponent.java | 17 +++-- ...mDescriptionEditorGroupComponentProps.java | 21 +++++- ...wFormDescriptionEditorConverterSwitch.java | 17 ++++- ...criptionEditorComponentPropsValidator.java | 9 ++- .../FormDescriptionEditorElementFactory.java | 5 +- ...scriptionEditorInstancePropsValidator.java | 9 ++- .../FormDescriptionEditorRenderer.java | 6 +- .../src/CustomWidget.tsx | 64 ++++++++++++++++++ .../src/FlexboxContainerWidget.tsx | 10 +-- .../src/FormDescriptionEditorEventFragment.ts | 8 +-- .../FormDescriptionEditorRepresentation.tsx | 33 ++++++--- .../src/Group.tsx | 11 +-- .../src/ToolbarActionWidget.tsx | 9 +-- .../src/ToolbarActions.tsx | 13 ++-- .../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 | 6 +- .../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 | 54 +++++++++------ .../renderer/FormInstancePropsValidator.java | 17 ++++- .../forms/renderer/FormRenderer.java | 7 +- .../forms/renderer/IWidgetDescriptor.java | 41 ++++++++++++ .../forms/render/RenderTextfieldTest.java | 6 +- .../src/form/Form.types.ts | 22 +++++- .../src/form/FormContext.ts | 30 +++++++++ .../src/form/FormContext.types.ts | 31 +++++++++ .../src/form/FormEventFragments.ts | 43 ++++++++++-- .../src/form/FormEventFragments.types.ts | 9 ++- .../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 | 13 ++-- .../configuration/SampleEMFConfiguration.java | 2 +- ...erDescriptionPreviewConverterProvider.java | 67 +++++++++++++++++++ .../ViewDetailsRenderingIntegrationTests.java | 4 +- .../emf/form/IWidgetConverterProvider.java | 28 ++++++++ .../form/ViewFormDescriptionConverter.java | 21 +++++- .../ViewFormDescriptionConverterSwitch.java | 12 +++- .../view/emf/view/DynamicFormsTests.java | 6 +- 72 files changed, 1042 insertions(+), 270 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/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/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescriptionPreviewConverterProvider.java 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 9be83586a7..4759da0085 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -37,6 +37,8 @@ In the _styleDescription_, the definition of a color are now a select list of al - https://github.com/eclipse-sirius/sirius-components/issues/1946[1#946] Enabled child extenders in the View DSL implementation. This allows downstream projects and applications to provide their own sub-types of the DSL types (e.g. new WidgetDescriptions). In addition to registering the extension metadmodel itself, users must provide a `ChildExtenderProvider` bean for their extensions to be properly integrated. +- 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. === Improvements 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 4ea2b7874e..ef80f92ce0 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 @@ -231,8 +231,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 19d876582e..d4330035d5 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 @@ -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.diagrams.api.DiagramConfiguration; import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramCreationService; import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramEventHandler; @@ -51,15 +52,14 @@ public class DiagramEventProcessorFactory implements IRepresentationEventProcess private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry; - public DiagramEventProcessorFactory(IRepresentationSearchService representationSearchService, IDiagramCreationService diagramCreationService, List diagramEventHandlers, - ISubscriptionManagerFactory subscriptionManagerFactory, IRepresentationDescriptionSearchService representationDescriptionSearchService, - IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry) { - this.representationSearchService = Objects.requireNonNull(representationSearchService); + public DiagramEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, IDiagramCreationService diagramCreationService, + List diagramEventHandlers) { + 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.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 772aa6d980..1f6a6be053 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 = List.copyOf(widgetDescriptors); + this.customWidgetConverterProviders = List.copyOf(customWidgetConverterProviders); // @formatter:off this.timer = Timer.builder(Monitoring.REPRESENTATION_EVENT_PROCESSOR_REFRESH) @@ -116,10 +124,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..b14a936a40 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 @@ -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..1d91d390ad 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 = List.copyOf(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-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 5d75d55e0b..fa3210917a 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 @@ -50,7 +50,7 @@ public Element render() { // @formatter:off String label = optionalPreviousFormDescriptionEditor.map(FormDescriptionEditor::getLabel) .orElseGet(() -> variableManager.get(FormDescriptionEditor.LABEL, String.class) - .orElse("Form Description Editor")); + .orElse("Form Description Editor")); // @formatter:on Function targetObjectIdProvider = formDescriptionEditorDescription.getTargetObjectIdProvider(); String targetObjectId = targetObjectIdProvider.apply(variableManager); @@ -60,7 +60,7 @@ public Element render() { formDescription.getGroups().forEach(viewGroupDescription -> { VariableManager childVariableManager = variableManager.createChild(); childVariableManager.put(VariableManager.SELF, viewGroupDescription); - FormDescriptionEditorGroupComponentProps fdeGroupComponentProps = new FormDescriptionEditorGroupComponentProps(childVariableManager, this.props.getFormDescriptionEditorDescription()); + FormDescriptionEditorGroupComponentProps fdeGroupComponentProps = new FormDescriptionEditorGroupComponentProps(childVariableManager, this.props.getFormDescriptionEditorDescription(), this.props.getWidgetDescriptors(), this.props.getCustomWidgetConverterProviders()); 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/FormDescriptionEditorComponentProps.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/FormDescriptionEditorComponentProps.java index 12fe90cb27..55be7f2639 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 = List.copyOf(widgetDescriptors); + this.customWidgetConverterProviders = List.copyOf(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 0194258d40..d143714b6e 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 @@ -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 @@ -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..52728e0c85 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 = List.copyOf(widgetDescriptors); + this.customWidgetConverterProviders = List.copyOf(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/ViewFormDescriptionEditorConverterSwitch.java b/packages/formdescriptioneditors/backend/sirius-components-formdescriptioneditors/src/main/java/org/eclipse/sirius/components/formdescriptioneditors/components/ViewFormDescriptionEditorConverterSwitch.java index 4ec05c8ff6..57d1ee0040 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 @@ -14,10 +14,12 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; 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 +66,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 +82,12 @@ public class ViewFormDescriptionEditorConverterSwitch extends ViewSwitch customWidgetConverter; + + public ViewFormDescriptionEditorConverterSwitch(FormDescriptionEditorDescription formDescriptionEditorDescription, VariableManager variableManager, Switch customWidgetConverter) { + this.formDescriptionEditorDescription = Objects.requireNonNull(formDescriptionEditorDescription); + this.variableManager = Objects.requireNonNull(variableManager); + this.customWidgetConverter = Objects.requireNonNull(customWidgetConverter); } @Override @@ -505,6 +511,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 6071c5eab1..f54aa6b017 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 @@ -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.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; import org.eclipse.sirius.components.formdescriptioneditors.components.FormDescriptionEditorGroupComponentProps; 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; @@ -29,8 +32,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 3fff40bb61..d7594064f7 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.Group; 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..31aed7ff52 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 @@ -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/frontend/sirius-components-formdescriptioneditors/src/CustomWidget.tsx b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/CustomWidget.tsx new file mode 100644 index 0000000000..6220e10f65 --- /dev/null +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/CustomWidget.tsx @@ -0,0 +1,64 @@ +/******************************************************************************* + * 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 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 { WidgetProps } from './WidgetEntry.types'; + +type CustomWidgetStyleProps = {}; +const useStyles = makeStyles((theme) => ({ + style: { + color: theme.palette.secondary.main, + }, + selected: { + color: theme.palette.primary.main, + }, +})); + +type CustomWidgetProps = WidgetProps; + +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/FlexboxContainerWidget.tsx b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/FlexboxContainerWidget.tsx index e88e5dc42a..01b7890e67 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 { GQLGroup, GQLToolbarAction, GQLWidget } from '@eclipse-sirius/sirius-components-forms'; +import { GQLGroup, GQLToolbarAction, 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 { @@ -162,6 +162,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); @@ -177,8 +178,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 c8e1606df6..7d5ab0dee3 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 b6ca6d245a..5eeb34ff5d 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 { useMutation, useSubscription } from '@apollo/client'; +import { gql, useMutation, 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'; @@ -33,7 +34,7 @@ import TextFormatIcon from '@material-ui/icons/TextFormat'; import ViewAgendaIcon from '@material-ui/icons/ViewAgenda'; import ViewColumnIcon from '@material-ui/icons/ViewColumn'; import { useMachine } from '@xstate/react'; -import React, { useEffect } from 'react'; +import React, { useContext, useEffect } from 'react'; import { addGroupMutation, formDescriptionEditorEventSubscription, @@ -56,16 +57,16 @@ import { import { FormDescriptionEditorRepresentationContext, FormDescriptionEditorRepresentationEvent, - formDescriptionEditorRepresentationMachine, HandleSubscriptionResultEvent, HideToastEvent, InitializeRepresentationEvent, SchemaValue, ShowToastEvent, + formDescriptionEditorRepresentationMachine, } from './FormDescriptionEditorRepresentationMachine'; import { Group } from './Group'; -import { Button } from './icons/Button'; import { isKind } from './WidgetOperations'; +import { Button } from './icons/Button'; const isErrorPayload = (payload: GQLAddWidgetPayload | GQLMoveWidgetPayload): payload is GQLErrorPayload => payload.__typename === 'ErrorPayload'; @@ -176,9 +177,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', @@ -291,7 +292,7 @@ export const FormDescriptionEditorRepresentation = ({ }; const addGroupVariables: GQLAddGroupMutationVariables = { input: addGroupInput }; addGroup({ variables: addGroupVariables }); - } else if (isKind(id)) { + } else if (isKind(id) || propertySectionsRegistry.getWidgetContributions().find((contrib) => contrib.name === id)) { // forbid to drag and drop new widgets into groups area return; } else { @@ -497,6 +498,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 5fd1dad858..fd3901a8ac 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 { GQLGroup, GQLToolbarAction, GQLWidget } from '@eclipse-sirius/sirius-components-forms'; +import { GQLGroup, GQLToolbarAction, 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, @@ -327,13 +327,14 @@ 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); const id: string = event.dataTransfer.getData('text/plain'); - if (isKind(id)) { + if (isKind(id) || propertySectionsRegistry.getWidgetContributions().find((contrib) => contrib.name === id)) { return; } else if (id === 'Group') { let newGroupIndex: number = formDescriptionEditor.groups.indexOf(group); @@ -381,7 +382,7 @@ export const Group = ({ return; } else if (getAllToolbarActions(formDescriptionEditor).find((tba: GQLToolbarAction) => tba.id === id)) { return; - } else if (isKind(id)) { + } else 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 807ce80960..8061fa4841 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActionWidget.tsx +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActionWidget.tsx @@ -14,16 +14,17 @@ import { useMutation } from '@apollo/client'; import { Selection, ServerContext, ServerContextValue } from '@eclipse-sirius/sirius-components-core'; import { ButtonStyleProps, - getTextDecorationLineValue, GQLButton, GQLGroup, 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'; @@ -281,11 +282,11 @@ 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('text/plain'); // We only accept drop of ToolbarAction, no Widget or Group allowed - if (isKind(id)) { + if (isKind(id) || propertySectionsRegistry.getWidgetContributions().find((contrib) => contrib.name === id)) { return; } else if (id === 'Group') { return; diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActions.tsx b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActions.tsx index 365593e06e..ef4d4cfbe7 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActions.tsx +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/ToolbarActions.tsx @@ -12,14 +12,14 @@ *******************************************************************************/ import { useMutation } from '@apollo/client'; -import { GQLGroup, GQLToolbarAction, GQLWidget } from '@eclipse-sirius/sirius-components-forms'; +import { GQLGroup, GQLToolbarAction, 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 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'; +import { useContext, useEffect, useState } from 'react'; import { addToolbarActionMutation, moveToolbarActionMutation } from './FormDescriptionEditorEventFragment'; import { GQLAddToolbarActionInput, @@ -32,8 +32,8 @@ import { GQLMoveToolbarActionMutationVariables, GQLMoveToolbarActionPayload, } from './FormDescriptionEditorEventFragment.types'; -import { ToolbarActionsProps } from './ToolbarActions.types'; import { ToolbarActionWidget } from './ToolbarActionWidget'; +import { ToolbarActionsProps } from './ToolbarActions.types'; import { getAllWidgets, isKind } from './WidgetOperations'; const useToolbarActionsStyles = makeStyles((theme: Theme) => ({ @@ -78,6 +78,8 @@ export const ToolbarActions = ({ selection, setSelection, }: ToolbarActionsProps) => { + const { propertySectionsRegistry } = useContext(PropertySectionContext); + const classes = useToolbarActionsStyles(); const [message, setMessage] = useState(null); @@ -148,8 +150,7 @@ export const ToolbarActions = ({ event.currentTarget.classList.remove(classes.dragOver); const id: string = event.dataTransfer.getData('text/plain'); - - if (isKind(id)) { + if (isKind(id) || propertySectionsRegistry.getWidgetContributions().find((contrib) => contrib.name === id)) { return; } else if (id === 'Group') { return; diff --git a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.tsx b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.tsx index 36d0e6f074..443c6d3e48 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.tsx +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.tsx @@ -30,16 +30,18 @@ import { GQLTextfield, GQLToolbarAction, 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 @@ -276,7 +280,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, @@ -462,6 +466,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 a712493832..641e9e4eea 100644 --- a/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.types.ts +++ b/packages/formdescriptioneditors/frontend/sirius-components-formdescriptioneditors/src/WidgetEntry.types.ts @@ -45,7 +45,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..e68dbb913a 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 = List.copyOf(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..3fe223405b 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 = List.copyOf(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..3e4f04d7b6 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 = List.copyOf(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..691011c8c0 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 = List.copyOf(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 781a5140b1..96df56553b 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 @@ -77,7 +77,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 @@ -101,7 +101,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)); @@ -129,7 +129,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 b40419ec1e..e922bfa0b8 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 @@ -65,7 +65,7 @@ public Element render() { childVariableManager.put(VariableManager.SELF, candidate); 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 b7a52d626b..06e8c662b6 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,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020, 2022 Obeo. + * Copyright (c) 2019, 2020, 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 @@ -77,11 +77,11 @@ public Element render() { for (AbstractControlDescription controlDescription : controlDescriptions) { if (controlDescription instanceof AbstractWidgetDescription) { AbstractWidgetDescription widgetDescription = (AbstractWidgetDescription) controlDescription; - 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 forDescription = (ForDescription) controlDescription; - 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..e31186afda 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 = List.copyOf(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 42b49a078b..63405b96da 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,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.eclipse.sirius.components.charts.IChart; import org.eclipse.sirius.components.charts.barchart.BarChart; @@ -72,6 +73,11 @@ * @author sbegaudeau */ public class FormElementFactory implements IElementFactory { + private final List widgetDescriptors; + + public FormElementFactory(List widgetDescriptors) { + this.widgetDescriptors = List.copyOf(widgetDescriptors); + } @Override @SuppressWarnings("checkstyle:JavaNCSS") @@ -121,6 +127,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; @@ -400,9 +416,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) { @@ -419,9 +435,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()); @@ -444,9 +460,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()); @@ -511,13 +527,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 } @@ -540,9 +556,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..3ded4808df 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 = List.copyOf(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 1b9758079e..42d089e18c 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 @@ -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 @@ -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..6574ff9121 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,23 @@ export const widgetFields = ` stringValue: value } + ${contributions.map( + (widget) => + ` + fragment ${widget.name.toLowerCase()}Fields on ${widget.name} { + ${widget.fields} + } + ` + )} + + fragment sliderFields on Slider { + label + iconURL + minValue + maxValue + currentValue + } + fragment widgetFields on Widget { ...commonFields ... on Textfield { @@ -343,12 +362,24 @@ export const widgetFields = ` ... on RichText { ...richTextFields } + + ${contributions.map( + (widget) => + ` + ... on ${widget.name} { + ...${widget.name.toLowerCase()}Fields + } + ` + )} + ... on Slider { + ...sliderFields + } } `; -export const flexboxContainerFields = ` +export const flexboxContainerFields = (contributions: Array) => ` ${commonFields} - ${widgetFields} + ${widgetFields(contributions)} fragment flexboxContainerFields on FlexboxContainer { ...commonFields label @@ -381,9 +412,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/form/FormEventFragments.types.ts b/packages/forms/frontend/sirius-components-forms/src/form/FormEventFragments.types.ts index 8a3189f1c6..1e5c124e3f 100644 --- a/packages/forms/frontend/sirius-components-forms/src/form/FormEventFragments.types.ts +++ b/packages/forms/frontend/sirius-components-forms/src/form/FormEventFragments.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 @@ -384,3 +384,10 @@ export interface GQLRichText extends GQLWidget { label: string; stringValue: string; } + +export interface GQLSlider extends GQLWidget { + label: string; + minValue: number; + maxValue: number; + currentValue: number; +} 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..a64627b335 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 @@ -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/main/java/org/eclipse/sirius/web/sample/configuration/SampleEMFConfiguration.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/configuration/SampleEMFConfiguration.java index b313415f3a..ddfb5db62f 100644 --- a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/configuration/SampleEMFConfiguration.java +++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/configuration/SampleEMFConfiguration.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 diff --git a/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescriptionPreviewConverterProvider.java b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescriptionPreviewConverterProvider.java new file mode 100644 index 0000000000..2711b45d16 --- /dev/null +++ b/packages/sirius-web/backend/sirius-web-sample-application/src/main/java/org/eclipse/sirius/web/sample/slider/SliderDescriptionPreviewConverterProvider.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * 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.web.sample.slider; + +import java.util.UUID; + +import org.eclipse.emf.ecore.util.Switch; +import org.eclipse.sirius.components.formdescriptioneditors.IWidgetConverterProvider; +import org.eclipse.sirius.components.formdescriptioneditors.description.FormDescriptionEditorDescription; +import org.eclipse.sirius.components.forms.description.AbstractWidgetDescription; +import org.eclipse.sirius.components.representations.Success; +import org.eclipse.sirius.components.representations.VariableManager; +import org.eclipse.sirius.web.customwidgets.SliderDescription; +import org.eclipse.sirius.web.customwidgets.util.CustomwidgetsSwitch; +import org.springframework.stereotype.Service; + +/** + * Provides the widget converter needed for the Slider widget preview in the context of a Form Description Editor. + * + * @author pcdavid + */ +@Service +public class SliderDescriptionPreviewConverterProvider implements IWidgetConverterProvider { + + @Override + public Switch getWidgetConverter(FormDescriptionEditorDescription formDescriptionEditorDescription, VariableManager variableManager) { + return new CustomwidgetsSwitch<>() { + @Override + public AbstractWidgetDescription caseSliderDescription(SliderDescription sliderDescription) { + VariableManager childVariableManager = variableManager.createChild(); + childVariableManager.put(VariableManager.SELF, sliderDescription); + String id = formDescriptionEditorDescription.getTargetObjectIdProvider().apply(childVariableManager); + return org.eclipse.sirius.web.sample.slider.SliderDescription.newSliderDescription(UUID.randomUUID().toString()) + .idProvider(vm -> id) + .labelProvider(vm -> SliderDescriptionPreviewConverterProvider.this.getWidgetLabel(sliderDescription, "Slider")) + .minValueProvider(vm -> 0) + .maxValueProvider(vm -> 0) + .currentValueProvider(vm -> 50) + .newValueHandler(vm -> new Success()) + .build(); + } + }; + } + + public String getWidgetLabel(org.eclipse.sirius.components.view.WidgetDescription widgetDescription, String defaultLabel) { + String widgetLabel = defaultLabel; + String name = widgetDescription.getName(); + String labelExpression = widgetDescription.getLabelExpression(); + if (labelExpression != null && !labelExpression.isBlank() && !labelExpression.startsWith("aql:")) { + widgetLabel = labelExpression; + } else if (name != null && !name.isBlank()) { + widgetLabel = name; + } + return widgetLabel; + } + +} 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 b01cfeb247..dd761705a6 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 @@ -12,6 +12,8 @@ *******************************************************************************/ package org.eclipse.sirius.components.view.emf.form; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -20,12 +22,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; @@ -58,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 = List.copyOf(customWidgetConverterProviders); } @Override @@ -72,7 +81,13 @@ 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(); + Collection> switches = new ArrayList<>(); + switches.add(new ViewFormDescriptionConverterSwitch(interpreter, this.editService, this.objectService, new ComposedSwitch<>(widgetConverters))); + switches.addAll(widgetConverters); + Switch dispatcher = new ComposedSwitch<>(switches); + // @formatter:off Function> semanticElementsProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class).stream().toList(); @@ -116,7 +131,7 @@ public IRepresentationDescription convert(RepresentationDescription representati // @formatter:on } - 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) { // @formatter:off List controlDescriptions = viewGroupDescription.getWidgets().stream() .map(dispatcher::doSwitch) 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 c78801258a..9adb342d20 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 @@ -1278,7 +1278,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); @@ -1291,8 +1291,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);