Skip to content

Instantly share code, notes, and snippets.

@NicolasDurant
Last active July 12, 2020 16:40
Show Gist options
  • Save NicolasDurant/65cfc483108fd4c642a36153397f7353 to your computer and use it in GitHub Desktop.
Save NicolasDurant/65cfc483108fd4c642a36153397f7353 to your computer and use it in GitHub Desktop.
[Vue - Mixin - Vuex Dynamically Generate Stores (Blueprints)] Mixin that generates Vuex stores dynamically under different names. Useful for stores that follow a 'blueprint/base' store. #VueJS #Vuex #JavaScript #Stores
import { mapActions } from 'vuex'
import * as filter from '@/store/filter/filter.js'
/** Mixin responsible for creating our filter store module based on a blue print store called filter.js
* Is also able to create multiple stores if needed.
* @author Nicolas Durant
* @mixin create-filter-module
* @summary Usually mixed into default Page Components that use tables
* @requires vuex - to set the inital filter and sort arrays
* @requires filter - store blueprint for our dynamic stores
*/
export default {
data () {
return {
storeFilterModuleName: '',
moduleNeedsGenerator: true,
registerMultipleModules: false,
store: this.$store
}
},
created () {
/** Check if the programmer provided valid data and then generate the store module
* @author Nicolas Durant
*/
if (this.registerMultipleModules) {
this.checkMultipleData()
this.registerMultipleStoreModules(this.storeNames, this.filters, this.sorts)
} else {
this.checkData()
this.generateFilterModule(this.storeName)
this.setFilterAndSortArray(this.filter, this.sort)
}
},
methods: {
/** Check for a single module creation
* @author Nicolas Durant
* @throws {error} Error - when programmer forgot storeName implementation
* @throws {error} Error - when programmer forgot filter implementation
* @throws {error} Error - when programmer forgot sort implementation
*/
checkData () {
if (!this.storeName) {
throw new Error('[Mixin]: You have to define a storeName (String) in your Component!')
} else if (!this.filter) {
throw new Error('[Mixin]: You have to define a filter (Array) in your Component!')
} else if (!this.sort) {
throw new Error('[Mixin]: You have to define a sort (Array) in your Component!')
}
},
/** Check for a multiple module creation
* @author Nicolas Durant
* @throws {error} Error - when programmer forgot storeNames implementation
* @throws {error} Error - when programmer forgot filters implementation
* @throws {error} Error - when programmer forgot sorts implementation
*/
checkMultipleData () {
if (!this.storeNames) {
throw new Error('[Mixin]: You have to define storeNames (Array:Strings) in your Component!')
} else if (!this.filters) {
throw new Error('[Mixin]: You have to define filters (Array:Arrays) in your Component!')
} else if (!this.sorts) {
throw new Error('[Mixin]: You have to define sorts (Array:Arrays) in your Component!')
}
},
/** Creates new filter store module from our filter blueprint
* When name is already used it will reuse that store rather than creating a new one
* @author Nicolas Durant
* @params {string} name - name of the storeModule to create
* @tutorial name should have syntax -> TestPage/TestTable -> testFilter
*/
generateFilterModule (name) {
this.storeFilterModuleName = name
// register a new module only if it doesn't exist
if (!(this.store && this.store.state && this.store.state[name])) {
this.store.registerModule(name, filter)
} else {
// re-use the already existing module
this.moduleNeedsGenerator = false
}
},
/** Sets the filter and sort array in our generated store
* @author Nicolas Durant
* @params {array} filterArray
* @params {array} sortArray
*/
setFilterAndSortArray (filterArray, sortArray) {
if (this.moduleNeedsGenerator) {
let payload = {
filter: filterArray,
sort: sortArray
}
if (this.storeFilterModuleName) { this.generate(payload) } else { throw new Error('[Mixin]: Call the generateFilterModule function first!') }
}
},
/** Loop for creating new filter store modules from our filter blueprint
* When name is already used it will reuse that store rather than creating a new one
* @author Nicolas Durant
* @params {string} name - name of the storeModule to create
* @params {array} filterArray
* @params {array} sortArray
* @tutorial name should have syntax -> TestPage/TestTable -> testFilter
*/
registerMultipleStoreModules (names, filters, sorts) {
for (let name in names) {
this.generateFilterModule(names[name])
this.setFilterAndSortArray(filters[name], sorts[name])
}
},
...mapActions({
/** Initialise our newly created module
* @author Nicolas Durant
* @params {object} payload - contains filter/sort
*/
generate (dispatch, payload) {
return dispatch(this.storeFilterModuleName + '/generate', payload)
},
// for translations, but this needs a deeper look, can't be solved quickly
// filterChanged (dispatch, payload) {
// return dispatch(this.storeFilterModuleName + '/setFilter', payload)
// },
// sortChanged (dispatch, payload) {
// return dispatch(this.storeFilterModuleName + '/setSort', payload)
// }
})
},
}
export const namespaced = true
export const state = function () {
return {
filter: [],
sort: []
}
}
export const mutations = {
SET_FILTER (state, filter) {
state.filter = filter
},
SET_SORT (state, sort) {
state.sort = sort
},
SET_FILTER_OBJECT_BOOL (state, payload) {
var group = payload.group
var key = payload.item.key
var bool = payload.bool
var filterState = state.filter
for (let grp in filterState) {
if (filterState[grp].key === group.key) {
let filterArray = filterState[grp].filter
for (let fil in filterArray) {
if (filterArray[fil].key === key) {
filterArray[fil].active = bool
}
}
}
}
},
SET_SORT_OBJECT_INTEGER (state, payload) {
var key = payload.item.key
var direction = payload.direction
var sortState = state.sort
for (let fil in sortState) {
if (sortState[fil].key === key) {
sortState[fil].direction = direction
}
}
},
RESET_SORT_OBJECTS (state) {
var sortState = state.sort
for (let sort in sortState) {
sortState[sort].direction = 0
}
}
}
export const actions = {
generate ({ dispatch }, payload) {
let filter = payload.filter
let sort = payload.sort
dispatch('setFilter', filter)
dispatch('setSort', sort)
},
setFilter (context, filter) {
context.commit('SET_FILTER', filter)
},
setSort (context, sort) {
context.commit('SET_SORT', sort)
},
setFilterObjectBool (context, payload) {
context.commit('SET_FILTER_OBJECT_BOOL', payload)
},
setSortObjectInteger (context, payload) {
context.commit('SET_SORT_OBJECT_INTEGER', payload)
},
resetSortObjects (context) {
context.commit('RESET_SORT_OBJECTS',)
}
}
export const getters = {
getSortStateByObject: (state, getters) => item => {
let sort = getters.getStates('Sort')
for (var t in sort) {
let index = sort[t]
let stateArray = state[index]
for (var u in stateArray) {
if (stateArray[u].key === item.key) {
return index
}
}
}
},
getFilterStateByObject: (state, getters) => group => {
let filters = getters.getStates('Filter')
for (var t in filters) {
let index = filters[t]
let stateArray = state[index]
for (var u in stateArray) {
if (stateArray[u].key === group.key) {
return index
}
}
}
},
getStates: state => categorie => {
if (categorie === 'Sort') {
let sort = []
for (let s in state) {
if (s.includes('Sort')) {
sort.push(s)
}
}
return sort
} else {
let filters = []
for (let s in state) {
if (s.includes('Filter')) {
filters.push(s)
}
}
return filters
}
},
filter: state => {
return state.filter
},
sort: state => {
return state.sort
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment