@flusys/ng-task-manager 5.4.1 → 6.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,41 +1,19 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Injectable, inject, signal, DestroyRef, computed, input, output, Component, model, effect, untracked } from '@angular/core';
|
|
3
|
-
import { ApiResourceService, TranslatePipe, AngularModule,
|
|
3
|
+
import { ApiResourceService, TranslatePipe, AngularModule, TranslateService, UserSelectComponent, resolveTranslationModule, SHARED_MESSAGES } from '@flusys/ng-shared';
|
|
4
4
|
import { firstValueFrom, Subject } from 'rxjs';
|
|
5
5
|
import { io } from 'socket.io-client';
|
|
6
6
|
import { APP_CONFIG } from '@flusys/ng-core';
|
|
7
7
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
8
|
-
import * as
|
|
8
|
+
import * as i3 from '@angular/common';
|
|
9
9
|
import { DatePipe } from '@angular/common';
|
|
10
|
-
import * as i1 from '
|
|
11
|
-
import {
|
|
12
|
-
import * as i2 from '
|
|
13
|
-
import { TooltipModule } from 'primeng/tooltip';
|
|
14
|
-
import * as i3 from '@angular/forms';
|
|
10
|
+
import * as i1 from '@flusys/ng-ui';
|
|
11
|
+
import { TooltipDirective, UiModule, ConfirmationService, MessageService } from '@flusys/ng-ui';
|
|
12
|
+
import * as i2 from '@angular/forms';
|
|
15
13
|
import { FormsModule } from '@angular/forms';
|
|
16
|
-
import * as i9 from 'primeng/button';
|
|
17
|
-
import { ButtonModule } from 'primeng/button';
|
|
18
|
-
import * as i7 from 'primeng/datepicker';
|
|
19
|
-
import { DatePickerModule } from 'primeng/datepicker';
|
|
20
|
-
import * as i1$1 from 'primeng/dialog';
|
|
21
|
-
import { DialogModule } from 'primeng/dialog';
|
|
22
|
-
import * as i4 from 'primeng/inputtext';
|
|
23
|
-
import { InputTextModule } from 'primeng/inputtext';
|
|
24
|
-
import * as i8 from 'primeng/multiselect';
|
|
25
|
-
import { MultiSelectModule } from 'primeng/multiselect';
|
|
26
|
-
import * as i5 from 'primeng/textarea';
|
|
27
|
-
import { TextareaModule } from 'primeng/textarea';
|
|
28
|
-
import * as i6 from 'primeng/select';
|
|
29
|
-
import { SelectModule } from 'primeng/select';
|
|
30
|
-
import * as i2$1 from 'primeng/api';
|
|
31
|
-
import { ConfirmationService, MessageService } from 'primeng/api';
|
|
32
|
-
import * as i1$2 from 'primeng/drawer';
|
|
33
|
-
import { DrawerModule } from 'primeng/drawer';
|
|
34
14
|
import { Router } from '@angular/router';
|
|
35
|
-
import * as
|
|
36
|
-
import * as i1$3 from '@angular/cdk/drag-drop';
|
|
15
|
+
import * as i2$1 from '@angular/cdk/drag-drop';
|
|
37
16
|
import { moveItemInArray, transferArrayItem, DragDropModule } from '@angular/cdk/drag-drop';
|
|
38
|
-
import * as i9$2 from 'primeng/table';
|
|
39
17
|
|
|
40
18
|
class TaskBoardApiService extends ApiResourceService {
|
|
41
19
|
constructor() {
|
|
@@ -53,10 +31,10 @@ class TaskBoardApiService extends ApiResourceService {
|
|
|
53
31
|
userId,
|
|
54
32
|
}));
|
|
55
33
|
}
|
|
56
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
57
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
34
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskBoardApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
35
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskBoardApiService, providedIn: 'root' });
|
|
58
36
|
}
|
|
59
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
37
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskBoardApiService, decorators: [{
|
|
60
38
|
type: Injectable,
|
|
61
39
|
args: [{ providedIn: 'root' }]
|
|
62
40
|
}], ctorParameters: () => [] });
|
|
@@ -68,10 +46,10 @@ class TaskApiService extends ApiResourceService {
|
|
|
68
46
|
moveTask(dto) {
|
|
69
47
|
return firstValueFrom(this.http.post(`${this.baseUrl}/move`, dto));
|
|
70
48
|
}
|
|
71
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
72
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
49
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
50
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskApiService, providedIn: 'root' });
|
|
73
51
|
}
|
|
74
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
52
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskApiService, decorators: [{
|
|
75
53
|
type: Injectable,
|
|
76
54
|
args: [{ providedIn: 'root' }]
|
|
77
55
|
}], ctorParameters: () => [] });
|
|
@@ -85,10 +63,10 @@ class TaskListApiService extends ApiResourceService {
|
|
|
85
63
|
reorderLists(dto) {
|
|
86
64
|
return firstValueFrom(this.http.post(`${this.baseUrl}/reorder`, dto));
|
|
87
65
|
}
|
|
88
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
89
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
66
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskListApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
67
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskListApiService, providedIn: 'root' });
|
|
90
68
|
}
|
|
91
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
69
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskListApiService, decorators: [{
|
|
92
70
|
type: Injectable,
|
|
93
71
|
args: [{ providedIn: 'root' }]
|
|
94
72
|
}], ctorParameters: () => [] });
|
|
@@ -96,10 +74,10 @@ class TaskLabelApiService extends ApiResourceService {
|
|
|
96
74
|
constructor() {
|
|
97
75
|
super('label', 'taskManager');
|
|
98
76
|
}
|
|
99
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
100
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
77
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskLabelApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
78
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskLabelApiService, providedIn: 'root' });
|
|
101
79
|
}
|
|
102
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
80
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskLabelApiService, decorators: [{
|
|
103
81
|
type: Injectable,
|
|
104
82
|
args: [{ providedIn: 'root' }]
|
|
105
83
|
}], ctorParameters: () => [] });
|
|
@@ -107,10 +85,10 @@ class TaskCommentApiService extends ApiResourceService {
|
|
|
107
85
|
constructor() {
|
|
108
86
|
super('comment', 'taskManager');
|
|
109
87
|
}
|
|
110
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
111
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
88
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskCommentApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
89
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskCommentApiService, providedIn: 'root' });
|
|
112
90
|
}
|
|
113
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
91
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskCommentApiService, decorators: [{
|
|
114
92
|
type: Injectable,
|
|
115
93
|
args: [{ providedIn: 'root' }]
|
|
116
94
|
}], ctorParameters: () => [] });
|
|
@@ -118,7 +96,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
118
96
|
class TaskBoardSocketService {
|
|
119
97
|
socket = null;
|
|
120
98
|
appConfig = inject(APP_CONFIG);
|
|
121
|
-
_isConnected = signal(false,
|
|
99
|
+
_isConnected = signal(false, /* @ts-ignore */
|
|
100
|
+
...(ngDevMode ? [{ debugName: "_isConnected" }] : /* istanbul ignore next */ []));
|
|
122
101
|
isConnected = this._isConnected.asReadonly();
|
|
123
102
|
boardEvent$ = new Subject();
|
|
124
103
|
onBoardEvent = this.boardEvent$.asObservable();
|
|
@@ -157,10 +136,10 @@ class TaskBoardSocketService {
|
|
|
157
136
|
const services = this.appConfig.services;
|
|
158
137
|
return services?.['taskManager']?.socketUrl ?? this.appConfig.apiBaseUrl;
|
|
159
138
|
}
|
|
160
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
161
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
139
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskBoardSocketService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
140
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskBoardSocketService, providedIn: 'root' });
|
|
162
141
|
}
|
|
163
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
142
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskBoardSocketService, decorators: [{
|
|
164
143
|
type: Injectable,
|
|
165
144
|
args: [{ providedIn: 'root' }]
|
|
166
145
|
}] });
|
|
@@ -172,15 +151,24 @@ class TaskBoardStateService {
|
|
|
172
151
|
labelApi = inject(TaskLabelApiService);
|
|
173
152
|
socketService = inject(TaskBoardSocketService);
|
|
174
153
|
destroyRef = inject(DestroyRef);
|
|
175
|
-
_boards = signal([],
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
154
|
+
_boards = signal([], /* @ts-ignore */
|
|
155
|
+
...(ngDevMode ? [{ debugName: "_boards" }] : /* istanbul ignore next */ []));
|
|
156
|
+
_activeBoard = signal(null, /* @ts-ignore */
|
|
157
|
+
...(ngDevMode ? [{ debugName: "_activeBoard" }] : /* istanbul ignore next */ []));
|
|
158
|
+
_lists = signal([], /* @ts-ignore */
|
|
159
|
+
...(ngDevMode ? [{ debugName: "_lists" }] : /* istanbul ignore next */ []));
|
|
160
|
+
_tasks = signal([], /* @ts-ignore */
|
|
161
|
+
...(ngDevMode ? [{ debugName: "_tasks" }] : /* istanbul ignore next */ []));
|
|
162
|
+
_labels = signal([], /* @ts-ignore */
|
|
163
|
+
...(ngDevMode ? [{ debugName: "_labels" }] : /* istanbul ignore next */ []));
|
|
164
|
+
_members = signal([], /* @ts-ignore */
|
|
165
|
+
...(ngDevMode ? [{ debugName: "_members" }] : /* istanbul ignore next */ []));
|
|
166
|
+
_selectedTask = signal(null, /* @ts-ignore */
|
|
167
|
+
...(ngDevMode ? [{ debugName: "_selectedTask" }] : /* istanbul ignore next */ []));
|
|
168
|
+
_isLoading = signal(false, /* @ts-ignore */
|
|
169
|
+
...(ngDevMode ? [{ debugName: "_isLoading" }] : /* istanbul ignore next */ []));
|
|
170
|
+
_isBoardLoading = signal(false, /* @ts-ignore */
|
|
171
|
+
...(ngDevMode ? [{ debugName: "_isBoardLoading" }] : /* istanbul ignore next */ []));
|
|
184
172
|
boards = this._boards.asReadonly();
|
|
185
173
|
activeBoard = this._activeBoard.asReadonly();
|
|
186
174
|
lists = this._lists.asReadonly();
|
|
@@ -198,15 +186,18 @@ class TaskBoardStateService {
|
|
|
198
186
|
map.set(task.listId, list);
|
|
199
187
|
}
|
|
200
188
|
return map;
|
|
201
|
-
},
|
|
189
|
+
}, /* @ts-ignore */
|
|
190
|
+
...(ngDevMode ? [{ debugName: "tasksByList" }] : /* istanbul ignore next */ []));
|
|
202
191
|
listsWithTasks = computed(() => this._lists()
|
|
203
192
|
.slice()
|
|
204
193
|
.sort((a, b) => a.position - b.position)
|
|
205
194
|
.map((list) => ({
|
|
206
195
|
...list,
|
|
207
196
|
tasks: (this.tasksByList().get(list.id) ?? []).slice().sort((a, b) => a.position - b.position),
|
|
208
|
-
})),
|
|
209
|
-
|
|
197
|
+
})), /* @ts-ignore */
|
|
198
|
+
...(ngDevMode ? [{ debugName: "listsWithTasks" }] : /* istanbul ignore next */ []));
|
|
199
|
+
hasActiveBoard = computed(() => this._activeBoard() !== null, /* @ts-ignore */
|
|
200
|
+
...(ngDevMode ? [{ debugName: "hasActiveBoard" }] : /* istanbul ignore next */ []));
|
|
210
201
|
isSocketConnected = this.socketService.isConnected;
|
|
211
202
|
constructor() {
|
|
212
203
|
this.socketService.onBoardEvent
|
|
@@ -368,10 +359,10 @@ class TaskBoardStateService {
|
|
|
368
359
|
}
|
|
369
360
|
}
|
|
370
361
|
}
|
|
371
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
372
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
362
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskBoardStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
363
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskBoardStateService, providedIn: 'root' });
|
|
373
364
|
}
|
|
374
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
365
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskBoardStateService, decorators: [{
|
|
375
366
|
type: Injectable,
|
|
376
367
|
args: [{ providedIn: 'root' }]
|
|
377
368
|
}], ctorParameters: () => [] });
|
|
@@ -421,39 +412,42 @@ function memberColorFromId(userId) {
|
|
|
421
412
|
}
|
|
422
413
|
|
|
423
414
|
class TaskCardComponent {
|
|
424
|
-
task = input.required(
|
|
415
|
+
task = input.required(/* @ts-ignore */
|
|
416
|
+
...(ngDevMode ? [{ debugName: "task" }] : /* istanbul ignore next */ []));
|
|
425
417
|
cardClick = output();
|
|
426
418
|
editClick = output();
|
|
427
419
|
deleteClick = output();
|
|
428
420
|
MAX_VISIBLE = 3;
|
|
429
|
-
visibleAssignees = computed(() => (this.task().assignees ?? []).slice(0, this.MAX_VISIBLE),
|
|
430
|
-
|
|
421
|
+
visibleAssignees = computed(() => (this.task().assignees ?? []).slice(0, this.MAX_VISIBLE), /* @ts-ignore */
|
|
422
|
+
...(ngDevMode ? [{ debugName: "visibleAssignees" }] : /* istanbul ignore next */ []));
|
|
423
|
+
overflowCount = computed(() => Math.max(0, (this.task().assignees ?? []).length - this.MAX_VISIBLE), /* @ts-ignore */
|
|
424
|
+
...(ngDevMode ? [{ debugName: "overflowCount" }] : /* istanbul ignore next */ []));
|
|
431
425
|
prioritySeverity = taskPrioritySeverity;
|
|
432
426
|
initials = memberInitials;
|
|
433
427
|
isOverdue = isTaskOverdue;
|
|
434
428
|
memberColor = memberColorFromId;
|
|
435
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
436
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
429
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
430
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TaskCardComponent, isStandalone: true, selector: "tm-task-card", inputs: { task: { classPropertyName: "task", publicName: "task", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { cardClick: "cardClick", editClick: "editClick", deleteClick: "deleteClick" }, ngImport: i0, template: `
|
|
437
431
|
<div
|
|
438
|
-
class="task-card group relative rounded-
|
|
432
|
+
class="task-card group relative rounded-border border border-surface p-3 cursor-pointer shadow-sm hover:shadow-md transition-shadow"
|
|
439
433
|
(click)="cardClick.emit(task())"
|
|
440
434
|
>
|
|
441
435
|
<div class="absolute top-2 right-2 hidden group-hover:flex gap-0.5">
|
|
442
436
|
<button
|
|
443
|
-
class="w-6 h-6 flex items-center justify-center rounded text-surface-400 hover:text-primary-500 hover:bg-surface-
|
|
444
|
-
[
|
|
437
|
+
class="w-6 h-6 flex items-center justify-center rounded text-surface-400 hover:text-primary-500 hover:bg-surface-hover transition-colors"
|
|
438
|
+
[fTooltip]="'shared.edit' | translate"
|
|
445
439
|
tooltipPosition="top"
|
|
446
440
|
(click)="$event.stopPropagation(); editClick.emit(task())"
|
|
447
441
|
>
|
|
448
|
-
<
|
|
442
|
+
<ui-icon name="pencil" class="text-xs"></ui-icon>
|
|
449
443
|
</button>
|
|
450
444
|
<button
|
|
451
|
-
class="w-6 h-6 flex items-center justify-center rounded text-surface-400 hover:text-red-500 hover:bg-surface-
|
|
452
|
-
[
|
|
445
|
+
class="w-6 h-6 flex items-center justify-center rounded text-surface-400 hover:text-red-500 hover:bg-surface-hover transition-colors"
|
|
446
|
+
[fTooltip]="'shared.delete' | translate"
|
|
453
447
|
tooltipPosition="top"
|
|
454
448
|
(click)="$event.stopPropagation(); deleteClick.emit(task())"
|
|
455
449
|
>
|
|
456
|
-
<
|
|
450
|
+
<ui-icon name="trash" class="text-xs"></ui-icon>
|
|
457
451
|
</button>
|
|
458
452
|
</div>
|
|
459
453
|
|
|
@@ -463,7 +457,7 @@ class TaskCardComponent {
|
|
|
463
457
|
<span
|
|
464
458
|
class="inline-block h-1.5 rounded-full w-8"
|
|
465
459
|
[style.background-color]="label.color"
|
|
466
|
-
[
|
|
460
|
+
[fTooltip]="label.name"
|
|
467
461
|
></span>
|
|
468
462
|
}
|
|
469
463
|
</div>
|
|
@@ -474,15 +468,15 @@ class TaskCardComponent {
|
|
|
474
468
|
</p>
|
|
475
469
|
|
|
476
470
|
<div class="flex items-center justify-between gap-2 mt-auto pt-2">
|
|
477
|
-
<
|
|
471
|
+
<f-tag
|
|
478
472
|
[value]="task().priority"
|
|
479
473
|
[severity]="prioritySeverity(task().priority)"
|
|
480
|
-
|
|
474
|
+
class="text-xs"
|
|
481
475
|
/>
|
|
482
476
|
|
|
483
477
|
@if (task().dueDate) {
|
|
484
478
|
<span
|
|
485
|
-
class="text-xs text-
|
|
479
|
+
class="text-xs text-muted-color"
|
|
486
480
|
[class.text-red-500]="isOverdue(task().dueDate!)"
|
|
487
481
|
>
|
|
488
482
|
{{ task().dueDate | date: 'MMM d' }}
|
|
@@ -492,53 +486,55 @@ class TaskCardComponent {
|
|
|
492
486
|
@if (visibleAssignees().length > 0) {
|
|
493
487
|
<div class="flex items-center -space-x-1.5">
|
|
494
488
|
@for (a of visibleAssignees(); track a.userId) {
|
|
495
|
-
<
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
[
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
489
|
+
<f-avatar
|
|
490
|
+
shape="circle"
|
|
491
|
+
size="small"
|
|
492
|
+
[label]="initials(a.userName)"
|
|
493
|
+
[color]="memberColor(a.userId)"
|
|
494
|
+
styleClass="!ring-surface-card flex-shrink-0"
|
|
495
|
+
[fTooltip]="a.userName ?? ''"
|
|
496
|
+
/>
|
|
502
497
|
}
|
|
503
498
|
@if (overflowCount() > 0) {
|
|
504
|
-
<
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
+
|
|
508
|
-
|
|
499
|
+
<f-avatar
|
|
500
|
+
shape="circle"
|
|
501
|
+
size="small"
|
|
502
|
+
[label]="'+' + overflowCount()"
|
|
503
|
+
styleClass="!bg-surface-200 dark:!bg-surface-700 !text-surface-600 dark:!text-surface-300 !ring-surface-card flex-shrink-0"
|
|
504
|
+
/>
|
|
509
505
|
}
|
|
510
506
|
</div>
|
|
511
507
|
}
|
|
512
508
|
</div>
|
|
513
509
|
</div>
|
|
514
|
-
`, isInline: true, dependencies: [{ kind: "
|
|
510
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay"] }, { kind: "ngmodule", type: UiModule }, { kind: "component", type: i1.AvatarComponent, selector: "f-avatar", inputs: ["label", "icon", "image", "shape", "size", "color", "styleClass"] }, { kind: "component", type: i1.TagComponent, selector: "f-tag", inputs: ["value", "severity", "icon", "rounded", "color"] }, { kind: "component", type: i1.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
515
511
|
}
|
|
516
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
512
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskCardComponent, decorators: [{
|
|
517
513
|
type: Component,
|
|
518
514
|
args: [{
|
|
519
515
|
selector: 'tm-task-card',
|
|
520
|
-
imports: [
|
|
516
|
+
imports: [DatePipe, TranslatePipe, TooltipDirective, UiModule],
|
|
521
517
|
template: `
|
|
522
518
|
<div
|
|
523
|
-
class="task-card group relative rounded-
|
|
519
|
+
class="task-card group relative rounded-border border border-surface p-3 cursor-pointer shadow-sm hover:shadow-md transition-shadow"
|
|
524
520
|
(click)="cardClick.emit(task())"
|
|
525
521
|
>
|
|
526
522
|
<div class="absolute top-2 right-2 hidden group-hover:flex gap-0.5">
|
|
527
523
|
<button
|
|
528
|
-
class="w-6 h-6 flex items-center justify-center rounded text-surface-400 hover:text-primary-500 hover:bg-surface-
|
|
529
|
-
[
|
|
524
|
+
class="w-6 h-6 flex items-center justify-center rounded text-surface-400 hover:text-primary-500 hover:bg-surface-hover transition-colors"
|
|
525
|
+
[fTooltip]="'shared.edit' | translate"
|
|
530
526
|
tooltipPosition="top"
|
|
531
527
|
(click)="$event.stopPropagation(); editClick.emit(task())"
|
|
532
528
|
>
|
|
533
|
-
<
|
|
529
|
+
<ui-icon name="pencil" class="text-xs"></ui-icon>
|
|
534
530
|
</button>
|
|
535
531
|
<button
|
|
536
|
-
class="w-6 h-6 flex items-center justify-center rounded text-surface-400 hover:text-red-500 hover:bg-surface-
|
|
537
|
-
[
|
|
532
|
+
class="w-6 h-6 flex items-center justify-center rounded text-surface-400 hover:text-red-500 hover:bg-surface-hover transition-colors"
|
|
533
|
+
[fTooltip]="'shared.delete' | translate"
|
|
538
534
|
tooltipPosition="top"
|
|
539
535
|
(click)="$event.stopPropagation(); deleteClick.emit(task())"
|
|
540
536
|
>
|
|
541
|
-
<
|
|
537
|
+
<ui-icon name="trash" class="text-xs"></ui-icon>
|
|
542
538
|
</button>
|
|
543
539
|
</div>
|
|
544
540
|
|
|
@@ -548,7 +544,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
548
544
|
<span
|
|
549
545
|
class="inline-block h-1.5 rounded-full w-8"
|
|
550
546
|
[style.background-color]="label.color"
|
|
551
|
-
[
|
|
547
|
+
[fTooltip]="label.name"
|
|
552
548
|
></span>
|
|
553
549
|
}
|
|
554
550
|
</div>
|
|
@@ -559,15 +555,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
559
555
|
</p>
|
|
560
556
|
|
|
561
557
|
<div class="flex items-center justify-between gap-2 mt-auto pt-2">
|
|
562
|
-
<
|
|
558
|
+
<f-tag
|
|
563
559
|
[value]="task().priority"
|
|
564
560
|
[severity]="prioritySeverity(task().priority)"
|
|
565
|
-
|
|
561
|
+
class="text-xs"
|
|
566
562
|
/>
|
|
567
563
|
|
|
568
564
|
@if (task().dueDate) {
|
|
569
565
|
<span
|
|
570
|
-
class="text-xs text-
|
|
566
|
+
class="text-xs text-muted-color"
|
|
571
567
|
[class.text-red-500]="isOverdue(task().dueDate!)"
|
|
572
568
|
>
|
|
573
569
|
{{ task().dueDate | date: 'MMM d' }}
|
|
@@ -577,20 +573,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
577
573
|
@if (visibleAssignees().length > 0) {
|
|
578
574
|
<div class="flex items-center -space-x-1.5">
|
|
579
575
|
@for (a of visibleAssignees(); track a.userId) {
|
|
580
|
-
<
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
[
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
576
|
+
<f-avatar
|
|
577
|
+
shape="circle"
|
|
578
|
+
size="small"
|
|
579
|
+
[label]="initials(a.userName)"
|
|
580
|
+
[color]="memberColor(a.userId)"
|
|
581
|
+
styleClass="!ring-surface-card flex-shrink-0"
|
|
582
|
+
[fTooltip]="a.userName ?? ''"
|
|
583
|
+
/>
|
|
587
584
|
}
|
|
588
585
|
@if (overflowCount() > 0) {
|
|
589
|
-
<
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
+
|
|
593
|
-
|
|
586
|
+
<f-avatar
|
|
587
|
+
shape="circle"
|
|
588
|
+
size="small"
|
|
589
|
+
[label]="'+' + overflowCount()"
|
|
590
|
+
styleClass="!bg-surface-200 dark:!bg-surface-700 !text-surface-600 dark:!text-surface-300 !ring-surface-card flex-shrink-0"
|
|
591
|
+
/>
|
|
594
592
|
}
|
|
595
593
|
</div>
|
|
596
594
|
}
|
|
@@ -601,21 +599,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
601
599
|
}], propDecorators: { task: [{ type: i0.Input, args: [{ isSignal: true, alias: "task", required: true }] }], cardClick: [{ type: i0.Output, args: ["cardClick"] }], editClick: [{ type: i0.Output, args: ["editClick"] }], deleteClick: [{ type: i0.Output, args: ["deleteClick"] }] } });
|
|
602
600
|
|
|
603
601
|
const PRIORITY_OPTIONS = [
|
|
604
|
-
{
|
|
605
|
-
{
|
|
606
|
-
{
|
|
607
|
-
{
|
|
602
|
+
{ labelKey: 'task.priority.LOW', value: 'LOW' },
|
|
603
|
+
{ labelKey: 'task.priority.MEDIUM', value: 'MEDIUM' },
|
|
604
|
+
{ labelKey: 'task.priority.HIGH', value: 'HIGH' },
|
|
605
|
+
{ labelKey: 'task.priority.URGENT', value: 'URGENT' },
|
|
608
606
|
];
|
|
609
607
|
class TaskFormDialogComponent {
|
|
610
608
|
taskApi = inject(TaskApiService);
|
|
611
|
-
visible = model(false,
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
609
|
+
visible = model(false, /* @ts-ignore */
|
|
610
|
+
...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
611
|
+
task = input(null, /* @ts-ignore */
|
|
612
|
+
...(ngDevMode ? [{ debugName: "task" }] : /* istanbul ignore next */ []));
|
|
613
|
+
boardId = input.required(/* @ts-ignore */
|
|
614
|
+
...(ngDevMode ? [{ debugName: "boardId" }] : /* istanbul ignore next */ []));
|
|
615
|
+
listId = input.required(/* @ts-ignore */
|
|
616
|
+
...(ngDevMode ? [{ debugName: "listId" }] : /* istanbul ignore next */ []));
|
|
617
|
+
members = input([], /* @ts-ignore */
|
|
618
|
+
...(ngDevMode ? [{ debugName: "members" }] : /* istanbul ignore next */ []));
|
|
619
|
+
labels = input([], /* @ts-ignore */
|
|
620
|
+
...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
|
|
617
621
|
saved = output();
|
|
618
|
-
isSaving = signal(false,
|
|
622
|
+
isSaving = signal(false, /* @ts-ignore */
|
|
623
|
+
...(ngDevMode ? [{ debugName: "isSaving" }] : /* istanbul ignore next */ []));
|
|
619
624
|
priorityOptions = PRIORITY_OPTIONS;
|
|
620
625
|
title = '';
|
|
621
626
|
description = '';
|
|
@@ -695,9 +700,9 @@ class TaskFormDialogComponent {
|
|
|
695
700
|
this.selectedAssigneeIds = [];
|
|
696
701
|
this.selectedLabelIds = [];
|
|
697
702
|
}
|
|
698
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
699
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
700
|
-
<
|
|
703
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskFormDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
704
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TaskFormDialogComponent, isStandalone: true, selector: "tm-task-form-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, task: { classPropertyName: "task", publicName: "task", isSignal: true, isRequired: false, transformFunction: null }, boardId: { classPropertyName: "boardId", publicName: "boardId", isSignal: true, isRequired: true, transformFunction: null }, listId: { classPropertyName: "listId", publicName: "listId", isSignal: true, isRequired: true, transformFunction: null }, members: { classPropertyName: "members", publicName: "members", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", saved: "saved" }, ngImport: i0, template: `
|
|
705
|
+
<f-dialog
|
|
701
706
|
[header]="
|
|
702
707
|
(task() ? 'task.form.title.edit' : 'task.form.title.create') | translate
|
|
703
708
|
"
|
|
@@ -713,7 +718,7 @@ class TaskFormDialogComponent {
|
|
|
713
718
|
<span class="text-red-500">*</span></label
|
|
714
719
|
>
|
|
715
720
|
<input
|
|
716
|
-
|
|
721
|
+
fInputText
|
|
717
722
|
[(ngModel)]="title"
|
|
718
723
|
[placeholder]="'task.form.title.placeholder' | translate"
|
|
719
724
|
/>
|
|
@@ -724,7 +729,7 @@ class TaskFormDialogComponent {
|
|
|
724
729
|
'shared.description' | translate
|
|
725
730
|
}}</label>
|
|
726
731
|
<textarea
|
|
727
|
-
|
|
732
|
+
fTextarea
|
|
728
733
|
[(ngModel)]="description"
|
|
729
734
|
rows="3"
|
|
730
735
|
[placeholder]="'task.form.description.placeholder' | translate"
|
|
@@ -736,27 +741,27 @@ class TaskFormDialogComponent {
|
|
|
736
741
|
<label class="text-sm font-medium">{{
|
|
737
742
|
'task.form.priority.label' | translate
|
|
738
743
|
}}</label>
|
|
739
|
-
<
|
|
744
|
+
<f-select
|
|
740
745
|
[(ngModel)]="priority"
|
|
741
746
|
[options]="priorityOptions"
|
|
742
|
-
optionLabel="
|
|
747
|
+
optionLabel="labelKey"
|
|
743
748
|
optionValue="value"
|
|
744
749
|
[placeholder]="'task.form.priority.placeholder' | translate"
|
|
745
750
|
>
|
|
746
751
|
<ng-template #selectedItem let-opt>
|
|
747
|
-
{{ opt.
|
|
752
|
+
{{ opt.labelKey | translate }}
|
|
748
753
|
</ng-template>
|
|
749
754
|
<ng-template #item let-opt>
|
|
750
|
-
{{ opt.
|
|
755
|
+
{{ opt.labelKey | translate }}
|
|
751
756
|
</ng-template>
|
|
752
|
-
</
|
|
757
|
+
</f-select>
|
|
753
758
|
</div>
|
|
754
759
|
|
|
755
760
|
<div class="flex flex-col gap-1">
|
|
756
761
|
<label class="text-sm font-medium">{{
|
|
757
762
|
'task.form.due.date.label' | translate
|
|
758
763
|
}}</label>
|
|
759
|
-
<
|
|
764
|
+
<f-datepicker
|
|
760
765
|
[(ngModel)]="dueDate"
|
|
761
766
|
[showClear]="true"
|
|
762
767
|
[placeholder]="'task.form.due.date.placeholder' | translate"
|
|
@@ -768,12 +773,11 @@ class TaskFormDialogComponent {
|
|
|
768
773
|
<label class="text-sm font-medium">{{
|
|
769
774
|
'task.form.assignee.label' | translate
|
|
770
775
|
}}</label>
|
|
771
|
-
<
|
|
776
|
+
<f-multiselect
|
|
772
777
|
[(ngModel)]="selectedAssigneeIds"
|
|
773
778
|
[options]="members()"
|
|
774
779
|
optionLabel="userName"
|
|
775
780
|
optionValue="userId"
|
|
776
|
-
appendTo="body"
|
|
777
781
|
[placeholder]="'task.form.assignee.placeholder' | translate"
|
|
778
782
|
[showClear]="true"
|
|
779
783
|
/>
|
|
@@ -783,51 +787,39 @@ class TaskFormDialogComponent {
|
|
|
783
787
|
<label class="text-sm font-medium">{{
|
|
784
788
|
'task.form.labels.label' | translate
|
|
785
789
|
}}</label>
|
|
786
|
-
<
|
|
790
|
+
<f-multiselect
|
|
787
791
|
[(ngModel)]="selectedLabelIds"
|
|
788
792
|
[options]="labels()"
|
|
789
793
|
optionLabel="name"
|
|
790
794
|
optionValue="id"
|
|
791
|
-
appendTo="body"
|
|
792
795
|
[placeholder]="'task.form.labels.placeholder' | translate"
|
|
793
796
|
/>
|
|
794
797
|
</div>
|
|
795
798
|
</div>
|
|
796
799
|
|
|
797
|
-
<ng-template
|
|
800
|
+
<ng-template #footer>
|
|
798
801
|
<div class="flex justify-end gap-2 pt-1">
|
|
799
|
-
<
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
/>
|
|
802
|
+
<button fButton severity="secondary" (click)="onClose()">
|
|
803
|
+
<span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
|
|
804
|
+
</button>
|
|
805
|
+
<button fButton (click)="onSave()" [disabled]="isSaving()">
|
|
806
|
+
@if (isSaving()) {
|
|
807
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
808
|
+
}
|
|
809
|
+
<span pButtonLabel>{{ 'shared.save' | translate }}</span>
|
|
810
|
+
</button>
|
|
809
811
|
</div>
|
|
810
812
|
</ng-template>
|
|
811
|
-
</
|
|
812
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type:
|
|
813
|
+
</f-dialog>
|
|
814
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: UiModule }, { kind: "directive", type: i1.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "rounded", "raised", "fluid", "disabled", "loading", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i1.DatePickerComponent, selector: "f-datepicker", inputs: ["placeholder", "dateFormat", "disabled", "showTime", "selectionMode", "minDate", "maxDate", "inputId", "invalid", "touched", "showClear", "inputStyleClass", "showIcon", "showButtonBar", "appendTo", "styleClass"], outputs: ["onBlur"] }, { kind: "directive", type: i1.InputTextDirective, selector: "[fInputText]", inputs: ["invalid", "touched"] }, { kind: "component", type: i1.MultiSelectComponent, selector: "f-multiselect", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "inputId", "invalid", "touched", "showClear", "optionDisabled", "display", "maxSelectedLabels", "selectionLimit", "showToggleAll", "styleClass"], outputs: ["onBlur"] }, { kind: "component", type: i1.SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "showClear", "loading", "inputId", "invalid", "touched", "styleClass", "editable"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur"] }, { kind: "directive", type: i1.TextareaDirective, selector: "[fTextarea]", inputs: ["invalid", "touched"] }, { kind: "component", type: i1.DialogComponent, selector: "f-dialog", inputs: ["header", "visible", "modal", "closable", "dismissableMask", "resizable", "style", "breakpoints"], outputs: ["visibleChange", "onShow", "onHide"] }, { kind: "component", type: i1.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
813
815
|
}
|
|
814
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
816
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskFormDialogComponent, decorators: [{
|
|
815
817
|
type: Component,
|
|
816
818
|
args: [{
|
|
817
819
|
selector: 'tm-task-form-dialog',
|
|
818
|
-
imports: [
|
|
819
|
-
DialogModule,
|
|
820
|
-
FormsModule,
|
|
821
|
-
InputTextModule,
|
|
822
|
-
TextareaModule,
|
|
823
|
-
SelectModule,
|
|
824
|
-
DatePickerModule,
|
|
825
|
-
MultiSelectModule,
|
|
826
|
-
ButtonModule,
|
|
827
|
-
TranslatePipe,
|
|
828
|
-
],
|
|
820
|
+
imports: [UiModule, FormsModule, TranslatePipe],
|
|
829
821
|
template: `
|
|
830
|
-
<
|
|
822
|
+
<f-dialog
|
|
831
823
|
[header]="
|
|
832
824
|
(task() ? 'task.form.title.edit' : 'task.form.title.create') | translate
|
|
833
825
|
"
|
|
@@ -843,7 +835,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
843
835
|
<span class="text-red-500">*</span></label
|
|
844
836
|
>
|
|
845
837
|
<input
|
|
846
|
-
|
|
838
|
+
fInputText
|
|
847
839
|
[(ngModel)]="title"
|
|
848
840
|
[placeholder]="'task.form.title.placeholder' | translate"
|
|
849
841
|
/>
|
|
@@ -854,7 +846,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
854
846
|
'shared.description' | translate
|
|
855
847
|
}}</label>
|
|
856
848
|
<textarea
|
|
857
|
-
|
|
849
|
+
fTextarea
|
|
858
850
|
[(ngModel)]="description"
|
|
859
851
|
rows="3"
|
|
860
852
|
[placeholder]="'task.form.description.placeholder' | translate"
|
|
@@ -866,27 +858,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
866
858
|
<label class="text-sm font-medium">{{
|
|
867
859
|
'task.form.priority.label' | translate
|
|
868
860
|
}}</label>
|
|
869
|
-
<
|
|
861
|
+
<f-select
|
|
870
862
|
[(ngModel)]="priority"
|
|
871
863
|
[options]="priorityOptions"
|
|
872
|
-
optionLabel="
|
|
864
|
+
optionLabel="labelKey"
|
|
873
865
|
optionValue="value"
|
|
874
866
|
[placeholder]="'task.form.priority.placeholder' | translate"
|
|
875
867
|
>
|
|
876
868
|
<ng-template #selectedItem let-opt>
|
|
877
|
-
{{ opt.
|
|
869
|
+
{{ opt.labelKey | translate }}
|
|
878
870
|
</ng-template>
|
|
879
871
|
<ng-template #item let-opt>
|
|
880
|
-
{{ opt.
|
|
872
|
+
{{ opt.labelKey | translate }}
|
|
881
873
|
</ng-template>
|
|
882
|
-
</
|
|
874
|
+
</f-select>
|
|
883
875
|
</div>
|
|
884
876
|
|
|
885
877
|
<div class="flex flex-col gap-1">
|
|
886
878
|
<label class="text-sm font-medium">{{
|
|
887
879
|
'task.form.due.date.label' | translate
|
|
888
880
|
}}</label>
|
|
889
|
-
<
|
|
881
|
+
<f-datepicker
|
|
890
882
|
[(ngModel)]="dueDate"
|
|
891
883
|
[showClear]="true"
|
|
892
884
|
[placeholder]="'task.form.due.date.placeholder' | translate"
|
|
@@ -898,12 +890,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
898
890
|
<label class="text-sm font-medium">{{
|
|
899
891
|
'task.form.assignee.label' | translate
|
|
900
892
|
}}</label>
|
|
901
|
-
<
|
|
893
|
+
<f-multiselect
|
|
902
894
|
[(ngModel)]="selectedAssigneeIds"
|
|
903
895
|
[options]="members()"
|
|
904
896
|
optionLabel="userName"
|
|
905
897
|
optionValue="userId"
|
|
906
|
-
appendTo="body"
|
|
907
898
|
[placeholder]="'task.form.assignee.placeholder' | translate"
|
|
908
899
|
[showClear]="true"
|
|
909
900
|
/>
|
|
@@ -913,32 +904,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
913
904
|
<label class="text-sm font-medium">{{
|
|
914
905
|
'task.form.labels.label' | translate
|
|
915
906
|
}}</label>
|
|
916
|
-
<
|
|
907
|
+
<f-multiselect
|
|
917
908
|
[(ngModel)]="selectedLabelIds"
|
|
918
909
|
[options]="labels()"
|
|
919
910
|
optionLabel="name"
|
|
920
911
|
optionValue="id"
|
|
921
|
-
appendTo="body"
|
|
922
912
|
[placeholder]="'task.form.labels.placeholder' | translate"
|
|
923
913
|
/>
|
|
924
914
|
</div>
|
|
925
915
|
</div>
|
|
926
916
|
|
|
927
|
-
<ng-template
|
|
917
|
+
<ng-template #footer>
|
|
928
918
|
<div class="flex justify-end gap-2 pt-1">
|
|
929
|
-
<
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
/>
|
|
919
|
+
<button fButton severity="secondary" (click)="onClose()">
|
|
920
|
+
<span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
|
|
921
|
+
</button>
|
|
922
|
+
<button fButton (click)="onSave()" [disabled]="isSaving()">
|
|
923
|
+
@if (isSaving()) {
|
|
924
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
925
|
+
}
|
|
926
|
+
<span pButtonLabel>{{ 'shared.save' | translate }}</span>
|
|
927
|
+
</button>
|
|
939
928
|
</div>
|
|
940
929
|
</ng-template>
|
|
941
|
-
</
|
|
930
|
+
</f-dialog>
|
|
942
931
|
`,
|
|
943
932
|
}]
|
|
944
933
|
}], ctorParameters: () => [], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], task: [{ type: i0.Input, args: [{ isSignal: true, alias: "task", required: false }] }], boardId: [{ type: i0.Input, args: [{ isSignal: true, alias: "boardId", required: true }] }], listId: [{ type: i0.Input, args: [{ isSignal: true, alias: "listId", required: true }] }], members: [{ type: i0.Input, args: [{ isSignal: true, alias: "members", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], saved: [{ type: i0.Output, args: ["saved"] }] } });
|
|
@@ -946,18 +935,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
946
935
|
class TaskDetailPanelComponent {
|
|
947
936
|
commentApi = inject(TaskCommentApiService);
|
|
948
937
|
state = inject(TaskBoardStateService);
|
|
949
|
-
task = input(null,
|
|
938
|
+
task = input(null, /* @ts-ignore */
|
|
939
|
+
...(ngDevMode ? [{ debugName: "task" }] : /* istanbul ignore next */ []));
|
|
950
940
|
closePanel = output();
|
|
951
941
|
editTask = output();
|
|
952
|
-
comments = signal([],
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
942
|
+
comments = signal([], /* @ts-ignore */
|
|
943
|
+
...(ngDevMode ? [{ debugName: "comments" }] : /* istanbul ignore next */ []));
|
|
944
|
+
isSendingComment = signal(false, /* @ts-ignore */
|
|
945
|
+
...(ngDevMode ? [{ debugName: "isSendingComment" }] : /* istanbul ignore next */ []));
|
|
946
|
+
isSendingReply = signal(false, /* @ts-ignore */
|
|
947
|
+
...(ngDevMode ? [{ debugName: "isSendingReply" }] : /* istanbul ignore next */ []));
|
|
948
|
+
replyingToId = signal(null, /* @ts-ignore */
|
|
949
|
+
...(ngDevMode ? [{ debugName: "replyingToId" }] : /* istanbul ignore next */ []));
|
|
950
|
+
isDeleting = signal(false, /* @ts-ignore */
|
|
951
|
+
...(ngDevMode ? [{ debugName: "isDeleting" }] : /* istanbul ignore next */ []));
|
|
957
952
|
newComment = '';
|
|
958
953
|
replyText = '';
|
|
959
|
-
assigneeMembers = computed(() => this.task()?.assignees ?? [],
|
|
960
|
-
|
|
954
|
+
assigneeMembers = computed(() => this.task()?.assignees ?? [], /* @ts-ignore */
|
|
955
|
+
...(ngDevMode ? [{ debugName: "assigneeMembers" }] : /* istanbul ignore next */ []));
|
|
956
|
+
rootComments = computed(() => this.comments().filter((c) => !c.parentCommentId), /* @ts-ignore */
|
|
957
|
+
...(ngDevMode ? [{ debugName: "rootComments" }] : /* istanbul ignore next */ []));
|
|
961
958
|
repliesFor(parentId) {
|
|
962
959
|
return this.comments().filter((c) => c.parentCommentId === parentId);
|
|
963
960
|
}
|
|
@@ -1036,9 +1033,9 @@ class TaskDetailPanelComponent {
|
|
|
1036
1033
|
this.isSendingReply.set(false);
|
|
1037
1034
|
}
|
|
1038
1035
|
}
|
|
1039
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1040
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
1041
|
-
<
|
|
1036
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskDetailPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1037
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TaskDetailPanelComponent, isStandalone: true, selector: "tm-task-detail-panel", inputs: { task: { classPropertyName: "task", publicName: "task", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closePanel: "closePanel", editTask: "editTask" }, ngImport: i0, template: `
|
|
1038
|
+
<f-drawer
|
|
1042
1039
|
[visible]="!!task()"
|
|
1043
1040
|
position="right"
|
|
1044
1041
|
[style]="{ width: '500px' }"
|
|
@@ -1048,34 +1045,42 @@ class TaskDetailPanelComponent {
|
|
|
1048
1045
|
@if (task(); as t) {
|
|
1049
1046
|
<div class="flex flex-col gap-6 h-full overflow-y-auto pb-4">
|
|
1050
1047
|
<div class="flex items-center justify-end gap-1">
|
|
1051
|
-
<
|
|
1052
|
-
|
|
1048
|
+
<button
|
|
1049
|
+
fButton
|
|
1053
1050
|
severity="secondary"
|
|
1054
1051
|
size="small"
|
|
1055
1052
|
[text]="true"
|
|
1056
|
-
[
|
|
1053
|
+
[fTooltip]="'task.detail.edit' | translate"
|
|
1057
1054
|
tooltipPosition="left"
|
|
1058
|
-
(
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1055
|
+
(click)="editTask.emit(t)"
|
|
1056
|
+
>
|
|
1057
|
+
<ui-icon pButtonIcon name="pencil"></ui-icon>
|
|
1058
|
+
</button>
|
|
1059
|
+
<button
|
|
1060
|
+
fButton
|
|
1062
1061
|
severity="danger"
|
|
1063
1062
|
size="small"
|
|
1064
1063
|
[text]="true"
|
|
1065
|
-
[
|
|
1066
|
-
[pTooltip]="'task.detail.delete' | translate"
|
|
1064
|
+
[fTooltip]="'task.detail.delete' | translate"
|
|
1067
1065
|
tooltipPosition="left"
|
|
1068
|
-
(
|
|
1069
|
-
|
|
1066
|
+
(click)="deleteTask(t.id)"
|
|
1067
|
+
[disabled]="isDeleting()"
|
|
1068
|
+
>
|
|
1069
|
+
@if (isDeleting()) {
|
|
1070
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
1071
|
+
} @else {
|
|
1072
|
+
<ui-icon pButtonIcon name="trash"></ui-icon>
|
|
1073
|
+
}
|
|
1074
|
+
</button>
|
|
1070
1075
|
</div>
|
|
1071
1076
|
|
|
1072
1077
|
<div class="flex items-center gap-3">
|
|
1073
|
-
<
|
|
1078
|
+
<f-tag
|
|
1074
1079
|
[value]="t.priority"
|
|
1075
1080
|
[severity]="prioritySeverity(t.priority)"
|
|
1076
1081
|
/>
|
|
1077
1082
|
@if (t.dueDate) {
|
|
1078
|
-
<span class="text-sm text-
|
|
1083
|
+
<span class="text-sm text-muted-color">
|
|
1079
1084
|
{{ 'task.detail.due.label' | translate }}:
|
|
1080
1085
|
{{ t.dueDate | date: 'mediumDate' }}
|
|
1081
1086
|
</span>
|
|
@@ -1090,11 +1095,12 @@ class TaskDetailPanelComponent {
|
|
|
1090
1095
|
<div class="flex flex-wrap gap-2">
|
|
1091
1096
|
@for (member of assigneeMembers(); track member.userId) {
|
|
1092
1097
|
<div class="flex items-center gap-2 px-2 py-1 rounded-full ">
|
|
1093
|
-
<
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
+
<f-avatar
|
|
1099
|
+
shape="circle"
|
|
1100
|
+
size="small"
|
|
1101
|
+
[label]="initials(member.userName)"
|
|
1102
|
+
styleClass="!bg-primary-100 dark:!bg-primary-900 !text-primary-700 dark:!text-primary-300"
|
|
1103
|
+
/>
|
|
1098
1104
|
<span class="text-sm">{{ member.userName }}</span>
|
|
1099
1105
|
</div>
|
|
1100
1106
|
}
|
|
@@ -1106,9 +1112,7 @@ class TaskDetailPanelComponent {
|
|
|
1106
1112
|
<h4 class="text-sm font-semibold mb-2">
|
|
1107
1113
|
{{ 'shared.description' | translate }}
|
|
1108
1114
|
</h4>
|
|
1109
|
-
<p
|
|
1110
|
-
class="text-sm text-surface-600 dark:text-surface-400 whitespace-pre-wrap"
|
|
1111
|
-
>
|
|
1115
|
+
<p class="text-sm text-color whitespace-pre-wrap">
|
|
1112
1116
|
{{
|
|
1113
1117
|
t.description || ('task.detail.description.empty' | translate)
|
|
1114
1118
|
}}
|
|
@@ -1124,31 +1128,33 @@ class TaskDetailPanelComponent {
|
|
|
1124
1128
|
|
|
1125
1129
|
@for (comment of rootComments(); track comment.id) {
|
|
1126
1130
|
<div
|
|
1127
|
-
class="group flex flex-col gap-1 py-2 border-b border-surface
|
|
1131
|
+
class="group flex flex-col gap-1 py-2 border-b border-surface last:border-0"
|
|
1128
1132
|
>
|
|
1129
1133
|
<div class="flex items-center justify-between">
|
|
1130
|
-
<span class="text-xs text-
|
|
1134
|
+
<span class="text-xs text-muted-color">{{
|
|
1131
1135
|
comment.createdAt | date: 'MMM d, y, h:mm a'
|
|
1132
1136
|
}}</span>
|
|
1133
|
-
<
|
|
1134
|
-
|
|
1135
|
-
icon="pi pi-reply"
|
|
1137
|
+
<button
|
|
1138
|
+
fButton
|
|
1136
1139
|
size="small"
|
|
1137
1140
|
[text]="true"
|
|
1138
1141
|
severity="secondary"
|
|
1139
|
-
|
|
1140
|
-
(
|
|
1141
|
-
|
|
1142
|
+
class="opacity-0 group-hover:opacity-100 transition-opacity !py-0.5 !px-1.5 text-xs"
|
|
1143
|
+
(click)="toggleReply(comment.id)"
|
|
1144
|
+
>
|
|
1145
|
+
<ui-icon pButtonIcon name="reply"></ui-icon>
|
|
1146
|
+
<span pButtonLabel>{{ 'task.comment.reply' | translate }}</span>
|
|
1147
|
+
</button>
|
|
1142
1148
|
</div>
|
|
1143
1149
|
<p class="text-sm">{{ comment.content }}</p>
|
|
1144
1150
|
|
|
1145
1151
|
@if (repliesFor(comment.id).length > 0) {
|
|
1146
1152
|
<div
|
|
1147
|
-
class="mt-1 pl-3 border-l-2 border-surface
|
|
1153
|
+
class="mt-1 pl-3 border-l-2 border-surface flex flex-col gap-2"
|
|
1148
1154
|
>
|
|
1149
1155
|
@for (reply of repliesFor(comment.id); track reply.id) {
|
|
1150
1156
|
<div class="flex flex-col gap-0.5">
|
|
1151
|
-
<span class="text-xs text-
|
|
1157
|
+
<span class="text-xs text-muted-color">{{
|
|
1152
1158
|
reply.createdAt | date: 'MMM d, y, h:mm a'
|
|
1153
1159
|
}}</span>
|
|
1154
1160
|
<p class="text-sm">{{ reply.content }}</p>
|
|
@@ -1162,7 +1168,7 @@ class TaskDetailPanelComponent {
|
|
|
1162
1168
|
class="mt-2 pl-3 border-l-2 border-primary-300 dark:border-primary-700 flex gap-2"
|
|
1163
1169
|
>
|
|
1164
1170
|
<textarea
|
|
1165
|
-
|
|
1171
|
+
fTextarea
|
|
1166
1172
|
[(ngModel)]="replyText"
|
|
1167
1173
|
rows="2"
|
|
1168
1174
|
[placeholder]="
|
|
@@ -1172,20 +1178,27 @@ class TaskDetailPanelComponent {
|
|
|
1172
1178
|
autoResize="true"
|
|
1173
1179
|
></textarea>
|
|
1174
1180
|
<div class="flex flex-col gap-1">
|
|
1175
|
-
<
|
|
1176
|
-
|
|
1181
|
+
<button
|
|
1182
|
+
fButton
|
|
1177
1183
|
size="small"
|
|
1178
|
-
[
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
+
[disabled]="!replyText.trim() || isSendingReply()"
|
|
1185
|
+
(click)="submitReply(t.id, comment.id)"
|
|
1186
|
+
>
|
|
1187
|
+
@if (isSendingReply()) {
|
|
1188
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
1189
|
+
} @else {
|
|
1190
|
+
<ui-icon pButtonIcon name="send"></ui-icon>
|
|
1191
|
+
}
|
|
1192
|
+
</button>
|
|
1193
|
+
<button
|
|
1194
|
+
fButton
|
|
1184
1195
|
size="small"
|
|
1185
1196
|
severity="secondary"
|
|
1186
1197
|
[text]="true"
|
|
1187
|
-
(
|
|
1188
|
-
|
|
1198
|
+
(click)="cancelReply()"
|
|
1199
|
+
>
|
|
1200
|
+
<ui-icon pButtonIcon name="times"></ui-icon>
|
|
1201
|
+
</button>
|
|
1189
1202
|
</div>
|
|
1190
1203
|
</div>
|
|
1191
1204
|
}
|
|
@@ -1193,48 +1206,46 @@ class TaskDetailPanelComponent {
|
|
|
1193
1206
|
}
|
|
1194
1207
|
|
|
1195
1208
|
@if (rootComments().length === 0) {
|
|
1196
|
-
<p class="text-sm text-
|
|
1209
|
+
<p class="text-sm text-muted-color py-2">
|
|
1197
1210
|
{{ 'task.detail.comments.empty' | translate }}
|
|
1198
1211
|
</p>
|
|
1199
1212
|
}
|
|
1200
1213
|
|
|
1201
1214
|
<div class="flex gap-2 mt-3">
|
|
1202
1215
|
<textarea
|
|
1203
|
-
|
|
1216
|
+
fTextarea
|
|
1204
1217
|
[(ngModel)]="newComment"
|
|
1205
1218
|
rows="2"
|
|
1206
1219
|
[placeholder]="'task.detail.comment.placeholder' | translate"
|
|
1207
1220
|
class="flex-1 resize-none"
|
|
1208
1221
|
></textarea>
|
|
1209
|
-
<
|
|
1210
|
-
|
|
1211
|
-
[
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1222
|
+
<button
|
|
1223
|
+
fButton
|
|
1224
|
+
[disabled]="!newComment.trim() || isSendingComment()"
|
|
1225
|
+
(click)="addComment(t.id)"
|
|
1226
|
+
>
|
|
1227
|
+
@if (isSendingComment()) {
|
|
1228
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
1229
|
+
} @else {
|
|
1230
|
+
<ui-icon pButtonIcon name="send"></ui-icon>
|
|
1231
|
+
}
|
|
1232
|
+
</button>
|
|
1215
1233
|
</div>
|
|
1216
1234
|
</div>
|
|
1217
1235
|
</div>
|
|
1218
1236
|
}
|
|
1219
|
-
</
|
|
1220
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type:
|
|
1237
|
+
</f-drawer>
|
|
1238
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: UiModule }, { kind: "component", type: i1.AvatarComponent, selector: "f-avatar", inputs: ["label", "icon", "image", "shape", "size", "color", "styleClass"] }, { kind: "directive", type: i1.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "rounded", "raised", "fluid", "disabled", "loading", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i1.TagComponent, selector: "f-tag", inputs: ["value", "severity", "icon", "rounded", "color"] }, { kind: "directive", type: i1.TextareaDirective, selector: "[fTextarea]", inputs: ["invalid", "touched"] }, { kind: "component", type: i1.DrawerComponent, selector: "f-drawer", inputs: ["header", "visible", "position", "fullScreen", "modal", "closable", "closeOnEscape"], outputs: ["visibleChange", "onHide"] }, { kind: "directive", type: i1.TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay"] }, { kind: "component", type: i1.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
1221
1239
|
}
|
|
1222
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1240
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TaskDetailPanelComponent, decorators: [{
|
|
1223
1241
|
type: Component,
|
|
1224
1242
|
args: [{
|
|
1225
1243
|
selector: 'tm-task-detail-panel',
|
|
1226
|
-
imports: [
|
|
1227
|
-
DrawerModule,
|
|
1228
|
-
ButtonModule,
|
|
1229
|
-
TagModule,
|
|
1230
|
-
DatePipe,
|
|
1244
|
+
imports: [UiModule, DatePipe,
|
|
1231
1245
|
FormsModule,
|
|
1232
|
-
|
|
1233
|
-
TooltipModule,
|
|
1234
|
-
TranslatePipe,
|
|
1235
|
-
],
|
|
1246
|
+
TranslatePipe,],
|
|
1236
1247
|
template: `
|
|
1237
|
-
<
|
|
1248
|
+
<f-drawer
|
|
1238
1249
|
[visible]="!!task()"
|
|
1239
1250
|
position="right"
|
|
1240
1251
|
[style]="{ width: '500px' }"
|
|
@@ -1244,34 +1255,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1244
1255
|
@if (task(); as t) {
|
|
1245
1256
|
<div class="flex flex-col gap-6 h-full overflow-y-auto pb-4">
|
|
1246
1257
|
<div class="flex items-center justify-end gap-1">
|
|
1247
|
-
<
|
|
1248
|
-
|
|
1258
|
+
<button
|
|
1259
|
+
fButton
|
|
1249
1260
|
severity="secondary"
|
|
1250
1261
|
size="small"
|
|
1251
1262
|
[text]="true"
|
|
1252
|
-
[
|
|
1263
|
+
[fTooltip]="'task.detail.edit' | translate"
|
|
1253
1264
|
tooltipPosition="left"
|
|
1254
|
-
(
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1265
|
+
(click)="editTask.emit(t)"
|
|
1266
|
+
>
|
|
1267
|
+
<ui-icon pButtonIcon name="pencil"></ui-icon>
|
|
1268
|
+
</button>
|
|
1269
|
+
<button
|
|
1270
|
+
fButton
|
|
1258
1271
|
severity="danger"
|
|
1259
1272
|
size="small"
|
|
1260
1273
|
[text]="true"
|
|
1261
|
-
[
|
|
1262
|
-
[pTooltip]="'task.detail.delete' | translate"
|
|
1274
|
+
[fTooltip]="'task.detail.delete' | translate"
|
|
1263
1275
|
tooltipPosition="left"
|
|
1264
|
-
(
|
|
1265
|
-
|
|
1276
|
+
(click)="deleteTask(t.id)"
|
|
1277
|
+
[disabled]="isDeleting()"
|
|
1278
|
+
>
|
|
1279
|
+
@if (isDeleting()) {
|
|
1280
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
1281
|
+
} @else {
|
|
1282
|
+
<ui-icon pButtonIcon name="trash"></ui-icon>
|
|
1283
|
+
}
|
|
1284
|
+
</button>
|
|
1266
1285
|
</div>
|
|
1267
1286
|
|
|
1268
1287
|
<div class="flex items-center gap-3">
|
|
1269
|
-
<
|
|
1288
|
+
<f-tag
|
|
1270
1289
|
[value]="t.priority"
|
|
1271
1290
|
[severity]="prioritySeverity(t.priority)"
|
|
1272
1291
|
/>
|
|
1273
1292
|
@if (t.dueDate) {
|
|
1274
|
-
<span class="text-sm text-
|
|
1293
|
+
<span class="text-sm text-muted-color">
|
|
1275
1294
|
{{ 'task.detail.due.label' | translate }}:
|
|
1276
1295
|
{{ t.dueDate | date: 'mediumDate' }}
|
|
1277
1296
|
</span>
|
|
@@ -1286,11 +1305,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1286
1305
|
<div class="flex flex-wrap gap-2">
|
|
1287
1306
|
@for (member of assigneeMembers(); track member.userId) {
|
|
1288
1307
|
<div class="flex items-center gap-2 px-2 py-1 rounded-full ">
|
|
1289
|
-
<
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1308
|
+
<f-avatar
|
|
1309
|
+
shape="circle"
|
|
1310
|
+
size="small"
|
|
1311
|
+
[label]="initials(member.userName)"
|
|
1312
|
+
styleClass="!bg-primary-100 dark:!bg-primary-900 !text-primary-700 dark:!text-primary-300"
|
|
1313
|
+
/>
|
|
1294
1314
|
<span class="text-sm">{{ member.userName }}</span>
|
|
1295
1315
|
</div>
|
|
1296
1316
|
}
|
|
@@ -1302,9 +1322,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1302
1322
|
<h4 class="text-sm font-semibold mb-2">
|
|
1303
1323
|
{{ 'shared.description' | translate }}
|
|
1304
1324
|
</h4>
|
|
1305
|
-
<p
|
|
1306
|
-
class="text-sm text-surface-600 dark:text-surface-400 whitespace-pre-wrap"
|
|
1307
|
-
>
|
|
1325
|
+
<p class="text-sm text-color whitespace-pre-wrap">
|
|
1308
1326
|
{{
|
|
1309
1327
|
t.description || ('task.detail.description.empty' | translate)
|
|
1310
1328
|
}}
|
|
@@ -1320,31 +1338,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1320
1338
|
|
|
1321
1339
|
@for (comment of rootComments(); track comment.id) {
|
|
1322
1340
|
<div
|
|
1323
|
-
class="group flex flex-col gap-1 py-2 border-b border-surface
|
|
1341
|
+
class="group flex flex-col gap-1 py-2 border-b border-surface last:border-0"
|
|
1324
1342
|
>
|
|
1325
1343
|
<div class="flex items-center justify-between">
|
|
1326
|
-
<span class="text-xs text-
|
|
1344
|
+
<span class="text-xs text-muted-color">{{
|
|
1327
1345
|
comment.createdAt | date: 'MMM d, y, h:mm a'
|
|
1328
1346
|
}}</span>
|
|
1329
|
-
<
|
|
1330
|
-
|
|
1331
|
-
icon="pi pi-reply"
|
|
1347
|
+
<button
|
|
1348
|
+
fButton
|
|
1332
1349
|
size="small"
|
|
1333
1350
|
[text]="true"
|
|
1334
1351
|
severity="secondary"
|
|
1335
|
-
|
|
1336
|
-
(
|
|
1337
|
-
|
|
1352
|
+
class="opacity-0 group-hover:opacity-100 transition-opacity !py-0.5 !px-1.5 text-xs"
|
|
1353
|
+
(click)="toggleReply(comment.id)"
|
|
1354
|
+
>
|
|
1355
|
+
<ui-icon pButtonIcon name="reply"></ui-icon>
|
|
1356
|
+
<span pButtonLabel>{{ 'task.comment.reply' | translate }}</span>
|
|
1357
|
+
</button>
|
|
1338
1358
|
</div>
|
|
1339
1359
|
<p class="text-sm">{{ comment.content }}</p>
|
|
1340
1360
|
|
|
1341
1361
|
@if (repliesFor(comment.id).length > 0) {
|
|
1342
1362
|
<div
|
|
1343
|
-
class="mt-1 pl-3 border-l-2 border-surface
|
|
1363
|
+
class="mt-1 pl-3 border-l-2 border-surface flex flex-col gap-2"
|
|
1344
1364
|
>
|
|
1345
1365
|
@for (reply of repliesFor(comment.id); track reply.id) {
|
|
1346
1366
|
<div class="flex flex-col gap-0.5">
|
|
1347
|
-
<span class="text-xs text-
|
|
1367
|
+
<span class="text-xs text-muted-color">{{
|
|
1348
1368
|
reply.createdAt | date: 'MMM d, y, h:mm a'
|
|
1349
1369
|
}}</span>
|
|
1350
1370
|
<p class="text-sm">{{ reply.content }}</p>
|
|
@@ -1358,7 +1378,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1358
1378
|
class="mt-2 pl-3 border-l-2 border-primary-300 dark:border-primary-700 flex gap-2"
|
|
1359
1379
|
>
|
|
1360
1380
|
<textarea
|
|
1361
|
-
|
|
1381
|
+
fTextarea
|
|
1362
1382
|
[(ngModel)]="replyText"
|
|
1363
1383
|
rows="2"
|
|
1364
1384
|
[placeholder]="
|
|
@@ -1368,20 +1388,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1368
1388
|
autoResize="true"
|
|
1369
1389
|
></textarea>
|
|
1370
1390
|
<div class="flex flex-col gap-1">
|
|
1371
|
-
<
|
|
1372
|
-
|
|
1391
|
+
<button
|
|
1392
|
+
fButton
|
|
1373
1393
|
size="small"
|
|
1374
|
-
[
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1394
|
+
[disabled]="!replyText.trim() || isSendingReply()"
|
|
1395
|
+
(click)="submitReply(t.id, comment.id)"
|
|
1396
|
+
>
|
|
1397
|
+
@if (isSendingReply()) {
|
|
1398
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
1399
|
+
} @else {
|
|
1400
|
+
<ui-icon pButtonIcon name="send"></ui-icon>
|
|
1401
|
+
}
|
|
1402
|
+
</button>
|
|
1403
|
+
<button
|
|
1404
|
+
fButton
|
|
1380
1405
|
size="small"
|
|
1381
1406
|
severity="secondary"
|
|
1382
1407
|
[text]="true"
|
|
1383
|
-
(
|
|
1384
|
-
|
|
1408
|
+
(click)="cancelReply()"
|
|
1409
|
+
>
|
|
1410
|
+
<ui-icon pButtonIcon name="times"></ui-icon>
|
|
1411
|
+
</button>
|
|
1385
1412
|
</div>
|
|
1386
1413
|
</div>
|
|
1387
1414
|
}
|
|
@@ -1389,30 +1416,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1389
1416
|
}
|
|
1390
1417
|
|
|
1391
1418
|
@if (rootComments().length === 0) {
|
|
1392
|
-
<p class="text-sm text-
|
|
1419
|
+
<p class="text-sm text-muted-color py-2">
|
|
1393
1420
|
{{ 'task.detail.comments.empty' | translate }}
|
|
1394
1421
|
</p>
|
|
1395
1422
|
}
|
|
1396
1423
|
|
|
1397
1424
|
<div class="flex gap-2 mt-3">
|
|
1398
1425
|
<textarea
|
|
1399
|
-
|
|
1426
|
+
fTextarea
|
|
1400
1427
|
[(ngModel)]="newComment"
|
|
1401
1428
|
rows="2"
|
|
1402
1429
|
[placeholder]="'task.detail.comment.placeholder' | translate"
|
|
1403
1430
|
class="flex-1 resize-none"
|
|
1404
1431
|
></textarea>
|
|
1405
|
-
<
|
|
1406
|
-
|
|
1407
|
-
[
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1432
|
+
<button
|
|
1433
|
+
fButton
|
|
1434
|
+
[disabled]="!newComment.trim() || isSendingComment()"
|
|
1435
|
+
(click)="addComment(t.id)"
|
|
1436
|
+
>
|
|
1437
|
+
@if (isSendingComment()) {
|
|
1438
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
1439
|
+
} @else {
|
|
1440
|
+
<ui-icon pButtonIcon name="send"></ui-icon>
|
|
1441
|
+
}
|
|
1442
|
+
</button>
|
|
1411
1443
|
</div>
|
|
1412
1444
|
</div>
|
|
1413
1445
|
</div>
|
|
1414
1446
|
}
|
|
1415
|
-
</
|
|
1447
|
+
</f-drawer>
|
|
1416
1448
|
`,
|
|
1417
1449
|
}]
|
|
1418
1450
|
}], ctorParameters: () => [], propDecorators: { task: [{ type: i0.Input, args: [{ isSignal: true, alias: "task", required: false }] }], closePanel: [{ type: i0.Output, args: ["closePanel"] }], editTask: [{ type: i0.Output, args: ["editTask"] }] } });
|
|
@@ -1421,11 +1453,13 @@ class BoardListPageComponent {
|
|
|
1421
1453
|
state = inject(TaskBoardStateService);
|
|
1422
1454
|
boardApi = inject(TaskBoardApiService);
|
|
1423
1455
|
router = inject(Router);
|
|
1424
|
-
showCreateDialog = signal(false,
|
|
1425
|
-
|
|
1456
|
+
showCreateDialog = signal(false, /* @ts-ignore */
|
|
1457
|
+
...(ngDevMode ? [{ debugName: "showCreateDialog" }] : /* istanbul ignore next */ []));
|
|
1458
|
+
isCreating = signal(false, /* @ts-ignore */
|
|
1459
|
+
...(ngDevMode ? [{ debugName: "isCreating" }] : /* istanbul ignore next */ []));
|
|
1426
1460
|
newBoardName = '';
|
|
1427
1461
|
newBoardDescription = '';
|
|
1428
|
-
newBoardColor =
|
|
1462
|
+
newBoardColor = BOARD_COLOR_PALETTE[0];
|
|
1429
1463
|
boardColors = BOARD_COLOR_PALETTE;
|
|
1430
1464
|
constructor() {
|
|
1431
1465
|
this.state.loadBoards();
|
|
@@ -1437,7 +1471,7 @@ class BoardListPageComponent {
|
|
|
1437
1471
|
this.showCreateDialog.set(false);
|
|
1438
1472
|
this.newBoardName = '';
|
|
1439
1473
|
this.newBoardDescription = '';
|
|
1440
|
-
this.newBoardColor =
|
|
1474
|
+
this.newBoardColor = BOARD_COLOR_PALETTE[0];
|
|
1441
1475
|
}
|
|
1442
1476
|
async createBoard() {
|
|
1443
1477
|
if (!this.newBoardName.trim())
|
|
@@ -1456,8 +1490,8 @@ class BoardListPageComponent {
|
|
|
1456
1490
|
this.isCreating.set(false);
|
|
1457
1491
|
}
|
|
1458
1492
|
}
|
|
1459
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1460
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
1493
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: BoardListPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1494
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: BoardListPageComponent, isStandalone: true, selector: "tm-board-list-page", ngImport: i0, template: `
|
|
1461
1495
|
<div class="p-2 sm:p-4">
|
|
1462
1496
|
<div
|
|
1463
1497
|
class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4"
|
|
@@ -1470,28 +1504,30 @@ class BoardListPageComponent {
|
|
|
1470
1504
|
{{ 'task.manager.boards.subtitle' | translate }}
|
|
1471
1505
|
</p>
|
|
1472
1506
|
</div>
|
|
1473
|
-
<
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1507
|
+
<button
|
|
1508
|
+
fButton
|
|
1509
|
+
(click)="showCreateDialog.set(true)"
|
|
1510
|
+
>
|
|
1511
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
1512
|
+
<span pButtonLabel>{{ 'task.manager.board.new' | translate }}</span>
|
|
1513
|
+
</button>
|
|
1478
1514
|
</div>
|
|
1479
1515
|
|
|
1480
1516
|
@if (state.isLoading()) {
|
|
1481
1517
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
1482
1518
|
@for (i of [1, 2, 3, 4, 5, 6]; track i) {
|
|
1483
1519
|
<div class="card !p-0 overflow-hidden">
|
|
1484
|
-
<
|
|
1520
|
+
<f-skeleton height="4px" borderRadius="0" />
|
|
1485
1521
|
<div class="p-5">
|
|
1486
|
-
<
|
|
1487
|
-
<
|
|
1488
|
-
<
|
|
1522
|
+
<f-skeleton height="18px" width="60%" class="mb-3" />
|
|
1523
|
+
<f-skeleton height="13px" class="mb-1" />
|
|
1524
|
+
<f-skeleton height="13px" width="70%" class="mb-5" />
|
|
1489
1525
|
<div class="flex gap-5 pt-4 border-t border-surface-100">
|
|
1490
|
-
<
|
|
1491
|
-
<
|
|
1492
|
-
<
|
|
1526
|
+
<f-skeleton height="14px" width="55px" />
|
|
1527
|
+
<f-skeleton height="14px" width="45px" />
|
|
1528
|
+
<f-skeleton height="14px" width="50px" />
|
|
1493
1529
|
</div>
|
|
1494
|
-
<
|
|
1530
|
+
<f-skeleton height="11px" width="100px" class="mt-2" />
|
|
1495
1531
|
</div>
|
|
1496
1532
|
</div>
|
|
1497
1533
|
}
|
|
@@ -1503,7 +1539,7 @@ class BoardListPageComponent {
|
|
|
1503
1539
|
<span
|
|
1504
1540
|
class="w-16 h-16 rounded-2xl border-2 border-dashed border-surface-300 flex items-center justify-center mb-4"
|
|
1505
1541
|
>
|
|
1506
|
-
<
|
|
1542
|
+
<ui-icon name="th-large" class="text-2xl text-surface-400"></ui-icon>
|
|
1507
1543
|
</span>
|
|
1508
1544
|
<p class="text-base font-semibold mb-1">
|
|
1509
1545
|
{{ 'task.manager.board.empty' | translate }}
|
|
@@ -1511,12 +1547,14 @@ class BoardListPageComponent {
|
|
|
1511
1547
|
<p class="text-sm text-muted-color mb-5">
|
|
1512
1548
|
{{ 'task.manager.board.empty.hint' | translate }}
|
|
1513
1549
|
</p>
|
|
1514
|
-
<
|
|
1515
|
-
|
|
1516
|
-
icon="pi pi-plus"
|
|
1550
|
+
<button
|
|
1551
|
+
fButton
|
|
1517
1552
|
size="small"
|
|
1518
|
-
(
|
|
1519
|
-
|
|
1553
|
+
(click)="showCreateDialog.set(true)"
|
|
1554
|
+
>
|
|
1555
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
1556
|
+
<span pButtonLabel>{{ 'task.manager.board.new' | translate }}</span>
|
|
1557
|
+
</button>
|
|
1520
1558
|
</div>
|
|
1521
1559
|
} @else {
|
|
1522
1560
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
@@ -1536,9 +1574,7 @@ class BoardListPageComponent {
|
|
|
1536
1574
|
{{ board.name }}
|
|
1537
1575
|
</h3>
|
|
1538
1576
|
</div>
|
|
1539
|
-
<
|
|
1540
|
-
class="pi pi-arrow-right text-xs text-surface-300 group-hover:text-primary-500 group-hover:translate-x-0.5 transition-all duration-150 flex-shrink-0 mt-1"
|
|
1541
|
-
></i>
|
|
1577
|
+
<ui-icon name="arrow-right" class="text-xs text-surface-300 group-hover:text-primary-500 group-hover:translate-x-0.5 transition-all duration-150 flex-shrink-0 mt-1"></ui-icon>
|
|
1542
1578
|
</div>
|
|
1543
1579
|
|
|
1544
1580
|
<p
|
|
@@ -1548,11 +1584,11 @@ class BoardListPageComponent {
|
|
|
1548
1584
|
</p>
|
|
1549
1585
|
|
|
1550
1586
|
<div
|
|
1551
|
-
class="border-t border-surface
|
|
1587
|
+
class="border-t border-surface mt-4 pt-4 space-y-2.5"
|
|
1552
1588
|
>
|
|
1553
1589
|
<div class="flex items-center gap-4">
|
|
1554
1590
|
<span class="flex items-center gap-1.5">
|
|
1555
|
-
<
|
|
1591
|
+
<ui-icon name="users" class="text-[11px] text-muted-color"></ui-icon>
|
|
1556
1592
|
<span class="text-sm font-semibold">{{
|
|
1557
1593
|
board.totalMembers ?? 0
|
|
1558
1594
|
}}</span>
|
|
@@ -1564,7 +1600,7 @@ class BoardListPageComponent {
|
|
|
1564
1600
|
class="w-px h-3 bg-surface-200 dark:bg-surface-600"
|
|
1565
1601
|
></span>
|
|
1566
1602
|
<span class="flex items-center gap-1.5">
|
|
1567
|
-
<
|
|
1603
|
+
<ui-icon name="list" class="text-[11px] text-muted-color"></ui-icon>
|
|
1568
1604
|
<span class="text-sm font-semibold">{{
|
|
1569
1605
|
board.totalLists ?? 0
|
|
1570
1606
|
}}</span>
|
|
@@ -1576,9 +1612,7 @@ class BoardListPageComponent {
|
|
|
1576
1612
|
class="w-px h-3 bg-surface-200 dark:bg-surface-600"
|
|
1577
1613
|
></span>
|
|
1578
1614
|
<span class="flex items-center gap-1.5">
|
|
1579
|
-
<
|
|
1580
|
-
class="pi pi-check-square text-[11px] text-muted-color"
|
|
1581
|
-
></i>
|
|
1615
|
+
<ui-icon name="check-square" class="text-[11px] text-muted-color"></ui-icon>
|
|
1582
1616
|
<span class="text-sm font-semibold">{{
|
|
1583
1617
|
board.totalTasks ?? 0
|
|
1584
1618
|
}}</span>
|
|
@@ -1590,7 +1624,7 @@ class BoardListPageComponent {
|
|
|
1590
1624
|
<div
|
|
1591
1625
|
class="flex items-center gap-1.5 text-xs text-muted-color"
|
|
1592
1626
|
>
|
|
1593
|
-
<
|
|
1627
|
+
<ui-icon name="clock" class="text-[10px]"></ui-icon>
|
|
1594
1628
|
<span>{{ board.createdAt | date: 'MMM d, yyyy' }}</span>
|
|
1595
1629
|
</div>
|
|
1596
1630
|
</div>
|
|
@@ -1601,7 +1635,7 @@ class BoardListPageComponent {
|
|
|
1601
1635
|
}
|
|
1602
1636
|
</div>
|
|
1603
1637
|
|
|
1604
|
-
<
|
|
1638
|
+
<f-dialog
|
|
1605
1639
|
[header]="'task.manager.board.new' | translate"
|
|
1606
1640
|
[(visible)]="showCreateDialog"
|
|
1607
1641
|
[modal]="true"
|
|
@@ -1614,7 +1648,7 @@ class BoardListPageComponent {
|
|
|
1614
1648
|
<span class="text-red-500">*</span></label
|
|
1615
1649
|
>
|
|
1616
1650
|
<input
|
|
1617
|
-
|
|
1651
|
+
fInputText
|
|
1618
1652
|
[(ngModel)]="newBoardName"
|
|
1619
1653
|
[placeholder]="'task.manager.board.name.placeholder' | translate"
|
|
1620
1654
|
/>
|
|
@@ -1624,7 +1658,7 @@ class BoardListPageComponent {
|
|
|
1624
1658
|
'shared.description' | translate
|
|
1625
1659
|
}}</label>
|
|
1626
1660
|
<textarea
|
|
1627
|
-
|
|
1661
|
+
fTextarea
|
|
1628
1662
|
[(ngModel)]="newBoardDescription"
|
|
1629
1663
|
rows="2"
|
|
1630
1664
|
[placeholder]="
|
|
@@ -1645,11 +1679,11 @@ class BoardListPageComponent {
|
|
|
1645
1679
|
[class.ring-2]="newBoardColor === c"
|
|
1646
1680
|
[class.ring-offset-2]="newBoardColor === c"
|
|
1647
1681
|
[class.ring-surface-900]="newBoardColor === c"
|
|
1648
|
-
[
|
|
1682
|
+
[fTooltip]="c"
|
|
1649
1683
|
(click)="newBoardColor = c"
|
|
1650
1684
|
>
|
|
1651
1685
|
@if (newBoardColor === c) {
|
|
1652
|
-
<
|
|
1686
|
+
<ui-icon name="check" class="text-white text-xs"></ui-icon>
|
|
1653
1687
|
}
|
|
1654
1688
|
</button>
|
|
1655
1689
|
}
|
|
@@ -1666,28 +1700,35 @@ class BoardListPageComponent {
|
|
|
1666
1700
|
</div>
|
|
1667
1701
|
</div>
|
|
1668
1702
|
|
|
1669
|
-
<ng-template
|
|
1703
|
+
<ng-template #footer>
|
|
1670
1704
|
<div class="flex justify-end gap-2">
|
|
1671
|
-
<
|
|
1672
|
-
|
|
1705
|
+
<button
|
|
1706
|
+
fButton
|
|
1673
1707
|
severity="secondary"
|
|
1674
|
-
(
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1708
|
+
(click)="closeCreateDialog()"
|
|
1709
|
+
>
|
|
1710
|
+
<span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
|
|
1711
|
+
</button>
|
|
1712
|
+
<button
|
|
1713
|
+
fButton
|
|
1714
|
+
(click)="createBoard()"
|
|
1715
|
+
[disabled]="isCreating()"
|
|
1716
|
+
>
|
|
1717
|
+
@if (isCreating()) {
|
|
1718
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
1719
|
+
}
|
|
1720
|
+
<span pButtonLabel>{{ 'shared.create' | translate }}</span>
|
|
1721
|
+
</button>
|
|
1681
1722
|
</div>
|
|
1682
1723
|
</ng-template>
|
|
1683
|
-
</
|
|
1684
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type:
|
|
1724
|
+
</f-dialog>
|
|
1725
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: UiModule }, { kind: "directive", type: i1.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "rounded", "raised", "fluid", "disabled", "loading", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i1.SkeletonComponent, selector: "f-skeleton", inputs: ["width", "height", "borderRadius", "shape"] }, { kind: "directive", type: i1.InputTextDirective, selector: "[fInputText]", inputs: ["invalid", "touched"] }, { kind: "directive", type: i1.TextareaDirective, selector: "[fTextarea]", inputs: ["invalid", "touched"] }, { kind: "component", type: i1.DialogComponent, selector: "f-dialog", inputs: ["header", "visible", "modal", "closable", "dismissableMask", "resizable", "style", "breakpoints"], outputs: ["visibleChange", "onShow", "onHide"] }, { kind: "directive", type: i1.TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay"] }, { kind: "component", type: i1.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
1685
1726
|
}
|
|
1686
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1727
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: BoardListPageComponent, decorators: [{
|
|
1687
1728
|
type: Component,
|
|
1688
1729
|
args: [{
|
|
1689
1730
|
selector: 'tm-board-list-page',
|
|
1690
|
-
imports: [AngularModule,
|
|
1731
|
+
imports: [AngularModule, UiModule, TranslatePipe],
|
|
1691
1732
|
template: `
|
|
1692
1733
|
<div class="p-2 sm:p-4">
|
|
1693
1734
|
<div
|
|
@@ -1701,28 +1742,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1701
1742
|
{{ 'task.manager.boards.subtitle' | translate }}
|
|
1702
1743
|
</p>
|
|
1703
1744
|
</div>
|
|
1704
|
-
<
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1745
|
+
<button
|
|
1746
|
+
fButton
|
|
1747
|
+
(click)="showCreateDialog.set(true)"
|
|
1748
|
+
>
|
|
1749
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
1750
|
+
<span pButtonLabel>{{ 'task.manager.board.new' | translate }}</span>
|
|
1751
|
+
</button>
|
|
1709
1752
|
</div>
|
|
1710
1753
|
|
|
1711
1754
|
@if (state.isLoading()) {
|
|
1712
1755
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
1713
1756
|
@for (i of [1, 2, 3, 4, 5, 6]; track i) {
|
|
1714
1757
|
<div class="card !p-0 overflow-hidden">
|
|
1715
|
-
<
|
|
1758
|
+
<f-skeleton height="4px" borderRadius="0" />
|
|
1716
1759
|
<div class="p-5">
|
|
1717
|
-
<
|
|
1718
|
-
<
|
|
1719
|
-
<
|
|
1760
|
+
<f-skeleton height="18px" width="60%" class="mb-3" />
|
|
1761
|
+
<f-skeleton height="13px" class="mb-1" />
|
|
1762
|
+
<f-skeleton height="13px" width="70%" class="mb-5" />
|
|
1720
1763
|
<div class="flex gap-5 pt-4 border-t border-surface-100">
|
|
1721
|
-
<
|
|
1722
|
-
<
|
|
1723
|
-
<
|
|
1764
|
+
<f-skeleton height="14px" width="55px" />
|
|
1765
|
+
<f-skeleton height="14px" width="45px" />
|
|
1766
|
+
<f-skeleton height="14px" width="50px" />
|
|
1724
1767
|
</div>
|
|
1725
|
-
<
|
|
1768
|
+
<f-skeleton height="11px" width="100px" class="mt-2" />
|
|
1726
1769
|
</div>
|
|
1727
1770
|
</div>
|
|
1728
1771
|
}
|
|
@@ -1734,7 +1777,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1734
1777
|
<span
|
|
1735
1778
|
class="w-16 h-16 rounded-2xl border-2 border-dashed border-surface-300 flex items-center justify-center mb-4"
|
|
1736
1779
|
>
|
|
1737
|
-
<
|
|
1780
|
+
<ui-icon name="th-large" class="text-2xl text-surface-400"></ui-icon>
|
|
1738
1781
|
</span>
|
|
1739
1782
|
<p class="text-base font-semibold mb-1">
|
|
1740
1783
|
{{ 'task.manager.board.empty' | translate }}
|
|
@@ -1742,12 +1785,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1742
1785
|
<p class="text-sm text-muted-color mb-5">
|
|
1743
1786
|
{{ 'task.manager.board.empty.hint' | translate }}
|
|
1744
1787
|
</p>
|
|
1745
|
-
<
|
|
1746
|
-
|
|
1747
|
-
icon="pi pi-plus"
|
|
1788
|
+
<button
|
|
1789
|
+
fButton
|
|
1748
1790
|
size="small"
|
|
1749
|
-
(
|
|
1750
|
-
|
|
1791
|
+
(click)="showCreateDialog.set(true)"
|
|
1792
|
+
>
|
|
1793
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
1794
|
+
<span pButtonLabel>{{ 'task.manager.board.new' | translate }}</span>
|
|
1795
|
+
</button>
|
|
1751
1796
|
</div>
|
|
1752
1797
|
} @else {
|
|
1753
1798
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
@@ -1767,9 +1812,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1767
1812
|
{{ board.name }}
|
|
1768
1813
|
</h3>
|
|
1769
1814
|
</div>
|
|
1770
|
-
<
|
|
1771
|
-
class="pi pi-arrow-right text-xs text-surface-300 group-hover:text-primary-500 group-hover:translate-x-0.5 transition-all duration-150 flex-shrink-0 mt-1"
|
|
1772
|
-
></i>
|
|
1815
|
+
<ui-icon name="arrow-right" class="text-xs text-surface-300 group-hover:text-primary-500 group-hover:translate-x-0.5 transition-all duration-150 flex-shrink-0 mt-1"></ui-icon>
|
|
1773
1816
|
</div>
|
|
1774
1817
|
|
|
1775
1818
|
<p
|
|
@@ -1779,11 +1822,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1779
1822
|
</p>
|
|
1780
1823
|
|
|
1781
1824
|
<div
|
|
1782
|
-
class="border-t border-surface
|
|
1825
|
+
class="border-t border-surface mt-4 pt-4 space-y-2.5"
|
|
1783
1826
|
>
|
|
1784
1827
|
<div class="flex items-center gap-4">
|
|
1785
1828
|
<span class="flex items-center gap-1.5">
|
|
1786
|
-
<
|
|
1829
|
+
<ui-icon name="users" class="text-[11px] text-muted-color"></ui-icon>
|
|
1787
1830
|
<span class="text-sm font-semibold">{{
|
|
1788
1831
|
board.totalMembers ?? 0
|
|
1789
1832
|
}}</span>
|
|
@@ -1795,7 +1838,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1795
1838
|
class="w-px h-3 bg-surface-200 dark:bg-surface-600"
|
|
1796
1839
|
></span>
|
|
1797
1840
|
<span class="flex items-center gap-1.5">
|
|
1798
|
-
<
|
|
1841
|
+
<ui-icon name="list" class="text-[11px] text-muted-color"></ui-icon>
|
|
1799
1842
|
<span class="text-sm font-semibold">{{
|
|
1800
1843
|
board.totalLists ?? 0
|
|
1801
1844
|
}}</span>
|
|
@@ -1807,9 +1850,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1807
1850
|
class="w-px h-3 bg-surface-200 dark:bg-surface-600"
|
|
1808
1851
|
></span>
|
|
1809
1852
|
<span class="flex items-center gap-1.5">
|
|
1810
|
-
<
|
|
1811
|
-
class="pi pi-check-square text-[11px] text-muted-color"
|
|
1812
|
-
></i>
|
|
1853
|
+
<ui-icon name="check-square" class="text-[11px] text-muted-color"></ui-icon>
|
|
1813
1854
|
<span class="text-sm font-semibold">{{
|
|
1814
1855
|
board.totalTasks ?? 0
|
|
1815
1856
|
}}</span>
|
|
@@ -1821,7 +1862,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1821
1862
|
<div
|
|
1822
1863
|
class="flex items-center gap-1.5 text-xs text-muted-color"
|
|
1823
1864
|
>
|
|
1824
|
-
<
|
|
1865
|
+
<ui-icon name="clock" class="text-[10px]"></ui-icon>
|
|
1825
1866
|
<span>{{ board.createdAt | date: 'MMM d, yyyy' }}</span>
|
|
1826
1867
|
</div>
|
|
1827
1868
|
</div>
|
|
@@ -1832,7 +1873,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1832
1873
|
}
|
|
1833
1874
|
</div>
|
|
1834
1875
|
|
|
1835
|
-
<
|
|
1876
|
+
<f-dialog
|
|
1836
1877
|
[header]="'task.manager.board.new' | translate"
|
|
1837
1878
|
[(visible)]="showCreateDialog"
|
|
1838
1879
|
[modal]="true"
|
|
@@ -1845,7 +1886,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1845
1886
|
<span class="text-red-500">*</span></label
|
|
1846
1887
|
>
|
|
1847
1888
|
<input
|
|
1848
|
-
|
|
1889
|
+
fInputText
|
|
1849
1890
|
[(ngModel)]="newBoardName"
|
|
1850
1891
|
[placeholder]="'task.manager.board.name.placeholder' | translate"
|
|
1851
1892
|
/>
|
|
@@ -1855,7 +1896,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1855
1896
|
'shared.description' | translate
|
|
1856
1897
|
}}</label>
|
|
1857
1898
|
<textarea
|
|
1858
|
-
|
|
1899
|
+
fTextarea
|
|
1859
1900
|
[(ngModel)]="newBoardDescription"
|
|
1860
1901
|
rows="2"
|
|
1861
1902
|
[placeholder]="
|
|
@@ -1876,11 +1917,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1876
1917
|
[class.ring-2]="newBoardColor === c"
|
|
1877
1918
|
[class.ring-offset-2]="newBoardColor === c"
|
|
1878
1919
|
[class.ring-surface-900]="newBoardColor === c"
|
|
1879
|
-
[
|
|
1920
|
+
[fTooltip]="c"
|
|
1880
1921
|
(click)="newBoardColor = c"
|
|
1881
1922
|
>
|
|
1882
1923
|
@if (newBoardColor === c) {
|
|
1883
|
-
<
|
|
1924
|
+
<ui-icon name="check" class="text-white text-xs"></ui-icon>
|
|
1884
1925
|
}
|
|
1885
1926
|
</button>
|
|
1886
1927
|
}
|
|
@@ -1897,21 +1938,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1897
1938
|
</div>
|
|
1898
1939
|
</div>
|
|
1899
1940
|
|
|
1900
|
-
<ng-template
|
|
1941
|
+
<ng-template #footer>
|
|
1901
1942
|
<div class="flex justify-end gap-2">
|
|
1902
|
-
<
|
|
1903
|
-
|
|
1943
|
+
<button
|
|
1944
|
+
fButton
|
|
1904
1945
|
severity="secondary"
|
|
1905
|
-
(
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1946
|
+
(click)="closeCreateDialog()"
|
|
1947
|
+
>
|
|
1948
|
+
<span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
|
|
1949
|
+
</button>
|
|
1950
|
+
<button
|
|
1951
|
+
fButton
|
|
1952
|
+
(click)="createBoard()"
|
|
1953
|
+
[disabled]="isCreating()"
|
|
1954
|
+
>
|
|
1955
|
+
@if (isCreating()) {
|
|
1956
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
1957
|
+
}
|
|
1958
|
+
<span pButtonLabel>{{ 'shared.create' | translate }}</span>
|
|
1959
|
+
</button>
|
|
1912
1960
|
</div>
|
|
1913
1961
|
</ng-template>
|
|
1914
|
-
</
|
|
1962
|
+
</f-dialog>
|
|
1915
1963
|
`,
|
|
1916
1964
|
}]
|
|
1917
1965
|
}], ctorParameters: () => [] });
|
|
@@ -1927,34 +1975,51 @@ class BoardViewPageComponent {
|
|
|
1927
1975
|
listApi = inject(TaskListApiService);
|
|
1928
1976
|
confirmationService = inject(ConfirmationService);
|
|
1929
1977
|
messageService = inject(MessageService);
|
|
1930
|
-
translateAdapter = inject(TranslateService, {
|
|
1978
|
+
translateAdapter = inject(TranslateService, {
|
|
1979
|
+
optional: true,
|
|
1980
|
+
});
|
|
1931
1981
|
destroyRef = inject(DestroyRef);
|
|
1932
1982
|
translate(key, vars) {
|
|
1933
1983
|
return this.translateAdapter?.translate(key, vars) ?? key;
|
|
1934
1984
|
}
|
|
1935
|
-
boardId = input.required(
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1985
|
+
boardId = input.required(/* @ts-ignore */
|
|
1986
|
+
...(ngDevMode ? [{ debugName: "boardId" }] : /* istanbul ignore next */ []));
|
|
1987
|
+
viewMode = signal('board', /* @ts-ignore */
|
|
1988
|
+
...(ngDevMode ? [{ debugName: "viewMode" }] : /* istanbul ignore next */ []));
|
|
1989
|
+
showTaskForm = signal(false, /* @ts-ignore */
|
|
1990
|
+
...(ngDevMode ? [{ debugName: "showTaskForm" }] : /* istanbul ignore next */ []));
|
|
1991
|
+
editingTask = signal(null, /* @ts-ignore */
|
|
1992
|
+
...(ngDevMode ? [{ debugName: "editingTask" }] : /* istanbul ignore next */ []));
|
|
1993
|
+
activeListId = signal('', /* @ts-ignore */
|
|
1994
|
+
...(ngDevMode ? [{ debugName: "activeListId" }] : /* istanbul ignore next */ []));
|
|
1995
|
+
showAddListDialog = signal(false, /* @ts-ignore */
|
|
1996
|
+
...(ngDevMode ? [{ debugName: "showAddListDialog" }] : /* istanbul ignore next */ []));
|
|
1997
|
+
isAddingList = signal(false, /* @ts-ignore */
|
|
1998
|
+
...(ngDevMode ? [{ debugName: "isAddingList" }] : /* istanbul ignore next */ []));
|
|
1999
|
+
showLabelsDialog = signal(false, /* @ts-ignore */
|
|
2000
|
+
...(ngDevMode ? [{ debugName: "showLabelsDialog" }] : /* istanbul ignore next */ []));
|
|
2001
|
+
isAddingLabel = signal(false, /* @ts-ignore */
|
|
2002
|
+
...(ngDevMode ? [{ debugName: "isAddingLabel" }] : /* istanbul ignore next */ []));
|
|
2003
|
+
showMembersDialog = signal(false, /* @ts-ignore */
|
|
2004
|
+
...(ngDevMode ? [{ debugName: "showMembersDialog" }] : /* istanbul ignore next */ []));
|
|
2005
|
+
isAddingMember = signal(false, /* @ts-ignore */
|
|
2006
|
+
...(ngDevMode ? [{ debugName: "isAddingMember" }] : /* istanbul ignore next */ []));
|
|
2007
|
+
editingListId = signal(null, /* @ts-ignore */
|
|
2008
|
+
...(ngDevMode ? [{ debugName: "editingListId" }] : /* istanbul ignore next */ []));
|
|
2009
|
+
editingListNameValue = signal('', /* @ts-ignore */
|
|
2010
|
+
...(ngDevMode ? [{ debugName: "editingListNameValue" }] : /* istanbul ignore next */ []));
|
|
2011
|
+
showEditBoardDialog = signal(false, /* @ts-ignore */
|
|
2012
|
+
...(ngDevMode ? [{ debugName: "showEditBoardDialog" }] : /* istanbul ignore next */ []));
|
|
2013
|
+
isSavingBoard = signal(false, /* @ts-ignore */
|
|
2014
|
+
...(ngDevMode ? [{ debugName: "isSavingBoard" }] : /* istanbul ignore next */ []));
|
|
1950
2015
|
newListName = '';
|
|
1951
2016
|
newLabelName = '';
|
|
1952
|
-
newLabelColor =
|
|
2017
|
+
newLabelColor = BOARD_COLOR_PALETTE[0];
|
|
1953
2018
|
selectedMemberUser = null;
|
|
1954
2019
|
newMemberRole = 'MEMBER';
|
|
1955
2020
|
editBoardName = '';
|
|
1956
2021
|
editBoardDescription = '';
|
|
1957
|
-
editBoardColor =
|
|
2022
|
+
editBoardColor = BOARD_COLOR_PALETTE[0];
|
|
1958
2023
|
boardColorPalette = BOARD_COLOR_PALETTE;
|
|
1959
2024
|
memberRoleOptions = [
|
|
1960
2025
|
{ labelKey: 'task.manager.member.role.admin', value: 'ADMIN' },
|
|
@@ -1965,10 +2030,15 @@ class BoardViewPageComponent {
|
|
|
1965
2030
|
...task,
|
|
1966
2031
|
listName: list.name,
|
|
1967
2032
|
listColor: list.color,
|
|
1968
|
-
}))),
|
|
1969
|
-
|
|
2033
|
+
}))), /* @ts-ignore */
|
|
2034
|
+
...(ngDevMode ? [{ debugName: "allTasksFlat" }] : /* istanbul ignore next */ []));
|
|
2035
|
+
listDropIds = computed(() => this.state.listsWithTasks().map((l) => l.id), /* @ts-ignore */
|
|
2036
|
+
...(ngDevMode ? [{ debugName: "listDropIds" }] : /* istanbul ignore next */ []));
|
|
1970
2037
|
constructor() {
|
|
1971
|
-
effect(() => {
|
|
2038
|
+
effect(() => {
|
|
2039
|
+
const id = this.boardId();
|
|
2040
|
+
untracked(() => this.state.openBoard(id));
|
|
2041
|
+
});
|
|
1972
2042
|
this.destroyRef.onDestroy(() => this.state.closeBoard());
|
|
1973
2043
|
}
|
|
1974
2044
|
openAddTask(list) {
|
|
@@ -1981,17 +2051,22 @@ class BoardViewPageComponent {
|
|
|
1981
2051
|
}
|
|
1982
2052
|
onDeleteTask(task) {
|
|
1983
2053
|
this.confirmationService.confirm({
|
|
1984
|
-
message: this.translate('shared.confirm.delete.item', {
|
|
2054
|
+
message: this.translate('shared.confirm.delete.item', {
|
|
2055
|
+
name: task.title,
|
|
2056
|
+
}),
|
|
1985
2057
|
header: this.translate('task.detail.delete'),
|
|
1986
|
-
icon: '
|
|
2058
|
+
icon: 'exclamation-triangle',
|
|
1987
2059
|
acceptButtonStyleClass: 'p-button-danger',
|
|
1988
2060
|
accept: async () => {
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
2061
|
+
try {
|
|
2062
|
+
await this.state.deleteTask(task.id);
|
|
2063
|
+
this.messageService.add({
|
|
2064
|
+
severity: 'success',
|
|
2065
|
+
summary: this.translate('shared.success'),
|
|
2066
|
+
detail: this.translate('task.delete.success'),
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
catch { }
|
|
1995
2070
|
},
|
|
1996
2071
|
});
|
|
1997
2072
|
}
|
|
@@ -2002,7 +2077,8 @@ class BoardViewPageComponent {
|
|
|
2002
2077
|
this.state.selectTask(null);
|
|
2003
2078
|
}
|
|
2004
2079
|
getMemberName(assigneeId) {
|
|
2005
|
-
return this.state.members().find((m) => m.userId === assigneeId)?.userName ??
|
|
2080
|
+
return (this.state.members().find((m) => m.userId === assigneeId)?.userName ??
|
|
2081
|
+
null);
|
|
2006
2082
|
}
|
|
2007
2083
|
getMemberInitials(assigneeId) {
|
|
2008
2084
|
return memberInitials(this.getMemberName(assigneeId));
|
|
@@ -2106,7 +2182,7 @@ class BoardViewPageComponent {
|
|
|
2106
2182
|
try {
|
|
2107
2183
|
await this.state.addLabel(this.boardId(), this.newLabelName.trim(), this.newLabelColor);
|
|
2108
2184
|
this.newLabelName = '';
|
|
2109
|
-
this.newLabelColor =
|
|
2185
|
+
this.newLabelColor = BOARD_COLOR_PALETTE[0];
|
|
2110
2186
|
}
|
|
2111
2187
|
finally {
|
|
2112
2188
|
this.isAddingLabel.set(false);
|
|
@@ -2153,8 +2229,8 @@ class BoardViewPageComponent {
|
|
|
2153
2229
|
this.isAddingList.set(false);
|
|
2154
2230
|
}
|
|
2155
2231
|
}
|
|
2156
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2157
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2232
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: BoardViewPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2233
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: BoardViewPageComponent, isStandalone: true, selector: "tm-board-view-page", inputs: { boardId: { classPropertyName: "boardId", publicName: "boardId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
2158
2234
|
<div class="flex flex-col h-full">
|
|
2159
2235
|
<div class="flex flex-col">
|
|
2160
2236
|
<div class="flex items-center justify-between px-5 py-2.5 gap-4">
|
|
@@ -2162,22 +2238,28 @@ class BoardViewPageComponent {
|
|
|
2162
2238
|
<div class="flex items-center gap-2.5 min-w-0 flex-1 group">
|
|
2163
2239
|
<div class="flex flex-col min-w-0">
|
|
2164
2240
|
<div class="flex items-center gap-1.5 min-w-0">
|
|
2165
|
-
<h1
|
|
2241
|
+
<h1
|
|
2242
|
+
class="text-base font-bold text-surface-900 dark:text-surface-0 truncate leading-snug"
|
|
2243
|
+
>
|
|
2166
2244
|
{{ board.name }}
|
|
2167
2245
|
</h1>
|
|
2168
|
-
<
|
|
2169
|
-
|
|
2246
|
+
<button
|
|
2247
|
+
fButton
|
|
2170
2248
|
[text]="true"
|
|
2171
2249
|
size="small"
|
|
2172
2250
|
severity="secondary"
|
|
2173
|
-
|
|
2174
|
-
[
|
|
2251
|
+
class="!w-6 !h-6 flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"
|
|
2252
|
+
[fTooltip]="'task.manager.board.edit' | translate"
|
|
2175
2253
|
tooltipPosition="bottom"
|
|
2176
|
-
(
|
|
2177
|
-
|
|
2254
|
+
(click)="openEditBoardDialog(board)"
|
|
2255
|
+
>
|
|
2256
|
+
<ui-icon pButtonIcon name="pencil"></ui-icon>
|
|
2257
|
+
</button>
|
|
2178
2258
|
</div>
|
|
2179
2259
|
@if (board.description) {
|
|
2180
|
-
<span
|
|
2260
|
+
<span
|
|
2261
|
+
class="text-xs text-muted-color truncate max-w-sm hidden md:block leading-snug"
|
|
2262
|
+
>
|
|
2181
2263
|
{{ board.description }}
|
|
2182
2264
|
</span>
|
|
2183
2265
|
}
|
|
@@ -2190,89 +2272,114 @@ class BoardViewPageComponent {
|
|
|
2190
2272
|
<div
|
|
2191
2273
|
class="flex items-center -space-x-2 cursor-pointer mr-1"
|
|
2192
2274
|
(click)="showMembersDialog.set(true)"
|
|
2193
|
-
[
|
|
2275
|
+
[fTooltip]="'task.manager.board.manage.members' | translate"
|
|
2194
2276
|
tooltipPosition="bottom"
|
|
2195
2277
|
>
|
|
2196
2278
|
@for (member of state.members().slice(0, 4); track member.id) {
|
|
2197
|
-
<
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2279
|
+
<f-avatar
|
|
2280
|
+
shape="circle"
|
|
2281
|
+
size="small"
|
|
2282
|
+
[label]="memberInitials(member)"
|
|
2283
|
+
[color]="memberColor(member)"
|
|
2284
|
+
styleClass="!border-2 !border-surface-card ring-1 ring-surface flex-shrink-0"
|
|
2285
|
+
/>
|
|
2203
2286
|
}
|
|
2204
2287
|
@if (state.members().length > 4) {
|
|
2205
|
-
<
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
+
|
|
2209
|
-
|
|
2288
|
+
<f-avatar
|
|
2289
|
+
shape="circle"
|
|
2290
|
+
size="small"
|
|
2291
|
+
[label]="'+' + (state.members().length - 4)"
|
|
2292
|
+
styleClass="!border-2 !border-surface-card !bg-surface-200 dark:!bg-surface-700 !text-surface-600 dark:!text-surface-300 flex-shrink-0"
|
|
2293
|
+
/>
|
|
2210
2294
|
}
|
|
2211
2295
|
</div>
|
|
2212
2296
|
}
|
|
2213
2297
|
|
|
2214
|
-
<div
|
|
2298
|
+
<div
|
|
2299
|
+
class="h-5 w-px bg-surface-300 dark:bg-surface-600 mx-0.5"
|
|
2300
|
+
></div>
|
|
2215
2301
|
|
|
2216
|
-
<div
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2302
|
+
<div
|
|
2303
|
+
class="flex rounded-border overflow-hidden border border-surface"
|
|
2304
|
+
>
|
|
2305
|
+
<button
|
|
2306
|
+
fButton
|
|
2307
|
+
[fTooltip]="'task.manager.view.board' | translate"
|
|
2220
2308
|
tooltipPosition="bottom"
|
|
2221
2309
|
size="small"
|
|
2222
2310
|
[severity]="viewMode() === 'board' ? 'primary' : 'secondary'"
|
|
2223
2311
|
[outlined]="viewMode() !== 'board'"
|
|
2224
|
-
|
|
2225
|
-
(
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2312
|
+
class="!rounded-none !border-0"
|
|
2313
|
+
(click)="viewMode.set('board')"
|
|
2314
|
+
>
|
|
2315
|
+
<ui-icon pButtonIcon name="th-large"></ui-icon>
|
|
2316
|
+
</button>
|
|
2317
|
+
<button
|
|
2318
|
+
fButton
|
|
2319
|
+
[fTooltip]="'task.manager.view.list' | translate"
|
|
2230
2320
|
tooltipPosition="bottom"
|
|
2231
2321
|
size="small"
|
|
2232
2322
|
[severity]="viewMode() === 'list' ? 'primary' : 'secondary'"
|
|
2233
2323
|
[outlined]="viewMode() !== 'list'"
|
|
2234
|
-
|
|
2235
|
-
(
|
|
2236
|
-
|
|
2324
|
+
class="!rounded-none !border-0"
|
|
2325
|
+
(click)="viewMode.set('list')"
|
|
2326
|
+
>
|
|
2327
|
+
<ui-icon pButtonIcon name="list"></ui-icon>
|
|
2328
|
+
</button>
|
|
2237
2329
|
</div>
|
|
2238
2330
|
|
|
2239
|
-
<div
|
|
2331
|
+
<div
|
|
2332
|
+
class="h-5 w-px bg-surface-300 dark:bg-surface-600 mx-0.5"
|
|
2333
|
+
></div>
|
|
2240
2334
|
|
|
2241
|
-
<
|
|
2242
|
-
|
|
2335
|
+
<button
|
|
2336
|
+
fButton
|
|
2243
2337
|
[text]="true"
|
|
2244
2338
|
severity="secondary"
|
|
2245
2339
|
size="small"
|
|
2246
|
-
|
|
2247
|
-
[
|
|
2340
|
+
class="!w-8 !h-8"
|
|
2341
|
+
[fTooltip]="'task.manager.board.manage.members' | translate"
|
|
2248
2342
|
tooltipPosition="bottom"
|
|
2249
|
-
(
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2343
|
+
(click)="showMembersDialog.set(true)"
|
|
2344
|
+
>
|
|
2345
|
+
<ui-icon pButtonIcon name="users"></ui-icon>
|
|
2346
|
+
</button>
|
|
2347
|
+
<button
|
|
2348
|
+
fButton
|
|
2253
2349
|
[text]="true"
|
|
2254
2350
|
severity="secondary"
|
|
2255
2351
|
size="small"
|
|
2256
|
-
|
|
2257
|
-
[
|
|
2352
|
+
class="!w-8 !h-8"
|
|
2353
|
+
[fTooltip]="'task.manager.board.manage.labels' | translate"
|
|
2258
2354
|
tooltipPosition="bottom"
|
|
2259
|
-
(
|
|
2260
|
-
|
|
2355
|
+
(click)="showLabelsDialog.set(true)"
|
|
2356
|
+
>
|
|
2357
|
+
<ui-icon pButtonIcon name="tag"></ui-icon>
|
|
2358
|
+
</button>
|
|
2261
2359
|
|
|
2262
2360
|
@if (viewMode() === 'board') {
|
|
2263
|
-
<div
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2361
|
+
<div
|
|
2362
|
+
class="h-5 w-px bg-surface-300 dark:bg-surface-600 mx-0.5"
|
|
2363
|
+
></div>
|
|
2364
|
+
<button
|
|
2365
|
+
fButton
|
|
2267
2366
|
size="small"
|
|
2268
|
-
(
|
|
2269
|
-
|
|
2367
|
+
(click)="showAddListDialog.set(true)"
|
|
2368
|
+
>
|
|
2369
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
2370
|
+
<span pButtonLabel>{{
|
|
2371
|
+
'task.manager.board.add.list' | translate
|
|
2372
|
+
}}</span>
|
|
2373
|
+
</button>
|
|
2270
2374
|
}
|
|
2271
2375
|
</div>
|
|
2272
2376
|
</div>
|
|
2273
2377
|
|
|
2274
2378
|
@if (state.activeBoard(); as board) {
|
|
2275
|
-
<div
|
|
2379
|
+
<div
|
|
2380
|
+
class="h-0.5 w-full flex-shrink-0"
|
|
2381
|
+
[style.background-color]="board.color"
|
|
2382
|
+
></div>
|
|
2276
2383
|
}
|
|
2277
2384
|
</div>
|
|
2278
2385
|
|
|
@@ -2281,9 +2388,9 @@ class BoardViewPageComponent {
|
|
|
2281
2388
|
<div class="flex gap-4 p-6 overflow-x-auto">
|
|
2282
2389
|
@for (i of [1, 2, 3]; track i) {
|
|
2283
2390
|
<div class="flex-shrink-0 w-72">
|
|
2284
|
-
<
|
|
2391
|
+
<f-skeleton height="36px" class="mb-3" />
|
|
2285
2392
|
@for (j of [1, 2, 3]; track j) {
|
|
2286
|
-
<
|
|
2393
|
+
<f-skeleton height="90px" class="mb-2" />
|
|
2287
2394
|
}
|
|
2288
2395
|
</div>
|
|
2289
2396
|
}
|
|
@@ -2291,11 +2398,10 @@ class BoardViewPageComponent {
|
|
|
2291
2398
|
} @else {
|
|
2292
2399
|
<div class="p-6">
|
|
2293
2400
|
@for (i of [1, 2, 3, 4, 5]; track i) {
|
|
2294
|
-
<
|
|
2401
|
+
<f-skeleton height="48px" class="mb-2" />
|
|
2295
2402
|
}
|
|
2296
2403
|
</div>
|
|
2297
2404
|
}
|
|
2298
|
-
|
|
2299
2405
|
} @else if (viewMode() === 'board') {
|
|
2300
2406
|
<div
|
|
2301
2407
|
class="flex gap-4 p-5 overflow-x-auto flex-1"
|
|
@@ -2307,21 +2413,21 @@ class BoardViewPageComponent {
|
|
|
2307
2413
|
@for (list of state.listsWithTasks(); track list.id) {
|
|
2308
2414
|
<div
|
|
2309
2415
|
cdkDrag
|
|
2310
|
-
class="flex-shrink-0 w-72 flex flex-col max-h-[calc(100vh-140px)] self-start"
|
|
2416
|
+
class="flex-shrink-0 w-72 flex flex-col max-h-[calc(100vh-140px)] self-start rounded-border border border-surface shadow-sm overflow-hidden"
|
|
2311
2417
|
>
|
|
2312
2418
|
<div
|
|
2313
|
-
class="flex items-center gap-1 px-2 py-2.5
|
|
2314
|
-
[style.border-top]="'3px solid ' + list.color"
|
|
2419
|
+
class="flex items-center gap-1 px-2.5 py-2.5 border-b border-surface"
|
|
2315
2420
|
>
|
|
2316
|
-
<
|
|
2421
|
+
<ui-icon
|
|
2317
2422
|
cdkDragHandle
|
|
2318
|
-
|
|
2319
|
-
|
|
2423
|
+
name="bars"
|
|
2424
|
+
class="text-muted-color text-xs cursor-grab flex-shrink-0 px-1"
|
|
2425
|
+
></ui-icon>
|
|
2320
2426
|
|
|
2321
2427
|
<div class="flex items-center gap-2 min-w-0 flex-1">
|
|
2322
2428
|
@if (editingListId() === list.id) {
|
|
2323
2429
|
<input
|
|
2324
|
-
|
|
2430
|
+
fInputText
|
|
2325
2431
|
class="text-sm font-semibold !h-6 !py-0 !px-1 w-full"
|
|
2326
2432
|
[ngModel]="editingListNameValue()"
|
|
2327
2433
|
(ngModelChange)="editingListNameValue.set($event)"
|
|
@@ -2332,7 +2438,9 @@ class BoardViewPageComponent {
|
|
|
2332
2438
|
autofocus
|
|
2333
2439
|
/>
|
|
2334
2440
|
} @else {
|
|
2335
|
-
<span class="font-semibold text-sm truncate">{{
|
|
2441
|
+
<span class="font-semibold text-sm truncate">{{
|
|
2442
|
+
list.name
|
|
2443
|
+
}}</span>
|
|
2336
2444
|
<span
|
|
2337
2445
|
class="text-[11px] font-semibold px-1.5 py-0.5 rounded-full text-white flex-shrink-0"
|
|
2338
2446
|
[style.background-color]="list.color"
|
|
@@ -2343,35 +2451,41 @@ class BoardViewPageComponent {
|
|
|
2343
2451
|
</div>
|
|
2344
2452
|
|
|
2345
2453
|
@if (editingListId() === list.id) {
|
|
2346
|
-
<
|
|
2347
|
-
|
|
2454
|
+
<button
|
|
2455
|
+
fButton
|
|
2348
2456
|
[text]="true"
|
|
2349
2457
|
size="small"
|
|
2350
2458
|
severity="success"
|
|
2351
|
-
|
|
2459
|
+
class="!w-6 !h-6 flex-shrink-0"
|
|
2352
2460
|
(mousedown)="$event.preventDefault()"
|
|
2353
2461
|
(click)="saveRenameList(); $event.stopPropagation()"
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2462
|
+
>
|
|
2463
|
+
<ui-icon pButtonIcon name="check"></ui-icon>
|
|
2464
|
+
</button>
|
|
2465
|
+
<button
|
|
2466
|
+
fButton
|
|
2357
2467
|
[text]="true"
|
|
2358
2468
|
size="small"
|
|
2359
2469
|
severity="secondary"
|
|
2360
|
-
|
|
2470
|
+
class="!w-6 !h-6 flex-shrink-0"
|
|
2361
2471
|
(mousedown)="$event.preventDefault()"
|
|
2362
2472
|
(click)="cancelRenameList(); $event.stopPropagation()"
|
|
2363
|
-
|
|
2473
|
+
>
|
|
2474
|
+
<ui-icon pButtonIcon name="times"></ui-icon>
|
|
2475
|
+
</button>
|
|
2364
2476
|
} @else {
|
|
2365
|
-
<
|
|
2366
|
-
|
|
2477
|
+
<button
|
|
2478
|
+
fButton
|
|
2367
2479
|
[text]="true"
|
|
2368
2480
|
size="small"
|
|
2369
2481
|
severity="secondary"
|
|
2370
|
-
|
|
2371
|
-
[
|
|
2482
|
+
class="!w-6 !h-6 flex-shrink-0"
|
|
2483
|
+
[fTooltip]="'task.manager.list.rename' | translate"
|
|
2372
2484
|
tooltipPosition="bottom"
|
|
2373
2485
|
(click)="startRenameList(list); $event.stopPropagation()"
|
|
2374
|
-
|
|
2486
|
+
>
|
|
2487
|
+
<ui-icon pButtonIcon name="pencil"></ui-icon>
|
|
2488
|
+
</button>
|
|
2375
2489
|
}
|
|
2376
2490
|
</div>
|
|
2377
2491
|
|
|
@@ -2381,7 +2495,7 @@ class BoardViewPageComponent {
|
|
|
2381
2495
|
[cdkDropListData]="list.tasks"
|
|
2382
2496
|
[cdkDropListConnectedTo]="listDropIds()"
|
|
2383
2497
|
(cdkDropListDropped)="onTaskDrop($event)"
|
|
2384
|
-
class="flex flex-col gap-2 p-2 overflow-y-auto flex-1 min-h-[60px]
|
|
2498
|
+
class="flex flex-col gap-2 p-2 overflow-y-auto flex-1 min-h-[60px]"
|
|
2385
2499
|
>
|
|
2386
2500
|
@for (task of list.tasks; track task.id) {
|
|
2387
2501
|
<div cdkDrag>
|
|
@@ -2395,91 +2509,99 @@ class BoardViewPageComponent {
|
|
|
2395
2509
|
}
|
|
2396
2510
|
@if (list.tasks.length === 0) {
|
|
2397
2511
|
<div
|
|
2398
|
-
class="flex items-center justify-center h-14 border-2 border-dashed border-surface
|
|
2512
|
+
class="flex items-center justify-center h-14 border-2 border-dashed border-surface rounded-border"
|
|
2399
2513
|
>
|
|
2400
|
-
<span class="text-xs text-
|
|
2514
|
+
<span class="text-xs text-muted-color">{{
|
|
2401
2515
|
'task.manager.board.drop.tasks.here' | translate
|
|
2402
2516
|
}}</span>
|
|
2403
2517
|
</div>
|
|
2404
2518
|
}
|
|
2405
2519
|
</div>
|
|
2406
2520
|
|
|
2407
|
-
<div
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
<p-button
|
|
2411
|
-
icon="pi pi-plus"
|
|
2412
|
-
[label]="'task.manager.board.add.task' | translate"
|
|
2521
|
+
<div class="border-t border-surface p-1.5">
|
|
2522
|
+
<button
|
|
2523
|
+
fButton
|
|
2413
2524
|
severity="secondary"
|
|
2525
|
+
[text]="true"
|
|
2414
2526
|
size="small"
|
|
2415
|
-
|
|
2416
|
-
(
|
|
2417
|
-
|
|
2527
|
+
class="w-full !justify-start"
|
|
2528
|
+
(click)="openAddTask(list)"
|
|
2529
|
+
>
|
|
2530
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
2531
|
+
<span pButtonLabel>{{
|
|
2532
|
+
'task.manager.board.add.task' | translate
|
|
2533
|
+
}}</span>
|
|
2534
|
+
</button>
|
|
2418
2535
|
</div>
|
|
2419
2536
|
</div>
|
|
2420
2537
|
}
|
|
2421
2538
|
|
|
2422
2539
|
@if (state.listsWithTasks().length === 0) {
|
|
2423
2540
|
<div class="flex-1 flex items-center justify-center">
|
|
2424
|
-
<div class="text-center text-
|
|
2541
|
+
<div class="text-center text-muted-color">
|
|
2425
2542
|
<div
|
|
2426
|
-
class="w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-4"
|
|
2543
|
+
class="w-16 h-16 rounded-2xl border-2 border-dashed border-surface flex items-center justify-center mx-auto mb-4"
|
|
2427
2544
|
>
|
|
2428
|
-
<
|
|
2429
|
-
|
|
2430
|
-
|
|
2545
|
+
<ui-icon
|
|
2546
|
+
name="list"
|
|
2547
|
+
class="text-3xl text-muted-color"
|
|
2548
|
+
></ui-icon>
|
|
2431
2549
|
</div>
|
|
2432
|
-
<p class="font-medium text-
|
|
2550
|
+
<p class="font-medium text-muted-color">
|
|
2433
2551
|
{{ 'task.manager.board.list.empty' | translate }}
|
|
2434
2552
|
</p>
|
|
2435
|
-
<
|
|
2436
|
-
|
|
2437
|
-
[label]="'task.manager.board.add.list' | translate"
|
|
2553
|
+
<button
|
|
2554
|
+
fButton
|
|
2438
2555
|
severity="secondary"
|
|
2439
2556
|
size="small"
|
|
2440
2557
|
class="mt-3"
|
|
2441
|
-
(
|
|
2442
|
-
|
|
2558
|
+
(click)="showAddListDialog.set(true)"
|
|
2559
|
+
>
|
|
2560
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
2561
|
+
<span pButtonLabel>{{
|
|
2562
|
+
'task.manager.board.add.list' | translate
|
|
2563
|
+
}}</span>
|
|
2564
|
+
</button>
|
|
2443
2565
|
</div>
|
|
2444
2566
|
</div>
|
|
2445
2567
|
}
|
|
2446
2568
|
</div>
|
|
2447
|
-
|
|
2448
2569
|
} @else {
|
|
2449
2570
|
<div class="p-4 sm:p-6 flex-1 overflow-auto">
|
|
2450
2571
|
<div class="card">
|
|
2451
2572
|
<div class="overflow-x-auto -mx-4 sm:mx-0">
|
|
2452
|
-
<
|
|
2573
|
+
<f-table
|
|
2453
2574
|
[value]="allTasksFlat()"
|
|
2454
2575
|
[paginator]="allTasksFlat().length > 20"
|
|
2455
2576
|
[rows]="20"
|
|
2456
2577
|
[rowsPerPageOptions]="[10, 20, 50]"
|
|
2457
2578
|
[scrollable]="true"
|
|
2458
|
-
class="p-datatable-sm"
|
|
2459
2579
|
[tableStyle]="{ 'min-width': '700px' }"
|
|
2460
2580
|
>
|
|
2461
2581
|
<ng-template #header>
|
|
2462
2582
|
<tr>
|
|
2463
|
-
<th
|
|
2583
|
+
<th fSortableColumn="title" class="min-w-[240px]">
|
|
2464
2584
|
{{ 'task.manager.table.title' | translate }}
|
|
2465
|
-
<
|
|
2585
|
+
<f-sorticon field="title" />
|
|
2466
2586
|
</th>
|
|
2467
|
-
<th
|
|
2587
|
+
<th fSortableColumn="listName" class="w-40">
|
|
2468
2588
|
{{ 'task.manager.table.list' | translate }}
|
|
2469
|
-
<
|
|
2589
|
+
<f-sorticon field="listName" />
|
|
2470
2590
|
</th>
|
|
2471
|
-
<th
|
|
2591
|
+
<th fSortableColumn="priority" class="w-32">
|
|
2472
2592
|
{{ 'task.manager.table.priority' | translate }}
|
|
2473
|
-
<
|
|
2593
|
+
<f-sorticon field="priority" />
|
|
2474
2594
|
</th>
|
|
2475
2595
|
<th class="w-36">
|
|
2476
2596
|
{{ 'task.manager.table.assignee' | translate }}
|
|
2477
2597
|
</th>
|
|
2478
|
-
<th
|
|
2598
|
+
<th fSortableColumn="dueDate" class="w-32">
|
|
2479
2599
|
{{ 'task.manager.table.due.date' | translate }}
|
|
2480
|
-
<
|
|
2600
|
+
<f-sorticon field="dueDate" />
|
|
2601
|
+
</th>
|
|
2602
|
+
<th class="w-[100px]">
|
|
2603
|
+
{{ 'shared.actions' | translate }}
|
|
2481
2604
|
</th>
|
|
2482
|
-
<th class="w-[100px]">{{ 'shared.actions' | translate }}</th>
|
|
2483
2605
|
</tr>
|
|
2484
2606
|
</ng-template>
|
|
2485
2607
|
<ng-template #body let-task>
|
|
@@ -2488,7 +2610,8 @@ class BoardViewPageComponent {
|
|
|
2488
2610
|
<span
|
|
2489
2611
|
class="font-medium text-sm cursor-pointer hover:text-primary-500 transition-colors"
|
|
2490
2612
|
(click)="state.selectTask(task)"
|
|
2491
|
-
|
|
2613
|
+
>{{ task.title }}</span
|
|
2614
|
+
>
|
|
2492
2615
|
</td>
|
|
2493
2616
|
<td>
|
|
2494
2617
|
<span class="inline-flex items-center gap-1.5 text-sm">
|
|
@@ -2500,7 +2623,7 @@ class BoardViewPageComponent {
|
|
|
2500
2623
|
</span>
|
|
2501
2624
|
</td>
|
|
2502
2625
|
<td>
|
|
2503
|
-
<
|
|
2626
|
+
<f-tag
|
|
2504
2627
|
[value]="task.priority"
|
|
2505
2628
|
[severity]="prioritySeverity(task.priority)"
|
|
2506
2629
|
/>
|
|
@@ -2508,21 +2631,26 @@ class BoardViewPageComponent {
|
|
|
2508
2631
|
<td>
|
|
2509
2632
|
@if (task.assignees?.length) {
|
|
2510
2633
|
<div class="flex items-center -space-x-1.5">
|
|
2511
|
-
@for (
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2634
|
+
@for (
|
|
2635
|
+
a of task.assignees!.slice(0, 3);
|
|
2636
|
+
track a.userId
|
|
2637
|
+
) {
|
|
2638
|
+
<f-avatar
|
|
2639
|
+
shape="circle"
|
|
2640
|
+
size="small"
|
|
2641
|
+
[label]="getMemberInitials(a.userId)"
|
|
2642
|
+
[color]="memberColorById(a.userId)"
|
|
2643
|
+
styleClass="!ring-surface-card flex-shrink-0"
|
|
2644
|
+
[fTooltip]="a.userName ?? ''"
|
|
2645
|
+
/>
|
|
2519
2646
|
}
|
|
2520
2647
|
@if (task.assignees!.length > 3) {
|
|
2521
|
-
<
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
+
|
|
2525
|
-
|
|
2648
|
+
<f-avatar
|
|
2649
|
+
shape="circle"
|
|
2650
|
+
size="small"
|
|
2651
|
+
[label]="'+' + (task.assignees!.length - 3)"
|
|
2652
|
+
styleClass="!bg-surface-200 dark:!bg-surface-700 !text-surface-600 !ring-surface-card flex-shrink-0"
|
|
2653
|
+
/>
|
|
2526
2654
|
}
|
|
2527
2655
|
</div>
|
|
2528
2656
|
} @else {
|
|
@@ -2543,22 +2671,26 @@ class BoardViewPageComponent {
|
|
|
2543
2671
|
</td>
|
|
2544
2672
|
<td>
|
|
2545
2673
|
<div class="flex gap-1">
|
|
2546
|
-
<
|
|
2547
|
-
|
|
2674
|
+
<button
|
|
2675
|
+
fButton
|
|
2548
2676
|
[text]="true"
|
|
2549
2677
|
severity="secondary"
|
|
2550
2678
|
size="small"
|
|
2551
|
-
[
|
|
2552
|
-
(
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2679
|
+
[fTooltip]="'shared.edit' | translate"
|
|
2680
|
+
(click)="onEditTask(task)"
|
|
2681
|
+
>
|
|
2682
|
+
<ui-icon pButtonIcon name="pencil"></ui-icon>
|
|
2683
|
+
</button>
|
|
2684
|
+
<button
|
|
2685
|
+
fButton
|
|
2556
2686
|
[text]="true"
|
|
2557
2687
|
severity="danger"
|
|
2558
2688
|
size="small"
|
|
2559
|
-
[
|
|
2560
|
-
(
|
|
2561
|
-
|
|
2689
|
+
[fTooltip]="'shared.delete' | translate"
|
|
2690
|
+
(click)="onDeleteTask(task)"
|
|
2691
|
+
>
|
|
2692
|
+
<ui-icon pButtonIcon name="trash"></ui-icon>
|
|
2693
|
+
</button>
|
|
2562
2694
|
</div>
|
|
2563
2695
|
</td>
|
|
2564
2696
|
</tr>
|
|
@@ -2566,12 +2698,15 @@ class BoardViewPageComponent {
|
|
|
2566
2698
|
<ng-template #emptymessage>
|
|
2567
2699
|
<tr>
|
|
2568
2700
|
<td colspan="6" class="text-center text-muted-color py-8">
|
|
2569
|
-
<
|
|
2701
|
+
<ui-icon
|
|
2702
|
+
name="inbox"
|
|
2703
|
+
class="text-4xl block mb-3"
|
|
2704
|
+
></ui-icon>
|
|
2570
2705
|
{{ 'task.manager.table.empty' | translate }}
|
|
2571
2706
|
</td>
|
|
2572
2707
|
</tr>
|
|
2573
2708
|
</ng-template>
|
|
2574
|
-
</
|
|
2709
|
+
</f-table>
|
|
2575
2710
|
</div>
|
|
2576
2711
|
</div>
|
|
2577
2712
|
</div>
|
|
@@ -2594,12 +2729,12 @@ class BoardViewPageComponent {
|
|
|
2594
2729
|
(editTask)="onEditTask($event)"
|
|
2595
2730
|
/>
|
|
2596
2731
|
|
|
2597
|
-
<
|
|
2732
|
+
<f-dialog
|
|
2598
2733
|
[header]="'task.manager.label.manage.title' | translate"
|
|
2599
2734
|
[(visible)]="showLabelsDialog"
|
|
2600
2735
|
[modal]="true"
|
|
2601
2736
|
[style]="{ width: '420px' }"
|
|
2602
|
-
(onHide)="newLabelName = ''; newLabelColor =
|
|
2737
|
+
(onHide)="newLabelName = ''; newLabelColor = boardColorPalette[0]"
|
|
2603
2738
|
>
|
|
2604
2739
|
<div class="flex flex-col gap-4 py-2">
|
|
2605
2740
|
<div class="flex gap-2 items-end">
|
|
@@ -2608,7 +2743,7 @@ class BoardViewPageComponent {
|
|
|
2608
2743
|
'task.manager.label.name.label' | translate
|
|
2609
2744
|
}}</label>
|
|
2610
2745
|
<input
|
|
2611
|
-
|
|
2746
|
+
fInputText
|
|
2612
2747
|
[(ngModel)]="newLabelName"
|
|
2613
2748
|
[placeholder]="'task.manager.label.name.placeholder' | translate"
|
|
2614
2749
|
/>
|
|
@@ -2623,24 +2758,30 @@ class BoardViewPageComponent {
|
|
|
2623
2758
|
class="w-10 h-10 rounded cursor-pointer border border-surface-300"
|
|
2624
2759
|
/>
|
|
2625
2760
|
</div>
|
|
2626
|
-
<
|
|
2627
|
-
|
|
2628
|
-
[label]="'task.manager.label.add' | translate"
|
|
2761
|
+
<button
|
|
2762
|
+
fButton
|
|
2629
2763
|
size="small"
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2764
|
+
(click)="addLabel()"
|
|
2765
|
+
[disabled]="isAddingLabel()"
|
|
2766
|
+
>
|
|
2767
|
+
@if (isAddingLabel()) {
|
|
2768
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
2769
|
+
} @else {
|
|
2770
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
2771
|
+
}
|
|
2772
|
+
<span pButtonLabel>{{ 'task.manager.label.add' | translate }}</span>
|
|
2773
|
+
</button>
|
|
2633
2774
|
</div>
|
|
2634
2775
|
|
|
2635
2776
|
<div class="flex flex-col gap-2 max-h-64 overflow-y-auto">
|
|
2636
2777
|
@if (state.labels().length === 0) {
|
|
2637
|
-
<p class="text-sm text-
|
|
2778
|
+
<p class="text-sm text-muted-color text-center py-4">
|
|
2638
2779
|
{{ 'task.manager.label.no.labels' | translate }}
|
|
2639
2780
|
</p>
|
|
2640
2781
|
}
|
|
2641
2782
|
@for (label of state.labels(); track label.id) {
|
|
2642
2783
|
<div
|
|
2643
|
-
class="flex items-center justify-between px-3 py-2 rounded-
|
|
2784
|
+
class="flex items-center justify-between px-3 py-2 rounded-border border border-surface"
|
|
2644
2785
|
>
|
|
2645
2786
|
<div class="flex items-center gap-2">
|
|
2646
2787
|
<span
|
|
@@ -2649,20 +2790,22 @@ class BoardViewPageComponent {
|
|
|
2649
2790
|
></span>
|
|
2650
2791
|
<span class="text-sm font-medium">{{ label.name }}</span>
|
|
2651
2792
|
</div>
|
|
2652
|
-
<
|
|
2653
|
-
|
|
2793
|
+
<button
|
|
2794
|
+
fButton
|
|
2654
2795
|
severity="danger"
|
|
2655
2796
|
size="small"
|
|
2656
2797
|
[text]="true"
|
|
2657
|
-
(
|
|
2658
|
-
|
|
2798
|
+
(click)="removeLabel(label.id)"
|
|
2799
|
+
>
|
|
2800
|
+
<ui-icon pButtonIcon name="trash"></ui-icon>
|
|
2801
|
+
</button>
|
|
2659
2802
|
</div>
|
|
2660
2803
|
}
|
|
2661
2804
|
</div>
|
|
2662
2805
|
</div>
|
|
2663
|
-
</
|
|
2806
|
+
</f-dialog>
|
|
2664
2807
|
|
|
2665
|
-
<
|
|
2808
|
+
<f-dialog
|
|
2666
2809
|
[header]="'task.manager.member.manage.title' | translate"
|
|
2667
2810
|
[(visible)]="showMembersDialog"
|
|
2668
2811
|
[modal]="true"
|
|
@@ -2687,7 +2830,7 @@ class BoardViewPageComponent {
|
|
|
2687
2830
|
<label class="text-sm font-medium">{{
|
|
2688
2831
|
'task.manager.member.role.label' | translate
|
|
2689
2832
|
}}</label>
|
|
2690
|
-
<
|
|
2833
|
+
<f-select
|
|
2691
2834
|
[(ngModel)]="newMemberRole"
|
|
2692
2835
|
[options]="memberRoleOptions"
|
|
2693
2836
|
optionValue="value"
|
|
@@ -2695,7 +2838,6 @@ class BoardViewPageComponent {
|
|
|
2695
2838
|
'task.manager.member.role.placeholder' | translate
|
|
2696
2839
|
"
|
|
2697
2840
|
class="w-full"
|
|
2698
|
-
appendTo="body"
|
|
2699
2841
|
>
|
|
2700
2842
|
<ng-template #selectedItem let-opt>
|
|
2701
2843
|
{{ opt.labelKey | translate }}
|
|
@@ -2703,42 +2845,49 @@ class BoardViewPageComponent {
|
|
|
2703
2845
|
<ng-template #item let-opt>
|
|
2704
2846
|
{{ opt.labelKey | translate }}
|
|
2705
2847
|
</ng-template>
|
|
2706
|
-
</
|
|
2848
|
+
</f-select>
|
|
2707
2849
|
</div>
|
|
2708
|
-
<
|
|
2709
|
-
|
|
2710
|
-
[label]="'task.manager.member.add' | translate"
|
|
2850
|
+
<button
|
|
2851
|
+
fButton
|
|
2711
2852
|
size="small"
|
|
2712
|
-
[
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2853
|
+
[disabled]="!selectedMemberUser || isAddingMember()"
|
|
2854
|
+
(click)="addMember()"
|
|
2855
|
+
>
|
|
2856
|
+
@if (isAddingMember()) {
|
|
2857
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
2858
|
+
} @else {
|
|
2859
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
2860
|
+
}
|
|
2861
|
+
<span pButtonLabel>{{
|
|
2862
|
+
'task.manager.member.add' | translate
|
|
2863
|
+
}}</span>
|
|
2864
|
+
</button>
|
|
2716
2865
|
</div>
|
|
2717
2866
|
</div>
|
|
2718
2867
|
|
|
2719
2868
|
<div class="flex flex-col gap-2 max-h-72 overflow-y-auto">
|
|
2720
2869
|
@if (state.members().length === 0) {
|
|
2721
|
-
<p class="text-sm text-
|
|
2870
|
+
<p class="text-sm text-muted-color text-center py-4">
|
|
2722
2871
|
{{ 'task.manager.member.no.members' | translate }}
|
|
2723
2872
|
</p>
|
|
2724
2873
|
}
|
|
2725
2874
|
@for (member of state.members(); track member.id) {
|
|
2726
2875
|
<div
|
|
2727
|
-
class="flex items-center justify-between px-3 py-2.5 rounded-
|
|
2876
|
+
class="flex items-center justify-between px-3 py-2.5 rounded-border border border-surface"
|
|
2728
2877
|
>
|
|
2729
2878
|
<div class="flex items-center gap-3">
|
|
2730
|
-
<
|
|
2731
|
-
|
|
2732
|
-
[
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2879
|
+
<f-avatar
|
|
2880
|
+
shape="circle"
|
|
2881
|
+
[label]="memberInitials(member)"
|
|
2882
|
+
[color]="memberColor(member)"
|
|
2883
|
+
styleClass="!text-[11px] flex-shrink-0"
|
|
2884
|
+
/>
|
|
2736
2885
|
<div>
|
|
2737
2886
|
<div class="text-sm font-medium ">
|
|
2738
2887
|
{{ member.userName ?? member.userId }}
|
|
2739
2888
|
</div>
|
|
2740
2889
|
@if (member.userEmail) {
|
|
2741
|
-
<div class="text-xs text-
|
|
2890
|
+
<div class="text-xs text-muted-color">
|
|
2742
2891
|
{{ member.userEmail }}
|
|
2743
2892
|
</div>
|
|
2744
2893
|
}
|
|
@@ -2749,25 +2898,30 @@ class BoardViewPageComponent {
|
|
|
2749
2898
|
class="text-[10px] font-semibold px-2 py-0.5 rounded-full"
|
|
2750
2899
|
[class]="roleBadgeClass(member.role)"
|
|
2751
2900
|
>
|
|
2752
|
-
{{
|
|
2901
|
+
{{
|
|
2902
|
+
'task.manager.member.role.' + member.role.toLowerCase()
|
|
2903
|
+
| translate
|
|
2904
|
+
}}
|
|
2753
2905
|
</span>
|
|
2754
2906
|
@if (member.role !== 'OWNER') {
|
|
2755
|
-
<
|
|
2756
|
-
|
|
2907
|
+
<button
|
|
2908
|
+
fButton
|
|
2757
2909
|
severity="danger"
|
|
2758
2910
|
size="small"
|
|
2759
2911
|
[text]="true"
|
|
2760
|
-
(
|
|
2761
|
-
|
|
2912
|
+
(click)="removeMember(member.userId)"
|
|
2913
|
+
>
|
|
2914
|
+
<ui-icon pButtonIcon name="trash"></ui-icon>
|
|
2915
|
+
</button>
|
|
2762
2916
|
}
|
|
2763
2917
|
</div>
|
|
2764
2918
|
</div>
|
|
2765
2919
|
}
|
|
2766
2920
|
</div>
|
|
2767
2921
|
</div>
|
|
2768
|
-
</
|
|
2922
|
+
</f-dialog>
|
|
2769
2923
|
|
|
2770
|
-
<
|
|
2924
|
+
<f-dialog
|
|
2771
2925
|
[header]="'task.manager.list.new' | translate"
|
|
2772
2926
|
[(visible)]="showAddListDialog"
|
|
2773
2927
|
[modal]="true"
|
|
@@ -2780,28 +2934,31 @@ class BoardViewPageComponent {
|
|
|
2780
2934
|
<span class="text-red-500">*</span>
|
|
2781
2935
|
</label>
|
|
2782
2936
|
<input
|
|
2783
|
-
|
|
2937
|
+
fInputText
|
|
2784
2938
|
[(ngModel)]="newListName"
|
|
2785
2939
|
[placeholder]="'task.manager.list.name.placeholder' | translate"
|
|
2786
2940
|
/>
|
|
2787
2941
|
</div>
|
|
2788
|
-
<ng-template
|
|
2942
|
+
<ng-template #footer>
|
|
2789
2943
|
<div class="flex justify-end gap-2">
|
|
2790
|
-
<
|
|
2791
|
-
|
|
2944
|
+
<button
|
|
2945
|
+
fButton
|
|
2792
2946
|
severity="secondary"
|
|
2793
|
-
(
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
(
|
|
2799
|
-
|
|
2947
|
+
(click)="showAddListDialog.set(false)"
|
|
2948
|
+
>
|
|
2949
|
+
<span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
|
|
2950
|
+
</button>
|
|
2951
|
+
<button fButton (click)="addList()" [disabled]="isAddingList()">
|
|
2952
|
+
@if (isAddingList()) {
|
|
2953
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
2954
|
+
}
|
|
2955
|
+
<span pButtonLabel>{{ 'shared.create' | translate }}</span>
|
|
2956
|
+
</button>
|
|
2800
2957
|
</div>
|
|
2801
2958
|
</ng-template>
|
|
2802
|
-
</
|
|
2959
|
+
</f-dialog>
|
|
2803
2960
|
|
|
2804
|
-
<
|
|
2961
|
+
<f-dialog
|
|
2805
2962
|
[header]="'task.manager.board.edit' | translate"
|
|
2806
2963
|
[(visible)]="showEditBoardDialog"
|
|
2807
2964
|
[modal]="true"
|
|
@@ -2813,17 +2970,19 @@ class BoardViewPageComponent {
|
|
|
2813
2970
|
{{ 'task.manager.board.name.label' | translate }}
|
|
2814
2971
|
<span class="text-red-500">*</span>
|
|
2815
2972
|
</label>
|
|
2816
|
-
<input
|
|
2973
|
+
<input fInputText [(ngModel)]="editBoardName" />
|
|
2817
2974
|
</div>
|
|
2818
2975
|
<div class="flex flex-col gap-1">
|
|
2819
2976
|
<label class="text-sm font-medium">{{
|
|
2820
2977
|
'task.manager.board.description.label' | translate
|
|
2821
2978
|
}}</label>
|
|
2822
2979
|
<textarea
|
|
2823
|
-
|
|
2980
|
+
fTextarea
|
|
2824
2981
|
[(ngModel)]="editBoardDescription"
|
|
2825
2982
|
[rows]="3"
|
|
2826
|
-
[placeholder]="
|
|
2983
|
+
[placeholder]="
|
|
2984
|
+
'task.manager.board.description.placeholder' | translate
|
|
2985
|
+
"
|
|
2827
2986
|
></textarea>
|
|
2828
2987
|
</div>
|
|
2829
2988
|
<div class="flex flex-col gap-1">
|
|
@@ -2851,32 +3010,38 @@ class BoardViewPageComponent {
|
|
|
2851
3010
|
</div>
|
|
2852
3011
|
</div>
|
|
2853
3012
|
</div>
|
|
2854
|
-
<ng-template
|
|
3013
|
+
<ng-template #footer>
|
|
2855
3014
|
<div class="flex justify-end gap-2">
|
|
2856
|
-
<
|
|
2857
|
-
|
|
3015
|
+
<button
|
|
3016
|
+
fButton
|
|
2858
3017
|
severity="secondary"
|
|
2859
|
-
(
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
3018
|
+
(click)="showEditBoardDialog.set(false)"
|
|
3019
|
+
>
|
|
3020
|
+
<span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
|
|
3021
|
+
</button>
|
|
3022
|
+
<button
|
|
3023
|
+
fButton
|
|
3024
|
+
[disabled]="!editBoardName.trim() || isSavingBoard()"
|
|
3025
|
+
(click)="saveBoard()"
|
|
3026
|
+
>
|
|
3027
|
+
@if (isSavingBoard()) {
|
|
3028
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
3029
|
+
}
|
|
3030
|
+
<span pButtonLabel>{{ 'shared.save' | translate }}</span>
|
|
3031
|
+
</button>
|
|
2867
3032
|
</div>
|
|
2868
3033
|
</ng-template>
|
|
2869
|
-
</
|
|
2870
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type:
|
|
3034
|
+
</f-dialog>
|
|
3035
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: UiModule }, { kind: "component", type: i1.AvatarComponent, selector: "f-avatar", inputs: ["label", "icon", "image", "shape", "size", "color", "styleClass"] }, { kind: "directive", type: i1.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "rounded", "raised", "fluid", "disabled", "loading", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i1.SkeletonComponent, selector: "f-skeleton", inputs: ["width", "height", "borderRadius", "shape"] }, { kind: "component", type: i1.TagComponent, selector: "f-tag", inputs: ["value", "severity", "icon", "rounded", "color"] }, { kind: "directive", type: i1.InputTextDirective, selector: "[fInputText]", inputs: ["invalid", "touched"] }, { kind: "component", type: i1.SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "showClear", "loading", "inputId", "invalid", "touched", "styleClass", "editable"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur"] }, { kind: "directive", type: i1.TextareaDirective, selector: "[fTextarea]", inputs: ["invalid", "touched"] }, { kind: "component", type: i1.DialogComponent, selector: "f-dialog", inputs: ["header", "visible", "modal", "closable", "dismissableMask", "resizable", "style", "breakpoints"], outputs: ["visibleChange", "onShow", "onHide"] }, { kind: "component", type: i1.SortIconComponent, selector: "f-sorticon", inputs: ["field"] }, { kind: "directive", type: i1.SortableColumnDirective, selector: "[fSortableColumn]", inputs: ["fSortableColumn"] }, { kind: "component", type: i1.TableComponent, selector: "f-table", inputs: ["value", "lazy", "loading", "rows", "totalRecords", "rowHover", "dataKey", "scrollable", "paginator", "first", "rowsPerPageOptions", "showCurrentPageReport", "currentPageReportTemplate", "tableStyle", "styleClass", "globalFilterFields", "sortField", "sortOrder"], outputs: ["sortFieldChange", "sortOrderChange", "onLazyLoad", "onSort"] }, { kind: "directive", type: i1.TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay"] }, { kind: "component", type: i1.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2$1.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TaskCardComponent, selector: "tm-task-card", inputs: ["task"], outputs: ["cardClick", "editClick", "deleteClick"] }, { kind: "component", type: TaskFormDialogComponent, selector: "tm-task-form-dialog", inputs: ["visible", "task", "boardId", "listId", "members", "labels"], outputs: ["visibleChange", "saved"] }, { kind: "component", type: TaskDetailPanelComponent, selector: "tm-task-detail-panel", inputs: ["task"], outputs: ["closePanel", "editTask"] }, { kind: "component", type: UserSelectComponent, selector: "lib-user-select", inputs: ["showClear", "value"], outputs: ["valueChange", "userSelected"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
2871
3036
|
}
|
|
2872
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3037
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: BoardViewPageComponent, decorators: [{
|
|
2873
3038
|
type: Component,
|
|
2874
3039
|
args: [{
|
|
2875
3040
|
selector: 'tm-board-view-page',
|
|
2876
3041
|
imports: [
|
|
3042
|
+
UiModule,
|
|
2877
3043
|
DragDropModule,
|
|
2878
3044
|
AngularModule,
|
|
2879
|
-
PrimeModule,
|
|
2880
3045
|
TaskCardComponent,
|
|
2881
3046
|
TaskFormDialogComponent,
|
|
2882
3047
|
TaskDetailPanelComponent,
|
|
@@ -2891,22 +3056,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2891
3056
|
<div class="flex items-center gap-2.5 min-w-0 flex-1 group">
|
|
2892
3057
|
<div class="flex flex-col min-w-0">
|
|
2893
3058
|
<div class="flex items-center gap-1.5 min-w-0">
|
|
2894
|
-
<h1
|
|
3059
|
+
<h1
|
|
3060
|
+
class="text-base font-bold text-surface-900 dark:text-surface-0 truncate leading-snug"
|
|
3061
|
+
>
|
|
2895
3062
|
{{ board.name }}
|
|
2896
3063
|
</h1>
|
|
2897
|
-
<
|
|
2898
|
-
|
|
3064
|
+
<button
|
|
3065
|
+
fButton
|
|
2899
3066
|
[text]="true"
|
|
2900
3067
|
size="small"
|
|
2901
3068
|
severity="secondary"
|
|
2902
|
-
|
|
2903
|
-
[
|
|
3069
|
+
class="!w-6 !h-6 flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"
|
|
3070
|
+
[fTooltip]="'task.manager.board.edit' | translate"
|
|
2904
3071
|
tooltipPosition="bottom"
|
|
2905
|
-
(
|
|
2906
|
-
|
|
3072
|
+
(click)="openEditBoardDialog(board)"
|
|
3073
|
+
>
|
|
3074
|
+
<ui-icon pButtonIcon name="pencil"></ui-icon>
|
|
3075
|
+
</button>
|
|
2907
3076
|
</div>
|
|
2908
3077
|
@if (board.description) {
|
|
2909
|
-
<span
|
|
3078
|
+
<span
|
|
3079
|
+
class="text-xs text-muted-color truncate max-w-sm hidden md:block leading-snug"
|
|
3080
|
+
>
|
|
2910
3081
|
{{ board.description }}
|
|
2911
3082
|
</span>
|
|
2912
3083
|
}
|
|
@@ -2919,89 +3090,114 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2919
3090
|
<div
|
|
2920
3091
|
class="flex items-center -space-x-2 cursor-pointer mr-1"
|
|
2921
3092
|
(click)="showMembersDialog.set(true)"
|
|
2922
|
-
[
|
|
3093
|
+
[fTooltip]="'task.manager.board.manage.members' | translate"
|
|
2923
3094
|
tooltipPosition="bottom"
|
|
2924
3095
|
>
|
|
2925
3096
|
@for (member of state.members().slice(0, 4); track member.id) {
|
|
2926
|
-
<
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
3097
|
+
<f-avatar
|
|
3098
|
+
shape="circle"
|
|
3099
|
+
size="small"
|
|
3100
|
+
[label]="memberInitials(member)"
|
|
3101
|
+
[color]="memberColor(member)"
|
|
3102
|
+
styleClass="!border-2 !border-surface-card ring-1 ring-surface flex-shrink-0"
|
|
3103
|
+
/>
|
|
2932
3104
|
}
|
|
2933
3105
|
@if (state.members().length > 4) {
|
|
2934
|
-
<
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
+
|
|
2938
|
-
|
|
3106
|
+
<f-avatar
|
|
3107
|
+
shape="circle"
|
|
3108
|
+
size="small"
|
|
3109
|
+
[label]="'+' + (state.members().length - 4)"
|
|
3110
|
+
styleClass="!border-2 !border-surface-card !bg-surface-200 dark:!bg-surface-700 !text-surface-600 dark:!text-surface-300 flex-shrink-0"
|
|
3111
|
+
/>
|
|
2939
3112
|
}
|
|
2940
3113
|
</div>
|
|
2941
3114
|
}
|
|
2942
3115
|
|
|
2943
|
-
<div
|
|
3116
|
+
<div
|
|
3117
|
+
class="h-5 w-px bg-surface-300 dark:bg-surface-600 mx-0.5"
|
|
3118
|
+
></div>
|
|
2944
3119
|
|
|
2945
|
-
<div
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
3120
|
+
<div
|
|
3121
|
+
class="flex rounded-border overflow-hidden border border-surface"
|
|
3122
|
+
>
|
|
3123
|
+
<button
|
|
3124
|
+
fButton
|
|
3125
|
+
[fTooltip]="'task.manager.view.board' | translate"
|
|
2949
3126
|
tooltipPosition="bottom"
|
|
2950
3127
|
size="small"
|
|
2951
3128
|
[severity]="viewMode() === 'board' ? 'primary' : 'secondary'"
|
|
2952
3129
|
[outlined]="viewMode() !== 'board'"
|
|
2953
|
-
|
|
2954
|
-
(
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
3130
|
+
class="!rounded-none !border-0"
|
|
3131
|
+
(click)="viewMode.set('board')"
|
|
3132
|
+
>
|
|
3133
|
+
<ui-icon pButtonIcon name="th-large"></ui-icon>
|
|
3134
|
+
</button>
|
|
3135
|
+
<button
|
|
3136
|
+
fButton
|
|
3137
|
+
[fTooltip]="'task.manager.view.list' | translate"
|
|
2959
3138
|
tooltipPosition="bottom"
|
|
2960
3139
|
size="small"
|
|
2961
3140
|
[severity]="viewMode() === 'list' ? 'primary' : 'secondary'"
|
|
2962
3141
|
[outlined]="viewMode() !== 'list'"
|
|
2963
|
-
|
|
2964
|
-
(
|
|
2965
|
-
|
|
3142
|
+
class="!rounded-none !border-0"
|
|
3143
|
+
(click)="viewMode.set('list')"
|
|
3144
|
+
>
|
|
3145
|
+
<ui-icon pButtonIcon name="list"></ui-icon>
|
|
3146
|
+
</button>
|
|
2966
3147
|
</div>
|
|
2967
3148
|
|
|
2968
|
-
<div
|
|
3149
|
+
<div
|
|
3150
|
+
class="h-5 w-px bg-surface-300 dark:bg-surface-600 mx-0.5"
|
|
3151
|
+
></div>
|
|
2969
3152
|
|
|
2970
|
-
<
|
|
2971
|
-
|
|
3153
|
+
<button
|
|
3154
|
+
fButton
|
|
2972
3155
|
[text]="true"
|
|
2973
3156
|
severity="secondary"
|
|
2974
3157
|
size="small"
|
|
2975
|
-
|
|
2976
|
-
[
|
|
3158
|
+
class="!w-8 !h-8"
|
|
3159
|
+
[fTooltip]="'task.manager.board.manage.members' | translate"
|
|
2977
3160
|
tooltipPosition="bottom"
|
|
2978
|
-
(
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
3161
|
+
(click)="showMembersDialog.set(true)"
|
|
3162
|
+
>
|
|
3163
|
+
<ui-icon pButtonIcon name="users"></ui-icon>
|
|
3164
|
+
</button>
|
|
3165
|
+
<button
|
|
3166
|
+
fButton
|
|
2982
3167
|
[text]="true"
|
|
2983
3168
|
severity="secondary"
|
|
2984
3169
|
size="small"
|
|
2985
|
-
|
|
2986
|
-
[
|
|
3170
|
+
class="!w-8 !h-8"
|
|
3171
|
+
[fTooltip]="'task.manager.board.manage.labels' | translate"
|
|
2987
3172
|
tooltipPosition="bottom"
|
|
2988
|
-
(
|
|
2989
|
-
|
|
3173
|
+
(click)="showLabelsDialog.set(true)"
|
|
3174
|
+
>
|
|
3175
|
+
<ui-icon pButtonIcon name="tag"></ui-icon>
|
|
3176
|
+
</button>
|
|
2990
3177
|
|
|
2991
3178
|
@if (viewMode() === 'board') {
|
|
2992
|
-
<div
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
3179
|
+
<div
|
|
3180
|
+
class="h-5 w-px bg-surface-300 dark:bg-surface-600 mx-0.5"
|
|
3181
|
+
></div>
|
|
3182
|
+
<button
|
|
3183
|
+
fButton
|
|
2996
3184
|
size="small"
|
|
2997
|
-
(
|
|
2998
|
-
|
|
3185
|
+
(click)="showAddListDialog.set(true)"
|
|
3186
|
+
>
|
|
3187
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
3188
|
+
<span pButtonLabel>{{
|
|
3189
|
+
'task.manager.board.add.list' | translate
|
|
3190
|
+
}}</span>
|
|
3191
|
+
</button>
|
|
2999
3192
|
}
|
|
3000
3193
|
</div>
|
|
3001
3194
|
</div>
|
|
3002
3195
|
|
|
3003
3196
|
@if (state.activeBoard(); as board) {
|
|
3004
|
-
<div
|
|
3197
|
+
<div
|
|
3198
|
+
class="h-0.5 w-full flex-shrink-0"
|
|
3199
|
+
[style.background-color]="board.color"
|
|
3200
|
+
></div>
|
|
3005
3201
|
}
|
|
3006
3202
|
</div>
|
|
3007
3203
|
|
|
@@ -3010,9 +3206,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3010
3206
|
<div class="flex gap-4 p-6 overflow-x-auto">
|
|
3011
3207
|
@for (i of [1, 2, 3]; track i) {
|
|
3012
3208
|
<div class="flex-shrink-0 w-72">
|
|
3013
|
-
<
|
|
3209
|
+
<f-skeleton height="36px" class="mb-3" />
|
|
3014
3210
|
@for (j of [1, 2, 3]; track j) {
|
|
3015
|
-
<
|
|
3211
|
+
<f-skeleton height="90px" class="mb-2" />
|
|
3016
3212
|
}
|
|
3017
3213
|
</div>
|
|
3018
3214
|
}
|
|
@@ -3020,11 +3216,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3020
3216
|
} @else {
|
|
3021
3217
|
<div class="p-6">
|
|
3022
3218
|
@for (i of [1, 2, 3, 4, 5]; track i) {
|
|
3023
|
-
<
|
|
3219
|
+
<f-skeleton height="48px" class="mb-2" />
|
|
3024
3220
|
}
|
|
3025
3221
|
</div>
|
|
3026
3222
|
}
|
|
3027
|
-
|
|
3028
3223
|
} @else if (viewMode() === 'board') {
|
|
3029
3224
|
<div
|
|
3030
3225
|
class="flex gap-4 p-5 overflow-x-auto flex-1"
|
|
@@ -3036,21 +3231,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3036
3231
|
@for (list of state.listsWithTasks(); track list.id) {
|
|
3037
3232
|
<div
|
|
3038
3233
|
cdkDrag
|
|
3039
|
-
class="flex-shrink-0 w-72 flex flex-col max-h-[calc(100vh-140px)] self-start"
|
|
3234
|
+
class="flex-shrink-0 w-72 flex flex-col max-h-[calc(100vh-140px)] self-start rounded-border border border-surface shadow-sm overflow-hidden"
|
|
3040
3235
|
>
|
|
3041
3236
|
<div
|
|
3042
|
-
class="flex items-center gap-1 px-2 py-2.5
|
|
3043
|
-
[style.border-top]="'3px solid ' + list.color"
|
|
3237
|
+
class="flex items-center gap-1 px-2.5 py-2.5 border-b border-surface"
|
|
3044
3238
|
>
|
|
3045
|
-
<
|
|
3239
|
+
<ui-icon
|
|
3046
3240
|
cdkDragHandle
|
|
3047
|
-
|
|
3048
|
-
|
|
3241
|
+
name="bars"
|
|
3242
|
+
class="text-muted-color text-xs cursor-grab flex-shrink-0 px-1"
|
|
3243
|
+
></ui-icon>
|
|
3049
3244
|
|
|
3050
3245
|
<div class="flex items-center gap-2 min-w-0 flex-1">
|
|
3051
3246
|
@if (editingListId() === list.id) {
|
|
3052
3247
|
<input
|
|
3053
|
-
|
|
3248
|
+
fInputText
|
|
3054
3249
|
class="text-sm font-semibold !h-6 !py-0 !px-1 w-full"
|
|
3055
3250
|
[ngModel]="editingListNameValue()"
|
|
3056
3251
|
(ngModelChange)="editingListNameValue.set($event)"
|
|
@@ -3061,7 +3256,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3061
3256
|
autofocus
|
|
3062
3257
|
/>
|
|
3063
3258
|
} @else {
|
|
3064
|
-
<span class="font-semibold text-sm truncate">{{
|
|
3259
|
+
<span class="font-semibold text-sm truncate">{{
|
|
3260
|
+
list.name
|
|
3261
|
+
}}</span>
|
|
3065
3262
|
<span
|
|
3066
3263
|
class="text-[11px] font-semibold px-1.5 py-0.5 rounded-full text-white flex-shrink-0"
|
|
3067
3264
|
[style.background-color]="list.color"
|
|
@@ -3072,35 +3269,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3072
3269
|
</div>
|
|
3073
3270
|
|
|
3074
3271
|
@if (editingListId() === list.id) {
|
|
3075
|
-
<
|
|
3076
|
-
|
|
3272
|
+
<button
|
|
3273
|
+
fButton
|
|
3077
3274
|
[text]="true"
|
|
3078
3275
|
size="small"
|
|
3079
3276
|
severity="success"
|
|
3080
|
-
|
|
3277
|
+
class="!w-6 !h-6 flex-shrink-0"
|
|
3081
3278
|
(mousedown)="$event.preventDefault()"
|
|
3082
3279
|
(click)="saveRenameList(); $event.stopPropagation()"
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3280
|
+
>
|
|
3281
|
+
<ui-icon pButtonIcon name="check"></ui-icon>
|
|
3282
|
+
</button>
|
|
3283
|
+
<button
|
|
3284
|
+
fButton
|
|
3086
3285
|
[text]="true"
|
|
3087
3286
|
size="small"
|
|
3088
3287
|
severity="secondary"
|
|
3089
|
-
|
|
3288
|
+
class="!w-6 !h-6 flex-shrink-0"
|
|
3090
3289
|
(mousedown)="$event.preventDefault()"
|
|
3091
3290
|
(click)="cancelRenameList(); $event.stopPropagation()"
|
|
3092
|
-
|
|
3291
|
+
>
|
|
3292
|
+
<ui-icon pButtonIcon name="times"></ui-icon>
|
|
3293
|
+
</button>
|
|
3093
3294
|
} @else {
|
|
3094
|
-
<
|
|
3095
|
-
|
|
3295
|
+
<button
|
|
3296
|
+
fButton
|
|
3096
3297
|
[text]="true"
|
|
3097
3298
|
size="small"
|
|
3098
3299
|
severity="secondary"
|
|
3099
|
-
|
|
3100
|
-
[
|
|
3300
|
+
class="!w-6 !h-6 flex-shrink-0"
|
|
3301
|
+
[fTooltip]="'task.manager.list.rename' | translate"
|
|
3101
3302
|
tooltipPosition="bottom"
|
|
3102
3303
|
(click)="startRenameList(list); $event.stopPropagation()"
|
|
3103
|
-
|
|
3304
|
+
>
|
|
3305
|
+
<ui-icon pButtonIcon name="pencil"></ui-icon>
|
|
3306
|
+
</button>
|
|
3104
3307
|
}
|
|
3105
3308
|
</div>
|
|
3106
3309
|
|
|
@@ -3110,7 +3313,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3110
3313
|
[cdkDropListData]="list.tasks"
|
|
3111
3314
|
[cdkDropListConnectedTo]="listDropIds()"
|
|
3112
3315
|
(cdkDropListDropped)="onTaskDrop($event)"
|
|
3113
|
-
class="flex flex-col gap-2 p-2 overflow-y-auto flex-1 min-h-[60px]
|
|
3316
|
+
class="flex flex-col gap-2 p-2 overflow-y-auto flex-1 min-h-[60px]"
|
|
3114
3317
|
>
|
|
3115
3318
|
@for (task of list.tasks; track task.id) {
|
|
3116
3319
|
<div cdkDrag>
|
|
@@ -3124,91 +3327,99 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3124
3327
|
}
|
|
3125
3328
|
@if (list.tasks.length === 0) {
|
|
3126
3329
|
<div
|
|
3127
|
-
class="flex items-center justify-center h-14 border-2 border-dashed border-surface
|
|
3330
|
+
class="flex items-center justify-center h-14 border-2 border-dashed border-surface rounded-border"
|
|
3128
3331
|
>
|
|
3129
|
-
<span class="text-xs text-
|
|
3332
|
+
<span class="text-xs text-muted-color">{{
|
|
3130
3333
|
'task.manager.board.drop.tasks.here' | translate
|
|
3131
3334
|
}}</span>
|
|
3132
3335
|
</div>
|
|
3133
3336
|
}
|
|
3134
3337
|
</div>
|
|
3135
3338
|
|
|
3136
|
-
<div
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
<p-button
|
|
3140
|
-
icon="pi pi-plus"
|
|
3141
|
-
[label]="'task.manager.board.add.task' | translate"
|
|
3339
|
+
<div class="border-t border-surface p-1.5">
|
|
3340
|
+
<button
|
|
3341
|
+
fButton
|
|
3142
3342
|
severity="secondary"
|
|
3343
|
+
[text]="true"
|
|
3143
3344
|
size="small"
|
|
3144
|
-
|
|
3145
|
-
(
|
|
3146
|
-
|
|
3345
|
+
class="w-full !justify-start"
|
|
3346
|
+
(click)="openAddTask(list)"
|
|
3347
|
+
>
|
|
3348
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
3349
|
+
<span pButtonLabel>{{
|
|
3350
|
+
'task.manager.board.add.task' | translate
|
|
3351
|
+
}}</span>
|
|
3352
|
+
</button>
|
|
3147
3353
|
</div>
|
|
3148
3354
|
</div>
|
|
3149
3355
|
}
|
|
3150
3356
|
|
|
3151
3357
|
@if (state.listsWithTasks().length === 0) {
|
|
3152
3358
|
<div class="flex-1 flex items-center justify-center">
|
|
3153
|
-
<div class="text-center text-
|
|
3359
|
+
<div class="text-center text-muted-color">
|
|
3154
3360
|
<div
|
|
3155
|
-
class="w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-4"
|
|
3361
|
+
class="w-16 h-16 rounded-2xl border-2 border-dashed border-surface flex items-center justify-center mx-auto mb-4"
|
|
3156
3362
|
>
|
|
3157
|
-
<
|
|
3158
|
-
|
|
3159
|
-
|
|
3363
|
+
<ui-icon
|
|
3364
|
+
name="list"
|
|
3365
|
+
class="text-3xl text-muted-color"
|
|
3366
|
+
></ui-icon>
|
|
3160
3367
|
</div>
|
|
3161
|
-
<p class="font-medium text-
|
|
3368
|
+
<p class="font-medium text-muted-color">
|
|
3162
3369
|
{{ 'task.manager.board.list.empty' | translate }}
|
|
3163
3370
|
</p>
|
|
3164
|
-
<
|
|
3165
|
-
|
|
3166
|
-
[label]="'task.manager.board.add.list' | translate"
|
|
3371
|
+
<button
|
|
3372
|
+
fButton
|
|
3167
3373
|
severity="secondary"
|
|
3168
3374
|
size="small"
|
|
3169
3375
|
class="mt-3"
|
|
3170
|
-
(
|
|
3171
|
-
|
|
3376
|
+
(click)="showAddListDialog.set(true)"
|
|
3377
|
+
>
|
|
3378
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
3379
|
+
<span pButtonLabel>{{
|
|
3380
|
+
'task.manager.board.add.list' | translate
|
|
3381
|
+
}}</span>
|
|
3382
|
+
</button>
|
|
3172
3383
|
</div>
|
|
3173
3384
|
</div>
|
|
3174
3385
|
}
|
|
3175
3386
|
</div>
|
|
3176
|
-
|
|
3177
3387
|
} @else {
|
|
3178
3388
|
<div class="p-4 sm:p-6 flex-1 overflow-auto">
|
|
3179
3389
|
<div class="card">
|
|
3180
3390
|
<div class="overflow-x-auto -mx-4 sm:mx-0">
|
|
3181
|
-
<
|
|
3391
|
+
<f-table
|
|
3182
3392
|
[value]="allTasksFlat()"
|
|
3183
3393
|
[paginator]="allTasksFlat().length > 20"
|
|
3184
3394
|
[rows]="20"
|
|
3185
3395
|
[rowsPerPageOptions]="[10, 20, 50]"
|
|
3186
3396
|
[scrollable]="true"
|
|
3187
|
-
class="p-datatable-sm"
|
|
3188
3397
|
[tableStyle]="{ 'min-width': '700px' }"
|
|
3189
3398
|
>
|
|
3190
3399
|
<ng-template #header>
|
|
3191
3400
|
<tr>
|
|
3192
|
-
<th
|
|
3401
|
+
<th fSortableColumn="title" class="min-w-[240px]">
|
|
3193
3402
|
{{ 'task.manager.table.title' | translate }}
|
|
3194
|
-
<
|
|
3403
|
+
<f-sorticon field="title" />
|
|
3195
3404
|
</th>
|
|
3196
|
-
<th
|
|
3405
|
+
<th fSortableColumn="listName" class="w-40">
|
|
3197
3406
|
{{ 'task.manager.table.list' | translate }}
|
|
3198
|
-
<
|
|
3407
|
+
<f-sorticon field="listName" />
|
|
3199
3408
|
</th>
|
|
3200
|
-
<th
|
|
3409
|
+
<th fSortableColumn="priority" class="w-32">
|
|
3201
3410
|
{{ 'task.manager.table.priority' | translate }}
|
|
3202
|
-
<
|
|
3411
|
+
<f-sorticon field="priority" />
|
|
3203
3412
|
</th>
|
|
3204
3413
|
<th class="w-36">
|
|
3205
3414
|
{{ 'task.manager.table.assignee' | translate }}
|
|
3206
3415
|
</th>
|
|
3207
|
-
<th
|
|
3416
|
+
<th fSortableColumn="dueDate" class="w-32">
|
|
3208
3417
|
{{ 'task.manager.table.due.date' | translate }}
|
|
3209
|
-
<
|
|
3418
|
+
<f-sorticon field="dueDate" />
|
|
3419
|
+
</th>
|
|
3420
|
+
<th class="w-[100px]">
|
|
3421
|
+
{{ 'shared.actions' | translate }}
|
|
3210
3422
|
</th>
|
|
3211
|
-
<th class="w-[100px]">{{ 'shared.actions' | translate }}</th>
|
|
3212
3423
|
</tr>
|
|
3213
3424
|
</ng-template>
|
|
3214
3425
|
<ng-template #body let-task>
|
|
@@ -3217,7 +3428,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3217
3428
|
<span
|
|
3218
3429
|
class="font-medium text-sm cursor-pointer hover:text-primary-500 transition-colors"
|
|
3219
3430
|
(click)="state.selectTask(task)"
|
|
3220
|
-
|
|
3431
|
+
>{{ task.title }}</span
|
|
3432
|
+
>
|
|
3221
3433
|
</td>
|
|
3222
3434
|
<td>
|
|
3223
3435
|
<span class="inline-flex items-center gap-1.5 text-sm">
|
|
@@ -3229,7 +3441,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3229
3441
|
</span>
|
|
3230
3442
|
</td>
|
|
3231
3443
|
<td>
|
|
3232
|
-
<
|
|
3444
|
+
<f-tag
|
|
3233
3445
|
[value]="task.priority"
|
|
3234
3446
|
[severity]="prioritySeverity(task.priority)"
|
|
3235
3447
|
/>
|
|
@@ -3237,21 +3449,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3237
3449
|
<td>
|
|
3238
3450
|
@if (task.assignees?.length) {
|
|
3239
3451
|
<div class="flex items-center -space-x-1.5">
|
|
3240
|
-
@for (
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3452
|
+
@for (
|
|
3453
|
+
a of task.assignees!.slice(0, 3);
|
|
3454
|
+
track a.userId
|
|
3455
|
+
) {
|
|
3456
|
+
<f-avatar
|
|
3457
|
+
shape="circle"
|
|
3458
|
+
size="small"
|
|
3459
|
+
[label]="getMemberInitials(a.userId)"
|
|
3460
|
+
[color]="memberColorById(a.userId)"
|
|
3461
|
+
styleClass="!ring-surface-card flex-shrink-0"
|
|
3462
|
+
[fTooltip]="a.userName ?? ''"
|
|
3463
|
+
/>
|
|
3248
3464
|
}
|
|
3249
3465
|
@if (task.assignees!.length > 3) {
|
|
3250
|
-
<
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
+
|
|
3254
|
-
|
|
3466
|
+
<f-avatar
|
|
3467
|
+
shape="circle"
|
|
3468
|
+
size="small"
|
|
3469
|
+
[label]="'+' + (task.assignees!.length - 3)"
|
|
3470
|
+
styleClass="!bg-surface-200 dark:!bg-surface-700 !text-surface-600 !ring-surface-card flex-shrink-0"
|
|
3471
|
+
/>
|
|
3255
3472
|
}
|
|
3256
3473
|
</div>
|
|
3257
3474
|
} @else {
|
|
@@ -3272,22 +3489,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3272
3489
|
</td>
|
|
3273
3490
|
<td>
|
|
3274
3491
|
<div class="flex gap-1">
|
|
3275
|
-
<
|
|
3276
|
-
|
|
3492
|
+
<button
|
|
3493
|
+
fButton
|
|
3277
3494
|
[text]="true"
|
|
3278
3495
|
severity="secondary"
|
|
3279
3496
|
size="small"
|
|
3280
|
-
[
|
|
3281
|
-
(
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3497
|
+
[fTooltip]="'shared.edit' | translate"
|
|
3498
|
+
(click)="onEditTask(task)"
|
|
3499
|
+
>
|
|
3500
|
+
<ui-icon pButtonIcon name="pencil"></ui-icon>
|
|
3501
|
+
</button>
|
|
3502
|
+
<button
|
|
3503
|
+
fButton
|
|
3285
3504
|
[text]="true"
|
|
3286
3505
|
severity="danger"
|
|
3287
3506
|
size="small"
|
|
3288
|
-
[
|
|
3289
|
-
(
|
|
3290
|
-
|
|
3507
|
+
[fTooltip]="'shared.delete' | translate"
|
|
3508
|
+
(click)="onDeleteTask(task)"
|
|
3509
|
+
>
|
|
3510
|
+
<ui-icon pButtonIcon name="trash"></ui-icon>
|
|
3511
|
+
</button>
|
|
3291
3512
|
</div>
|
|
3292
3513
|
</td>
|
|
3293
3514
|
</tr>
|
|
@@ -3295,12 +3516,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3295
3516
|
<ng-template #emptymessage>
|
|
3296
3517
|
<tr>
|
|
3297
3518
|
<td colspan="6" class="text-center text-muted-color py-8">
|
|
3298
|
-
<
|
|
3519
|
+
<ui-icon
|
|
3520
|
+
name="inbox"
|
|
3521
|
+
class="text-4xl block mb-3"
|
|
3522
|
+
></ui-icon>
|
|
3299
3523
|
{{ 'task.manager.table.empty' | translate }}
|
|
3300
3524
|
</td>
|
|
3301
3525
|
</tr>
|
|
3302
3526
|
</ng-template>
|
|
3303
|
-
</
|
|
3527
|
+
</f-table>
|
|
3304
3528
|
</div>
|
|
3305
3529
|
</div>
|
|
3306
3530
|
</div>
|
|
@@ -3323,12 +3547,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3323
3547
|
(editTask)="onEditTask($event)"
|
|
3324
3548
|
/>
|
|
3325
3549
|
|
|
3326
|
-
<
|
|
3550
|
+
<f-dialog
|
|
3327
3551
|
[header]="'task.manager.label.manage.title' | translate"
|
|
3328
3552
|
[(visible)]="showLabelsDialog"
|
|
3329
3553
|
[modal]="true"
|
|
3330
3554
|
[style]="{ width: '420px' }"
|
|
3331
|
-
(onHide)="newLabelName = ''; newLabelColor =
|
|
3555
|
+
(onHide)="newLabelName = ''; newLabelColor = boardColorPalette[0]"
|
|
3332
3556
|
>
|
|
3333
3557
|
<div class="flex flex-col gap-4 py-2">
|
|
3334
3558
|
<div class="flex gap-2 items-end">
|
|
@@ -3337,7 +3561,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3337
3561
|
'task.manager.label.name.label' | translate
|
|
3338
3562
|
}}</label>
|
|
3339
3563
|
<input
|
|
3340
|
-
|
|
3564
|
+
fInputText
|
|
3341
3565
|
[(ngModel)]="newLabelName"
|
|
3342
3566
|
[placeholder]="'task.manager.label.name.placeholder' | translate"
|
|
3343
3567
|
/>
|
|
@@ -3352,24 +3576,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3352
3576
|
class="w-10 h-10 rounded cursor-pointer border border-surface-300"
|
|
3353
3577
|
/>
|
|
3354
3578
|
</div>
|
|
3355
|
-
<
|
|
3356
|
-
|
|
3357
|
-
[label]="'task.manager.label.add' | translate"
|
|
3579
|
+
<button
|
|
3580
|
+
fButton
|
|
3358
3581
|
size="small"
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3582
|
+
(click)="addLabel()"
|
|
3583
|
+
[disabled]="isAddingLabel()"
|
|
3584
|
+
>
|
|
3585
|
+
@if (isAddingLabel()) {
|
|
3586
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
3587
|
+
} @else {
|
|
3588
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
3589
|
+
}
|
|
3590
|
+
<span pButtonLabel>{{ 'task.manager.label.add' | translate }}</span>
|
|
3591
|
+
</button>
|
|
3362
3592
|
</div>
|
|
3363
3593
|
|
|
3364
3594
|
<div class="flex flex-col gap-2 max-h-64 overflow-y-auto">
|
|
3365
3595
|
@if (state.labels().length === 0) {
|
|
3366
|
-
<p class="text-sm text-
|
|
3596
|
+
<p class="text-sm text-muted-color text-center py-4">
|
|
3367
3597
|
{{ 'task.manager.label.no.labels' | translate }}
|
|
3368
3598
|
</p>
|
|
3369
3599
|
}
|
|
3370
3600
|
@for (label of state.labels(); track label.id) {
|
|
3371
3601
|
<div
|
|
3372
|
-
class="flex items-center justify-between px-3 py-2 rounded-
|
|
3602
|
+
class="flex items-center justify-between px-3 py-2 rounded-border border border-surface"
|
|
3373
3603
|
>
|
|
3374
3604
|
<div class="flex items-center gap-2">
|
|
3375
3605
|
<span
|
|
@@ -3378,20 +3608,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3378
3608
|
></span>
|
|
3379
3609
|
<span class="text-sm font-medium">{{ label.name }}</span>
|
|
3380
3610
|
</div>
|
|
3381
|
-
<
|
|
3382
|
-
|
|
3611
|
+
<button
|
|
3612
|
+
fButton
|
|
3383
3613
|
severity="danger"
|
|
3384
3614
|
size="small"
|
|
3385
3615
|
[text]="true"
|
|
3386
|
-
(
|
|
3387
|
-
|
|
3616
|
+
(click)="removeLabel(label.id)"
|
|
3617
|
+
>
|
|
3618
|
+
<ui-icon pButtonIcon name="trash"></ui-icon>
|
|
3619
|
+
</button>
|
|
3388
3620
|
</div>
|
|
3389
3621
|
}
|
|
3390
3622
|
</div>
|
|
3391
3623
|
</div>
|
|
3392
|
-
</
|
|
3624
|
+
</f-dialog>
|
|
3393
3625
|
|
|
3394
|
-
<
|
|
3626
|
+
<f-dialog
|
|
3395
3627
|
[header]="'task.manager.member.manage.title' | translate"
|
|
3396
3628
|
[(visible)]="showMembersDialog"
|
|
3397
3629
|
[modal]="true"
|
|
@@ -3416,7 +3648,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3416
3648
|
<label class="text-sm font-medium">{{
|
|
3417
3649
|
'task.manager.member.role.label' | translate
|
|
3418
3650
|
}}</label>
|
|
3419
|
-
<
|
|
3651
|
+
<f-select
|
|
3420
3652
|
[(ngModel)]="newMemberRole"
|
|
3421
3653
|
[options]="memberRoleOptions"
|
|
3422
3654
|
optionValue="value"
|
|
@@ -3424,7 +3656,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3424
3656
|
'task.manager.member.role.placeholder' | translate
|
|
3425
3657
|
"
|
|
3426
3658
|
class="w-full"
|
|
3427
|
-
appendTo="body"
|
|
3428
3659
|
>
|
|
3429
3660
|
<ng-template #selectedItem let-opt>
|
|
3430
3661
|
{{ opt.labelKey | translate }}
|
|
@@ -3432,42 +3663,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3432
3663
|
<ng-template #item let-opt>
|
|
3433
3664
|
{{ opt.labelKey | translate }}
|
|
3434
3665
|
</ng-template>
|
|
3435
|
-
</
|
|
3666
|
+
</f-select>
|
|
3436
3667
|
</div>
|
|
3437
|
-
<
|
|
3438
|
-
|
|
3439
|
-
[label]="'task.manager.member.add' | translate"
|
|
3668
|
+
<button
|
|
3669
|
+
fButton
|
|
3440
3670
|
size="small"
|
|
3441
|
-
[
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3671
|
+
[disabled]="!selectedMemberUser || isAddingMember()"
|
|
3672
|
+
(click)="addMember()"
|
|
3673
|
+
>
|
|
3674
|
+
@if (isAddingMember()) {
|
|
3675
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
3676
|
+
} @else {
|
|
3677
|
+
<ui-icon pButtonIcon name="plus"></ui-icon>
|
|
3678
|
+
}
|
|
3679
|
+
<span pButtonLabel>{{
|
|
3680
|
+
'task.manager.member.add' | translate
|
|
3681
|
+
}}</span>
|
|
3682
|
+
</button>
|
|
3445
3683
|
</div>
|
|
3446
3684
|
</div>
|
|
3447
3685
|
|
|
3448
3686
|
<div class="flex flex-col gap-2 max-h-72 overflow-y-auto">
|
|
3449
3687
|
@if (state.members().length === 0) {
|
|
3450
|
-
<p class="text-sm text-
|
|
3688
|
+
<p class="text-sm text-muted-color text-center py-4">
|
|
3451
3689
|
{{ 'task.manager.member.no.members' | translate }}
|
|
3452
3690
|
</p>
|
|
3453
3691
|
}
|
|
3454
3692
|
@for (member of state.members(); track member.id) {
|
|
3455
3693
|
<div
|
|
3456
|
-
class="flex items-center justify-between px-3 py-2.5 rounded-
|
|
3694
|
+
class="flex items-center justify-between px-3 py-2.5 rounded-border border border-surface"
|
|
3457
3695
|
>
|
|
3458
3696
|
<div class="flex items-center gap-3">
|
|
3459
|
-
<
|
|
3460
|
-
|
|
3461
|
-
[
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3697
|
+
<f-avatar
|
|
3698
|
+
shape="circle"
|
|
3699
|
+
[label]="memberInitials(member)"
|
|
3700
|
+
[color]="memberColor(member)"
|
|
3701
|
+
styleClass="!text-[11px] flex-shrink-0"
|
|
3702
|
+
/>
|
|
3465
3703
|
<div>
|
|
3466
3704
|
<div class="text-sm font-medium ">
|
|
3467
3705
|
{{ member.userName ?? member.userId }}
|
|
3468
3706
|
</div>
|
|
3469
3707
|
@if (member.userEmail) {
|
|
3470
|
-
<div class="text-xs text-
|
|
3708
|
+
<div class="text-xs text-muted-color">
|
|
3471
3709
|
{{ member.userEmail }}
|
|
3472
3710
|
</div>
|
|
3473
3711
|
}
|
|
@@ -3478,25 +3716,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3478
3716
|
class="text-[10px] font-semibold px-2 py-0.5 rounded-full"
|
|
3479
3717
|
[class]="roleBadgeClass(member.role)"
|
|
3480
3718
|
>
|
|
3481
|
-
{{
|
|
3719
|
+
{{
|
|
3720
|
+
'task.manager.member.role.' + member.role.toLowerCase()
|
|
3721
|
+
| translate
|
|
3722
|
+
}}
|
|
3482
3723
|
</span>
|
|
3483
3724
|
@if (member.role !== 'OWNER') {
|
|
3484
|
-
<
|
|
3485
|
-
|
|
3725
|
+
<button
|
|
3726
|
+
fButton
|
|
3486
3727
|
severity="danger"
|
|
3487
3728
|
size="small"
|
|
3488
3729
|
[text]="true"
|
|
3489
|
-
(
|
|
3490
|
-
|
|
3730
|
+
(click)="removeMember(member.userId)"
|
|
3731
|
+
>
|
|
3732
|
+
<ui-icon pButtonIcon name="trash"></ui-icon>
|
|
3733
|
+
</button>
|
|
3491
3734
|
}
|
|
3492
3735
|
</div>
|
|
3493
3736
|
</div>
|
|
3494
3737
|
}
|
|
3495
3738
|
</div>
|
|
3496
3739
|
</div>
|
|
3497
|
-
</
|
|
3740
|
+
</f-dialog>
|
|
3498
3741
|
|
|
3499
|
-
<
|
|
3742
|
+
<f-dialog
|
|
3500
3743
|
[header]="'task.manager.list.new' | translate"
|
|
3501
3744
|
[(visible)]="showAddListDialog"
|
|
3502
3745
|
[modal]="true"
|
|
@@ -3509,28 +3752,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3509
3752
|
<span class="text-red-500">*</span>
|
|
3510
3753
|
</label>
|
|
3511
3754
|
<input
|
|
3512
|
-
|
|
3755
|
+
fInputText
|
|
3513
3756
|
[(ngModel)]="newListName"
|
|
3514
3757
|
[placeholder]="'task.manager.list.name.placeholder' | translate"
|
|
3515
3758
|
/>
|
|
3516
3759
|
</div>
|
|
3517
|
-
<ng-template
|
|
3760
|
+
<ng-template #footer>
|
|
3518
3761
|
<div class="flex justify-end gap-2">
|
|
3519
|
-
<
|
|
3520
|
-
|
|
3762
|
+
<button
|
|
3763
|
+
fButton
|
|
3521
3764
|
severity="secondary"
|
|
3522
|
-
(
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
(
|
|
3528
|
-
|
|
3765
|
+
(click)="showAddListDialog.set(false)"
|
|
3766
|
+
>
|
|
3767
|
+
<span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
|
|
3768
|
+
</button>
|
|
3769
|
+
<button fButton (click)="addList()" [disabled]="isAddingList()">
|
|
3770
|
+
@if (isAddingList()) {
|
|
3771
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
3772
|
+
}
|
|
3773
|
+
<span pButtonLabel>{{ 'shared.create' | translate }}</span>
|
|
3774
|
+
</button>
|
|
3529
3775
|
</div>
|
|
3530
3776
|
</ng-template>
|
|
3531
|
-
</
|
|
3777
|
+
</f-dialog>
|
|
3532
3778
|
|
|
3533
|
-
<
|
|
3779
|
+
<f-dialog
|
|
3534
3780
|
[header]="'task.manager.board.edit' | translate"
|
|
3535
3781
|
[(visible)]="showEditBoardDialog"
|
|
3536
3782
|
[modal]="true"
|
|
@@ -3542,17 +3788,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3542
3788
|
{{ 'task.manager.board.name.label' | translate }}
|
|
3543
3789
|
<span class="text-red-500">*</span>
|
|
3544
3790
|
</label>
|
|
3545
|
-
<input
|
|
3791
|
+
<input fInputText [(ngModel)]="editBoardName" />
|
|
3546
3792
|
</div>
|
|
3547
3793
|
<div class="flex flex-col gap-1">
|
|
3548
3794
|
<label class="text-sm font-medium">{{
|
|
3549
3795
|
'task.manager.board.description.label' | translate
|
|
3550
3796
|
}}</label>
|
|
3551
3797
|
<textarea
|
|
3552
|
-
|
|
3798
|
+
fTextarea
|
|
3553
3799
|
[(ngModel)]="editBoardDescription"
|
|
3554
3800
|
[rows]="3"
|
|
3555
|
-
[placeholder]="
|
|
3801
|
+
[placeholder]="
|
|
3802
|
+
'task.manager.board.description.placeholder' | translate
|
|
3803
|
+
"
|
|
3556
3804
|
></textarea>
|
|
3557
3805
|
</div>
|
|
3558
3806
|
<div class="flex flex-col gap-1">
|
|
@@ -3580,22 +3828,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3580
3828
|
</div>
|
|
3581
3829
|
</div>
|
|
3582
3830
|
</div>
|
|
3583
|
-
<ng-template
|
|
3831
|
+
<ng-template #footer>
|
|
3584
3832
|
<div class="flex justify-end gap-2">
|
|
3585
|
-
<
|
|
3586
|
-
|
|
3833
|
+
<button
|
|
3834
|
+
fButton
|
|
3587
3835
|
severity="secondary"
|
|
3588
|
-
(
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3836
|
+
(click)="showEditBoardDialog.set(false)"
|
|
3837
|
+
>
|
|
3838
|
+
<span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
|
|
3839
|
+
</button>
|
|
3840
|
+
<button
|
|
3841
|
+
fButton
|
|
3842
|
+
[disabled]="!editBoardName.trim() || isSavingBoard()"
|
|
3843
|
+
(click)="saveBoard()"
|
|
3844
|
+
>
|
|
3845
|
+
@if (isSavingBoard()) {
|
|
3846
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
3847
|
+
}
|
|
3848
|
+
<span pButtonLabel>{{ 'shared.save' | translate }}</span>
|
|
3849
|
+
</button>
|
|
3596
3850
|
</div>
|
|
3597
3851
|
</ng-template>
|
|
3598
|
-
</
|
|
3852
|
+
</f-dialog>
|
|
3599
3853
|
`,
|
|
3600
3854
|
}]
|
|
3601
3855
|
}], ctorParameters: () => [], propDecorators: { boardId: [{ type: i0.Input, args: [{ isSignal: true, alias: "boardId", required: true }] }] } });
|