Properly handle multiple categories properties

Signed-off-by: Raimund Schlüßler <raimund.schluessler@mailbox.org>
This commit is contained in:
Raimund Schlüßler 2020-07-09 22:39:03 +02:00
parent 6ea8c4bb0c
commit f198e3e1ec
6 changed files with 106 additions and 12 deletions

View File

@ -103,8 +103,7 @@ export default class Task {
const d = due || start
this._allDay = d !== null && d.isDate
this._loaded = false
const categories = this.vtodo.getFirstProperty('categories')
this._categories = categories ? categories.getValues() : []
this._categories = this.getCategories()
this._modified = this.vtodo.getFirstPropertyValue('last-modified')
this._modifiedMoment = moment(this._modified, 'YYYYMMDDTHHmmss')
this._created = this.vtodo.getFirstPropertyValue('created')
@ -508,6 +507,16 @@ export default class Task {
return this._categories
}
getCategories() {
let categories = []
for (const cats of this.vtodo.getAllProperties('categories')) {
if (cats) {
categories = categories.concat(cats.getValues())
}
}
return categories
}
/**
* Set the categories
*
@ -515,21 +524,38 @@ export default class Task {
* @memberof Task
*/
set categories(newCategories) {
let categories = this.vtodo.getFirstProperty('categories')
if (newCategories.length > 0) {
if (categories) {
categories.setValues(newCategories)
} else {
let categories = this.vtodo.getAllProperties('categories')
// If there are no categories set yet, just set them
if (categories.length < 1) {
const prop = new ICAL.Property('categories')
prop.setValues(newCategories)
categories = this.vtodo.addProperty(prop)
// If there is only one categories property, overwrite it
} else if (categories.length < 2) {
categories[0].setValues(newCategories)
// If there are multiple categories properties, we have to iterate over all
// and remove unwanted categories and add new ones
} else {
const toRemove = this._categories.filter(c => !newCategories.includes(c))
const toAdd = newCategories.filter(c => !this._categories.includes(c))
// Remove all unwanted categories
for (const cats of categories) {
const c = cats.getValues().filter(c => !toRemove.includes(c))
if (c.length) {
cats.setValues(c)
} else {
this.vtodo.removeProperty(cats)
}
}
// Add new categories
categories[0].setValues(categories[0].getValues().concat(toAdd))
}
} else {
this.vtodo.removeProperty('categories')
this.vtodo.removeAllProperties('categories')
}
this.updateLastModified()
categories = this.vtodo.getFirstProperty('categories')
this._categories = categories ? categories.getValues() : []
this._categories = this.getCategories()
}
updateLastModified() {

View File

@ -424,9 +424,7 @@ const mutations = {
* @param {String} category The category to add
*/
addCategory(state, { task, category }) {
const categories = task.categories
categories.push(category)
Vue.set(task, 'categories', categories)
Vue.set(task, 'categories', task.categories.concat([category]))
},
/**

View File

@ -0,0 +1,13 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Nextcloud Tasks 0.11.3
BEGIN:VTODO
CREATED:20181119T183919
DTSTAMP:20190918T095816
LAST-MODIFIED:20190918T095816
UID:pwen9kz28g
CATEGORIES:cat1,cat2
CATEGORIES:cat3
SUMMARY:Test 1
END:VTODO
END:VCALENDAR

View File

@ -0,0 +1,11 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Nextcloud Tasks 0.11.3
BEGIN:VTODO
CREATED:20181119T183919
DTSTAMP:20190918T095816
LAST-MODIFIED:20190918T095816
UID:pwen9kz29f
SUMMARY:Test 1
END:VTODO
END:VCALENDAR

View File

@ -0,0 +1,12 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Nextcloud Tasks 0.11.3
BEGIN:VTODO
CREATED:20181119T183919
DTSTAMP:20190918T095816
LAST-MODIFIED:20190918T095816
UID:pwen9kz31g
CATEGORIES:cat1,cat2
SUMMARY:Test 1
END:VTODO
END:VCALENDAR

View File

@ -161,4 +161,38 @@ describe('task', () => {
task.sortOrder = 2
expect(task.sortOrder).toEqual(2)
})
it('Should show all categories from multiple properties.', () => {
const task = new Task(loadICS('vcalendars/vcalendar-categories-multiple'), {})
expect(task.categories.length).toEqual(3)
})
it('Should properly add and remove categories from multiple properties.', () => {
const task = new Task(loadICS('vcalendars/vcalendar-categories-multiple'), {})
expect(task.categories.length).toEqual(3)
expect(task.categories).toEqual(['cat1', 'cat2', 'cat3'])
task.categories = ['cat1', 'cat5']
expect(task.categories).toEqual(['cat1', 'cat5'])
task.categories = []
expect(task.categories.length).toEqual(0)
})
it('Should properly add and remove categories from a single property.', () => {
const task = new Task(loadICS('vcalendars/vcalendar-categories-single'), {})
expect(task.categories.length).toEqual(2)
expect(task.categories).toEqual(['cat1', 'cat2'])
task.categories = ['cat1', 'cat3']
expect(task.categories).toEqual(['cat1', 'cat3'])
task.categories = []
expect(task.categories.length).toEqual(0)
})
it('Should properly add and remove categories if none are set yet.', () => {
const task = new Task(loadICS('vcalendars/vcalendar-categories-none'), {})
expect(task.categories.length).toEqual(0)
task.categories = ['cat1', 'cat3']
expect(task.categories).toEqual(['cat1', 'cat3'])
task.categories = []
expect(task.categories.length).toEqual(0)
})
})