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

[Dashboards] Add getSerializedState method to Dashboard API #204140

Merged
merged 10 commits into from
Dec 19, 2024

Conversation

nickpeihl
Copy link
Member

@nickpeihl nickpeihl commented Dec 12, 2024

Summary

Adds a getSerializedState method to the Dashboard API.

This can be used to retrieve a serialized form of the Dashboard that can be used with the Dashboard HTTP API. The "Export" flyout is a possible future consumer of this method.

Checklist

Check the PR satisfies following conditions.

Reviewers should verify this PR satisfies this list as well.

  • Any text added follows EUI's writing guidelines, uses sentence case text and includes i18n support
  • Documentation was added for features that require explanation or tutorials
  • Unit or functional tests were updated or added to match the most common scenarios
  • If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the docker list
  • This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The release_note:breaking label should be applied in these situations.
  • Flaky Test Runner was used on any tests changed
  • The PR description includes the appropriate Release Notes section, and the correct release_note:* label is applied per the guidelines

Identify risks

Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss.

Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging.

@nickpeihl nickpeihl added Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas v9.0.0 v8.18.0 labels Dec 12, 2024
@nickpeihl nickpeihl requested a review from a team as a code owner December 12, 2024 21:49
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-presentation (Team:Presentation)

@nickpeihl nickpeihl added backport:prev-minor Backport to (8.x) the previous minor version (i.e. one version back from main) release_note:skip Skip the PR/issue when compiling release notes labels Dec 12, 2024
@@ -171,6 +171,14 @@ export function getDashboardApi({
unifiedSearchManager.internalApi.controlGroupReload$,
unifiedSearchManager.internalApi.panelsReload$
).pipe(debounceTime(0)),
getSerializedState: async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

#203662 made getState sync so this method could now become sync as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh good call! Updated in b58c33d.

Unfortunately, the getSerializedState method still needs to be async for now since the getDashboardState method on the CM service relies on a Promise to extract searchSource references. But this might change when we move reference handling to the server in #192758.

Unfortunately, the `getSerializedState` method still needs to be async since the `getDashboardState` method on the CM service is a promise. But this might change when we move reference handling to the server in elastic#192758.
}
};

export const getDashboardState = async ({
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this part of content management service instead of just a function that can be imported where needed? Does it need to be part of content management service?

Copy link
Member Author

Choose a reason for hiding this comment

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

It does not need to be on content management service. I moved the module into the dashboard_api directory in ed68550.

...(prefixedPanelReferences ?? []),
...(controlGroupReferences ?? []),
];
const { attributes, references } = await getDashboardState({
Copy link
Contributor

@nreese nreese Dec 13, 2024

Choose a reason for hiding this comment

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

Should save methods be updated to just take output of getDashboardState instead of calling getDashboardState internally.

I think it would be better if getDashboardState lived in dashboard_api folder and any place that needed serialized state would just get passed { attributes: DashboardAttributes; references: SavedObjectReference[]; }

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 like this idea a lot, but I think I would like to scope that in a different PR. Making those changes in this PR would greatly increase the number of changes required for review.

}
};

export const getDashboardState = ({
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this be renamed to getSerializedState (and rename file to get_serialized_state)? That will avoid ambiguity of what state this is returning.

panelReferences: [],
});

expect(result.attributes.panels).toEqual([]);
Copy link
Contributor

Choose a reason for hiding this comment

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

How about asserting the entire result.attributes

const dashboardState = {
...getSampleDashboardState(),
panels: { oldPanelId: { type: 'visualization' } },
} as unknown as DashboardState;
Copy link
Contributor

@nreese nreese Dec 17, 2024

Choose a reason for hiding this comment

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

Can you move the cast from the entire dashboard state to just panel

const dashboardState = {
      ...getSampleDashboardState(),
      panels: { oldPanelId: { type: 'visualization' } as DashboardPanelState },
    };

],
});

expect(result.attributes.panels).toEqual(
Copy link
Contributor

Choose a reason for hiding this comment

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

Why don't you mock v4 so you know the new id. Then you can assert attributes.panels has the right shape.

jest.mock('uuid', () => ({
  v4: jest.fn().mockReturnValue('12345'),
}));
expect(result.attributes.panels).toEqual({ ...expectedValue});

@@ -102,7 +102,7 @@ export async function openSaveModal({
controlGroupReferences,
panelReferences,
saveOptions,
currentState: dashboardStateToSave,
dashboardState: dashboardStateToSave,
Copy link
Contributor

@nreese nreese Dec 17, 2024

Choose a reason for hiding this comment

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

searchSourceReferences is not passed to saveDashboardState call

@nickpeihl nickpeihl requested a review from nreese December 19, 2024 14:58
Copy link
Contributor

@nreese nreese left a comment

Choose a reason for hiding this comment

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

LGTM
code review only


it('should return the current state attributes and references', async () => {
const dashboardState = getSampleDashboardState();
const result = await getSerializedState({
Copy link
Contributor

Choose a reason for hiding this comment

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

Calls to getSerializedState should not be async. Also, all test cases do not need to be async

@elastic-vault-github-plugin-prod elastic-vault-github-plugin-prod bot requested a review from a team as a code owner December 19, 2024 15:17
@ThomThomson
Copy link
Contributor

@elasticmachine merge upstream

@ThomThomson ThomThomson removed the request for review from a team December 19, 2024 18:39
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
dashboard 696 697 +1

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
dashboard 111 113 +2

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
dashboard 667.8KB 668.1KB +335.0B
Unknown metric groups

API count

id before after diff
dashboard 114 117 +3

History

@ThomThomson ThomThomson merged commit d7280a1 into elastic:main Dec 19, 2024
9 checks passed
@kibanamachine
Copy link
Contributor

Starting backport for target branches: 8.x

https://github.com/elastic/kibana/actions/runs/12420230354

@kibanamachine
Copy link
Contributor

💔 All backports failed

Status Branch Result
8.x Backport failed because of merge conflicts

Manual backport

To create the backport manually run:

node scripts/backport --pr 204140

Questions ?

Please refer to the Backport tool documentation

@nickpeihl
Copy link
Member Author

💚 All backports created successfully

Status Branch Result
8.x

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

nickpeihl added a commit to nickpeihl/kibana that referenced this pull request Dec 19, 2024
…204140)

Adds a `getSerializedState` method to the Dashboard API.

(cherry picked from commit d7280a1)
nickpeihl added a commit that referenced this pull request Dec 19, 2024
…04140) (#205010)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Dashboards] Add getSerializedState method to Dashboard API
(#204140)](#204140)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Nick
Peihl","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-12-19T20:24:49Z","message":"[Dashboards]
Add getSerializedState method to Dashboard API (#204140)\n\nAdds a
`getSerializedState` method to the Dashboard
API.","sha":"d7280a1380d66107a6818b1b84358c1762c20bb9","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Presentation","release_note:skip","v9.0.0","backport:prev-minor","v8.18.0"],"number":204140,"url":"https://github.com/elastic/kibana/pull/204140","mergeCommit":{"message":"[Dashboards]
Add getSerializedState method to Dashboard API (#204140)\n\nAdds a
`getSerializedState` method to the Dashboard
API.","sha":"d7280a1380d66107a6818b1b84358c1762c20bb9"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/204140","number":204140,"mergeCommit":{"message":"[Dashboards]
Add getSerializedState method to Dashboard API (#204140)\n\nAdds a
`getSerializedState` method to the Dashboard
API.","sha":"d7280a1380d66107a6818b1b84358c1762c20bb9"}},{"branch":"8.x","label":"v8.18.0","labelRegex":"^v8.18.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:prev-minor Backport to (8.x) the previous minor version (i.e. one version back from main) release_note:skip Skip the PR/issue when compiling release notes Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas v8.18.0 v9.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants