mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-25 08:53:50 +00:00
feat(tasks): show deadlines in scheduled list page and planner task
This commit is contained in:
parent
b1a4d9326f
commit
9e8f45b1f8
7 changed files with 114 additions and 1 deletions
|
|
@ -44,6 +44,17 @@
|
|||
|
||||
<div class="title">{{ task.title }}</div>
|
||||
|
||||
@if (task.deadlineDay || task.deadlineWithTime) {
|
||||
<div class="deadline-indicator">
|
||||
<mat-icon>event_busy</mat-icon>
|
||||
@if (task.deadlineWithTime) {
|
||||
<span>{{ task.deadlineWithTime | shortDate2 }}</span>
|
||||
} @else if (task.deadlineDay) {
|
||||
<span>{{ task.deadlineDay | shortDate2 }}</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<tag-list
|
||||
[isShowProjectTagAlways]="true"
|
||||
[tagsToHide]="tagsToHide()"
|
||||
|
|
|
|||
|
|
@ -234,6 +234,25 @@
|
|||
margin-left: -6px;
|
||||
}
|
||||
|
||||
.deadline-indicator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 4px;
|
||||
font-size: var(--planner-font-size-smaller-mobile);
|
||||
opacity: 0.7;
|
||||
|
||||
@include mq(xs) {
|
||||
font-size: var(--planner-font-size-smaller);
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
font-size: 14px;
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
:host ::ng-deep .due-date + .planner-time-remaining-shared {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -567,6 +567,26 @@ export const selectAllTasksWithDeadlineReminder = createSelector(
|
|||
},
|
||||
);
|
||||
|
||||
export const selectAllUndoneTasksWithDeadlineSorted = createSelector(
|
||||
selectAllTasks,
|
||||
(tasks: Task[]): Task[] => {
|
||||
return tasks
|
||||
.filter(
|
||||
(task) =>
|
||||
task &&
|
||||
!task.isDone &&
|
||||
(task.deadlineDay || typeof task.deadlineWithTime === 'number'),
|
||||
)
|
||||
.sort((a, b) => {
|
||||
const aTime =
|
||||
a.deadlineWithTime || new Date(a.deadlineDay + 'T23:59:59').getTime();
|
||||
const bTime =
|
||||
b.deadlineWithTime || new Date(b.deadlineDay + 'T23:59:59').getTime();
|
||||
return aTime - bTime;
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
export const selectUndoneTasksWithDueDayNoReminder = createSelector(
|
||||
selectAllTasks,
|
||||
(tasks: Task[]): Task[] => {
|
||||
|
|
|
|||
|
|
@ -133,4 +133,50 @@
|
|||
} @else {
|
||||
<full-page-spinner></full-page-spinner>
|
||||
}
|
||||
@if (tasksWithDeadlines$ | async; as tasksWithDeadlines) {
|
||||
<section
|
||||
class="component-wrapper"
|
||||
style="margin-top: 24px"
|
||||
>
|
||||
<h2>{{ T.SCHEDULE.TASKS_WITH_DEADLINES | translate }}</h2>
|
||||
@if (!tasksWithDeadlines?.length) {
|
||||
<p class="no-scheduled-tasks">{{ T.SCHEDULE.NO_DEADLINES | translate }}</p>
|
||||
}
|
||||
<div
|
||||
[@standardList]="tasksWithDeadlines?.length"
|
||||
class="tasks"
|
||||
>
|
||||
@for (task of tasksWithDeadlines; track task.id) {
|
||||
<planner-task [task]="task">
|
||||
<div
|
||||
(click)="editDeadline(task, $event)"
|
||||
class="due-date"
|
||||
mat-ripple
|
||||
>
|
||||
<div class="date-and-time-left">
|
||||
@if (task.deadlineWithTime) {
|
||||
<div class="date hide-xs">
|
||||
{{ task.deadlineWithTime | localeDate: 'EE, d MMM, ' }}
|
||||
{{ task.deadlineWithTime | shortTime }}
|
||||
</div>
|
||||
<div class="date show-xs-only">
|
||||
{{ task.deadlineWithTime | localeDate: 'd MMM, ' }},
|
||||
{{ task.deadlineWithTime | shortTime }}
|
||||
</div>
|
||||
<div class="time-left">
|
||||
({{ task.deadlineWithTime | humanizeTimestamp }})
|
||||
</div>
|
||||
} @else if (task.deadlineDay) {
|
||||
<div class="date">{{ task.deadlineDay | localeDate: 'EE, d MMM' }}</div>
|
||||
}
|
||||
</div>
|
||||
<mat-icon>event_busy</mat-icon>
|
||||
</div>
|
||||
</planner-task>
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
} @else {
|
||||
<full-page-spinner></full-page-spinner>
|
||||
}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { TranslatePipe, TranslateService } from '@ngx-translate/core';
|
|||
import { DialogEditTaskRepeatCfgComponent } from '../../features/task-repeat-cfg/dialog-edit-task-repeat-cfg/dialog-edit-task-repeat-cfg.component';
|
||||
import { TaskRepeatCfgService } from '../../features/task-repeat-cfg/task-repeat-cfg.service';
|
||||
import { DialogScheduleTaskComponent } from '../../features/planner/dialog-schedule-task/dialog-schedule-task.component';
|
||||
import { DialogDeadlineComponent } from '../../features/tasks/dialog-deadline/dialog-deadline.component';
|
||||
import { DateTimeFormatService } from '../../core/date-time-format/date-time-format.service';
|
||||
import { MatCard, MatCardContent } from '@angular/material/card';
|
||||
import { TaskTitleComponent } from '../../ui/task-title/task-title.component';
|
||||
|
|
@ -26,6 +27,7 @@ import { PlannerTaskComponent } from '../../features/planner/planner-task/planne
|
|||
import {
|
||||
selectAllTasksWithDueTimeSorted,
|
||||
selectAllUndoneTasksWithDueDay,
|
||||
selectAllUndoneTasksWithDeadlineSorted,
|
||||
} from '../../features/tasks/store/task.selectors';
|
||||
import { selectTaskRepeatCfgsSortedByTitleAndProject } from '../../features/task-repeat-cfg/store/task-repeat-cfg.selectors';
|
||||
import { getNextRepeatOccurrence } from '../../features/task-repeat-cfg/store/get-next-repeat-occurrence.util';
|
||||
|
|
@ -69,6 +71,7 @@ export class ScheduledListPageComponent {
|
|||
taskRepeatCfgs$ = this._store.select(selectTaskRepeatCfgsSortedByTitleAndProject);
|
||||
tasksPlannedForDays$ = this._store.select(selectAllUndoneTasksWithDueDay);
|
||||
tasksPlannedWithTime$ = this._store.select(selectAllTasksWithDueTimeSorted);
|
||||
tasksWithDeadlines$ = this._store.select(selectAllUndoneTasksWithDeadlineSorted);
|
||||
|
||||
editReminder(task: TaskCopy, ev: MouseEvent): void {
|
||||
ev.preventDefault();
|
||||
|
|
@ -79,6 +82,16 @@ export class ScheduledListPageComponent {
|
|||
});
|
||||
}
|
||||
|
||||
editDeadline(task: TaskCopy, ev: MouseEvent): void {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this._matDialog.open(DialogDeadlineComponent, {
|
||||
autoFocus: false,
|
||||
restoreFocus: true,
|
||||
data: { task },
|
||||
});
|
||||
}
|
||||
|
||||
editTaskRepeatCfg(repeatCfg: TaskRepeatCfg): void {
|
||||
this._matDialog.open(DialogEditTaskRepeatCfgComponent, {
|
||||
restoreFocus: false,
|
||||
|
|
|
|||
|
|
@ -2579,6 +2579,8 @@ const T = {
|
|||
SCHEDULED_TASKS: 'SCHEDULE.SCHEDULED_TASKS',
|
||||
SCHEDULED_TASKS_WITH_TIME: 'SCHEDULE.SCHEDULED_TASKS_WITH_TIME',
|
||||
START_TASK: 'SCHEDULE.START_TASK',
|
||||
TASKS_WITH_DEADLINES: 'SCHEDULE.TASKS_WITH_DEADLINES',
|
||||
NO_DEADLINES: 'SCHEDULE.NO_DEADLINES',
|
||||
},
|
||||
'Share Chart': 'Share Chart',
|
||||
'Share Heatmap': 'Share Heatmap',
|
||||
|
|
|
|||
|
|
@ -2523,7 +2523,9 @@
|
|||
"REPEATED_TASKS": "Recurring Tasks",
|
||||
"SCHEDULED_TASKS": "Scheduled Tasks",
|
||||
"SCHEDULED_TASKS_WITH_TIME": "Scheduled Tasks with Start Time",
|
||||
"START_TASK": "Start task and remove reminder"
|
||||
"START_TASK": "Start task and remove reminder",
|
||||
"TASKS_WITH_DEADLINES": "Tasks with Deadlines",
|
||||
"NO_DEADLINES": "There are currently no tasks with deadlines. You can set a deadline via the task's context menu or detail panel."
|
||||
},
|
||||
"Share Chart": "",
|
||||
"Share Heatmap": "",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue