fix(quick add magic): parse full month name as month, do not replace only the abbreviation
Resolves https://kolaente.dev/vikunja/vikunja/issues/2320
This commit is contained in:
parent
358e11c404
commit
b0db3ce34c
@ -2,7 +2,7 @@ import {calculateDayInterval} from './calculateDayInterval'
|
|||||||
import {calculateNearestHours} from './calculateNearestHours'
|
import {calculateNearestHours} from './calculateNearestHours'
|
||||||
import {replaceAll} from '../replaceAll'
|
import {replaceAll} from '../replaceAll'
|
||||||
|
|
||||||
interface dateParseResult {
|
export interface dateParseResult {
|
||||||
newText: string,
|
newText: string,
|
||||||
date: Date | null,
|
date: Date | null,
|
||||||
}
|
}
|
||||||
@ -12,7 +12,7 @@ interface dateFoundResult {
|
|||||||
date: Date | null,
|
date: Date | null,
|
||||||
}
|
}
|
||||||
|
|
||||||
const monthsRegexGroup = '(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)'
|
const monthsRegexGroup = '(january|february|march|april|june|july|august|september|october|november|december|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)'
|
||||||
|
|
||||||
function matchesDateExpr(text: string, dateExpr: string): boolean {
|
function matchesDateExpr(text: string, dateExpr: string): boolean {
|
||||||
return text.match(new RegExp('(^| )' + dateExpr, 'gi')) !== null
|
return text.match(new RegExp('(^| )' + dateExpr, 'gi')) !== null
|
||||||
@ -60,12 +60,12 @@ export const parseDate = (text: string, now: Date = new Date()): dateParseResult
|
|||||||
return addTimeToDate(text, date, 'end of month')
|
return addTimeToDate(text, date, 'end of month')
|
||||||
}
|
}
|
||||||
|
|
||||||
let parsed = getDateFromWeekday(text)
|
let parsed = getDateFromWeekday(text, now)
|
||||||
if (parsed.date !== null) {
|
if (parsed.date !== null) {
|
||||||
return addTimeToDate(text, parsed.date, parsed.foundText)
|
return addTimeToDate(text, parsed.date, parsed.foundText)
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed = getDayFromText(text)
|
parsed = getDayFromText(text, now)
|
||||||
if (parsed.date !== null) {
|
if (parsed.date !== null) {
|
||||||
const month = getMonthFromText(text, parsed.date)
|
const month = getMonthFromText(text, parsed.date)
|
||||||
return addTimeToDate(month.newText, month.date, parsed.foundText)
|
return addTimeToDate(month.newText, month.date, parsed.foundText)
|
||||||
@ -76,7 +76,7 @@ export const parseDate = (text: string, now: Date = new Date()): dateParseResult
|
|||||||
return addTimeToDate(text, parsed.date, parsed.foundText)
|
return addTimeToDate(text, parsed.date, parsed.foundText)
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed = getDateFromText(text)
|
parsed = getDateFromText(text, now)
|
||||||
|
|
||||||
if (parsed.date === null) {
|
if (parsed.date === null) {
|
||||||
return {
|
return {
|
||||||
@ -230,7 +230,7 @@ export const getDateFromTextIn = (text: string, now: Date = new Date()) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDateFromWeekday = (text: string): dateFoundResult => {
|
const getDateFromWeekday = (text: string, date: Date = new Date()): dateFoundResult => {
|
||||||
const matcher = /(^| )(next )?(monday|mon|tuesday|tue|wednesday|wed|thursday|thu|friday|fri|saturday|sat|sunday|sun)($| )/g
|
const matcher = /(^| )(next )?(monday|mon|tuesday|tue|wednesday|wed|thursday|thu|friday|fri|saturday|sat|sunday|sun)($| )/g
|
||||||
const results: string[] | null = matcher.exec(text.toLowerCase()) // The i modifier does not seem to work.
|
const results: string[] | null = matcher.exec(text.toLowerCase()) // The i modifier does not seem to work.
|
||||||
if (results === null) {
|
if (results === null) {
|
||||||
@ -240,7 +240,6 @@ const getDateFromWeekday = (text: string): dateFoundResult => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const date: Date = new Date()
|
|
||||||
const currentDay: number = date.getDay()
|
const currentDay: number = date.getDay()
|
||||||
let day = 0
|
let day = 0
|
||||||
|
|
||||||
@ -296,7 +295,7 @@ const getDateFromWeekday = (text: string): dateFoundResult => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDayFromText = (text: string) => {
|
const getDayFromText = (text: string, now: Date = new Date()) => {
|
||||||
const matcher = /(^| )(([1-2][0-9])|(3[01])|(0?[1-9]))(st|nd|rd|th|\.)($| )/ig
|
const matcher = /(^| )(([1-2][0-9])|(3[01])|(0?[1-9]))(st|nd|rd|th|\.)($| )/ig
|
||||||
const results = matcher.exec(text)
|
const results = matcher.exec(text)
|
||||||
if (results === null) {
|
if (results === null) {
|
||||||
@ -306,7 +305,6 @@ const getDayFromText = (text: string) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = new Date()
|
|
||||||
const date = new Date(now)
|
const date = new Date(now)
|
||||||
const day = parseInt(results[0])
|
const day = parseInt(results[0])
|
||||||
date.setDate(day)
|
date.setDate(day)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {beforeEach, afterEach, describe, it, expect, vi} from 'vitest'
|
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'
|
||||||
|
|
||||||
import {parseTaskText, PrefixMode} from './parseTaskText'
|
import {ParsedTaskText, parseTaskText, PrefixMode} from './parseTaskText'
|
||||||
import {getDateFromText, parseDate} from '../helpers/time/parseDate'
|
import {parseDate} from '../helpers/time/parseDate'
|
||||||
import {calculateDayInterval} from '../helpers/time/calculateDayInterval'
|
import {calculateDayInterval} from '../helpers/time/calculateDayInterval'
|
||||||
import {PRIORITIES} from '@/constants/priorities'
|
import {PRIORITIES} from '@/constants/priorities'
|
||||||
import {MILLISECONDS_A_DAY} from '@/constants/date'
|
import {MILLISECONDS_A_DAY} from '@/constants/date'
|
||||||
@ -461,50 +461,69 @@ describe('Parse Task Text', () => {
|
|||||||
'1/27': '2022-1-27',
|
'1/27': '2022-1-27',
|
||||||
'jan 27': '2022-1-27',
|
'jan 27': '2022-1-27',
|
||||||
'Jan 27': '2022-1-27',
|
'Jan 27': '2022-1-27',
|
||||||
|
'january 27': '2022-1-27',
|
||||||
|
'January 27': '2022-1-27',
|
||||||
'feb 21': '2022-2-21',
|
'feb 21': '2022-2-21',
|
||||||
'Feb 21': '2022-2-21',
|
'Feb 21': '2022-2-21',
|
||||||
|
'february 21': '2022-2-21',
|
||||||
|
'February 21': '2022-2-21',
|
||||||
'mar 21': '2022-3-21',
|
'mar 21': '2022-3-21',
|
||||||
'Mar 21': '2022-3-21',
|
'Mar 21': '2022-3-21',
|
||||||
|
'march 21': '2022-3-21',
|
||||||
|
'March 21': '2022-3-21',
|
||||||
'apr 21': '2022-4-21',
|
'apr 21': '2022-4-21',
|
||||||
'Apr 21': '2022-4-21',
|
'Apr 21': '2022-4-21',
|
||||||
|
'april 21': '2022-4-21',
|
||||||
|
'April 21': '2022-4-21',
|
||||||
'may 21': '2022-5-21',
|
'may 21': '2022-5-21',
|
||||||
'May 21': '2022-5-21',
|
'May 21': '2022-5-21',
|
||||||
'jun 21': '2022-6-21',
|
'jun 21': '2022-6-21',
|
||||||
'Jun 21': '2022-6-21',
|
'Jun 21': '2022-6-21',
|
||||||
|
'june 21': '2022-6-21',
|
||||||
|
'June 21': '2022-6-21',
|
||||||
|
'21st June': '2021-6-21',
|
||||||
'jul 21': '2021-7-21',
|
'jul 21': '2021-7-21',
|
||||||
'Jul 21': '2021-7-21',
|
'Jul 21': '2021-7-21',
|
||||||
|
'july 21': '2021-7-21',
|
||||||
|
'July 21': '2021-7-21',
|
||||||
'aug 21': '2021-8-21',
|
'aug 21': '2021-8-21',
|
||||||
'Aug 21': '2021-8-21',
|
'Aug 21': '2021-8-21',
|
||||||
|
'august 21': '2021-8-21',
|
||||||
|
'August 21': '2021-8-21',
|
||||||
'sep 21': '2021-9-21',
|
'sep 21': '2021-9-21',
|
||||||
'Sep 21': '2021-9-21',
|
'Sep 21': '2021-9-21',
|
||||||
|
'september 21': '2021-9-21',
|
||||||
|
'September 21': '2021-9-21',
|
||||||
'oct 21': '2021-10-21',
|
'oct 21': '2021-10-21',
|
||||||
'Oct 21': '2021-10-21',
|
'Oct 21': '2021-10-21',
|
||||||
|
'october 21': '2021-10-21',
|
||||||
|
'October 21': '2021-10-21',
|
||||||
'nov 21': '2021-11-21',
|
'nov 21': '2021-11-21',
|
||||||
'Nov 21': '2021-11-21',
|
'Nov 21': '2021-11-21',
|
||||||
|
'november 21': '2021-11-21',
|
||||||
|
'November 21': '2021-11-21',
|
||||||
'dec 21': '2021-12-21',
|
'dec 21': '2021-12-21',
|
||||||
'Dec 21': '2021-12-21',
|
'Dec 21': '2021-12-21',
|
||||||
|
'december 21': '2021-12-21',
|
||||||
|
'December 21': '2021-12-21',
|
||||||
} as Record<string, string | null>
|
} as Record<string, string | null>
|
||||||
|
|
||||||
for (const c in cases) {
|
for (const c in cases) {
|
||||||
it(`should parse '${c}' as '${cases[c]}' with the date at the end`, () => {
|
const assertResult = ({date, text}: ParsedTaskText) => {
|
||||||
const {date, foundText} = getDateFromText(`Lorem Ipsum ${c}`, now)
|
|
||||||
if (date === null && cases[c] === null) {
|
if (date === null && cases[c] === null) {
|
||||||
expect(date).toBeNull()
|
expect(date).toBeNull()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(`${date?.getFullYear()}-${date?.getMonth() + 1}-${date?.getDate()}`).toBe(cases[c])
|
expect(`${date?.getFullYear()}-${date?.getMonth() + 1}-${date?.getDate()}`).toBe(cases[c])
|
||||||
expect(foundText.trim()).toBe(c)
|
expect(text.trim()).toBe('Lorem Ipsum')
|
||||||
|
}
|
||||||
|
|
||||||
|
it(`should parse '${c}' as '${cases[c]}' with the date at the end`, () => {
|
||||||
|
assertResult(parseTaskText(`Lorem Ipsum ${c}`, PrefixMode.Default, now))
|
||||||
})
|
})
|
||||||
it(`should parse '${c}' as '${cases[c]}' with the date at the beginning`, () => {
|
it(`should parse '${c}' as '${cases[c]}' with the date at the beginning`, () => {
|
||||||
const {date, foundText} = getDateFromText(`${c} Lorem Ipsum`, now)
|
assertResult(parseTaskText(`${c} Lorem Ipsum`, PrefixMode.Default, now))
|
||||||
if (date === null && cases[c] === null) {
|
|
||||||
expect(date).toBeNull()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(`${date?.getFullYear()}-${date?.getMonth() + 1}-${date?.getDate()}`).toBe(cases[c])
|
|
||||||
expect(foundText.trim()).toBe(c)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -55,7 +55,7 @@ interface Prefixes {
|
|||||||
*
|
*
|
||||||
* @param text
|
* @param text
|
||||||
*/
|
*/
|
||||||
export const parseTaskText = (text: string, prefixesMode: PrefixMode = PrefixMode.Default): ParsedTaskText => {
|
export const parseTaskText = (text: string, prefixesMode: PrefixMode = PrefixMode.Default, now: Date = new Date()): ParsedTaskText => {
|
||||||
const result: ParsedTaskText = {
|
const result: ParsedTaskText = {
|
||||||
text: text,
|
text: text,
|
||||||
date: null,
|
date: null,
|
||||||
@ -86,7 +86,7 @@ export const parseTaskText = (text: string, prefixesMode: PrefixMode = PrefixMod
|
|||||||
result.text = textWithoutMatched
|
result.text = textWithoutMatched
|
||||||
result.repeats = repeats
|
result.repeats = repeats
|
||||||
|
|
||||||
const {newText, date} = parseDate(result.text)
|
const {newText, date} = parseDate(result.text, now)
|
||||||
result.text = newText
|
result.text = newText
|
||||||
result.date = date
|
result.date = date
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user