mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-18 17:05:48 +00:00
feat(tasks): add estimate quick-pick submenu to context menu
This commit is contained in:
parent
9e11c09562
commit
eca8d211ae
8 changed files with 85 additions and 12 deletions
|
|
@ -113,7 +113,7 @@
|
|||
[class.menu-open]="isEstimateMenuOpen()"
|
||||
(click)="onEstimateMenuClick()"
|
||||
>
|
||||
<mat-icon>timer</mat-icon>
|
||||
<mat-icon>hourglass_empty</mat-icon>
|
||||
<span>{{
|
||||
estimateDisplay() || (T.F.TASK.ADD_TASK_BAR.ESTIMATE_BUTTON | translate)
|
||||
}}</span>
|
||||
|
|
|
|||
|
|
@ -17,16 +17,18 @@ export interface AddTaskBarState {
|
|||
attachments: TaskAttachment[];
|
||||
repeatQuickSetting: RepeatQuickSetting | null;
|
||||
}
|
||||
const M = 60 * 1000;
|
||||
const H = 60 * M;
|
||||
export const ESTIMATE_OPTIONS = [
|
||||
{ label: '5m', value: '5m' },
|
||||
{ label: '10m', value: '10m' },
|
||||
{ label: '15m', value: '15m' },
|
||||
{ label: '30m', value: '30m' },
|
||||
{ label: '1h', value: '1h' },
|
||||
{ label: '2h', value: '2h' },
|
||||
{ label: '3h', value: '3h' },
|
||||
{ label: '4h', value: '4h' },
|
||||
{ label: '8h', value: '8h' },
|
||||
{ label: '5m', value: '5m', ms: 5 * M },
|
||||
{ label: '10m', value: '10m', ms: 10 * M },
|
||||
{ label: '15m', value: '15m', ms: 15 * M },
|
||||
{ label: '30m', value: '30m', ms: 30 * M },
|
||||
{ label: '1h', value: '1h', ms: 1 * H },
|
||||
{ label: '2h', value: '2h', ms: 2 * H },
|
||||
{ label: '3h', value: '3h', ms: 3 * H },
|
||||
{ label: '4h', value: '4h', ms: 4 * H },
|
||||
{ label: '8h', value: '8h', ms: 8 * H },
|
||||
];
|
||||
|
||||
export const INITIAL_ADD_TASK_BAR_STATE: AddTaskBarState = {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
@if (task.timeSpent || task.timeEstimate) {
|
||||
<section class="section">
|
||||
<h3>
|
||||
<mat-icon>timer</mat-icon>
|
||||
<mat-icon>hourglass_empty</mat-icon>
|
||||
<strong>{{ T.F.TASK.ADDITIONAL_INFO.TIME | translate }}</strong>
|
||||
</h3>
|
||||
<div class="time-info">
|
||||
|
|
|
|||
|
|
@ -249,6 +249,21 @@
|
|||
</button>
|
||||
}
|
||||
|
||||
@if (!task.subTaskIds.length) {
|
||||
<button
|
||||
#estimateMenuTrigger="matMenuTrigger"
|
||||
[matMenuTriggerFor]="estimateMenu"
|
||||
mat-menu-item
|
||||
[menuTouchFix]="estimateMenuTrigger"
|
||||
>
|
||||
<span class="menuItemLeft">
|
||||
<mat-icon>hourglass_empty</mat-icon>
|
||||
{{ T.F.TASK.CMP.ESTIMATE | translate }}
|
||||
</span>
|
||||
<span class="key-i">{{ kb.taskOpenEstimationDialog }}</span>
|
||||
</button>
|
||||
}
|
||||
|
||||
<button
|
||||
[matMenuTriggerFor]="tagMenu"
|
||||
mat-menu-item
|
||||
|
|
@ -306,6 +321,45 @@
|
|||
</button>
|
||||
</mat-menu>
|
||||
|
||||
<mat-menu
|
||||
#estimateMenu="matMenu"
|
||||
(closed)="focusRelatedTaskOrNext()"
|
||||
>
|
||||
<ng-template matMenuContent>
|
||||
@for (option of ESTIMATE_OPTIONS; track option.value) {
|
||||
<button
|
||||
mat-menu-item
|
||||
menuTouchFix
|
||||
(click)="setEstimate(option.ms)"
|
||||
>
|
||||
@if (option.ms === task.timeEstimate) {
|
||||
<mat-icon>check</mat-icon>
|
||||
}
|
||||
{{ option.label }}
|
||||
</button>
|
||||
}
|
||||
<mat-divider></mat-divider>
|
||||
<button
|
||||
mat-menu-item
|
||||
menuTouchFix
|
||||
(click)="estimateTime()"
|
||||
>
|
||||
<mat-icon>tune</mat-icon>
|
||||
{{ T.F.TASK.CMP.CUSTOM_ESTIMATE | translate }}
|
||||
</button>
|
||||
@if (task.timeEstimate > 0) {
|
||||
<button
|
||||
mat-menu-item
|
||||
menuTouchFix
|
||||
(click)="setEstimate(0)"
|
||||
>
|
||||
<mat-icon>clear</mat-icon>
|
||||
{{ T.F.TASK.CMP.CLEAR_ESTIMATE | translate }}
|
||||
</button>
|
||||
}
|
||||
</ng-template>
|
||||
</mat-menu>
|
||||
|
||||
<mat-menu
|
||||
#projectMenu="matMenu"
|
||||
(closed)="focusRelatedTaskOrNext()"
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import {
|
|||
MatMenuItem,
|
||||
MatMenuTrigger,
|
||||
} from '@angular/material/menu';
|
||||
import { MatDivider } from '@angular/material/divider';
|
||||
import { ESTIMATE_OPTIONS } from '../../add-task-bar/add-task-bar.const';
|
||||
import { Task, TaskCopy, TaskWithSubTasks } from '../../task.model';
|
||||
import { EMPTY, forkJoin, from, Observable, of, ReplaySubject, Subject } from 'rxjs';
|
||||
import {
|
||||
|
|
@ -86,6 +88,7 @@ import { DEFAULT_GLOBAL_CONFIG } from 'src/app/features/config/default-global-co
|
|||
MatMenu,
|
||||
MatMenuContent,
|
||||
MatMenuItem,
|
||||
MatDivider,
|
||||
TranslateModule,
|
||||
MatMenuTrigger,
|
||||
MatIconButton,
|
||||
|
|
@ -118,6 +121,7 @@ export class TaskContextMenuInnerComponent implements AfterViewInit, OnDestroy {
|
|||
|
||||
protected readonly isTouchActive = isTouchActive;
|
||||
protected readonly T = T;
|
||||
readonly ESTIMATE_OPTIONS = ESTIMATE_OPTIONS;
|
||||
|
||||
isAdvancedControls = input<boolean>(false);
|
||||
todayList = toSignal(this._store.select(selectTodayTaskIds), { initialValue: [] });
|
||||
|
|
@ -433,6 +437,13 @@ export class TaskContextMenuInnerComponent implements AfterViewInit, OnDestroy {
|
|||
.subscribe(() => this.focusRelatedTaskOrNext());
|
||||
}
|
||||
|
||||
setEstimate(ms: number): void {
|
||||
if (ms === this.task.timeEstimate) {
|
||||
return;
|
||||
}
|
||||
this._taskService.update(this.task.id, { timeEstimate: ms });
|
||||
}
|
||||
|
||||
addSubTask(): void {
|
||||
this._taskService.addSubTaskTo(this.task.parentId || this.task.id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@
|
|||
class="input-item --estimate"
|
||||
>
|
||||
<ng-container input-title>
|
||||
<mat-icon>timer</mat-icon>
|
||||
<mat-icon>hourglass_empty</mat-icon>
|
||||
<span>{{ T.F.TASK.ADDITIONAL_INFO.TIME | translate }}</span>
|
||||
</ng-container>
|
||||
<ng-container input-value>
|
||||
|
|
|
|||
|
|
@ -1601,13 +1601,16 @@ const T = {
|
|||
ADD_SUB_TASK: 'F.TASK.CMP.ADD_SUB_TASK',
|
||||
ADD_TO_MY_DAY: 'F.TASK.CMP.ADD_TO_MY_DAY',
|
||||
ADD_TO_PROJECT: 'F.TASK.CMP.ADD_TO_PROJECT',
|
||||
CLEAR_ESTIMATE: 'F.TASK.CMP.CLEAR_ESTIMATE',
|
||||
CONVERT_TO_PARENT_TASK: 'F.TASK.CMP.CONVERT_TO_PARENT_TASK',
|
||||
CUSTOM_ESTIMATE: 'F.TASK.CMP.CUSTOM_ESTIMATE',
|
||||
DELETE: 'F.TASK.CMP.DELETE',
|
||||
DELETE_REPEAT_INSTANCE: 'F.TASK.CMP.DELETE_REPEAT_INSTANCE',
|
||||
DROP_ATTACHMENT: 'F.TASK.CMP.DROP_ATTACHMENT',
|
||||
DUPLICATE: 'F.TASK.CMP.DUPLICATE',
|
||||
EDIT_DEADLINE: 'F.TASK.CMP.EDIT_DEADLINE',
|
||||
EDIT_SCHEDULED: 'F.TASK.CMP.EDIT_SCHEDULED',
|
||||
ESTIMATE: 'F.TASK.CMP.ESTIMATE',
|
||||
FOCUS_SESSION: 'F.TASK.CMP.FOCUS_SESSION',
|
||||
MARK_DONE: 'F.TASK.CMP.MARK_DONE',
|
||||
MOVE_TO_BACKLOG: 'F.TASK.CMP.MOVE_TO_BACKLOG',
|
||||
|
|
|
|||
|
|
@ -1563,13 +1563,16 @@
|
|||
"ADD_SUB_TASK": "Add subtask",
|
||||
"ADD_TO_MY_DAY": "Add to Today",
|
||||
"ADD_TO_PROJECT": "Add to a project",
|
||||
"CLEAR_ESTIMATE": "Clear estimate",
|
||||
"CONVERT_TO_PARENT_TASK": "Convert to parent task",
|
||||
"CUSTOM_ESTIMATE": "Custom…",
|
||||
"DELETE": "Delete task",
|
||||
"DELETE_REPEAT_INSTANCE": "Delete recurring task instance",
|
||||
"DROP_ATTACHMENT": "Drop here to attach to \"{{title}}\"",
|
||||
"DUPLICATE": "Duplicate",
|
||||
"EDIT_DEADLINE": "Edit deadline",
|
||||
"EDIT_SCHEDULED": "Reschedule",
|
||||
"ESTIMATE": "Estimate",
|
||||
"FOCUS_SESSION": "Start focus session",
|
||||
"MARK_DONE": "Mark as completed",
|
||||
"MOVE_TO_BACKLOG": "Move to backlog",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue