Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1988] Add support for optional help text on widgets #2011

Merged
merged 2 commits into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: vscode
path: vscode-extension/sirius-web-2023.6.0.vsix
path: vscode-extension/sirius-web-2023.6.1.vsix
retention-days: 20

- name: Compress the code coverage results
Expand Down
9 changes: 7 additions & 2 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
=== Shapes

- Add disable / enable concept for widgets
- Add support for Help Expressions in Form widgets
- Add new custom widget to edit single and multi-valued references
- Add support for Help Expressions in Form widgets

=== Architectural decision records

- [ADR-103] Improves the existing feedback messages capability
- [ADR-104] Add support for Help Expressions in Form widgets

=== Breaking changes

Expand Down Expand Up @@ -44,7 +45,11 @@ image:doc/screenshots/feedbackMessages.png[Feedback messages,30%,30%]
There is an example of the `IFeedbackMessageService` interface usage in `DomainAttributeServices`.
Note that in the end, the message list will be the only way to return info in payload, the single message will be removed.
- https://github.com/eclipse-sirius/sirius-components/issues/2010[#2010] [diagram] Add a palette on node with the alternate diagram rendering.

- https://github.com/eclipse-sirius/sirius-components/issues/1988[#1988] All Form widgets can now define (if relevant) a dynamically computed "help text".
Widgets which define such a help text have a new "?" icon next to their labels; the actual help text is accessible as a tooltip on this icon.
For View-based widgets, this materializes as an AQL `helpExpression`.
The help text can include multiple lines (separated by `\n`), but no text formatting.
:image:doc/images/Widget_Help_Tooltip.png[Example of a help tooltip on a widget]

== v2023.6.0

Expand Down
112 changes: 112 additions & 0 deletions doc/adrs/104_help_expressions.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
= ADR-104 - Add support for Help Expressions in Form widgets

== Context

In the desktop version of EEF-based properties views, widgets support an optional "Help" text which is exposed as a tooltip on widgets which define one.
This is helpful to add user-oriented documentation on the property represented by the widget.
It is not currently supported in the Sirius Components' _Form_ representation.

== Decision

All widget descriptions in the _Form_ representation (including the View-based Forms) will have an optional "help text provider".
If defined, the corresponding widget instances will have a visible "?" icon which, when hovered, will display the corresponding help text to the end-user.
The help content will be a plain text (no formatting).
It will be computed in the context of the semantic element of the widget so that the text can be adapted to the current state of the element.

== Solution

=== Backend

The overall design of the solution will follow the same approach as for completion support.

We will add a new (optional) field `Function<VariableManager, String> helpTextProvider` to the core `AbstractWidgetDescription` class:

```java
public abstract class AbstractWidgetDescription extends AbstractControlDescription {
// Added:
protected Function<VariableManager, String> helpTextProvider;

public Function<VariableManager, String> getHelpTextProvider() {
return this.helpTextProvider;
}
}
```

When a widget is rendered, this `Function<VariableManager, String>` is specialized into a plain, parameter-less `Supplier<String>` in the widget instance, with the `VariableManager` used for the rendering captured:

```java
public class CheckboxComponent implements IComponent {

@Override
public Element render() {
// ...
if (checkboxDescription.getHelpTextProvider() != null) {
checkboxElementPropsBuilder.helpTextProvider(() -> checkboxDescription.getHelpTextProvider().apply(variableManager));
}
...
}
}
```

This means the value of the help expression will *not* be evaluated as part of the widget's rendering.
In the vast majority of form renders, no help text will need to be displayed for any widget.
Computing them eagerly would incur both an additional runtime cost to each render of each form _and_ a network transfer cost for text values which will never be visible.

Instead, the evaluation of a "help expression" will be done on-demand through a new GraphQL Query:

```
type FormDescription implements RepresentationDescription {
helpText(widgetId: ID!): String
}
```

The event handler for this query will simply need to find the proper widget, and if it has a non-null `Supplier<String> getHelpTextProvider()`, invoke it.

Although the actual help expression is not evaluated at render-time, we will provide a `hasHelpText: Boolean` field for each widget in the GraphQL Schema.
This GraphQL field will be computed using a custom datafetcher:

```java
@QueryDataFetcher(type = "Widget", field = "hasHelpText")
public class WidgetHasHelpTextDataFetcher implements IDataFetcherWithFieldCoordinates<Boolean> {
@Override
public Boolean get(DataFetchingEnvironment environment) throws Exception {
AbstractWidget item = environment.getSource();
return item.getHelpTextProvider() != null;
}
}
```

This attribute will be used by the frontend to know if it should display a visual hint/icon to indicate that a help text is available for the widget.

There will be no caching of the help expression's value.
Each GraphQL Query invocation will trigger the evaluation of the expression.

=== View

In the View DSL, we will add a `helpExpression : IntepretedExpression` attribute the `WidgetDescription` _EClass_.
During the View conversion, we will create a non-null `helpTextProvider` only if the WidgetDescription has a non-null and non-blank `helpExpression`:

```java
if (viewWidgetDescription.getHelpExpression() != null && !viewWidgetDescription.getHelpExpression().isBlank()) {
builder.helpTextProvider(this.getStringValueProvider(viewWidgetDescription.getHelpExpression()));
}
```

This will allow users to clear the `helpExpression` field of a widget definition to mean "no help text".

=== Frontend

On the frontend, the Form representation will fetch the `hasHelpText` for all widgets, and use that to know if some help text is available on a given widget.
When help text is available, a "?" icon (`HelpOutlineOutlined`) will be added to the right of the widget's label text.
If the user hovers the mouse on the icon, the frontend will issue the GraphQL Query mentioned above to retrieve the proper help text, and display it inside a tooltip.

The "preview" version of all widgets displaed inside a _FormDescriptionEditor_ will also show the "?" icon if (and only if) the widget defines a non-empty help expression.
This icon will not show any toolip, it will just be a visual indication that the widget has/will have a help text at runtime.

== Status

Accepted.

== Consequences

A similar feature could be added to all our representations (diagram elements, tree items...), but this is out of scope for the moment.
Binary file added doc/images/Widget_Help_Tooltip.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions integration-tests/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion integration-tests/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sirius-web-integration-tests",
"version": "2023.6.0",
"version": "2023.6.1",
"license": "EPL-2.0",
"private": true,
"devDependencies": {
Expand Down
30 changes: 15 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eclipse-sirius/sirius-components-parent",
"version": "2023.6.0",
"version": "2023.6.1",
"author": "Eclipse Sirius",
"license": "EPL-2.0",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/charts/backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-charts-parent</artifactId>
<version>2023.6.0</version>
<version>2023.6.1</version>

<name>sirius-components-charts-parent</name>
<description>Sirius Components Charts Parent</description>
Expand Down
6 changes: 3 additions & 3 deletions packages/charts/backend/sirius-components-charts/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
</parent>
<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-charts</artifactId>
<version>2023.6.0</version>
<version>2023.6.1</version>
<name>sirius-components-charts</name>
<description>Sirius Components Charts</description>

Expand Down Expand Up @@ -54,7 +54,7 @@
<dependency>
<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-representations</artifactId>
<version>2023.6.0</version>
<version>2023.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand All @@ -64,7 +64,7 @@
<dependency>
<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-tests</artifactId>
<version>2023.6.0</version>
<version>2023.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
</parent>
<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-collaborative-charts</artifactId>
<version>2023.6.0</version>
<version>2023.6.1</version>
<name>sirius-components-collaborative-charts</name>
<description>Sirius Components Collaborative Charts</description>

Expand Down Expand Up @@ -51,23 +51,23 @@
<dependency>
<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-charts</artifactId>
<version>2023.6.0</version>
<version>2023.6.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-collaborative</artifactId>
<version>2023.6.0</version>
<version>2023.6.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-tests</artifactId>
<version>2023.6.0</version>
<version>2023.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-spring-tests</artifactId>
<version>2023.6.0</version>
<version>2023.6.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eclipse-sirius/sirius-components-charts",
"version": "2023.6.0",
"version": "2023.6.1",
"author": "Eclipse Sirius",
"license": "EPL-2.0",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/compatibility/backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

<groupId>org.eclipse.sirius</groupId>
<artifactId>sirius-components-compatibility-parent</artifactId>
<version>2023.6.0</version>
<version>2023.6.1</version>

<name>sirius-components-compatibility-parent</name>
<description>Sirius Components Compatibility Parent</description>
Expand Down