@valtimo/task 13.37.0 → 13.39.0
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.
- package/fesm2022/valtimo-task.mjs +96 -21
- package/fesm2022/valtimo-task.mjs.map +1 -1
- package/lib/components/task-detail-modal/task-detail-modal.component.d.ts +2 -0
- package/lib/components/task-detail-modal/task-detail-modal.component.d.ts.map +1 -1
- package/lib/components/task-list/task-list.component.d.ts +1 -0
- package/lib/components/task-list/task-list.component.d.ts.map +1 -1
- package/lib/services/task-list-column.service.d.ts +1 -0
- package/lib/services/task-list-column.service.d.ts.map +1 -1
- package/lib/services/task.service.d.ts +1 -1
- package/lib/services/task.service.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -15,6 +15,7 @@ import * as i2$1 from 'carbon-components-angular';
|
|
|
15
15
|
import { LoadingModule, NotificationModule, ButtonModule, IconModule, ModalModule, ToggletipModule, DatePickerModule, LayerModule, LinkModule, TabsModule, ContentSwitcherModule, DropdownModule, TooltipModule as TooltipModule$1 } from 'carbon-components-angular';
|
|
16
16
|
import { BehaviorSubject, combineLatest, Subject, switchMap, of, tap, filter, take as take$1, map as map$1, catchError, Subscription, distinctUntilChanged, shareReplay, EMPTY } from 'rxjs';
|
|
17
17
|
import * as i2 from '@valtimo/document';
|
|
18
|
+
import { CaseTagsUtils } from '@valtimo/document';
|
|
18
19
|
import * as i4 from 'ngx-logger';
|
|
19
20
|
import * as i3 from '@valtimo/access-control';
|
|
20
21
|
import * as i1$2 from '@angular/router';
|
|
@@ -162,14 +163,27 @@ class TaskService extends BaseApiService {
|
|
|
162
163
|
getTasks() {
|
|
163
164
|
return this.httpClient.get(this.getApiUrl('/v1/task?filter=all'));
|
|
164
165
|
}
|
|
165
|
-
getTask(id) {
|
|
166
|
-
|
|
166
|
+
getTask(id, skipStatusCodes) {
|
|
167
|
+
// Skipping status codes prevents the global HttpErrorInterceptor from showing an error toast
|
|
168
|
+
// for those responses, so callers that expect and handle a status (e.g. a 403/404 after a
|
|
169
|
+
// task assignment change removes the user's access) can do so silently.
|
|
170
|
+
const options = skipStatusCodes && skipStatusCodes.length > 0
|
|
171
|
+
? { headers: new HttpHeaders().set(InterceptorSkip, skipStatusCodes.join(',')) }
|
|
172
|
+
: {};
|
|
173
|
+
return this.httpClient.get(this.getApiUrl(`/v1/task/${id}`), options);
|
|
167
174
|
}
|
|
168
175
|
getCandidateUsers(id) {
|
|
169
|
-
|
|
176
|
+
// The endpoint requires the assign permission. Right after an assignment change the task can be
|
|
177
|
+
// re-fetched while the (soon to be invalidated) assign permission still reads as allowed, which
|
|
178
|
+
// triggers this request and a 403. That 403 is expected, so it is skipped to avoid an error
|
|
179
|
+
// toast; callers fall back to an empty candidate list.
|
|
180
|
+
return this.httpClient.get(this.getApiUrl(`/v2/task/${id}/candidate-user`), {
|
|
181
|
+
headers: new HttpHeaders().set(InterceptorSkip, '403'),
|
|
182
|
+
});
|
|
170
183
|
}
|
|
171
184
|
getCandidateTeams(id) {
|
|
172
|
-
|
|
185
|
+
// See getCandidateUsers: a 403 is expected right after an assignment change and is skipped.
|
|
186
|
+
return this.httpClient.get(this.getApiUrl(`/v1/task/${id}/candidate-team`), { params: { size: '1000' }, headers: new HttpHeaders().set(InterceptorSkip, '403') });
|
|
173
187
|
}
|
|
174
188
|
assignTask(id, assigneeRequest) {
|
|
175
189
|
return this.httpClient.post(this.getApiUrl(`/v1/task/${id}/assign`), assigneeRequest);
|
|
@@ -417,6 +431,12 @@ class TaskListColumnService {
|
|
|
417
431
|
get availableFields$() {
|
|
418
432
|
return this._availableFields$.asObservable();
|
|
419
433
|
}
|
|
434
|
+
getTagColumnKeys() {
|
|
435
|
+
return this._availableFields$
|
|
436
|
+
.getValue()
|
|
437
|
+
.filter((field) => field.viewType === ViewType.TAGS)
|
|
438
|
+
.map((field) => field.key);
|
|
439
|
+
}
|
|
420
440
|
get fields$() {
|
|
421
441
|
return combineLatest([this._availableFields$, this.hiddenColumns$]).pipe(map(([availableFields, hiddenColumns]) => {
|
|
422
442
|
if (!hiddenColumns || hiddenColumns.length === 0) {
|
|
@@ -1823,11 +1843,15 @@ class TaskDetailModalComponent {
|
|
|
1823
1843
|
this.candidateUsers$ = combineLatest([
|
|
1824
1844
|
this.task$.pipe(filter$1(task => !!task)),
|
|
1825
1845
|
this.canAssignUserToTask$,
|
|
1826
|
-
]).pipe(switchMap$1(([task, canAssign]) => canAssign
|
|
1846
|
+
]).pipe(switchMap$1(([task, canAssign]) => canAssign
|
|
1847
|
+
? this.taskService.getCandidateUsers(task.id).pipe(catchError$1(() => of([])))
|
|
1848
|
+
: of([])), shareReplay(1));
|
|
1827
1849
|
this.candidateTeams$ = combineLatest([
|
|
1828
1850
|
this.task$.pipe(filter$1(task => !!task)),
|
|
1829
1851
|
this.canAssignUserToTask$,
|
|
1830
|
-
]).pipe(switchMap$1(([task, canAssign]) => canAssign
|
|
1852
|
+
]).pipe(switchMap$1(([task, canAssign]) => canAssign
|
|
1853
|
+
? this.taskService.getCandidateTeams(task.id).pipe(map(page => page.content), catchError$1(() => of([])))
|
|
1854
|
+
: of([])), shareReplay(1));
|
|
1831
1855
|
this._subscriptions = new Subscription();
|
|
1832
1856
|
this.iconService.registerAll([FolderDetailsReference16]);
|
|
1833
1857
|
}
|
|
@@ -1869,23 +1893,42 @@ class TaskDetailModalComponent {
|
|
|
1869
1893
|
.subscribe((allowed) => {
|
|
1870
1894
|
this.canModifyTask$.next(allowed);
|
|
1871
1895
|
});
|
|
1896
|
+
this.permissionService
|
|
1897
|
+
.requestPermission(CAN_VIEW_TASK_PERMISSION, {
|
|
1898
|
+
resource: TASK_DETAIL_PERMISSION_RESOURCE.task,
|
|
1899
|
+
identifier: task.id,
|
|
1900
|
+
})
|
|
1901
|
+
.subscribe((allowed) => {
|
|
1902
|
+
if (!allowed && this.task$.getValue()?.id === task.id) {
|
|
1903
|
+
this.logger.debug('Closing task detail as user is not allowed to view Task with id:', task.id);
|
|
1904
|
+
this.closeModal();
|
|
1905
|
+
}
|
|
1906
|
+
});
|
|
1872
1907
|
}
|
|
1873
1908
|
else {
|
|
1874
1909
|
this.logger.debug('Reset is user allowed to assign a user to Task as task is null');
|
|
1875
1910
|
this.canAssignUserToTask$.next(false);
|
|
1911
|
+
this.canModifyTask$.next(false);
|
|
1876
1912
|
}
|
|
1877
1913
|
}));
|
|
1878
1914
|
}
|
|
1879
1915
|
openTaskUpdateSseEventSubscription() {
|
|
1880
1916
|
this._subscriptions.add(this.sseService
|
|
1881
1917
|
.getSseEventObservable('TASK_UPDATE')
|
|
1882
|
-
.pipe(filter$1(event => this.task$.getValue()?.id === event.taskId), switchMap$1(event =>
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1918
|
+
.pipe(filter$1(event => this.task$.getValue()?.id === event.taskId), switchMap$1(event => {
|
|
1919
|
+
// A task update (e.g. an assignment by another user) can change the outcome of
|
|
1920
|
+
// permission checks for this task, so drop cached permissions before re-checking
|
|
1921
|
+
this.permissionService.invalidateResource(TASK_DETAIL_PERMISSION_RESOURCE.task, event.taskId);
|
|
1922
|
+
// a 403 or 404 means the user can no longer view the task; these are expected
|
|
1923
|
+
// outcomes here, so they are skipped to avoid a global error toast
|
|
1924
|
+
return this.taskService.getTask(event.taskId, ['403', '404']).pipe(catchError$1(err => {
|
|
1925
|
+
if (err.status === 403 || err.status === 404) {
|
|
1926
|
+
return of(null);
|
|
1927
|
+
}
|
|
1928
|
+
this.logger.error('Failed to fetch task on SSE update', err);
|
|
1929
|
+
return EMPTY;
|
|
1930
|
+
}));
|
|
1931
|
+
}))
|
|
1889
1932
|
.subscribe(response => {
|
|
1890
1933
|
if (!response) {
|
|
1891
1934
|
this.closeModal();
|
|
@@ -1985,10 +2028,9 @@ class TaskDetailModalComponent {
|
|
|
1985
2028
|
assignRequest.assignedTeamKey = event.teamKey ?? '';
|
|
1986
2029
|
this.taskService
|
|
1987
2030
|
.assignTask(task.id, assignRequest)
|
|
1988
|
-
.pipe(switchMap$1(() => this.
|
|
2031
|
+
.pipe(switchMap$1(() => this.refreshTaskAfterAssignmentChange(task.id)), take(1))
|
|
1989
2032
|
.subscribe(response => {
|
|
1990
|
-
this.
|
|
1991
|
-
this.assignmentOfTaskChanged.emit();
|
|
2033
|
+
this.handleAssignmentChangeResponse(response);
|
|
1992
2034
|
});
|
|
1993
2035
|
}
|
|
1994
2036
|
onUnassigned() {
|
|
@@ -1997,12 +2039,34 @@ class TaskDetailModalComponent {
|
|
|
1997
2039
|
return;
|
|
1998
2040
|
this.taskService
|
|
1999
2041
|
.unassignTask(task.id)
|
|
2000
|
-
.pipe(switchMap$1(() => this.
|
|
2042
|
+
.pipe(switchMap$1(() => this.refreshTaskAfterAssignmentChange(task.id)), take(1))
|
|
2001
2043
|
.subscribe(response => {
|
|
2002
|
-
this.
|
|
2003
|
-
this.assignmentOfTaskChanged.emit();
|
|
2044
|
+
this.handleAssignmentChangeResponse(response);
|
|
2004
2045
|
});
|
|
2005
2046
|
}
|
|
2047
|
+
refreshTaskAfterAssignmentChange(taskId) {
|
|
2048
|
+
// The new assignment can change the outcome of permission checks for this task,
|
|
2049
|
+
// so drop cached permissions before the task is re-fetched and re-checked
|
|
2050
|
+
this.permissionService.invalidateResource(TASK_DETAIL_PERMISSION_RESOURCE.task, taskId);
|
|
2051
|
+
// a 403 or 404 means the user can no longer view the task; these are expected
|
|
2052
|
+
// outcomes here, so they are skipped to avoid a global error toast
|
|
2053
|
+
return this.taskService.getTask(taskId, ['403', '404']).pipe(catchError$1(error => {
|
|
2054
|
+
if (error?.status === 403 || error?.status === 404) {
|
|
2055
|
+
return of(null);
|
|
2056
|
+
}
|
|
2057
|
+
this.logger.error('Failed to fetch task after assignment change', error);
|
|
2058
|
+
return EMPTY;
|
|
2059
|
+
}));
|
|
2060
|
+
}
|
|
2061
|
+
handleAssignmentChangeResponse(response) {
|
|
2062
|
+
if (response) {
|
|
2063
|
+
this.refreshTask(response);
|
|
2064
|
+
}
|
|
2065
|
+
else {
|
|
2066
|
+
this.closeModal();
|
|
2067
|
+
}
|
|
2068
|
+
this.assignmentOfTaskChanged.emit();
|
|
2069
|
+
}
|
|
2006
2070
|
onFormSubmit() {
|
|
2007
2071
|
this.formSubmit.emit();
|
|
2008
2072
|
}
|
|
@@ -2417,6 +2481,7 @@ class TaskListComponent {
|
|
|
2417
2481
|
mapTasksForList(isSpecified, tasks, canViewTaskPermissions, canViewCasePermissions) {
|
|
2418
2482
|
const MOMENT_FORMAT = 'DD MMM YYYY HH:mm';
|
|
2419
2483
|
if (isSpecified) {
|
|
2484
|
+
const tagColumnKeys = this.taskListColumnService.getTagColumnKeys();
|
|
2420
2485
|
return tasks.content.map((specifiedTask, specifiedTaskIndex) => specifiedTask.items.reduce((acc, curr) => ({
|
|
2421
2486
|
id: specifiedTask.id,
|
|
2422
2487
|
businessKey: specifiedTask.businessKey,
|
|
@@ -2432,7 +2497,9 @@ class TaskListComponent {
|
|
|
2432
2497
|
caseLocked: !canViewCasePermissions[specifiedTaskIndex],
|
|
2433
2498
|
}),
|
|
2434
2499
|
...acc,
|
|
2435
|
-
[curr.key]: curr.
|
|
2500
|
+
[curr.key]: tagColumnKeys.includes(curr.key)
|
|
2501
|
+
? this.mapCaseTagsToCarbonTags(curr.value)
|
|
2502
|
+
: curr.value,
|
|
2436
2503
|
}), {}));
|
|
2437
2504
|
}
|
|
2438
2505
|
return tasks?.content?.map((task, taskIndex) => {
|
|
@@ -2450,6 +2517,14 @@ class TaskListComponent {
|
|
|
2450
2517
|
return taskCopy;
|
|
2451
2518
|
});
|
|
2452
2519
|
}
|
|
2520
|
+
mapCaseTagsToCarbonTags(value) {
|
|
2521
|
+
if (!Array.isArray(value))
|
|
2522
|
+
return value;
|
|
2523
|
+
return value.map((tag) => ({
|
|
2524
|
+
content: tag.title,
|
|
2525
|
+
type: CaseTagsUtils.getTagTypeFromCaseTagColor(tag.color),
|
|
2526
|
+
}));
|
|
2527
|
+
}
|
|
2453
2528
|
setParamsFromQueryParams() {
|
|
2454
2529
|
const decodedParams = this.taskListQueryParamService.getTaskListQueryParams();
|
|
2455
2530
|
if (decodedParams.caseDefinitionKey) {
|
|
@@ -2490,7 +2565,7 @@ class TaskListComponent {
|
|
|
2490
2565
|
provide: QUICK_SEARCH_SERVICE,
|
|
2491
2566
|
useClass: TaskListQuickSearchService,
|
|
2492
2567
|
},
|
|
2493
|
-
], viewQueries: [{ propertyName: "_taskDetail", first: true, predicate: ["taskDetail"], descendants: true }, { propertyName: "_unreadIndicator", first: true, predicate: ["unreadIndicator"], descendants: true, static: true }], ngImport: i0, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<div\n *ngIf=\"{\n loading: loadingTasks$ | async,\n selectedTaskType: selectedTaskType$ | async,\n tasks: tasks$ | async,\n fields: fields$ | async,\n availableFields: availableFields$ | async,\n hiddenColumns: hiddenColumns$ | async,\n visibleTabs: visibleTabs$ | async,\n pagination: paginationForCurrentTaskTypeForList$ | async,\n taskListColumnsForCase: taskListColumnsForCase$ | async,\n sortState: sortStateForCurrentTaskType$ | async,\n overrideSortState: overrideSortState$ | async,\n searchFields: searchFields$ | async,\n loadingSearchFields: loadingSearchFields$ | async,\n caseDefinitionKey: caseDefinitionKey$ | async,\n noResultsMessage: noResultsMessage$ | async,\n } as obs\"\n class=\"main-content\"\n>\n <div class=\"container-fluid\">\n @if (obs.caseDefinitionKey && obs.caseDefinitionKey !== ALL_CASES_ID) {\n <ng-container\n *ngTemplateOutlet=\"\n searchFields;\n context: {\n obs: obs,\n }\n \"\n ></ng-container>\n\n <div class=\"mb-3\">\n <valtimo-quick-search (quickSearchEvent)=\"onQuickSearchEvent($event)\"></valtimo-quick-search>\n </div>\n }\n\n <ng-container\n *ngTemplateOutlet=\"\n tasksList;\n context: {\n obs: obs,\n }\n \"\n ></ng-container>\n\n <ng-container\n *ngTemplateOutlet=\"\n tasksListLoading;\n context: {\n obs: obs,\n }\n \"\n ></ng-container>\n\n <valtimo-task-detail-modal\n #taskDetail\n (formSubmit)=\"reload()\"\n (assignmentOfTaskChanged)=\"reload()\"\n (dueDateChanged)=\"reload()\"\n (modalClosed)=\"reload()\"\n ></valtimo-task-detail-modal>\n </div>\n</div>\n\n<ng-template #configuredTabs let-selectedTaskType=\"selectedTaskType\" let-visibleTabs=\"visibleTabs\">\n <cds-tabs *ngIf=\"visibleTabs\" type=\"contained\" class=\"valtimo-carbon-list__tabs\">\n <cds-tab\n *ngFor=\"let tab of visibleTabs\"\n [attr.data-testid]=\"'task-list-tab-' + tab\"\n [heading]=\"'task-list.' + tab + '.title' | translate\"\n [active]=\"selectedTaskType === tab\"\n (selected)=\"tabChange(tab)\"\n ></cds-tab>\n </cds-tabs>\n</ng-template>\n\n<ng-template #unreadIndicator let-data=\"data\">\n <span *ngIf=\"!data.item?.isOpened\" class=\"valtimo-task-list__unread-dot\"></span>\n</ng-template>\n\n<ng-template #caseLink let-data=\"data\">\n <ng-container *ngIf=\"cachedTasks$ | async as cachedTasks\">\n <div *ngIf=\"cachedTasks[data.index].caseLocked\">\n <a\n class=\"float-left cds--link--disabled\"\n cdsLink\n href=\"javascript:void(0)\"\n ngbTooltip=\"{{ 'task-list.caseLocked' | translate }}\"\n (click)=\"$event.stopPropagation()\"\n >\n {{ 'task-list.goToCase' | translate }}\n </a>\n </div>\n <div *ngIf=\"!cachedTasks[data.index].caseLocked\">\n <a\n class=\"float-left cds--link\"\n cdsLink\n href=\"javascript:void(0)\"\n (click)=\"openRelatedCase($event, data.index)\"\n >\n {{ 'task-list.goToCase' | translate }}\n </a>\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #tasksList let-obs=\"obs\">\n <valtimo-carbon-list\n *ngIf=\"!obs.loading\"\n [fields]=\"obs.fields\"\n [header]=\"false\"\n [items]=\"obs.tasks\"\n [lastColumnTemplate]=\"caseLink\"\n [pagination]=\"obs.pagination\"\n\n lockedTooltipTranslationKey=\"task-list.rowLocked\"\n [sortState]=\"obs.overrideSortState || obs.sortState\"\n (paginationClicked)=\"paginationClicked($event, obs.selectedTaskType)\"\n (paginationSet)=\"paginationSet($event)\"\n (rowClicked)=\"rowOpenTaskClick($event)\"\n (sortChanged)=\"sortChanged($event)\"\n >\n <div tabs>\n <ng-container *ngIf=\"obs.visibleTabs\">\n <ng-container\n *ngTemplateOutlet=\"\n configuredTabs;\n context: {selectedTaskType: obs.selectedTaskType, visibleTabs: obs.visibleTabs}\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n <div carbonToolbarContent>\n <valtimo-list-column-view\n *ngIf=\"obs.caseDefinitionKey && obs.caseDefinitionKey !== ALL_CASES_ID\"\n [availableFields]=\"obs.availableFields\"\n [hiddenColumns]=\"obs.hiddenColumns\"\n (viewUpdateEvent)=\"onViewUpdateEvent($event)\"\n ></valtimo-list-column-view>\n </div>\n\n <valtimo-no-results\n [description]=\"obs.noResultsMessage.description | translate\"\n [title]=\"obs.noResultsMessage.title | translate\"\n >\n </valtimo-no-results>\n </valtimo-carbon-list>\n</ng-template>\n\n<ng-template #tasksListLoading let-obs=\"obs\">\n <valtimo-carbon-list *ngIf=\"obs.loading\" [loading]=\"true\">\n <div tabs>\n <cds-tabs *ngIf=\"!obs.visibleTabs\" type=\"contained\" class=\"valtimo-carbon-list__tabs\">\n <cds-tab\n [heading]=\"'task-list.mine.title' | translate\"\n [active]=\"obs.selectedTaskType === 'mine'\"\n >\n </cds-tab>\n\n <cds-tab\n [heading]=\"'task-list.open.title' | translate\"\n [active]=\"obs.selectedTaskType === 'open'\"\n >\n </cds-tab>\n\n <cds-tab\n [heading]=\"'task-list.all.title' | translate\"\n [active]=\"obs.selectedTaskType === 'all'\"\n >\n </cds-tab>\n </cds-tabs>\n\n <cds-tabs *ngIf=\"obs.visibleTabs\" type=\"contained\" class=\"valtimo-carbon-list__tabs\">\n <cds-tab\n *ngFor=\"let tab of obs.visibleTabs\"\n [heading]=\"'task-list.' + tab + '.title' | translate\"\n [active]=\"obs.selectedTaskType === tab\"\n ></cds-tab>\n </cds-tabs>\n </div>\n </valtimo-carbon-list>\n</ng-template>\n\n<ng-template #searchFields let-obs=\"obs\">\n <div class=\"mb-3\">\n <valtimo-search-fields\n [canSaveSearch]=\"true\"\n [searchFields]=\"obs.searchFields\"\n [inputDisabled]=\"obs.loadingSearchFields\"\n [caseDefinitionKey]=\"obs.caseDefinitionKey\"\n [setValuesSubject$]=\"setSearchFieldValuesSubject$\"\n [clearValuesSubject$]=\"clearSearchFieldValuesSubject$\"\n (doSearch)=\"search($event)\"\n (saveSearchEvent)=\"onSaveSearchEvent($event)\"\n >\n </valtimo-search-fields>\n </div>\n</ng-template>\n\n<ng-container renderInPageHeader [fullWidth]=\"true\">\n <ng-template>\n <cds-dropdown\n class=\"case-definition-selection\"\n *ngIf=\"{\n loadingCaseListItems: loadingCaseListItems$ | async,\n caseListItems: caseListItems$ | async,\n } as obs\"\n [attr.data-testid]=\"'task-list-case-dropdown'\"\n [disabled]=\"obs.loadingCaseListItems || (obs.caseListItems || []).length === 1\"\n [skeleton]=\"obs.loadingCaseListItems\"\n (selected)=\"setCaseDefinition($event)\"\n >\n <cds-dropdown-list [items]=\"obs.caseListItems || []\"></cds-dropdown-list>\n </cds-dropdown>\n </ng-template>\n</ng-container>\n", styles: [".cds--link--disabled{cursor:not-allowed;pointer-events:auto!important;outline:0!important}.case-definition-selection{display:flex;width:250px}.valtimo-task-list__unread-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background-color:var(--cds-link-primary)}::ng-deep .valtimo-task-list__unread-column{width:2rem;padding-right:0!important}\n/*!\n * Copyright 2015-2025 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i9.CarbonListComponent, selector: "valtimo-carbon-list", inputs: ["items", "fields", "tableTranslations", "paginatorConfig", "pagination", "loading", "skeletonRowCount", "actions", "actionItems", "showActionItems", "header", "hideColumnHeader", "initialSortState", "sortState", "isSearchable", "enableSingleSelection", "lastColumnTemplate", "paginationIdentifier", "showSelectionColumn", "striped", "hideToolbar", "lockedTooltipTranslationKey", "movingRowsEnabled", "dragAndDrop", "dragAndDropDisabled"], outputs: ["rowClicked", "paginationClicked", "paginationSet", "search", "sortChanged", "moveRow", "itemsReordered"] }, { kind: "component", type: i9.CarbonNoResultsComponent, selector: "valtimo-no-results", inputs: ["action", "description", "illustration", "title", "smallPadding", "collapseVertically", "alwaysRenderVertically"] }, { kind: "directive", type: i13.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "triggers", "container", "disableTooltip", "tooltipClass", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "directive", type: i2$1.Link, selector: "[cdsLink], [ibmLink]", inputs: ["inline", "disabled"] }, { kind: "component", type: i2$1.Tabs, selector: "cds-tabs, ibm-tabs", inputs: ["position", "cacheActive", "followFocus", "isNavigation", "ariaLabel", "ariaLabelledby", "type", "theme", "skeleton"] }, { kind: "component", type: i2$1.Tab, selector: "cds-tab, ibm-tab", inputs: ["heading", "title", "context", "active", "disabled", "tabIndex", "id", "cacheActive", "tabContent", "templateContext"], outputs: ["selected"] }, { kind: "directive", type: i9.RenderInPageHeaderDirective, selector: "[renderInPageHeader]", inputs: ["fullWidth"] }, { kind: "component", type: i2$1.Dropdown, selector: "cds-dropdown, ibm-dropdown", inputs: ["id", "label", "hideLabel", "helperText", "placeholder", "displayValue", "clearText", "size", "type", "theme", "disabled", "readonly", "skeleton", "inline", "disableArrowKeys", "invalid", "invalidText", "warn", "warnText", "appendInline", "scrollableContainer", "itemValueKey", "selectionFeedback", "menuButtonLabel", "selectedLabel", "dropUp", "fluid"], outputs: ["selected", "onClose", "close"] }, { kind: "component", type: i2$1.DropdownList, selector: "cds-dropdown-list, ibm-dropdown-list", inputs: ["ariaLabel", "items", "listTpl", "type", "showTitles"], outputs: ["select", "scroll", "blurIntent"] }, { kind: "component", type: i9.SearchFieldsComponent, selector: "valtimo-search-fields", inputs: ["loading", "searchFields", "caseDefinitionKey", "setValuesSubject$", "clearValuesSubject$", "defaultValues", "disableSaveSearch", "inputDisabled", "externalSearchField", "canSaveSearch"], outputs: ["doSearch", "saveSearchEvent", "clearEvent"] }, { kind: "component", type: i9.QuickSearchComponent, selector: "valtimo-quick-search", outputs: ["quickSearchEvent"] }, { kind: "component", type: i9.ListColumnViewComponent, selector: "valtimo-list-column-view", inputs: ["availableFields", "hiddenColumns", "disabled"], outputs: ["viewUpdateEvent"] }, { kind: "component", type: TaskDetailModalComponent, selector: "valtimo-task-detail-modal", inputs: ["modalSize", "openFromCaseManagement"], outputs: ["formSubmit", "assignmentOfTaskChanged", "dueDateChanged", "modalClosed"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i4$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2568
|
+
], viewQueries: [{ propertyName: "_taskDetail", first: true, predicate: ["taskDetail"], descendants: true }, { propertyName: "_unreadIndicator", first: true, predicate: ["unreadIndicator"], descendants: true, static: true }], ngImport: i0, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<div\n *ngIf=\"{\n loading: loadingTasks$ | async,\n selectedTaskType: selectedTaskType$ | async,\n tasks: tasks$ | async,\n fields: fields$ | async,\n availableFields: availableFields$ | async,\n hiddenColumns: hiddenColumns$ | async,\n visibleTabs: visibleTabs$ | async,\n pagination: paginationForCurrentTaskTypeForList$ | async,\n taskListColumnsForCase: taskListColumnsForCase$ | async,\n sortState: sortStateForCurrentTaskType$ | async,\n overrideSortState: overrideSortState$ | async,\n searchFields: searchFields$ | async,\n loadingSearchFields: loadingSearchFields$ | async,\n caseDefinitionKey: caseDefinitionKey$ | async,\n noResultsMessage: noResultsMessage$ | async,\n } as obs\"\n class=\"main-content\"\n>\n <div class=\"container-fluid\">\n @if (obs.caseDefinitionKey && obs.caseDefinitionKey !== ALL_CASES_ID) {\n <ng-container\n *ngTemplateOutlet=\"\n searchFields;\n context: {\n obs: obs,\n }\n \"\n ></ng-container>\n\n <div class=\"mb-3\">\n <valtimo-quick-search (quickSearchEvent)=\"onQuickSearchEvent($event)\"></valtimo-quick-search>\n </div>\n }\n\n <ng-container\n *ngTemplateOutlet=\"\n tasksList;\n context: {\n obs: obs,\n }\n \"\n ></ng-container>\n\n <ng-container\n *ngTemplateOutlet=\"\n tasksListLoading;\n context: {\n obs: obs,\n }\n \"\n ></ng-container>\n\n <valtimo-task-detail-modal\n #taskDetail\n (formSubmit)=\"reload()\"\n (assignmentOfTaskChanged)=\"reload()\"\n (dueDateChanged)=\"reload()\"\n (modalClosed)=\"reload()\"\n ></valtimo-task-detail-modal>\n </div>\n</div>\n\n<ng-template #configuredTabs let-selectedTaskType=\"selectedTaskType\" let-visibleTabs=\"visibleTabs\">\n <cds-tabs *ngIf=\"visibleTabs\" type=\"contained\" class=\"valtimo-carbon-list__tabs\">\n <cds-tab\n *ngFor=\"let tab of visibleTabs\"\n [attr.data-testid]=\"'task-list-tab-' + tab\"\n [heading]=\"'task-list.' + tab + '.title' | translate\"\n [active]=\"selectedTaskType === tab\"\n (selected)=\"tabChange(tab)\"\n ></cds-tab>\n </cds-tabs>\n</ng-template>\n\n<ng-template #unreadIndicator let-data=\"data\">\n <span *ngIf=\"!data.item?.isOpened\" class=\"valtimo-task-list__unread-dot\"></span>\n</ng-template>\n\n<ng-template #caseLink let-data=\"data\">\n <ng-container *ngIf=\"cachedTasks$ | async as cachedTasks\">\n <div *ngIf=\"cachedTasks[data.index].caseLocked\">\n <a\n class=\"float-left cds--link--disabled\"\n cdsLink\n href=\"javascript:void(0)\"\n ngbTooltip=\"{{ 'task-list.caseLocked' | translate }}\"\n (click)=\"$event.stopPropagation()\"\n >\n {{ 'task-list.goToCase' | translate }}\n </a>\n </div>\n <div *ngIf=\"!cachedTasks[data.index].caseLocked\">\n <a\n class=\"float-left cds--link\"\n cdsLink\n href=\"javascript:void(0)\"\n (click)=\"openRelatedCase($event, data.index)\"\n >\n {{ 'task-list.goToCase' | translate }}\n </a>\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #tasksList let-obs=\"obs\">\n <valtimo-carbon-list\n *ngIf=\"!obs.loading\"\n [fields]=\"obs.fields\"\n [header]=\"false\"\n [items]=\"obs.tasks\"\n [lastColumnTemplate]=\"caseLink\"\n [pagination]=\"obs.pagination\"\n\n lockedTooltipTranslationKey=\"task-list.rowLocked\"\n [sortState]=\"obs.overrideSortState || obs.sortState\"\n (paginationClicked)=\"paginationClicked($event, obs.selectedTaskType)\"\n (paginationSet)=\"paginationSet($event)\"\n (rowClicked)=\"rowOpenTaskClick($event)\"\n (sortChanged)=\"sortChanged($event)\"\n >\n <div tabs>\n <ng-container *ngIf=\"obs.visibleTabs\">\n <ng-container\n *ngTemplateOutlet=\"\n configuredTabs;\n context: {selectedTaskType: obs.selectedTaskType, visibleTabs: obs.visibleTabs}\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n <div carbonToolbarContent>\n <valtimo-list-column-view\n *ngIf=\"obs.caseDefinitionKey && obs.caseDefinitionKey !== ALL_CASES_ID\"\n [availableFields]=\"obs.availableFields\"\n [hiddenColumns]=\"obs.hiddenColumns\"\n (viewUpdateEvent)=\"onViewUpdateEvent($event)\"\n ></valtimo-list-column-view>\n </div>\n\n <valtimo-no-results\n [description]=\"obs.noResultsMessage.description | translate\"\n [title]=\"obs.noResultsMessage.title | translate\"\n >\n </valtimo-no-results>\n </valtimo-carbon-list>\n</ng-template>\n\n<ng-template #tasksListLoading let-obs=\"obs\">\n <valtimo-carbon-list *ngIf=\"obs.loading\" [loading]=\"true\">\n <div tabs>\n <cds-tabs *ngIf=\"!obs.visibleTabs\" type=\"contained\" class=\"valtimo-carbon-list__tabs\">\n <cds-tab\n [heading]=\"'task-list.mine.title' | translate\"\n [active]=\"obs.selectedTaskType === 'mine'\"\n >\n </cds-tab>\n\n <cds-tab\n [heading]=\"'task-list.open.title' | translate\"\n [active]=\"obs.selectedTaskType === 'open'\"\n >\n </cds-tab>\n\n <cds-tab\n [heading]=\"'task-list.all.title' | translate\"\n [active]=\"obs.selectedTaskType === 'all'\"\n >\n </cds-tab>\n </cds-tabs>\n\n <cds-tabs *ngIf=\"obs.visibleTabs\" type=\"contained\" class=\"valtimo-carbon-list__tabs\">\n <cds-tab\n *ngFor=\"let tab of obs.visibleTabs\"\n [heading]=\"'task-list.' + tab + '.title' | translate\"\n [active]=\"obs.selectedTaskType === tab\"\n ></cds-tab>\n </cds-tabs>\n </div>\n </valtimo-carbon-list>\n</ng-template>\n\n<ng-template #searchFields let-obs=\"obs\">\n <div class=\"mb-3\">\n <valtimo-search-fields\n [canSaveSearch]=\"true\"\n [searchFields]=\"obs.searchFields\"\n [inputDisabled]=\"obs.loadingSearchFields\"\n [caseDefinitionKey]=\"obs.caseDefinitionKey\"\n [setValuesSubject$]=\"setSearchFieldValuesSubject$\"\n [clearValuesSubject$]=\"clearSearchFieldValuesSubject$\"\n (doSearch)=\"search($event)\"\n (saveSearchEvent)=\"onSaveSearchEvent($event)\"\n >\n </valtimo-search-fields>\n </div>\n</ng-template>\n\n<ng-container renderInPageHeader [fullWidth]=\"true\">\n <ng-template>\n <cds-dropdown\n class=\"case-definition-selection\"\n *ngIf=\"{\n loadingCaseListItems: loadingCaseListItems$ | async,\n caseListItems: caseListItems$ | async,\n } as obs\"\n [attr.data-testid]=\"'task-list-case-dropdown'\"\n [disabled]=\"obs.loadingCaseListItems || (obs.caseListItems || []).length === 1\"\n [skeleton]=\"obs.loadingCaseListItems\"\n (selected)=\"setCaseDefinition($event)\"\n >\n <cds-dropdown-list [items]=\"obs.caseListItems || []\"></cds-dropdown-list>\n </cds-dropdown>\n </ng-template>\n</ng-container>\n", styles: [".cds--link--disabled{cursor:not-allowed;pointer-events:auto!important;outline:0!important}.case-definition-selection{display:flex;width:250px}.valtimo-task-list__unread-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background-color:var(--cds-link-primary)}::ng-deep .valtimo-task-list__unread-column{width:2rem;padding-right:0!important}\n/*!\n * Copyright 2015-2025 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i9.CarbonListComponent, selector: "valtimo-carbon-list", inputs: ["items", "fields", "tableTranslations", "paginatorConfig", "pagination", "loading", "skeletonRowCount", "actions", "actionItems", "showActionItems", "header", "hideColumnHeader", "initialSortState", "sortState", "isSearchable", "initialSearchValue", "searchDebounceMs", "invalidSearchFields", "searchFields", "enableSingleSelection", "lastColumnTemplate", "paginationIdentifier", "showSelectionColumn", "striped", "hideToolbar", "lockedTooltipTranslationKey", "movingRowsEnabled", "dragAndDrop", "dragAndDropDisabled", "expandedRowTemplate", "expandedRowKey", "trackByKey"], outputs: ["rowClicked", "paginationClicked", "paginationSet", "search", "sortChanged", "moveRow", "itemsReordered"] }, { kind: "component", type: i9.CarbonNoResultsComponent, selector: "valtimo-no-results", inputs: ["action", "description", "illustration", "title", "smallPadding", "collapseVertically", "alwaysRenderVertically"] }, { kind: "directive", type: i13.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "triggers", "container", "disableTooltip", "tooltipClass", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "directive", type: i2$1.Link, selector: "[cdsLink], [ibmLink]", inputs: ["inline", "disabled"] }, { kind: "component", type: i2$1.Tabs, selector: "cds-tabs, ibm-tabs", inputs: ["position", "cacheActive", "followFocus", "isNavigation", "ariaLabel", "ariaLabelledby", "type", "theme", "skeleton"] }, { kind: "component", type: i2$1.Tab, selector: "cds-tab, ibm-tab", inputs: ["heading", "title", "context", "active", "disabled", "tabIndex", "id", "cacheActive", "tabContent", "templateContext"], outputs: ["selected"] }, { kind: "directive", type: i9.RenderInPageHeaderDirective, selector: "[renderInPageHeader]", inputs: ["fullWidth"] }, { kind: "component", type: i2$1.Dropdown, selector: "cds-dropdown, ibm-dropdown", inputs: ["id", "label", "hideLabel", "helperText", "placeholder", "displayValue", "clearText", "size", "type", "theme", "disabled", "readonly", "skeleton", "inline", "disableArrowKeys", "invalid", "invalidText", "warn", "warnText", "appendInline", "scrollableContainer", "itemValueKey", "selectionFeedback", "menuButtonLabel", "selectedLabel", "dropUp", "fluid"], outputs: ["selected", "onClose", "close"] }, { kind: "component", type: i2$1.DropdownList, selector: "cds-dropdown-list, ibm-dropdown-list", inputs: ["ariaLabel", "items", "listTpl", "type", "showTitles"], outputs: ["select", "scroll", "blurIntent"] }, { kind: "component", type: i9.SearchFieldsComponent, selector: "valtimo-search-fields", inputs: ["loading", "searchFields", "caseDefinitionKey", "setValuesSubject$", "clearValuesSubject$", "defaultValues", "disableSaveSearch", "inputDisabled", "externalSearchField", "canSaveSearch"], outputs: ["doSearch", "saveSearchEvent", "clearEvent"] }, { kind: "component", type: i9.QuickSearchComponent, selector: "valtimo-quick-search", outputs: ["quickSearchEvent"] }, { kind: "component", type: i9.ListColumnViewComponent, selector: "valtimo-list-column-view", inputs: ["availableFields", "hiddenColumns", "disabled"], outputs: ["viewUpdateEvent"] }, { kind: "component", type: TaskDetailModalComponent, selector: "valtimo-task-detail-modal", inputs: ["modalSize", "openFromCaseManagement"], outputs: ["formSubmit", "assignmentOfTaskChanged", "dueDateChanged", "modalClosed"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i4$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2494
2569
|
}
|
|
2495
2570
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TaskListComponent, decorators: [{
|
|
2496
2571
|
type: Component,
|