-
Notifications
You must be signed in to change notification settings - Fork 61
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
Add support for multi row select and context menu in Timegraph Component #1044
Add support for multi row select and context menu in Timegraph Component #1044
Conversation
eea555b
to
a3eb3ef
Compare
In order to test this: First register a context menu to timegraph component using the signal:
Once you have done that - your timegraph view should have a context menu along with the ability to multi-select rows. Once you make selections, you can right click, and click a menu item. To handle the item clicked, you can attach a listener for CONTEXT_MENU_ITEM_CLICKED signal:
|
ROW_SELECTIONS_CHANGED - This signal is intended for components that are interested in the multi selections but without the actions through a context menu |
a3eb3ef
to
6c97f0a
Compare
Thanks for the contribution. Sounds interesting. I see that such an API provides the possibility for third-party extensions to add custom functionality. To be able to use it also in vscode-trace-extension, there is some more work to be done there. I tried something similar at one point, but I've never been able to work on it beyond a proof-of-concept. See below for both related branches on my GitHub forks. I'm not able to continue working on it in the near future, so, I'm glad that you're bringing this forward. I'll review your PR in the coming days. https://github.com/bhufmann/theia-trace-extension/tree/command-handler-api |
Okay, Thanks! :) Yes, there will have to be a follow up commit to this for vscode trace extension! I have it done, i will push the PR soon! I briefly look at the work you did - I think a generic command handler API would definitely be very useful! I will look at it in detail tomorrow - maybe I can pick it up at some point. |
Sorry for the delay: I have posted eclipse-cdt-cloud/vscode-trace-extension#205, which is the follow up work for this commit in the vscode trace extension. Looking forward to your reply! |
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.
Thanks a lot for this interesting contribution. My mind started thinking on how to use it for our user base. It opens some door of add-on features for specific views.
I did a pass of review and testing. I added my findings to this review.
@@ -0,0 +1,29 @@ | |||
/*************************************************************************************** | |||
* Copyright (c) 2023 BlackBerry Limited and contributors. |
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.
2024
@@ -0,0 +1,41 @@ | |||
/*************************************************************************************** | |||
* Copyright (c) 2023 BlackBerry Limited and contributors. |
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.
2024
let calculatedX = 0; | ||
let calculatedY = 0; | ||
if (refNode) { | ||
calculatedX = event.clientX; |
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.
shouldn't it be calculatedX = event.clientX - refNode.getBoundingClientRect().left;
?
Otherwise the menu is opened further right and it feel not correct, as well as the location is further left if the trace explorer is minimized.
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 meant for it to opened further right as that is the flow of the view - but i am ok with what you suggested as well - I will update it in the next patch!
rows?.push(id); | ||
} | ||
} | ||
this.setState({ selectedRow: undefined, selectedRows: [...rows] }); |
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.
Does selectedRow
to need to be set to undefined? When clicking afterwards on a context menu, the selected row is undefined. Also, there s a misalignment between the tree on the left and the state row on the right of the view.
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 primiarily did this for styling of the table row.. I wanted all multi selection of rows to be the same color - and if i dont set selectedRow to be undefined, the className that gets attached to the row would be selected as that was my 2nd check for what className should be used.
But on second thought, I dont think multi-select needs to be a different background. It can just re-use the same background as the normal selection. WDYT?
@@ -977,6 +1094,12 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent<Timegr | |||
} | |||
}; | |||
|
|||
private doHandleContextMenuContributed(payload: ContextMenuContributedSignalPayload) { | |||
if (payload.getOutputDescriptor().id === this.props.outputDescriptor.id) { | |||
this.setState({ ctxMenu: payload.getMenu() }); |
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.
if there are multiple menus contributed, then the last menu will override the previous one. What I can see that there might be multiple sources of menu contributions, e.g. external third-party extension (I think that's your case), maybe some build-in menus, or maybe some server driven-menus (haven't fully thought this through though), So, I don't think it we should be limiting it to one possible contribution.
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.
Hmm good point - Maybe i should change it so that the signals can pass menu items rather an entire context menu - That way it will have a generic menu with the ability to add as many menu items as needed from multiple sources. WDYT?
selectedRow: this.state.selectedRow, | ||
selectedRows: this.state.selectedRows | ||
}; | ||
const signalPayload: ContextMenuItemClickedSignalPayload = new ContextMenuItemClickedSignalPayload( |
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.
each row might have some metadata associated which can be used on the receiving side of the signal. The metadata is aleady used to select a specific row upon reception of a selection changed signal from the events table (see method findElement()
). It night be interesting to send the metadata as part of the this new signal and row_selection_changed_signal instead of just the array of row ids for future enhancements.
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 would definitely be a very nice enhancement to this signal - I will look into it
protected handleItemClick = (params: ItemParams): void => { | ||
const props = { | ||
outputDescriptor: this.props.outputDescriptor, | ||
selectedRow: this.state.selectedRow, |
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.
selectedRow
and selectedRows
are to close in name and name should be clearer. Maybe rename new variable and releated methods/signals to make it clearer.
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.
Ok - i will change it in the next patch!
onMultipleRowClick(node.id, false); | ||
} else if (onMultipleRowClick && e.shiftKey) { | ||
onMultipleRowClick(node.id, true); | ||
} else { |
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 noticed the following exception in the log:
Uncaught TypeError TypeError: onRowClick is not a function
at TableRow.onClick (/home/eedbhu/git/theia-training/theia-trace-extension/packages/react-components/src/components/utils/filter-tree/table-row.tsx:102:13)
at callCallback (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:4164:1)
at invokeGuardedCallbackDev (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:4213:1)
at invokeGuardedCallback (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:4277:1)
at invokeGuardedCallbackAndCatchFirstError (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:4291:1)
at executeDispatch (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:9041:1)
at processDispatchQueueItemsInOrder (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:9073:1)
at processDispatchQueue (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:9086:1)
at dispatchEventsForPlugins (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:9097:1)
at <anonymous> (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:9288:1)
at batchedUpdates$1 (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:26140:1)
at batchedUpdates (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:3991:1)
at dispatchEventForPluginEventSystem (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:9287:1)
at dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:6465:1)
at dispatchEvent (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:6457:1)
at dispatchDiscreteEvent (/home/eedbhu/git/theia-training/theia-trace-extension/node_modules/react-dom/cjs/react-dom.development.js:6430:1)
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 can't seem to reproduce this - can you maybe provide some steps to reproduce this?
}; | ||
|
||
renderContextMenu(): React.ReactNode { | ||
return ( |
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 mouse click on a row of a timegraph view that doesn't have a context menu registered I get the following error in the console log (descriptor id is the one I used and will vary for other data providers):
root ERROR It seems that the menu you are trying to display is not renderer or you have a menu id mismatch. You used the menu id: timegraph.context.menuId org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.provider.flamechart:org.eclipse.tracecompass.incubator.callstack.core.lttng.ust```
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.
Ah - I forgot to add a check in onCtxMenu to see if a context menu was contributed - will fix in next patch!
private menu: ContextMenu; | ||
|
||
constructor(outputDescriptor: OutputDescriptor, menuItems: ContextMenu) { | ||
this.outputDescriptor = outputDescriptor; |
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'm a bit torn about the following comment. I'm not sure if the whole descriptor needs to be sent or just the descriptor ID. The sender of that signal might not know all the mandatory fields of the descriptor. But it might be useful to have the descriptor. WDYT?
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 don't think the whole descriptor is needed - just the descriptor id would suffice for the purpose of attaching a context menu. But I left in the whole OutputDescritor incase you had a use case for it
6c97f0a
to
50b4409
Compare
fa4f7bd
to
da7b720
Compare
changes made: - Support for adding context menu via signals - Support for making multiple selections in data tree of timegraph component - Added Signals to notify context menu selection and multi row selections This change will allow for a context menu to be added to the timegraph component based on the outputDescriptor id via a signal. The component also adds the ability to select multiple rows. The multi selections can be passed with the item clicked signal payload as well as through a rowSelectionsChanged signal. The end goal is to provide the timegraph views with the ability to make multi-row selections and perform some actions with the selections. Signed-off-by: Neel Gondalia ngondalia@blackberry.com
da7b720
to
75aa1c0
Compare
I have addressed most of the issues from the previous patch - I have also updated eclipse-cdt-cloud/vscode-trace-extension#205, which is the code i used to test this from vscode-trace-extension. I looked into updating the styling of chart layer rows - but currently only way to update a row's style is by updating selectedRow, which doesnt work for multi selection rows which invokes rowStyleProvider through "updateRowStyle". To support this, it requires a change in Timeline Chart, which includes making "updateRowStyle" method in time-graph-chart.ts to be public API. However, we do not have an internal mirror/setup for that repo, so i wont be able to commit to it anytime soon. The workaround would be to update chart layer anytime the multiselections are changed - but i dont think that is a good idea as it is a costly operation and it breaks the user flow.. WDYT? |
Thanks for the updates. I going to test and review your updates soon. |
I think it's ok to only synchronize one single selection between tree and chart. This new feature of this PR then will apply only for the single- or multi-selection in the tree. If there is a need for a different behaviour in the future then we can address it. |
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 looks good to me.
I tested it with a sample code within this repo and with example eclipse-cdt-cloud/vscode-trace-extension#205.
Thanks for the contribution!
Changes made:
This change will allow for a context menu to be added to the timegraph component based on the outputDescriptor id via a signal. The component also adds the ability to select multiple rows. The multi selections can be passed with the item clicked signal payload as well as through a rowSelectionsChanged signal. The end goal is to provide the timegraph views with the ability to make multi-row selections and perform some actions with the selections.
Signed-off-by: Neel Gondalia ngondalia@blackberry.com