@valtimo/task 0.0.0

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