fix(tasks): enable editing goals and tasks
This commit is contained in:
1 parent
139e4c5198
commit
0a68782172
23 files changed
+191
-34
No files matched your search
+53
-2
@@ -70,6 +70,57 @@ assert.doesNotMatch(assets.indexHtml, /<script\s+src=/, "the desktop cannot sile
|
||||
assert.ok(assets.indexHtml.indexOf('window.systemApp =') < assets.indexHtml.lastIndexOf("window.init()"), "locale renderers run before desktop initialization");
|
||||
for (const script of shippedScripts) new vm.Script(script);
|
||||
for (const script of [assets.i18nJs, assets.dataActionsJs, assets.terminalAppJs, assets.dbAdminJs, assets.tasksJs, assets.calendarJs, assets.notificationsJs, assets.i18nRenderersJs, assets.desktopPersonalizationJs, assets.desktopWidgetsJs, assets.systemNavigationJs, assets.browserAppJs, assets.addonsJs]) new vm.Script(script);
|
||||
const editState = { tasksBoard: { goals: [
|
||||
{ id: 'g1', title: 'Original goal', description: 'Old note', targetDate: '2026-11-01', showOnDesktop: true, done: false, createdAt: '2026-09-01T00:00:00Z' },
|
||||
{ id: 'g2', title: 'Finished goal', done: true, targetDate: '', createdAt: '2026-09-01T00:00:00Z' }
|
||||
], tasks: [
|
||||
{ id: 't1', title: 'Original task', dueDate: '2026-10-10', goalId: 'g1', priority: 'normal', done: false, createdAt: '2026-09-02T00:00:00Z' },
|
||||
{ id: 't2', title: 'Finished task', dueDate: '', goalId: 'g2', priority: 'low', done: true, completedAt: '2026-09-20T00:00:00Z', createdAt: '2026-09-02T00:00:00Z' }
|
||||
] } };
|
||||
const editModal = { innerHTML: '' }, editToasts = [], editContent = { innerHTML: '' };
|
||||
const editContext = vm.createContext({
|
||||
document: { createElement: () => ({}), head: { append() {} }, querySelector: selector => selector === '#modal' ? editModal : null },
|
||||
LifeI18n: { t: key => key, locale: () => 'en-US' },
|
||||
sys: () => editState, save: (key, value) => { if (key === 'lifeos_system') Object.assign(editState, structuredClone(value)); },
|
||||
renderAll: () => {}, closeModal: () => { editModal.innerHTML = ''; }, toast: value => editToasts.push(value),
|
||||
day: () => '2026-10-02', setInterval: () => 0, setTimeout: () => 0, crypto: globalThis.crypto, Date
|
||||
});
|
||||
editContext.window = editContext;
|
||||
vm.runInContext(assets.dataActionsJs, editContext);
|
||||
vm.runInContext(assets.tasksJs, editContext);
|
||||
editContext.tasksApp(editContent);
|
||||
assert.match(editContent.innerHTML, /openTaskEdit\(this\.dataset\.id\)/);
|
||||
assert.match(editContent.innerHTML, /openGoalForm\(this\.dataset\.id\)/);
|
||||
editContext.setTaskFilter('done');
|
||||
editContext.tasksApp(editContent);
|
||||
assert.match(editContent.innerHTML, /Finished task/);
|
||||
assert.match(editContent.innerHTML, /openTaskEdit\(this\.dataset\.id\)/, 'completed tasks have an edit button');
|
||||
editContext.openTaskEdit('t1');
|
||||
assert.match(editModal.innerHTML, /value="Original task"/);
|
||||
assert.match(editModal.innerHTML, /value="2026-10-10"/);
|
||||
const taskFields = { '#task-edit-title-input': 'Updated task', '#task-edit-date': '2026-10-12', '#task-edit-goal': 'g2', '#task-edit-priority': 'high' };
|
||||
editContext.saveTaskEdit({ preventDefault() {}, currentTarget: { dataset: { id: 't1' }, querySelector: selector => ({ value: taskFields[selector] }) } });
|
||||
assert.equal(editState.tasksBoard.tasks[0].title, 'Updated task');
|
||||
assert.equal(editState.tasksBoard.tasks[0].goalId, 'g2');
|
||||
assert.equal(editState.tasksBoard.tasks[0].priority, 'high');
|
||||
assert.equal(editState.tasksBoard.tasks[0].dueDate, '2026-10-12');
|
||||
assert.equal(editState.tasksBoard.tasks[0].createdAt, '2026-09-02T00:00:00Z');
|
||||
assert.equal(editState.tasksBoard.tasks[0].done, false);
|
||||
assert.throws(() => editContext.LifeOSActions.updateTask('t1', { title: 'No link', goalId: 'missing' }), /notFound/);
|
||||
assert.equal(editState.tasksBoard.tasks[0].goalId, 'g2', 'invalid edits do not write changes');
|
||||
editContext.openGoalForm('g1');
|
||||
assert.match(editModal.innerHTML, /value="Original goal"/);
|
||||
assert.match(editModal.innerHTML, /checked/);
|
||||
const goalFields = { '#goal-new-title': { value: 'Updated goal' }, '#goal-new-description': { value: 'New note' }, '#goal-new-date': { value: '' }, '#goal-new-desktop': { checked: true } };
|
||||
editContext.saveGoal({ preventDefault() {}, currentTarget: { dataset: { id: 'g1' }, querySelector: selector => goalFields[selector] } });
|
||||
assert.equal(editState.tasksBoard.goals[0].title, 'Updated goal');
|
||||
assert.equal(editState.tasksBoard.goals[0].description, 'New note');
|
||||
assert.equal(editState.tasksBoard.goals[0].showOnDesktop, false, 'removing the target date also removes the countdown');
|
||||
assert.equal(editState.tasksBoard.goals[0].createdAt, '2026-09-01T00:00:00Z');
|
||||
assert.equal(editState.tasksBoard.tasks[0].goalId, 'g2', 'editing a goal keeps task links');
|
||||
editContext.openGoalForm('g2');
|
||||
assert.match(editModal.innerHTML, /value="Finished goal"/, 'finished goals remain editable');
|
||||
assert.deepEqual(editToasts, ['tasks.taskUpdated', 'tasks.goalUpdated']);
|
||||
const reminderStorage = new Map(), delivered = [];
|
||||
reminderStorage.set('lifeos_notifications_v1', JSON.stringify(Object.fromEntries(['memory', 'tasks', 'goals'].map(kind => [kind, { enabled: true, time: '12:00' }]))));
|
||||
const reminderContext = vm.createContext({
|
||||
@@ -143,7 +194,7 @@ assert.equal(terminalStorage.get('lifeos_system').tasksBoard.tasks[0].done, true
|
||||
assert.equal(command('memory add "Experiment" --date 2026-09-28 --tag school --energy 4 --text "Finished lab"').message, 'terminal.memorySaved');
|
||||
assert.equal(terminalStorage.get('lifeos_memories')[0].text, 'Finished lab');
|
||||
assert.equal(terminalStorage.get('lifeos_memories')[0].tags[0], 'school');
|
||||
assert.throws(() => command('memory add "Again" --text "Duplicate"'), /memoryExists/);
|
||||
assert.throws(() => command('memory add "Again" --date 2026-09-28 --text "Duplicate"'), /memoryExists/);
|
||||
assert.throws(() => command('goal add "Invalid date" --due 2026-02-30'), /invalidDate/);
|
||||
assert.match(command('memory add "Multiline" --date 2026-09-29').message, /terminal\.wizard\.tags/);
|
||||
assert.match(command('back').message, /terminal\.wizard\.date/);
|
||||
@@ -218,7 +269,7 @@ assert.ok(command('date').message.length > 8);
|
||||
assert.ok(command('time').message.includes(':'));
|
||||
assert.ok(command('datetime').message.length > 12);
|
||||
assert.equal(command('uptime').message, 'terminal.uptime');
|
||||
assert.equal(command('version').message, 'Life OS v1.18.0');
|
||||
assert.equal(command('version').message, 'Life OS v1.18.1');
|
||||
assert.equal(command('status').message, 'terminal.status');
|
||||
assert.match(command('apps').message, /calendar/);
|
||||
assert.equal(command('echo "hello Life OS"').message, 'hello Life OS');
|
||||
|
||||
Reference in new issue
Block a user