Scopes: Move URL values from selector to facade (#96842)
This commit is contained in:
@@ -1,6 +1,12 @@
|
|||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
|
|
||||||
import { SceneObjectBase, SceneObjectState } from '@grafana/scenes';
|
import {
|
||||||
|
SceneObjectBase,
|
||||||
|
SceneObjectState,
|
||||||
|
SceneObjectUrlSyncConfig,
|
||||||
|
SceneObjectUrlValues,
|
||||||
|
SceneObjectWithUrlSync,
|
||||||
|
} from '@grafana/scenes';
|
||||||
|
|
||||||
import { scopesSelectorScene } from './instance';
|
import { scopesSelectorScene } from './instance';
|
||||||
import { disableScopes, enableScopes, enterScopesReadOnly, exitScopesReadOnly, getSelectedScopes } from './utils';
|
import { disableScopes, enableScopes, enterScopesReadOnly, exitScopesReadOnly, getSelectedScopes } from './utils';
|
||||||
@@ -8,21 +14,47 @@ import { disableScopes, enableScopes, enterScopesReadOnly, exitScopesReadOnly, g
|
|||||||
interface ScopesFacadeState extends SceneObjectState {
|
interface ScopesFacadeState extends SceneObjectState {
|
||||||
// A callback that will be executed when new scopes are set
|
// A callback that will be executed when new scopes are set
|
||||||
handler?: (facade: ScopesFacade) => void;
|
handler?: (facade: ScopesFacade) => void;
|
||||||
|
// The render count is a workaround to force the URL sync manager to update the URL with the latest scopes
|
||||||
|
// Basically it starts at 0, and it is increased with every scopes value update
|
||||||
|
renderCount?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ScopesFacade extends SceneObjectBase<ScopesFacadeState> {
|
export class ScopesFacade extends SceneObjectBase<ScopesFacadeState> implements SceneObjectWithUrlSync {
|
||||||
|
protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['scopes'] });
|
||||||
|
|
||||||
public constructor(state: ScopesFacadeState) {
|
public constructor(state: ScopesFacadeState) {
|
||||||
super(state);
|
super({
|
||||||
|
...state,
|
||||||
|
renderCount: 0,
|
||||||
|
});
|
||||||
|
|
||||||
this.addActivationHandler(this._activationHandler);
|
this.addActivationHandler(this._activationHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getUrlState() {
|
||||||
|
return {
|
||||||
|
scopes: this.value.map(({ metadata }) => metadata.name),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateFromUrl(values: SceneObjectUrlValues) {
|
||||||
|
if (!values.scopes && !scopesSelectorScene?.state.isEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let scopeNames = values.scopes ?? [];
|
||||||
|
scopeNames = Array.isArray(scopeNames) ? scopeNames : [scopeNames];
|
||||||
|
|
||||||
|
scopesSelectorScene?.updateScopes(scopeNames.map((scopeName) => ({ scopeName, path: [] })));
|
||||||
|
}
|
||||||
|
|
||||||
private _activationHandler = () => {
|
private _activationHandler = () => {
|
||||||
this.enable();
|
this.enable();
|
||||||
|
|
||||||
this._subs.add(
|
this._subs.add(
|
||||||
scopesSelectorScene?.subscribeToState((newState, prevState) => {
|
scopesSelectorScene?.subscribeToState((newState, prevState) => {
|
||||||
if (!newState.isLoadingScopes && (prevState.isLoadingScopes || !isEqual(newState.scopes, prevState.scopes))) {
|
if (!newState.isLoadingScopes && (prevState.isLoadingScopes || !isEqual(newState.scopes, prevState.scopes))) {
|
||||||
|
this.setState({ renderCount: (this.state.renderCount ?? 0) + 1 });
|
||||||
this.state.handler?.(this);
|
this.state.handler?.(this);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { UrlSyncManager } from '@grafana/scenes';
|
|
||||||
|
|
||||||
import { ScopesDashboardsScene } from './internal/ScopesDashboardsScene';
|
import { ScopesDashboardsScene } from './internal/ScopesDashboardsScene';
|
||||||
import { ScopesSelectorScene } from './internal/ScopesSelectorScene';
|
import { ScopesSelectorScene } from './internal/ScopesSelectorScene';
|
||||||
@@ -14,8 +13,5 @@ export function initializeScopes() {
|
|||||||
|
|
||||||
scopesSelectorScene.setState({ dashboards: scopesDashboardsScene.getRef() });
|
scopesSelectorScene.setState({ dashboards: scopesDashboardsScene.getRef() });
|
||||||
scopesDashboardsScene.setState({ selector: scopesSelectorScene.getRef() });
|
scopesDashboardsScene.setState({ selector: scopesSelectorScene.getRef() });
|
||||||
|
|
||||||
const urlSyncManager = new UrlSyncManager();
|
|
||||||
urlSyncManager.initSync(scopesSelectorScene!);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { ScopesDashboardsTreeSearch } from './ScopesDashboardsTreeSearch';
|
|||||||
import { ScopesSelectorScene } from './ScopesSelectorScene';
|
import { ScopesSelectorScene } from './ScopesSelectorScene';
|
||||||
import { fetchDashboards } from './api';
|
import { fetchDashboards } from './api';
|
||||||
import { SuggestedDashboardsFoldersMap } from './types';
|
import { SuggestedDashboardsFoldersMap } from './types';
|
||||||
import { filterFolders, getScopeNamesFromSelectedScopes, groupDashboards } from './utils';
|
import { filterFolders, groupDashboards } from './utils';
|
||||||
|
|
||||||
export interface ScopesDashboardsSceneState extends SceneObjectState {
|
export interface ScopesDashboardsSceneState extends SceneObjectState {
|
||||||
selector: SceneObjectRef<ScopesSelectorScene> | null;
|
selector: SceneObjectRef<ScopesSelectorScene> | null;
|
||||||
@@ -27,7 +27,6 @@ export interface ScopesDashboardsSceneState extends SceneObjectState {
|
|||||||
isPanelOpened: boolean;
|
isPanelOpened: boolean;
|
||||||
isEnabled: boolean;
|
isEnabled: boolean;
|
||||||
isReadOnly: boolean;
|
isReadOnly: boolean;
|
||||||
scopesSelected: boolean;
|
|
||||||
searchQuery: string;
|
searchQuery: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +39,6 @@ export const getInitialDashboardsState: () => Omit<ScopesDashboardsSceneState, '
|
|||||||
isPanelOpened: false,
|
isPanelOpened: false,
|
||||||
isEnabled: false,
|
isEnabled: false,
|
||||||
isReadOnly: false,
|
isReadOnly: false,
|
||||||
scopesSelected: false,
|
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -56,40 +54,16 @@ export class ScopesDashboardsScene extends SceneObjectBase<ScopesDashboardsScene
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.addActivationHandler(() => {
|
this.addActivationHandler(() => {
|
||||||
const resolvedSelector = this.state.selector?.resolve();
|
|
||||||
|
|
||||||
if (resolvedSelector?.state.scopes.length ?? 0 > 0) {
|
|
||||||
this.fetchDashboards();
|
|
||||||
this.openPanel();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolvedSelector) {
|
|
||||||
this._subs.add(
|
|
||||||
resolvedSelector.subscribeToState((newState, prevState) => {
|
|
||||||
const newScopeNames = getScopeNamesFromSelectedScopes(newState.scopes ?? []);
|
|
||||||
const oldScopeNames = getScopeNamesFromSelectedScopes(prevState.scopes ?? []);
|
|
||||||
|
|
||||||
if (!isEqual(newScopeNames, oldScopeNames)) {
|
|
||||||
this.fetchDashboards();
|
|
||||||
|
|
||||||
if (newState.scopes.length > 0) {
|
|
||||||
this.openPanel();
|
|
||||||
} else {
|
|
||||||
this.closePanel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
this.dashboardsFetchingSub?.unsubscribe();
|
this.dashboardsFetchingSub?.unsubscribe();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchDashboards() {
|
public async fetchDashboards(scopeNames: string[]) {
|
||||||
const scopeNames = getScopeNamesFromSelectedScopes(this.state.selector?.resolve().state.scopes ?? []);
|
if (isEqual(this.state.forScopeNames, scopeNames)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.dashboardsFetchingSub?.unsubscribe();
|
this.dashboardsFetchingSub?.unsubscribe();
|
||||||
|
|
||||||
@@ -102,7 +76,7 @@ export class ScopesDashboardsScene extends SceneObjectBase<ScopesDashboardsScene
|
|||||||
filteredFolders: {},
|
filteredFolders: {},
|
||||||
forScopeNames: [],
|
forScopeNames: [],
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
scopesSelected: false,
|
isPanelOpened: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +97,7 @@ export class ScopesDashboardsScene extends SceneObjectBase<ScopesDashboardsScene
|
|||||||
folders,
|
folders,
|
||||||
filteredFolders,
|
filteredFolders,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
scopesSelected: scopeNames.length > 0,
|
isPanelOpened: scopeNames.length > 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.dashboardsFetchingSub?.unsubscribe();
|
this.dashboardsFetchingSub?.unsubscribe();
|
||||||
@@ -202,7 +176,7 @@ export class ScopesDashboardsScene extends SceneObjectBase<ScopesDashboardsScene
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ScopesDashboardsSceneRenderer({ model }: SceneComponentProps<ScopesDashboardsScene>) {
|
export function ScopesDashboardsSceneRenderer({ model }: SceneComponentProps<ScopesDashboardsScene>) {
|
||||||
const { dashboards, filteredFolders, isLoading, isPanelOpened, isEnabled, isReadOnly, searchQuery, scopesSelected } =
|
const { dashboards, filteredFolders, forScopeNames, isLoading, isPanelOpened, isEnabled, isReadOnly, searchQuery } =
|
||||||
model.useState();
|
model.useState();
|
||||||
|
|
||||||
const styles = useStyles2(getStyles);
|
const styles = useStyles2(getStyles);
|
||||||
@@ -212,7 +186,7 @@ export function ScopesDashboardsSceneRenderer({ model }: SceneComponentProps<Sco
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isLoading) {
|
if (!isLoading) {
|
||||||
if (!scopesSelected) {
|
if (forScopeNames.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(styles.container, styles.noResultsContainer)}
|
className={cx(styles.container, styles.noResultsContainer)}
|
||||||
|
|||||||
@@ -4,15 +4,7 @@ import { finalize, from, Subscription } from 'rxjs';
|
|||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import {
|
import { SceneComponentProps, SceneObjectBase, SceneObjectRef, SceneObjectState } from '@grafana/scenes';
|
||||||
SceneComponentProps,
|
|
||||||
SceneObjectBase,
|
|
||||||
SceneObjectRef,
|
|
||||||
SceneObjectState,
|
|
||||||
SceneObjectUrlSyncConfig,
|
|
||||||
SceneObjectUrlValues,
|
|
||||||
SceneObjectWithUrlSync,
|
|
||||||
} from '@grafana/scenes';
|
|
||||||
import { Button, Drawer, IconButton, Spinner, useStyles2 } from '@grafana/ui';
|
import { Button, Drawer, IconButton, Spinner, useStyles2 } from '@grafana/ui';
|
||||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||||
import { t, Trans } from 'app/core/internationalization';
|
import { t, Trans } from 'app/core/internationalization';
|
||||||
@@ -22,12 +14,7 @@ import { ScopesInput } from './ScopesInput';
|
|||||||
import { ScopesTree } from './ScopesTree';
|
import { ScopesTree } from './ScopesTree';
|
||||||
import { fetchNodes, fetchScope, fetchSelectedScopes } from './api';
|
import { fetchNodes, fetchScope, fetchSelectedScopes } from './api';
|
||||||
import { NodeReason, NodesMap, SelectedScope, TreeScope } from './types';
|
import { NodeReason, NodesMap, SelectedScope, TreeScope } from './types';
|
||||||
import {
|
import { getBasicScope, getScopesAndTreeScopesWithPaths, getTreeScopesFromSelectedScopes } from './utils';
|
||||||
getBasicScope,
|
|
||||||
getScopeNamesFromSelectedScopes,
|
|
||||||
getScopesAndTreeScopesWithPaths,
|
|
||||||
getTreeScopesFromSelectedScopes,
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
export interface ScopesSelectorSceneState extends SceneObjectState {
|
export interface ScopesSelectorSceneState extends SceneObjectState {
|
||||||
dashboards: SceneObjectRef<ScopesDashboardsScene> | null;
|
dashboards: SceneObjectRef<ScopesDashboardsScene> | null;
|
||||||
@@ -64,11 +51,9 @@ export const initialSelectorState: Omit<ScopesSelectorSceneState, 'dashboards'>
|
|||||||
isEnabled: false,
|
isEnabled: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class ScopesSelectorScene extends SceneObjectBase<ScopesSelectorSceneState> implements SceneObjectWithUrlSync {
|
export class ScopesSelectorScene extends SceneObjectBase<ScopesSelectorSceneState> {
|
||||||
static Component = ScopesSelectorSceneRenderer;
|
static Component = ScopesSelectorSceneRenderer;
|
||||||
|
|
||||||
protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['scopes'] });
|
|
||||||
|
|
||||||
private nodesFetchingSub: Subscription | undefined;
|
private nodesFetchingSub: Subscription | undefined;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -78,7 +63,11 @@ export class ScopesSelectorScene extends SceneObjectBase<ScopesSelectorSceneStat
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.addActivationHandler(() => {
|
this.addActivationHandler(() => {
|
||||||
this.fetchBaseNodes();
|
// Only fetch base nodes on activation when there are no nodes fetched
|
||||||
|
// This prevents an issue where base nodes are overwritten upon re-activations
|
||||||
|
if (Object.keys(this.state.nodes[''].nodes).length === 0) {
|
||||||
|
this.fetchBaseNodes();
|
||||||
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
this.nodesFetchingSub?.unsubscribe();
|
this.nodesFetchingSub?.unsubscribe();
|
||||||
@@ -86,19 +75,6 @@ export class ScopesSelectorScene extends SceneObjectBase<ScopesSelectorSceneStat
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUrlState() {
|
|
||||||
return {
|
|
||||||
scopes: this.state.isEnabled ? getScopeNamesFromSelectedScopes(this.state.scopes) : [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public updateFromUrl(values: SceneObjectUrlValues) {
|
|
||||||
let scopeNames = values.scopes ?? [];
|
|
||||||
scopeNames = Array.isArray(scopeNames) ? scopeNames : [scopeNames];
|
|
||||||
|
|
||||||
this.updateScopes(scopeNames.map((scopeName) => ({ scopeName, path: [] })));
|
|
||||||
}
|
|
||||||
|
|
||||||
public fetchBaseNodes() {
|
public fetchBaseNodes() {
|
||||||
return this.updateNode([''], true, '');
|
return this.updateNode([''], true, '');
|
||||||
}
|
}
|
||||||
@@ -231,6 +207,8 @@ export class ScopesSelectorScene extends SceneObjectBase<ScopesSelectorSceneStat
|
|||||||
isLoadingScopes: true,
|
isLoadingScopes: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.state.dashboards?.resolve().fetchDashboards(treeScopes.map(({ scopeName }) => scopeName));
|
||||||
|
|
||||||
const scopes = await fetchSelectedScopes(treeScopes);
|
const scopes = await fetchSelectedScopes(treeScopes);
|
||||||
|
|
||||||
this.setState({ scopes, isLoadingScopes: false });
|
this.setState({ scopes, isLoadingScopes: false });
|
||||||
@@ -240,8 +218,8 @@ export class ScopesSelectorScene extends SceneObjectBase<ScopesSelectorSceneStat
|
|||||||
this.setState({ treeScopes: getTreeScopesFromSelectedScopes(this.state.scopes) });
|
this.setState({ treeScopes: getTreeScopesFromSelectedScopes(this.state.scopes) });
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeAllScopes() {
|
public async removeAllScopes() {
|
||||||
this.setState({ scopes: [], treeScopes: [], isLoadingScopes: false });
|
return this.updateScopes([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public enterReadOnly() {
|
public enterReadOnly() {
|
||||||
|
|||||||
@@ -126,16 +126,16 @@ describe('Tree', () => {
|
|||||||
await openSelector();
|
await openSelector();
|
||||||
await expandResultApplications();
|
await expandResultApplications();
|
||||||
await searchScopes('Cloud');
|
await searchScopes('Cloud');
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(3);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(2);
|
||||||
expectResultApplicationsGrafanaNotPresent();
|
expectResultApplicationsGrafanaNotPresent();
|
||||||
expectResultApplicationsMimirNotPresent();
|
expectResultApplicationsMimirNotPresent();
|
||||||
expectResultApplicationsCloudPresent();
|
expectResultApplicationsCloudPresent();
|
||||||
|
|
||||||
await clearScopesSearch();
|
await clearScopesSearch();
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(4);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(3);
|
||||||
|
|
||||||
await searchScopes('Grafana');
|
await searchScopes('Grafana');
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(5);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(4);
|
||||||
expectResultApplicationsGrafanaPresent();
|
expectResultApplicationsGrafanaPresent();
|
||||||
expectResultApplicationsCloudNotPresent();
|
expectResultApplicationsCloudNotPresent();
|
||||||
});
|
});
|
||||||
@@ -156,7 +156,7 @@ describe('Tree', () => {
|
|||||||
await expandResultApplications();
|
await expandResultApplications();
|
||||||
await selectResultApplicationsMimir();
|
await selectResultApplicationsMimir();
|
||||||
await searchScopes('grafana');
|
await searchScopes('grafana');
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(3);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(2);
|
||||||
expectPersistedApplicationsMimirPresent();
|
expectPersistedApplicationsMimirPresent();
|
||||||
expectPersistedApplicationsGrafanaNotPresent();
|
expectPersistedApplicationsGrafanaNotPresent();
|
||||||
expectResultApplicationsMimirNotPresent();
|
expectResultApplicationsMimirNotPresent();
|
||||||
@@ -168,7 +168,7 @@ describe('Tree', () => {
|
|||||||
await expandResultApplications();
|
await expandResultApplications();
|
||||||
await selectResultApplicationsMimir();
|
await selectResultApplicationsMimir();
|
||||||
await searchScopes('mimir');
|
await searchScopes('mimir');
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(3);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(2);
|
||||||
expectPersistedApplicationsMimirNotPresent();
|
expectPersistedApplicationsMimirNotPresent();
|
||||||
expectResultApplicationsMimirPresent();
|
expectResultApplicationsMimirPresent();
|
||||||
});
|
});
|
||||||
@@ -178,10 +178,10 @@ describe('Tree', () => {
|
|||||||
await expandResultApplications();
|
await expandResultApplications();
|
||||||
await selectResultApplicationsMimir();
|
await selectResultApplicationsMimir();
|
||||||
await searchScopes('grafana');
|
await searchScopes('grafana');
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(3);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(2);
|
||||||
|
|
||||||
await clearScopesSearch();
|
await clearScopesSearch();
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(4);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(3);
|
||||||
expectPersistedApplicationsMimirNotPresent();
|
expectPersistedApplicationsMimirNotPresent();
|
||||||
expectPersistedApplicationsGrafanaNotPresent();
|
expectPersistedApplicationsGrafanaNotPresent();
|
||||||
expectResultApplicationsMimirPresent();
|
expectResultApplicationsMimirPresent();
|
||||||
@@ -192,15 +192,15 @@ describe('Tree', () => {
|
|||||||
await openSelector();
|
await openSelector();
|
||||||
await expandResultApplications();
|
await expandResultApplications();
|
||||||
await searchScopes('mimir');
|
await searchScopes('mimir');
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(3);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(2);
|
||||||
|
|
||||||
await selectResultApplicationsMimir();
|
await selectResultApplicationsMimir();
|
||||||
await searchScopes('unknown');
|
await searchScopes('unknown');
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(4);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(3);
|
||||||
expectPersistedApplicationsMimirPresent();
|
expectPersistedApplicationsMimirPresent();
|
||||||
|
|
||||||
await clearScopesSearch();
|
await clearScopesSearch();
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(5);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(4);
|
||||||
expectResultApplicationsMimirPresent();
|
expectResultApplicationsMimirPresent();
|
||||||
expectResultApplicationsGrafanaPresent();
|
expectResultApplicationsGrafanaPresent();
|
||||||
});
|
});
|
||||||
@@ -210,7 +210,7 @@ describe('Tree', () => {
|
|||||||
await expandResultApplications();
|
await expandResultApplications();
|
||||||
await selectResultApplicationsMimir();
|
await selectResultApplicationsMimir();
|
||||||
await searchScopes('grafana');
|
await searchScopes('grafana');
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(3);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(2);
|
||||||
|
|
||||||
await selectResultApplicationsGrafana();
|
await selectResultApplicationsGrafana();
|
||||||
await applyScopes();
|
await applyScopes();
|
||||||
@@ -222,7 +222,7 @@ describe('Tree', () => {
|
|||||||
await expandResultApplications();
|
await expandResultApplications();
|
||||||
await selectResultApplicationsMimir();
|
await selectResultApplicationsMimir();
|
||||||
await searchScopes('grafana');
|
await searchScopes('grafana');
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(3);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(2);
|
||||||
|
|
||||||
await selectResultApplicationsGrafana();
|
await selectResultApplicationsGrafana();
|
||||||
await applyScopes();
|
await applyScopes();
|
||||||
@@ -239,11 +239,11 @@ describe('Tree', () => {
|
|||||||
expectScopesHeadline('Recommended');
|
expectScopesHeadline('Recommended');
|
||||||
|
|
||||||
await searchScopes('Applications');
|
await searchScopes('Applications');
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(2);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(1);
|
||||||
expectScopesHeadline('Results');
|
expectScopesHeadline('Results');
|
||||||
|
|
||||||
await searchScopes('unknown');
|
await searchScopes('unknown');
|
||||||
expect(fetchNodesSpy).toHaveBeenCalledTimes(3);
|
expect(fetchNodesSpy).toHaveBeenCalledTimes(2);
|
||||||
expectScopesHeadline('No results found for your query');
|
expectScopesHeadline('No results found for your query');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user