From f04abb414d6ec6e79bebb87b0a9b9f83623b6eb7 Mon Sep 17 00:00:00 2001 From: Bogdan Matei Date: Thu, 20 Jun 2024 11:49:23 +0300 Subject: [PATCH] Scopes: Fix preserving scopes when accessing a dashboard only by uid (#89406) --- .../scene/Scopes/ScopesFiltersScene.tsx | 12 ++++++-- .../scene/Scopes/ScopesScene.tsx | 2 +- .../dashboard-scene/scene/Scopes/api.ts | 24 ++-------------- .../dashboard-scene/scene/Scopes/utils.ts | 28 +++++++++++++++++++ 4 files changed, 42 insertions(+), 24 deletions(-) create mode 100644 public/app/features/dashboard-scene/scene/Scopes/utils.ts diff --git a/public/app/features/dashboard-scene/scene/Scopes/ScopesFiltersScene.tsx b/public/app/features/dashboard-scene/scene/Scopes/ScopesFiltersScene.tsx index cef966c5944..fa2213265f5 100644 --- a/public/app/features/dashboard-scene/scene/Scopes/ScopesFiltersScene.tsx +++ b/public/app/features/dashboard-scene/scene/Scopes/ScopesFiltersScene.tsx @@ -21,6 +21,7 @@ import { ScopesScene } from './ScopesScene'; import { ScopesTreeLevel } from './ScopesTreeLevel'; import { fetchNodes, fetchScope, fetchSelectedScopes } from './api'; import { NodesMap, SelectedScope, TreeScope } from './types'; +import { getBasicScope } from './utils'; export interface ScopesFiltersSceneState extends SceneObjectState { nodes: NodesMap; @@ -180,9 +181,16 @@ export class ScopesFiltersScene extends SceneObjectBase return; } - this.setState({ treeScopes, isLoadingScopes: true }); + this.setState({ + // Update the scopes with the basic scopes otherwise they'd be lost between URL syncs + scopes: treeScopes.map(({ scopeName, path }) => ({ scope: getBasicScope(scopeName), path })), + treeScopes, + isLoadingScopes: true, + }); - this.setState({ scopes: await fetchSelectedScopes(treeScopes), isLoadingScopes: false }); + const scopes = await fetchSelectedScopes(treeScopes); + + this.setState({ scopes, isLoadingScopes: false }); } public resetDirtyScopeNames() { diff --git a/public/app/features/dashboard-scene/scene/Scopes/ScopesScene.tsx b/public/app/features/dashboard-scene/scene/Scopes/ScopesScene.tsx index a7f991913c5..f0217190b57 100644 --- a/public/app/features/dashboard-scene/scene/Scopes/ScopesScene.tsx +++ b/public/app/features/dashboard-scene/scene/Scopes/ScopesScene.tsx @@ -30,7 +30,7 @@ export class ScopesScene extends SceneObjectBase { this.addActivationHandler(() => { this._subs.add( this.state.filters.subscribeToState((newState, prevState) => { - if (newState.scopes !== prevState.scopes) { + if (!newState.isLoadingScopes && newState.scopes !== prevState.scopes) { if (this.state.isExpanded) { this.state.dashboards.fetchDashboards(this.state.filters.getSelectedScopes()); } diff --git a/public/app/features/dashboard-scene/scene/Scopes/api.ts b/public/app/features/dashboard-scene/scene/Scopes/api.ts index 71ec07cec19..07df4877a54 100644 --- a/public/app/features/dashboard-scene/scene/Scopes/api.ts +++ b/public/app/features/dashboard-scene/scene/Scopes/api.ts @@ -3,6 +3,7 @@ import { config, getBackendSrv } from '@grafana/runtime'; import { ScopedResourceClient } from 'app/features/apiserver/client'; import { NodesMap, SelectedScope, SuggestedDashboard, TreeScope } from './types'; +import { getBasicScope, mergeScopes } from './utils'; const group = 'scope.grafana.app'; const version = 'v0alpha1'; @@ -48,31 +49,12 @@ export async function fetchScope(name: string): Promise { } const response = new Promise(async (resolve) => { - const basicScope: Scope = { - metadata: { name }, - spec: { - filters: [], - title: name, - type: '', - category: '', - description: '', - }, - }; + const basicScope = getBasicScope(name); try { const serverScope = await scopesClient.get(name); - const scope = { - ...basicScope, - metadata: { - ...basicScope.metadata, - ...serverScope.metadata, - }, - spec: { - ...basicScope.spec, - ...serverScope.spec, - }, - }; + const scope = mergeScopes(basicScope, serverScope); resolve(scope); } catch (err) { diff --git a/public/app/features/dashboard-scene/scene/Scopes/utils.ts b/public/app/features/dashboard-scene/scene/Scopes/utils.ts new file mode 100644 index 00000000000..bbe68774966 --- /dev/null +++ b/public/app/features/dashboard-scene/scene/Scopes/utils.ts @@ -0,0 +1,28 @@ +import { Scope } from '@grafana/data'; + +export function getBasicScope(name: string): Scope { + return { + metadata: { name }, + spec: { + filters: [], + title: name, + type: '', + category: '', + description: '', + }, + }; +} + +export function mergeScopes(scope1: Scope, scope2: Scope): Scope { + return { + ...scope1, + metadata: { + ...scope1.metadata, + ...scope2.metadata, + }, + spec: { + ...scope1.spec, + ...scope2.spec, + }, + }; +}