Skip to content

Commit e31bac1

Browse files
feat(notes): add completed task cleanup controls (#854)
* feat(notes): add completed task cleanup API * feat(notes): add completed task controls * test(notes): cover completed task cleanup
1 parent 7c75908 commit e31bac1

29 files changed

Lines changed: 507 additions & 9 deletions

File tree

src/main/api/dto/notes.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,15 @@ const notesCountsResponse = t.Object({
6565
trash: t.Number(),
6666
})
6767

68+
const notesTasksCleanupResponse = t.Object({
69+
count: t.Number(),
70+
})
71+
6872
export const notesDTO = new Elysia().model({
6973
notesAdd,
7074
notesContentUpdate,
7175
notesCountsResponse,
76+
notesTasksCleanupResponse,
7277
noteItemResponse: noteItem,
7378
noteProperties,
7479
notesResponse,
@@ -86,6 +91,7 @@ export const notesDTO = new Elysia().model({
8691
propertyStatus: t.Optional(t.String()),
8792
propertyStatusNot: t.Optional(t.String()),
8893
propertyType: t.Optional(t.String()),
94+
hideCompletedTasks: t.Optional(t.Number({ minimum: 0, maximum: 1 })),
8995
}),
9096
notePropertiesUpdate,
9197
notesUpdate,

src/main/api/routes/notes.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { NoteItemResponse, NotesResponse } from '../dto/notes'
22
import Elysia from 'elysia'
33
import { useNotesStorage } from '../../storage'
4+
import { runTasksCleanupNow } from '../../tasks'
45
import {
56
commonAddResponse,
67
commonMessageResponse,
@@ -313,5 +314,18 @@ app
313314
},
314315
},
315316
)
317+
.post(
318+
'/tasks/cleanup',
319+
() => {
320+
const count = runTasksCleanupNow()
321+
return { count }
322+
},
323+
{
324+
response: 'notesTasksCleanupResponse',
325+
detail: {
326+
tags: ['Notes'],
327+
},
328+
},
329+
)
316330

317331
export default app

src/main/i18n/locales/en_US/menu.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757
"ascending": "Ascending",
5858
"descending": "Descending"
5959
},
60-
"compactMode": "Compact List"
60+
"compactMode": "Compact List",
61+
"hideCompletedTasks": "Hide Completed Tasks"
6162
},
6263
"edit": {
6364
"label": "Edit",

src/main/i18n/locales/en_US/preferences.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
}
100100
},
101101
"notesEditor": {
102-
"label": "Note Editor",
102+
"label": "Notes",
103103
"fontSize": {
104104
"label": "Font Size",
105105
"description": "Base font size in pixels for the notes editor."
@@ -185,6 +185,22 @@
185185
"rateLimited": "Rate limit exceeded. Try again later."
186186
}
187187
},
188+
"tasks": {
189+
"label": "Tasks",
190+
"autoCleanup": {
191+
"label": "Auto-clean completed",
192+
"description": "Move completed tasks to trash on a schedule. They stay in trash until you empty it.",
193+
"never": "Never",
194+
"1d": "Every day",
195+
"7d": "Every 7 days",
196+
"30d": "Every 30 days"
197+
},
198+
"cleanupNow": {
199+
"label": "Clean up now",
200+
"button": "Move completed to trash",
201+
"description": "Move all completed tasks to trash right now."
202+
}
203+
},
188204
"http": {
189205
"label": "HTTP Client",
190206
"wrapLines": {

src/main/i18n/locales/en_US/ui.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,12 @@
413413
"duePlaceholder": "Due",
414414
"clearDue": "Clear due date",
415415
"noDue": "No due",
416+
"cleanupCompleted": "Clean up completed tasks",
417+
"cleanupConfirmTitle": "Clean up completed tasks?",
418+
"cleanupConfirmMessage": "All completed tasks will be moved to trash. You can restore them until you empty the trash.",
419+
"cleanupDone": "Moved {{count}} completed task(s) to trash",
420+
"cleanupEmpty": "No completed tasks to clean up",
421+
"cleanupError": "Failed to clean up completed tasks",
416422
"status": {
417423
"todo": "Todo",
418424
"inProgress": "In progress",

src/main/i18n/locales/ru_RU/menu.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757
"ascending": "По возрастанию",
5858
"descending": "По убыванию"
5959
},
60-
"compactMode": "Компактный список"
60+
"compactMode": "Компактный список",
61+
"hideCompletedTasks": "Скрывать завершённые задачи"
6162
},
6263
"edit": {
6364
"label": "Правка",

src/main/i18n/locales/ru_RU/preferences.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
}
9898
},
9999
"notesEditor": {
100-
"label": "Редактор заметок",
100+
"label": "Заметки",
101101
"fontSize": {
102102
"label": "Размер шрифта",
103103
"description": "Базовый размер шрифта в пикселях для редактора заметок."
@@ -152,6 +152,22 @@
152152
"label": "Markdown",
153153
"codeRenderer": "Рендер блоков кода"
154154
},
155+
"tasks": {
156+
"label": "Задачи",
157+
"autoCleanup": {
158+
"label": "Автоочистка завершённых",
159+
"description": "Периодически перемещать завершённые задачи в корзину. Они остаются в корзине, пока вы её не очистите.",
160+
"never": "Никогда",
161+
"1d": "Каждый день",
162+
"7d": "Каждые 7 дней",
163+
"30d": "Каждые 30 дней"
164+
},
165+
"cleanupNow": {
166+
"label": "Очистить сейчас",
167+
"button": "Переместить завершённые в корзину",
168+
"description": "Переместить все завершённые задачи в корзину прямо сейчас."
169+
}
170+
},
155171
"http": {
156172
"label": "HTTP Client",
157173
"wrapLines": {

src/main/i18n/locales/ru_RU/ui.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,12 @@
414414
"duePlaceholder": "Срок",
415415
"clearDue": "Очистить срок",
416416
"noDue": "Нет срока",
417+
"cleanupCompleted": "Очистить завершённые задачи",
418+
"cleanupConfirmTitle": "Очистить завершённые задачи?",
419+
"cleanupConfirmMessage": "Все завершённые задачи будут перемещены в корзину. Их можно восстановить, пока корзина не очищена.",
420+
"cleanupDone": "Перемещено завершённых задач в корзину: {{count}}",
421+
"cleanupEmpty": "Нет завершённых задач для очистки",
422+
"cleanupError": "Не удалось очистить завершённые задачи",
417423
"status": {
418424
"todo": "К выполнению",
419425
"inProgress": "В работе",

src/main/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { isQuitting, setQuitting } from './quitState'
1212
import { startMarkdownWatcher, stopMarkdownWatcher } from './storage'
1313
import { ensureFlatSpacesLayout } from './storage/providers/markdown/runtime/spaces'
1414
import { store } from './store'
15+
import { startTasksCleanupScheduler, stopTasksCleanupScheduler } from './tasks'
1516
import { checkForUpdates } from './updates'
1617
import { isSqliteFile, log } from './utils'
1718
import { DEFAULT_WINDOW_BOUNDS, normalizeWindowBounds } from './windowBounds'
@@ -234,6 +235,13 @@ else {
234235
log('Error starting markdown watcher', error)
235236
}
236237

238+
try {
239+
startTasksCleanupScheduler()
240+
}
241+
catch (error) {
242+
log('Error starting tasks cleanup scheduler', error)
243+
}
244+
237245
try {
238246
registerIPC()
239247
}
@@ -286,6 +294,7 @@ else {
286294
flushWindowBoundsSave()
287295
stopThemeWatcher()
288296
stopMarkdownWatcher()
297+
stopTasksCleanupScheduler()
289298
})
290299

291300
app.on('window-all-closed', () => {

src/main/menu/__tests__/main.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ describe('createMainMenu', () => {
6262
contentSortField: 'updatedAt',
6363
contentSortOrder: 'DESC',
6464
canToggleCompactMode: true,
65+
canToggleHideCompletedTasks: false,
66+
isHideCompletedTasksInFolders: false,
6567
canToggleMindmap: false,
6668
isCompactMode: true,
6769
isMindmapShown: false,
@@ -137,6 +139,8 @@ describe('createMainMenu', () => {
137139
contentSortField: null,
138140
contentSortOrder: null,
139141
canToggleCompactMode: false,
142+
canToggleHideCompletedTasks: false,
143+
isHideCompletedTasksInFolders: false,
140144
canToggleMindmap: false,
141145
isCompactMode: false,
142146
isMindmapShown: false,
@@ -186,6 +190,8 @@ describe('createMainMenu', () => {
186190
contentSortField: 'createdAt',
187191
contentSortOrder: 'DESC',
188192
canToggleCompactMode: true,
193+
canToggleHideCompletedTasks: false,
194+
isHideCompletedTasksInFolders: false,
189195
canToggleMindmap: false,
190196
isCompactMode: false,
191197
isMindmapShown: false,
@@ -241,6 +247,8 @@ describe('createMainMenu', () => {
241247
contentSortField: null,
242248
contentSortOrder: null,
243249
canToggleCompactMode: true,
250+
canToggleHideCompletedTasks: false,
251+
isHideCompletedTasksInFolders: false,
244252
canToggleMindmap: false,
245253
isCompactMode: true,
246254
isMindmapShown: false,
@@ -310,6 +318,8 @@ describe('createMainMenu', () => {
310318
contentSortField: 'createdAt',
311319
contentSortOrder: 'ASC',
312320
canToggleCompactMode: false,
321+
canToggleHideCompletedTasks: false,
322+
isHideCompletedTasksInFolders: false,
313323
canToggleMindmap: false,
314324
isCompactMode: false,
315325
isMindmapShown: false,

0 commit comments

Comments
 (0)