mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-17 16:37:43 +00:00
fix(tasks): preserve schedule when moving between backlog and regular list (#8603)
Moving a task between the backlog and the regular list now only changes its list position. Previously, moving to the regular list force-scheduled the task for today (planTasksForToday) and moving to the backlog cleared a schedule that fell on today, so the task's due date silently changed. Fixes #8592
This commit is contained in:
parent
13b23c09dc
commit
9e23832879
3 changed files with 59 additions and 14 deletions
|
|
@ -18,6 +18,8 @@ import { DateAdapter } from '@angular/material/core';
|
|||
import { of } from 'rxjs';
|
||||
import { selectTaskByIdWithSubTaskData } from '../../store/task.selectors';
|
||||
import { addSubTask } from '../../store/task.actions';
|
||||
import { TaskSharedActions } from '../../../../root-store/meta/task-shared.actions';
|
||||
import { DateService } from '../../../../core/date/date.service';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { AddSubtaskInputService } from '../../add-subtask-input/add-subtask-input.service';
|
||||
import { Project } from '../../../project/project.model';
|
||||
|
|
@ -89,6 +91,8 @@ describe('TaskContextMenuInnerComponent', () => {
|
|||
projectInTreeOrder('project-a', 'Project A'),
|
||||
]),
|
||||
getByIdOnce$: () => of({}),
|
||||
moveTaskToTodayList: () => {},
|
||||
moveTaskToBacklog: () => {},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -339,4 +343,51 @@ describe('TaskContextMenuInnerComponent', () => {
|
|||
expect(addSubtaskInputService.requestOpen).toHaveBeenCalledWith('PARENT_ID');
|
||||
});
|
||||
});
|
||||
|
||||
// Moving a task between the backlog and the regular list is a list-position
|
||||
// change only; it must not touch the task's schedule (issue #8592).
|
||||
describe('moveToToday() / moveToBacklog() schedule preservation (#8592)', () => {
|
||||
let projectService: ProjectService;
|
||||
|
||||
beforeEach(() => {
|
||||
projectService = TestBed.inject(ProjectService);
|
||||
});
|
||||
|
||||
it('moveToToday() moves to the regular list without scheduling for today', () => {
|
||||
const moveSpy = spyOn(projectService, 'moveTaskToTodayList');
|
||||
const dispatchSpy = spyOn(store, 'dispatch');
|
||||
component.task = {
|
||||
...DEFAULT_TASK,
|
||||
id: 'task-1',
|
||||
projectId: 'project-current',
|
||||
} as Task;
|
||||
|
||||
component.moveToToday();
|
||||
|
||||
expect(moveSpy).toHaveBeenCalledWith('task-1', 'project-current');
|
||||
const dispatchedTypes = dispatchSpy.calls
|
||||
.allArgs()
|
||||
.map((args) => (args[0] as unknown as { type: string }).type);
|
||||
expect(dispatchedTypes).not.toContain(TaskSharedActions.planTasksForToday.type);
|
||||
});
|
||||
|
||||
it('moveToBacklog() moves to the backlog without clearing a schedule set for today', () => {
|
||||
const moveSpy = spyOn(projectService, 'moveTaskToBacklog');
|
||||
const dispatchSpy = spyOn(store, 'dispatch');
|
||||
component.task = {
|
||||
...DEFAULT_TASK,
|
||||
id: 'task-1',
|
||||
projectId: 'project-current',
|
||||
dueDay: TestBed.inject(DateService).todayStr(),
|
||||
} as Task;
|
||||
|
||||
component.moveToBacklog();
|
||||
|
||||
expect(moveSpy).toHaveBeenCalledWith('task-1', 'project-current');
|
||||
const dispatchedTypes = dispatchSpy.calls
|
||||
.allArgs()
|
||||
.map((args) => (args[0] as unknown as { type: string }).type);
|
||||
expect(dispatchedTypes).not.toContain(TaskSharedActions.unscheduleTask.type);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -674,20 +674,17 @@ export class TaskContextMenuInnerComponent implements AfterViewInit, OnDestroy {
|
|||
|
||||
moveToBacklog(): void {
|
||||
if (this.task.projectId && !this.task.parentId) {
|
||||
// Moving to the backlog is a list-position change only; it must not
|
||||
// alter the task's schedule (#8592).
|
||||
this._projectService.moveTaskToBacklog(this.task.id, this.task.projectId);
|
||||
if (
|
||||
this.task.dueDay === this._dateService.todayStr() ||
|
||||
(this.task.dueWithTime && this._dateService.isToday(this.task.dueWithTime))
|
||||
) {
|
||||
this.unschedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moveToToday(): void {
|
||||
if (this.task.projectId && !this.task.parentId) {
|
||||
// Moving to the regular list is a list-position change only; it must not
|
||||
// schedule the task for today (#8592).
|
||||
this._projectService.moveTaskToTodayList(this.task.id, this.task.projectId);
|
||||
this.addToMyDay();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -230,9 +230,6 @@ export class TaskComponent implements OnDestroy, AfterViewInit {
|
|||
return 'chat';
|
||||
});
|
||||
|
||||
isTaskOnTodayList = computed(() =>
|
||||
this._taskService.todayListSet().has(this.task().id),
|
||||
);
|
||||
isTodayListActive = computed(() => this.workContextService.isTodayList);
|
||||
taskIdWithPrefix = computed(() => 't-' + this.task().id);
|
||||
isRepeatTaskCreatedToday = computed(
|
||||
|
|
@ -1335,18 +1332,18 @@ export class TaskComponent implements OnDestroy, AfterViewInit {
|
|||
moveToBacklog(): void {
|
||||
const t = this.task();
|
||||
if (t.projectId && !t.parentId) {
|
||||
// Moving to the backlog is a list-position change only; it must not
|
||||
// alter the task's schedule (#8592).
|
||||
this._projectService.moveTaskToBacklog(t.id, t.projectId);
|
||||
if (this.isTaskOnTodayList()) {
|
||||
this.unschedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moveToToday(): void {
|
||||
const t = this.task();
|
||||
if (t.projectId) {
|
||||
// Moving to the regular list is a list-position change only; it must not
|
||||
// schedule the task for today (#8592).
|
||||
this._projectService.moveTaskToTodayList(t.id, t.projectId);
|
||||
this.addToMyDay();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue