@valtimo/task 0.0.0-test

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.
Files changed (61) hide show
  1. package/fesm2022/valtimo-task.mjs +2675 -0
  2. package/fesm2022/valtimo-task.mjs.map +1 -0
  3. package/index.d.ts +6 -0
  4. package/lib/components/set-task-due-date/set-task-due-date.component.d.ts +52 -0
  5. package/lib/components/set-task-due-date/set-task-due-date.component.d.ts.map +1 -0
  6. package/lib/components/task-detail-content/task-detail-content.component.d.ts +92 -0
  7. package/lib/components/task-detail-content/task-detail-content.component.d.ts.map +1 -0
  8. package/lib/components/task-detail-intermediate-save/task-detail-intermediate-save.component.d.ts +43 -0
  9. package/lib/components/task-detail-intermediate-save/task-detail-intermediate-save.component.d.ts.map +1 -0
  10. package/lib/components/task-detail-modal/task-detail-modal.component.d.ts +77 -0
  11. package/lib/components/task-detail-modal/task-detail-modal.component.d.ts.map +1 -0
  12. package/lib/components/task-list/task-list.component.d.ts +90 -0
  13. package/lib/components/task-list/task-list.component.d.ts.map +1 -0
  14. package/lib/constants/index.d.ts +2 -0
  15. package/lib/constants/index.d.ts.map +1 -0
  16. package/lib/constants/task-list.constants.d.ts +4 -0
  17. package/lib/constants/task-list.constants.d.ts.map +1 -0
  18. package/lib/models/index.d.ts +7 -0
  19. package/lib/models/index.d.ts.map +1 -0
  20. package/lib/models/task-definition.model.d.ts +7 -0
  21. package/lib/models/task-definition.model.d.ts.map +1 -0
  22. package/lib/models/task-intermediate-save.model.d.ts +13 -0
  23. package/lib/models/task-intermediate-save.model.d.ts.map +1 -0
  24. package/lib/models/task-list-search-field.model.d.ts +40 -0
  25. package/lib/models/task-list-search-field.model.d.ts.map +1 -0
  26. package/lib/models/task-list.model.d.ts +59 -0
  27. package/lib/models/task-list.model.d.ts.map +1 -0
  28. package/lib/models/task-sse-event.model.d.ts +8 -0
  29. package/lib/models/task-sse-event.model.d.ts.map +1 -0
  30. package/lib/models/task.model.d.ts +78 -0
  31. package/lib/models/task.model.d.ts.map +1 -0
  32. package/lib/services/index.d.ts +8 -0
  33. package/lib/services/index.d.ts.map +1 -0
  34. package/lib/services/task-intermediate-save.service.d.ts +22 -0
  35. package/lib/services/task-intermediate-save.service.d.ts.map +1 -0
  36. package/lib/services/task-list-column.service.d.ts +27 -0
  37. package/lib/services/task-list-column.service.d.ts.map +1 -0
  38. package/lib/services/task-list-pagination.service.d.ts +20 -0
  39. package/lib/services/task-list-pagination.service.d.ts.map +1 -0
  40. package/lib/services/task-list-query-param.service.d.ts +16 -0
  41. package/lib/services/task-list-query-param.service.d.ts.map +1 -0
  42. package/lib/services/task-list-search.service.d.ts +25 -0
  43. package/lib/services/task-list-search.service.d.ts.map +1 -0
  44. package/lib/services/task-list-sort.service.d.ts +29 -0
  45. package/lib/services/task-list-sort.service.d.ts.map +1 -0
  46. package/lib/services/task-list.service.d.ts +21 -0
  47. package/lib/services/task-list.service.d.ts.map +1 -0
  48. package/lib/services/task.service.d.ts +31 -0
  49. package/lib/services/task.service.d.ts.map +1 -0
  50. package/lib/task-permissions.d.ts +11 -0
  51. package/lib/task-permissions.d.ts.map +1 -0
  52. package/lib/task-routing.module.d.ts +9 -0
  53. package/lib/task-routing.module.d.ts.map +1 -0
  54. package/lib/task.module.d.ts +21 -0
  55. package/lib/task.module.d.ts.map +1 -0
  56. package/lib/utils/task-enrichment.utils.d.ts +9 -0
  57. package/lib/utils/task-enrichment.utils.d.ts.map +1 -0
  58. package/package.json +26 -0
  59. package/public_api.d.ts +12 -0
  60. package/public_api.d.ts.map +1 -0
  61. package/valtimo-task.d.ts.map +1 -0
@@ -0,0 +1,2675 @@
1
+ import * as i6 from '@angular/common';
2
+ import { CommonModule } from '@angular/common';
3
+ import * as i0 from '@angular/core';
4
+ import { Injectable, EventEmitter, ViewContainerRef, Output, Input, ViewChild, Optional, Inject, ChangeDetectionStrategy, Component, signal, ViewEncapsulation, HostListener, NgModule } from '@angular/core';
5
+ import { RecentlyViewed16, CalendarAdd16, Edit16, FolderDetailsReference16 } from '@carbon/icons';
6
+ import * as i4$1 from '@ngx-translate/core';
7
+ import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
8
+ import * as i9 from '@valtimo/components';
9
+ import { ViewType, FormioOptionsImpl, FormIoModule, ConfirmationModalModule, TooltipModule, RemoveClassnamesDirective, runAfterCarbonModalClosed, CarbonListModule, PageHeaderModule, WidgetModule, SpinnerModule, CamundaFormModule, RenderInPageHeaderDirective, SearchFieldsModule, AssignmentComponent, ValtimoCdsModalDirective } from '@valtimo/components';
10
+ import * as i1$1 from '@valtimo/shared';
11
+ import { BaseApiService, TaskListTab, InterceptorSkip, FORM_VIEW_MODEL_TOKEN, ROLE_USER, HttpLoaderFactory } from '@valtimo/shared';
12
+ import * as i7 from '@valtimo/process-link';
13
+ import { FORM_CUSTOM_COMPONENT_TOKEN, ProcessLinkModule, formSizeToCarbonModalSizeMap } from '@valtimo/process-link';
14
+ import * as i2$1 from 'carbon-components-angular';
15
+ import { LoadingModule, NotificationModule, ButtonModule, IconModule, ModalModule, ToggletipModule, DatePickerModule, LayerModule, LinkModule, TabsModule, ContentSwitcherModule, DropdownModule, TooltipModule as TooltipModule$1 } from 'carbon-components-angular';
16
+ import { BehaviorSubject, combineLatest, tap, filter, switchMap, of, map as map$1, catchError, Subscription, take as take$1, distinctUntilChanged, Subject, shareReplay, EMPTY } from 'rxjs';
17
+ import * as i2 from '@valtimo/document';
18
+ import * as i4 from 'ngx-logger';
19
+ import * as i3 from '@valtimo/access-control';
20
+ import * as i1$2 from '@angular/router';
21
+ import { RouterModule } from '@angular/router';
22
+ import * as i1 from '@angular/common/http';
23
+ import { HttpParams, HttpHeaders, HttpClient } from '@angular/common/http';
24
+ import { map, take, filter as filter$1, startWith, distinctUntilChanged as distinctUntilChanged$1, switchMap as switchMap$1, catchError as catchError$1 } from 'rxjs/operators';
25
+ import { omit, isEqual } from 'lodash';
26
+ import moment from 'moment';
27
+ import * as i6$1 from '@valtimo/sse';
28
+ import * as i11 from '@valtimo/teams';
29
+ import * as i13 from '@ng-bootstrap/ng-bootstrap';
30
+ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
31
+ import { FormsModule } from '@angular/forms';
32
+ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
33
+ import { AuthGuardService } from '@valtimo/security';
34
+
35
+ /*
36
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
37
+ *
38
+ * Licensed under EUPL, Version 1.2 (the "License");
39
+ * you may not use this file except in compliance with the License.
40
+ * You may obtain a copy of the License at
41
+ *
42
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
43
+ *
44
+ * Unless required by applicable law or agreed to in writing, software
45
+ * distributed under the License is distributed on an "AS IS" basis,
46
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47
+ * See the License for the specific language governing permissions and
48
+ * limitations under the License.
49
+ */
50
+ var PERMISSION_ACTION;
51
+ (function (PERMISSION_ACTION) {
52
+ PERMISSION_ACTION["assign"] = "assign";
53
+ PERMISSION_ACTION["view"] = "view";
54
+ PERMISSION_ACTION["modify"] = "modify";
55
+ })(PERMISSION_ACTION || (PERMISSION_ACTION = {}));
56
+ var TASK_DETAIL_PERMISSION_RESOURCE;
57
+ (function (TASK_DETAIL_PERMISSION_RESOURCE) {
58
+ TASK_DETAIL_PERMISSION_RESOURCE["jsonSchemaDocument"] = "com.ritense.document.domain.impl.JsonSchemaDocument";
59
+ TASK_DETAIL_PERMISSION_RESOURCE["task"] = "com.ritense.valtimo.operaton.domain.OperatonTask";
60
+ })(TASK_DETAIL_PERMISSION_RESOURCE || (TASK_DETAIL_PERMISSION_RESOURCE = {}));
61
+ const CAN_ASSIGN_TASK_PERMISSION = {
62
+ action: PERMISSION_ACTION.assign,
63
+ resource: TASK_DETAIL_PERMISSION_RESOURCE.task,
64
+ };
65
+ const CAN_VIEW_TASK_PERMISSION = {
66
+ action: PERMISSION_ACTION.view,
67
+ resource: TASK_DETAIL_PERMISSION_RESOURCE.task,
68
+ };
69
+ const CAN_VIEW_CASE_PERMISSION = {
70
+ action: PERMISSION_ACTION.view,
71
+ resource: TASK_DETAIL_PERMISSION_RESOURCE.jsonSchemaDocument,
72
+ };
73
+ const CAN_MODIFY_TASK_PERMISSION = {
74
+ action: PERMISSION_ACTION.modify,
75
+ resource: TASK_DETAIL_PERMISSION_RESOURCE.task,
76
+ };
77
+
78
+ /*
79
+ * Copyright 2015-2026 Ritense BV, the Netherlands.
80
+ *
81
+ * Licensed under EUPL, Version 1.2 (the "License");
82
+ * you may not use this file except in compliance with the License.
83
+ * You may obtain a copy of the License at
84
+ *
85
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
86
+ *
87
+ * Unless required by applicable law or agreed to in writing, software
88
+ * distributed under the License is distributed on an "AS IS" basis,
89
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
90
+ * See the License for the specific language governing permissions and
91
+ * limitations under the License.
92
+ */
93
+ /**
94
+ * Enriches a task with assignee and due date from a process link result,
95
+ * only filling in fields that are missing on the task itself.
96
+ * Returns a new task object if any fields were enriched, or the original task if unchanged.
97
+ */
98
+ function enrichTaskFromProcessLink(task, processLink) {
99
+ if (!processLink)
100
+ return task;
101
+ const needsAssignee = processLink.assignee && !task.assignee;
102
+ const needsDue = processLink.due && !task.due;
103
+ if (!needsAssignee && !needsDue)
104
+ return task;
105
+ return {
106
+ ...task,
107
+ ...(needsAssignee && { assignee: processLink.assignee }),
108
+ ...(needsDue && { due: processLink.due }),
109
+ };
110
+ }
111
+
112
+ /*
113
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
114
+ *
115
+ * Licensed under EUPL, Version 1.2 (the "License");
116
+ * you may not use this file except in compliance with the License.
117
+ * You may obtain a copy of the License at
118
+ *
119
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
120
+ *
121
+ * Unless required by applicable law or agreed to in writing, software
122
+ * distributed under the License is distributed on an "AS IS" basis,
123
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124
+ * See the License for the specific language governing permissions and
125
+ * limitations under the License.
126
+ */
127
+ class TaskService extends BaseApiService {
128
+ constructor(httpClient, configService) {
129
+ super(httpClient, configService);
130
+ this.httpClient = httpClient;
131
+ this.configService = configService;
132
+ }
133
+ queryTasks(params) {
134
+ return this.httpClient.get(this.getApiUrl('/v1/task'), {
135
+ observe: 'response',
136
+ params,
137
+ });
138
+ }
139
+ queryTasksPage(params) {
140
+ return this.httpClient.get(this.getApiUrl('/v2/task'), {
141
+ params,
142
+ });
143
+ }
144
+ queryTasksPageV3(assigneeFilter = TaskListTab.ALL, pageParams, caseDefinitionKey, otherFilters) {
145
+ let httpParams = new HttpParams().set('page', pageParams.page).set('size', pageParams.size);
146
+ if (pageParams.sort) {
147
+ httpParams = httpParams.append('sort', pageParams.sort);
148
+ }
149
+ if (caseDefinitionKey && (otherFilters || []).length > 0) {
150
+ return this.searchTasks(httpParams, caseDefinitionKey, otherFilters, assigneeFilter);
151
+ }
152
+ httpParams = httpParams.append('filter', assigneeFilter.toUpperCase());
153
+ return this.httpClient.post(this.getApiUrl('/v3/task'), { ...(caseDefinitionKey && { caseDefinitionKey }) }, { params: httpParams });
154
+ }
155
+ searchTasks(params, caseDefinitionKey, otherFilters, assigneeFilter = TaskListTab.ALL) {
156
+ return this.httpClient.post(this.getApiUrl(`/v1/document-definition/${caseDefinitionKey}/task/search`), {
157
+ caseDefinitionKey,
158
+ assigneeFilter: assigneeFilter.toUpperCase(),
159
+ ...(otherFilters && { otherFilters }),
160
+ }, { params });
161
+ }
162
+ getTasks() {
163
+ return this.httpClient.get(this.getApiUrl('/v1/task?filter=all'));
164
+ }
165
+ getTask(id) {
166
+ return this.httpClient.get(this.getApiUrl(`/v1/task/${id}`));
167
+ }
168
+ getCandidateUsers(id) {
169
+ return this.httpClient.get(this.getApiUrl(`/v2/task/${id}/candidate-user`));
170
+ }
171
+ getCandidateTeams(id) {
172
+ return this.httpClient.get(this.getApiUrl(`/v1/task/${id}/candidate-team`), { params: { size: '1000' } });
173
+ }
174
+ assignTask(id, assigneeRequest) {
175
+ return this.httpClient.post(this.getApiUrl(`/v1/task/${id}/assign`), assigneeRequest);
176
+ }
177
+ unassignTask(id) {
178
+ return this.httpClient.post(this.getApiUrl(`/v1/task/${id}/unassign`), null);
179
+ }
180
+ completeTask(id, variables) {
181
+ return this.httpClient.post(this.getApiUrl(`/v1/task/${id}/complete`), {
182
+ variables,
183
+ filesToDelete: [],
184
+ });
185
+ }
186
+ getTaskProcessLink(taskId) {
187
+ return this.httpClient.get(this.getApiUrl(`/v2/process-link/task/${taskId}`), { headers: new HttpHeaders().set(InterceptorSkip, '404') });
188
+ }
189
+ getTaskListColumns(caseDefinitionKey) {
190
+ return this.httpClient.get(this.getApiUrl(`/v1/case/${caseDefinitionKey}/task-list-column`));
191
+ }
192
+ getConfigCustomTaskList() {
193
+ return this.configService.config.customTaskList;
194
+ }
195
+ getTaskListSearchFields(caseDefinitionKey) {
196
+ return this.httpClient.get(this.getApiUrl(`v1/search/field/TaskListSearchColumns/${caseDefinitionKey}`));
197
+ }
198
+ setTaskDueDate(taskId, setTaskDueDateRequest) {
199
+ return this.httpClient.post(this.getApiUrl(`/v1/task/${taskId}/set-due-date`), setTaskDueDateRequest);
200
+ }
201
+ removeTaskDueDate(taskId) {
202
+ return this.httpClient.post(this.getApiUrl(`/v1/task/${taskId}/set-due-date`), null);
203
+ }
204
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskService, deps: [{ token: i1.HttpClient }, { token: i1$1.ConfigService }], target: i0.ɵɵFactoryTarget.Injectable }); }
205
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskService, providedIn: 'root' }); }
206
+ }
207
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskService, decorators: [{
208
+ type: Injectable,
209
+ args: [{ providedIn: 'root' }]
210
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i1$1.ConfigService }] });
211
+
212
+ /*
213
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
214
+ *
215
+ * Licensed under EUPL, Version 1.2 (the "License");
216
+ * you may not use this file except in compliance with the License.
217
+ * You may obtain a copy of the License at
218
+ *
219
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
220
+ *
221
+ * Unless required by applicable law or agreed to in writing, software
222
+ * distributed under the License is distributed on an "AS IS" basis,
223
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
224
+ * See the License for the specific language governing permissions and
225
+ * limitations under the License.
226
+ */
227
+ class TaskListService {
228
+ constructor() {
229
+ this._ALL_CASES_ID = 'ALL_CASES';
230
+ this._caseDefinitionKey$ = new BehaviorSubject(null);
231
+ this._selectedTaskType$ = new BehaviorSubject(TaskListTab.MINE);
232
+ this._loadingStateForCaseDefinition$ = new BehaviorSubject(false);
233
+ }
234
+ get caseDefinitionKey$() {
235
+ return this._caseDefinitionKey$.asObservable();
236
+ }
237
+ get selectedTaskType$() {
238
+ return this._selectedTaskType$.asObservable();
239
+ }
240
+ get caseDefinitionKey() {
241
+ return this._caseDefinitionKey$.getValue();
242
+ }
243
+ get selectedTaskType() {
244
+ return this._selectedTaskType$.getValue();
245
+ }
246
+ get loadingStateForCaseDefinition$() {
247
+ return this._loadingStateForCaseDefinition$.asObservable();
248
+ }
249
+ get ALL_CASES_ID() {
250
+ return this._ALL_CASES_ID;
251
+ }
252
+ setSelectedTaskType(type) {
253
+ this._selectedTaskType$.next(type);
254
+ }
255
+ setCaseDefinitionKey(caseDefinitionKey) {
256
+ this._loadingStateForCaseDefinition$.next(true);
257
+ this._caseDefinitionKey$.next(caseDefinitionKey);
258
+ }
259
+ setLoadingStateForCaseDefinition(loading) {
260
+ this._loadingStateForCaseDefinition$.next(loading);
261
+ }
262
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
263
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListService }); }
264
+ }
265
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListService, decorators: [{
266
+ type: Injectable
267
+ }] });
268
+
269
+ /*
270
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
271
+ *
272
+ * Licensed under EUPL, Version 1.2 (the "License");
273
+ * you may not use this file except in compliance with the License.
274
+ * You may obtain a copy of the License at
275
+ *
276
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
277
+ *
278
+ * Unless required by applicable law or agreed to in writing, software
279
+ * distributed under the License is distributed on an "AS IS" basis,
280
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
281
+ * See the License for the specific language governing permissions and
282
+ * limitations under the License.
283
+ */
284
+ class TaskListSortService {
285
+ get sortStateForCurrentTaskType$() {
286
+ return this._sortStateForCurrentTaskType$;
287
+ }
288
+ get sortStringForCurrentTaskType$() {
289
+ return this.sortStateForCurrentTaskType$.pipe(map(sortState => (sortState ? this.getSortString(sortState) : null)));
290
+ }
291
+ get overrideSortState$() {
292
+ return this._overrideSortState$.asObservable();
293
+ }
294
+ get overrideSortStateString$() {
295
+ return this._overrideSortState$.pipe(map(state => (state ? this.getSortString(state) : null)));
296
+ }
297
+ get _defaultSortState() {
298
+ return this.taskService.getConfigCustomTaskList()?.defaultSortedColumn || null;
299
+ }
300
+ constructor(taskService, taskListService) {
301
+ this.taskService = taskService;
302
+ this.taskListService = taskListService;
303
+ this._overrideSortState$ = new BehaviorSubject(null);
304
+ this._sortState$ = new BehaviorSubject({
305
+ [TaskListTab.ALL]: this._defaultSortState,
306
+ [TaskListTab.MINE]: this._defaultSortState,
307
+ [TaskListTab.OPEN]: this._defaultSortState,
308
+ [TaskListTab.TEAM]: this._defaultSortState,
309
+ });
310
+ this._sortStateForCurrentTaskType$ = combineLatest([
311
+ this.taskListService.selectedTaskType$,
312
+ this._sortState$,
313
+ ]).pipe(map(([selectedTaskType, sortStates]) => sortStates[selectedTaskType]));
314
+ }
315
+ updateSortState(taskType, updatedSortState) {
316
+ this._sortState$.pipe(take(1)).subscribe(sortState => {
317
+ this._sortState$.next({
318
+ ...sortState,
319
+ [taskType]: { ...sortState[taskType], ...updatedSortState },
320
+ });
321
+ });
322
+ }
323
+ updateSortStates(updatedSortState) {
324
+ this._sortState$.pipe(take(1)).subscribe(sortStates => {
325
+ const sortStatesCopy = { ...sortStates };
326
+ Object.keys(sortStates).forEach(taskType => {
327
+ sortStatesCopy[taskType] = { ...sortStatesCopy[taskType], ...updatedSortState };
328
+ });
329
+ this._sortState$.next(sortStatesCopy);
330
+ });
331
+ }
332
+ clearSortStates() {
333
+ this._sortState$.pipe(take(1)).subscribe(sortStates => {
334
+ const sortStatesCopy = { ...sortStates };
335
+ Object.keys(sortStates).forEach(taskType => {
336
+ sortStatesCopy[taskType] = null;
337
+ });
338
+ this._sortState$.next(sortStatesCopy);
339
+ });
340
+ }
341
+ resetDefaultSortStates() {
342
+ this._sortState$.pipe(take(1)).subscribe(sortStates => {
343
+ const sortStatesCopy = { ...sortStates };
344
+ Object.keys(sortStates).forEach(taskType => {
345
+ sortStatesCopy[taskType] = this._defaultSortState;
346
+ });
347
+ this._sortState$.next(sortStatesCopy);
348
+ });
349
+ }
350
+ getSortStateFromSortString(sortString) {
351
+ const splitString = sortString && sortString.split(',');
352
+ if (splitString?.length > 1) {
353
+ return {
354
+ isSorting: true,
355
+ state: {
356
+ name: splitString[0],
357
+ direction: splitString[1],
358
+ },
359
+ };
360
+ }
361
+ return null;
362
+ }
363
+ setOverrideSortState(state) {
364
+ this._overrideSortState$.next(state);
365
+ }
366
+ resetOverrideSortState() {
367
+ this._overrideSortState$.next(null);
368
+ }
369
+ getSortString(sort) {
370
+ return `${sort.state.name},${sort.state.direction}`;
371
+ }
372
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListSortService, deps: [{ token: TaskService }, { token: TaskListService }], target: i0.ɵɵFactoryTarget.Injectable }); }
373
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListSortService }); }
374
+ }
375
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListSortService, decorators: [{
376
+ type: Injectable
377
+ }], ctorParameters: () => [{ type: TaskService }, { type: TaskListService }] });
378
+
379
+ /*
380
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
381
+ *
382
+ * Licensed under EUPL, Version 1.2 (the "License");
383
+ * you may not use this file except in compliance with the License.
384
+ * You may obtain a copy of the License at
385
+ *
386
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
387
+ *
388
+ * Unless required by applicable law or agreed to in writing, software
389
+ * distributed under the License is distributed on an "AS IS" basis,
390
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
391
+ * See the License for the specific language governing permissions and
392
+ * limitations under the License.
393
+ */
394
+ class TaskListColumnService {
395
+ get hasCustomConfigTaskList() {
396
+ return !!this.taskService.getConfigCustomTaskList();
397
+ }
398
+ get fields$() {
399
+ return this._fields$.asObservable();
400
+ }
401
+ get taskListColumnsForCase$() {
402
+ return this.taskListService.caseDefinitionKey$.pipe(tap(caseDefinitionName => {
403
+ if (caseDefinitionName === this.taskListService.ALL_CASES_ID) {
404
+ this.resetTaskListFields();
405
+ }
406
+ }), filter(caseDefinitionName => !!caseDefinitionName && caseDefinitionName !== this.taskListService.ALL_CASES_ID), switchMap(caseDefinitionName => this.taskService.getTaskListColumns(caseDefinitionName)), tap(taskListColumns => {
407
+ if (taskListColumns.length === 0) {
408
+ this.taskListSortService.updateSortStates({
409
+ isSorting: true,
410
+ state: {
411
+ name: this._DEFAULT_SPECIFIED_TASK_LIST_FIELDS[0].key,
412
+ direction: 'DESC',
413
+ },
414
+ });
415
+ this._fields$.next(this._DEFAULT_SPECIFIED_TASK_LIST_FIELDS);
416
+ }
417
+ else {
418
+ this._fields$.next(this.mapTaskListColumnToColumnConfig(taskListColumns));
419
+ }
420
+ }), tap(() => this.taskListService.setLoadingStateForCaseDefinition(false)));
421
+ }
422
+ constructor(taskService, taskListService, taskListSortService) {
423
+ this.taskService = taskService;
424
+ this.taskListService = taskListService;
425
+ this.taskListSortService = taskListSortService;
426
+ this._DEFAULT_TASK_LIST_FIELDS = [
427
+ {
428
+ key: 'created',
429
+ label: `task-list.fieldLabels.created`,
430
+ viewType: ViewType.TEXT,
431
+ sortable: true,
432
+ },
433
+ {
434
+ key: 'name',
435
+ label: `task-list.fieldLabels.name`,
436
+ viewType: ViewType.TEXT,
437
+ sortable: true,
438
+ },
439
+ {
440
+ key: 'valtimoAssignee.fullName',
441
+ label: `task-list.fieldLabels.valtimoAssignee.fullName`,
442
+ viewType: ViewType.TEXT,
443
+ },
444
+ {
445
+ key: 'due',
446
+ label: `task-list.fieldLabels.due`,
447
+ viewType: ViewType.TEXT,
448
+ sortable: true,
449
+ },
450
+ {
451
+ key: 'context',
452
+ label: `task-list.fieldLabels.context`,
453
+ viewType: ViewType.TEXT,
454
+ },
455
+ ];
456
+ this._DEFAULT_SPECIFIED_TASK_LIST_FIELDS = [
457
+ {
458
+ key: 'createTime',
459
+ label: `task-list.fieldLabels.created`,
460
+ viewType: ViewType.DATE,
461
+ sortable: true,
462
+ format: 'DD MMM YYYY HH:mm',
463
+ },
464
+ {
465
+ key: 'name',
466
+ label: `task-list.fieldLabels.name`,
467
+ viewType: ViewType.TEXT,
468
+ sortable: true,
469
+ },
470
+ {
471
+ key: 'assignee',
472
+ label: `task-list.fieldLabels.valtimoAssignee.fullName`,
473
+ viewType: ViewType.TEXT,
474
+ },
475
+ {
476
+ key: 'dueDate',
477
+ label: `task-list.fieldLabels.due`,
478
+ viewType: ViewType.TEXT,
479
+ sortable: true,
480
+ },
481
+ ];
482
+ this._fields$ = new BehaviorSubject(this._DEFAULT_TASK_LIST_FIELDS);
483
+ }
484
+ resetTaskListFields() {
485
+ if (this.hasCustomConfigTaskList) {
486
+ this.setFieldsToCustomTaskListFields();
487
+ }
488
+ else {
489
+ this.setFieldsToDefaultTaskListFields();
490
+ }
491
+ this.taskListSortService.resetDefaultSortStates();
492
+ this.taskListService.setLoadingStateForCaseDefinition(false);
493
+ }
494
+ setFieldsToCustomTaskListFields() {
495
+ const customTaskListFields = this.taskService.getConfigCustomTaskList().fields;
496
+ if (customTaskListFields) {
497
+ this._fields$.next(customTaskListFields.map((column, index) => ({
498
+ key: column.propertyName,
499
+ label: `task-list.fieldLabels.${column.translationKey}`,
500
+ sortable: column.sortable,
501
+ ...(column.viewType && { viewType: column.viewType }),
502
+ ...(column.enum && { enum: column.enum }),
503
+ })));
504
+ }
505
+ }
506
+ setFieldsToDefaultTaskListFields() {
507
+ this._fields$.next(this._DEFAULT_TASK_LIST_FIELDS);
508
+ }
509
+ mapTaskListColumnToColumnConfig(taskListColumns) {
510
+ const hasDefaultSort = !!taskListColumns.find(column => column.defaultSort);
511
+ const firstSortableColumn = taskListColumns.find(column => column.sortable);
512
+ if (!hasDefaultSort && firstSortableColumn) {
513
+ this.taskListSortService.updateSortStates({
514
+ isSorting: true,
515
+ state: {
516
+ name: firstSortableColumn.key,
517
+ direction: 'DESC',
518
+ },
519
+ });
520
+ }
521
+ if (!hasDefaultSort && !firstSortableColumn) {
522
+ this.taskListSortService.clearSortStates();
523
+ }
524
+ return taskListColumns.map(column => {
525
+ if (column.defaultSort) {
526
+ this.taskListSortService.updateSortStates({
527
+ isSorting: true,
528
+ state: {
529
+ name: column.key,
530
+ direction: column.defaultSort,
531
+ },
532
+ });
533
+ }
534
+ return {
535
+ viewType: this.getViewType(column.displayType.type),
536
+ key: column.key,
537
+ label: column.title || column.key,
538
+ sortable: column.sortable,
539
+ ...(column?.displayType?.displayTypeParameters?.enum && {
540
+ enum: column?.displayType?.displayTypeParameters?.enum,
541
+ }),
542
+ ...(column?.displayType?.displayTypeParameters?.dateFormat && {
543
+ format: column?.displayType?.displayTypeParameters?.dateFormat,
544
+ }),
545
+ };
546
+ });
547
+ }
548
+ getViewType(taskListColumnColumnDisplayType) {
549
+ switch (taskListColumnColumnDisplayType) {
550
+ case 'arrayCount':
551
+ return 'relatedFiles';
552
+ case 'underscoresToSpaces':
553
+ return 'stringReplaceUnderscore';
554
+ default:
555
+ return taskListColumnColumnDisplayType;
556
+ }
557
+ }
558
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListColumnService, deps: [{ token: TaskService }, { token: TaskListService }, { token: TaskListSortService }], target: i0.ɵɵFactoryTarget.Injectable }); }
559
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListColumnService }); }
560
+ }
561
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListColumnService, decorators: [{
562
+ type: Injectable
563
+ }], ctorParameters: () => [{ type: TaskService }, { type: TaskListService }, { type: TaskListSortService }] });
564
+
565
+ /*
566
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
567
+ *
568
+ * Licensed under EUPL, Version 1.2 (the "License");
569
+ * you may not use this file except in compliance with the License.
570
+ * You may obtain a copy of the License at
571
+ *
572
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
573
+ *
574
+ * Unless required by applicable law or agreed to in writing, software
575
+ * distributed under the License is distributed on an "AS IS" basis,
576
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
577
+ * See the License for the specific language governing permissions and
578
+ * limitations under the License.
579
+ */
580
+ class TaskListPaginationService {
581
+ get paginationForCurrentTaskType$() {
582
+ return this._paginationForCurrentTaskType$;
583
+ }
584
+ get paginationForCurrentTaskTypeForList$() {
585
+ return this._paginationForCurrentTaskType$.pipe(map(pagination => ({ ...pagination, page: pagination?.page + 1 || 1 })));
586
+ }
587
+ constructor(taskListService) {
588
+ this.taskListService = taskListService;
589
+ this._pagination$ = new BehaviorSubject({
590
+ [TaskListTab.ALL]: this.getDefaultPagination(),
591
+ [TaskListTab.MINE]: this.getDefaultPagination(),
592
+ [TaskListTab.OPEN]: this.getDefaultPagination(),
593
+ [TaskListTab.TEAM]: this.getDefaultPagination(),
594
+ });
595
+ this._paginationForCurrentTaskType$ = combineLatest([
596
+ this.taskListService.selectedTaskType$,
597
+ this._pagination$,
598
+ ]).pipe(map(([selectedTaskType, pagination]) => pagination[selectedTaskType]));
599
+ }
600
+ updateTaskPagination(taskType, updatedPagination) {
601
+ this._pagination$.pipe(take(1)).subscribe(pagination => {
602
+ const currentPagination = pagination[taskType];
603
+ this._pagination$.next({
604
+ ...pagination,
605
+ [taskType]: { ...currentPagination, ...updatedPagination },
606
+ });
607
+ });
608
+ }
609
+ getLastAvailablePage(page, size, collectionSize) {
610
+ if (this.isNumber(page) && this.isNumber(size) && this.isNumber(collectionSize) && page !== 0) {
611
+ const amountOfPages = Math.ceil(collectionSize / size);
612
+ if (page + 1 > amountOfPages) {
613
+ return amountOfPages - 1;
614
+ }
615
+ }
616
+ return page;
617
+ }
618
+ isNumber(value) {
619
+ return typeof value === 'number';
620
+ }
621
+ getDefaultPagination() {
622
+ return {
623
+ page: 0,
624
+ size: 10,
625
+ };
626
+ }
627
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListPaginationService, deps: [{ token: TaskListService }], target: i0.ɵɵFactoryTarget.Injectable }); }
628
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListPaginationService }); }
629
+ }
630
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListPaginationService, decorators: [{
631
+ type: Injectable
632
+ }], ctorParameters: () => [{ type: TaskListService }] });
633
+
634
+ /*
635
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
636
+ *
637
+ * Licensed under EUPL, Version 1.2 (the "License");
638
+ * you may not use this file except in compliance with the License.
639
+ * You may obtain a copy of the License at
640
+ *
641
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
642
+ *
643
+ * Unless required by applicable law or agreed to in writing, software
644
+ * distributed under the License is distributed on an "AS IS" basis,
645
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
646
+ * See the License for the specific language governing permissions and
647
+ * limitations under the License.
648
+ */
649
+ class TaskListSearchService {
650
+ get loadingSearchFields$() {
651
+ return this._loadingSearchFields$.asObservable();
652
+ }
653
+ get otherFilters$() {
654
+ return this._otherFilters$.asObservable();
655
+ }
656
+ constructor(configService, taskListService, taskService) {
657
+ this.configService = configService;
658
+ this.taskListService = taskListService;
659
+ this.taskService = taskService;
660
+ this._loadingSearchFields$ = new BehaviorSubject(true);
661
+ this._otherFilters$ = new BehaviorSubject([]);
662
+ this.searchFields$ = this.taskListService.caseDefinitionKey$.pipe(tap(() => this._loadingSearchFields$.next(true)), switchMap(caseDefinitionName => caseDefinitionName
663
+ ? this.taskService.getTaskListSearchFields(caseDefinitionName)
664
+ : of([])), map$1(searchFields => searchFields.map(searchField => {
665
+ const fieldTypeLowerCase = searchField.fieldType?.toLowerCase();
666
+ return {
667
+ ...searchField,
668
+ dataType: searchField.dataType?.toLowerCase(),
669
+ fieldType: fieldTypeLowerCase === 'text_contains' ? 'single' : fieldTypeLowerCase,
670
+ matchType: searchField?.matchType?.toLowerCase(),
671
+ };
672
+ })), tap(() => this._loadingSearchFields$.next(false)));
673
+ }
674
+ setSearchFieldValues(searchFieldValues) {
675
+ this._otherFilters$.next(this.mapSearchValuesToFilters(searchFieldValues));
676
+ }
677
+ setOtherFilters(otherFilters) {
678
+ this._otherFilters$.next(otherFilters);
679
+ }
680
+ resetOtherFilters() {
681
+ this._otherFilters$.next([]);
682
+ }
683
+ mapOtherFilterToSearchValues(otherFilters) {
684
+ return otherFilters.reduce((acc, curr) => {
685
+ const filter = curr;
686
+ if (filter.rangeFrom) {
687
+ return {
688
+ ...acc,
689
+ [filter.key]: {
690
+ start: filter.rangeFrom,
691
+ end: filter.rangeTo,
692
+ },
693
+ };
694
+ }
695
+ else if (filter.multiValue) {
696
+ return { ...acc, [filter.key]: filter.values };
697
+ }
698
+ else if (Array.isArray(filter.values) && filter.values.length > 0 && !filter.multiValue) {
699
+ return { ...acc, [filter.key]: filter.values[0] };
700
+ }
701
+ return acc;
702
+ }, {});
703
+ }
704
+ mapSearchValuesToFilters(values) {
705
+ const filters = [];
706
+ Object.keys(values).forEach(valueKey => {
707
+ const searchValue = values[valueKey];
708
+ if (searchValue.start) {
709
+ filters.push({ key: valueKey, rangeFrom: searchValue.start, rangeTo: searchValue.end });
710
+ }
711
+ else if (Array.isArray(searchValue)) {
712
+ filters.push({ key: valueKey, values: searchValue, multiValue: true });
713
+ }
714
+ else {
715
+ filters.push({ key: valueKey, values: [searchValue], multiValue: false });
716
+ }
717
+ });
718
+ return filters;
719
+ }
720
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListSearchService, deps: [{ token: i1$1.ConfigService }, { token: TaskListService }, { token: TaskService }], target: i0.ɵɵFactoryTarget.Injectable }); }
721
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListSearchService }); }
722
+ }
723
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListSearchService, decorators: [{
724
+ type: Injectable
725
+ }], ctorParameters: () => [{ type: i1$1.ConfigService }, { type: TaskListService }, { type: TaskService }] });
726
+
727
+ /*
728
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
729
+ *
730
+ * Licensed under EUPL, Version 1.2 (the "License");
731
+ * you may not use this file except in compliance with the License.
732
+ * You may obtain a copy of the License at
733
+ *
734
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
735
+ *
736
+ * Unless required by applicable law or agreed to in writing, software
737
+ * distributed under the License is distributed on an "AS IS" basis,
738
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
739
+ * See the License for the specific language governing permissions and
740
+ * limitations under the License.
741
+ */
742
+ class TaskListQueryParamService {
743
+ setTaskListParams(params) {
744
+ const queryParams = omit(params, 'reload');
745
+ const encodedQueryParams = Object.keys(queryParams).reduce((acc, curr) => ({ ...acc, [curr]: this.objectToBase64(queryParams[curr]) }), {});
746
+ this.router.navigate([this.getUrlWithoutParams()], { queryParams: encodedQueryParams });
747
+ }
748
+ constructor(router, route) {
749
+ this.router = router;
750
+ this.route = route;
751
+ }
752
+ getTaskListQueryParams() {
753
+ const queryParams = this.route.snapshot.queryParams;
754
+ const decodedParams = Object.keys(queryParams).reduce((acc, curr) => ({ ...acc, [curr]: this.parseBase64(queryParams[curr]) }), {});
755
+ return decodedParams;
756
+ }
757
+ getUrlWithoutParams() {
758
+ const urlTree = this.router.parseUrl(this.router.url);
759
+ urlTree.queryParams = {};
760
+ urlTree.fragment = null;
761
+ return urlTree.toString();
762
+ }
763
+ objectToBase64(jsObject) {
764
+ return btoa(JSON.stringify(jsObject));
765
+ }
766
+ parseBase64(base64string) {
767
+ return JSON.parse(atob(base64string));
768
+ }
769
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListQueryParamService, deps: [{ token: i1$2.Router }, { token: i1$2.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Injectable }); }
770
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListQueryParamService }); }
771
+ }
772
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListQueryParamService, decorators: [{
773
+ type: Injectable
774
+ }], ctorParameters: () => [{ type: i1$2.Router }, { type: i1$2.ActivatedRoute }] });
775
+
776
+ /*
777
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
778
+ *
779
+ * Licensed under EUPL, Version 1.2 (the "License");
780
+ * you may not use this file except in compliance with the License.
781
+ * You may obtain a copy of the License at
782
+ *
783
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
784
+ *
785
+ * Unless required by applicable law or agreed to in writing, software
786
+ * distributed under the License is distributed on an "AS IS" basis,
787
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
788
+ * See the License for the specific language governing permissions and
789
+ * limitations under the License.
790
+ */
791
+ class TaskIntermediateSaveService extends BaseApiService {
792
+ get submission$() {
793
+ return this._submission$.pipe(filter((value) => !!value));
794
+ }
795
+ get formIoFormData$() {
796
+ return this._formIoFormData$.pipe(filter((value) => !!value));
797
+ }
798
+ constructor(httpClient, configService) {
799
+ super(httpClient, configService);
800
+ this.httpClient = httpClient;
801
+ this.configService = configService;
802
+ this._submission$ = new BehaviorSubject({});
803
+ this._formIoFormData$ = new BehaviorSubject({});
804
+ }
805
+ getIntermediateSubmission(taskInstanceId) {
806
+ return this.httpClient
807
+ .get(this.getApiUrl('/v1/form/intermediate/submission'), {
808
+ params: {
809
+ taskInstanceId,
810
+ },
811
+ headers: new HttpHeaders().set(InterceptorSkip, '404'),
812
+ })
813
+ .pipe(catchError(() => of(null)));
814
+ }
815
+ storeIntermediateSubmission(request) {
816
+ return this.httpClient.post(this.getApiUrl('/v1/form/intermediate/submission'), request, {
817
+ headers: new HttpHeaders().set(InterceptorSkip, '400'),
818
+ });
819
+ }
820
+ clearIntermediateSubmission(taskInstanceId) {
821
+ return this.httpClient.delete(this.getApiUrl('/v1/form/intermediate/submission'), {
822
+ params: {
823
+ taskInstanceId,
824
+ },
825
+ });
826
+ }
827
+ setSubmission(value) {
828
+ this._submission$.next(value);
829
+ }
830
+ setFormIoFormData(value) {
831
+ this._formIoFormData$.next(value);
832
+ }
833
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskIntermediateSaveService, deps: [{ token: i1.HttpClient }, { token: i1$1.ConfigService }], target: i0.ɵɵFactoryTarget.Injectable }); }
834
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskIntermediateSaveService, providedIn: 'root' }); }
835
+ }
836
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskIntermediateSaveService, decorators: [{
837
+ type: Injectable,
838
+ args: [{ providedIn: 'root' }]
839
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i1$1.ConfigService }] });
840
+
841
+ /*
842
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
843
+ *
844
+ * Licensed under EUPL, Version 1.2 (the "License");
845
+ * you may not use this file except in compliance with the License.
846
+ * You may obtain a copy of the License at
847
+ *
848
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
849
+ *
850
+ * Unless required by applicable law or agreed to in writing, software
851
+ * distributed under the License is distributed on an "AS IS" basis,
852
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
853
+ * See the License for the specific language governing permissions and
854
+ * limitations under the License.
855
+ */
856
+
857
+ /*
858
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
859
+ *
860
+ * Licensed under EUPL, Version 1.2 (the "License");
861
+ * you may not use this file except in compliance with the License.
862
+ * You may obtain a copy of the License at
863
+ *
864
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
865
+ *
866
+ * Unless required by applicable law or agreed to in writing, software
867
+ * distributed under the License is distributed on an "AS IS" basis,
868
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
869
+ * See the License for the specific language governing permissions and
870
+ * limitations under the License.
871
+ */
872
+ class TaskDetailContentComponent {
873
+ set task(value) {
874
+ if (!value)
875
+ return;
876
+ if (this.taskInstanceId$.getValue() === value.id) {
877
+ this.task$.next(value);
878
+ return;
879
+ }
880
+ this.loadTaskDetails(value);
881
+ }
882
+ set taskAndProcessLink(value) {
883
+ if (!value)
884
+ return;
885
+ const task = enrichTaskFromProcessLink(value.task, value.processLinkActivityResult);
886
+ this.loadTaskDetails(task, value.processLinkActivityResult);
887
+ }
888
+ set modalClosed(closed) {
889
+ // save form flow data on modal closed
890
+ if (this.formFlow)
891
+ this.formFlow.saveData();
892
+ this.taskInstanceId$.next(null);
893
+ if (closed) {
894
+ this.closeModalEvent.emit();
895
+ }
896
+ }
897
+ get viewInitialized$() {
898
+ return this._viewInitialized$.pipe(filter(initialized => initialized));
899
+ }
900
+ constructor(configService, documentService, globalNotificationService, iconService, logger, modalService, permissionService, processLinkService, router, stateService, taskIntermediateSaveService, taskService, translateService, formViewModel, formCustomComponentConfig, urlResolverService) {
901
+ this.configService = configService;
902
+ this.documentService = documentService;
903
+ this.globalNotificationService = globalNotificationService;
904
+ this.iconService = iconService;
905
+ this.logger = logger;
906
+ this.modalService = modalService;
907
+ this.permissionService = permissionService;
908
+ this.processLinkService = processLinkService;
909
+ this.router = router;
910
+ this.stateService = stateService;
911
+ this.taskIntermediateSaveService = taskIntermediateSaveService;
912
+ this.taskService = taskService;
913
+ this.translateService = translateService;
914
+ this.formViewModel = formViewModel;
915
+ this.formCustomComponentConfig = formCustomComponentConfig;
916
+ this.urlResolverService = urlResolverService;
917
+ this.closeModalEvent = new EventEmitter();
918
+ this.formSubmit = new EventEmitter();
919
+ this.activeChange = new EventEmitter();
920
+ this.taskUpdated = new EventEmitter();
921
+ this.canAssignUserToTask$ = new BehaviorSubject(false);
922
+ this.errorMessage$ = new BehaviorSubject(null);
923
+ this.formDefinition$ = new BehaviorSubject(null);
924
+ this.formDefinitionId$ = new BehaviorSubject(null);
925
+ this.formFlowInstanceId$ = new BehaviorSubject(null);
926
+ this.formioOptions$ = new BehaviorSubject(null);
927
+ this.formIoFormData$ = new BehaviorSubject(null);
928
+ this.formName$ = new BehaviorSubject(null);
929
+ this.loading$ = new BehaviorSubject(true);
930
+ this.submission$ = new BehaviorSubject(null);
931
+ this.task$ = new BehaviorSubject(null);
932
+ this.taskInstanceId$ = new BehaviorSubject(null);
933
+ this.intermediateSaveEnabled = false;
934
+ this._taskProcessLinkType$ = new BehaviorSubject(null);
935
+ this.processLinkIsForm$ = this._taskProcessLinkType$.pipe(map$1((type) => type === 'form'));
936
+ this.processLinkIsFormViewModel$ = this._taskProcessLinkType$.pipe(map$1((type) => type === 'form-view-model'));
937
+ this.processLinkIsFormFlow$ = this._taskProcessLinkType$.pipe(map$1((type) => type === 'form-flow'));
938
+ this.processLinkIsUiComponent$ = this._taskProcessLinkType$.pipe(map$1((type) => type === 'ui-component'));
939
+ this.noFormNotification$ = combineLatest([
940
+ this.loading$,
941
+ this.formDefinition$,
942
+ this.formFlowInstanceId$,
943
+ this.errorMessage$,
944
+ this.processLinkIsUiComponent$,
945
+ this.processLinkIsFormViewModel$,
946
+ ]).pipe(map$1(([loading, formDefinition, formFlowInstanceId, errorMessage, isUiComponent, isFormViewModel,]) => {
947
+ if (!loading &&
948
+ !formDefinition &&
949
+ !formFlowInstanceId &&
950
+ !errorMessage &&
951
+ !isUiComponent &&
952
+ !isFormViewModel) {
953
+ return {
954
+ type: 'warning',
955
+ title: this.translateService.instant('interface.warning'),
956
+ message: this.translateService.instant('formManagement.noFormDefinitionFoundUser'),
957
+ showClose: false,
958
+ lowContrast: true,
959
+ };
960
+ }
961
+ return null;
962
+ }));
963
+ this._processLinkId$ = new BehaviorSubject(null);
964
+ this._subscriptions = new Subscription();
965
+ this._formCustomComponentConfig$ = new BehaviorSubject({});
966
+ this._viewInitialized$ = new BehaviorSubject(false);
967
+ this.intermediateSaveEnabled = !!this.configService.featureToggles?.enableIntermediateSave;
968
+ this.iconService.registerAll([RecentlyViewed16]);
969
+ const options = new FormioOptionsImpl();
970
+ options.disableAlerts = true;
971
+ this.formioOptions$.next(options);
972
+ this._formCustomComponentConfig$.next(formCustomComponentConfig);
973
+ }
974
+ ngOnInit() {
975
+ this.openPermissionSubscription();
976
+ }
977
+ ngOnDestroy() {
978
+ this._subscriptions.unsubscribe();
979
+ this.submission$.next(null);
980
+ this._viewInitialized$.next(false);
981
+ }
982
+ ngAfterViewInit() {
983
+ this._viewInitialized$.next(true);
984
+ }
985
+ onSubmit(submission) {
986
+ if (submission.data) {
987
+ this.taskIntermediateSaveService.setFormIoFormData(submission.data);
988
+ this.formIoFormData$.next(submission.data);
989
+ }
990
+ combineLatest([this._processLinkId$, this._taskProcessLinkType$, this.task$])
991
+ .pipe(take$1(1))
992
+ .subscribe(([processLinkId, taskProcessLinkType, task]) => {
993
+ if (taskProcessLinkType === 'form') {
994
+ if (processLinkId) {
995
+ this.processLinkService
996
+ .submitForm(processLinkId, submission.data, task?.businessKey, task?.id)
997
+ .subscribe({
998
+ next: (_) => {
999
+ this.completeTask(task);
1000
+ },
1001
+ error: errors => {
1002
+ this.form.showErrors(errors);
1003
+ },
1004
+ });
1005
+ }
1006
+ }
1007
+ else if (taskProcessLinkType === 'form-view-model') {
1008
+ this.completeTask(task);
1009
+ }
1010
+ });
1011
+ }
1012
+ completeTask(task) {
1013
+ if (!task)
1014
+ return;
1015
+ this.globalNotificationService.showToast({
1016
+ title: `${task.name} ${this.translateService.instant('taskDetail.taskCompleted')}`,
1017
+ type: 'success',
1018
+ });
1019
+ this.task$.next(null);
1020
+ this.formSubmit.emit();
1021
+ this.closeModalEvent.emit();
1022
+ this.activeChange.emit(false);
1023
+ if (this.formFlow)
1024
+ this.formFlow.saveData();
1025
+ }
1026
+ onChange(event) {
1027
+ if (event.data) {
1028
+ this.taskIntermediateSaveService.setFormIoFormData(event.data);
1029
+ this.formIoFormData$.next(event.data);
1030
+ this.activeChange.emit(true);
1031
+ }
1032
+ }
1033
+ onFormFlowChangeEvent() {
1034
+ this.activeChange.emit(true);
1035
+ }
1036
+ loadTaskDetails(task, processLink) {
1037
+ this.resetTaskProcessLinkType();
1038
+ this.resetFormDefinition();
1039
+ this.taskInstanceId$.next(task.id);
1040
+ if (!processLink) {
1041
+ this.getTaskProcessLink(task.id);
1042
+ }
1043
+ else {
1044
+ this.setTaskProcessLink(processLink);
1045
+ }
1046
+ this.setDocumentDefinitionNameInService(task);
1047
+ const documentId = task.businessKey;
1048
+ this.stateService.setDocumentId(documentId);
1049
+ this.task$.next(task);
1050
+ this.stateService.setProcessInstanceId(task.processInstanceId);
1051
+ }
1052
+ getCurrentProgress(formViewModelComponentRef) {
1053
+ this.taskInstanceId$
1054
+ .pipe(filter(value => !!value), take$1(1), switchMap((taskInstanceId) => this.taskIntermediateSaveService.getIntermediateSubmission(taskInstanceId ?? '')))
1055
+ .subscribe({
1056
+ next: (intermediateSubmission) => {
1057
+ this.taskIntermediateSaveService.setSubmission({
1058
+ data: intermediateSubmission?.submission || {},
1059
+ });
1060
+ if (formViewModelComponentRef) {
1061
+ formViewModelComponentRef.instance.submission = {
1062
+ data: intermediateSubmission.submission,
1063
+ };
1064
+ }
1065
+ },
1066
+ });
1067
+ }
1068
+ getTaskProcessLink(taskId) {
1069
+ this.taskService.getTaskProcessLink(taskId).subscribe({
1070
+ next: res => {
1071
+ this.updateTaskFromProcessLink(res);
1072
+ this.setTaskProcessLink(res);
1073
+ },
1074
+ error: _ => {
1075
+ this.loading$.next(false);
1076
+ },
1077
+ });
1078
+ }
1079
+ updateTaskFromProcessLink(processLinkResult) {
1080
+ const currentTask = this.task$.getValue();
1081
+ if (!currentTask)
1082
+ return;
1083
+ const enrichedTask = enrichTaskFromProcessLink(currentTask, processLinkResult);
1084
+ if (enrichedTask !== currentTask) {
1085
+ this.task$.next(enrichedTask);
1086
+ this.taskUpdated.emit(enrichedTask);
1087
+ }
1088
+ }
1089
+ setTaskProcessLink(processLinkResult) {
1090
+ if (processLinkResult !== null) {
1091
+ switch (processLinkResult?.type) {
1092
+ case 'form':
1093
+ this._taskProcessLinkType$.next('form');
1094
+ this._processLinkId$.next(processLinkResult.processLinkId);
1095
+ // initializeFormWithSubmission will set loading to false after form is ready
1096
+ this.initializeFormWithSubmission(processLinkResult.properties.prefilledForm);
1097
+ break;
1098
+ case 'form-flow':
1099
+ this._taskProcessLinkType$.next('form-flow');
1100
+ this.formFlowInstanceId$.next(processLinkResult.properties.formFlowInstanceId ?? '');
1101
+ this.loading$.next(false);
1102
+ break;
1103
+ case 'form-view-model':
1104
+ this._taskProcessLinkType$.next('form-view-model');
1105
+ this._processLinkId$.next(processLinkResult.processLinkId);
1106
+ this.formDefinition$.next(processLinkResult.properties.formDefinition);
1107
+ this.formName$.next(processLinkResult.properties.formName ?? '');
1108
+ this.setFormViewModelComponent();
1109
+ this.loading$.next(false);
1110
+ break;
1111
+ case 'url':
1112
+ this._taskProcessLinkType$.next('url');
1113
+ this._processLinkId$.next(processLinkResult.processLinkId);
1114
+ combineLatest([this.processLinkService.getVariables(), this.task$])
1115
+ .pipe(take$1(1))
1116
+ .subscribe(([variables, task]) => {
1117
+ let url = this.urlResolverService.resolveUrlVariables(processLinkResult.properties.url, variables.variables);
1118
+ window.open(url, '_blank').focus();
1119
+ this.processLinkService
1120
+ .submitURLProcessLink(processLinkResult.processLinkId, task.businessKey, task.id)
1121
+ .subscribe(() => {
1122
+ this.completeTask(task);
1123
+ });
1124
+ });
1125
+ this.loading$.next(false);
1126
+ break;
1127
+ case 'ui-component':
1128
+ this._taskProcessLinkType$.next('ui-component');
1129
+ this._processLinkId$.next(processLinkResult.processLinkId);
1130
+ this.formDefinition$.next(null);
1131
+ this.formName$.next('');
1132
+ this.setFormCustomComponent(processLinkResult.properties.componentKey);
1133
+ this.loading$.next(false);
1134
+ break;
1135
+ }
1136
+ }
1137
+ }
1138
+ openPermissionSubscription() {
1139
+ this._subscriptions.add(this.task$.subscribe(task => {
1140
+ if (task) {
1141
+ this.logger.debug('Checking if user allowed to assign a user to Task with id:', task.id);
1142
+ this.permissionService
1143
+ .requestPermission(CAN_ASSIGN_TASK_PERMISSION, {
1144
+ resource: TASK_DETAIL_PERMISSION_RESOURCE.task,
1145
+ identifier: task.id,
1146
+ })
1147
+ .subscribe((allowed) => {
1148
+ this.canAssignUserToTask$.next(allowed);
1149
+ });
1150
+ }
1151
+ else {
1152
+ this.logger.debug('Reset is user allowed to assign a user to Task as task is null');
1153
+ this.canAssignUserToTask$.next(false);
1154
+ }
1155
+ }));
1156
+ }
1157
+ setFormDefinition(formDefinition) {
1158
+ this._taskProcessLinkType$.next('form');
1159
+ this.formDefinition$.next(formDefinition);
1160
+ }
1161
+ initializeFormWithSubmission(formDefinition) {
1162
+ if (this.intermediateSaveEnabled) {
1163
+ // Wait for intermediate submission before rendering the form
1164
+ this.taskInstanceId$
1165
+ .pipe(filter(value => !!value), take$1(1), switchMap((taskInstanceId) => this.taskIntermediateSaveService.getIntermediateSubmission(taskInstanceId ?? '')))
1166
+ .subscribe({
1167
+ next: (intermediateSubmission) => {
1168
+ // Set submission first, then form definition, then mark as loaded
1169
+ this.submission$.next({
1170
+ data: intermediateSubmission?.submission || {},
1171
+ });
1172
+ this.setFormDefinition(formDefinition);
1173
+ this.loading$.next(false);
1174
+ },
1175
+ error: () => {
1176
+ // If fetching fails, still render form with empty submission
1177
+ this.submission$.next({ data: {} });
1178
+ this.setFormDefinition(formDefinition);
1179
+ this.loading$.next(false);
1180
+ },
1181
+ });
1182
+ }
1183
+ else {
1184
+ // No intermediate save, render form immediately with empty submission
1185
+ this.submission$.next({ data: {} });
1186
+ this.setFormDefinition(formDefinition);
1187
+ this.loading$.next(false);
1188
+ }
1189
+ }
1190
+ setFormViewModelComponent() {
1191
+ combineLatest([this._viewInitialized$, this.processLinkIsFormViewModel$]).subscribe(([viewInitialized, isFvm]) => {
1192
+ if (viewInitialized && isFvm) {
1193
+ this.formViewModelDynamicContainer.clear();
1194
+ if (!this.formViewModel) {
1195
+ return;
1196
+ }
1197
+ const formViewModelComponent = this.formViewModelDynamicContainer.createComponent(this.formViewModel.component);
1198
+ formViewModelComponent.instance.form = this.formDefinition$.getValue();
1199
+ formViewModelComponent.instance.formName = this.formName$.getValue();
1200
+ formViewModelComponent.instance.taskInstanceId = this.taskInstanceId$.getValue();
1201
+ formViewModelComponent.instance.isStartForm = false;
1202
+ formViewModelComponent.instance.formSubmit
1203
+ .pipe(switchMap(() => this.task$), take$1(1))
1204
+ .subscribe((task) => {
1205
+ this.completeTask(task);
1206
+ });
1207
+ if (this.intermediateSaveEnabled) {
1208
+ this._subscriptions.add(formViewModelComponent.instance.submission$.subscribe(submission => {
1209
+ this.taskIntermediateSaveService.setSubmission(submission);
1210
+ }));
1211
+ this._subscriptions.add(this.submission$.pipe(distinctUntilChanged()).subscribe((submission) => {
1212
+ if (submission?.data && Object.keys(submission.data).length === 0) {
1213
+ formViewModelComponent.instance.submission = { data: {} };
1214
+ }
1215
+ }));
1216
+ this.getCurrentProgress(formViewModelComponent);
1217
+ }
1218
+ this._subscriptions.add(this.closeModalEvent.subscribe(() => {
1219
+ formViewModelComponent.destroy();
1220
+ }));
1221
+ }
1222
+ });
1223
+ }
1224
+ setFormCustomComponent(formCustomComponentKey) {
1225
+ combineLatest([this._viewInitialized$, this.processLinkIsUiComponent$]).subscribe(([viewInitialized, isUiComponent]) => {
1226
+ if (viewInitialized && isUiComponent) {
1227
+ this.formCustomComponentDynamicContainer.clear();
1228
+ if (!this.formCustomComponentConfig) {
1229
+ return;
1230
+ }
1231
+ let renderedComponent;
1232
+ this._subscriptions.add(this._formCustomComponentConfig$.subscribe((formCustomComponentConfig) => {
1233
+ const customComponent = formCustomComponentConfig[formCustomComponentKey];
1234
+ renderedComponent = this.formCustomComponentDynamicContainer.createComponent(customComponent);
1235
+ renderedComponent.instance.taskInstanceId = this.taskInstanceId$.value;
1236
+ renderedComponent.instance.submittedEvent.subscribe(() => {
1237
+ this.closeModalEvent.emit();
1238
+ });
1239
+ }));
1240
+ this._subscriptions.add(this.closeModalEvent.subscribe(() => {
1241
+ renderedComponent.destroy();
1242
+ }));
1243
+ }
1244
+ });
1245
+ }
1246
+ resetFormDefinition() {
1247
+ this.formDefinition$.next(null);
1248
+ this.submission$.next(null);
1249
+ this.loading$.next(true);
1250
+ }
1251
+ resetTaskProcessLinkType() {
1252
+ this._taskProcessLinkType$.next(null);
1253
+ this._processLinkId$.next(null);
1254
+ }
1255
+ setDocumentDefinitionNameInService(task) {
1256
+ this.documentService
1257
+ .getProcessDefinitionCaseDefinitionFromProcessInstanceId(task.processInstanceId)
1258
+ .subscribe(ProcessDefinitionCaseDefinition => {
1259
+ const caseDefinitionKey = ProcessDefinitionCaseDefinition.id.caseDefinitionId.key;
1260
+ this.modalService.setCaseDefinitionKey(caseDefinitionKey);
1261
+ this.stateService.setCaseDefinitionKey(caseDefinitionKey);
1262
+ });
1263
+ }
1264
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskDetailContentComponent, deps: [{ token: i1$1.ConfigService }, { token: i2.DocumentService }, { token: i1$1.GlobalNotificationService }, { token: i2$1.IconService }, { token: i4.NGXLogger }, { token: i9.ValtimoModalService }, { token: i3.PermissionService }, { token: i7.ProcessLinkService }, { token: i1$2.Router }, { token: i9.FormIoStateService }, { token: TaskIntermediateSaveService }, { token: TaskService }, { token: i4$1.TranslateService }, { token: FORM_VIEW_MODEL_TOKEN, optional: true }, { token: FORM_CUSTOM_COMPONENT_TOKEN, optional: true }, { token: i7.UrlResolverService }], target: i0.ɵɵFactoryTarget.Component }); }
1265
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: TaskDetailContentComponent, isStandalone: true, selector: "valtimo-task-detail-content", inputs: { task: "task", taskAndProcessLink: "taskAndProcessLink", modalClosed: "modalClosed" }, outputs: { closeModalEvent: "closeModalEvent", formSubmit: "formSubmit", activeChange: "activeChange", taskUpdated: "taskUpdated" }, viewQueries: [{ propertyName: "form", first: true, predicate: ["form"], descendants: true }, { propertyName: "formViewModelDynamicContainer", first: true, predicate: ["formViewModelComponent"], descendants: true, read: ViewContainerRef }, { propertyName: "formFlow", first: true, predicate: ["formFlow"], descendants: true }, { propertyName: "formCustomComponentDynamicContainer", first: true, predicate: ["formCustomComponent"], descendants: true, read: ViewContainerRef }], 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<ng-container\n *ngIf=\"{\n loading: loading$ | async,\n task: task$ | async,\n taskId: taskInstanceId$ | async,\n formDefinition: formDefinition$ | async,\n formDefinitionId: formDefinitionId$ | async,\n formName: formName$ | async,\n formIoFormData: formIoFormData$ | async,\n submission: submission$ | async,\n processLinkIsForm: processLinkIsForm$ | async,\n processLinkIsFormViewModel: processLinkIsFormViewModel$ | async,\n processLinkIsUiComponent: processLinkIsUiComponent$ | async,\n formioOptions: formioOptions$ | async,\n processLinkIsFormFlow: processLinkIsFormFlow$ | async,\n formFlowInstanceId: formFlowInstanceId$ | async,\n errorMessage: errorMessage$ | async,\n canAssignUserToTask: canAssignUserToTask$ | async,\n noFormNotification: noFormNotification$ | async,\n } as obs\"\n>\n @if (obs.loading) {\n <div style=\"width: 100%; display: flex; justify-content: center; padding: 1rem\">\n <cds-loading size=\"sm\"></cds-loading>\n </div>\n } @else {\n <valtimo-form-io\n #form\n *ngIf=\"\n obs.formDefinition &&\n obs.submission &&\n obs.processLinkIsForm &&\n !obs.processLinkIsUiComponent &&\n !obs.processLinkIsFormViewModel\n \"\n [form]=\"obs.formDefinition\"\n [submission]=\"obs.submission\"\n (submit)=\"onSubmit($event)\"\n (change)=\"onChange($event)\"\n [options]=\"obs.formioOptions\"\n ></valtimo-form-io>\n\n <valtimo-form-flow\n #formFlow\n *ngIf=\"obs.processLinkIsFormFlow\"\n [formIoFormData]=\"formIoFormData$\"\n [formFlowInstanceId]=\"obs.formFlowInstanceId\"\n (formFlowComplete)=\"completeTask(obs.task)\"\n (formFlowChange)=\"onFormFlowChangeEvent()\"\n ></valtimo-form-flow>\n\n @if (obs.noFormNotification) {\n <cds-inline-notification [notificationObj]=\"obs.noFormNotification\"></cds-inline-notification>\n }\n\n @if (obs.errorMessage) {\n <cds-inline-notification\n [notificationObj]=\"{\n type: 'error',\n title: ('interface.error' | translate),\n message: obs.errorMessage,\n showClose: false,\n lowContrast: true\n }\"\n ></cds-inline-notification>\n }\n }\n\n <div class=\"m-2\">\n <ng-template #formViewModelComponent></ng-template>\n <ng-template #formCustomComponent></ng-template>\n </div>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormIoModule }, { kind: "component", type: i9.FormioComponent, selector: "valtimo-form-io", inputs: ["options", "submission", "form", "readOnly", "formRefresh$"], outputs: ["submit", "change", "event"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i4$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ProcessLinkModule }, { kind: "component", type: i7.FormFlowComponent, selector: "valtimo-form-flow", inputs: ["formIoFormData", "formFlowInstanceId"], outputs: ["formFlowComplete", "formFlowChange"] }, { kind: "ngmodule", type: LoadingModule }, { kind: "component", type: i2$1.Loading, selector: "cds-loading, ibm-loading", inputs: ["title", "isActive", "size", "overlay"] }, { kind: "ngmodule", type: NotificationModule }, { kind: "component", type: i2$1.Notification, selector: "cds-notification, cds-inline-notification, ibm-notification, ibm-inline-notification", inputs: ["notificationObj"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1266
+ }
1267
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskDetailContentComponent, decorators: [{
1268
+ type: Component,
1269
+ args: [{ selector: 'valtimo-task-detail-content', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1270
+ CommonModule,
1271
+ FormIoModule,
1272
+ TranslateModule,
1273
+ ProcessLinkModule,
1274
+ LoadingModule,
1275
+ NotificationModule,
1276
+ ], 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<ng-container\n *ngIf=\"{\n loading: loading$ | async,\n task: task$ | async,\n taskId: taskInstanceId$ | async,\n formDefinition: formDefinition$ | async,\n formDefinitionId: formDefinitionId$ | async,\n formName: formName$ | async,\n formIoFormData: formIoFormData$ | async,\n submission: submission$ | async,\n processLinkIsForm: processLinkIsForm$ | async,\n processLinkIsFormViewModel: processLinkIsFormViewModel$ | async,\n processLinkIsUiComponent: processLinkIsUiComponent$ | async,\n formioOptions: formioOptions$ | async,\n processLinkIsFormFlow: processLinkIsFormFlow$ | async,\n formFlowInstanceId: formFlowInstanceId$ | async,\n errorMessage: errorMessage$ | async,\n canAssignUserToTask: canAssignUserToTask$ | async,\n noFormNotification: noFormNotification$ | async,\n } as obs\"\n>\n @if (obs.loading) {\n <div style=\"width: 100%; display: flex; justify-content: center; padding: 1rem\">\n <cds-loading size=\"sm\"></cds-loading>\n </div>\n } @else {\n <valtimo-form-io\n #form\n *ngIf=\"\n obs.formDefinition &&\n obs.submission &&\n obs.processLinkIsForm &&\n !obs.processLinkIsUiComponent &&\n !obs.processLinkIsFormViewModel\n \"\n [form]=\"obs.formDefinition\"\n [submission]=\"obs.submission\"\n (submit)=\"onSubmit($event)\"\n (change)=\"onChange($event)\"\n [options]=\"obs.formioOptions\"\n ></valtimo-form-io>\n\n <valtimo-form-flow\n #formFlow\n *ngIf=\"obs.processLinkIsFormFlow\"\n [formIoFormData]=\"formIoFormData$\"\n [formFlowInstanceId]=\"obs.formFlowInstanceId\"\n (formFlowComplete)=\"completeTask(obs.task)\"\n (formFlowChange)=\"onFormFlowChangeEvent()\"\n ></valtimo-form-flow>\n\n @if (obs.noFormNotification) {\n <cds-inline-notification [notificationObj]=\"obs.noFormNotification\"></cds-inline-notification>\n }\n\n @if (obs.errorMessage) {\n <cds-inline-notification\n [notificationObj]=\"{\n type: 'error',\n title: ('interface.error' | translate),\n message: obs.errorMessage,\n showClose: false,\n lowContrast: true\n }\"\n ></cds-inline-notification>\n }\n }\n\n <div class=\"m-2\">\n <ng-template #formViewModelComponent></ng-template>\n <ng-template #formCustomComponent></ng-template>\n </div>\n</ng-container>\n" }]
1277
+ }], ctorParameters: () => [{ type: i1$1.ConfigService }, { type: i2.DocumentService }, { type: i1$1.GlobalNotificationService }, { type: i2$1.IconService }, { type: i4.NGXLogger }, { type: i9.ValtimoModalService }, { type: i3.PermissionService }, { type: i7.ProcessLinkService }, { type: i1$2.Router }, { type: i9.FormIoStateService }, { type: TaskIntermediateSaveService }, { type: TaskService }, { type: i4$1.TranslateService }, { type: undefined, decorators: [{
1278
+ type: Optional
1279
+ }, {
1280
+ type: Inject,
1281
+ args: [FORM_VIEW_MODEL_TOKEN]
1282
+ }] }, { type: undefined, decorators: [{
1283
+ type: Optional
1284
+ }, {
1285
+ type: Inject,
1286
+ args: [FORM_CUSTOM_COMPONENT_TOKEN]
1287
+ }] }, { type: i7.UrlResolverService }], propDecorators: { form: [{
1288
+ type: ViewChild,
1289
+ args: ['form']
1290
+ }], formViewModelDynamicContainer: [{
1291
+ type: ViewChild,
1292
+ args: ['formViewModelComponent', { static: false, read: ViewContainerRef }]
1293
+ }], formFlow: [{
1294
+ type: ViewChild,
1295
+ args: ['formFlow']
1296
+ }], formCustomComponentDynamicContainer: [{
1297
+ type: ViewChild,
1298
+ args: ['formCustomComponent', { static: false, read: ViewContainerRef }]
1299
+ }], task: [{
1300
+ type: Input
1301
+ }], taskAndProcessLink: [{
1302
+ type: Input
1303
+ }], modalClosed: [{
1304
+ type: Input
1305
+ }], closeModalEvent: [{
1306
+ type: Output
1307
+ }], formSubmit: [{
1308
+ type: Output
1309
+ }], activeChange: [{
1310
+ type: Output
1311
+ }], taskUpdated: [{
1312
+ type: Output
1313
+ }] } });
1314
+
1315
+ /*
1316
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
1317
+ *
1318
+ * Licensed under EUPL, Version 1.2 (the "License");
1319
+ * you may not use this file except in compliance with the License.
1320
+ * You may obtain a copy of the License at
1321
+ *
1322
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
1323
+ *
1324
+ * Unless required by applicable law or agreed to in writing, software
1325
+ * distributed under the License is distributed on an "AS IS" basis,
1326
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327
+ * See the License for the specific language governing permissions and
1328
+ * limitations under the License.
1329
+ */
1330
+ class TaskDetailIntermediateSaveComponent {
1331
+ set task(value) {
1332
+ if (!value)
1333
+ return;
1334
+ this.taskService
1335
+ .getTaskProcessLink(value.id)
1336
+ .pipe(take$1(1))
1337
+ .subscribe(res => {
1338
+ this.setFormFlow(res);
1339
+ });
1340
+ this.taskValue.set(value);
1341
+ this.page.set({
1342
+ title: value.name,
1343
+ subtitle: `${this.translateService.instant('taskDetail.taskCreated')} ${value.created}`,
1344
+ });
1345
+ this.getCurrentProgress(value);
1346
+ }
1347
+ set taskAndProcessLink(value) {
1348
+ if (!value)
1349
+ return;
1350
+ this.setFormFlow(value.processLinkActivityResult);
1351
+ this.taskValue.set(value.task);
1352
+ this.page.set({
1353
+ title: value?.task.name,
1354
+ subtitle: `${this.translateService.instant('taskDetail.taskCreated')} ${value?.task.created}`,
1355
+ });
1356
+ this.getCurrentProgress(value.task);
1357
+ }
1358
+ constructor(configService, globalNotificationService, iconService, taskIntermediateSaveService, taskService, translateService) {
1359
+ this.configService = configService;
1360
+ this.globalNotificationService = globalNotificationService;
1361
+ this.iconService = iconService;
1362
+ this.taskIntermediateSaveService = taskIntermediateSaveService;
1363
+ this.taskService = taskService;
1364
+ this.translateService = translateService;
1365
+ this.currentIntermediateSaveEvent = new EventEmitter();
1366
+ this.showModalEvent = new EventEmitter();
1367
+ this.formFlowInstanceId$ = new BehaviorSubject(undefined);
1368
+ this.showConfirmationModal$ = new BehaviorSubject(false);
1369
+ this.taskValue = signal(null);
1370
+ this.page = signal(null);
1371
+ this.canAssignUserToTask = signal(false);
1372
+ this.submission$ = this.taskIntermediateSaveService.submission$;
1373
+ this.formIoFormData$ = this.taskIntermediateSaveService.formIoFormData$;
1374
+ this.intermediateSaveEnabled = false;
1375
+ this.currentIntermediateSave = null;
1376
+ this.intermediateSaveEnabled = !!this.configService.featureToggles?.enableIntermediateSave;
1377
+ this.iconService.registerAll([RecentlyViewed16]);
1378
+ }
1379
+ saveCurrentProgress() {
1380
+ combineLatest([this.submission$, this.formIoFormData$])
1381
+ .pipe(take$1(1), switchMap(([submission, formIoFormData]) => {
1382
+ const dataToSave = submission?.data ? submission.data : formIoFormData;
1383
+ const intermediateSaveRequest = {
1384
+ submission: dataToSave,
1385
+ taskInstanceId: this.taskValue()?.id ?? '',
1386
+ };
1387
+ return this.taskIntermediateSaveService
1388
+ .storeIntermediateSubmission(intermediateSaveRequest)
1389
+ .pipe(tap(() => {
1390
+ // Update in-memory submission so form retains data on re-render
1391
+ this.taskIntermediateSaveService.setSubmission({ data: dataToSave });
1392
+ }));
1393
+ }))
1394
+ .subscribe({
1395
+ next: intermediateSubmission => {
1396
+ this.globalNotificationService.showToast({
1397
+ title: this.translateService.instant('formManagement.intermediateSave.success'),
1398
+ type: 'success',
1399
+ });
1400
+ this.currentIntermediateSave = this.formatIntermediateSubmission(intermediateSubmission);
1401
+ this.currentIntermediateSaveEvent.emit(this.currentIntermediateSave);
1402
+ },
1403
+ error: () => {
1404
+ this.globalNotificationService.showToast({
1405
+ title: this.translateService.instant('formManagement.intermediateSave.error'),
1406
+ type: 'error',
1407
+ });
1408
+ },
1409
+ });
1410
+ }
1411
+ revertSaveClick() {
1412
+ if (this.showModalEvent.observed) {
1413
+ this.showModalEvent.emit();
1414
+ return;
1415
+ }
1416
+ this.showConfirmationModal$.next(true);
1417
+ }
1418
+ clearCurrentProgress() {
1419
+ this.taskIntermediateSaveService
1420
+ .clearIntermediateSubmission(this.taskValue()?.id ?? '')
1421
+ .pipe(take$1(1))
1422
+ .subscribe(() => {
1423
+ this.taskIntermediateSaveService.setSubmission({});
1424
+ this.currentIntermediateSave = null;
1425
+ this.currentIntermediateSaveEvent.emit(this.currentIntermediateSave);
1426
+ });
1427
+ }
1428
+ setFormFlow(processLink) {
1429
+ if (processLink !== null && processLink.type === 'form-flow') {
1430
+ this.formFlowInstanceId$.next(processLink.properties.formFlowInstanceId);
1431
+ }
1432
+ }
1433
+ formatIntermediateSubmission(intermediateSubmission) {
1434
+ intermediateSubmission.createdOn = moment(intermediateSubmission.createdOn).format('DD MMM YYYY HH:mm');
1435
+ if (intermediateSubmission.editedOn) {
1436
+ intermediateSubmission.editedOn = moment(new Date(intermediateSubmission.editedOn)).format('DD MMM YYYY HH:mm');
1437
+ }
1438
+ return intermediateSubmission;
1439
+ }
1440
+ getCurrentProgress(task) {
1441
+ this.taskIntermediateSaveService
1442
+ .getIntermediateSubmission(task.id ?? '')
1443
+ .pipe(take$1(1))
1444
+ .subscribe(intermediateSave => {
1445
+ if (intermediateSave !== null) {
1446
+ this.currentIntermediateSave = this.formatIntermediateSubmission(intermediateSave);
1447
+ // Update in-memory submission with data from API
1448
+ this.taskIntermediateSaveService.setSubmission({ data: intermediateSave.submission });
1449
+ }
1450
+ else {
1451
+ this.currentIntermediateSave = null;
1452
+ this.taskIntermediateSaveService.setSubmission({});
1453
+ }
1454
+ this.currentIntermediateSaveEvent.emit(this.currentIntermediateSave);
1455
+ });
1456
+ }
1457
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskDetailIntermediateSaveComponent, deps: [{ token: i1$1.ConfigService }, { token: i1$1.GlobalNotificationService }, { token: i2$1.IconService }, { token: TaskIntermediateSaveService }, { token: TaskService }, { token: i4$1.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
1458
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: TaskDetailIntermediateSaveComponent, isStandalone: true, selector: "valtimo-task-detail-intermediate-save", inputs: { task: "task", taskAndProcessLink: "taskAndProcessLink" }, outputs: { currentIntermediateSaveEvent: "currentIntermediateSaveEvent", showModalEvent: "showModalEvent" }, 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@if (intermediateSaveEnabled && (formFlowInstanceId$ | async) === undefined) {\n <button\n cdsButton=\"ghost\"\n iconOnly=\"true\"\n cdsIcon=\"save\"\n [vTooltip]=\"'formManagement.intermediateSave.save' | translate\"\n (click)=\"saveCurrentProgress()\"\n ></button>\n\n <button\n cdsButton=\"ghost\"\n iconOnly=\"true\"\n cdsIcon=\"recently-viewed\"\n [disabled]=\"!currentIntermediateSave\"\n [vTooltip]=\"'formManagement.intermediateSave.clear' | translate\"\n (click)=\"revertSaveClick()\"\n ></button>\n}\n\n<valtimo-confirmation-modal\n [showModalSubject$]=\"showConfirmationModal$\"\n (confirmEvent)=\"clearCurrentProgress()\"\n (cancelEvent)=\"showConfirmationModal$.next(false)\"\n cancelButtonType=\"ghost\"\n confirmButtonTextTranslationKey=\"interface.confirm\"\n titleTranslationKey=\"formManagement.intermediateSave.clear\"\n contentTranslationKey=\"formManagement.intermediateSave.clearConfirm\"\n></valtimo-confirmation-modal>\n", styles: [":host{flex-shrink:0}\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: "ngmodule", type: CommonModule }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i4$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: ConfirmationModalModule }, { kind: "component", type: i9.ConfirmationModalComponent, selector: "valtimo-confirmation-modal", inputs: ["titleTranslationKey", "title", "content", "contentTranslationKey", "confirmButtonText", "confirmButtonTextTranslationKey", "confirmButtonType", "showOptionalButton", "optionalButtonText", "optionalButtonTextTranslationKey", "optionalButtonType", "cancelButtonText", "cancelButtonTextTranslationKey", "cancelButtonType", "showModalSubject$", "outputOnConfirm", "outputOnOptional", "spacerAfterCancelButton"], outputs: ["confirmEvent", "optionalEvent", "cancelEvent"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i2$1.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "ngmodule", type: ModalModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i9.TooltipDirective, selector: "[vTooltip]", inputs: ["vTooltip", "onBottom", "tooltipDisabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1459
+ }
1460
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskDetailIntermediateSaveComponent, decorators: [{
1461
+ type: Component,
1462
+ args: [{ selector: 'valtimo-task-detail-intermediate-save', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
1463
+ CommonModule,
1464
+ TranslateModule,
1465
+ ButtonModule,
1466
+ ConfirmationModalModule,
1467
+ IconModule,
1468
+ ModalModule,
1469
+ TooltipModule,
1470
+ ], 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@if (intermediateSaveEnabled && (formFlowInstanceId$ | async) === undefined) {\n <button\n cdsButton=\"ghost\"\n iconOnly=\"true\"\n cdsIcon=\"save\"\n [vTooltip]=\"'formManagement.intermediateSave.save' | translate\"\n (click)=\"saveCurrentProgress()\"\n ></button>\n\n <button\n cdsButton=\"ghost\"\n iconOnly=\"true\"\n cdsIcon=\"recently-viewed\"\n [disabled]=\"!currentIntermediateSave\"\n [vTooltip]=\"'formManagement.intermediateSave.clear' | translate\"\n (click)=\"revertSaveClick()\"\n ></button>\n}\n\n<valtimo-confirmation-modal\n [showModalSubject$]=\"showConfirmationModal$\"\n (confirmEvent)=\"clearCurrentProgress()\"\n (cancelEvent)=\"showConfirmationModal$.next(false)\"\n cancelButtonType=\"ghost\"\n confirmButtonTextTranslationKey=\"interface.confirm\"\n titleTranslationKey=\"formManagement.intermediateSave.clear\"\n contentTranslationKey=\"formManagement.intermediateSave.clearConfirm\"\n></valtimo-confirmation-modal>\n", styles: [":host{flex-shrink:0}\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"] }]
1471
+ }], ctorParameters: () => [{ type: i1$1.ConfigService }, { type: i1$1.GlobalNotificationService }, { type: i2$1.IconService }, { type: TaskIntermediateSaveService }, { type: TaskService }, { type: i4$1.TranslateService }], propDecorators: { task: [{
1472
+ type: Input
1473
+ }], taskAndProcessLink: [{
1474
+ type: Input
1475
+ }], currentIntermediateSaveEvent: [{
1476
+ type: Output
1477
+ }], showModalEvent: [{
1478
+ type: Output
1479
+ }] } });
1480
+
1481
+ /*
1482
+ * Copyright 2015-2026 Ritense BV, the Netherlands.
1483
+ *
1484
+ * Licensed under EUPL, Version 1.2 (the "License");
1485
+ * you may not use this file except in compliance with the License.
1486
+ * You may obtain a copy of the License at
1487
+ *
1488
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
1489
+ *
1490
+ * Unless required by applicable law or agreed to in writing, software
1491
+ * distributed under the License is distributed on an "AS IS" basis,
1492
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1493
+ * See the License for the specific language governing permissions and
1494
+ * limitations under the License.
1495
+ */
1496
+ class SetTaskDueDateComponent {
1497
+ set canModifyTask(value) {
1498
+ this.canModifyTaskSet$.next(true);
1499
+ this.canModifyTask$.next(value);
1500
+ }
1501
+ get _task() {
1502
+ return this._task$.getValue();
1503
+ }
1504
+ get _selectedDateString() {
1505
+ return this.selectedDateString$.getValue();
1506
+ }
1507
+ set task(value) {
1508
+ if (!value) {
1509
+ this.hasDueDate$.next(false);
1510
+ this._task$.next(null);
1511
+ this.selectedDateString$.next('');
1512
+ return;
1513
+ }
1514
+ this.hasDueDate$.next(!!value.due);
1515
+ this._task$.next(value);
1516
+ }
1517
+ constructor(cdsThemeService, iconService, taskService, translateService, globalNotificationService) {
1518
+ this.cdsThemeService = cdsThemeService;
1519
+ this.iconService = iconService;
1520
+ this.taskService = taskService;
1521
+ this.translateService = translateService;
1522
+ this.globalNotificationService = globalNotificationService;
1523
+ this.dueDateChanged = new EventEmitter();
1524
+ this.canModifyTaskSet$ = new BehaviorSubject(false);
1525
+ this.canModifyTask$ = new BehaviorSubject(false);
1526
+ this._task$ = new BehaviorSubject(null);
1527
+ this.hasDueDate$ = new BehaviorSubject(false);
1528
+ this.selectedDateString$ = new BehaviorSubject('');
1529
+ this.taskDueDate$ = this._task$.pipe(filter$1(task => !!task), map(task => new Date(task.due)));
1530
+ this.showDatePicker$ = new BehaviorSubject(true);
1531
+ this.disabled$ = new BehaviorSubject(false);
1532
+ this.open$ = new Subject();
1533
+ this.editToggletipOpen$ = new BehaviorSubject(false);
1534
+ this.mouseIsOverDueDate$ = new BehaviorSubject(false);
1535
+ this.toggletipTheme$ = this.cdsThemeService.toggletipTheme$;
1536
+ this.toggletipDropdownTheme$ = this.cdsThemeService.toggletipDropdownTheme$;
1537
+ this.language$ = this.translateService.onLangChange.pipe(map(event => event.lang), startWith(this.translateService.currentLang), distinctUntilChanged$1());
1538
+ this.iconService.registerAll([CalendarAdd16, Edit16]);
1539
+ }
1540
+ clear() {
1541
+ this.selectedDateString$.next('');
1542
+ this.resetDatePicker();
1543
+ }
1544
+ initEditWithCurrentDate() {
1545
+ this.editToggletipOpen$.next(true);
1546
+ const task = this._task;
1547
+ if (task?.due) {
1548
+ this.selectedDateString$.next(new Date(task.due).toISOString());
1549
+ }
1550
+ else {
1551
+ this.selectedDateString$.next('');
1552
+ }
1553
+ this.resetDatePicker();
1554
+ }
1555
+ onCloseEditToggletip() {
1556
+ this.editToggletipOpen$.next(false);
1557
+ }
1558
+ onMouseEnterDueDate() {
1559
+ this.mouseIsOverDueDate$.next(true);
1560
+ }
1561
+ onMouseLeaveDueDate() {
1562
+ this.mouseIsOverDueDate$.next(false);
1563
+ }
1564
+ onDateValueChange(value) {
1565
+ const date = Array.isArray(value) && value[0];
1566
+ if (!date) {
1567
+ this.selectedDateString$.next('');
1568
+ return;
1569
+ }
1570
+ this.selectedDateString$.next(date.toISOString());
1571
+ }
1572
+ onSubmitButtonClick() {
1573
+ this.disabled$.next(true);
1574
+ const dateString = this._selectedDateString;
1575
+ this.taskService.setTaskDueDate(this._task.id, { dueDate: dateString }).subscribe({
1576
+ next: () => {
1577
+ this.disabled$.next(false);
1578
+ this.hasDueDate$.next(true);
1579
+ this._task$.next({ ...this._task, due: dateString });
1580
+ this.selectedDateString$.next('');
1581
+ this.closeToggletip();
1582
+ this.dueDateChanged.emit();
1583
+ this.showDueDateSetNotification(dateString);
1584
+ },
1585
+ error: () => {
1586
+ this.disabled$.next(false);
1587
+ },
1588
+ });
1589
+ }
1590
+ onRemoveButtonClick() {
1591
+ this.disabled$.next(true);
1592
+ this.taskService.removeTaskDueDate(this._task.id).subscribe({
1593
+ next: () => {
1594
+ this.disabled$.next(false);
1595
+ this.hasDueDate$.next(false);
1596
+ this._task$.next({ ...this._task, due: null });
1597
+ this.closeToggletip();
1598
+ this.dueDateChanged.emit();
1599
+ this.showDueDateRemovedNotification();
1600
+ },
1601
+ error: () => {
1602
+ this.disabled$.next(false);
1603
+ },
1604
+ });
1605
+ }
1606
+ resetDatePicker() {
1607
+ this.showDatePicker$.next(false);
1608
+ setTimeout(() => this.showDatePicker$.next(true));
1609
+ }
1610
+ closeToggletip() {
1611
+ this.editToggletipOpen$.next(false);
1612
+ this.open$.next(true);
1613
+ setTimeout(() => this.open$.next(false));
1614
+ }
1615
+ showDueDateSetNotification(dateString) {
1616
+ const formattedDate = new Date(dateString).toLocaleDateString(this.translateService.currentLang);
1617
+ this.globalNotificationService.showToast({
1618
+ title: this.translateService.instant('taskDetail.dueDateSetNotificationTitle'),
1619
+ subtitle: this.translateService.instant('taskDetail.dueDateSetNotificationContent', {
1620
+ date: formattedDate,
1621
+ task: this._task?.name,
1622
+ }),
1623
+ type: 'info',
1624
+ });
1625
+ }
1626
+ showDueDateRemovedNotification() {
1627
+ this.globalNotificationService.showToast({
1628
+ title: this.translateService.instant('taskDetail.dueDateRemovedNotificationTitle'),
1629
+ subtitle: this.translateService.instant('taskDetail.dueDateRemovedNotificationContent', {
1630
+ task: this._task?.name,
1631
+ }),
1632
+ type: 'info',
1633
+ });
1634
+ }
1635
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: SetTaskDueDateComponent, deps: [{ token: i9.CdsThemeService }, { token: i2$1.IconService }, { token: TaskService }, { token: i4$1.TranslateService }, { token: i1$1.GlobalNotificationService }], target: i0.ɵɵFactoryTarget.Component }); }
1636
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: SetTaskDueDateComponent, isStandalone: true, selector: "valtimo-set-task-due-date", inputs: { canModifyTask: "canModifyTask", task: "task" }, outputs: { dueDateChanged: "dueDateChanged" }, ngImport: i0, template: "<!--\n ~ Copyright 2015-2026 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<ng-container\n *ngIf=\"\n (canModifyTaskSet$ | async) && {\n hasDueDate: hasDueDate$ | async,\n taskDueDate: taskDueDate$ | async,\n selectedDateString: selectedDateString$ | async,\n disabled: disabled$ | async,\n mouseIsOverDueDate: mouseIsOverDueDate$ | async,\n canModifyTask: canModifyTask$ | async,\n language: language$ | async,\n showDatePicker: showDatePicker$ | async,\n editToggletipOpen: editToggletipOpen$ | async,\n } as obs\n \"\n>\n <div\n *ngIf=\"obs.canModifyTask || (!obs.canModifyTask && obs.hasDueDate)\"\n class=\"due-date-container\"\n (mouseenter)=\"onMouseEnterDueDate()\"\n (mouseleave)=\"onMouseLeaveDueDate()\"\n >\n <div\n class=\"due-date-text element\"\n [ngClass]=\"{\n active: obs.canModifyTask\n ? obs.hasDueDate && !obs.mouseIsOverDueDate && !obs.editToggletipOpen\n : obs.hasDueDate,\n }\"\n >\n <span class=\"bold\">{{ 'setTaskDueDate.dueDateText' | translate }}</span>\n &nbsp;\n {{ obs.taskDueDate | date: 'dd-MM-yyyy' }}\n </div>\n\n <cds-toggletip\n *ngIf=\"obs.canModifyTask\"\n align=\"bottom\"\n class=\"element\"\n [autoAlign]=\"true\"\n [isOpen]=\"open$ | async\"\n [ngClass]=\"{active: obs.hasDueDate && (obs.mouseIsOverDueDate || obs.editToggletipOpen)}\"\n (onOpen)=\"initEditWithCurrentDate()\"\n (onClose)=\"onCloseEditToggletip()\"\n >\n <button\n cdsToggletipButton\n [removeClassnames]=\"['cds--toggletip-button']\"\n cdsButton=\"ghost\"\n size=\"sm\"\n class=\"click-to-edit-button\"\n >\n {{ 'setTaskDueDate.clickToEdit' | translate }}\n </button>\n\n <div cdsToggletipContent class=\"assign-due-date-popover-content\">\n <cds-date-picker\n *ngIf=\"obs.showDatePicker\"\n [attr.data-carbon-theme]=\"toggletipDropdownTheme$ | async\"\n [cdsLayer]=\"1\"\n [label]=\"'setTaskDueDate.label' | translate\"\n [language]=\"obs.language\"\n [placeholder]=\"'dd-mm-jjjj'\"\n dateFormat=\"d/m/Y\"\n [value]=\"obs.taskDueDate ? [obs.taskDueDate] : []\"\n [disabled]=\"obs.disabled\"\n (valueChange)=\"onDateValueChange($event)\"\n ></cds-date-picker>\n\n <button\n cdsButton\n [attr.data-carbon-theme]=\"toggletipTheme$ | async\"\n class=\"submit-due-date-button\"\n [disabled]=\"!obs.selectedDateString || obs.disabled\"\n (click)=\"onSubmitButtonClick()\"\n >\n {{ 'setTaskDueDate.submitButtonText' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"calendar--add\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"danger--tertiary\"\n [cdsLayer]=\"1\"\n [attr.data-carbon-theme]=\"toggletipTheme$ | async\"\n [disabled]=\"obs.disabled\"\n (click)=\"onRemoveButtonClick()\"\n >\n {{ 'setTaskDueDate.removeButtonText' | translate }}\n </button>\n </div>\n </cds-toggletip>\n\n <cds-toggletip\n align=\"bottom\"\n class=\"element main\"\n [autoAlign]=\"true\"\n [isOpen]=\"open$ | async\"\n [ngClass]=\"{active: !obs.hasDueDate}\"\n (onOpen)=\"clear()\"\n >\n <button\n cdsToggletipButton\n [removeClassnames]=\"['cds--toggletip-button']\"\n cdsButton=\"tertiary\"\n size=\"sm\"\n class=\"set-task-due-date-button\"\n >\n {{ 'setTaskDueDate.buttonText' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"calendar--add\" size=\"16\"></svg>\n </button>\n\n <div cdsToggletipContent class=\"assign-due-date-popover-content\">\n <cds-date-picker\n *ngIf=\"!obs.hasDueDate && obs.showDatePicker\"\n [attr.data-carbon-theme]=\"toggletipDropdownTheme$ | async\"\n [cdsLayer]=\"1\"\n [label]=\"'setTaskDueDate.label' | translate\"\n [language]=\"obs.language\"\n [placeholder]=\"'dd-mm-jjjj'\"\n dateFormat=\"d/m/Y\"\n [disabled]=\"obs.disabled\"\n (valueChange)=\"onDateValueChange($event)\"\n ></cds-date-picker>\n\n <button\n cdsButton\n [attr.data-carbon-theme]=\"toggletipTheme$ | async\"\n class=\"submit-due-date-button\"\n [disabled]=\"!obs.selectedDateString || obs.disabled\"\n (click)=\"onSubmitButtonClick()\"\n >\n {{ 'setTaskDueDate.submitButtonText' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"calendar--add\" size=\"16\"></svg>\n </button>\n </div>\n </cds-toggletip>\n </div>\n</ng-container>\n", styles: [":host ::ng-deep .cds--popover-content{max-inline-size:unset}.due-date-container{display:flex;align-items:center;justify-content:center;position:relative;font-weight:400;font-size:14px;line-height:18px;letter-spacing:.16px;color:var(--cds-link-01)}.due-date-container .bold{font-weight:700}.due-date-text{display:flex;justify-content:flex-start;align-items:center;width:100%}.element{opacity:0;visibility:hidden;position:absolute;width:100%;transition:opacity .3s ease-in-out}.element.active{opacity:1;visibility:visible}.element.main{position:relative;width:auto}.assign-due-date-popover-content{width:400px;max-inline-size:400px;display:flex;flex-direction:column;gap:16px}.assign-due-date-popover-content .cds--btn{width:100%;max-width:unset}.assign-due-date-popover-content ::ng-deep .cds--date-picker-input__wrapper,.assign-due-date-popover-content ::ng-deep .cds--date-picker-input__wrapper>span,.assign-due-date-popover-content ::ng-deep .cds--date-picker-container,.assign-due-date-popover-content ::ng-deep .cds--date-picker,.assign-due-date-popover-content ::ng-deep .cds--date-picker__input{width:100%}.set-task-due-date-button{width:250px}.click-to-edit-button{width:100%}\n/*!\n * Copyright 2015-2026 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: "ngmodule", type: CommonModule }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.DatePipe, name: "date" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i4$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i2$1.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "ngmodule", type: ToggletipModule }, { kind: "component", type: i2$1.Toggletip, selector: "cds-toggletip, ibm-toggletip", inputs: ["id", "isOpen"] }, { kind: "directive", type: i2$1.ToggletipButton, selector: "[cdsToggletipButton], [ibmToggletipButton]", inputs: ["ariaLabel"] }, { kind: "directive", type: i2$1.ToggletipContent, selector: "[cdsToggletipContent], [ibmToggletipContent]" }, { kind: "ngmodule", type: DatePickerModule }, { kind: "component", type: i2$1.DatePicker, selector: "cds-date-picker, ibm-date-picker", inputs: ["range", "dateFormat", "language", "label", "helperText", "rangeHelperText", "rangeLabel", "placeholder", "ariaLabel", "inputPattern", "id", "value", "theme", "disabled", "readonly", "invalid", "invalidText", "warn", "warnText", "size", "rangeInvalid", "rangeInvalidText", "rangeWarn", "rangeWarnText", "skeleton", "plugins", "flatpickrOptions"], outputs: ["valueChange", "onClose"] }, { kind: "ngmodule", type: LayerModule }, { kind: "directive", type: i2$1.LayerDirective, selector: "[cdsLayer], [ibmLayer]", inputs: ["ibmLayer", "cdsLayer"], exportAs: ["layer"] }, { kind: "directive", type: RemoveClassnamesDirective, selector: "[removeClassnames]", inputs: ["removeClassnames"] }] }); }
1637
+ }
1638
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: SetTaskDueDateComponent, decorators: [{
1639
+ type: Component,
1640
+ args: [{ selector: 'valtimo-set-task-due-date', standalone: true, imports: [
1641
+ CommonModule,
1642
+ TranslateModule,
1643
+ ButtonModule,
1644
+ IconModule,
1645
+ ToggletipModule,
1646
+ DatePickerModule,
1647
+ LayerModule,
1648
+ RemoveClassnamesDirective,
1649
+ ], template: "<!--\n ~ Copyright 2015-2026 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<ng-container\n *ngIf=\"\n (canModifyTaskSet$ | async) && {\n hasDueDate: hasDueDate$ | async,\n taskDueDate: taskDueDate$ | async,\n selectedDateString: selectedDateString$ | async,\n disabled: disabled$ | async,\n mouseIsOverDueDate: mouseIsOverDueDate$ | async,\n canModifyTask: canModifyTask$ | async,\n language: language$ | async,\n showDatePicker: showDatePicker$ | async,\n editToggletipOpen: editToggletipOpen$ | async,\n } as obs\n \"\n>\n <div\n *ngIf=\"obs.canModifyTask || (!obs.canModifyTask && obs.hasDueDate)\"\n class=\"due-date-container\"\n (mouseenter)=\"onMouseEnterDueDate()\"\n (mouseleave)=\"onMouseLeaveDueDate()\"\n >\n <div\n class=\"due-date-text element\"\n [ngClass]=\"{\n active: obs.canModifyTask\n ? obs.hasDueDate && !obs.mouseIsOverDueDate && !obs.editToggletipOpen\n : obs.hasDueDate,\n }\"\n >\n <span class=\"bold\">{{ 'setTaskDueDate.dueDateText' | translate }}</span>\n &nbsp;\n {{ obs.taskDueDate | date: 'dd-MM-yyyy' }}\n </div>\n\n <cds-toggletip\n *ngIf=\"obs.canModifyTask\"\n align=\"bottom\"\n class=\"element\"\n [autoAlign]=\"true\"\n [isOpen]=\"open$ | async\"\n [ngClass]=\"{active: obs.hasDueDate && (obs.mouseIsOverDueDate || obs.editToggletipOpen)}\"\n (onOpen)=\"initEditWithCurrentDate()\"\n (onClose)=\"onCloseEditToggletip()\"\n >\n <button\n cdsToggletipButton\n [removeClassnames]=\"['cds--toggletip-button']\"\n cdsButton=\"ghost\"\n size=\"sm\"\n class=\"click-to-edit-button\"\n >\n {{ 'setTaskDueDate.clickToEdit' | translate }}\n </button>\n\n <div cdsToggletipContent class=\"assign-due-date-popover-content\">\n <cds-date-picker\n *ngIf=\"obs.showDatePicker\"\n [attr.data-carbon-theme]=\"toggletipDropdownTheme$ | async\"\n [cdsLayer]=\"1\"\n [label]=\"'setTaskDueDate.label' | translate\"\n [language]=\"obs.language\"\n [placeholder]=\"'dd-mm-jjjj'\"\n dateFormat=\"d/m/Y\"\n [value]=\"obs.taskDueDate ? [obs.taskDueDate] : []\"\n [disabled]=\"obs.disabled\"\n (valueChange)=\"onDateValueChange($event)\"\n ></cds-date-picker>\n\n <button\n cdsButton\n [attr.data-carbon-theme]=\"toggletipTheme$ | async\"\n class=\"submit-due-date-button\"\n [disabled]=\"!obs.selectedDateString || obs.disabled\"\n (click)=\"onSubmitButtonClick()\"\n >\n {{ 'setTaskDueDate.submitButtonText' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"calendar--add\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"danger--tertiary\"\n [cdsLayer]=\"1\"\n [attr.data-carbon-theme]=\"toggletipTheme$ | async\"\n [disabled]=\"obs.disabled\"\n (click)=\"onRemoveButtonClick()\"\n >\n {{ 'setTaskDueDate.removeButtonText' | translate }}\n </button>\n </div>\n </cds-toggletip>\n\n <cds-toggletip\n align=\"bottom\"\n class=\"element main\"\n [autoAlign]=\"true\"\n [isOpen]=\"open$ | async\"\n [ngClass]=\"{active: !obs.hasDueDate}\"\n (onOpen)=\"clear()\"\n >\n <button\n cdsToggletipButton\n [removeClassnames]=\"['cds--toggletip-button']\"\n cdsButton=\"tertiary\"\n size=\"sm\"\n class=\"set-task-due-date-button\"\n >\n {{ 'setTaskDueDate.buttonText' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"calendar--add\" size=\"16\"></svg>\n </button>\n\n <div cdsToggletipContent class=\"assign-due-date-popover-content\">\n <cds-date-picker\n *ngIf=\"!obs.hasDueDate && obs.showDatePicker\"\n [attr.data-carbon-theme]=\"toggletipDropdownTheme$ | async\"\n [cdsLayer]=\"1\"\n [label]=\"'setTaskDueDate.label' | translate\"\n [language]=\"obs.language\"\n [placeholder]=\"'dd-mm-jjjj'\"\n dateFormat=\"d/m/Y\"\n [disabled]=\"obs.disabled\"\n (valueChange)=\"onDateValueChange($event)\"\n ></cds-date-picker>\n\n <button\n cdsButton\n [attr.data-carbon-theme]=\"toggletipTheme$ | async\"\n class=\"submit-due-date-button\"\n [disabled]=\"!obs.selectedDateString || obs.disabled\"\n (click)=\"onSubmitButtonClick()\"\n >\n {{ 'setTaskDueDate.submitButtonText' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"calendar--add\" size=\"16\"></svg>\n </button>\n </div>\n </cds-toggletip>\n </div>\n</ng-container>\n", styles: [":host ::ng-deep .cds--popover-content{max-inline-size:unset}.due-date-container{display:flex;align-items:center;justify-content:center;position:relative;font-weight:400;font-size:14px;line-height:18px;letter-spacing:.16px;color:var(--cds-link-01)}.due-date-container .bold{font-weight:700}.due-date-text{display:flex;justify-content:flex-start;align-items:center;width:100%}.element{opacity:0;visibility:hidden;position:absolute;width:100%;transition:opacity .3s ease-in-out}.element.active{opacity:1;visibility:visible}.element.main{position:relative;width:auto}.assign-due-date-popover-content{width:400px;max-inline-size:400px;display:flex;flex-direction:column;gap:16px}.assign-due-date-popover-content .cds--btn{width:100%;max-width:unset}.assign-due-date-popover-content ::ng-deep .cds--date-picker-input__wrapper,.assign-due-date-popover-content ::ng-deep .cds--date-picker-input__wrapper>span,.assign-due-date-popover-content ::ng-deep .cds--date-picker-container,.assign-due-date-popover-content ::ng-deep .cds--date-picker,.assign-due-date-popover-content ::ng-deep .cds--date-picker__input{width:100%}.set-task-due-date-button{width:250px}.click-to-edit-button{width:100%}\n/*!\n * Copyright 2015-2026 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"] }]
1650
+ }], ctorParameters: () => [{ type: i9.CdsThemeService }, { type: i2$1.IconService }, { type: TaskService }, { type: i4$1.TranslateService }, { type: i1$1.GlobalNotificationService }], propDecorators: { dueDateChanged: [{
1651
+ type: Output
1652
+ }], canModifyTask: [{
1653
+ type: Input
1654
+ }], task: [{
1655
+ type: Input
1656
+ }] } });
1657
+
1658
+ /*
1659
+ * Copyright 2015-2026 Ritense BV, the Netherlands.
1660
+ *
1661
+ * Licensed under EUPL, Version 1.2 (the "License");
1662
+ * you may not use this file except in compliance with the License.
1663
+ * You may obtain a copy of the License at
1664
+ *
1665
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
1666
+ *
1667
+ * Unless required by applicable law or agreed to in writing, software
1668
+ * distributed under the License is distributed on an "AS IS" basis,
1669
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1670
+ * See the License for the specific language governing permissions and
1671
+ * limitations under the License.
1672
+ */
1673
+ moment.locale(localStorage.getItem('langKey') || '');
1674
+ class TaskDetailModalComponent {
1675
+ set modalSize(value) {
1676
+ if (value)
1677
+ this.size$.next(formSizeToCarbonModalSizeMap[value]);
1678
+ }
1679
+ set openFromCaseManagement(value) {
1680
+ if (value)
1681
+ this.openFromCaseManagement$.next(value);
1682
+ }
1683
+ constructor(router, translateService, permissionService, logger, taskIntermediateSaveService, sseService, cdr, iconService, documentService, taskService, globalNotificationService) {
1684
+ this.router = router;
1685
+ this.translateService = translateService;
1686
+ this.permissionService = permissionService;
1687
+ this.logger = logger;
1688
+ this.taskIntermediateSaveService = taskIntermediateSaveService;
1689
+ this.sseService = sseService;
1690
+ this.cdr = cdr;
1691
+ this.iconService = iconService;
1692
+ this.documentService = documentService;
1693
+ this.taskService = taskService;
1694
+ this.globalNotificationService = globalNotificationService;
1695
+ this.formSubmit = new EventEmitter();
1696
+ this.assignmentOfTaskChanged = new EventEmitter();
1697
+ this.dueDateChanged = new EventEmitter();
1698
+ this.modalClosed = new EventEmitter();
1699
+ this.currentIntermediateSave$ = new BehaviorSubject(null);
1700
+ this.processLinkPreloaded$ = new BehaviorSubject(false);
1701
+ this.task$ = new BehaviorSubject(null);
1702
+ this.taskAndProcessLink$ = new BehaviorSubject(null);
1703
+ this.submission$ = new BehaviorSubject({});
1704
+ this.page$ = new BehaviorSubject(null);
1705
+ this.showConfirmationModal$ = new BehaviorSubject(false);
1706
+ this.businessKey$ = new BehaviorSubject('');
1707
+ this.caseDocumentId$ = new BehaviorSubject('');
1708
+ this.size$ = new BehaviorSubject('md');
1709
+ this.openFromCaseManagement$ = new BehaviorSubject(false);
1710
+ this.canAssignUserToTask$ = new BehaviorSubject(false);
1711
+ this.canModifyTask$ = new BehaviorSubject(false);
1712
+ this.modalCloseEvent$ = new BehaviorSubject(false);
1713
+ this.modalOpen$ = new BehaviorSubject(false);
1714
+ this.candidateUsers$ = combineLatest([
1715
+ this.task$.pipe(filter$1(task => !!task)),
1716
+ this.canAssignUserToTask$,
1717
+ ]).pipe(switchMap$1(([task, canAssign]) => canAssign ? this.taskService.getCandidateUsers(task.id) : of([])), shareReplay(1));
1718
+ this.candidateTeams$ = combineLatest([
1719
+ this.task$.pipe(filter$1(task => !!task)),
1720
+ this.canAssignUserToTask$,
1721
+ ]).pipe(switchMap$1(([task, canAssign]) => canAssign ? this.taskService.getCandidateTeams(task.id).pipe(map(page => page.content)) : of([])), shareReplay(1));
1722
+ this._subscriptions = new Subscription();
1723
+ this.iconService.registerAll([FolderDetailsReference16]);
1724
+ }
1725
+ ngOnInit() {
1726
+ this.openTaskSubscription();
1727
+ this.openTaskUpdateSseEventSubscription();
1728
+ }
1729
+ ngOnDestroy() {
1730
+ this._subscriptions.unsubscribe();
1731
+ }
1732
+ openRelatedCase() {
1733
+ const caseDocId = this.caseDocumentId$.getValue() || this.businessKey$.getValue();
1734
+ this.documentService
1735
+ .getDocument(caseDocId)
1736
+ .pipe(take(1))
1737
+ .subscribe(document => {
1738
+ window.open(`/cases/${document.definitionId?.name}/document/${caseDocId}`, '_blank');
1739
+ });
1740
+ }
1741
+ openTaskSubscription() {
1742
+ this._subscriptions.add(this.task$.subscribe(task => {
1743
+ if (task) {
1744
+ this.logger.debug('Checking if user allowed to assign a user to Task with id:', task.id);
1745
+ this.businessKey$.next(task.businessKey);
1746
+ this.caseDocumentId$.next(task.caseDocumentId || task.businessKey);
1747
+ this.permissionService
1748
+ .requestPermission(CAN_ASSIGN_TASK_PERMISSION, {
1749
+ resource: TASK_DETAIL_PERMISSION_RESOURCE.task,
1750
+ identifier: task.id,
1751
+ })
1752
+ .subscribe((allowed) => {
1753
+ this.canAssignUserToTask$.next(allowed);
1754
+ });
1755
+ this.permissionService
1756
+ .requestPermission(CAN_MODIFY_TASK_PERMISSION, {
1757
+ resource: TASK_DETAIL_PERMISSION_RESOURCE.task,
1758
+ identifier: task.id,
1759
+ })
1760
+ .subscribe((allowed) => {
1761
+ this.canModifyTask$.next(allowed);
1762
+ });
1763
+ }
1764
+ else {
1765
+ this.logger.debug('Reset is user allowed to assign a user to Task as task is null');
1766
+ this.canAssignUserToTask$.next(false);
1767
+ }
1768
+ }));
1769
+ }
1770
+ openTaskUpdateSseEventSubscription() {
1771
+ this._subscriptions.add(this.sseService
1772
+ .getSseEventObservable('TASK_UPDATE')
1773
+ .pipe(filter$1(event => this.task$.getValue()?.id === event.taskId), switchMap$1(event => this.taskService.getTask(event.taskId).pipe(catchError$1(err => {
1774
+ if (err.status === 404) {
1775
+ return of(null);
1776
+ }
1777
+ this.logger.error('Failed to fetch task on SSE update', err);
1778
+ return EMPTY;
1779
+ }))))
1780
+ .subscribe(response => {
1781
+ if (!response) {
1782
+ this.closeModal();
1783
+ }
1784
+ else {
1785
+ const currentTask = this.task$.getValue();
1786
+ const fetchedTask = response.task;
1787
+ if (!currentTask || !fetchedTask)
1788
+ return;
1789
+ // Merge fetched task data onto the existing task, only overwriting with
1790
+ // defined values to preserve fields not returned by the GET /v1/task/{id}
1791
+ // endpoint (e.g. valtimoAssignee, businessKey, caseDocumentId)
1792
+ const mergedTask = { ...currentTask };
1793
+ for (const [key, value] of Object.entries(fetchedTask)) {
1794
+ if (value !== undefined) {
1795
+ mergedTask[key] = value;
1796
+ }
1797
+ }
1798
+ if (currentTask.assignee !== mergedTask.assignee) {
1799
+ this.showAssigneeNotification(mergedTask);
1800
+ }
1801
+ this.task$.next(mergedTask);
1802
+ }
1803
+ }));
1804
+ }
1805
+ refreshTask(response) {
1806
+ const currentTask = this.task$.getValue();
1807
+ const fetchedTask = response.task;
1808
+ if (!currentTask || !fetchedTask)
1809
+ return;
1810
+ const mergedTask = { ...currentTask };
1811
+ for (const [key, value] of Object.entries(fetchedTask)) {
1812
+ if (value !== undefined) {
1813
+ mergedTask[key] = value;
1814
+ }
1815
+ }
1816
+ this.task$.next(mergedTask);
1817
+ }
1818
+ showAssigneeNotification(task) {
1819
+ if (task.assignee) {
1820
+ this.globalNotificationService.showToast({
1821
+ title: this.translateService.instant('taskDetail.assignedNotificationTitle'),
1822
+ type: 'info',
1823
+ });
1824
+ }
1825
+ else {
1826
+ this.globalNotificationService.showToast({
1827
+ title: this.translateService.instant('taskDetail.unassignedNotificationTitle'),
1828
+ type: 'info',
1829
+ });
1830
+ }
1831
+ }
1832
+ clearCurrentProgress() {
1833
+ this._intermediateSaveComponent.clearCurrentProgress();
1834
+ }
1835
+ openTaskDetails(task) {
1836
+ if (task) {
1837
+ this.task$.next({ ...task });
1838
+ }
1839
+ this.setPageFromTask(task);
1840
+ this.openModal();
1841
+ }
1842
+ openTaskAndProcessLinkDetails(taskWithProcessLink) {
1843
+ this.processLinkPreloaded$.next(true);
1844
+ if (taskWithProcessLink) {
1845
+ this.taskAndProcessLink$.next(taskWithProcessLink);
1846
+ const task = enrichTaskFromProcessLink({ ...taskWithProcessLink.task }, taskWithProcessLink.processLinkActivityResult);
1847
+ this.task$.next(task);
1848
+ }
1849
+ this.setPageFromTask(taskWithProcessLink?.task);
1850
+ this.openModal();
1851
+ }
1852
+ setPageFromTask(task) {
1853
+ this.page$.next({
1854
+ title: task?.name,
1855
+ subtitle: `${this.translateService.instant('taskDetail.taskCreated')} ${task?.created}`,
1856
+ });
1857
+ }
1858
+ gotoProcessLinkScreen() {
1859
+ this.closeModal();
1860
+ this.router.navigate(['process-links']);
1861
+ }
1862
+ onCurrentIntermediateSaveEvent(value) {
1863
+ this.currentIntermediateSave$.next(value);
1864
+ }
1865
+ onTaskUpdated(task) {
1866
+ this.task$.next(task);
1867
+ }
1868
+ onAssignmentChanged(event) {
1869
+ const task = this.task$.getValue();
1870
+ if (!task)
1871
+ return;
1872
+ const assignRequest = {};
1873
+ if (event.userId !== undefined)
1874
+ assignRequest.assignee = event.userId ?? '';
1875
+ if (event.teamKey !== undefined)
1876
+ assignRequest.assignedTeamKey = event.teamKey ?? '';
1877
+ this.taskService
1878
+ .assignTask(task.id, assignRequest)
1879
+ .pipe(switchMap$1(() => this.taskService.getTask(task.id)), take(1))
1880
+ .subscribe(response => {
1881
+ this.refreshTask(response);
1882
+ this.assignmentOfTaskChanged.emit();
1883
+ });
1884
+ }
1885
+ onUnassigned() {
1886
+ const task = this.task$.getValue();
1887
+ if (!task)
1888
+ return;
1889
+ this.taskService
1890
+ .unassignTask(task.id)
1891
+ .pipe(switchMap$1(() => this.taskService.getTask(task.id)), take(1))
1892
+ .subscribe(response => {
1893
+ this.refreshTask(response);
1894
+ this.assignmentOfTaskChanged.emit();
1895
+ });
1896
+ }
1897
+ onFormSubmit() {
1898
+ this.formSubmit.emit();
1899
+ }
1900
+ onShowModalEvent() {
1901
+ this.showConfirmationModal$.next(true);
1902
+ }
1903
+ closeModal() {
1904
+ this.modalOpen$.next(false);
1905
+ this.modalCloseEvent$.next(!this.modalCloseEvent$.getValue());
1906
+ this.modalClosed.emit();
1907
+ // Delay clearing task data and submission until after modal close animation completes
1908
+ runAfterCarbonModalClosed(() => {
1909
+ this.processLinkPreloaded$.next(false);
1910
+ this.task$.next(null);
1911
+ this.taskAndProcessLink$.next(null);
1912
+ this.taskIntermediateSaveService.setSubmission({});
1913
+ });
1914
+ }
1915
+ openModal() {
1916
+ this.modalOpen$.next(false);
1917
+ setTimeout(() => {
1918
+ this.modalOpen$.next(true);
1919
+ this.cdr.detectChanges();
1920
+ });
1921
+ }
1922
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskDetailModalComponent, deps: [{ token: i1$2.Router }, { token: i4$1.TranslateService }, { token: i3.PermissionService }, { token: i4.NGXLogger }, { token: TaskIntermediateSaveService }, { token: i6$1.SseService }, { token: i0.ChangeDetectorRef }, { token: i2$1.IconService }, { token: i2.DocumentService }, { token: TaskService }, { token: i1$1.GlobalNotificationService }], target: i0.ɵɵFactoryTarget.Component }); }
1923
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: TaskDetailModalComponent, isStandalone: false, selector: "valtimo-task-detail-modal", inputs: { modalSize: "modalSize", openFromCaseManagement: "openFromCaseManagement" }, outputs: { formSubmit: "formSubmit", assignmentOfTaskChanged: "assignmentOfTaskChanged", dueDateChanged: "dueDateChanged", modalClosed: "modalClosed" }, viewQueries: [{ propertyName: "_intermediateSaveComponent", first: true, predicate: TaskDetailIntermediateSaveComponent, descendants: 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<cds-modal\n id=\"taskDetailModal\"\n [size]=\"size$ | async\"\n [open]=\"modalOpen$ | async\"\n (close)=\"closeModal()\"\n valtimoCdsModal\n [minContentHeight]=\"480\"\n>\n <cds-modal-header (closeSelect)=\"closeModal()\">\n <div class=\"title-container\">\n <p class=\"cds--modal-header__heading cds--type-beta\">{{ (page$ | async)?.title }}</p>\n\n <p class=\"cds--modal-header__label cds--type-delta\">{{ (page$ | async)?.subtitle }}</p>\n\n <p\n class=\"cds--modal-header__label cds--type-delta\"\n *ngIf=\"currentIntermediateSave$ | async as currentIntermediateSave\"\n >\n {{ 'formManagement.intermediateSave.lastSavedBy' | translate }}:\n\n {{\n currentIntermediateSave?.editedBy\n ? currentIntermediateSave?.editedBy\n : currentIntermediateSave.createdBy\n }}\n\n {{ 'formManagement.intermediateSave.on' | translate }}:\n\n {{\n currentIntermediateSave?.editedOn\n ? currentIntermediateSave?.editedOn\n : currentIntermediateSave.createdOn\n }}\n </p>\n\n <ng-container *ngTemplateOutlet=\"assignUserToTask\"></ng-container>\n </div>\n\n <div class=\"save-buttons-margin\">\n <button\n *ngIf=\"!(openFromCaseManagement$ | async)\"\n cdsButton=\"ghost\"\n iconOnly=\"true\"\n cdsIcon=\"folder--details--reference\"\n [vTooltip]=\"'formManagement.navigateToRelatedCase' | translate\"\n (click)=\"openRelatedCase()\"\n ></button>\n\n @if (processLinkPreloaded$ | async) {\n <valtimo-task-detail-intermediate-save\n [taskAndProcessLink]=\"taskAndProcessLink$ | async\"\n (currentIntermediateSaveEvent)=\"onCurrentIntermediateSaveEvent($event)\"\n (showModalEvent)=\"onShowModalEvent()\"\n ></valtimo-task-detail-intermediate-save>\n } @else {\n <valtimo-task-detail-intermediate-save\n [task]=\"task$ | async\"\n (currentIntermediateSaveEvent)=\"onCurrentIntermediateSaveEvent($event)\"\n (showModalEvent)=\"onShowModalEvent()\"\n ></valtimo-task-detail-intermediate-save>\n }\n </div>\n </cds-modal-header>\n\n <div body class=\"cds--modal-content pb-1\">\n @if (processLinkPreloaded$ | async) {\n <valtimo-task-detail-content\n [taskAndProcessLink]=\"taskAndProcessLink$ | async\"\n [modalClosed]=\"modalCloseEvent$ | async\"\n (formSubmit)=\"onFormSubmit()\"\n (closeModalEvent)=\"closeModal()\"\n (taskUpdated)=\"onTaskUpdated($event)\"\n ></valtimo-task-detail-content>\n } @else {\n <valtimo-task-detail-content\n [task]=\"task$ | async\"\n [modalClosed]=\"modalCloseEvent$ | async\"\n (formSubmit)=\"onFormSubmit()\"\n (closeModalEvent)=\"closeModal()\"\n (taskUpdated)=\"onTaskUpdated($event)\"\n ></valtimo-task-detail-content>\n }\n </div>\n</cds-modal>\n\n<valtimo-confirmation-modal\n [showModalSubject$]=\"showConfirmationModal$\"\n (confirmEvent)=\"clearCurrentProgress()\"\n (cancelEvent)=\"showConfirmationModal$.next(false)\"\n cancelButtonType=\"ghost\"\n confirmButtonTextTranslationKey=\"interface.confirm\"\n titleTranslationKey=\"formManagement.intermediateSave.clear\"\n contentTranslationKey=\"formManagement.intermediateSave.clearConfirm\"\n></valtimo-confirmation-modal>\n\n<ng-template #assignUserToTask>\n <div\n *ngIf=\"{\n task: task$ | async,\n canAssignUserToTask: canAssignUserToTask$ | async,\n canModifyTask: canModifyTask$ | async,\n } as obs\"\n class=\"task-actions\"\n >\n <valtimo-assignment\n *ngIf=\"obs.task && assignmentOfTaskChanged\"\n mode=\"task\"\n [assigneeId]=\"obs.task.assignee\"\n [assigneeFullName]=\"obs.task.valtimoAssignee?.fullName\"\n [assignedTeamKey]=\"obs.task.assignedTeam?.key\"\n [assignedTeamTitle]=\"obs.task.assignedTeam?.title\"\n [hasPermission]=\"obs.canAssignUserToTask\"\n [candidateUsers$]=\"candidateUsers$\"\n [candidateTeams$]=\"candidateTeams$\"\n (assignmentChangedEvent)=\"onAssignmentChanged($event)\"\n (unassignedEvent)=\"onUnassigned()\"\n ></valtimo-assignment>\n\n <valtimo-set-task-due-date\n [task]=\"obs.task\"\n [canModifyTask]=\"obs.canModifyTask\"\n (dueDateChanged)=\"dueDateChanged.emit()\"\n ></valtimo-set-task-due-date>\n </div>\n</ng-template>\n", styles: ["#taskDetailModal .formio-component-submit{text-align:right}#taskDetailModal .cds--modal:not(.is-visible){pointer-events:none}cds-modal-header .cds--modal-header{display:flex;justify-content:space-between}.save-buttons-margin{margin-top:-15px}.task-actions{display:flex;flex-wrap:wrap;width:100%;padding-top:8px;gap:8px}\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.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$1.Modal, selector: "cds-modal, ibm-modal", inputs: ["size", "theme", "ariaLabel", "open", "trigger", "hasScrollingContent"], outputs: ["overlaySelected", "close"] }, { kind: "component", type: i2$1.ModalHeader, selector: "cds-modal-header, ibm-modal-header", inputs: ["theme", "closeLabel", "showCloseButton"], outputs: ["closeSelect"] }, { kind: "directive", type: i2$1.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "directive", type: i2$1.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "directive", type: i9.TooltipDirective, selector: "[vTooltip]", inputs: ["vTooltip", "onBottom", "tooltipDisabled"] }, { kind: "component", type: i9.ConfirmationModalComponent, selector: "valtimo-confirmation-modal", inputs: ["titleTranslationKey", "title", "content", "contentTranslationKey", "confirmButtonText", "confirmButtonTextTranslationKey", "confirmButtonType", "showOptionalButton", "optionalButtonText", "optionalButtonTextTranslationKey", "optionalButtonType", "cancelButtonText", "cancelButtonTextTranslationKey", "cancelButtonType", "showModalSubject$", "outputOnConfirm", "outputOnOptional", "spacerAfterCancelButton"], outputs: ["confirmEvent", "optionalEvent", "cancelEvent"] }, { kind: "component", type: i9.AssignmentComponent, selector: "valtimo-assignment", inputs: ["mode", "hasPermission", "assigneeId", "assigneeFullName", "assignedTeamKey", "assignedTeamTitle", "candidateUsers$", "candidateTeams$"], outputs: ["assignmentChangedEvent", "unassignedEvent"] }, { kind: "component", type: TaskDetailContentComponent, selector: "valtimo-task-detail-content", inputs: ["task", "taskAndProcessLink", "modalClosed"], outputs: ["closeModalEvent", "formSubmit", "activeChange", "taskUpdated"] }, { kind: "component", type: TaskDetailIntermediateSaveComponent, selector: "valtimo-task-detail-intermediate-save", inputs: ["task", "taskAndProcessLink"], outputs: ["currentIntermediateSaveEvent", "showModalEvent"] }, { kind: "component", type: SetTaskDueDateComponent, selector: "valtimo-set-task-due-date", inputs: ["canModifyTask", "task"], outputs: ["dueDateChanged"] }, { kind: "directive", type: i9.ValtimoCdsModalDirective, selector: "[valtimoCdsModal]", inputs: ["minContentHeight"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i4$1.TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1924
+ }
1925
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskDetailModalComponent, decorators: [{
1926
+ type: Component,
1927
+ args: [{ standalone: false, selector: 'valtimo-task-detail-modal', encapsulation: ViewEncapsulation.None, 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<cds-modal\n id=\"taskDetailModal\"\n [size]=\"size$ | async\"\n [open]=\"modalOpen$ | async\"\n (close)=\"closeModal()\"\n valtimoCdsModal\n [minContentHeight]=\"480\"\n>\n <cds-modal-header (closeSelect)=\"closeModal()\">\n <div class=\"title-container\">\n <p class=\"cds--modal-header__heading cds--type-beta\">{{ (page$ | async)?.title }}</p>\n\n <p class=\"cds--modal-header__label cds--type-delta\">{{ (page$ | async)?.subtitle }}</p>\n\n <p\n class=\"cds--modal-header__label cds--type-delta\"\n *ngIf=\"currentIntermediateSave$ | async as currentIntermediateSave\"\n >\n {{ 'formManagement.intermediateSave.lastSavedBy' | translate }}:\n\n {{\n currentIntermediateSave?.editedBy\n ? currentIntermediateSave?.editedBy\n : currentIntermediateSave.createdBy\n }}\n\n {{ 'formManagement.intermediateSave.on' | translate }}:\n\n {{\n currentIntermediateSave?.editedOn\n ? currentIntermediateSave?.editedOn\n : currentIntermediateSave.createdOn\n }}\n </p>\n\n <ng-container *ngTemplateOutlet=\"assignUserToTask\"></ng-container>\n </div>\n\n <div class=\"save-buttons-margin\">\n <button\n *ngIf=\"!(openFromCaseManagement$ | async)\"\n cdsButton=\"ghost\"\n iconOnly=\"true\"\n cdsIcon=\"folder--details--reference\"\n [vTooltip]=\"'formManagement.navigateToRelatedCase' | translate\"\n (click)=\"openRelatedCase()\"\n ></button>\n\n @if (processLinkPreloaded$ | async) {\n <valtimo-task-detail-intermediate-save\n [taskAndProcessLink]=\"taskAndProcessLink$ | async\"\n (currentIntermediateSaveEvent)=\"onCurrentIntermediateSaveEvent($event)\"\n (showModalEvent)=\"onShowModalEvent()\"\n ></valtimo-task-detail-intermediate-save>\n } @else {\n <valtimo-task-detail-intermediate-save\n [task]=\"task$ | async\"\n (currentIntermediateSaveEvent)=\"onCurrentIntermediateSaveEvent($event)\"\n (showModalEvent)=\"onShowModalEvent()\"\n ></valtimo-task-detail-intermediate-save>\n }\n </div>\n </cds-modal-header>\n\n <div body class=\"cds--modal-content pb-1\">\n @if (processLinkPreloaded$ | async) {\n <valtimo-task-detail-content\n [taskAndProcessLink]=\"taskAndProcessLink$ | async\"\n [modalClosed]=\"modalCloseEvent$ | async\"\n (formSubmit)=\"onFormSubmit()\"\n (closeModalEvent)=\"closeModal()\"\n (taskUpdated)=\"onTaskUpdated($event)\"\n ></valtimo-task-detail-content>\n } @else {\n <valtimo-task-detail-content\n [task]=\"task$ | async\"\n [modalClosed]=\"modalCloseEvent$ | async\"\n (formSubmit)=\"onFormSubmit()\"\n (closeModalEvent)=\"closeModal()\"\n (taskUpdated)=\"onTaskUpdated($event)\"\n ></valtimo-task-detail-content>\n }\n </div>\n</cds-modal>\n\n<valtimo-confirmation-modal\n [showModalSubject$]=\"showConfirmationModal$\"\n (confirmEvent)=\"clearCurrentProgress()\"\n (cancelEvent)=\"showConfirmationModal$.next(false)\"\n cancelButtonType=\"ghost\"\n confirmButtonTextTranslationKey=\"interface.confirm\"\n titleTranslationKey=\"formManagement.intermediateSave.clear\"\n contentTranslationKey=\"formManagement.intermediateSave.clearConfirm\"\n></valtimo-confirmation-modal>\n\n<ng-template #assignUserToTask>\n <div\n *ngIf=\"{\n task: task$ | async,\n canAssignUserToTask: canAssignUserToTask$ | async,\n canModifyTask: canModifyTask$ | async,\n } as obs\"\n class=\"task-actions\"\n >\n <valtimo-assignment\n *ngIf=\"obs.task && assignmentOfTaskChanged\"\n mode=\"task\"\n [assigneeId]=\"obs.task.assignee\"\n [assigneeFullName]=\"obs.task.valtimoAssignee?.fullName\"\n [assignedTeamKey]=\"obs.task.assignedTeam?.key\"\n [assignedTeamTitle]=\"obs.task.assignedTeam?.title\"\n [hasPermission]=\"obs.canAssignUserToTask\"\n [candidateUsers$]=\"candidateUsers$\"\n [candidateTeams$]=\"candidateTeams$\"\n (assignmentChangedEvent)=\"onAssignmentChanged($event)\"\n (unassignedEvent)=\"onUnassigned()\"\n ></valtimo-assignment>\n\n <valtimo-set-task-due-date\n [task]=\"obs.task\"\n [canModifyTask]=\"obs.canModifyTask\"\n (dueDateChanged)=\"dueDateChanged.emit()\"\n ></valtimo-set-task-due-date>\n </div>\n</ng-template>\n", styles: ["#taskDetailModal .formio-component-submit{text-align:right}#taskDetailModal .cds--modal:not(.is-visible){pointer-events:none}cds-modal-header .cds--modal-header{display:flex;justify-content:space-between}.save-buttons-margin{margin-top:-15px}.task-actions{display:flex;flex-wrap:wrap;width:100%;padding-top:8px;gap:8px}\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"] }]
1928
+ }], ctorParameters: () => [{ type: i1$2.Router }, { type: i4$1.TranslateService }, { type: i3.PermissionService }, { type: i4.NGXLogger }, { type: TaskIntermediateSaveService }, { type: i6$1.SseService }, { type: i0.ChangeDetectorRef }, { type: i2$1.IconService }, { type: i2.DocumentService }, { type: TaskService }, { type: i1$1.GlobalNotificationService }], propDecorators: { _intermediateSaveComponent: [{
1929
+ type: ViewChild,
1930
+ args: [TaskDetailIntermediateSaveComponent]
1931
+ }], formSubmit: [{
1932
+ type: Output
1933
+ }], assignmentOfTaskChanged: [{
1934
+ type: Output
1935
+ }], dueDateChanged: [{
1936
+ type: Output
1937
+ }], modalClosed: [{
1938
+ type: Output
1939
+ }], modalSize: [{
1940
+ type: Input
1941
+ }], openFromCaseManagement: [{
1942
+ type: Input
1943
+ }] } });
1944
+
1945
+ /*
1946
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
1947
+ *
1948
+ * Licensed under EUPL, Version 1.2 (the "License");
1949
+ * you may not use this file except in compliance with the License.
1950
+ * You may obtain a copy of the License at
1951
+ *
1952
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
1953
+ *
1954
+ * Unless required by applicable law or agreed to in writing, software
1955
+ * distributed under the License is distributed on an "AS IS" basis,
1956
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1957
+ * See the License for the specific language governing permissions and
1958
+ * limitations under the License.
1959
+ */
1960
+ const TASK_LIST_NO_SEARCH_RESULTS_MESSAGE = {
1961
+ description: 'task-list.noSearchResultsDescription',
1962
+ isSearchResult: true,
1963
+ title: 'task-list.noSearchResultsTitle',
1964
+ };
1965
+
1966
+ /*
1967
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
1968
+ *
1969
+ * Licensed under EUPL, Version 1.2 (the "License");
1970
+ * you may not use this file except in compliance with the License.
1971
+ * You may obtain a copy of the License at
1972
+ *
1973
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
1974
+ *
1975
+ * Unless required by applicable law or agreed to in writing, software
1976
+ * distributed under the License is distributed on an "AS IS" basis,
1977
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1978
+ * See the License for the specific language governing permissions and
1979
+ * limitations under the License.
1980
+ */
1981
+
1982
+ /*
1983
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
1984
+ *
1985
+ * Licensed under EUPL, Version 1.2 (the "License");
1986
+ * you may not use this file except in compliance with the License.
1987
+ * You may obtain a copy of the License at
1988
+ *
1989
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
1990
+ *
1991
+ * Unless required by applicable law or agreed to in writing, software
1992
+ * distributed under the License is distributed on an "AS IS" basis,
1993
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1994
+ * See the License for the specific language governing permissions and
1995
+ * limitations under the License.
1996
+ */
1997
+ moment.locale(localStorage.getItem('langKey') || '');
1998
+ class TaskListComponent {
1999
+ onPopState() {
2000
+ setTimeout(() => {
2001
+ this.setParamsFromQueryParams();
2002
+ });
2003
+ }
2004
+ constructor(configService, documentService, permissionService, router, taskService, taskListService, translateService, taskListColumnService, taskListPaginationService, taskListSortService, taskListSearchService, taskListQueryParamService, pageTitleService, sseService, teamsApiService) {
2005
+ this.configService = configService;
2006
+ this.documentService = documentService;
2007
+ this.permissionService = permissionService;
2008
+ this.router = router;
2009
+ this.taskService = taskService;
2010
+ this.taskListService = taskListService;
2011
+ this.translateService = translateService;
2012
+ this.taskListColumnService = taskListColumnService;
2013
+ this.taskListPaginationService = taskListPaginationService;
2014
+ this.taskListSortService = taskListSortService;
2015
+ this.taskListSearchService = taskListSearchService;
2016
+ this.taskListQueryParamService = taskListQueryParamService;
2017
+ this.pageTitleService = pageTitleService;
2018
+ this.sseService = sseService;
2019
+ this.teamsApiService = teamsApiService;
2020
+ this.ALL_CASES_ID = this.taskListService.ALL_CASES_ID;
2021
+ this.selectedTaskType$ = this.taskListService.selectedTaskType$;
2022
+ this._overrideNoResultsMessage$ = new BehaviorSubject(null);
2023
+ this.noResultsMessage$ = combineLatest([
2024
+ this.selectedTaskType$,
2025
+ this._overrideNoResultsMessage$,
2026
+ ]).pipe(map(([selectedTaskType, overrideNoResultsMessage]) => overrideNoResultsMessage || {
2027
+ title: 'task-list.' + selectedTaskType + '.noResultsTitle',
2028
+ description: 'task-list.' + selectedTaskType + '.noResultsDescription',
2029
+ isSearchResult: false,
2030
+ }));
2031
+ this.fields$ = this.taskListColumnService.fields$.pipe(map((fields) => [
2032
+ {
2033
+ key: 'isOpened',
2034
+ label: '',
2035
+ viewType: ViewType.TEMPLATE,
2036
+ template: this._unreadIndicator,
2037
+ className: 'valtimo-task-list__unread-column',
2038
+ },
2039
+ ...fields,
2040
+ ]));
2041
+ this.loadingTasks$ = new BehaviorSubject(true);
2042
+ this.visibleTabs$ = new BehaviorSubject(null);
2043
+ this._enableLoadingAnimation$ = new BehaviorSubject(true);
2044
+ this.cachedTasks$ = new BehaviorSubject(null);
2045
+ this.paginationForCurrentTaskTypeForList$ = this.taskListPaginationService.paginationForCurrentTaskTypeForList$;
2046
+ this.sortStateForCurrentTaskType$ = this.taskListSortService.sortStateForCurrentTaskType$;
2047
+ this.overrideSortState$ = this.taskListSortService.overrideSortState$;
2048
+ this._reload$ = new BehaviorSubject(true);
2049
+ this.caseDefinitionKey$ = this.taskListService.caseDefinitionKey$;
2050
+ this.tasks$ = combineLatest([
2051
+ this.taskListService.loadingStateForCaseDefinition$,
2052
+ this.selectedTaskType$,
2053
+ this.taskListPaginationService.paginationForCurrentTaskType$,
2054
+ this.taskListSortService.sortStringForCurrentTaskType$,
2055
+ this.caseDefinitionKey$,
2056
+ this._enableLoadingAnimation$,
2057
+ this._reload$,
2058
+ this.taskListSearchService.otherFilters$,
2059
+ this.taskListSortService.overrideSortStateString$,
2060
+ ]).pipe(filter$1(([loadingStateForCaseDefinition]) => loadingStateForCaseDefinition === false), map(([_, selectedTaskType, paginationForSelectedTaskType, sortStringForSelectedTaskType, caseDefinitionKey, enableLoadingAnimation, reload, otherFilters, overrideSortStateString,]) => this.getTaskListParams(paginationForSelectedTaskType, overrideSortStateString || sortStringForSelectedTaskType, selectedTaskType, caseDefinitionKey, enableLoadingAnimation, reload, otherFilters)), distinctUntilChanged$1((previous, current) => isEqual(previous.params, current.params)), tap(params => {
2061
+ if (params.enableLoadingAnimation)
2062
+ this.loadingTasks$.next(true);
2063
+ this.taskListQueryParamService.setTaskListParams(params.params);
2064
+ }), switchMap(({ params }) => combineLatest([
2065
+ this.taskService.queryTasksPageV3(params.selectedTaskType, params.params, params.caseDefinitionKey, params.otherFilters),
2066
+ of(!!params.caseDefinitionKey),
2067
+ ])), switchMap(([tasksResult, isSpecified]) => this.getTaskListPermissionsRequest(tasksResult, isSpecified)), map(([isSpecified, taskResult, canViewTaskPermissions, canViewCasePermissions]) => {
2068
+ this.updateTaskListPaginationAfterResponse(Number(taskResult.totalElements));
2069
+ return this.mapTasksForList(isSpecified, taskResult, canViewTaskPermissions, canViewCasePermissions);
2070
+ }), tap(tasks => {
2071
+ this.cachedTasks$.next(tasks);
2072
+ this.loadingTasks$.next(false);
2073
+ this.disableLoadingAnimation();
2074
+ this.taskListSearchService.otherFilters$.pipe(take(1)).subscribe(otherFilters => {
2075
+ this._overrideNoResultsMessage$.next(otherFilters?.length > 0 ? TASK_LIST_NO_SEARCH_RESULTS_MESSAGE : null);
2076
+ });
2077
+ }));
2078
+ this.loadingCaseListItems$ = new BehaviorSubject(true);
2079
+ this._selectedCaseDefinitionId$ = new BehaviorSubject(this.ALL_CASES_ID);
2080
+ this.caseListItems$ = combineLatest([
2081
+ this.documentService.getAllDefinitions(),
2082
+ this._selectedCaseDefinitionId$,
2083
+ this.translateService.stream('key'),
2084
+ ]).pipe(map(([documentDefinitionRes, selectedCaseDefinitionId]) => [
2085
+ {
2086
+ content: this.translateService.instant('task-list.allCases'),
2087
+ id: this.ALL_CASES_ID,
2088
+ selected: selectedCaseDefinitionId === this.ALL_CASES_ID,
2089
+ },
2090
+ ...documentDefinitionRes.content.map(documentDefinition => ({
2091
+ id: documentDefinition.id.name,
2092
+ content: documentDefinition?.schema?.title,
2093
+ selected: documentDefinition.id.name === selectedCaseDefinitionId,
2094
+ })),
2095
+ ]), tap(() => this.loadingCaseListItems$.next(false)));
2096
+ this.taskListColumnsForCase$ = this.taskListColumnService.taskListColumnsForCase$;
2097
+ this.loadingSearchFields$ = this.taskListSearchService.loadingSearchFields$;
2098
+ this.searchFields$ = this.taskListSearchService.searchFields$;
2099
+ this._DEFAULT_TASK_LIST_TABS = [
2100
+ TaskListTab.MINE,
2101
+ TaskListTab.TEAM,
2102
+ TaskListTab.OPEN,
2103
+ TaskListTab.ALL,
2104
+ ];
2105
+ this.setSearchFieldValuesSubject$ = new BehaviorSubject({});
2106
+ this.clearSearchFieldValuesSubject$ = new Subject();
2107
+ this._subscriptions = new Subscription();
2108
+ }
2109
+ ngOnInit() {
2110
+ this.taskListColumnService.resetTaskListFields();
2111
+ this.setVisibleTabs();
2112
+ this.pageTitleService.disableReset();
2113
+ this.setParamsFromQueryParams();
2114
+ this.openTaskUpdateSseEventSubscription();
2115
+ }
2116
+ openTaskUpdateSseEventSubscription() {
2117
+ this._subscriptions.add(combineLatest([
2118
+ this.sseService.getSseEventObservable('TASK_UPDATE'),
2119
+ this.caseDefinitionKey$,
2120
+ ])
2121
+ .pipe(filter$1(([event, caseDefinitionKey]) => caseDefinitionKey === null || event.caseDefinitionKey === caseDefinitionKey))
2122
+ .subscribe(() => this.reload()));
2123
+ }
2124
+ ngOnDestroy() {
2125
+ this.pageTitleService.enableReset();
2126
+ this._subscriptions.unsubscribe();
2127
+ }
2128
+ paginationClicked(page, type) {
2129
+ this.taskListPaginationService.updateTaskPagination(type, { page: page - 1 });
2130
+ }
2131
+ paginationSet(newSize) {
2132
+ combineLatest([
2133
+ this.taskListPaginationService.paginationForCurrentTaskType$,
2134
+ this.taskListService.selectedTaskType$,
2135
+ ])
2136
+ .pipe(take(1))
2137
+ .subscribe(([pagination, selectedTaskType]) => {
2138
+ this.taskListPaginationService.updateTaskPagination(selectedTaskType, {
2139
+ size: Number(newSize),
2140
+ page: this.taskListPaginationService.getLastAvailablePage(pagination.page, Number(newSize), pagination.collectionSize),
2141
+ });
2142
+ });
2143
+ }
2144
+ tabChange(tab) {
2145
+ this.taskListService.selectedTaskType$.pipe(take(1)).subscribe(selectedTaskType => {
2146
+ if (selectedTaskType !== tab) {
2147
+ this.enableLoadingAnimation();
2148
+ this.taskListService.setSelectedTaskType(tab);
2149
+ this.taskListPaginationService.updateTaskPagination(tab, { page: 0 });
2150
+ }
2151
+ });
2152
+ }
2153
+ openRelatedCase(event, index) {
2154
+ event.stopPropagation();
2155
+ this.cachedTasks$.pipe(take(1)).subscribe(cachedTasks => {
2156
+ const currentTask = cachedTasks && cachedTasks[index];
2157
+ if (currentTask && !currentTask.caseLocked) {
2158
+ const caseDocId = currentTask.caseDocumentId || currentTask.businessKey;
2159
+ this.documentService
2160
+ .getDocument(caseDocId)
2161
+ .pipe(take(1))
2162
+ .subscribe(document => {
2163
+ this.router.navigate([`/cases/${document.definitionId?.name}/document/${caseDocId}`]);
2164
+ });
2165
+ }
2166
+ });
2167
+ }
2168
+ rowOpenTaskClick(task) {
2169
+ return !task.endTime && !task.locked ? this._taskDetail.openTaskDetails(task) : false;
2170
+ }
2171
+ sortChanged(sortState) {
2172
+ this.taskListSortService.setOverrideSortState(sortState);
2173
+ this.taskListSortService.updateSortState(this.taskListService.selectedTaskType, sortState);
2174
+ }
2175
+ setCaseDefinition(definition) {
2176
+ if (definition.item.id && definition.item.id !== this.taskListService.caseDefinitionKey) {
2177
+ this.taskListSortService.resetOverrideSortState();
2178
+ this.loadingTasks$.next(true);
2179
+ this.taskListService.setCaseDefinitionKey(definition.item.id);
2180
+ }
2181
+ }
2182
+ reload() {
2183
+ this.enableLoadingAnimation();
2184
+ this._reload$.next(!this._reload$.getValue());
2185
+ }
2186
+ search(searchFieldValues) {
2187
+ if (!searchFieldValues)
2188
+ return;
2189
+ this.taskListSearchService.setSearchFieldValues(searchFieldValues);
2190
+ }
2191
+ updateTaskListPaginationAfterResponse(newCollectionSize) {
2192
+ this.taskListPaginationService.paginationForCurrentTaskType$
2193
+ .pipe(take(1))
2194
+ .subscribe(currentPagination => {
2195
+ this.taskListPaginationService.updateTaskPagination(this.taskListService.selectedTaskType, {
2196
+ collectionSize: Number(newCollectionSize),
2197
+ page: this.taskListPaginationService.getLastAvailablePage(currentPagination.page, currentPagination.size, newCollectionSize),
2198
+ });
2199
+ });
2200
+ }
2201
+ setVisibleTabs() {
2202
+ const configuredTabs = this.configService.config?.visibleTaskListTabs || this._DEFAULT_TASK_LIST_TABS;
2203
+ this.teamsApiService.getCurrentUserTeams().subscribe(teams => {
2204
+ const tabs = teams.length > 0
2205
+ ? configuredTabs
2206
+ : configuredTabs.filter(tab => tab !== TaskListTab.TEAM);
2207
+ this.visibleTabs$.next(tabs);
2208
+ this.taskListService.setSelectedTaskType(tabs[0]);
2209
+ });
2210
+ }
2211
+ disableLoadingAnimation() {
2212
+ this._enableLoadingAnimation$.next(false);
2213
+ }
2214
+ enableLoadingAnimation() {
2215
+ this._enableLoadingAnimation$.next(true);
2216
+ }
2217
+ getTaskListParams(paginationForSelectedTaskType, sortStringForSelectedTaskType, selectedTaskType, caseDefinitionKey, enableLoadingAnimation, reload, otherFilters) {
2218
+ const params = {
2219
+ ...paginationForSelectedTaskType,
2220
+ ...(sortStringForSelectedTaskType && { sort: sortStringForSelectedTaskType }),
2221
+ };
2222
+ delete params.collectionSize;
2223
+ return {
2224
+ params: {
2225
+ reload,
2226
+ selectedTaskType,
2227
+ params,
2228
+ ...(caseDefinitionKey &&
2229
+ caseDefinitionKey !== this.ALL_CASES_ID && { caseDefinitionKey: caseDefinitionKey }),
2230
+ ...(otherFilters && { otherFilters }),
2231
+ },
2232
+ enableLoadingAnimation,
2233
+ };
2234
+ }
2235
+ getTaskListPermissionsRequest(tasksResult, isSpecified) {
2236
+ const taskResults = tasksResult.content;
2237
+ const hasTaskResults = Array.isArray(taskResults) && taskResults.length > 0;
2238
+ return combineLatest([
2239
+ of(isSpecified),
2240
+ of(tasksResult),
2241
+ hasTaskResults
2242
+ ? combineLatest(taskResults.map(task => this.permissionService.requestPermission(CAN_VIEW_TASK_PERMISSION, {
2243
+ resource: TASK_DETAIL_PERMISSION_RESOURCE.task,
2244
+ identifier: !isSpecified ? task.id : task.id,
2245
+ })))
2246
+ : of(null),
2247
+ hasTaskResults
2248
+ ? combineLatest(taskResults.map(task => this.permissionService.requestPermission(CAN_VIEW_CASE_PERMISSION, {
2249
+ resource: TASK_DETAIL_PERMISSION_RESOURCE.jsonSchemaDocument,
2250
+ identifier: task.caseDocumentId || task.businessKey,
2251
+ })))
2252
+ : of(null),
2253
+ ]);
2254
+ }
2255
+ mapTasksForList(isSpecified, tasks, canViewTaskPermissions, canViewCasePermissions) {
2256
+ const MOMENT_FORMAT = 'DD MMM YYYY HH:mm';
2257
+ if (isSpecified) {
2258
+ return tasks.content.map((specifiedTask, specifiedTaskIndex) => specifiedTask.items.reduce((acc, curr) => ({
2259
+ id: specifiedTask.id,
2260
+ businessKey: specifiedTask.businessKey,
2261
+ caseDocumentId: specifiedTask.caseDocumentId,
2262
+ processInstanceId: specifiedTask.processInstanceId,
2263
+ name: specifiedTask.name,
2264
+ isOpened: specifiedTask.isOpened,
2265
+ ...(moment(specifiedTask.created).isValid() && {
2266
+ created: moment(specifiedTask.created).format(MOMENT_FORMAT),
2267
+ }),
2268
+ ...(canViewTaskPermissions && { locked: !canViewTaskPermissions[specifiedTaskIndex] }),
2269
+ ...(canViewCasePermissions && {
2270
+ caseLocked: !canViewCasePermissions[specifiedTaskIndex],
2271
+ }),
2272
+ ...acc,
2273
+ [curr.key]: curr.value,
2274
+ }), {}));
2275
+ }
2276
+ return tasks?.content?.map((task, taskIndex) => {
2277
+ const createdDate = moment(task.created);
2278
+ const dueDate = moment(task.due);
2279
+ const taskCopy = { ...task };
2280
+ if (task.due && dueDate.isValid())
2281
+ taskCopy.due = dueDate.format(MOMENT_FORMAT);
2282
+ if (createdDate.isValid())
2283
+ taskCopy.created = createdDate.format(MOMENT_FORMAT);
2284
+ if (canViewTaskPermissions)
2285
+ taskCopy.locked = !canViewTaskPermissions[taskIndex];
2286
+ if (canViewCasePermissions)
2287
+ taskCopy.caseLocked = !canViewCasePermissions[taskIndex];
2288
+ return taskCopy;
2289
+ });
2290
+ }
2291
+ setParamsFromQueryParams() {
2292
+ const decodedParams = this.taskListQueryParamService.getTaskListQueryParams();
2293
+ if (decodedParams.caseDefinitionKey) {
2294
+ this.taskListService.setCaseDefinitionKey(decodedParams.caseDefinitionKey);
2295
+ this._selectedCaseDefinitionId$.next(decodedParams.caseDefinitionKey);
2296
+ }
2297
+ if (decodedParams.otherFilters?.length > 0) {
2298
+ const searchFieldValues = this.taskListSearchService.mapOtherFilterToSearchValues(decodedParams.otherFilters);
2299
+ this.setSearchFieldValuesSubject$.next(searchFieldValues);
2300
+ }
2301
+ else {
2302
+ this.clearSearchFieldValuesSubject$.next(null);
2303
+ }
2304
+ if (decodedParams.selectedTaskType)
2305
+ this.taskListService.setSelectedTaskType(decodedParams.selectedTaskType);
2306
+ if (decodedParams.params?.sort) {
2307
+ const stateFromSortString = this.taskListSortService.getSortStateFromSortString(decodedParams.params.sort);
2308
+ if (stateFromSortString)
2309
+ this.taskListSortService.setOverrideSortState(stateFromSortString);
2310
+ }
2311
+ if (decodedParams.params)
2312
+ this.taskListPaginationService.updateTaskPagination(this.taskListService.selectedTaskType, decodedParams.params);
2313
+ }
2314
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListComponent, deps: [{ token: i1$1.ConfigService }, { token: i2.DocumentService }, { token: i3.PermissionService }, { token: i1$2.Router }, { token: TaskService }, { token: TaskListService }, { token: i4$1.TranslateService }, { token: TaskListColumnService }, { token: TaskListPaginationService }, { token: TaskListSortService }, { token: TaskListSearchService }, { token: TaskListQueryParamService }, { token: i9.PageTitleService }, { token: i6$1.SseService }, { token: i11.TeamsApiService }], target: i0.ɵɵFactoryTarget.Component }); }
2315
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: TaskListComponent, isStandalone: false, selector: "valtimo-task-list", host: { listeners: { "window:popstate": "onPopState($event)" } }, providers: [
2316
+ TaskListService,
2317
+ TaskListColumnService,
2318
+ TaskListPaginationService,
2319
+ TaskListSortService,
2320
+ TaskListSearchService,
2321
+ TaskListQueryParamService,
2322
+ ], 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 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\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 paginationIdentifier=\"taskList\"\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 <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 [searchFields]=\"obs.searchFields\"\n [inputDisabled]=\"obs.loadingSearchFields\"\n [caseDefinitionKey]=\"obs.caseDefinitionKey\"\n [setValuesSubject$]=\"setSearchFieldValuesSubject$\"\n [clearValuesSubject$]=\"clearSearchFieldValuesSubject$\"\n (doSearch)=\"search($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: 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 }); }
2323
+ }
2324
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskListComponent, decorators: [{
2325
+ type: Component,
2326
+ args: [{ standalone: false, selector: 'valtimo-task-list', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
2327
+ TaskListService,
2328
+ TaskListColumnService,
2329
+ TaskListPaginationService,
2330
+ TaskListSortService,
2331
+ TaskListSearchService,
2332
+ TaskListQueryParamService,
2333
+ ], 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 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\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 paginationIdentifier=\"taskList\"\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 <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 [searchFields]=\"obs.searchFields\"\n [inputDisabled]=\"obs.loadingSearchFields\"\n [caseDefinitionKey]=\"obs.caseDefinitionKey\"\n [setValuesSubject$]=\"setSearchFieldValuesSubject$\"\n [clearValuesSubject$]=\"clearSearchFieldValuesSubject$\"\n (doSearch)=\"search($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"] }]
2334
+ }], ctorParameters: () => [{ type: i1$1.ConfigService }, { type: i2.DocumentService }, { type: i3.PermissionService }, { type: i1$2.Router }, { type: TaskService }, { type: TaskListService }, { type: i4$1.TranslateService }, { type: TaskListColumnService }, { type: TaskListPaginationService }, { type: TaskListSortService }, { type: TaskListSearchService }, { type: TaskListQueryParamService }, { type: i9.PageTitleService }, { type: i6$1.SseService }, { type: i11.TeamsApiService }], propDecorators: { _taskDetail: [{
2335
+ type: ViewChild,
2336
+ args: ['taskDetail']
2337
+ }], _unreadIndicator: [{
2338
+ type: ViewChild,
2339
+ args: ['unreadIndicator', { static: true }]
2340
+ }], onPopState: [{
2341
+ type: HostListener,
2342
+ args: ['window:popstate', ['$event']]
2343
+ }] } });
2344
+
2345
+ /*
2346
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
2347
+ *
2348
+ * Licensed under EUPL, Version 1.2 (the "License");
2349
+ * you may not use this file except in compliance with the License.
2350
+ * You may obtain a copy of the License at
2351
+ *
2352
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
2353
+ *
2354
+ * Unless required by applicable law or agreed to in writing, software
2355
+ * distributed under the License is distributed on an "AS IS" basis,
2356
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2357
+ * See the License for the specific language governing permissions and
2358
+ * limitations under the License.
2359
+ */
2360
+
2361
+ /*
2362
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
2363
+ *
2364
+ * Licensed under EUPL, Version 1.2 (the "License");
2365
+ * you may not use this file except in compliance with the License.
2366
+ * You may obtain a copy of the License at
2367
+ *
2368
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
2369
+ *
2370
+ * Unless required by applicable law or agreed to in writing, software
2371
+ * distributed under the License is distributed on an "AS IS" basis,
2372
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2373
+ * See the License for the specific language governing permissions and
2374
+ * limitations under the License.
2375
+ */
2376
+
2377
+ /*
2378
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
2379
+ *
2380
+ * Licensed under EUPL, Version 1.2 (the "License");
2381
+ * you may not use this file except in compliance with the License.
2382
+ * You may obtain a copy of the License at
2383
+ *
2384
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
2385
+ *
2386
+ * Unless required by applicable law or agreed to in writing, software
2387
+ * distributed under the License is distributed on an "AS IS" basis,
2388
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2389
+ * See the License for the specific language governing permissions and
2390
+ * limitations under the License.
2391
+ */
2392
+ var TaskListColumnDefaultSort;
2393
+ (function (TaskListColumnDefaultSort) {
2394
+ TaskListColumnDefaultSort["ASC"] = "ASC";
2395
+ TaskListColumnDefaultSort["DESC"] = "DESC";
2396
+ })(TaskListColumnDefaultSort || (TaskListColumnDefaultSort = {}));
2397
+
2398
+ /*
2399
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
2400
+ *
2401
+ * Licensed under EUPL, Version 1.2 (the "License");
2402
+ * you may not use this file except in compliance with the License.
2403
+ * You may obtain a copy of the License at
2404
+ *
2405
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
2406
+ *
2407
+ * Unless required by applicable law or agreed to in writing, software
2408
+ * distributed under the License is distributed on an "AS IS" basis,
2409
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2410
+ * See the License for the specific language governing permissions and
2411
+ * limitations under the License.
2412
+ */
2413
+
2414
+ /*
2415
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
2416
+ *
2417
+ * Licensed under EUPL, Version 1.2 (the "License");
2418
+ * you may not use this file except in compliance with the License.
2419
+ * You may obtain a copy of the License at
2420
+ *
2421
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
2422
+ *
2423
+ * Unless required by applicable law or agreed to in writing, software
2424
+ * distributed under the License is distributed on an "AS IS" basis,
2425
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2426
+ * See the License for the specific language governing permissions and
2427
+ * limitations under the License.
2428
+ */
2429
+ var TaskListSearchFieldDataType;
2430
+ (function (TaskListSearchFieldDataType) {
2431
+ TaskListSearchFieldDataType["TEXT"] = "text";
2432
+ TaskListSearchFieldDataType["NUMBER"] = "number";
2433
+ TaskListSearchFieldDataType["DATE"] = "date";
2434
+ TaskListSearchFieldDataType["DATETIME"] = "datetime";
2435
+ TaskListSearchFieldDataType["TIME"] = "time";
2436
+ TaskListSearchFieldDataType["BOOLEAN"] = "boolean";
2437
+ })(TaskListSearchFieldDataType || (TaskListSearchFieldDataType = {}));
2438
+ var TaskListSearchFieldFieldType;
2439
+ (function (TaskListSearchFieldFieldType) {
2440
+ TaskListSearchFieldFieldType["SINGLE"] = "single";
2441
+ TaskListSearchFieldFieldType["RANGE"] = "range";
2442
+ TaskListSearchFieldFieldType["SINGLE_SELECT_DROPDOWN"] = "single_select_dropdown";
2443
+ TaskListSearchFieldFieldType["MULTI_SELECT_DROPDOWN"] = "multi_select_dropdown";
2444
+ })(TaskListSearchFieldFieldType || (TaskListSearchFieldFieldType = {}));
2445
+ var TaskListSearchFieldMatchType;
2446
+ (function (TaskListSearchFieldMatchType) {
2447
+ TaskListSearchFieldMatchType["LIKE"] = "like";
2448
+ TaskListSearchFieldMatchType["EXACT"] = "exact";
2449
+ })(TaskListSearchFieldMatchType || (TaskListSearchFieldMatchType = {}));
2450
+ var TaskListSearchDropdownDataProvider;
2451
+ (function (TaskListSearchDropdownDataProvider) {
2452
+ TaskListSearchDropdownDataProvider["DATABASE"] = "dropdownDatabaseDataProvider";
2453
+ TaskListSearchDropdownDataProvider["JSON"] = "dropdownJsonFileDataProvider";
2454
+ })(TaskListSearchDropdownDataProvider || (TaskListSearchDropdownDataProvider = {}));
2455
+
2456
+ /*
2457
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
2458
+ *
2459
+ * Licensed under EUPL, Version 1.2 (the "License");
2460
+ * you may not use this file except in compliance with the License.
2461
+ * You may obtain a copy of the License at
2462
+ *
2463
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
2464
+ *
2465
+ * Unless required by applicable law or agreed to in writing, software
2466
+ * distributed under the License is distributed on an "AS IS" basis,
2467
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2468
+ * See the License for the specific language governing permissions and
2469
+ * limitations under the License.
2470
+ */
2471
+
2472
+ /*
2473
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
2474
+ *
2475
+ * Licensed under EUPL, Version 1.2 (the "License");
2476
+ * you may not use this file except in compliance with the License.
2477
+ * You may obtain a copy of the License at
2478
+ *
2479
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
2480
+ *
2481
+ * Unless required by applicable law or agreed to in writing, software
2482
+ * distributed under the License is distributed on an "AS IS" basis,
2483
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2484
+ * See the License for the specific language governing permissions and
2485
+ * limitations under the License.
2486
+ */
2487
+
2488
+ /*
2489
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
2490
+ *
2491
+ * Licensed under EUPL, Version 1.2 (the "License");
2492
+ * you may not use this file except in compliance with the License.
2493
+ * You may obtain a copy of the License at
2494
+ *
2495
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
2496
+ *
2497
+ * Unless required by applicable law or agreed to in writing, software
2498
+ * distributed under the License is distributed on an "AS IS" basis,
2499
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2500
+ * See the License for the specific language governing permissions and
2501
+ * limitations under the License.
2502
+ */
2503
+ const routes = [
2504
+ {
2505
+ path: 'tasks',
2506
+ component: TaskListComponent,
2507
+ canActivate: [AuthGuardService],
2508
+ data: { title: 'Tasks', roles: [ROLE_USER] },
2509
+ },
2510
+ ];
2511
+ class TaskRoutingModule {
2512
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskRoutingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2513
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.20", ngImport: i0, type: TaskRoutingModule, imports: [CommonModule, i1$2.RouterModule], exports: [RouterModule] }); }
2514
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskRoutingModule, imports: [CommonModule, RouterModule.forChild(routes), RouterModule] }); }
2515
+ }
2516
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskRoutingModule, decorators: [{
2517
+ type: NgModule,
2518
+ args: [{
2519
+ declarations: [],
2520
+ imports: [CommonModule, RouterModule.forChild(routes)],
2521
+ exports: [RouterModule],
2522
+ }]
2523
+ }] });
2524
+
2525
+ /*
2526
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
2527
+ *
2528
+ * Licensed under EUPL, Version 1.2 (the "License");
2529
+ * you may not use this file except in compliance with the License.
2530
+ * You may obtain a copy of the License at
2531
+ *
2532
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
2533
+ *
2534
+ * Unless required by applicable law or agreed to in writing, software
2535
+ * distributed under the License is distributed on an "AS IS" basis,
2536
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2537
+ * See the License for the specific language governing permissions and
2538
+ * limitations under the License.
2539
+ */
2540
+ class TaskModule {
2541
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2542
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.20", ngImport: i0, type: TaskModule, declarations: [TaskListComponent, TaskDetailModalComponent], imports: [CommonModule,
2543
+ TaskRoutingModule,
2544
+ CarbonListModule,
2545
+ PageHeaderModule,
2546
+ WidgetModule,
2547
+ SpinnerModule,
2548
+ CamundaFormModule,
2549
+ BrowserAnimationsModule,
2550
+ FormsModule, i4$1.TranslateModule, NgbModule,
2551
+ FormIoModule,
2552
+ ModalModule,
2553
+ LinkModule,
2554
+ ProcessLinkModule,
2555
+ TabsModule,
2556
+ ContentSwitcherModule,
2557
+ RenderInPageHeaderDirective,
2558
+ DropdownModule,
2559
+ ButtonModule,
2560
+ IconModule,
2561
+ TooltipModule$1,
2562
+ TooltipModule,
2563
+ ConfirmationModalModule,
2564
+ SearchFieldsModule,
2565
+ AssignmentComponent,
2566
+ TaskDetailContentComponent,
2567
+ TaskDetailIntermediateSaveComponent,
2568
+ SetTaskDueDateComponent,
2569
+ ValtimoCdsModalDirective], exports: [TaskListComponent, TaskDetailModalComponent] }); }
2570
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskModule, imports: [CommonModule,
2571
+ TaskRoutingModule,
2572
+ CarbonListModule,
2573
+ PageHeaderModule,
2574
+ WidgetModule,
2575
+ SpinnerModule,
2576
+ CamundaFormModule,
2577
+ BrowserAnimationsModule,
2578
+ FormsModule,
2579
+ TranslateModule.forRoot({
2580
+ loader: {
2581
+ provide: TranslateLoader,
2582
+ useFactory: HttpLoaderFactory,
2583
+ deps: [HttpClient],
2584
+ },
2585
+ }),
2586
+ NgbModule,
2587
+ FormIoModule,
2588
+ ModalModule,
2589
+ LinkModule,
2590
+ ProcessLinkModule,
2591
+ TabsModule,
2592
+ ContentSwitcherModule,
2593
+ DropdownModule,
2594
+ ButtonModule,
2595
+ IconModule,
2596
+ TooltipModule$1,
2597
+ TooltipModule,
2598
+ ConfirmationModalModule,
2599
+ SearchFieldsModule,
2600
+ AssignmentComponent,
2601
+ TaskDetailContentComponent,
2602
+ TaskDetailIntermediateSaveComponent,
2603
+ SetTaskDueDateComponent] }); }
2604
+ }
2605
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TaskModule, decorators: [{
2606
+ type: NgModule,
2607
+ args: [{
2608
+ declarations: [TaskListComponent, TaskDetailModalComponent],
2609
+ imports: [
2610
+ CommonModule,
2611
+ TaskRoutingModule,
2612
+ CarbonListModule,
2613
+ PageHeaderModule,
2614
+ WidgetModule,
2615
+ SpinnerModule,
2616
+ CamundaFormModule,
2617
+ BrowserAnimationsModule,
2618
+ FormsModule,
2619
+ TranslateModule.forRoot({
2620
+ loader: {
2621
+ provide: TranslateLoader,
2622
+ useFactory: HttpLoaderFactory,
2623
+ deps: [HttpClient],
2624
+ },
2625
+ }),
2626
+ NgbModule,
2627
+ FormIoModule,
2628
+ ModalModule,
2629
+ LinkModule,
2630
+ ProcessLinkModule,
2631
+ TabsModule,
2632
+ ContentSwitcherModule,
2633
+ RenderInPageHeaderDirective,
2634
+ DropdownModule,
2635
+ ButtonModule,
2636
+ IconModule,
2637
+ TooltipModule$1,
2638
+ TooltipModule,
2639
+ ConfirmationModalModule,
2640
+ SearchFieldsModule,
2641
+ AssignmentComponent,
2642
+ TaskDetailContentComponent,
2643
+ TaskDetailIntermediateSaveComponent,
2644
+ SetTaskDueDateComponent,
2645
+ ValtimoCdsModalDirective,
2646
+ ],
2647
+ exports: [TaskListComponent, TaskDetailModalComponent],
2648
+ }]
2649
+ }] });
2650
+
2651
+ /*
2652
+ * Copyright 2015-2025 Ritense BV, the Netherlands.
2653
+ *
2654
+ * Licensed under EUPL, Version 1.2 (the "License");
2655
+ * you may not use this file except in compliance with the License.
2656
+ * You may obtain a copy of the License at
2657
+ *
2658
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
2659
+ *
2660
+ * Unless required by applicable law or agreed to in writing, software
2661
+ * distributed under the License is distributed on an "AS IS" basis,
2662
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2663
+ * See the License for the specific language governing permissions and
2664
+ * limitations under the License.
2665
+ */
2666
+ /*
2667
+ * Public API Surface of task
2668
+ */
2669
+
2670
+ /**
2671
+ * Generated bundle index. Do not edit.
2672
+ */
2673
+
2674
+ export { CAN_ASSIGN_TASK_PERMISSION, CAN_MODIFY_TASK_PERMISSION, CAN_VIEW_CASE_PERMISSION, CAN_VIEW_TASK_PERMISSION, SetTaskDueDateComponent, TASK_DETAIL_PERMISSION_RESOURCE, TASK_LIST_NO_SEARCH_RESULTS_MESSAGE, TaskDetailContentComponent, TaskDetailIntermediateSaveComponent, TaskDetailModalComponent, TaskIntermediateSaveService, TaskListColumnDefaultSort, TaskListColumnService, TaskListComponent, TaskListPaginationService, TaskListQueryParamService, TaskListSearchDropdownDataProvider, TaskListSearchFieldDataType, TaskListSearchFieldFieldType, TaskListSearchFieldMatchType, TaskListSearchService, TaskListService, TaskModule, TaskService };
2675
+ //# sourceMappingURL=valtimo-task.mjs.map