grafana_bak/public/app/features/scopes/ScopesFacadeScene.ts
2025-04-01 10:38:02 +09:00

88 lines
2.2 KiB
TypeScript

import { isEqual } from 'lodash';
import {
SceneObjectBase,
SceneObjectState,
SceneObjectUrlSyncConfig,
SceneObjectUrlValues,
SceneObjectWithUrlSync,
} from '@grafana/scenes';
import { scopesSelectorScene } from './instance';
import { disableScopes, enableScopes, enterScopesReadOnly, exitScopesReadOnly, getSelectedScopes } from './utils';
interface ScopesFacadeState extends SceneObjectState {
// A callback that will be executed when new scopes are set
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> implements SceneObjectWithUrlSync {
protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['scopes'] });
public constructor(state: ScopesFacadeState) {
super({
...state,
renderCount: 0,
});
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 = () => {
this.enable();
this._subs.add(
scopesSelectorScene?.subscribeToState((newState, prevState) => {
if (!newState.isLoadingScopes && (prevState.isLoadingScopes || !isEqual(newState.scopes, prevState.scopes))) {
this.setState({ renderCount: (this.state.renderCount ?? 0) + 1 });
this.state.handler?.(this);
}
})
);
return () => {
this.disable();
};
};
public get value() {
return getSelectedScopes();
}
public enable() {
enableScopes();
}
public disable() {
disableScopes();
}
public enterReadOnly() {
enterScopesReadOnly();
}
public exitReadOnly() {
exitScopesReadOnly();
}
}