feat: cache custom attributes in IDB

This commit is contained in:
Shivam Mishra
2026-05-27 12:45:30 +05:30
parent 5cb517612f
commit c929319045
7 changed files with 47 additions and 7 deletions
+18 -4
View File
@@ -1,13 +1,27 @@
/* global axios */
import ApiClient from './ApiClient';
import CacheEnabledApiClient from './CacheEnabledApiClient';
class AttributeAPI extends ApiClient {
class AttributeAPI extends CacheEnabledApiClient {
constructor() {
super('custom_attribute_definitions', { accountScoped: true });
}
// eslint-disable-next-line class-methods-use-this
get cacheModelName() {
return 'custom_attribute_definition';
}
// eslint-disable-next-line class-methods-use-this
extractDataFromResponse(response) {
return response.data;
}
// eslint-disable-next-line class-methods-use-this
marshallData(dataToParse) {
return { data: dataToParse };
}
getAttributesByModel() {
return axios.get(this.url);
return super.get(true);
}
}
@@ -36,6 +36,11 @@ export const cacheableModels = [
dispatchPath: 'agents/revalidate',
setMutation: 'agents/SET_AGENTS',
},
{
name: 'custom_attribute_definition',
dispatchPath: 'attributes/revalidate',
setMutation: 'attributes/SET_CUSTOM_ATTRIBUTE',
},
];
export const cacheableModelNames = cacheableModels.map(model => model.name);
@@ -5,5 +5,5 @@
// idempotently creates any missing stores. So bump this whenever a cached
// model's serializer shape changes, or to force all clients to refetch.
//
// Wednesday, 21 May 2026 — bumped to add canned_response + account_user stores
export const DATA_VERSION = '1747785600';
// Thursday, 28 May 2026 — bumped to add canned_response + account_user stores + custom_attribute_definition store
export const DATA_VERSION = '1748390400';
@@ -54,6 +54,17 @@ export const actions = {
commit(types.SET_CUSTOM_ATTRIBUTE_UI_FLAG, { isFetching: false });
}
},
revalidate: async ({ commit }, { newKey }) => {
try {
const isExistingKeyValid = await AttributeAPI.validateCacheKey(newKey);
if (!isExistingKeyValid) {
const response = await AttributeAPI.refetchAndCommit(newKey);
commit(types.SET_CUSTOM_ATTRIBUTE, response.data);
}
} catch (error) {
// Ignore error
}
},
create: async function createAttribute({ commit }, attributeObj) {
commit(types.SET_CUSTOM_ATTRIBUTE_UI_FLAG, { isCreating: true });
try {
@@ -1,12 +1,20 @@
import axios from 'axios';
import { actions } from '../../attributes';
import * as types from '../../../mutation-types';
import AttributeAPI from '../../../../api/attributes';
import attributesList from './fixtures';
const commit = vi.fn();
global.axios = axios;
vi.mock('axios');
// Clear the IDB-backed cache between tests so each case starts from a known
// empty state and isn't affected by data persisted by a previous test.
beforeEach(async () => {
await AttributeAPI.dataManager.initDb();
await AttributeAPI.dataManager.db.clear(AttributeAPI.cacheModelName);
});
describe('#actions', () => {
describe('#get', () => {
it('sends correct actions if API is success', async () => {