@mee4dy/crud
Version:
Create a backend and frontend in 5 minutes! With our powerful full stack crud system, customize it to suit you.
266 lines (214 loc) • 6.56 kB
text/typescript
import * as _ from 'lodash';
import qs from 'qs';
interface FetchOptions {
applyQuery?: boolean;
filters?: object;
groups?: string[];
orders?: object;
}
export default {
setCtx({ getters, dispatch, state, commit }) {
commit('setCtx', { getters, dispatch, commit, state });
},
setQuery({ commit, dispatch }, query) {
commit('setQuery', query);
dispatch('setQuerySelectedFilters', query);
dispatch('setQuerySelectedGroups', query);
dispatch('setQuerySelectedOrders', query);
},
setQuerySelectedFilters({ commit, state, getters }, query) {
const filters = getters.getFilters;
const queryFilters = query;
const selectedFilters = {};
for (let key in queryFilters) {
const filterValue = queryFilters[key];
if (key === 'pk') {
queryFilters[state.pk] = filterValue;
key = state.pk;
}
if (filters.find((filter) => filter.key === key)) {
selectedFilters[key] = filterValue;
}
}
commit('setSelectedFilters', selectedFilters);
},
setQuerySelectedGroups({ commit, state, getters }, query) {
const groups = getters.getGroups.map((group) => group.key);
const queryGroups = query?.groups ? query?.groups.split(',') : [];
const selectedGroups = [];
for (let key of queryGroups) {
if (key === 'pk') {
key = state.pk;
}
if (groups.includes(key)) {
selectedGroups.push(key);
}
}
commit('setSelectedGroups', selectedGroups);
},
setQuerySelectedOrders({ commit, state, getters }, query) {
const orders = getters.getOrders;
const queryOrders = query?.orders ? query?.orders.split(',') : [];
const selectedOrders = {};
for (let key of queryOrders) {
const directionDesc = key.charAt(0) === '-';
if (directionDesc) {
key = key.substring(1);
}
if (key === 'pk') {
queryOrders[state.pk] = queryOrders[key];
key = state.pk;
}
if (orders.includes(key)) {
selectedOrders[key] = directionDesc ? 'desc' : 'asc';
}
}
commit('setSelectedOrders', selectedOrders);
},
syncSelectedToQuery({ commit, state, getters }) {
const querySelectedFilters = getters.getSelectedFilters;
const querySelectedGroups = getters.getSelectedGroups.join(',');
const querySelectedOrders = Object.entries(getters.getSelectedOrders)
.map(([direction, field]) => `${direction === 'desc' ? '-' : ''}${field}`)
.join(',');
const querySelected = {
filters: querySelectedFilters,
groups: querySelectedGroups,
orders: querySelectedOrders,
};
const queryParams = new URLSearchParams(window.location.search);
for (const queryParam in querySelected) {
const queryValue = querySelected[queryParam];
if (queryValue) {
if (typeof queryValue === 'object') {
Object.entries(getters.getSelectedFilters).forEach(([field, value]) => {
queryParams.set(field, value.toString());
});
} else {
queryParams.set(queryParam, queryValue);
}
}
}
const queryString = decodeURIComponent(queryParams.toString());
history.pushState(null, null, queryString ? `?${queryString}` : '');
},
async setItems({ commit, state, getters, dispatch }, items) {
await dispatch('setCtx');
commit('setItems', items);
},
async fetch({ commit, state, getters, dispatch }, options: FetchOptions) {
const endpoint = getters.getEndpoint('fetch');
if (!endpoint) {
return;
}
try {
commit('setLoading', true);
const params = getters.getParams;
const configClientAbort = getters.getState('config.client.abort');
const cancelTokenPrev = getters.getState('config.client.cancelToken');
if (options?.applyQuery) {
dispatch('syncSelectedToQuery');
}
if (options?.filters) {
params.filters = options.filters;
}
if (options?.groups) {
params.groups = options.groups;
}
if (options?.orders) {
params.orders = options.orders;
}
if (configClientAbort && cancelTokenPrev) {
cancelTokenPrev.cancel();
}
const cancelToken = this.$axios.CancelToken;
const source = cancelToken.source();
commit('setState', {
path: 'config.client.cancelToken',
value: source,
});
const response = await this.$axios.get(endpoint, {
cancelToken: source.token,
params: params,
paramsSerializer: (params) => qs.stringify(params, { arrayFormat: 'brackets' }),
});
let items = response.data.data.items;
dispatch('setItems', items);
return response?.data;
} catch (e) {
console.log(e);
} finally {
commit('setLoading', false);
commit('setState', {
path: 'config.client.cancelToken',
value: null,
});
}
},
async create({ commit, state, dispatch, getters }, { data }) {
const endpoint = getters.getEndpoint('create');
if (!endpoint) {
return;
}
try {
const response = await this.$axios.post(endpoint, {
data,
});
return response?.data;
} catch (e) {
console.log(e);
}
},
async update({ commit, state, dispatch, getters }, { pk, data, level }) {
if (level && level.path && level.parentPK) {
const entity = _.toPath(level.path)[0];
await dispatch(`${entity}/update`, { pk, data }, { root: true });
commit('update', {
pk,
data,
level,
});
return;
}
const endpoint = getters.getEndpoint('update', pk);
if (!endpoint || !pk) {
return;
}
try {
const response = await this.$axios.post(endpoint, {
pk,
data,
});
commit('update', {
pk,
data,
});
return response?.data;
} catch (e) {
console.log(e);
}
},
async delete({ commit, state, getters, dispatch }, { pk, level }) {
if (level && level.path && level.parentPK) {
const entity = _.toPath(level.path)[0];
await dispatch(`${entity}/delete`, { pk }, { root: true });
commit('delete', {
pk,
level,
});
return;
}
const endpoint = getters.getEndpoint('delete', pk);
if (!endpoint || !pk) {
return;
}
try {
await this.$axios.post(endpoint, {
pk: pk,
});
commit('delete', { pk });
} catch (e) {
console.log(e);
}
},
};