feat: port label store to pinia | pinia 1/9 (#2391)

Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/2391
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
This commit is contained in:
Dominik Pschenitschni 2022-09-21 14:23:57 +00:00 committed by konrad
parent e91b5fde02
commit d67e5e386d
17 changed files with 276 additions and 235 deletions

View file

@ -1,4 +1,5 @@
import type { ActionContext } from 'vuex'
import type { StoreDefinition } from 'pinia'
import {LOADING, LOADING_MODULE} from './mutation-types'
import type { RootStoreState } from './types'
@ -31,4 +32,22 @@ export function setLoading<State>(
loadFunc(false)
}
}
}
export const setLoadingPinia = (store: StoreDefinition, loadFunc : ((isLoading: boolean) => void) | null = null) => {
const timeout = setTimeout(() => {
if (loadFunc === null) {
store.isLoading = true
} else {
loadFunc(true)
}
}, 100)
return () => {
clearTimeout(timeout)
if (loadFunc === null) {
store.isLoading = false
} else {
loadFunc(false)
}
}
}

View file

@ -20,7 +20,6 @@ import kanban from './modules/kanban'
import tasks from './modules/tasks'
import lists from './modules/lists'
import attachments from './modules/attachments'
import labels from './modules/labels'
import ListModel from '@/models/list'
@ -46,7 +45,6 @@ export const store = createStore<RootStoreState>({
tasks,
lists,
attachments,
labels,
},
state: () => ({
loading: false,

View file

@ -1,121 +0,0 @@
import type { Module } from 'vuex'
import {i18n} from '@/i18n'
import {success} from '@/message'
import LabelService from '@/services/label'
import {setLoading} from '@/store/helper'
import type { LabelState, RootStoreState } from '@/store/types'
import {getLabelsByIds, filterLabelsByQuery} from '@/helpers/labels'
import {createNewIndexer} from '@/indexes'
import type { ILabel } from '@/modelTypes/ILabel'
const {add, remove, update} = createNewIndexer('labels', ['title', 'description'])
async function getAllLabels(page = 1): Promise<ILabel[]> {
const labelService = new LabelService()
const labels = await labelService.getAll({}, {}, page) as ILabel[]
if (page < labelService.totalPages) {
const nextLabels = await getAllLabels(page + 1)
return labels.concat(nextLabels)
} else {
return labels
}
}
const LabelStore : Module<LabelState, RootStoreState> = {
namespaced: true,
state: () => ({
labels: {},
loaded: false,
}),
mutations: {
setLabels(state, labels: ILabel[]) {
labels.forEach(l => {
state.labels[l.id] = l
add(l)
})
},
setLabel(state, label: ILabel) {
state.labels[label.id] = label
update(label)
},
removeLabelById(state, label: ILabel) {
remove(label)
delete state.labels[label.id]
},
setLoaded(state, loaded: boolean) {
state.loaded = loaded
},
},
getters: {
getLabelsByIds(state) {
return (ids: ILabel['id'][]) => getLabelsByIds(state, ids)
},
filterLabelsByQuery(state) {
return (labelsToHide: ILabel[], query: string) => filterLabelsByQuery(state, labelsToHide, query)
},
getLabelsByExactTitles(state) {
return labelTitles => Object
.values(state.labels)
.filter(({title}) => labelTitles.some(l => l.toLowerCase() === title.toLowerCase()))
},
},
actions: {
async loadAllLabels(ctx, {forceLoad} = {}) {
if (ctx.state.loaded && !forceLoad) {
return
}
const cancel = setLoading(ctx, 'labels')
try {
const labels = await getAllLabels()
ctx.commit('setLabels', labels)
ctx.commit('setLoaded', true)
return labels
} finally {
cancel()
}
},
async deleteLabel(ctx, label: ILabel) {
const cancel = setLoading(ctx, 'labels')
const labelService = new LabelService()
try {
const result = await labelService.delete(label)
ctx.commit('removeLabelById', label)
success({message: i18n.global.t('label.deleteSuccess')})
return result
} finally {
cancel()
}
},
async updateLabel(ctx, label: ILabel) {
const cancel = setLoading(ctx, 'labels')
const labelService = new LabelService()
try {
const newLabel = await labelService.update(label)
ctx.commit('setLabel', newLabel)
success({message: i18n.global.t('label.edit.success')})
return newLabel
} finally {
cancel()
}
},
async createLabel(ctx, label: ILabel) {
const cancel = setLoading(ctx, 'labels')
const labelService = new LabelService()
try {
const newLabel = await labelService.create(label)
ctx.commit('setLabel', newLabel)
return newLabel
} finally {
cancel()
}
},
},
}
export default LabelStore

View file

@ -25,6 +25,7 @@ import type { IAttachment } from '@/modelTypes/IAttachment'
import type { IList } from '@/modelTypes/IList'
import type { RootStoreState, TaskState } from '@/store/types'
import { useLabelStore } from '@/stores/labels'
// IDEA: maybe use a small fuzzy search here to prevent errors
function findPropertyByValue(object, key, value) {
@ -268,22 +269,19 @@ const tasksStore : Module<TaskState, RootStoreState>= {
},
// Do everything that is involved in finding, creating and adding the label to the task
async addLabelsToTask({rootState, dispatch}, {
task,
parsedLabels,
}) {
async addLabelsToTask(_, { task, parsedLabels }) {
if (parsedLabels.length <= 0) {
return task
}
const {labels} = rootState.labels
const labelStore = useLabelStore()
const labelAddsToWaitFor = parsedLabels.map(async labelTitle => {
let label = validateLabel(labels, labelTitle)
let label = validateLabel(labelStore.labels, labelTitle)
if (typeof label === 'undefined') {
// label not found, create it
const labelModel = new LabelModel({title: labelTitle})
label = await dispatch('labels/createLabel', labelModel, {root: true})
label = await labelStore.createLabel(labelModel)
}
return addLabelToTask(task, label)

View file

@ -93,7 +93,7 @@ export interface LabelState {
labels: {
[id: ILabel['id']]: ILabel
},
loaded: boolean,
isLoading: boolean,
}
export interface ListState {