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

PanelContext: Add functionality to update data from panel #66993

Merged
merged 9 commits into from
Apr 25, 2023

Conversation

torkelo
Copy link
Member

@torkelo torkelo commented Apr 20, 2023

The DataGrid panel PR wants to update data, but to do that it needs to switch the query to Grafanas built in data source, and update the queries. First approach was to emit events that was subscribed to by QueryGroup. That felt a bit hacky. Second version is using getDashboardSrv().getCurrent() to find the panel and update it's queries via updateQueries method. This will not work in other context when panel is rendered via PanelRenderer or in new scenes powered dashboards.

this PR explores two different ways to accomplish this

PanelContext.onUpdateQueries

Overall pretty simple. Problems

  • Panels do not have access to the current (so strange to have an update function but no way to access current). Could provide it via optional PanelProps (or context)
  • queries: DataQuery[] array is not really enough, miss the "main datasource" in case of mixed data sources. But we could detect if the data sources have different data sources and set the data source to mixed otherwise set it to to data source of the first query.

PanelContext.onUpdateDAta

This attacks the problem in a different way. What does the panel actually want to do? Update the data! How can it be done? well that's up to the PanelContext to figure out :)

@torkelo torkelo requested review from a team as code owners April 20, 2023 17:29
@torkelo torkelo requested review from ivanortegaalba, juanicabanas, tskarhed and ashharrison90 and removed request for a team April 20, 2023 17:29
@torkelo torkelo marked this pull request as draft April 20, 2023 17:29
@torkelo torkelo requested review from dprokop and removed request for ivanortegaalba, juanicabanas, tskarhed and ashharrison90 April 20, 2023 17:29
Copy link
Member

@ryantxu ryantxu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Between the two... I think the direct query approach makes more sense

/**
* Some panels could be interested in updating the queries.
* This optional and not always available in all contexts.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is odd since a panel viz does not know the queries

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but in the datagrid scenario it can create new snapshot queries

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore above message. I think the onUpdateData is all datagrid needs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryantxu we could add queries to PanelProps


/**
* Optional, only some contexts support this. This can fail / be cancelled. Which is why it returns a promise.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this one is odd given that can only translate to a single query type/ so not sure the helper wrapper is a good approach

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryantxu what do you mean, only translate to single query?

We send a DataFrame array (via panel data ) so the update is an array. How the context updates the data is up to the context

@mdvictor
Copy link
Contributor

Why would we need 2 handlers? I think onUpdateData will be enough for Datagrid, because it will always generate snapshot queries. Do you have any future cases in mind?

@torkelo
Copy link
Member Author

torkelo commented Apr 21, 2023

@mdvictor i added two approaches to solve the same problem to get feedback on both (instead of opening two PRs)

@mdvictor
Copy link
Contributor

Taking into consideration what @ryantxu mentioned about panels not knowing about queries, I'm more inclined to go with onUpdateData

/**
* Optional, only some contexts support this. This can fail / be cancelled. Which is why it returns a promise.
*/
onUpdateData?: (frames: DataFrame[]) => Promise<boolean>;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the update that removes your queries needs a ConfirmModal as it's a destructive action where the user looses all his queries. Question who is responsible for that confirm modal? the panel or the context implementation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the context should own confirming the destructive action, since leaving it to panels means that panel devs might not always enforce it.

@mdvictor
Copy link
Contributor

@torkelo I added a confirmation modal for onUpdateData. wdyt?

Comment on lines 160 to 179
changeToSnapshotData = (frames: DataFrame[]) => {
const snapshot: DataFrameJSON[] = frames.map((f) => dataFrameToJSON(f));

const query: GrafanaQuery = {
refId: 'A',
queryType: GrafanaQueryType.Snapshot,
snapshot,
datasource: { uid: GRAFANA_DATASOURCE_NAME },
};

this.props.panel.updateQueries({
dataSource: { uid: GRAFANA_DATASOURCE_NAME },
queries: [query],
});

this.props.panel.refresh();

this.closeConfirmationModal();
};

Copy link
Member Author

@torkelo torkelo Apr 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mdvictor

Can we move this to a function/file in the grafana datasource folder?

And I think that function could handle showing the confirm modal. You can show a confirm modal from anywhere with simply this

 appEvents.publish(
        new ShowConfirmModalEvent({
          title: 'Delete',
          text: 'Are you sure you want to permanently delete your starred query?',
          yesText: 'Delete',
          icon: 'trash-alt',
          onConfirm: () => performDelete(query.id),
        })
      );

Don't want to add to much stuff to PanelStateWrapper that is too large already :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mdvictor what does happen in the data grid panel if you cancel the update? Is the edit change reverted in the panel (without knowing it was cancelled).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The confirmation modal makes more sense. I pushed a fix. As for the datagrid, the data won't change in the view with anything but the latest frame. If the update fails, then the frame would not change and there would be no updated cell on cell edit. I do need to make a few changes in the datagrid though to fully support this.

Even though the datagrid itself doesn't need to know whether the event was successful or not, I think there might be cases where the panel needs to know what the user selected on the modal, so I changed the onUpdateData and added back the boolean promise.


import { GrafanaQuery, GrafanaQueryType } from './types';

export const changeToSnapshotData = (frames: DataFrame[], panel: PanelModel) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@torkelo I was thinking that maybe this would sit better in a place like public/app/core/utils/changeToSnapshotData.ts instead of the grafana datasource. Wdyt?

@mdvictor mdvictor added this to the 10.0.0 milestone Apr 25, 2023
@mdvictor mdvictor added add to changelog no-backport Skip backport of PR labels Apr 25, 2023
@mdvictor mdvictor changed the title PanelContext: Exploring two ways to update queries or update data PanelContext: Add functionality to update snapshot data from panel Apr 25, 2023
@mdvictor mdvictor changed the title PanelContext: Add functionality to update snapshot data from panel PanelContext: Add functionality to update data from panel Apr 25, 2023
@mdvictor mdvictor marked this pull request as ready for review April 25, 2023 10:51
@mdvictor mdvictor requested a review from ryantxu April 25, 2023 10:52
@torkelo
Copy link
Member Author

torkelo commented Apr 25, 2023

@mdvictor pushed some refactorings this morning (to move move code to the util function)

Copy link
Contributor

@mdvictor mdvictor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@torkelo torkelo merged commit de18ed6 into main Apr 25, 2023
24 checks passed
@torkelo torkelo deleted the update-queries-panel-context branch April 25, 2023 12:55
@torkelo
Copy link
Member Author

torkelo commented Apr 25, 2023

@mdvictor merged!

@zerok zerok modified the milestones: 10.0.0, 10.0.0-preview May 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants