feat: always use index for buckets
This commit is contained in:
parent
672d63fbed
commit
8d88b3792d
4 changed files with 94 additions and 54 deletions
|
@ -1,10 +0,0 @@
|
||||||
export const filterObject = (obj, fn) => {
|
|
||||||
let key
|
|
||||||
|
|
||||||
for (key in obj) {
|
|
||||||
if (fn(obj[key])) {
|
|
||||||
return key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
|
@ -1,3 +1,7 @@
|
||||||
export function findIndexById(array : [], id : string | number) {
|
export function findIndexById(array : [], id : string | number) {
|
||||||
return array.findIndex(({id: currentId}) => currentId === id)
|
return array.findIndex(({id: currentId}) => currentId === id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function findById(array : [], id : string | number) {
|
||||||
|
return array.find(({id: currentId}) => currentId === id)
|
||||||
|
}
|
|
@ -1,16 +1,36 @@
|
||||||
import cloneDeep from 'lodash/cloneDeep'
|
import cloneDeep from 'lodash/cloneDeep'
|
||||||
|
|
||||||
|
import {findById, findIndexById} from '@/helpers/find'
|
||||||
import BucketService from '../../services/bucket'
|
import BucketService from '../../services/bucket'
|
||||||
import {filterObject} from '@/helpers/filterObject'
|
|
||||||
import {setLoading} from '../helper'
|
import {setLoading} from '../helper'
|
||||||
import TaskCollectionService from '@/services/taskCollection'
|
import TaskCollectionService from '@/services/taskCollection'
|
||||||
|
|
||||||
const TASKS_PER_BUCKET = 25
|
const TASKS_PER_BUCKET = 25
|
||||||
|
|
||||||
|
function getTaskPosition(state, task) {
|
||||||
|
const bucketIndex = findIndexById(state.buckets, task.bucketId)
|
||||||
|
|
||||||
|
if (!bucketIndex) {
|
||||||
|
throw('Bucket not found')
|
||||||
|
}
|
||||||
|
|
||||||
|
const bucket = state.buckets[bucketIndex]
|
||||||
|
const taskIndex = findIndexById(bucket.tasks, task.id)
|
||||||
|
|
||||||
|
if (!bucketIndex) {
|
||||||
|
throw('Task not found')
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
bucketIndex,
|
||||||
|
taskIndex,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const addTaskToBucketAndSort = (state, task) => {
|
const addTaskToBucketAndSort = (state, task) => {
|
||||||
const bi = filterObject(state.buckets, b => b.id === task.bucketId)
|
const bucketIndex = findIndexById(state.buckets, task.bucketId)
|
||||||
state.buckets[bi].tasks.push(task)
|
state.buckets[bucketIndex].tasks.push(task)
|
||||||
state.buckets[bi].tasks.sort((a, b) => a.kanbanPosition > b.kanbanPosition ? 1 : -1)
|
state.buckets[bucketIndex].tasks.sort((a, b) => a.kanbanPosition > b.kanbanPosition ? 1 : -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,6 +39,7 @@ const addTaskToBucketAndSort = (state, task) => {
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
|
|
||||||
state: () => ({
|
state: () => ({
|
||||||
buckets: [],
|
buckets: [],
|
||||||
listId: 0,
|
listId: 0,
|
||||||
|
@ -26,10 +47,12 @@ export default {
|
||||||
taskPagesPerBucket: {},
|
taskPagesPerBucket: {},
|
||||||
allTasksLoadedForBucket: {},
|
allTasksLoadedForBucket: {},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
mutations: {
|
mutations: {
|
||||||
setListId(state, listId) {
|
setListId(state, listId) {
|
||||||
state.listId = parseInt(listId)
|
state.listId = parseInt(listId)
|
||||||
},
|
},
|
||||||
|
|
||||||
setBuckets(state, buckets) {
|
setBuckets(state, buckets) {
|
||||||
state.buckets = buckets
|
state.buckets = buckets
|
||||||
buckets.forEach(b => {
|
buckets.forEach(b => {
|
||||||
|
@ -37,32 +60,39 @@ export default {
|
||||||
state.allTasksLoadedForBucket[b.id] = false
|
state.allTasksLoadedForBucket[b.id] = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
addBucket(state, bucket) {
|
addBucket(state, bucket) {
|
||||||
state.buckets.push(bucket)
|
state.buckets.push(bucket)
|
||||||
},
|
},
|
||||||
|
|
||||||
removeBucket(state, bucket) {
|
removeBucket(state, bucket) {
|
||||||
for (const b in state.buckets) {
|
const bucketIndex = findIndexById(state.buckets, bucket.id)
|
||||||
if (state.buckets[b].id === bucket.id) {
|
state.buckets.splice(bucketIndex, 1)
|
||||||
state.buckets.splice(b, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setBucketById(state, bucket) {
|
setBucketById(state, bucket) {
|
||||||
for (const b in state.buckets) {
|
const bucketIndex = findIndexById(state.buckets, bucket.id)
|
||||||
if (state.buckets[b].id === bucket.id) {
|
state.buckets[bucketIndex] = bucket
|
||||||
state.buckets[b] = bucket
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setBucketByIndex(state, {bucketIndex, bucket}) {
|
setBucketByIndex(state, {bucketIndex, bucket}) {
|
||||||
state.buckets[bucketIndex] = bucket
|
state.buckets[bucketIndex] = bucket
|
||||||
},
|
},
|
||||||
|
|
||||||
setTaskInBucketByIndex(state, {bucketIndex, taskIndex, task}) {
|
setTaskInBucketByIndex(state, {bucketIndex, taskIndex, task}) {
|
||||||
const bucket = state.buckets[bucketIndex]
|
const bucket = state.buckets[bucketIndex]
|
||||||
bucket.tasks[taskIndex] = task
|
bucket.tasks[taskIndex] = task
|
||||||
state.buckets[bucketIndex] = bucket
|
state.buckets[bucketIndex] = bucket
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setTasksInBucketByBucketId(state, {bucketId, tasks}) {
|
||||||
|
const bucketIndex = findIndexById(state.buckets, bucketId)
|
||||||
|
state.buckets[bucketIndex] = {
|
||||||
|
...state.buckets[bucketIndex],
|
||||||
|
tasks,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
setTaskInBucket(state, task) {
|
setTaskInBucket(state, task) {
|
||||||
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
|
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
|
||||||
if (state.buckets.length === 0) {
|
if (state.buckets.length === 0) {
|
||||||
|
@ -106,49 +136,61 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addTaskToBucket(state, task) {
|
|
||||||
const bi = filterObject(state.buckets, b => b.id === task.bucketId)
|
|
||||||
state.buckets[bi].tasks.push(task)
|
|
||||||
},
|
|
||||||
addTasksToBucket(state, {tasks, bucketId}) {
|
|
||||||
const bi = filterObject(state.buckets, b => b.id === bucketId)
|
|
||||||
|
|
||||||
tasks.forEach(t => {
|
addTaskToBucket(state, task) {
|
||||||
state.buckets[bi].tasks.push(t)
|
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}) {
|
||||||
|
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) {
|
removeTaskInBucket(state, task) {
|
||||||
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
|
// If this gets invoked without any tasks actually loaded, we can save the hassle of finding the task
|
||||||
if (state.buckets.length === 0) {
|
if (state.buckets.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const b in state.buckets) {
|
const { bucketIndex, taskIndex } = getTaskPosition(state, task)
|
||||||
if (state.buckets[b].id === task.bucketId) {
|
|
||||||
for (const t in state.buckets[b].tasks) {
|
state.buckets[bucketIndex].tasks.splice(taskIndex, 1)
|
||||||
if (state.buckets[b].tasks[t].id === task.id) {
|
|
||||||
const bucket = state.buckets[b]
|
|
||||||
bucket.tasks.splice(t, 1)
|
|
||||||
state.buckets[b] = bucket
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setBucketLoading(state, {bucketId, loading}) {
|
setBucketLoading(state, {bucketId, loading}) {
|
||||||
state.bucketLoading[bucketId] = loading
|
state.bucketLoading[bucketId] = loading
|
||||||
},
|
},
|
||||||
|
|
||||||
setTasksLoadedForBucketPage(state, {bucketId, page}) {
|
setTasksLoadedForBucketPage(state, {bucketId, page}) {
|
||||||
state.taskPagesPerBucket[bucketId] = page
|
state.taskPagesPerBucket[bucketId] = page
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setAllTasksLoadedForBucket(state, bucketId) {
|
setAllTasksLoadedForBucket(state, bucketId) {
|
||||||
state.allTasksLoadedForBucket[bucketId] = true
|
state.allTasksLoadedForBucket[bucketId] = true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
|
getBucketById(state) {
|
||||||
|
return (bucketId) => findById(state.buckets, bucketId)
|
||||||
|
},
|
||||||
getTaskById: state => id => {
|
getTaskById: state => id => {
|
||||||
for (const b in state.buckets) {
|
for (const b in state.buckets) {
|
||||||
for (const t in state.buckets[b].tasks) {
|
for (const t in state.buckets[b].tasks) {
|
||||||
|
@ -168,6 +210,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
loadBucketsForList(ctx, {listId, params}) {
|
loadBucketsForList(ctx, {listId, params}) {
|
||||||
const cancel = setLoading(ctx, 'kanban')
|
const cancel = setLoading(ctx, 'kanban')
|
||||||
|
@ -191,15 +234,18 @@ export default {
|
||||||
cancel()
|
cancel()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
loadNextTasksForBucket(ctx, {listId, ps = {}, bucketId}) {
|
loadNextTasksForBucket(ctx, {listId, ps = {}, bucketId}) {
|
||||||
const isLoading = ctx.state.bucketLoading[bucketId] ?? false
|
const bucketIndex = findIndexById(ctx.state.buckets, bucketId)
|
||||||
|
|
||||||
|
const isLoading = ctx.state.bucketLoading[bucketIndex] ?? false
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = (ctx.state.taskPagesPerBucket[bucketId] ?? 1) + 1
|
const page = (ctx.state.taskPagesPerBucket[bucketIndex] ?? 1) + 1
|
||||||
|
|
||||||
const alreadyLoaded = ctx.state.allTasksLoadedForBucket[bucketId] ?? false
|
const alreadyLoaded = ctx.state.allTasksLoadedForBucket[bucketIndex] ?? false
|
||||||
if (alreadyLoaded) {
|
if (alreadyLoaded) {
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
@ -289,7 +335,7 @@ export default {
|
||||||
const bucketService = new BucketService()
|
const bucketService = new BucketService()
|
||||||
return bucketService.update(bucket)
|
return bucketService.update(bucket)
|
||||||
.then(r => {
|
.then(r => {
|
||||||
const bi = filterObject(ctx.state.buckets, b => b.id === r.id)
|
const bi = findById(ctx.state.buckets, r.id)
|
||||||
const bucket = r
|
const bucket = r
|
||||||
bucket.tasks = ctx.state.buckets[bi].tasks
|
bucket.tasks = ctx.state.buckets[bi].tasks
|
||||||
ctx.commit('setBucketByIndex', {bucketIndex: bi, bucket})
|
ctx.commit('setBucketByIndex', {bucketIndex: bi, bucket})
|
||||||
|
|
|
@ -235,7 +235,7 @@
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
|
|
||||||
import BucketModel from '../../../models/bucket'
|
import BucketModel from '../../../models/bucket'
|
||||||
import {filterObject} from '@/helpers/filterObject'
|
import {findById} from '@/helpers/find'
|
||||||
import {mapState} from 'vuex'
|
import {mapState} from 'vuex'
|
||||||
import {saveListView} from '@/helpers/saveListView'
|
import {saveListView} from '@/helpers/saveListView'
|
||||||
import Rights from '../../../models/constants/rights.json'
|
import Rights from '../../../models/constants/rights.json'
|
||||||
|
@ -503,7 +503,7 @@ export default {
|
||||||
// Because the contenteditable does not have a change event,
|
// Because the contenteditable does not have a change event,
|
||||||
// we're building it ourselves here and only updating the bucket
|
// we're building it ourselves here and only updating the bucket
|
||||||
// if the title changed.
|
// if the title changed.
|
||||||
const realBucket = this.buckets[filterObject(this.buckets, b => b.id === bucketId)]
|
const realBucket = findById(this.buckets, bucketId)
|
||||||
if (realBucket.title === bucketTitle) {
|
if (realBucket.title === bucketTitle) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue