feat(natural language): make natural language prefixes configurable (#795)
Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/795 Co-authored-by: konrad <k@knt.li> Co-committed-by: konrad <k@knt.li>
This commit is contained in:
parent
3b58756285
commit
d47b13647e
7 changed files with 192 additions and 89 deletions
|
|
@ -1,10 +1,31 @@
|
|||
import {parseDate} from '../helpers/time/parseDate'
|
||||
import _priorities from '../models/constants/priorities.json'
|
||||
|
||||
const LABEL_PREFIX: string = '@'
|
||||
const LIST_PREFIX: string = '#'
|
||||
const PRIORITY_PREFIX: string = '!'
|
||||
const ASSIGNEE_PREFIX: string = '+'
|
||||
const VIKUNJA_PREFIXES: Prefixes = {
|
||||
label: '*',
|
||||
list: '+',
|
||||
priority: '!',
|
||||
assignee: '@',
|
||||
}
|
||||
|
||||
const TODOIST_PREFIXES: Prefixes = {
|
||||
label: '@',
|
||||
list: '#',
|
||||
priority: '!',
|
||||
assignee: '+',
|
||||
}
|
||||
|
||||
export enum PrefixMode {
|
||||
Disabled = 'disabled',
|
||||
Default = 'vikunja',
|
||||
Todoist = 'todoist',
|
||||
}
|
||||
|
||||
export const PREFIXES = {
|
||||
[PrefixMode.Disabled]: undefined,
|
||||
[PrefixMode.Default]: VIKUNJA_PREFIXES,
|
||||
[PrefixMode.Todoist]: TODOIST_PREFIXES,
|
||||
}
|
||||
|
||||
const priorities: Priorites = _priorities
|
||||
|
||||
|
|
@ -26,12 +47,19 @@ interface ParsedTaskText {
|
|||
assignees: string[],
|
||||
}
|
||||
|
||||
interface Prefixes {
|
||||
label: string,
|
||||
list: string,
|
||||
priority: string,
|
||||
assignee: string,
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses task text for dates, assignees, labels, lists, priorities and returns an object with all found intents.
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
export const parseTaskText = (text: string): ParsedTaskText => {
|
||||
export const parseTaskText = (text: string, prefixesMode: PrefixMode = PrefixMode.Default): ParsedTaskText => {
|
||||
const result: ParsedTaskText = {
|
||||
text: text,
|
||||
date: null,
|
||||
|
|
@ -41,20 +69,25 @@ export const parseTaskText = (text: string): ParsedTaskText => {
|
|||
assignees: [],
|
||||
}
|
||||
|
||||
result.labels = getItemsFromPrefix(text, LABEL_PREFIX)
|
||||
const prefixes = PREFIXES[prefixesMode]
|
||||
if (prefixes === undefined) {
|
||||
return result
|
||||
}
|
||||
|
||||
const lists: string[] = getItemsFromPrefix(text, LIST_PREFIX)
|
||||
result.labels = getItemsFromPrefix(text, prefixes.label)
|
||||
|
||||
const lists: string[] = getItemsFromPrefix(text, prefixes.list)
|
||||
result.list = lists.length > 0 ? lists[0] : null
|
||||
|
||||
result.priority = getPriority(text)
|
||||
result.priority = getPriority(text, prefixes.priority)
|
||||
|
||||
result.assignees = getItemsFromPrefix(text, ASSIGNEE_PREFIX)
|
||||
result.assignees = getItemsFromPrefix(text, prefixes.assignee)
|
||||
|
||||
const {newText, date} = parseDate(text)
|
||||
result.text = newText
|
||||
result.date = date
|
||||
|
||||
return cleanupResult(result)
|
||||
return cleanupResult(result, prefixes)
|
||||
}
|
||||
|
||||
const getItemsFromPrefix = (text: string, prefix: string): string[] => {
|
||||
|
|
@ -82,8 +115,8 @@ const getItemsFromPrefix = (text: string, prefix: string): string[] => {
|
|||
return Array.from(new Set(items))
|
||||
}
|
||||
|
||||
const getPriority = (text: string): number | null => {
|
||||
const ps = getItemsFromPrefix(text, PRIORITY_PREFIX)
|
||||
const getPriority = (text: string, prefix: string): number | null => {
|
||||
const ps = getItemsFromPrefix(text, prefix)
|
||||
if (ps.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
|
@ -112,11 +145,11 @@ const cleanupItemText = (text: string, items: string[], prefix: string): string
|
|||
return text
|
||||
}
|
||||
|
||||
const cleanupResult = (result: ParsedTaskText): ParsedTaskText => {
|
||||
result.text = cleanupItemText(result.text, result.labels, LABEL_PREFIX)
|
||||
result.text = result.list !== null ? cleanupItemText(result.text, [result.list], LIST_PREFIX) : result.text
|
||||
result.text = result.priority !== null ? cleanupItemText(result.text, [String(result.priority)], PRIORITY_PREFIX) : result.text
|
||||
result.text = cleanupItemText(result.text, result.assignees, ASSIGNEE_PREFIX)
|
||||
const cleanupResult = (result: ParsedTaskText, prefixes: Prefixes): ParsedTaskText => {
|
||||
result.text = cleanupItemText(result.text, result.labels, prefixes.label)
|
||||
result.text = result.list !== null ? cleanupItemText(result.text, [result.list], prefixes.list) : result.text
|
||||
result.text = result.priority !== null ? cleanupItemText(result.text, [String(result.priority)], prefixes.priority) : result.text
|
||||
result.text = cleanupItemText(result.text, result.assignees, prefixes.assignee)
|
||||
result.text = result.text.trim()
|
||||
|
||||
return result
|
||||
|
|
|
|||
Reference in a new issue