feat: rename list to project everywhere
fix: project table view fix: e2e tests fix: typo in readme fix: list view route fix: don't wait until background is loaded for list to show fix: rename component imports fix: lint fix: parse task text fix: use list card grid fix: use correct class names fix: i18n keys fix: load project fix: task overview fix: list view spacing fix: find project fix: setLoading when updating a project fix: loading saved filter fix: project store loading fix: color picker import fix: cypress tests feat: migrate old list settings chore: add const for project settings fix: wrong projecten rename from lists chore: rename unused variable fix: editor list fix: shortcut list class name fix: pagination list class name fix: notifications list class name fix: list view variable name chore: clarify comment fix: i18n keys fix: router imports fix: comment chore: remove debugging leftover fix: remove duplicate variables fix: change comment fix: list view variable name fix: list view css class name fix: list item property name fix: name update tasks function correctly fix: update comment fix: project create route fix: list view class names fix: list view component name fix: result list class name fix: animation class list name fix: change debug log fix: revert a few navigation changes fix: use @ for imports of all views fix: rename link share list class fix: remove unused css class fix: dynamically import project components again
This commit is contained in:
@ -21,14 +21,14 @@ describe('Parse Task Text', () => {
|
||||
})
|
||||
|
||||
it('should not parse text when disabled', () => {
|
||||
const text = 'Lorem Ipsum today *label +list !2 @user'
|
||||
const text = 'Lorem Ipsum today *label +project !2 @user'
|
||||
const result = parseTaskText(text, PrefixMode.Disabled)
|
||||
|
||||
expect(result.text).toBe(text)
|
||||
})
|
||||
|
||||
it('should parse text in todoist mode when configured', () => {
|
||||
const result = parseTaskText('Lorem Ipsum today @label #list !2 +user', PrefixMode.Todoist)
|
||||
const result = parseTaskText('Lorem Ipsum today @label #project !2 +user', PrefixMode.Todoist)
|
||||
|
||||
expect(result.text).toBe('Lorem Ipsum +user')
|
||||
const now = new Date()
|
||||
@ -37,7 +37,7 @@ describe('Parse Task Text', () => {
|
||||
expect(result?.date?.getDate()).toBe(now.getDate())
|
||||
expect(result.labels).toHaveLength(1)
|
||||
expect(result.labels[0]).toBe('label')
|
||||
expect(result.list).toBe('list')
|
||||
expect(result.project).toBe('project')
|
||||
expect(result.priority).toBe(2)
|
||||
expect(result.assignees).toHaveLength(1)
|
||||
expect(result.assignees[0]).toBe('user')
|
||||
@ -574,36 +574,36 @@ describe('Parse Task Text', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('List', () => {
|
||||
it('should parse a list', () => {
|
||||
const result = parseTaskText('Lorem Ipsum +list')
|
||||
describe('Project', () => {
|
||||
it('should parse a project', () => {
|
||||
const result = parseTaskText('Lorem Ipsum +project')
|
||||
|
||||
expect(result.text).toBe('Lorem Ipsum')
|
||||
expect(result.list).toBe('list')
|
||||
expect(result.project).toBe('project')
|
||||
})
|
||||
it('should parse a list with a space in it', () => {
|
||||
const result = parseTaskText(`Lorem Ipsum +'list with long name'`)
|
||||
it('should parse a project with a space in it', () => {
|
||||
const result = parseTaskText(`Lorem Ipsum +'project with long name'`)
|
||||
|
||||
expect(result.text).toBe('Lorem Ipsum')
|
||||
expect(result.list).toBe('list with long name')
|
||||
expect(result.project).toBe('project with long name')
|
||||
})
|
||||
it('should parse a list with a space in it and "', () => {
|
||||
const result = parseTaskText(`Lorem Ipsum +"list with long name"`)
|
||||
it('should parse a project with a space in it and "', () => {
|
||||
const result = parseTaskText(`Lorem Ipsum +"project with long name"`)
|
||||
|
||||
expect(result.text).toBe('Lorem Ipsum')
|
||||
expect(result.list).toBe('list with long name')
|
||||
expect(result.project).toBe('project with long name')
|
||||
})
|
||||
it('should parse only the first list', () => {
|
||||
const result = parseTaskText(`Lorem Ipsum +list1 +list2 +list3`)
|
||||
it('should parse only the first project', () => {
|
||||
const result = parseTaskText(`Lorem Ipsum +project1 +project2 +project3`)
|
||||
|
||||
expect(result.text).toBe('Lorem Ipsum +list2 +list3')
|
||||
expect(result.list).toBe('list1')
|
||||
expect(result.text).toBe('Lorem Ipsum +project2 +project3')
|
||||
expect(result.project).toBe('project1')
|
||||
})
|
||||
it('should parse a list that\'s called like a date as list', () => {
|
||||
it('should parse a project that\'s called like a date as project', () => {
|
||||
const result = parseTaskText(`Lorem Ipsum +today`)
|
||||
|
||||
expect(result.text).toBe('Lorem Ipsum')
|
||||
expect(result.list).toBe('today')
|
||||
expect(result.project).toBe('today')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -5,14 +5,14 @@ import {getQuickAddMagicMode} from '@/helpers/quickAddMagicMode'
|
||||
|
||||
const VIKUNJA_PREFIXES: Prefixes = {
|
||||
label: '*',
|
||||
list: '+',
|
||||
project: '+',
|
||||
priority: '!',
|
||||
assignee: '@',
|
||||
}
|
||||
|
||||
const TODOIST_PREFIXES: Prefixes = {
|
||||
label: '@',
|
||||
list: '#',
|
||||
project: '#',
|
||||
priority: '!',
|
||||
assignee: '+',
|
||||
}
|
||||
@ -38,7 +38,7 @@ export interface ParsedTaskText {
|
||||
text: string,
|
||||
date: Date | null,
|
||||
labels: string[],
|
||||
list: string | null,
|
||||
project: string | null,
|
||||
priority: number | null,
|
||||
assignees: string[],
|
||||
repeats: IRepeatAfter | null,
|
||||
@ -46,13 +46,13 @@ export interface ParsedTaskText {
|
||||
|
||||
interface Prefixes {
|
||||
label: string,
|
||||
list: string,
|
||||
project: string,
|
||||
priority: string,
|
||||
assignee: string,
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses task text for dates, assignees, labels, lists, priorities and returns an object with all found intents.
|
||||
* Parses task text for dates, assignees, labels, projects, priorities and returns an object with all found intents.
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
@ -61,7 +61,7 @@ export const parseTaskText = (text: string, prefixesMode: PrefixMode = PrefixMod
|
||||
text: text,
|
||||
date: null,
|
||||
labels: [],
|
||||
list: null,
|
||||
project: null,
|
||||
priority: null,
|
||||
assignees: [],
|
||||
repeats: null,
|
||||
@ -75,8 +75,8 @@ export const parseTaskText = (text: string, prefixesMode: PrefixMode = PrefixMod
|
||||
result.labels = getLabelsFromPrefix(text, prefixes.label) ?? []
|
||||
result.text = cleanupItemText(result.text, result.labels, prefixes.label)
|
||||
|
||||
result.list = getListFromPrefix(result.text, prefixes.list)
|
||||
result.text = result.list !== null ? cleanupItemText(result.text, [result.list], prefixes.list) : result.text
|
||||
result.project = getProjectFromPrefix(result.text, prefixes.project)
|
||||
result.text = result.project !== null ? cleanupItemText(result.text, [result.project], prefixes.project) : result.text
|
||||
|
||||
result.priority = getPriority(result.text, prefixes.priority)
|
||||
result.text = result.priority !== null ? cleanupItemText(result.text, [String(result.priority)], prefixes.priority) : result.text
|
||||
@ -129,27 +129,27 @@ const getItemsFromPrefix = (text: string, prefix: string): string[] => {
|
||||
return Array.from(new Set(items))
|
||||
}
|
||||
|
||||
export const getListFromPrefix = (text: string, listPrefix: string | null = null): string | null => {
|
||||
if (listPrefix === null) {
|
||||
export const getProjectFromPrefix = (text: string, projectPrefix: string | null = null): string | null => {
|
||||
if (projectPrefix === null) {
|
||||
const prefixes = PREFIXES[getQuickAddMagicMode()]
|
||||
if (prefixes === undefined) {
|
||||
return null
|
||||
}
|
||||
listPrefix = prefixes.list
|
||||
projectPrefix = prefixes.project
|
||||
}
|
||||
const lists: string[] = getItemsFromPrefix(text, listPrefix)
|
||||
return lists.length > 0 ? lists[0] : null
|
||||
const projects: string[] = getItemsFromPrefix(text, projectPrefix)
|
||||
return projects.length > 0 ? projects[0] : null
|
||||
}
|
||||
|
||||
export const getLabelsFromPrefix = (text: string, listPrefix: string | null = null): string[] | null => {
|
||||
if (listPrefix === null) {
|
||||
export const getLabelsFromPrefix = (text: string, projectPrefix: string | null = null): string[] | null => {
|
||||
if (projectPrefix === null) {
|
||||
const prefixes = PREFIXES[getQuickAddMagicMode()]
|
||||
if (prefixes === undefined) {
|
||||
return null
|
||||
}
|
||||
listPrefix = prefixes.label
|
||||
projectPrefix = prefixes.label
|
||||
}
|
||||
return getItemsFromPrefix(text, listPrefix)
|
||||
return getItemsFromPrefix(text, projectPrefix)
|
||||
}
|
||||
|
||||
const getPriority = (text: string, prefix: string): number | null => {
|
||||
@ -291,7 +291,7 @@ export const cleanupItemText = (text: string, items: string[], prefix: string):
|
||||
|
||||
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.project !== null ? cleanupItemText(result.text, [result.project], prefixes.project) : result.text
|
||||
result.text = result.priority !== null ? cleanupItemText(result.text, [String(result.priority)], prefixes.priority) : result.text
|
||||
// Not removing assignees to avoid removing @text where the user does not exist
|
||||
result.text = result.text.trim()
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {test, expect, vi} from 'vitest'
|
||||
import {getHistory, removeListFromHistory, saveListToHistory} from './listHistory'
|
||||
import {getHistory, removeProjectFromHistory, saveProjectToHistory} from './projectHistory'
|
||||
|
||||
test('return an empty history when none was saved', () => {
|
||||
Storage.prototype.getItem = vi.fn(() => null)
|
||||
@ -15,68 +15,68 @@ test('return a saved history', () => {
|
||||
expect(h).toStrictEqual(saved)
|
||||
})
|
||||
|
||||
test('store list in history', () => {
|
||||
test('store project in history', () => {
|
||||
let saved = {}
|
||||
Storage.prototype.getItem = vi.fn(() => null)
|
||||
Storage.prototype.setItem = vi.fn((key, lists) => {
|
||||
saved = lists
|
||||
Storage.prototype.setItem = vi.fn((key, projects) => {
|
||||
saved = projects
|
||||
})
|
||||
|
||||
saveListToHistory({id: 1})
|
||||
saveProjectToHistory({id: 1})
|
||||
expect(saved).toBe('[{"id":1}]')
|
||||
})
|
||||
|
||||
test('store only the last 5 lists in history', () => {
|
||||
test('store only the last 5 projects in history', () => {
|
||||
let saved: string | null = null
|
||||
Storage.prototype.getItem = vi.fn(() => saved)
|
||||
Storage.prototype.setItem = vi.fn((key: string, lists: string) => {
|
||||
saved = lists
|
||||
Storage.prototype.setItem = vi.fn((key: string, projects: string) => {
|
||||
saved = projects
|
||||
})
|
||||
|
||||
saveListToHistory({id: 1})
|
||||
saveListToHistory({id: 2})
|
||||
saveListToHistory({id: 3})
|
||||
saveListToHistory({id: 4})
|
||||
saveListToHistory({id: 5})
|
||||
saveListToHistory({id: 6})
|
||||
saveProjectToHistory({id: 1})
|
||||
saveProjectToHistory({id: 2})
|
||||
saveProjectToHistory({id: 3})
|
||||
saveProjectToHistory({id: 4})
|
||||
saveProjectToHistory({id: 5})
|
||||
saveProjectToHistory({id: 6})
|
||||
expect(saved).toBe('[{"id":6},{"id":5},{"id":4},{"id":3},{"id":2}]')
|
||||
})
|
||||
|
||||
test('don\'t store the same list twice', () => {
|
||||
test('don\'t store the same project twice', () => {
|
||||
let saved: string | null = null
|
||||
Storage.prototype.getItem = vi.fn(() => saved)
|
||||
Storage.prototype.setItem = vi.fn((key: string, lists: string) => {
|
||||
saved = lists
|
||||
Storage.prototype.setItem = vi.fn((key: string, projects: string) => {
|
||||
saved = projects
|
||||
})
|
||||
|
||||
saveListToHistory({id: 1})
|
||||
saveListToHistory({id: 1})
|
||||
saveProjectToHistory({id: 1})
|
||||
saveProjectToHistory({id: 1})
|
||||
expect(saved).toBe('[{"id":1}]')
|
||||
})
|
||||
|
||||
test('move a list to the beginning when storing it multiple times', () => {
|
||||
test('move a project to the beginning when storing it multiple times', () => {
|
||||
let saved: string | null = null
|
||||
Storage.prototype.getItem = vi.fn(() => saved)
|
||||
Storage.prototype.setItem = vi.fn((key: string, lists: string) => {
|
||||
saved = lists
|
||||
Storage.prototype.setItem = vi.fn((key: string, projects: string) => {
|
||||
saved = projects
|
||||
})
|
||||
|
||||
saveListToHistory({id: 1})
|
||||
saveListToHistory({id: 2})
|
||||
saveListToHistory({id: 1})
|
||||
saveProjectToHistory({id: 1})
|
||||
saveProjectToHistory({id: 2})
|
||||
saveProjectToHistory({id: 1})
|
||||
expect(saved).toBe('[{"id":1},{"id":2}]')
|
||||
})
|
||||
|
||||
test('remove list from history', () => {
|
||||
test('remove project from history', () => {
|
||||
let saved: string | null = '[{"id": 1}]'
|
||||
Storage.prototype.getItem = vi.fn(() => null)
|
||||
Storage.prototype.setItem = vi.fn((key: string, lists: string) => {
|
||||
saved = lists
|
||||
Storage.prototype.setItem = vi.fn((key: string, projects: string) => {
|
||||
saved = projects
|
||||
})
|
||||
Storage.prototype.removeItem = vi.fn((key: string) => {
|
||||
saved = null
|
||||
})
|
||||
|
||||
removeListFromHistory({id: 1})
|
||||
removeProjectFromHistory({id: 1})
|
||||
expect(saved).toBeNull()
|
||||
})
|
||||
|
@ -1,9 +1,9 @@
|
||||
export interface ListHistory {
|
||||
export interface ProjectHistory {
|
||||
id: number;
|
||||
}
|
||||
|
||||
export function getHistory(): ListHistory[] {
|
||||
const savedHistory = localStorage.getItem('listHistory')
|
||||
export function getHistory(): ProjectHistory[] {
|
||||
const savedHistory = localStorage.getItem('projectHistory')
|
||||
if (savedHistory === null) {
|
||||
return []
|
||||
}
|
||||
@ -11,27 +11,27 @@ export function getHistory(): ListHistory[] {
|
||||
return JSON.parse(savedHistory)
|
||||
}
|
||||
|
||||
function saveHistory(history: ListHistory[]) {
|
||||
function saveHistory(history: ProjectHistory[]) {
|
||||
if (history.length === 0) {
|
||||
localStorage.removeItem('listHistory')
|
||||
localStorage.removeItem('projectHistory')
|
||||
return
|
||||
}
|
||||
|
||||
localStorage.setItem('listHistory', JSON.stringify(history))
|
||||
localStorage.setItem('projectHistory', JSON.stringify(history))
|
||||
}
|
||||
|
||||
export function saveListToHistory(list: ListHistory) {
|
||||
const history: ListHistory[] = getHistory()
|
||||
export function saveProjectToHistory(project: ProjectHistory) {
|
||||
const history: ProjectHistory[] = getHistory()
|
||||
|
||||
// Remove the element if it already exists in history, preventing duplicates and essentially moving it to the beginning
|
||||
history.forEach((l, i) => {
|
||||
if (l.id === list.id) {
|
||||
if (l.id === project.id) {
|
||||
history.splice(i, 1)
|
||||
}
|
||||
})
|
||||
|
||||
// Add the new list to the beginning of the list
|
||||
history.unshift(list)
|
||||
// Add the new project to the beginning of the project
|
||||
history.unshift(project)
|
||||
|
||||
if (history.length > 5) {
|
||||
history.pop()
|
||||
@ -39,11 +39,11 @@ export function saveListToHistory(list: ListHistory) {
|
||||
saveHistory(history)
|
||||
}
|
||||
|
||||
export function removeListFromHistory(list: ListHistory) {
|
||||
const history: ListHistory[] = getHistory()
|
||||
export function removeProjectFromHistory(project: ProjectHistory) {
|
||||
const history: ProjectHistory[] = getHistory()
|
||||
|
||||
history.forEach((l, i) => {
|
||||
if (l.id === list.id) {
|
||||
if (l.id === project.id) {
|
||||
history.splice(i, 1)
|
||||
}
|
||||
})
|
||||
|
Reference in New Issue
Block a user