feat: migrate kanban store to pina (#2411)

Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/2411
This commit is contained in:
konrad 2022-10-01 12:15:22 +00:00
commit d1d7cd535e
7 changed files with 277 additions and 261 deletions

View file

@ -13,7 +13,6 @@ import {
MENU_ACTIVE,
QUICK_ACTIONS_ACTIVE,
} from './mutation-types'
import kanban from './modules/kanban'
import ListModel from '@/models/list'
@ -33,9 +32,6 @@ export function useStore () {
export const store = createStore<RootStoreState>({
strict: import.meta.env.DEV,
modules: {
kanban,
},
state: () => ({
loading: false,
loadingModule: null,

View file

@ -68,13 +68,16 @@ export interface ConfigState {
export interface KanbanState {
buckets: IBucket[],
listId: IList['id'],
bucketLoading: {},
bucketLoading: {
[id: IBucket['id']]: boolean
},
taskPagesPerBucket: {
[id: IBucket['id']]: number
},
allTasksLoadedForBucket: {
[id: IBucket['id']]: boolean
},
isLoading: boolean,
}
export interface LabelState {

View file

@ -1,14 +1,14 @@
import type { Module } from 'vuex'
import {defineStore, acceptHMRUpdate} from 'pinia'
import cloneDeep from 'lodash.clonedeep'
import {findById, findIndexById} from '@/helpers/utils'
import {i18n} from '@/i18n'
import {success} from '@/message'
import BucketService from '../../services/bucket'
import {setLoading} from '../helper'
import BucketService from '../services/bucket'
import {setLoadingPinia} from '@/store/helper'
import TaskCollectionService from '@/services/taskCollection'
import type { RootStoreState, KanbanState } from '@/store/types'
import type { KanbanState } from '@/store/types'
import type { ITask } from '@/modelTypes/ITask'
import type { IList } from '@/modelTypes/IList'
import type { IBucket } from '@/modelTypes/IBucket'
@ -41,188 +41,16 @@ const addTaskToBucketAndSort = (state: KanbanState, task: ITask) => {
* This store is intended to hold the currently active kanban view.
* It should hold only the current buckets.
*/
const kanbanStore : Module<KanbanState, RootStoreState> = {
namespaced: true,
state: () => ({
export const useKanbanStore = defineStore('kanban', {
state: () : KanbanState => ({
buckets: [],
listId: 0,
bucketLoading: {},
taskPagesPerBucket: {},
allTasksLoadedForBucket: {},
isLoading: false,
}),
mutations: {
setListId(state, listId: IList['id']) {
state.listId = parseInt(listId)
},
setBuckets(state, buckets: IBucket[]) {
state.buckets = buckets
buckets.forEach(b => {
state.taskPagesPerBucket[b.id] = 1
state.allTasksLoadedForBucket[b.id] = false
})
},
addBucket(state, bucket: IBucket) {
state.buckets.push(bucket)
},
removeBucket(state, bucket: IBucket) {
const bucketIndex = findIndexById(state.buckets, bucket.id)
state.buckets.splice(bucketIndex, 1)
},
setBucketById(state, bucket: IBucket) {
const bucketIndex = findIndexById(state.buckets, bucket.id)
state.buckets[bucketIndex] = bucket
},
setBucketByIndex(state, {
bucketIndex,
bucket,
} : {
bucketIndex: number,
bucket: IBucket
}) {
state.buckets[bucketIndex] = bucket
},
setTaskInBucketByIndex(state, {
bucketIndex,
taskIndex,
task,
} : {
bucketIndex: number,
taskIndex: number,
task: ITask
}) {
const bucket = state.buckets[bucketIndex]
bucket.tasks[taskIndex] = task
state.buckets[bucketIndex] = bucket
},
setTasksInBucketByBucketId(state, {
bucketId,
tasks,
} : {
bucketId: IBucket['id'],
tasks: ITask[],
}) {
const bucketIndex = findIndexById(state.buckets, bucketId)
state.buckets[bucketIndex] = {
...state.buckets[bucketIndex],
tasks,
}
},
setTaskInBucket(state, task: ITask) {
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
if (state.buckets.length === 0) {
return
}
let found = false
const findAndUpdate = b => {
for (const t in state.buckets[b].tasks) {
if (state.buckets[b].tasks[t].id === task.id) {
const bucket = state.buckets[b]
bucket.tasks[t] = task
if (bucket.id !== task.bucketId) {
bucket.tasks.splice(t, 1)
addTaskToBucketAndSort(state, task)
}
state.buckets[b] = bucket
found = true
return
}
}
}
for (const b in state.buckets) {
if (state.buckets[b].id === task.bucketId) {
findAndUpdate(b)
if (found) {
return
}
}
}
for (const b in state.buckets) {
findAndUpdate(b)
if (found) {
return
}
}
},
addTaskToBucket(state, task: ITask) {
const bucketIndex = findIndexById(state.buckets, task.bucketId)
const oldBucket = state.buckets[bucketIndex]
const newBucket = {
...oldBucket,
tasks: [
...oldBucket.tasks,
task,
],
}
state.buckets[bucketIndex] = newBucket
},
addTasksToBucket(state, {tasks, bucketId}: {
tasks: ITask[];
bucketId: IBucket['id'];
}) {
const bucketIndex = findIndexById(state.buckets, bucketId)
const oldBucket = state.buckets[bucketIndex]
const newBucket = {
...oldBucket,
tasks: [
...oldBucket.tasks,
...tasks,
],
}
state.buckets[bucketIndex] = newBucket
},
removeTaskInBucket(state, task: ITask) {
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
if (state.buckets.length === 0) {
return
}
const { bucketIndex, taskIndex } = getTaskIndicesById(state, task.id)
if (
!bucketIndex ||
state.buckets[bucketIndex]?.id !== task.bucketId ||
!taskIndex ||
(state.buckets[bucketIndex]?.tasks[taskIndex]?.id !== task.id)
) {
return
}
state.buckets[bucketIndex].tasks.splice(taskIndex, 1)
},
setBucketLoading(state, {bucketId, loading}) {
state.bucketLoading[bucketId] = loading
},
setTasksLoadedForBucketPage(state: KanbanState, {bucketId, page}) {
state.taskPagesPerBucket[bucketId] = page
},
setAllTasksLoadedForBucket(state: KanbanState, bucketId) {
state.allTasksLoadedForBucket[bucketId] = true
},
},
getters: {
getBucketById(state) {
return (bucketId: IBucket['id']) => findById(state.buckets, bucketId)
@ -243,40 +71,216 @@ const kanbanStore : Module<KanbanState, RootStoreState> = {
},
actions: {
async loadBucketsForList(ctx, {listId, params}) {
const cancel = setLoading(ctx, 'kanban')
setIsLoading(isLoading: boolean) {
this.isLoading = isLoading
},
setListId(listId: IList['id']) {
this.listId = Number(listId)
},
setBuckets(buckets: IBucket[]) {
this.buckets = buckets
buckets.forEach(b => {
this.taskPagesPerBucket[b.id] = 1
this.allTasksLoadedForBucket[b.id] = false
})
},
addBucket(bucket: IBucket) {
this.buckets.push(bucket)
},
removeBucket(bucket: IBucket) {
const bucketIndex = findIndexById(this.buckets, bucket.id)
this.buckets.splice(bucketIndex, 1)
},
setBucketById(bucket: IBucket) {
const bucketIndex = findIndexById(this.buckets, bucket.id)
this.buckets[bucketIndex] = bucket
},
setBucketByIndex({
bucketIndex,
bucket,
} : {
bucketIndex: number,
bucket: IBucket
}) {
this.buckets[bucketIndex] = bucket
},
setTaskInBucketByIndex({
bucketIndex,
taskIndex,
task,
} : {
bucketIndex: number,
taskIndex: number,
task: ITask
}) {
const bucket = this.buckets[bucketIndex]
bucket.tasks[taskIndex] = task
this.buckets[bucketIndex] = bucket
},
setTasksInBucketByBucketId({
bucketId,
tasks,
} : {
bucketId: IBucket['id'],
tasks: ITask[],
}) {
const bucketIndex = findIndexById(this.buckets, bucketId)
this.buckets[bucketIndex] = {
...this.buckets[bucketIndex],
tasks,
}
},
setTaskInBucket(task: ITask) {
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
if (this.buckets.length === 0) {
return
}
let found = false
const findAndUpdate = b => {
for (const t in this.buckets[b].tasks) {
if (this.buckets[b].tasks[t].id === task.id) {
const bucket = this.buckets[b]
bucket.tasks[t] = task
if (bucket.id !== task.bucketId) {
bucket.tasks.splice(t, 1)
addTaskToBucketAndSort(this, task)
}
this.buckets[b] = bucket
found = true
return
}
}
}
for (const b in this.buckets) {
if (this.buckets[b].id === task.bucketId) {
findAndUpdate(b)
if (found) {
return
}
}
}
for (const b in this.buckets) {
findAndUpdate(b)
if (found) {
return
}
}
},
addTaskToBucket(task: ITask) {
const bucketIndex = findIndexById(this.buckets, task.bucketId)
const oldBucket = this.buckets[bucketIndex]
const newBucket = {
...oldBucket,
tasks: [
...oldBucket.tasks,
task,
],
}
this.buckets[bucketIndex] = newBucket
},
addTasksToBucket({tasks, bucketId}: {
tasks: ITask[];
bucketId: IBucket['id'];
}) {
const bucketIndex = findIndexById(this.buckets, bucketId)
const oldBucket = this.buckets[bucketIndex]
const newBucket = {
...oldBucket,
tasks: [
...oldBucket.tasks,
...tasks,
],
}
this.buckets[bucketIndex] = newBucket
},
removeTaskInBucket(task: ITask) {
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
if (this.buckets.length === 0) {
return
}
const { bucketIndex, taskIndex } = getTaskIndicesById(this, task.id)
if (
!bucketIndex ||
this.buckets[bucketIndex]?.id !== task.bucketId ||
!taskIndex ||
(this.buckets[bucketIndex]?.tasks[taskIndex]?.id !== task.id)
) {
return
}
this.buckets[bucketIndex].tasks.splice(taskIndex, 1)
},
setBucketLoading({bucketId, loading}: {bucketId: IBucket['id'], loading: boolean}) {
this.bucketLoading[bucketId] = loading
},
setTasksLoadedForBucketPage({bucketId, page}: {bucketId: IBucket['id'], page: number}) {
this.taskPagesPerBucket[bucketId] = page
},
setAllTasksLoadedForBucket(bucketId: IBucket['id']) {
this.allTasksLoadedForBucket[bucketId] = true
},
async loadBucketsForList({listId, params}: {listId: IList['id'], params}) {
const cancel = setLoadingPinia(this)
// Clear everything to prevent having old buckets in the list if loading the buckets from this list takes a few moments
ctx.commit('setBuckets', [])
this.setBuckets([])
params.per_page = TASKS_PER_BUCKET
const bucketService = new BucketService()
try {
const response = await bucketService.getAll({listId}, params)
ctx.commit('setBuckets', response)
ctx.commit('setListId', listId)
return response
const buckets = await bucketService.getAll({listId}, params)
this.setBuckets(buckets)
this.setListId(listId)
return buckets
} finally {
cancel()
}
},
async loadNextTasksForBucket(ctx, {listId, ps = {}, bucketId}) {
const isLoading = ctx.state.bucketLoading[bucketId] ?? false
async loadNextTasksForBucket(
{listId, ps = {}, bucketId} :
{listId: IList['id'], ps, bucketId: IBucket['id']},
) {
const isLoading = this.bucketLoading[bucketId] ?? false
if (isLoading) {
return
}
const page = (ctx.state.taskPagesPerBucket[bucketId] ?? 1) + 1
const page = (this.taskPagesPerBucket[bucketId] ?? 1) + 1
const alreadyLoaded = ctx.state.allTasksLoadedForBucket[bucketId] ?? false
const alreadyLoaded = this.allTasksLoadedForBucket[bucketId] ?? false
if (alreadyLoaded) {
return
}
const cancel = setLoading(ctx, 'kanban')
ctx.commit('setBucketLoading', {bucketId: bucketId, loading: true})
const cancel = setLoadingPinia(this)
this.setBucketLoading({bucketId: bucketId, loading: true})
const params = JSON.parse(JSON.stringify(ps))
@ -305,67 +309,67 @@ const kanbanStore : Module<KanbanState, RootStoreState> = {
const taskService = new TaskCollectionService()
try {
const tasks = await taskService.getAll({listId}, params, page)
ctx.commit('addTasksToBucket', {tasks, bucketId: bucketId})
ctx.commit('setTasksLoadedForBucketPage', {bucketId, page})
this.addTasksToBucket({tasks, bucketId: bucketId})
this.setTasksLoadedForBucketPage({bucketId, page})
if (taskService.totalPages <= page) {
ctx.commit('setAllTasksLoadedForBucket', bucketId)
this.setAllTasksLoadedForBucket(bucketId)
}
return tasks
} finally {
cancel()
ctx.commit('setBucketLoading', {bucketId, loading: false})
this.setBucketLoading({bucketId, loading: false})
}
},
async createBucket(ctx, bucket: IBucket) {
const cancel = setLoading(ctx, 'kanban')
async createBucket(bucket: IBucket) {
const cancel = setLoadingPinia(this)
const bucketService = new BucketService()
try {
const createdBucket = await bucketService.create(bucket)
ctx.commit('addBucket', createdBucket)
this.addBucket(createdBucket)
return createdBucket
} finally {
cancel()
}
},
async deleteBucket(ctx, {bucket, params}) {
const cancel = setLoading(ctx, 'kanban')
async deleteBucket({bucket, params}: {bucket: IBucket, params}) {
const cancel = setLoadingPinia(this)
const bucketService = new BucketService()
try {
const response = await bucketService.delete(bucket)
ctx.commit('removeBucket', bucket)
this.removeBucket(bucket)
// We reload all buckets because tasks are being moved from the deleted bucket
ctx.dispatch('loadBucketsForList', {listId: bucket.listId, params})
this.loadBucketsForList({listId: bucket.listId, params})
return response
} finally {
cancel()
}
},
async updateBucket(ctx, updatedBucketData) {
const cancel = setLoading(ctx, 'kanban')
async updateBucket(updatedBucketData: IBucket) {
const cancel = setLoadingPinia(this)
const bucketIndex = findIndexById(ctx.state.buckets, updatedBucketData.id)
const oldBucket = cloneDeep(ctx.state.buckets[bucketIndex])
const bucketIndex = findIndexById(this.buckets, updatedBucketData.id)
const oldBucket = cloneDeep(this.buckets[bucketIndex])
const updatedBucket = {
...oldBucket,
...updatedBucketData,
}
ctx.commit('setBucketByIndex', {bucketIndex, bucket: updatedBucket})
this.setBucketByIndex({bucketIndex, bucket: updatedBucket})
const bucketService = new BucketService()
try {
const returnedBucket = await bucketService.update(updatedBucket)
ctx.commit('setBucketByIndex', {bucketIndex, bucket: returnedBucket})
this.setBucketByIndex({bucketIndex, bucket: returnedBucket})
return returnedBucket
} catch(e) {
// restore original state
ctx.commit('setBucketByIndex', {bucketIndex, bucket: oldBucket})
this.setBucketByIndex({bucketIndex, bucket: oldBucket})
throw e
} finally {
@ -373,23 +377,21 @@ const kanbanStore : Module<KanbanState, RootStoreState> = {
}
},
async updateBucketTitle(ctx, { id, title }) {
const bucket = findById(ctx.state.buckets, id)
async updateBucketTitle({ id, title }: { id: IBucket['id'], title: IBucket['title'] }) {
const bucket = findById(this.buckets, id)
if (bucket?.title === title) {
// bucket title has not changed
return
}
const updatedBucketData = {
id,
title,
}
await ctx.dispatch('updateBucket', updatedBucketData)
await this.updateBucket({ id, title })
success({message: i18n.global.t('list.kanban.bucketTitleSavedSuccess')})
},
},
}
})
export default kanbanStore
// support hot reloading
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useKanbanStore, import.meta.hot))
}

View file

@ -28,6 +28,7 @@ import type {TaskState} from '@/store/types'
import {useLabelStore} from '@/stores/labels'
import {useListStore} from '@/stores/lists'
import {useAttachmentStore} from '@/stores/attachments'
import {useKanbanStore} from '@/stores/kanban'
import {playPop} from '@/helpers/playPop'
import {store} from '@/store'
@ -101,7 +102,7 @@ export const useTaskStore = defineStore('task', {
const taskService = new TaskService()
try {
const updatedTask = await taskService.update(task)
store.commit('kanban/setTaskInBucket', updatedTask)
useKanbanStore().setTaskInBucket(updatedTask)
if (task.done) {
playPop()
}
@ -114,7 +115,7 @@ export const useTaskStore = defineStore('task', {
async delete(task: ITask) {
const taskService = new TaskService()
const response = await taskService.delete(task)
store.commit('kanban/removeTaskInBucket', task)
useKanbanStore().removeTaskInBucket(task)
return response
},
@ -127,7 +128,8 @@ export const useTaskStore = defineStore('task', {
taskId: ITask['id']
attachment: IAttachment
}) {
const t = store.getters['kanban/getTaskById'](taskId)
const kanbanStore = useKanbanStore()
const t = kanbanStore.getTaskById(taskId)
if (t.task !== null) {
const attachments = [
...t.task.attachments,
@ -141,7 +143,7 @@ export const useTaskStore = defineStore('task', {
attachments,
},
}
store.commit('kanban/setTaskInBucketByIndex', newTask)
kanbanStore.setTaskInBucketByIndex(newTask)
}
const attachmentStore = useAttachmentStore()
attachmentStore.add(attachment)
@ -154,12 +156,13 @@ export const useTaskStore = defineStore('task', {
user: IUser,
taskId: ITask['id']
}) {
const kanbanStore = useKanbanStore()
const taskAssigneeService = new TaskAssigneeService()
const r = await taskAssigneeService.create(new TaskAssigneeModel({
userId: user.id,
taskId: taskId,
}))
const t = store.getters['kanban/getTaskById'](taskId)
const t = kanbanStore.getTaskById(taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
@ -168,7 +171,7 @@ export const useTaskStore = defineStore('task', {
return r
}
store.commit('kanban/setTaskInBucketByIndex', {
kanbanStore.setTaskInBucketByIndex({
...t,
task: {
...t.task,
@ -188,12 +191,13 @@ export const useTaskStore = defineStore('task', {
user: IUser,
taskId: ITask['id']
}) {
const kanbanStore = useKanbanStore()
const taskAssigneeService = new TaskAssigneeService()
const response = await taskAssigneeService.delete(new TaskAssigneeModel({
userId: user.id,
taskId: taskId,
}))
const t = store.getters['kanban/getTaskById'](taskId)
const t = kanbanStore.getTaskById(taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
@ -204,7 +208,7 @@ export const useTaskStore = defineStore('task', {
const assignees = t.task.assignees.filter(({ id }) => id !== user.id)
store.commit('kanban/setTaskInBucketByIndex', {
kanbanStore.setTaskInBucketByIndex({
...t,
task: {
...t.task,
@ -222,12 +226,13 @@ export const useTaskStore = defineStore('task', {
label: ILabel,
taskId: ITask['id']
}) {
const kanbanStore = useKanbanStore()
const labelTaskService = new LabelTaskService()
const r = await labelTaskService.create(new LabelTaskModel({
taskId,
labelId: label.id,
}))
const t = store.getters['kanban/getTaskById'](taskId)
const t = kanbanStore.getTaskById(taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
@ -236,7 +241,7 @@ export const useTaskStore = defineStore('task', {
return r
}
store.commit('kanban/setTaskInBucketByIndex', {
kanbanStore.setTaskInBucketByIndex({
...t,
task: {
...t.task,
@ -254,12 +259,13 @@ export const useTaskStore = defineStore('task', {
{label, taskId}:
{label: ILabel, taskId: ITask['id']},
) {
const kanbanStore = useKanbanStore()
const labelTaskService = new LabelTaskService()
const response = await labelTaskService.delete(new LabelTaskModel({
taskId, labelId:
label.id,
}))
const t = store.getters['kanban/getTaskById'](taskId)
const t = kanbanStore.getTaskById(taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
@ -271,7 +277,7 @@ export const useTaskStore = defineStore('task', {
// Remove the label from the list
const labels = t.task.labels.filter(({ id }) => id !== label.id)
store.commit('kanban/setTaskInBucketByIndex', {
kanbanStore.setTaskInBucketByIndex({
...t,
task: {
...t.task,

View file

@ -229,9 +229,9 @@ import draggable from 'zhyswan-vuedraggable'
import cloneDeep from 'lodash.clonedeep'
import BucketModel from '../../models/bucket'
import {mapState} from 'vuex'
import {mapState as mapStateVuex} from 'vuex'
import {mapState} from 'pinia'
import {RIGHTS as Rights} from '@/constants/rights'
import {LOADING, LOADING_MODULE} from '@/store/mutation-types'
import ListWrapper from './ListWrapper.vue'
import FilterPopup from '@/components/list/partials/filter-popup.vue'
import Dropdown from '@/components/misc/dropdown.vue'
@ -241,6 +241,7 @@ import KanbanCard from '@/components/tasks/partials/kanban-card.vue'
import DropdownItem from '@/components/misc/dropdown-item.vue'
import {isSavedFilter} from '@/helpers/savedFilter'
import {useTaskStore} from '@/stores/tasks'
import {useKanbanStore} from '@/stores/kanban'
const DRAG_OPTIONS = {
// sortable options
@ -342,16 +343,18 @@ export default defineComponent({
],
}
},
buckets() {
return this.$store.state.kanban.buckets
},
...mapState({
loadedListId: state => state.kanban.listId,
loading: state => state[LOADING] && state[LOADING_MODULE] === 'kanban',
taskLoading: state => state[LOADING] && state[LOADING_MODULE] === 'tasks',
...mapStateVuex({
canWrite: state => state.currentList.maxRight > Rights.READ,
list: state => state.currentList,
}),
...mapState(useKanbanStore, {
buckets: state => state.buckets,
loadedListId: state => state.listId,
loading: state => state.isLoading,
}),
...mapState(useTaskStore, {
taskLoading: state => state.isLoading,
}),
},
methods: {
@ -364,7 +367,7 @@ export default defineComponent({
console.debug(`Loading buckets, loadedListId = ${this.loadedListId}, $attrs = ${this.$attrs} $route.params =`, this.$route.params)
this.$store.dispatch('kanban/loadBucketsForList', {listId, params})
useKanbanStore().loadBucketsForList({listId, params})
},
setTaskContainerRef(id, el) {
@ -382,7 +385,7 @@ export default defineComponent({
return
}
this.$store.dispatch('kanban/loadNextTasksForBucket', {
useKanbanStore().loadNextTasksForBucket({
listId: listId,
params: this.params,
bucketId: id,
@ -390,12 +393,13 @@ export default defineComponent({
},
updateTasks(bucketId, tasks) {
const kanbanStore = useKanbanStore()
const newBucket = {
...this.$store.getters['kanban/getBucketById'](bucketId),
...kanbanStore.getBucketById(bucketId),
tasks,
}
this.$store.commit('kanban/setBucketById', newBucket)
kanbanStore.setBucketById(newBucket)
},
async updateTaskPosition(e) {
@ -472,7 +476,7 @@ export default defineComponent({
listId: this.listId,
})
this.newTaskText = ''
this.$store.commit('kanban/addTaskToBucket', task)
useKanbanStore().addTaskToBucket(task)
this.scrollTaskContainerToBottom(bucketId)
},
@ -494,7 +498,7 @@ export default defineComponent({
listId: this.listId,
})
await this.$store.dispatch('kanban/createBucket', newBucket)
await useKanbanStore().createBucket(newBucket)
this.newBucketTitle = ''
this.showNewBucketInput = false
},
@ -515,7 +519,7 @@ export default defineComponent({
})
try {
await this.$store.dispatch('kanban/deleteBucket', {
await useKanbanStore().deleteBucket({
bucket,
params: this.params,
})
@ -537,13 +541,13 @@ export default defineComponent({
title: bucketTitle,
}
await this.$store.dispatch('kanban/updateBucketTitle', updatedBucketData)
await useKanbanStore().updateBucketTitle(updatedBucketData)
this.bucketTitleEditable = false
},
updateBuckets(value) {
// (1) buckets get updated in store and tasks positions get invalidated
this.$store.commit('kanban/setBuckets', value)
useKanbanStore().setBuckets(value)
},
updateBucketPosition(e) {
@ -562,7 +566,7 @@ export default defineComponent({
),
}
this.$store.dispatch('kanban/updateBucket', updatedData)
useKanbanStore().updateBucket(updatedData)
},
async setBucketLimit(bucketId, limit) {
@ -570,12 +574,14 @@ export default defineComponent({
return
}
const kanbanStore = useKanbanStore()
const newBucket = {
...this.$store.getters['kanban/getBucketById'](bucketId),
...kanbanStore.getBucketById(bucketId),
limit,
}
await this.$store.dispatch('kanban/updateBucket', newBucket)
await kanbanStore.updateBucket(newBucket)
this.$message.success({message: this.$t('list.kanban.bucketLimitSavedSuccess')})
},
@ -600,7 +606,7 @@ export default defineComponent({
...bucket,
isDoneBucket: !bucket.isDoneBucket,
}
await this.$store.dispatch('kanban/updateBucket', newBucket)
await useKanbanStore().updateBucket(newBucket)
this.$message.success({message: this.$t('list.kanban.doneBucketSavedSuccess')})
},

View file

@ -62,6 +62,7 @@ import {saveListToHistory} from '@/modules/listHistory'
import {useTitle} from '@/composables/useTitle'
import {useStore} from '@/store'
import {useListStore} from '@/stores/lists'
import {useKanbanStore} from '@/stores/kanban'
const props = defineProps({
listId: {
@ -77,6 +78,7 @@ const props = defineProps({
const route = useRoute()
const store = useStore()
const kanbanStore = useKanbanStore()
const listStore = useListStore()
const listService = ref(new ListService())
const loadedListId = ref(0)
@ -116,7 +118,7 @@ async function loadList(listIdToLoad: number) {
props.viewName === 'list.list' ||
props.viewName === 'list.gantt'
) {
store.commit('kanban/setListId', 0)
kanbanStore.setListId(0)
}
// Don't load the list if we either already loaded it or aren't dealing with a list at all currently and

View file

@ -465,6 +465,7 @@ import {colorIsDark} from '@/helpers/color/colorIsDark'
import {useNamespaceStore} from '@/stores/namespaces'
import {useAttachmentStore} from '@/stores/attachments'
import {useTaskStore} from '@/stores/tasks'
import {useKanbanStore} from '@/stores/kanban'
function scrollIntoView(el) {
if (!el) {
@ -748,7 +749,7 @@ export default defineComponent({
},
async changeList(list: IList) {
this.$store.commit('kanban/removeTaskInBucket', this.task)
useKanbanStore().removeTaskInBucket(this.task)
await this.saveTask({
task: {
...this.task,