UNPKG

freedom-vue-framework

Version:
249 lines (228 loc) 8.22 kB
import _camelCase from 'lodash/camelCase' import _pick from 'lodash/pick' import Arr from 'freedom-js-support/src/utilities/arr' import Querifier from 'freedom-js-support/src/utilities/querifier' import Vue from 'vue'; export const types = { PER_PAGE:'per_page', PAGE:'page', SEARCH:'search', ORDER_BY:'orderBy', TOTAL:'total', META:'meta', GET_PARAMS:'getParams', SET_PARAMS:'setParams', SET_QUERY_STRING:'setQueryString', GET_QUERY_STRING:'getQueryString', } const exclude = ['total','meta','queryString']; const _defaults = { per_page : 15, page : 1, search : {}, orderBy : {}, total : 0, meta: {}, queryString:'', isLoaded:false, } const addMutation = (mutations,key) => { let type = _camelCase(key) mutations[type] = (state,value) => { if(!state.hasOwnProperty(key)){ return } if(typeof value !== 'object' || value === null){ return Vue.set(state,key,value) } Object.keys(value).forEach((field)=>{ Vue.set(state[key],field,value[field]) }); } return mutations; } const addGetter = (getters,key) => { let type = _camelCase(key); getters[type] = (state) => { return state[ key ]; } return getters; } const setCurrentPage = (context,pagination) => { let current_page = Arr.getProperty(pagination,'current_page',null) if(!current_page){ return } context.commit(types.PAGE, current_page) } const builder = function(store,config){ let handler = Arr.getProperty(config,'handler',null); let block = Arr.getProperty(config,'block',null); let bus = Arr.getProperty(config,'bus','search') let parameters = [types.PER_PAGE,types.PAGE,types.SEARCH,types.ORDER_BY,types.TOTAL] .concat(Arr.getProperty(config,'parameters',[])) .filter((value,index,self)=>{ return self.indexOf(value) === index; }) let defaults = Object.assign(_defaults,store.state); let state = Object.assign({ },defaults); if(handler === null){ console.error('A SEARCH HANDLER PARAM IS REQUIRED') throw 'A SEARCH HANDLER PARAM IS REQUIRED' } let getters = Object.assign({ from(state){ return Arr.getProperty(state.meta,'from',0) }, to(state){ return Arr.getProperty(state.meta,'to',0) }, total(state){ return Arr.getProperty(state.meta,'total',0) }, lastPage(state){ return Arr.getProperty(state.meta,'last_page',0) }, getParams(state){ return _pick(state,parameters); }, getQueryString(state){ return state['queryString'] }, getQueryObject(state){ return Querifier.querifyable.reduce((query,key,index)=>{ if(!state.hasOwnProperty(key) || !state[key] || ( typeof state[key] === 'object' && Object.keys(state[key]).length <= 0)){ return query; } let isObject = typeof state[key] == 'object' && !Array.isArray(state[key]) query[key] = isObject ? Querifier.getCriteriaString(state[key],key,{decode: false, valueOnly:true }) : state[key] return query; },{}) }, isLoaded(state){ return state.isLoaded; } },store.getters); let mutations = Object.assign({ setIsLoaded(state,payload){ Vue.set(state,'isLoaded',Boolean(payload)); }, orderBy(state,payload){ Vue.set(state,types.ORDER_BY,payload); }, setParams(state,value){ Object.keys(value).forEach((field)=>{ Vue.set(state,field,value[field]) }); }, setQueryString(state){ let queryables = Object.keys(state).reduce(( queryables,key,index )=>{ if(!exclude.includes(key)){ queryables[key] = state[key]; } return queryables; },{}); Vue.set(state,'queryString',Querifier.querify(queryables).join('&')) }, search(state,payload){ state[types.SEARCH] = {...payload}; } },store.mutations) Object.values(types).forEach((key)=>{ if(key.indexOf('set') < 0 && !getters.hasOwnProperty(key)){ getters = addGetter(getters,key) } if(key.indexOf('get') < 0 && !mutations.hasOwnProperty(key)){ mutations = addMutation(mutations,key) } }); let actions = Object.assign({ search(context,payload){ context.commit(types.SEARCH,payload); context.commit(types.PAGE,1); context.commit(types.TOTAL,null) Vue.bus.emit(`${bus}:search`,payload); return context.dispatch('handle'); }, orderBy(context,payload){ context.commit(types.ORDER_BY,payload); Vue.bus.emit(`${bus}:orderBy`,payload); return context.dispatch('handle'); }, page(context,payload){ context.commit(types.PAGE,payload); Vue.bus.emit(`${bus}:page-change`,payload); return context.dispatch('handle'); }, previousPage({getters,dispatch}){ let { page, lastPage } = getters; if(page <= lastPage){ return dispatch('page',--page); } return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(); },1000) }); }, nextPage({getters,dispatch}){ let { page, lastPage } = getters; if( page <= lastPage){ return dispatch('page',++page); } return new Promise((resolve)=>{ setTimeout(()=>{ resolve(); },1000) }); }, perPage(context,payload){ context.commit(_camelCase(types.PER_PAGE),payload); Vue.bus.emit(`${bus}:per-page-change`,payload); return context.dispatch('handle'); }, clear({ state }){ let original = Object.assign({ },defaults); Object.keys(state).forEach((field)=>{ let value = original[field] Vue.set(state,field,value) if(typeof value === 'object' && value && !Array.isArray(value)){ state[field] = Object.assign({},value) } }); Vue.bus.emit(`${bus}:clear-state`,original); }, recount(context){ context.commit(_camelCase(types.TOTAL),undefined) Vue.bus.emit(`${bus}:recount`); return context.dispatch('handle'); }, handle(context,payload={}){ let process = () => { context.commit(types.SET_PARAMS,payload); let params = Object.assign(_pick(context.state,parameters),payload); Vue.bus.emit(`${bus}:loading`,{ state: context.state, params } ); let promise = handler(context,params); promise.then((response)=>{ let meta = Arr.getProperty(response,types.META,defaults[types.META]); let pagination = Arr.getProperty(meta,'pagination',meta); setCurrentPage(context,pagination); context.commit(types.META, pagination) context.commit(types.TOTAL, Arr.getProperty(pagination,'total',undefined)); context.commit(types.SET_QUERY_STRING); context.commit('setIsLoaded',true); Vue.bus.emit(`${bus}:load`,{ state: context.state, response} ); Vue.bus.emit(`${bus}:loaded`,{ state: context.state, response} ); }) return promise; } return typeof block === 'function' ? block(process) : process(); }, },store.actions) return { namespaced:true, state, getters, mutations, actions, } } export default builder