User Storage: Expose functionality for frontend-only datasources (#106165)

bergquist_update_tempo_ref
Andres Martinez Gotor 4 weeks ago committed by GitHub
parent fc988c8771
commit 301d78bf96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      packages/grafana-data/src/index.ts
  2. 6
      packages/grafana-data/src/types/datasource.ts
  3. 15
      packages/grafana-data/src/types/userStorage.ts
  4. 2
      packages/grafana-runtime/src/utils/DataSourceWithBackend.ts
  5. 21
      packages/grafana-runtime/src/utils/userStorage.tsx
  6. 6
      public/app/features/plugins/datasource_srv.ts

@ -877,3 +877,5 @@ export {
userHasAllPermissions,
userHasAnyPermission,
} from './rbac/rbac';
export { type UserStorage } from './types/userStorage';

@ -19,6 +19,7 @@ import { DataQuery } from './query';
import { Scope } from './scopes';
import { AdHocVariableFilter } from './templateVars';
import { RawTimeRange, TimeRange } from './time';
import { UserStorage } from './userStorage';
import { CustomVariableSupport, DataSourceVariableSupport, StandardVariableSupport } from './variables';
export interface DataSourcePluginOptionsEditorProps<
@ -238,6 +239,11 @@ abstract class DataSourceApi<
*/
interval?: string;
/**
* Initialized in datasource_srv.ts
*/
userStorage?: UserStorage;
constructor(instanceSettings: DataSourceInstanceSettings<TOptions>) {
this.name = instanceSettings.name;
this.id = instanceSettings.id;

@ -0,0 +1,15 @@
export interface UserStorage {
/**
* Retrieves an item from the backend user storage or local storage if not enabled.
* @param key - The key of the item to retrieve.
* @returns A promise that resolves to the item value or null if not found.
*/
getItem(key: string): Promise<string | null>;
/**
* Sets an item in the backend user storage or local storage if not enabled.
* @param key - The key of the item to set.
* @param value - The value of the item to set.
* @returns A promise that resolves when the item is set.
*/
setItem(key: string, value: string): Promise<void>;
}

@ -122,7 +122,7 @@ class DataSourceWithBackend<
TQuery extends DataQuery = DataQuery,
TOptions extends DataSourceJsonData = DataSourceJsonData,
> extends DataSourceApi<TQuery, TOptions> {
protected userStorage: UserStorage;
userStorage: UserStorage;
constructor(instanceSettings: DataSourceInstanceSettings<TOptions>) {
super(instanceSettings);

@ -1,7 +1,7 @@
import { get } from 'lodash';
import { lastValueFrom } from 'rxjs';
import { usePluginContext } from '@grafana/data';
import { usePluginContext, type UserStorage as UserStorageType } from '@grafana/data';
import { config } from '../config';
import { BackendSrvRequest, getBackendSrv } from '../services';
@ -40,7 +40,7 @@ async function apiRequest<T>(requestOptions: RequestOptions) {
* A class for interacting with the backend user storage.
* Exposed internally only to avoid misuse (wrong service name)..
*/
export class UserStorage {
export class UserStorage implements UserStorageType {
private service: string;
private resourceName: string;
private userUID: string;
@ -141,21 +141,8 @@ export class UserStorage {
}
}
export interface PluginUserStorage {
/**
* Retrieves an item from the backend user storage or local storage if not enabled.
* @param key - The key of the item to retrieve.
* @returns A promise that resolves to the item value or null if not found.
*/
getItem(key: string): Promise<string | null>;
/**
* Sets an item in the backend user storage or local storage if not enabled.
* @param key - The key of the item to set.
* @param value - The value of the item to set.
* @returns A promise that resolves when the item is set.
*/
setItem(key: string, value: string): Promise<void>;
}
// This is a type alias to avoid breaking changes
export interface PluginUserStorage extends UserStorageType {}
/**
* A hook for interacting with the backend user storage (or local storage if not enabled).

@ -19,7 +19,7 @@ import {
TemplateSrv,
isExpressionReference,
} from '@grafana/runtime';
import { ExpressionDatasourceRef } from '@grafana/runtime/internal';
import { ExpressionDatasourceRef, UserStorage } from '@grafana/runtime/internal';
import { DataQuery, DataSourceJsonData } from '@grafana/schema';
import appEvents from 'app/core/app_events';
import config from 'app/core/config';
@ -205,6 +205,10 @@ export class DatasourceSrv implements DataSourceService {
const instance = new dsPlugin.DataSourceClass(instanceSettings);
instance.components = dsPlugin.components;
if (!instance.userStorage) {
// DatasourceApi does not instantiate a userStorage property, but DataSourceWithBackend does
instance.userStorage = new UserStorage(instanceSettings.type);
}
// Some old plugins does not extend DataSourceApi so we need to manually patch them
if (!(instance instanceof DataSourceApi)) {

Loading…
Cancel
Save