1
0

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:
kolaente
2022-11-13 22:04:57 +01:00
committed by Gitea
parent b9d3b5c756
commit befa6f27bb
133 changed files with 1873 additions and 1881 deletions

View File

@ -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')
})
})

View File

@ -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()

View File

@ -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()
})

View File

@ -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)
}
})