UserStorage: multiple improvements (#103779)

pull/91108/head
Andres Martinez Gotor 3 months ago committed by GitHub
parent 3607356f65
commit 8ebce76535
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      packages/grafana-runtime/src/internal/index.ts
  2. 17
      packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts
  3. 4
      packages/grafana-runtime/src/utils/DataSourceWithBackend.ts
  4. 10
      packages/grafana-runtime/src/utils/userStorage.test.tsx
  5. 10
      packages/grafana-runtime/src/utils/userStorage.tsx

@ -25,3 +25,5 @@ export {
setGetObservablePluginLinks,
type GetObservablePluginLinks,
} from '../services/pluginExtensions/getObservablePluginLinks';
export { UserStorage } from '../utils/userStorage';

@ -37,6 +37,14 @@ class MyDataSource extends DataSourceWithBackend<MyQuery, DataSourceJsonData> {
applyTemplateVariables(query: MyQuery, scopedVars: ScopedVars, filters?: AdHocVariableFilter[] | undefined): MyQuery {
return { ...query, applyTemplateVariablesCalled: true, filters };
}
async getValue(key: string) {
return await this.userStorage.getItem(key);
}
async setValue(key: string, value: string) {
await this.userStorage.setItem(key, value);
}
}
const mockDatasourceRequest = jest.fn<Promise<FetchResponse>, BackendSrvRequest[]>();
@ -536,6 +544,15 @@ describe('DataSourceWithBackend', () => {
expect(publicDashboardQueryHandler).toHaveBeenCalledWith(request);
});
});
describe('user storage', () => {
test('sets and gets a value', async () => {
const { ds } = createMockDatasource();
await ds.setValue('multiplier', '1');
expect(await ds.getValue('multiplier')).toBe('1');
});
});
});
function createMockDatasource() {

@ -34,6 +34,7 @@ import {
import { publicDashboardQueryHandler } from './publicDashboardQueryHandler';
import { BackendDataSourceResponse, toDataQueryResponse } from './queryResponse';
import { UserStorage } from './userStorage';
/**
* @internal
@ -121,8 +122,11 @@ class DataSourceWithBackend<
TQuery extends DataQuery = DataQuery,
TOptions extends DataSourceJsonData = DataSourceJsonData,
> extends DataSourceApi<TQuery, TOptions> {
protected userStorage: UserStorage;
constructor(instanceSettings: DataSourceInstanceSettings<TOptions>) {
super(instanceSettings);
this.userStorage = new UserStorage(instanceSettings.type);
}
/**

@ -48,15 +48,15 @@ describe('userStorage', () => {
it('use localStorage if the user is not logged in', async () => {
config.bootData.user.isSignedIn = false;
const storage = usePluginUserStorage();
storage.getItem('key');
expect(localStorage.getItem).toHaveBeenCalled();
await storage.getItem('key');
expect(localStorage.getItem).toHaveBeenCalledWith('plugin-id:abc:key');
});
it('use localStorage if the user storage is not found', async () => {
request.mockReturnValue(Promise.reject({ status: 404 } as FetchError));
const storage = usePluginUserStorage();
await storage.getItem('key');
expect(localStorage.getItem).toHaveBeenCalled();
expect(localStorage.getItem).toHaveBeenCalledWith('plugin-id:abc:key');
});
it('returns the value from the user storage', async () => {
@ -73,8 +73,8 @@ describe('userStorage', () => {
it('use localStorage if the user is not logged in', async () => {
config.bootData.user.isSignedIn = false;
const storage = usePluginUserStorage();
storage.setItem('key', 'value');
expect(localStorage.setItem).toHaveBeenCalled();
await storage.setItem('key', 'value');
expect(localStorage.setItem).toHaveBeenCalledWith('plugin-id:abc:key', 'value');
});
it('creates a new user storage if it does not exist', async () => {

@ -37,9 +37,9 @@ async function apiRequest<T>(requestOptions: RequestOptions) {
/**
* A class for interacting with the backend user storage.
* Unexported because it is currently only be used through the useUserStorage hook.
* Exposed internally only to avoid misuse (wrong service name)..
*/
class UserStorage {
export class UserStorage {
private service: string;
private resourceName: string;
private userUID: string;
@ -76,13 +76,13 @@ class UserStorage {
async getItem(key: string): Promise<string | null> {
if (!this.canUseUserStorage) {
// Fallback to localStorage
return localStorage.getItem(this.resourceName);
return localStorage.getItem(`${this.resourceName}:${key}`);
}
// Ensure this.storageSpec is initialized
await this.init();
if (!this.storageSpec) {
// Also, fallback to localStorage for backward compatibility
return localStorage.getItem(this.resourceName);
return localStorage.getItem(`${this.resourceName}:${key}`);
}
return this.storageSpec.data[key];
}
@ -90,7 +90,7 @@ class UserStorage {
async setItem(key: string, value: string): Promise<void> {
if (!this.canUseUserStorage) {
// Fallback to localStorage
localStorage.setItem(key, value);
localStorage.setItem(`${this.resourceName}:${key}`, value);
return;
}

Loading…
Cancel
Save