UNPKG

@api-platform/client-generator

Version:

Generate apps built with Next, Nuxt, Quasar, React, React Native, Vue or Vuetify for any API documented using Hydra or OpenAPI

274 lines (254 loc) 7.54 kB
import Vue from 'vue'; import { getField, updateField } from 'vuex-map-fields'; import remove from 'lodash/remove'; import SubmissionError from '../../error/SubmissionError'; const initialState = () => ({ allIds: [], byId: {}, created: null, deleted: null, error: "", isLoading: false, resetList: false, selectItems: null, totalItems: 0, updated: null, view: null, violations: null }); const handleError = (commit, e) => { commit(ACTIONS.TOGGLE_LOADING); if (e instanceof SubmissionError) { commit(ACTIONS.SET_VIOLATIONS, e.errors); // eslint-disable-next-line commit(ACTIONS.SET_ERROR, e.errors._error); return Promise.reject(e); } // eslint-disable-next-line commit(ACTIONS.SET_ERROR, e.message); return Promise.reject(e); }; export const ACTIONS = { ADD: 'ADD', RESET_CREATE: 'RESET_CREATE', RESET_DELETE: 'RESET_DELETE', RESET_LIST: 'RESET_LIST', RESET_SHOW: 'RESET_SHOW', RESET_UPDATE: 'RESET_UPDATE', SET_CREATED: 'SET_CREATED', SET_DELETED: 'SET_DELETED', SET_ERROR: 'SET_ERROR', SET_SELECT_ITEMS: 'SET_SELECT_ITEMS', SET_TOTAL_ITEMS: 'SET_TOTAL_ITEMS', SET_UPDATED: 'SET_UPDATED', SET_VIEW: 'SET_VIEW', SET_VIOLATIONS: 'SET_VIOLATIONS', TOGGLE_LOADING: 'TOGGLE_LOADING' }; export default function makeCrudModule({ normalizeRelations = x => x, resolveRelations = x => x, service } = {}) { return { actions: { create: ({ commit }, values) => { commit(ACTIONS.SET_ERROR, ''); commit(ACTIONS.TOGGLE_LOADING); return service .create(values) .then(response => response.json()) .then(data => { commit(ACTIONS.TOGGLE_LOADING); commit(ACTIONS.ADD, data); commit(ACTIONS.SET_CREATED, data); }) .catch(e => handleError(commit, e)); }, del: ({ commit }, item) => { commit(ACTIONS.TOGGLE_LOADING); return service .del(item) .then(() => { commit(ACTIONS.TOGGLE_LOADING); commit(ACTIONS.SET_DELETED, item); }) .catch(e => handleError(commit, e)); }, fetchAll: ({ commit, state }, params) => { if (!service) throw new Error('No service specified!'); commit(ACTIONS.TOGGLE_LOADING); return service .findAll({ params }) .then(response => response.json()) .then(retrieved => { commit(ACTIONS.TOGGLE_LOADING); commit( ACTIONS.SET_TOTAL_ITEMS, retrieved['{{{hydraPrefix}}}totalItems'] ); commit(ACTIONS.SET_VIEW, retrieved['{{{hydraPrefix}}}view']); if (true === state.resetList) { commit(ACTIONS.RESET_LIST); } retrieved['{{{hydraPrefix}}}member'].forEach(item => { commit(ACTIONS.ADD, normalizeRelations(item)); }); }) .catch(e => handleError(commit, e)); }, fetchSelectItems: ( { commit }, { params = { properties: ['@id', 'name'] } } = {} ) => { commit(ACTIONS.TOGGLE_LOADING); if (!service) throw new Error('No service specified!'); return service .findAll({ params }) .then(response => response.json()) .then(retrieved => { commit( ACTIONS.SET_SELECT_ITEMS, retrieved['{{{hydraPrefix}}}member'] ); }) .catch(e => handleError(commit, e)); }, load: ({ commit }, id) => { if (!service) throw new Error('No service specified!'); commit(ACTIONS.TOGGLE_LOADING); return service .find(id) .then(response => response.json()) .then(item => { commit(ACTIONS.TOGGLE_LOADING); commit(ACTIONS.ADD, normalizeRelations(item)); }) .catch(e => handleError(commit, e)); }, resetCreate: ({ commit }) => { commit(ACTIONS.RESET_CREATE); }, resetDelete: ({ commit }) => { commit(ACTIONS.RESET_DELETE); }, resetShow: ({ commit }) => { commit(ACTIONS.RESET_SHOW); }, resetUpdate: ({ commit }) => { commit(ACTIONS.RESET_UPDATE); }, update: ({ commit }, item) => { commit(ACTIONS.SET_ERROR, ''); commit(ACTIONS.TOGGLE_LOADING); return service .update(item) .then(response => response.json()) .then(data => { commit(ACTIONS.TOGGLE_LOADING); commit(ACTIONS.SET_UPDATED, data); }) .catch(e => handleError(commit, e)); } }, getters: { find: state => id => { return resolveRelations(state.byId[id]); }, getField, list: (state, getters) => { return state.allIds.map(id => getters.find(id)); } }, mutations: { updateField, [ACTIONS.ADD]: (state, item) => { Vue.set(state.byId, item['@id'], item); Vue.set(state, 'isLoading', false); if (state.allIds.includes(item['@id'])) return; state.allIds.push(item['@id']); }, [ACTIONS.RESET_CREATE]: state => { Object.assign(state, { isLoading: false, error: '', created: null, violations: null }); }, [ACTIONS.RESET_DELETE]: state => { Object.assign(state, { isLoading: false, error: '', deleted: null }); }, [ACTIONS.RESET_LIST]: state => { Object.assign(state, { allIds: [], byId: {}, error: '', isLoading: false, resetList: false }); }, [ACTIONS.RESET_SHOW]: state => { Object.assign(state, { error: '', isLoading: false }); }, [ACTIONS.RESET_UPDATE]: state => { Object.assign(state, { error: '', isLoading: false, updated: null, violations: null }); }, [ACTIONS.SET_CREATED]: (state, created) => { Object.assign(state, { created }); }, [ACTIONS.SET_DELETED]: (state, deleted) => { if (!state.allIds.includes(deleted['@id'])) return; Object.assign(state, { allIds: remove(state.allIds, item => item['@id'] === deleted['@id']), byId: remove(state.byId, id => id === deleted['@id']), deleted }); }, [ACTIONS.SET_ERROR]: (state, error) => { Object.assign(state, { error, isLoading: false }); }, [ACTIONS.SET_SELECT_ITEMS]: (state, selectItems) => { Object.assign(state, { error: '', isLoading: false, selectItems }); }, [ACTIONS.SET_TOTAL_ITEMS]: (state, totalItems) => { Object.assign(state, { totalItems }); }, [ACTIONS.SET_UPDATED]: (state, updated) => { Object.assign(state, { byId: { [updated['@id']]: updated }, updated }); }, [ACTIONS.SET_VIEW]: (state, view) => { Object.assign(state, { view }); }, [ACTIONS.SET_VIOLATIONS]: (state, violations) => { Object.assign(state, { violations }); }, [ACTIONS.TOGGLE_LOADING]: state => { Object.assign(state, { error: '', isLoading: !state.isLoading }); } }, namespaced: true, state: initialState }; }