Skip to content

Commit

Permalink
[2125] Add the possibility to programmatically order and filter pages…
Browse files Browse the repository at this point in the history
… of a form.

Bug: #2125
Signed-off-by: Florian ROUËNÉ <florian.rouene@obeosoft.com>
  • Loading branch information
frouene committed Jul 7, 2023
1 parent a60f5cf commit 628278f
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 93 deletions.
17 changes: 10 additions & 7 deletions CHANGELOG.adoc
Expand Up @@ -30,8 +30,7 @@ This allows for code which does not depend on Sirius Web and the Document notion

=== Bug fixes

- https://github.com/eclipse-sirius/sirius-components/issues/2058[#2058] [view] Fix an issue where the default icon for List widget candidates was missing when the candidates wer
e not EObjects.
- https://github.com/eclipse-sirius/sirius-components/issues/2058[#2058] [view] Fix an issue where the default icon for List widget candidates was missing when the candidates were not EObjects.
- https://github.com/eclipse-sirius/sirius-components/issues/2060[#2060] [form] Fix an issue where the list widget was displayed on a single line inside a flexbox container, no matter the length of the labels of its items.
- https://github.com/eclipse-sirius/sirius-components/issues/2076[#2076] [sirius-web] Fix `EditingDomainFactoryService` declaration to use an interface.
- https://github.com/eclipse-sirius/sirius-components/issues/2032[#2032] [form] Add domainType on PageDescription in the view DSL and takes into account the impacts for the FormDescriptionAggregator.
Expand Down Expand Up @@ -59,7 +58,10 @@ image:doc/screenshots/ShowIconOptionSelectWidget.jpg[Icons on select widget opti
- https://github.com/eclipse-sirius/sirius-components/issues/2077[#2077] [form] Add the ability to define a border style for groups and flexbox containers.
- https://github.com/eclipse-sirius/sirius-components/issues/2080[#2080] [tree] Add an initial label value when editing tree items label.
- https://github.com/eclipse-sirius/sirius-components/issues/2080[#2080] [tree] Add an inital label value when editing tree items label.
- https://github.com/eclipse-sirius/sirius-components/issues/2090[#2090] [diagram] Add the support for the arrange all on react flow diagram. The arrange all is made with elkjs.
- https://github.com/eclipse-sirius/sirius-components/issues/2090[#2090] [diagram] Add the support for the arrange all on react flow diagram.
The arrange all is made with elkjs.
- https://github.com/eclipse-sirius/sirius-components/issues/2125[#2125] [form] Add the API `IFormPostProcessor` to programmatically modify all forms just before they are published on the subscription.
Note that IFormPostProcessor is a singleton, if several rules must be applied to several forms, a mechanism has to be added to the implementation.

=== Improvements

Expand All @@ -80,7 +82,8 @@ The help text can include multiple lines (separated by `\n`), but no text format
+
image:doc/images/Widget_Help_Tooltip.png[Example of a help tooltip on a widget]
+
- https://github.com/eclipse-sirius/sirius-components/issues/2048[#2048] [diagram] Add a basic support for the resize. It is possible to reduce the size of a node less than the space needed to display all children.
- https://github.com/eclipse-sirius/sirius-components/issues/2048[#2048] [diagram] Add a basic support for the resize.
It is possible to reduce the size of a node less than the space needed to display all children.
- https://github.com/eclipse-sirius/sirius-components/issues/2064[#2064] [forms] Make the `IWidgetDescriptor` API more flexible.
- https://github.com/eclipse-sirius/sirius-components/issues/1618[#1618] [view] Split the view metamodel into dedicated subpackages.
- https://github.com/eclipse-sirius/sirius-components/issues/2083[#2083] [diagram] Add support for edge markers
Expand Down Expand Up @@ -184,14 +187,15 @@ image:doc/screenshots/filterBarFilterButton.png[Filter Bar Filter Button,30%,30%
- https://github.com/eclipse-sirius/sirius-components/issues/1914[#1914] [form] It is now possible for applications to provide their own custom widgets without forking Sirius Components.
See link:doc/how-to/contribute-custom-widget.adoc[the documentation] for more details.

- https://github.com/eclipse-sirius/sirius-components/issues/1830[#1830] [layout] This feature is experimental and can be activated on a diagram by adding "__EXPERIMENTAL" to its name. The new algorithm does the minimum possible to place node without overlap.
- https://github.com/eclipse-sirius/sirius-components/issues/1830[#1830] [layout] This feature is experimental and can be activated on a diagram by adding "__EXPERIMENTAL" to its name.
The new algorithm does the minimum possible to place node without overlap.
- https://github.com/eclipse-sirius/sirius-components/issues/1985[|#1985] [sirius-web] It is now possible to use in-memory View-based representations by registering them in the new `InMemoryViewRegistry`.
These representations can be created programmatically or loaded from `.view` EMF models on startup, and do not need to be stored as documents inside a project in the database.
- https://github.com/eclipse-sirius/sirius-components/issues/1921[#1921] [view] Added a project sirius-components-view-builder.
+
Introducing providers interfaces to help creating view programmatically.
+
Introducing a generator of builders aimed to help creating view programmatically, the generation makes use of emf-merge and modifications to these builders can be annotated to live during future regeneration.
Introducing a generator of builders aimed to help creating view programmatically, the generation makes use of emf-merge and modifications to these builders can be annotated to live during future regeneration.

- https://github.com/eclipse-sirius/sirius-components/issues/1912[#1912] [core] Add the possibility to send feedback messages to the frontend after an action.
- https://github.com/eclipse-sirius/sirius-components/issues/1989[#1989] [diagram] Contribute a new way to render diagrams to evaluate an alternate layouting strategy
Expand Down Expand Up @@ -249,7 +253,6 @@ Such calls will not work anymore since `null` will not be an acceptable value an
+
Removing dependencies from sirius-components-compatibility-emf in the canHandle methods of sirius-components-view-emf services


=== Dependency update

- [form] Switch to lexical 0.8.1
Expand Down
Expand Up @@ -27,7 +27,9 @@
import org.eclipse.sirius.components.collaborative.forms.api.IFormEventHandler;
import org.eclipse.sirius.components.collaborative.forms.api.IFormEventProcessor;
import org.eclipse.sirius.components.collaborative.forms.api.IFormInput;
import org.eclipse.sirius.components.collaborative.forms.api.IFormPostProcessor;
import org.eclipse.sirius.components.collaborative.forms.api.IWidgetSubscriptionManager;
import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorConfiguration;
import org.eclipse.sirius.components.collaborative.forms.dto.FormRefreshedEventPayload;
import org.eclipse.sirius.components.collaborative.forms.dto.RenameFormInput;
import org.eclipse.sirius.components.collaborative.forms.dto.UpdateWidgetFocusInput;
Expand Down Expand Up @@ -84,17 +86,21 @@ public class FormEventProcessor implements IFormEventProcessor {

private final AtomicReference<Form> currentForm = new AtomicReference<>();

public FormEventProcessor(IEditingContext editingContext, FormCreationParameters formCreationParameters, List<IWidgetDescriptor> widgetDescriptors, List<IFormEventHandler> formEventHandlers,
ISubscriptionManager subscriptionManager, IWidgetSubscriptionManager widgetSubscriptionManager, IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry) {
this.logger.trace("Creating the form event processor {}", formCreationParameters.getId());
private final IFormPostProcessor formPostProcessor;

this.editingContext = Objects.requireNonNull(editingContext);
this.formCreationParameters = Objects.requireNonNull(formCreationParameters);
this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors);
this.formEventHandlers = Objects.requireNonNull(formEventHandlers);
public FormEventProcessor(FormEventProcessorConfiguration configuration,
ISubscriptionManager subscriptionManager, IWidgetSubscriptionManager widgetSubscriptionManager,
IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry, IFormPostProcessor formPostProcessor) {
this.logger.trace("Creating the form event processor {}", configuration.formCreationParameters().getId());

this.editingContext = Objects.requireNonNull(configuration.editingContext());
this.formCreationParameters = Objects.requireNonNull(configuration.formCreationParameters());
this.widgetDescriptors = Objects.requireNonNull(configuration.widgetDescriptors());
this.formEventHandlers = Objects.requireNonNull(configuration.formEventHandlers());
this.subscriptionManager = Objects.requireNonNull(subscriptionManager);
this.widgetSubscriptionManager = Objects.requireNonNull(widgetSubscriptionManager);
this.representationRefreshPolicyRegistry = Objects.requireNonNull(representationRefreshPolicyRegistry);
this.formPostProcessor = Objects.requireNonNull(formPostProcessor);

Form form = this.refreshForm();
this.currentForm.set(form);
Expand All @@ -114,16 +120,13 @@ public ISubscriptionManager getSubscriptionManager() {
@Override
public void handle(One<IPayload> payloadSink, Many<ChangeDescription> changeDescriptionSink, IRepresentationInput representationInput) {
IRepresentationInput effectiveInput = representationInput;
if (representationInput instanceof RenameRepresentationInput) {
RenameRepresentationInput renameRepresentationInput = (RenameRepresentationInput) representationInput;
if (representationInput instanceof RenameRepresentationInput renameRepresentationInput) {
effectiveInput = new RenameFormInput(renameRepresentationInput.id(), renameRepresentationInput.editingContextId(), renameRepresentationInput.representationId(),
renameRepresentationInput.newLabel());
}
if (effectiveInput instanceof IFormInput) {
IFormInput formInput = (IFormInput) effectiveInput;
if (effectiveInput instanceof IFormInput formInput) {

if (formInput instanceof UpdateWidgetFocusInput) {
UpdateWidgetFocusInput input = (UpdateWidgetFocusInput) formInput;
if (formInput instanceof UpdateWidgetFocusInput input) {
this.widgetSubscriptionManager.handle(input);

payloadSink.tryEmitValue(new UpdateWidgetFocusSuccessPayload(input.id(), input.widgetId()));
Expand Down Expand Up @@ -159,11 +162,9 @@ public void refresh(ChangeDescription changeDescription) {
}

private boolean shouldRefresh(ChangeDescription changeDescription) {
// @formatter:off
return this.representationRefreshPolicyRegistry.getRepresentationRefreshPolicy(this.formCreationParameters.getFormDescription())
.orElseGet(this::getDefaultRefreshPolicy)
.shouldRefresh(changeDescription);
// @formatter:on

}

Expand All @@ -182,6 +183,8 @@ private Form refreshForm() {
Element element = new Element(FormComponent.class, formComponentProps);
Form form = new FormRenderer(this.widgetDescriptors).render(element);

form = this.formPostProcessor.postProcess(form, variableManager);

this.logger.trace("Form refreshed: {}", form.getId());

return form;
Expand All @@ -192,13 +195,11 @@ public Flux<IPayload> getOutputEvents(IInput input) {
var initialRefresh = Mono.fromCallable(() -> new FormRefreshedEventPayload(input.id(), this.currentForm.get()));
var refreshEventFlux = Flux.concat(initialRefresh, this.sink.asFlux());

// @formatter:off
return Flux.merge(
refreshEventFlux,
this.widgetSubscriptionManager.getFlux(input),
this.subscriptionManager.getFlux(input)
);
// @formatter:on
);
}

@Override
Expand Down
Expand Up @@ -27,7 +27,10 @@
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;
import org.eclipse.sirius.components.collaborative.forms.api.IFormPostProcessor;
import org.eclipse.sirius.components.collaborative.forms.api.IWidgetSubscriptionManagerFactory;
import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorConfiguration;
import org.eclipse.sirius.components.collaborative.forms.configuration.FormEventProcessorFactoryConfiguration;
import org.eclipse.sirius.components.core.api.IEditingContext;
import org.eclipse.sirius.components.core.api.IObjectService;
import org.eclipse.sirius.components.core.api.IRepresentationDescriptionSearchService;
Expand Down Expand Up @@ -61,16 +64,18 @@ public class FormEventProcessorFactory implements IRepresentationEventProcessorF

private final IRepresentationRefreshPolicyRegistry representationRefreshPolicyRegistry;

public FormEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, IObjectService objectService, List<IWidgetDescriptor> widgetDescriptors,
List<IFormEventHandler> formEventHandlers, IWidgetSubscriptionManagerFactory widgetSubscriptionManagerFactory) {
private final IFormPostProcessor formPostProcessor;

public FormEventProcessorFactory(RepresentationEventProcessorFactoryConfiguration configuration, List<IWidgetDescriptor> widgetDescriptors, FormEventProcessorFactoryConfiguration formConfiguration) {
this.representationDescriptionSearchService = Objects.requireNonNull(configuration.getRepresentationDescriptionSearchService());
this.representationSearchService = Objects.requireNonNull(configuration.getRepresentationSearchService());
this.subscriptionManagerFactory = Objects.requireNonNull(configuration.getSubscriptionManagerFactory());
this.objectService = Objects.requireNonNull(objectService);
this.objectService = Objects.requireNonNull(formConfiguration.getObjectService());
this.widgetDescriptors = Objects.requireNonNull(widgetDescriptors);
this.formEventHandlers = Objects.requireNonNull(formEventHandlers);
this.widgetSubscriptionManagerFactory = Objects.requireNonNull(widgetSubscriptionManagerFactory);
this.formEventHandlers = Objects.requireNonNull(formConfiguration.getFormEventHandlers());
this.widgetSubscriptionManagerFactory = Objects.requireNonNull(formConfiguration.getWidgetSubscriptionManagerFactory());
this.representationRefreshPolicyRegistry = Objects.requireNonNull(configuration.getRepresentationRefreshPolicyRegistry());
this.formPostProcessor = Objects.requireNonNull(formConfiguration.getFormPostProcessor());
}

@Override
Expand All @@ -81,39 +86,34 @@ public <T extends IRepresentationEventProcessor> boolean canHandle(Class<T> repr
@Override
public <T extends IRepresentationEventProcessor> Optional<T> createRepresentationEventProcessor(Class<T> representationEventProcessorClass, IRepresentationConfiguration configuration,
IEditingContext editingContext) {
if (IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof FormConfiguration) {
FormConfiguration formConfiguration = (FormConfiguration) configuration;
if (IFormEventProcessor.class.isAssignableFrom(representationEventProcessorClass) && configuration instanceof FormConfiguration formConfiguration) {

Optional<Form> optionalForm = this.representationSearchService.findById(editingContext, formConfiguration.getId(), Form.class);
if (optionalForm.isPresent()) {
Form form = optionalForm.get();
// @formatter:off
Optional<FormDescription> optionalFormDescription = this.representationDescriptionSearchService.findById(editingContext, form.getDescriptionId())
.filter(FormDescription.class::isInstance)
.map(FormDescription.class::cast);
// @formatter:on
Optional<Object> optionalObject = this.objectService.getObject(editingContext, form.getTargetObjectId());
if (optionalFormDescription.isPresent() && optionalObject.isPresent()) {
FormDescription formDescription = optionalFormDescription.get();
Object object = optionalObject.get();

// @formatter:off
FormCreationParameters formCreationParameters = FormCreationParameters.newFormCreationParameters(formConfiguration.getId())
.editingContext(editingContext)
.formDescription(formDescription)
.object(object)
.selection(List.of())
.build();
// @formatter:on

IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(editingContext, formCreationParameters, this.widgetDescriptors, this.formEventHandlers,
this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry);
IRepresentationEventProcessor formEventProcessor = new FormEventProcessor(new FormEventProcessorConfiguration(editingContext, formCreationParameters, this.widgetDescriptors,
this.formEventHandlers),
this.subscriptionManagerFactory.create(), this.widgetSubscriptionManagerFactory.create(), this.representationRefreshPolicyRegistry,
this.formPostProcessor);

// @formatter:off
return Optional.of(formEventProcessor)
.filter(representationEventProcessorClass::isInstance)
.map(representationEventProcessorClass::cast);
// @formatter:on

}
}
Expand Down

0 comments on commit 628278f

Please sign in to comment.