-
Notifications
You must be signed in to change notification settings - Fork 52
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
[3875] Refactor the tree event classes related to the explorer #3876
[3875] Refactor the tree event classes related to the explorer #3876
Conversation
6bbab40
to
dd27f6e
Compare
aad3475
to
69116ec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is absolutely critical that the reference widget keeps being usable without the explorer. As such, it will be necessary to have a modelBrowserEvent subscription with its event processor factory.
CHANGELOG.adoc
Outdated
@@ -109,6 +109,7 @@ A migration participant has been added to automatically keep compatible all diag | |||
- https://github.com/eclipse-sirius/sirius-web/issues/3777[#3777] [sirius-web] Add support for any kind of object as semantic element in the tree representation | |||
- https://github.com/eclipse-sirius/sirius-web/issues/3392[#3392] [diagram] Prevent edge from passing through another node | |||
- https://github.com/eclipse-sirius/sirius-web/issues/3763[#3763] [diagram] Split the SelectionDialogDescription to prepare the Tree support | |||
- https://github.com/eclipse-sirius/sirius-web/issues/3875[#3875] [sirius-web] Move explorer related code from components-trees to sirius-web-application |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sirius-components-trees
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -69,6 +69,8 @@ export const ModelBrowserTreeView = ({ | |||
textToHighlight={state.filterBarText} | |||
markedItemIds={markedItemIds} | |||
treeItemActionRender={(props) => <WidgetReferenceTreeItemAction {...props} />} | |||
eventType="explorerEvent" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect that this make the reference widget unusable without the presence of the explorer. There are applications that are integrating Sirius Components without Sirius Web. Sirius Components cannot make any assumptions on the presence or capabilities of Sirius Web. This will have to change in favor of reference-widget specific capabilities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly, ModelBrowser has its own modelBrowserEvent
subscription now.
VariableManager variableManager = new VariableManager(); | ||
variableManager.put(TreeConfiguration.TREE_ID, treeConfiguration.getId()); | ||
variableManager.put(ExplorerConfiguration.TREE_ID, treeConfiguration.getId()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we now explicitly what we are looking for since we are not in some generic tree-related code but instead in some explorer related code, could you instead search for the description with the id ExplorerDescriptionProvider#DESCRIPTION_ID
.
Thanks to that:
- you don't need to have this TREE_ID variable here
- you don't need to have a special canCreatPredicate in ExplorerDescriptionProvider
- you can remove all usages of this TREE_ID
- you don't have to introduce the useless interface ITreeConfiguration to hold this variable
And you will have to provide the concept necessary for the reference widget explicitly in its collaborative project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, I got rid of this variable.
|
||
input ExplorerEventInput { | ||
id: ID! | ||
treeId: String! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just as an information, treeId
is probably what will be replaced in favor of treeDescriptionId
to let the frontend specify to the backend which tree description to use to compute the explorer later.
I suspect that the treeId variable could be fully removed in this PR without any impact, it is now a duplicate of the information contained in the fact that we are using a GraphQL field named explorerEvent
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unchanged for the moment.
You are right this field will be renamed treeDescriptionId
in the future task that tackles the explorer selection.
This ID will be sent from the frontend as the current description to build.
...ain/java/org/eclipse/sirius/web/tests/services/explorer/ExplorerEventSubscriptionRunner.java
Show resolved
Hide resolved
@@ -60,7 +60,7 @@ public class ModelBrowserExpandAllControllerTests extends AbstractIntegrationTes | |||
private IGivenInitialServerState givenInitialServerState; | |||
|
|||
@Autowired | |||
private TreeEventSubscriptionRunner treeEventSubscriptionRunner; | |||
private ExplorerEventSubscriptionRunner treeEventSubscriptionRunner; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should make you stop because such dependency between the reference widget from the form representation and the explorer cannot be introduced.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, there is a dedicated ModelBrowserEventSubscritionRunner
helper class.
The test has been updated to use model browser related classes and not explorer one (EventInput for instance).
const isATreeEventData = (data: GQLTreeEventData | GQLExplorerEventData): data is GQLTreeEventData => { | ||
return 'treeEvent' in data; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a bit odd and I suspect that it will just become more and more untenable (try fixing the issue with the reference widget with this code and I suspect that it won't be possible without adding odds dependencies). I suspect that we will have to move to the same situation as in forms with the subscription moved outside of TreeView with a dedicated useExplorerEvent subscription and a TreeView component which would simply receive the payload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the subscription has been moved outside the TreeView component. This is now the parent component of TreeView, which is in charge of managing the subscription. For instance, ModelBrowserTreeView retrieves the tree through the subscription and passes it to its inner TreeView via props.
@@ -10,11 +10,11 @@ | |||
* Contributors: | |||
* Obeo - initial API and implementation | |||
*******************************************************************************/ | |||
export const getTreeEventSubscription = (depth: number): string => { | |||
export const getTreeEventSubscription = (depth: number, eventType: string, eventInputType: string): string => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I've seen in the code, if I'm right, you will have to duplicate this subscription to have a getExplorerEventSubscription in sirius-web-application
instead and just keep the function recursiveGetChildren
and the fragment here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
You should also keep an eye on this PR by @florianbarbin since it will introduce yet another usage of the tree representation. I don't know yet which PR will be merged first but the other one will have to be updated to take into account these changes. On the same topic, the previous PR from Florian Barbin introduced another basic version of a TreeDescription in the view DSL in order to leverage it in the selection dialog. One of the goal of the future tree description that you will add in the view DSL is to replace both this one dedicated to the selection dialog (which is on purpose very minimal) and the one powering the form representation. |
2d9a402
to
98578a3
Compare
PR updated. |
98578a3
to
4acc6b5
Compare
966fbb0
to
71bf311
Compare
71bf311
to
2c8e030
Compare
4320da1
to
b9d5e52
Compare
90a5879
to
7afa45f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll update the PR with fixes for my latest comments. After that I'll rebase it and merge it. No need to touch anything now
}, | ||
} | ||
); | ||
const [state, setState] = useState<TreeViewComponentState>({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TreeViewState to match our naming conventions
@@ -16,42 +16,24 @@ import { TreeItemActionProps } from '../treeitems/TreeItemAction.types'; | |||
|
|||
export interface TreeViewComponentProps extends WorkbenchViewComponentProps { | |||
treeId: string; | |||
tree: GQLTree; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TreeView component cannot be used directly as a workbench view anymore, it does not have to keep extending WorkbenchViewComponentProps it doesn't make sense. ExplorerView needs to do it (which it does) but not TreeView.
|
||
export interface GQLTreeEventPayload { | ||
__typename: string; | ||
} | ||
|
||
export interface GQLTreeRefreshedEventPayload extends GQLTreeEventPayload { | ||
id: string; | ||
tree: GQLTree; | ||
} | ||
|
||
export interface UseTreeSubscriptionValue { | ||
loading: boolean; | ||
tree: GQLTree | null; | ||
complete: boolean; | ||
} | ||
|
||
export interface UseTreeSubscriptionState { | ||
id: string; | ||
tree: GQLTree | null; | ||
complete: boolean; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are not the concern of sirius-components-trees it's not used in this npm package.
By putting this code here, you are trying to avoid having two almost identical copies of those types in useModelBrowserSubscription
and useExplorerSubscription
. Unless we have some maintainability issue with the code, some duplicated code is not an issue I care about. On the other hand, useless code (for sirius-components-trees
) and useless coupling are both of the most critical issues that I'm trying to avoid.
Removing duplicated code always comes with one critical tradeoff, creating additional coupling.
Now both the lifecycle the explorer and the model browser are tied together with those types. What if someone wants to change one of those? Their first instinct will be to update UseTreeSubscriptionState
and we will end up with useless code for the other one.
The state of useExplorerSubscription
needs to fulfill the expectations of useExplorersubscription
and the state of useModelBrowserSubscription
needs to fulfill the expectations of useModelBrowserSubscription
. It just happens that today both have the same expectations.
markedItemIds={markedItemIds} | ||
treeItemActionRender={(props) => <WidgetReferenceTreeItemAction {...props} />} | ||
/> | ||
{tree && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use this way for conditional rendering, be explicit because the implicit casting in JavaScript for boolean is funky
/> | ||
</> | ||
<div data-testid={treeId}> | ||
{tree ? ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Do not use this way to express conditional rendering
- Why does tree can be
null
when it is explicitly described as non null in its type?
@@ -136,11 +147,12 @@ export const ExplorerView = ({ editingContextId, readOnly }: WorkbenchViewCompon | |||
editingContextId={editingContextId} | |||
readOnly={readOnly} | |||
treeId={'explorer://'} | |||
tree={tree} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you are giving a GQLTree | null
to TreeView which expects a GQLTree
. On the other hand, in ModelBrowserTree
you are not rendering TreeView
unless you have a GQLTree
. So who is responsible for testing that tree
is null
?
Given the fact that both ModelBrowser
is testing for null
and the type of tree
in TreeViewProps
is GQLTree
, I suspect that ExplorerView
should do the job.
eb85278
to
3b1d36e
Compare
Bug: eclipse-sirius#3875 Signed-off-by: Jerome Gout <[email protected]> Signed-off-by: Florian ROUËNÉ <[email protected]> Signed-off-by: Stéphane Bégaudeau <[email protected]>
3b1d36e
to
e6afb31
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll wait for the build to merge it
Bug: #3875
Pull request template
General purpose
What is the main goal of this pull request?
Project management
priority:
andpr:
labels been added to the pull request? (In case of doubt, start with the labelspriority: low
andpr: to review later
)area:
,difficulty:
,type:
)CHANGELOG.adoc
been updated to reference the relevant issues?CHANGELOG.adoc
? (Including changes in the GraphQL API)CHANGELOG.adoc
? For example indoc/screenshots/2022.5.0-my-new-feature.png
Architectural decision records (ADR)
[doc]
?CHANGELOG.adoc
?Dependencies
CHANGELOG.adoc
?CHANGELOG.adoc
?Frontend
This section is not relevant if your contribution does not come with changes to the frontend.
General purpose
Typing
We need to improve the typing of our code, as such, we require every contribution to come with proper TypeScript typing for both changes contributing new files and those modifying existing files.
Please ensure that the following statements are true for each file created or modified (this may require you to improve code outside of your contribution).
useMutation<DATA_TYPE, VARIABLE_TYPE>(…)
useQuery<DATA_TYPE, VARIABLE_TYPE>(…)
useSubscription<DATA_TYPE, VARIABLE_TYPE>(…)
useMachine<CONTEXT_TYPE, EVENTS_TYPE>(…)
useState<STATE_TYPE>(…)
?.
(if the GraphQL API specifies that a field cannot benull
, do not treat it has potentiallynull
for example)let diagram: Diagram | null = null;
)Backend
This section is not relevant if your contribution does not come with changes to the backend.
General purpose
Architecture
Review
How to test this PR?
Please describe here the various use cases to test this pull request