1
0

feat: lists store with composition api (#2606)

Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/2606
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-10-31 20:41:23 +00:00 committed by konrad
parent 0832184222
commit 5ae8bace82

View File

@ -1,4 +1,4 @@
import {watch, reactive, shallowReactive, unref, toRefs, readonly} from 'vue' import {watch, reactive, shallowReactive, unref, toRefs, readonly, ref, computed} from 'vue'
import {acceptHMRUpdate, defineStore} from 'pinia' import {acceptHMRUpdate, defineStore} from 'pinia'
import {useI18n} from 'vue-i18n' import {useI18n} from 'vue-i18n'
@ -21,105 +21,101 @@ const {add, remove, search, update} = createNewIndexer('lists', ['title', 'descr
const FavoriteListsNamespace = -2 const FavoriteListsNamespace = -2
export interface ListState { export interface ListState {
lists: { [id: IList['id']]: IList }, [id: IList['id']]: IList
isLoading: boolean,
} }
export const useListStore = defineStore('list', { export const useListStore = defineStore('list', () => {
state: () : ListState => ({ const baseStore = useBaseStore()
isLoading: false, const namespaceStore = useNamespaceStore()
const isLoading = ref(false)
// The lists are stored as an object which has the list ids as keys. // The lists are stored as an object which has the list ids as keys.
lists: {}, const lists = ref<ListState>({})
}),
getters: {
getListById(state) {
return (id: IList['id']) => typeof state.lists[id] !== 'undefined' ? state.lists[id] : null
},
findListByExactname(state) { const getListById = computed(() => {
return (id: IList['id']) => typeof lists.value[id] !== 'undefined' ? lists.value[id] : null
})
const findListByExactname = computed(() => {
return (name: string) => { return (name: string) => {
const list = Object.values(state.lists).find(l => { const list = Object.values(lists.value).find(l => {
return l.title.toLowerCase() === name.toLowerCase() return l.title.toLowerCase() === name.toLowerCase()
}) })
return typeof list === 'undefined' ? null : list return typeof list === 'undefined' ? null : list
} }
}, })
searchList(state) { const searchList = computed(() => {
return (query: string, includeArchived = false) => { return (query: string, includeArchived = false) => {
return search(query) return search(query)
?.filter(value => value > 0) ?.filter(value => value > 0)
.map(id => state.lists[id]) .map(id => lists.value[id])
.filter(list => list.isArchived === includeArchived) .filter(list => list.isArchived === includeArchived)
|| [] || []
} }
}, })
},
actions: { function setIsLoading(newIsLoading: boolean) {
setIsLoading(isLoading: boolean) { isLoading.value = newIsLoading
this.isLoading = isLoading }
},
setList(list: IList) { function setList(list: IList) {
this.lists[list.id] = list lists.value[list.id] = list
update(list) update(list)
const baseStore = useBaseStore()
if (baseStore.currentList?.id === list.id) { if (baseStore.currentList?.id === list.id) {
baseStore.setCurrentList(list) baseStore.setCurrentList(list)
} }
}, }
setLists(lists: IList[]) { function setLists(newLists: IList[]) {
lists.forEach(l => { newLists.forEach(l => {
this.lists[l.id] = l lists.value[l.id] = l
add(l) add(l)
}) })
}, }
removeListById(list: IList) { function removeListById(list: IList) {
remove(list) remove(list)
delete this.lists[list.id] delete lists.value[list.id]
}, }
toggleListFavorite(list: IList) { function toggleListFavorite(list: IList) {
// The favorites pseudo list is always favorite // The favorites pseudo list is always favorite
// Archived lists cannot be marked favorite // Archived lists cannot be marked favorite
if (list.id === -1 || list.isArchived) { if (list.id === -1 || list.isArchived) {
return return
} }
return this.updateList({ return updateList({
...list, ...list,
isFavorite: !list.isFavorite, isFavorite: !list.isFavorite,
}) })
}, }
async createList(list: IList) { async function createList(list: IList) {
const cancel = setModuleLoading(this) const cancel = setModuleLoading(this, setIsLoading)
const listService = new ListService() const listService = new ListService()
try { try {
const createdList = await listService.create(list) const createdList = await listService.create(list)
createdList.namespaceId = list.namespaceId createdList.namespaceId = list.namespaceId
const namespaceStore = useNamespaceStore()
namespaceStore.addListToNamespace(createdList) namespaceStore.addListToNamespace(createdList)
this.setList(createdList) setList(createdList)
return createdList return createdList
} finally { } finally {
cancel() cancel()
} }
}, }
async updateList(list: IList) { async function updateList(list: IList) {
const cancel = setModuleLoading(this) const cancel = setModuleLoading(this, setIsLoading)
const listService = new ListService() const listService = new ListService()
try { try {
await listService.update(list) await listService.update(list)
this.setList(list) setList(list)
const namespaceStore = useNamespaceStore()
namespaceStore.setListInNamespaceById(list) namespaceStore.setListInNamespaceById(list)
// the returned list from listService.update is the same! // the returned list from listService.update is the same!
@ -133,12 +129,12 @@ export const useListStore = defineStore('list', {
} else { } else {
namespaceStore.removeListFromNamespaceById(newList) namespaceStore.removeListFromNamespaceById(newList)
} }
namespaceStore.loadNamespacesIfFavoritesDontExist(null) namespaceStore.loadNamespacesIfFavoritesDontExist()
namespaceStore.removeFavoritesNamespaceIfEmpty(null) namespaceStore.removeFavoritesNamespaceIfEmpty()
return newList return newList
} catch (e) { } catch (e) {
// Reset the list state to the initial one to avoid confusion for the user // Reset the list state to the initial one to avoid confusion for the user
this.setList({ setList({
...list, ...list,
isFavorite: !list.isFavorite, isFavorite: !list.isFavorite,
}) })
@ -146,24 +142,39 @@ export const useListStore = defineStore('list', {
} finally { } finally {
cancel() cancel()
} }
}, }
async deleteList(list: IList) { async function deleteList(list: IList) {
const cancel = setModuleLoading(this) const cancel = setModuleLoading(this, setIsLoading)
const listService = new ListService() const listService = new ListService()
try { try {
const response = await listService.delete(list) const response = await listService.delete(list)
this.removeListById(list) removeListById(list)
const namespaceStore = useNamespaceStore()
namespaceStore.removeListFromNamespaceById(list) namespaceStore.removeListFromNamespaceById(list)
removeListFromHistory({id: list.id}) removeListFromHistory({id: list.id})
return response return response
} finally { } finally {
cancel() cancel()
} }
}, }
},
return {
isLoading: readonly(isLoading),
lists: readonly(lists),
getListById,
findListByExactname,
searchList,
setList,
setLists,
removeListById,
toggleListFavorite,
createList,
updateList,
deleteList,
}
}) })
export function useList(listId: MaybeRef<IList['id']>) { export function useList(listId: MaybeRef<IList['id']>) {