From 02748bd1e1785ff2ecc0664fe4e71fb01f6d761f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raimund=20Schl=C3=BC=C3=9Fler?= Date: Sat, 30 Dec 2023 23:03:21 +0100 Subject: [PATCH] feat: extract tags from task summary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raimund Schlüßler --- src/store/storeHelper.js | 22 +++++++++++++ src/store/tasks.js | 8 +++-- .../javascript/unit/store/storeHelper.spec.js | 32 +++++++++++++++++-- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/store/storeHelper.js b/src/store/storeHelper.js index 8a6ead15f..ca9c59918 100644 --- a/src/store/storeHelper.js +++ b/src/store/storeHelper.js @@ -449,6 +449,27 @@ function searchSubTasks(task, searchQuery) { }) } +/** + * Parses a string to extract tags and a summary + * + * @param {string} string The string + * @return {object} The object containing the parsed results + */ +function parseString(str) { + const matches = str.matchAll(/\s?#([^\s#]+)/g) + let summary = str + const tags = [] + for (const match of matches) { + tags.push(match[1]) + summary = summary.replace(match[0], '') + } + summary = summary.trim() + return { + summary, + tags, + } +} + export { isTaskInList, overdue, @@ -456,4 +477,5 @@ export { sort, momentToICALTime, searchSubTasks, + parseString, } diff --git a/src/store/tasks.js b/src/store/tasks.js index d79e51dc7..40792daee 100644 --- a/src/store/tasks.js +++ b/src/store/tasks.js @@ -23,7 +23,7 @@ import { Calendar } from './calendars.js' import { findVTODObyUid } from './cdav-requests.js' -import { isParentInList, momentToICALTime } from './storeHelper.js' +import { isParentInList, momentToICALTime, parseString } from './storeHelper.js' import SyncStatus from '../models/syncStatus.js' import Task from '../models/task.js' @@ -35,6 +35,7 @@ import moment from '@nextcloud/moment' import ICAL from 'ical.js' import Vue from 'vue' import Vuex from 'vuex' +import { parse } from 'uuid' Vue.use(Vuex) @@ -703,8 +704,11 @@ const actions = { } const task = new Task('BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Nextcloud Tasks v' + appVersion + '\nEND:VCALENDAR', taskData.calendar) + const parsed = parseString(taskData.summary) + task.created = ICAL.Time.now() - task.summary = taskData.summary + task.summary = parsed.summary + task.tags = parsed.tags task.hidesubtasks = 0 if (taskData.priority) { task.priority = taskData.priority diff --git a/tests/javascript/unit/store/storeHelper.spec.js b/tests/javascript/unit/store/storeHelper.spec.js index db8ab0be0..ce4a4c573 100644 --- a/tests/javascript/unit/store/storeHelper.spec.js +++ b/tests/javascript/unit/store/storeHelper.spec.js @@ -1,4 +1,4 @@ -import { sort } from '../../../../src/store/storeHelper.js' +import { sort, parseString } from '../../../../src/store/storeHelper.js' import Task from '../../../../src/models/task.js' import { loadICS } from '../../../assets/loadAsset.js' @@ -14,7 +14,7 @@ const vCalendarNames = [ const tasks = vCalendarNames.map((vCalendar) => { return new Task(loadICS(vCalendar)) }) -describe('storeHelper', () => { +describe('storeHelper - sort', () => { 'use strict' it('Tests descending sort by due date.', () => { @@ -31,3 +31,31 @@ describe('storeHelper', () => { expect(receivedTasks).toEqual(expectedTasks) }) }) + +describe('storeHelper - parseString', () => { + 'use strict' + + it('returns the whole summary if no delimiters are present', () => { + const summary = 'plain summary without special delimiters' + const result = parseString(summary) + expect(result).toEqual({ summary, tags: []}) + }) + + it('returns the summary and single tag found', () => { + const summary = 'summary and #tag' + const result = parseString(summary) + expect(result).toEqual({ summary: 'summary and', tags: ['tag']}) + }) + + it('returns the summary and multiple tags found', () => { + const summary = 'summary and #tag1 #tag2' + const result = parseString(summary) + expect(result).toEqual({ summary: 'summary and', tags: ['tag1', 'tag2']}) + }) + + it('returns the summary and multiple tags found in varying order', () => { + const summary = '#tag1 summary and #tag2 #tag3 more summary #tag4' + const result = parseString(summary) + expect(result).toEqual({ summary: 'summary and more summary', tags: ['tag1', 'tag2', 'tag3', 'tag4']}) + }) +}) \ No newline at end of file