feat(scheduleRightPanel): improve on drag out to unschedule

This commit is contained in:
Johannes Millan 2025-10-17 12:25:52 +02:00
parent 795c8b361f
commit 27b714bf91
4 changed files with 45 additions and 9 deletions

View file

@ -15,6 +15,8 @@ import { calculateTimeFromYPosition } from '../schedule-utils';
import { IS_TOUCH_PRIMARY } from '../../../util/is-mouse-primary';
import type { DragPreviewContext } from './schedule-week-drag.types';
import type { ScheduleEvent } from '../schedule.model';
import { selectTodayTagTaskIds } from '../../tag/store/tag.reducer';
import { first } from 'rxjs/operators';
interface PointerPosition {
x: number;
@ -246,8 +248,8 @@ export class ScheduleWeekDragService {
// 4. No column but hovering over another task → reorder
dispatchMoveBefore();
} else if (dropPoint && this._isOutsideGrid(dropPoint)) {
// 5. Dropped outside grid → unschedule and plan for today
this._store.dispatch(TaskSharedActions.planTasksForToday({ taskIds: [task.id] }));
// 5. Dropped outside grid → unschedule and remove from today
this._handleUnschedule(task, sourceEvent);
}
// Clear timestamp and other drag-related vars AFTER drop is processed
@ -469,7 +471,8 @@ export class ScheduleWeekDragService {
}
} else {
// TODO use proper translation string
this._dragPreviewContext.set({ kind: 'override', label: '✖ Unschedule' });
this._dragPreviewContext.set({ kind: 'override', label: '✖ Unschedule Time' });
// this._dragPreviewContext.set({ kind: 'override', label: '✖ Unschedule' });
this._lastCalculatedTimestamp = null;
}
}
@ -734,4 +737,31 @@ export class ScheduleWeekDragService {
);
return true;
}
private _handleUnschedule(task: TaskCopy, sourceEvent: ScheduleEvent): void {
// Check if task has scheduled time - unschedule it
// This also removes from planner days (but not from today tag)
if (task.dueWithTime) {
this._store.dispatch(
TaskSharedActions.unscheduleTask({
id: task.id,
reminderId: task.reminderId,
isLeaveInToday: true,
}),
);
} else {
this._store
.select(selectTodayTagTaskIds)
.pipe(first())
.subscribe((todayTagTaskIds) => {
if (todayTagTaskIds.includes(task.id)) {
this._store.dispatch(
TaskSharedActions.removeTasksFromTodayTag({
taskIds: [task.id],
}),
);
}
});
}
}
}

View file

@ -78,7 +78,11 @@ const handleScheduleTaskWithTime = (
]);
};
const handleUnScheduleTask = (state: RootState, taskId: string): RootState => {
const handleUnScheduleTask = (
state: RootState,
taskId: string,
isLeaveInToday = false,
): RootState => {
// First, update the task entity to clear scheduling data
const updatedState = {
...state,
@ -96,8 +100,7 @@ const handleUnScheduleTask = (state: RootState, taskId: string): RootState => {
// Then, handle today tag updates
const todayTag = getTag(updatedState, TODAY_TAG.id);
if (!todayTag.taskIds.includes(taskId)) {
if (!todayTag.taskIds.includes(taskId) || isLeaveInToday) {
return updatedState;
}
@ -245,8 +248,10 @@ const createActionHandlers = (state: RootState, action: Action): ActionHandlerMa
return handleScheduleTaskWithTime(state, task, dueWithTime);
},
[TaskSharedActions.unscheduleTask.type]: () => {
const { id } = action as ReturnType<typeof TaskSharedActions.unscheduleTask>;
return handleUnScheduleTask(state, id);
const { id, isLeaveInToday } = action as ReturnType<
typeof TaskSharedActions.unscheduleTask
>;
return handleUnScheduleTask(state, id, isLeaveInToday);
},
[TaskSharedActions.dismissReminderOnly.type]: () => {
const { id } = action as ReturnType<typeof TaskSharedActions.dismissReminderOnly>;

View file

@ -69,6 +69,7 @@ export const TaskSharedActions = createActionGroup({
id: string;
reminderId?: string;
isSkipToast?: boolean;
isLeaveInToday?: boolean;
}>(),
dismissReminderOnly: props<{

View file

@ -939,7 +939,7 @@
"MONTH": "Month",
"NO_TASKS": "Currently there are no tasks. Please add some tasks via the + Button in the top bar.",
"NOW": "Now",
"INSERT_BEFORE": "Insert before",
"INSERT_BEFORE": "Before",
"PLAN_END_DAY": "End of {{date}}",
"PLAN_START_DAY": "Start of {{date}}",
"SHIFT_KEY_INFO": "Hold Shift to toggle day planning mode",