Skip to content

Commit

Permalink
[doc] Update the Selection Dialog ADR
Browse files Browse the repository at this point in the history
Signed-off-by: Florian Barbin <[email protected]>
  • Loading branch information
florianbarbin committed Jun 28, 2024
1 parent df752c9 commit f98960d
Showing 1 changed file with 104 additions and 11 deletions.
115 changes: 104 additions & 11 deletions doc/adrs/152_reactivate_tool_selection_dialog.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ The backend and frontend part of the selection dialog are located here:
* Frontend
** packages/selection/frontend/sirius-components-selection

=== Lifecycle
=== Former Selection Dialog Lifecycle

On the specifier side, the selection dialog is asked by adding a _SelectionDescription_ in the _NodeTool_.
On the specifier side, the selection dialog was asked by adding a _SelectionDescription_ in the _NodeTool_.
If a _SelectionDescription_ is defined on the node tool, the _selectionDescriptionId_ is set in the Tool pojo returned to the frontend.

In the former diagram architecture, if the tool defined a selectionDescription (the tool.selectionDescriptionId value is defined) a SHOW_SELECTION_DIALOG event was dispatched on the DiagramWebSocketContainer state machine.
Expand Down Expand Up @@ -73,6 +73,58 @@ The tool was finaly invoked within this useEffect (depending on the selectedObje

== Decision

In addition to retrieving the former behavior of the Selection Dialog, we also want to make this feature as generic as possible:

* We want to offer the possibility to create any other kind of Dialog
* We also want to offer an API for developers extending sirius-web to contribute additional dialogs.

=== Diagram View DSL ===
We will create an abstract _DialogDescription_ under the _NodeTool_. The current _SelectionDescription_ will be renamed into _SelectionDialogDescription_ and will extend the _DialogDescription_ concept.
The View DSL will thus be ready for other kinds of Dialog.

=== Dialog GraphQL API ===

the _selectionDescriptionId_ from _SingleClickOnDiagramElementTool_ will be renamed into _dialogDescriptionId_

```
type SingleClickOnDiagramElementTool implements Tool {
id: ID!
label: String!
iconURL: [String!]!
appliesToDiagramRoot: Boolean!
dialogDescriptionId: String
targetDescriptions: [DiagramElementDescription!]!
}
```
The property _selectedObjectId_ from _InvokeSingleClickOnDiagramElementToolInput_ will be removed and will take a list of variables as parameter to be more generic:

```
input InvokeSingleClickOnDiagramElementToolInput {
id: ID!
editingContextId: ID!
representationId: ID!
variables: [ToolVariable!]!
diagramElementId: ID!
startingPositionX: Float!
startingPositionY: Float!
toolId: ID!
}

input ToolVariable {
name: String!
value: String!
type: ToolVariableType!
}

enum ToolVariableType {
STRING
OBJECT_ID
OBJECT_ID_ARRAY
}

```
=== Frontend ===

The new diagram architecture based on react-flow has changed significantly. The tools are now invoked in the _Palette_ component:

```ts
Expand Down Expand Up @@ -102,40 +154,81 @@ The new diagram architecture based on react-flow has changed significantly. The
};
```

In a similar way than the delete tool shows the deletion confirmation dialog, the palette should call a showSelectionDialog if the tool defines a selectionDescriptionID.
In a similar way than the delete tool shows the deletion confirmation dialog, the palette should call a showDialog if the tool defines a DialogDescriptionID.

Palette.tsx:
```ts
const { showDeletionConfirmation } = useDeletionConfirmationDialog();
const { showSelectionDialog } = useSelectionDialog();
const { showDialog } = useDialog();
```

The Palette will not call the invokeSingleClickTool directly but it will first verify if we need to show the selection dialog. The callback when performing the finish action will be responsible for invoking the tool with the selectedElementId.
The Palette will not call the invokeSingleClickTool directly but it will first verify if we need to show a dialog. The callback when performing the finish action will be responsible for invoking the tool with the variables provided by the dialog.

```ts
if (tool.selectionDescriptionId) {
showSelectionDialog(editingContextId, tool.selectionRepresentationId, targetObjectId, onFinish, onClose);
if (tool.dialogDescriptionId) {
showDialog(editingContextId, tool.dialogRepresentationId, targetObjectId, onFinish, onClose);
} else {
invokeSingleClickTool(tool);
}

```

We will create a new hook "_useSelectionDialog_" in a similar way than the confirmationDialog. This hook will use the _SelectionDialogContext_.
The _SelectionDialogContextProvider_ will be added in the DiagramRepresentation:
We will create a new hook "_useDialog_" in a similar way than the confirmationDialog. This hook will use the _DialogContext_.
The _DialogContextProvider_ will be added in the DiagramRepresentation:

```
<FullscreenContextProvider>
<SelectionDialogContextProvider>
<DialogContextProvider>
<DiagramRenderer
key={state.diagramRefreshedEventPayload.diagram.id}
diagramRefreshedEventPayload={state.diagramRefreshedEventPayload}
/>
</SelectionDialogContextProvider>
</DialogContextProvider>
</FullscreenContextProvider>

```

The _DialogContextProvider_ will retrieve the concrete dialog component in the _extensionRegistry_ via the _useData_ hook.

We will create a new dedicated extension point _diagramDialogContributionExtensionPoint_.

```ts
const { data: dialogContributions } = useData(diagramDialogContributionExtensionPoint);

const dialogContribution = dialogContributions.filter(dialogContribution => dialogContribution.canHandle(dialogId))[0];
const DialogComponent = dialogDefinition.component;
const dialogComponentProps: DialogComponentProps = { ... };
return (
<DialogContext.Provider value={{ ... }}>
{children}
{state.open && (
<DialogComponent
{...dialogComponentProps}
/>
)}
</DialogContext.Provider>
)
```

The current _SelectionDialog_ will be contributed in the _defaultExtensionRegistry_ by Sirius-web.

=== Possible Dialog API evolution ===

With those changes it will not be possible to pass values from the tool defined in the backend to the frontend dialog. For the current Selection Dialog needs, it will not be a problem since it does not require any other information than the selected element.

The GraphQL API could provide to the front a Dialog object with at least the dialog kind Id extended by the concrete dialog implementation:

```
type SingleClickOnDiagramElementTool implements Tool {
id: ID!
label: String!
iconURL: [String!]!
appliesToDiagramRoot: Boolean!
dialog: Dialog
targetDescriptions: [DiagramElementDescription!]!
}
```

== Status

Work in progress
Expand Down

0 comments on commit f98960d

Please sign in to comment.