Files
nuxt-frontend/store/learning.js
Joris Slagter 791aebc346
Some checks failed
continuous-integration/drone/push Build is failing
Initial Nuxt frontend import
- 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
2025-12-02 17:48:48 +01:00

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
},
}