Some checks failed
continuous-integration/drone/push Build is failing
- Complete GGZ Ecademy Nuxt.js user portal - Learning products browser and management - Member management interface - User authentication and roles - Multi-language support (NL/EN) - Vuex store for state management - Component-based architecture
449 lines
12 KiB
JavaScript
449 lines
12 KiB
JavaScript
import Vue from 'vue'
|
|
|
|
export const state = () => ({
|
|
products: [],
|
|
remote: {},
|
|
local: { filtersGrouped: {} },
|
|
images: [],
|
|
cover: {
|
|
name: '',
|
|
url: '',
|
|
file: null,
|
|
},
|
|
tile: {
|
|
name: '',
|
|
url: '',
|
|
file: null,
|
|
},
|
|
columns: [
|
|
{
|
|
text: 'learning.product',
|
|
sortable: false,
|
|
value: 'cover',
|
|
fixed: true,
|
|
},
|
|
{
|
|
text: '',
|
|
sortable: false,
|
|
value: 'title',
|
|
fixed: true,
|
|
divider: true,
|
|
},
|
|
{
|
|
text: 'learning.code',
|
|
sortable: true,
|
|
value: 'code',
|
|
display: true,
|
|
},
|
|
{
|
|
text: 'learning.partner',
|
|
sortable: true,
|
|
value: 'partner',
|
|
display: true,
|
|
},
|
|
{
|
|
text: 'learning.owner',
|
|
sortable: true,
|
|
value: 'owner',
|
|
display: true,
|
|
},
|
|
{
|
|
text: 'learning.status.title',
|
|
sortable: false,
|
|
value: 'status',
|
|
display: true,
|
|
},
|
|
{
|
|
text: 'learning.product_overview.duration',
|
|
sortable: true,
|
|
value: 'lead_time',
|
|
display: true,
|
|
},
|
|
{
|
|
text: 'learning.filters.product_type',
|
|
sortable: false,
|
|
value: 'product_type',
|
|
display: true,
|
|
},
|
|
{
|
|
text: 'learning.filters.theme',
|
|
sortable: true,
|
|
value: 'theme',
|
|
display: true,
|
|
},
|
|
{
|
|
text: 'learning.filters.course',
|
|
sortable: false,
|
|
value: 'course',
|
|
display: true,
|
|
},
|
|
],
|
|
filters: [],
|
|
columnsSorted: [],
|
|
columnsSortedSubset: [],
|
|
filtersSelected: [],
|
|
filtersDisabledForSearch: ['format_version'],
|
|
versionsFiltersSelected: {},
|
|
accreditationsFiltersSelected: {},
|
|
checklists: [],
|
|
checklistsSelected: [],
|
|
synonyms: [],
|
|
synonymsSelected: [],
|
|
coursesTableOptions: {},
|
|
})
|
|
|
|
export const actions = {
|
|
async pullProducts({ commit, state }) {
|
|
try {
|
|
const response = await this.$axios.get('/learning-products')
|
|
const learningProducts = response.data
|
|
await commit('STORE_PRODUCTS', learningProducts)
|
|
} catch (error) {
|
|
console.log('pullProducts -> error', error)
|
|
}
|
|
},
|
|
|
|
async setColumns({ commit, state }, arrayColumns = state.columns) {
|
|
await commit('SORT_COLUMNS', arrayColumns)
|
|
},
|
|
async setFilters({ commit, state }, arrayFilters = state.filters) {
|
|
await commit('SORT_FILTERS', arrayFilters)
|
|
},
|
|
async resetProduct({ commit }) {
|
|
await commit('RESET_PRODUCT')
|
|
await commit('RESET_COVER')
|
|
await commit('RESET_TILE')
|
|
await commit('RESET_SELECTED_SYNONYMS')
|
|
},
|
|
|
|
async storeProduct({ commit, state, rootGetters }, published = false) {
|
|
// Set product to save as published
|
|
if (published)
|
|
await commit('UPDATE_FIELD', { field: 'published', value: 1 })
|
|
if (state.local.in_the_picture)
|
|
await commit('UPDATE_FIELD', { field: 'in_the_picture', value: 1 })
|
|
if (state.local.for_members)
|
|
await commit('UPDATE_FIELD', { field: 'for_members', value: 1 })
|
|
|
|
// Check if remotely the product was already set as published
|
|
const wasPublished = state.remote.published
|
|
|
|
// If it has a parent_id, it's a draft of a product published
|
|
const hasParentId = state.remote.parent_id
|
|
|
|
// Preparing data
|
|
//-----------------------------------------
|
|
const formData = new FormData()
|
|
|
|
for (let key in state.local) {
|
|
if (state.local[key] && state.local[key] != 'null') {
|
|
// If value is array/object, stringify that
|
|
formData.append(
|
|
key,
|
|
typeof state.local[key] === 'object'
|
|
? JSON.stringify(state.local[key])
|
|
: state.local[key]
|
|
)
|
|
} else {
|
|
formData.append(key, '')
|
|
}
|
|
}
|
|
|
|
if (state.tile.file) formData.append('tile', state.tile.file)
|
|
else formData.delete('tile')
|
|
|
|
if (state.cover.file) formData.append('cover', state.cover.file)
|
|
else formData.delete('cover')
|
|
|
|
if (state.local.parent_id == null) formData.delete('parent_id')
|
|
|
|
// If wasn't published and we want to save as draft
|
|
if (wasPublished && !published && !hasParentId) {
|
|
formData.append('parent_id', state.remote.id)
|
|
formData.delete('published')
|
|
formData.delete('id')
|
|
}
|
|
|
|
if (rootGetters.synonymsHaveChanges) {
|
|
formData.append(
|
|
'synonymsSelected',
|
|
JSON.stringify(state.synonymsSelected)
|
|
)
|
|
}
|
|
|
|
if (!formData.get('published')) {
|
|
formData.delete('published')
|
|
}
|
|
|
|
let slug = ''
|
|
|
|
// console.log([...formData])
|
|
await this.$axios
|
|
.post('/learning-products', formData)
|
|
.then((response) => {
|
|
// 'Cause if it's published we close the page
|
|
Promise.resolve(response)
|
|
if (!published) commit('SET_PRODUCT', response.data)
|
|
slug = response.data.slug
|
|
})
|
|
.catch((error) => Promise.reject(error))
|
|
|
|
return slug
|
|
},
|
|
|
|
async deleteProduct({ dispatch, state }, productId) {
|
|
if (!productId) return
|
|
|
|
try {
|
|
// $nuxt.$loading.start();
|
|
await this.$axios.delete(`/learning-products/${productId}`)
|
|
await dispatch('pullProducts')
|
|
|
|
$nuxt.$loading.finish()
|
|
$nuxt.$notifier.showMessage({
|
|
content: `Product deleted`,
|
|
color: 'success',
|
|
icon: 'mdi-delete',
|
|
})
|
|
} catch (error) {
|
|
console.log('deleteProduct -> error', error)
|
|
$nuxt.$loading.finish()
|
|
$nuxt.$notifier.showMessage({
|
|
content: error,
|
|
color: 'error',
|
|
icon: 'mdi-close',
|
|
})
|
|
}
|
|
},
|
|
|
|
async removeSynonym({ commit, state }, synonymId) {
|
|
if (!synonymId) return
|
|
|
|
const backup = [...state.synonymsSelected]
|
|
|
|
const synonymsFiltered = backup.filter((s) => s !== synonymId)
|
|
|
|
commit('SELECT_SYNONYM', synonymsFiltered)
|
|
},
|
|
}
|
|
|
|
export const mutations = {
|
|
STORE_PRODUCTS: (state, products) => {
|
|
state.products = []
|
|
state.products = [...products]
|
|
},
|
|
SORT_COLUMNS: (state, columns) => {
|
|
state.columnsSorted = columns
|
|
},
|
|
SET_COLUMNS_SUBSET: (state, columns) => {
|
|
state.columnsSortedSubset = null
|
|
state.columnsSortedSubset = columns
|
|
},
|
|
SORT_FILTERS: (state, filters) => {
|
|
// Workaround because Vuex doesn't recognize changes otherwise
|
|
state.filters = []
|
|
state.filters = [...filters]
|
|
},
|
|
SET_PRODUCT: (state, product) => {
|
|
state.remote = {}
|
|
state.local = {}
|
|
state.remote = Object.assign({}, product)
|
|
state.local = Object.assign({}, product)
|
|
|
|
// console.log(JSON.stringify(state.remote))
|
|
// console.log(JSON.stringify(state.local))
|
|
},
|
|
RESET_PRODUCT: (state) => {
|
|
state.remote = {}
|
|
state.local = {}
|
|
state.versionsFiltersSelected = {}
|
|
},
|
|
RESET_VERSIONS_FILTERS: (state) => {
|
|
state.versionsFiltersSelected = {}
|
|
},
|
|
RESET_ACCREDITATIONS_FILTERS: (state) => {
|
|
state.accreditationsFiltersSelected = {}
|
|
},
|
|
UPDATE_FIELD: (state, payload) => {
|
|
state.local[payload.field] = payload.value
|
|
},
|
|
UPDATE_FILTERS: async (state, payload) => {
|
|
if (payload.target === 'versions') {
|
|
return Vue.set(
|
|
state.versionsFiltersSelected,
|
|
payload.filterId,
|
|
Array.isArray(payload.value) ? payload.value : [payload.value]
|
|
)
|
|
|
|
// Workaround because Vuex doesn't recognize changes otherwise
|
|
// let tmp = Object.assign({}, state.versionsFiltersSelected)
|
|
// state.versionsFiltersSelected = {}
|
|
// state.versionsFiltersSelected = Object.assign({}, tmp)
|
|
|
|
// return state.versionsFiltersSelected[payload.filterId] = Array.isArray(payload.value)
|
|
// ? payload.value
|
|
// : [payload.value]
|
|
}
|
|
|
|
if (payload.target === 'accreditations') {
|
|
return Vue.set(
|
|
state.accreditationsFiltersSelected,
|
|
payload.filterId,
|
|
Array.isArray(payload.value) ? payload.value : [payload.value]
|
|
)
|
|
|
|
// Workaround because Vuex doesn't recognize changes otherwise
|
|
// let tmp = Object.assign({}, state.accreditationsFiltersSelected)
|
|
// state.accreditationsFiltersSelected = {}
|
|
// state.accreditationsFiltersSelected = Object.assign({}, tmp)
|
|
|
|
// return state.accreditationsFiltersSelected[payload.filterId] = Array.isArray(payload.value)
|
|
// ? payload.value
|
|
// : [payload.value]
|
|
}
|
|
|
|
if (!state.local['filtersGrouped']) state.local['filtersGrouped'] = {}
|
|
|
|
state.local['filtersGrouped'][payload.filterId] = Array.isArray(
|
|
payload.value
|
|
)
|
|
? payload.value
|
|
: [payload.value]
|
|
state.local['filterItemsSelected'] = Object.values(
|
|
state.local.filtersGrouped
|
|
).flat()
|
|
},
|
|
|
|
ADD_VERSION_LOCAL: (state, payload) => {
|
|
// Workaround because Vuex doesn't recognize changes otherwise
|
|
const tmp = [...state.local.versions]
|
|
tmp.push(payload)
|
|
|
|
state.local.versions = []
|
|
state.remote.versions = []
|
|
state.local.versions = [...tmp]
|
|
state.remote.versions = [...tmp]
|
|
},
|
|
EDIT_VERSION_LOCAL: (state, payload) => {
|
|
// Workaround because Vuex doesn't recognize changes otherwise
|
|
let tmp = [...state.local.versions]
|
|
tmp[payload.index] = Object.assign({}, payload.version)
|
|
|
|
state.local.versions = []
|
|
state.remote.versions = []
|
|
state.local.versions = [...tmp]
|
|
state.remote.versions = [...tmp]
|
|
},
|
|
DELETE_VERSION_LOCAL: (state, payload) => {
|
|
const indexLocal = state.local.versions.indexOf(payload)
|
|
const indexRemote = state.remote.versions.indexOf(payload)
|
|
state.local.versions.splice(indexLocal, 1)
|
|
state.remote.versions.splice(indexRemote, 1)
|
|
},
|
|
|
|
ADD_ACCREDITATION_LOCAL: (state, payload) => {
|
|
// Workaround because Vuex doesn't recognize changes otherwise
|
|
const tmp = [...state.local.accreditations]
|
|
tmp.push(payload)
|
|
|
|
state.local.accreditations = []
|
|
state.local.accreditations = [...tmp]
|
|
},
|
|
EDIT_ACCREDITATION_LOCAL: (state, payload) => {
|
|
// Workaround because Vuex doesn't recognize changes otherwise
|
|
let tmp = [...state.local.accreditations]
|
|
tmp[payload.index] = Object.assign({}, payload.accreditation)
|
|
|
|
state.local.accreditations = []
|
|
state.local.accreditations = [...tmp]
|
|
},
|
|
DELETE_ACCREDITATION_LOCAL: (state, payload) => {
|
|
const index = state.local.accreditations.indexOf(payload)
|
|
state.local.accreditations.splice(index, 1)
|
|
},
|
|
ADD_COURSE_NOTIFICATION_LOCAL: (state, payload) => {
|
|
// Workaround because Vuex doesn't recognize changes otherwise
|
|
const tmp = [...state.local.notifications]
|
|
tmp.push(payload)
|
|
|
|
state.local.notifications = []
|
|
state.local.notifications = [...tmp]
|
|
},
|
|
EDIT_COURSE_NOTIFICATION_LOCAL: (state, payload) => {
|
|
// Workaround because Vuex doesn't recognize changes otherwise
|
|
let tmp = [...state.local.notifications]
|
|
tmp[payload.index] = Object.assign({}, payload.notification)
|
|
|
|
state.local.notifications = []
|
|
state.local.notifications = [...tmp]
|
|
},
|
|
DELETE_COURSE_NOTIFICATION_LOCAL: (state, payload) => {
|
|
const index = state.local.notifications.indexOf(payload)
|
|
state.local.notifications.splice(index, 1)
|
|
},
|
|
RESET_TILE: (state) => {
|
|
state.tile = {
|
|
name: '',
|
|
url: '',
|
|
file: null,
|
|
}
|
|
},
|
|
UPDATE_TILE: (state, payload) => {
|
|
state.tile = payload
|
|
},
|
|
RESET_COVER: (state) => {
|
|
state.cover = {
|
|
name: '',
|
|
url: '',
|
|
file: null,
|
|
}
|
|
},
|
|
UPDATE_COVER: (state, payload) => {
|
|
state.cover = payload
|
|
},
|
|
SELECT_FILTERS: (state, payload) => {
|
|
state.filtersSelected = payload
|
|
state.coursesTableOptions.page = 1
|
|
},
|
|
REMOVE_SELECTED_FILTER: (state, payload) => {
|
|
state.filtersSelected = state.filtersSelected.filter(
|
|
(item) => item !== payload
|
|
)
|
|
state.coursesTableOptions.page = 1
|
|
},
|
|
|
|
SET_CHECKLIST: (state, checklists) => {
|
|
// Workaround because Vuex doesn't recognize changes otherwise
|
|
let tmp = [...checklists]
|
|
state.checklists = []
|
|
state.checklists = [...tmp]
|
|
},
|
|
|
|
RESET_CHECKLIST_SELECTED: (state) => (state.checklistsSelected = []),
|
|
|
|
SET_CHECKED_CHECKLISTS: (state, payload) => {
|
|
state.checklistsSelected = [...payload]
|
|
},
|
|
|
|
SELECT_CHECKLIST: (state, payload) => {
|
|
state.checklistsSelected = payload
|
|
},
|
|
|
|
SET_SYNONYMS_LIST: (state, payload) => {
|
|
state.synonyms = [...payload]
|
|
},
|
|
|
|
SELECT_SYNONYM: (state, payload) => {
|
|
state.synonymsSelected = payload
|
|
},
|
|
|
|
RESET_SELECTED_SYNONYMS: (state) => {
|
|
state.synonymsSelected = []
|
|
},
|
|
|
|
SET_COURSES_TABLE_OPTIONS: (state, payload) => {
|
|
state.coursesTableOptions = {}
|
|
state.coursesTableOptions = payload
|
|
},
|
|
}
|