@yuuvis/bpm-management-app 1.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.
@@ -0,0 +1,2649 @@
1
+ import * as i1$2 from '@angular/common';
2
+ import { CommonModule, formatDate } from '@angular/common';
3
+ import * as i0 from '@angular/core';
4
+ import { inject, Component, Injectable, input, forwardRef, ViewChild, computed, signal, output, Pipe, effect } from '@angular/core';
5
+ import * as i1 from '@angular/router';
6
+ import { RouterModule } from '@angular/router';
7
+ import { TranslateService, TranslatePipe, BackendService, ApiBase, Utils, Logger, NotificationService } from '@yuuvis/client-core';
8
+ import { Title } from '@angular/platform-browser';
9
+ import * as i2 from '@angular/material/tabs';
10
+ import { MatTabsModule } from '@angular/material/tabs';
11
+ import * as i3$1 from '@angular/material/icon';
12
+ import { MatIconModule } from '@angular/material/icon';
13
+ import { ShellService } from '@yuuvis/client-shell-core';
14
+ import * as i6 from '@yuuvis/material/layout';
15
+ import { YmtLayoutModule } from '@yuuvis/material/layout';
16
+ import * as i7 from '@yuuvis/material/panes';
17
+ import { YmtPanesModule } from '@yuuvis/material/panes';
18
+ import * as i5$1 from '@yuuvis/client-shell';
19
+ import { YuvClientShellModule } from '@yuuvis/client-shell';
20
+ import * as i2$2 from '@angular/material/button';
21
+ import { MatButtonModule } from '@angular/material/button';
22
+ import * as i4 from '@angular/material/tooltip';
23
+ import { MatTooltipModule, MatTooltip } from '@angular/material/tooltip';
24
+ import * as i4$1 from '@angular/material/table';
25
+ import { MatTableModule } from '@angular/material/table';
26
+ import * as i5 from '@angular/material/paginator';
27
+ import { MatPaginatorModule } from '@angular/material/paginator';
28
+ import { MatSortModule } from '@angular/material/sort';
29
+ import { YuvMasterDetailsModule } from '@yuuvis/client-components/master-details';
30
+ import * as i6$1 from '@yuuvis/client-components/overflow-menu';
31
+ import { YuvOverflowMenuModule } from '@yuuvis/client-components/overflow-menu';
32
+ import { HttpParams } from '@angular/common/http';
33
+ import { map, startWith, pairwise, debounceTime, distinctUntilChanged, forkJoin, catchError, of } from 'rxjs';
34
+ import * as i1$4 from '@angular/material/checkbox';
35
+ import { MatCheckboxModule, MatCheckbox } from '@angular/material/checkbox';
36
+ import * as i3 from '@angular/material/input';
37
+ import { MatInputModule, MatLabel } from '@angular/material/input';
38
+ import * as i2$1 from '@angular/material/form-field';
39
+ import { MatFormFieldModule } from '@angular/material/form-field';
40
+ import * as i3$2 from '@angular/material/select';
41
+ import { MatSelectModule } from '@angular/material/select';
42
+ import { MatDatepickerModule } from '@angular/material/datepicker';
43
+ import { MatNativeDateModule } from '@angular/material/core';
44
+ import { MatMenuModule } from '@angular/material/menu';
45
+ import { MatDividerModule } from '@angular/material/divider';
46
+ import * as i1$1 from '@angular/forms';
47
+ import { FormGroup, FormControl, ReactiveFormsModule, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
48
+ import { DatepickerComponent } from '@yuuvis/client-components/datepicker';
49
+ import { MatProgressBar } from '@angular/material/progress-bar';
50
+ import { MatCardModule } from '@angular/material/card';
51
+ import * as i1$3 from '@angular/material/progress-spinner';
52
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
53
+ import { SelectionModel } from '@angular/cdk/collections';
54
+ import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogModule } from '@angular/material/dialog';
55
+ import { DialogComponent, ConfirmComponent } from '@yuuvis/client-components/common';
56
+ import { YmtButtonDirective } from '@yuuvis/material';
57
+ import { OrganizationComponent } from '@yuuvis/client-framework/forms';
58
+
59
+ const APP_ID = 'io.yuuvis.app.bpm-management';
60
+ const ProcessDefinitionScope = {
61
+ GLOBAL: { value: 'GLOBAL', label: 'yuv.app.bpm-management.processdefinitions.scope.global', icon: 'globe' },
62
+ TENANT: { value: 'TENANT', label: 'yuv.app.bpm-management.processdefinitions.scope.tenant', icon: 'tenant' }
63
+ };
64
+ const ProcessDefinitionStatus = {
65
+ ACTIVE: { value: 'ACTIVE', label: 'yuv.app.bpm-management.status.active' },
66
+ SUSPENDED: { value: 'SUSPENDED', label: 'yuv.app.bpm-management.status.suspended' }
67
+ };
68
+ const ProcessStatus = {
69
+ RUNNING: { value: 'RUNNING', label: 'yuv.app.bpm-management.status.running' },
70
+ SUSPENDED: { value: 'SUSPENDED', label: 'yuv.app.bpm-management.status.suspended' },
71
+ RUNNING_SUSPENDED: { value: 'RUNNING_SUSPENDED', label: 'yuv.app.bpm-management.status.runningORsuspended' },
72
+ COMPLETED: { value: 'COMPLETED', label: 'yuv.app.bpm-management.status.completed' }
73
+ };
74
+ const TaskStatus = {
75
+ RUNNING: { value: 'RUNNING', label: 'yuv.app.bpm-management.status.running' },
76
+ COMPLETED: { value: 'COMPLETED', label: 'yuv.app.bpm-management.status.completed' }
77
+ };
78
+ const APP_ICONS = {
79
+ assign: 'person_add',
80
+ cancel: 'cancel',
81
+ unassign: 'person_remove',
82
+ clearFilter: 'filter_alt_off',
83
+ dockToLeft: 'dock_to_left',
84
+ filterActive: 'filter_alt',
85
+ filterEquals: 'equal',
86
+ filterContains: 'find_in_page',
87
+ filterStartsWith: 'subdirectory_arrow_right',
88
+ filterEndsWith: 'subdirectory_arrow_left',
89
+ filterGreaterThan: 'arrow_upward',
90
+ filterLessThan: 'arrow_downward',
91
+ filterAfter: 'east',
92
+ filterBefore: 'west',
93
+ filterBetween: 'compare_arrows',
94
+ globe: 'public',
95
+ info: 'info',
96
+ refresh: 'refresh',
97
+ radioButtonChecked: 'radio_button_checked',
98
+ radioButtonUnchecked: 'radio_button_unchecked',
99
+ tenant: 'groups',
100
+ delegated: 'assignment',
101
+ resolved: 'order_approve',
102
+ activate: 'play_arrow',
103
+ suspend: 'pause'
104
+ };
105
+ const FILTER_OPERATORS = {
106
+ // Text operators
107
+ CONTAINS: { value: 'contains', label: 'yuv.app.bpm-management.filters.operators.contains', icon: 'filterContains' },
108
+ EQUALS: { value: 'equals', label: 'yuv.app.bpm-management.filters.operators.equals', icon: 'filterEquals' },
109
+ STARTS_WITH: { value: 'startsWith', label: 'yuv.app.bpm-management.filters.operators.startsWith', icon: 'filterStartsWith' },
110
+ ENDS_WITH: { value: 'endsWith', label: 'yuv.app.bpm-management.filters.operators.endsWith', icon: 'filterEndsWith' },
111
+ // Number operators
112
+ GREATER_THAN: { value: 'greaterThan', label: 'yuv.app.bpm-management.filters.operators.greaterThan', icon: 'filterGreaterThan' },
113
+ LESS_THAN: { value: 'lessThan', label: 'yuv.app.bpm-management.filters.operators.lessThan', icon: 'filterLessThan' },
114
+ // Date operators
115
+ BEFORE: { value: 'before', label: 'yuv.app.bpm-management.filters.operators.before', icon: 'filterBefore' },
116
+ AFTER: { value: 'after', label: 'yuv.app.bpm-management.filters.operators.after', icon: 'filterAfter' },
117
+ BETWEEN: { value: 'between', label: 'yuv.app.bpm-management.filters.operators.between', icon: 'filterBetween' }
118
+ };
119
+ const FILTER_TYPES = {
120
+ TEXT: 'text',
121
+ NUMBER: 'number',
122
+ DATE: 'date',
123
+ SELECT: 'select',
124
+ CHECKBOX: 'checkbox'
125
+ };
126
+ function formatDateTime(utcDateString, locale, type = 'datetime') {
127
+ if (!utcDateString)
128
+ return '';
129
+ try {
130
+ const date = new Date(utcDateString);
131
+ const formatOptions = {
132
+ datetime: {
133
+ year: 'numeric',
134
+ month: '2-digit',
135
+ day: '2-digit',
136
+ hour: '2-digit',
137
+ minute: '2-digit'
138
+ },
139
+ date: {
140
+ year: 'numeric',
141
+ month: '2-digit',
142
+ day: '2-digit'
143
+ },
144
+ time: {
145
+ hour: '2-digit',
146
+ minute: '2-digit'
147
+ }
148
+ };
149
+ return type === 'datetime'
150
+ ? date.toLocaleString(locale, formatOptions[type])
151
+ : type === 'date'
152
+ ? date.toLocaleDateString(locale, formatOptions[type])
153
+ : date.toLocaleTimeString(locale, formatOptions[type]);
154
+ }
155
+ catch (error) {
156
+ console.error('Error formatting date:', error);
157
+ return utcDateString;
158
+ }
159
+ }
160
+
161
+ class YuvBpmManagementComponent {
162
+ #shell = inject(ShellService);
163
+ #titleService = inject(Title);
164
+ #translateService = inject(TranslateService);
165
+ #app = this.#shell.getApp(APP_ID);
166
+ appName = this.#app?.title;
167
+ appIcon = this.#app?.iconName;
168
+ icons = {
169
+ ...APP_ICONS,
170
+ };
171
+ ngOnInit() {
172
+ // Browser-Tab-Titel lokalisiert setzen
173
+ const translatedTitle = this.appName.startsWith('yuv.')
174
+ ? this.#translateService.instant(this.appName)
175
+ : this.appName;
176
+ this.#titleService.setTitle(translatedTitle);
177
+ }
178
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvBpmManagementComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
179
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: YuvBpmManagementComponent, isStandalone: true, selector: "ymbpm-root", ngImport: i0, template: "<section class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n <nav mat-tab-nav-bar [tabPanel]=\"tabPanel\">\n <a mat-tab-link\n routerLink=\"deployments\"\n routerLinkActive\n #rla1=\"routerLinkActive\"\n [active]=\"rla1.isActive\">\n {{ 'yuv.app.bpm-management.tabs.deployments' | translate }}\n </a>\n <a mat-tab-link\n routerLink=\"processdefinitions\"\n routerLinkActive\n #rla2=\"routerLinkActive\"\n [active]=\"rla2.isActive\">\n {{ 'yuv.app.bpm-management.tabs.processdefinitions' | translate }}\n </a>\n <a mat-tab-link\n routerLink=\"processes\"\n routerLinkActive\n #rla3=\"routerLinkActive\"\n [active]=\"rla3.isActive\">\n {{ 'yuv.app.bpm-management.tabs.processes' | translate }}\n </a>\n <a mat-tab-link\n routerLink=\"tasks\"\n routerLinkActive\n #rla4=\"routerLinkActive\"\n [active]=\"rla4.isActive\">\n {{ 'yuv.app.bpm-management.tabs.tasks' | translate }}\n </a>\n </nav>\n <mat-tab-nav-panel #tabPanel>\n <router-outlet></router-outlet>\n </mat-tab-nav-panel>\n</section>\n\n<router-outlet name=\"modal\"></router-outlet>\n", styles: [":host{height:100%;overflow:hidden;display:flex;flex-flow:column}:host .bpmmgmt-main__content{flex:1;overflow-y:hidden;display:flex;flex-flow:column}:host .bpmmgmt-main__content nav[mat-tab-nav-bar]{flex:0 0 auto;padding-left:1rem;padding-right:1rem}:host .bpmmgmt-main__content mat-tab-nav-panel{flex:1;overflow:hidden;display:flex;flex-flow:column}:host .bpmmgmt-main__content mat-tab-nav-panel ::ng-deep>.mat-mdc-tab-body-wrapper{height:100%;display:flex;flex-flow:column}:host ::ng-deep span.yuv-bpmn-status{border-radius:var(--ymt-corner-s);font-family:monospace;padding:2px 4px}:host ::ng-deep span.yuv-bpmn-status.running{background-color:var(--ymt-primary);color:var(--ymt-on-primary)}:host ::ng-deep span.yuv-bpmn-status.completed{background-color:var(--ymt-success);color:var(--ymt-on-primary)}:host ::ng-deep span.yuv-bpmn-status.suspended{background-color:var(--ymt-danger);color:var(--ymt-on-primary)}:host ::ng-deep span.yuv-bpmn-status.delegated{background-color:var(--ymt-warning);color:var(--ymt-on-primary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2.MatTabNav, selector: "[mat-tab-nav-bar]", inputs: ["fitInkBarToContent", "mat-stretch-tabs", "animationDuration", "backgroundColor", "disableRipple", "color", "tabPanel"], exportAs: ["matTabNavBar", "matTabNav"] }, { kind: "component", type: i2.MatTabNavPanel, selector: "mat-tab-nav-panel", inputs: ["id"], exportAs: ["matTabNavPanel"] }, { kind: "component", type: i2.MatTabLink, selector: "[mat-tab-link], [matTabLink]", inputs: ["active", "disabled", "disableRipple", "tabIndex", "id"], exportAs: ["matTabLink"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: YmtLayoutModule }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
180
+ }
181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvBpmManagementComponent, decorators: [{
182
+ type: Component,
183
+ args: [{ selector: 'ymbpm-root', standalone: true, imports: [
184
+ CommonModule,
185
+ RouterModule,
186
+ TranslatePipe,
187
+ MatTabsModule,
188
+ MatIconModule,
189
+ YmtLayoutModule,
190
+ YmtPanesModule
191
+ ], template: "<section class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n <nav mat-tab-nav-bar [tabPanel]=\"tabPanel\">\n <a mat-tab-link\n routerLink=\"deployments\"\n routerLinkActive\n #rla1=\"routerLinkActive\"\n [active]=\"rla1.isActive\">\n {{ 'yuv.app.bpm-management.tabs.deployments' | translate }}\n </a>\n <a mat-tab-link\n routerLink=\"processdefinitions\"\n routerLinkActive\n #rla2=\"routerLinkActive\"\n [active]=\"rla2.isActive\">\n {{ 'yuv.app.bpm-management.tabs.processdefinitions' | translate }}\n </a>\n <a mat-tab-link\n routerLink=\"processes\"\n routerLinkActive\n #rla3=\"routerLinkActive\"\n [active]=\"rla3.isActive\">\n {{ 'yuv.app.bpm-management.tabs.processes' | translate }}\n </a>\n <a mat-tab-link\n routerLink=\"tasks\"\n routerLinkActive\n #rla4=\"routerLinkActive\"\n [active]=\"rla4.isActive\">\n {{ 'yuv.app.bpm-management.tabs.tasks' | translate }}\n </a>\n </nav>\n <mat-tab-nav-panel #tabPanel>\n <router-outlet></router-outlet>\n </mat-tab-nav-panel>\n</section>\n\n<router-outlet name=\"modal\"></router-outlet>\n", styles: [":host{height:100%;overflow:hidden;display:flex;flex-flow:column}:host .bpmmgmt-main__content{flex:1;overflow-y:hidden;display:flex;flex-flow:column}:host .bpmmgmt-main__content nav[mat-tab-nav-bar]{flex:0 0 auto;padding-left:1rem;padding-right:1rem}:host .bpmmgmt-main__content mat-tab-nav-panel{flex:1;overflow:hidden;display:flex;flex-flow:column}:host .bpmmgmt-main__content mat-tab-nav-panel ::ng-deep>.mat-mdc-tab-body-wrapper{height:100%;display:flex;flex-flow:column}:host ::ng-deep span.yuv-bpmn-status{border-radius:var(--ymt-corner-s);font-family:monospace;padding:2px 4px}:host ::ng-deep span.yuv-bpmn-status.running{background-color:var(--ymt-primary);color:var(--ymt-on-primary)}:host ::ng-deep span.yuv-bpmn-status.completed{background-color:var(--ymt-success);color:var(--ymt-on-primary)}:host ::ng-deep span.yuv-bpmn-status.suspended{background-color:var(--ymt-danger);color:var(--ymt-on-primary)}:host ::ng-deep span.yuv-bpmn-status.delegated{background-color:var(--ymt-warning);color:var(--ymt-on-primary)}\n"] }]
192
+ }] });
193
+
194
+ /**
195
+ * Base class for BPM filter conversion with shared logic
196
+ */
197
+ class BaseBpmFilter {
198
+ /**
199
+ * Converts AG Grid filter model to BPM filter format
200
+ * @param tableFilters - The AG Grid table filters
201
+ * @param ts - Optional TranslateService for date formatting
202
+ * @returns The converted BPM filter instance
203
+ */
204
+ static convertFromAgFilterModel(filterInstance, tableFilters, ts) {
205
+ for (const columnFilter in tableFilters) {
206
+ const columnFilterData = tableFilters[columnFilter];
207
+ switch (columnFilterData['type']) {
208
+ case FILTER_TYPES.TEXT:
209
+ filterInstance[columnFilter] = this.handleTextFilter(columnFilterData);
210
+ break;
211
+ case FILTER_TYPES.NUMBER:
212
+ filterInstance[columnFilter] = { value: columnFilterData.value, type: FILTER_TYPES.NUMBER };
213
+ break;
214
+ case FILTER_TYPES.DATE:
215
+ this.handleDateFilter(filterInstance, columnFilter, columnFilterData, ts);
216
+ break;
217
+ case FILTER_TYPES.SELECT:
218
+ this.handleSelectFilter(filterInstance, columnFilter, columnFilterData);
219
+ break;
220
+ }
221
+ }
222
+ return filterInstance;
223
+ }
224
+ static handleTextFilter(columnFilterData) {
225
+ if (columnFilterData.operator === FILTER_OPERATORS.CONTAINS.value) {
226
+ return { value: '%' + columnFilterData.value + '%', type: FILTER_TYPES.TEXT };
227
+ }
228
+ else if (columnFilterData.operator === FILTER_OPERATORS.STARTS_WITH.value) {
229
+ return { value: columnFilterData.value + '%', type: FILTER_TYPES.TEXT };
230
+ }
231
+ else if (columnFilterData.operator === FILTER_OPERATORS.ENDS_WITH.value) {
232
+ return { value: '%' + columnFilterData.value, type: FILTER_TYPES.TEXT };
233
+ }
234
+ else {
235
+ return { value: columnFilterData.value, type: FILTER_TYPES.TEXT };
236
+ }
237
+ }
238
+ static handleDateFilter(filterInstance, columnFilter, columnFilterData, ts) {
239
+ if (!ts)
240
+ return;
241
+ if (columnFilterData.operator === FILTER_OPERATORS.BETWEEN.value) {
242
+ if (columnFilterData.value !== null && columnFilterData.value instanceof Date) {
243
+ const formattedStartDate = formatDate(columnFilterData.value, 'yyyy-MM-ddTHH:mm:ss', ts.currentLang, 'UTC');
244
+ filterInstance[columnFilter + 'After'] = { value: formattedStartDate, type: FILTER_TYPES.DATE };
245
+ }
246
+ if (columnFilterData.endDate !== null && columnFilterData.endDate instanceof Date) {
247
+ const formattedEndDate = formatDate(columnFilterData.endDate, 'yyyy-MM-ddTHH:mm:ss', ts.currentLang, 'UTC');
248
+ filterInstance[columnFilter + 'Before'] = { value: formattedEndDate, type: FILTER_TYPES.DATE };
249
+ }
250
+ }
251
+ else if (columnFilterData.operator === FILTER_OPERATORS.AFTER.value) {
252
+ if (columnFilterData.value !== null && columnFilterData.value instanceof Date) {
253
+ const formattedDate = formatDate(columnFilterData.value, 'yyyy-MM-ddTHH:mm:ss', ts.currentLang, 'UTC');
254
+ filterInstance[columnFilter + 'After'] = { value: formattedDate, type: FILTER_TYPES.DATE };
255
+ }
256
+ }
257
+ else if (columnFilterData.operator === FILTER_OPERATORS.BEFORE.value) {
258
+ if (columnFilterData.value !== null && columnFilterData.value instanceof Date) {
259
+ const formattedDate = formatDate(columnFilterData.value, 'yyyy-MM-ddTHH:mm:ss', ts.currentLang, 'UTC');
260
+ filterInstance[columnFilter + 'Before'] = { value: formattedDate, type: FILTER_TYPES.DATE };
261
+ }
262
+ }
263
+ }
264
+ static handleSelectFilter(_filterInstance, _columnFilter, _columnFilterData) {
265
+ return;
266
+ }
267
+ }
268
+ class DeploymentFilter extends BaseBpmFilter {
269
+ static bpmFilterToRestApiName = {
270
+ id: 'id',
271
+ name: 'nameLike',
272
+ category: 'category'
273
+ };
274
+ id;
275
+ name;
276
+ category;
277
+ static fromAgFilterModel(tableFilters) {
278
+ return this.convertFromAgFilterModel(new DeploymentFilter(), tableFilters);
279
+ }
280
+ }
281
+ class ProcessDefinitionFilter extends BaseBpmFilter {
282
+ static bpmFilterToRestApiName = {
283
+ id: 'id',
284
+ deploymentId: 'deploymentId',
285
+ name: 'nameLikeIgnoreCase',
286
+ category: 'categoryLike',
287
+ version: 'version',
288
+ key: 'keyLike',
289
+ status: 'suspended',
290
+ global: 'global',
291
+ latest: 'latest'
292
+ };
293
+ id;
294
+ deploymentId;
295
+ name;
296
+ category;
297
+ version;
298
+ key;
299
+ status;
300
+ global;
301
+ latest;
302
+ static fromAgFilterModel(tableFilters) {
303
+ return this.convertFromAgFilterModel(new ProcessDefinitionFilter(), tableFilters);
304
+ }
305
+ static handleSelectFilter(filterInstance, columnFilter, columnFilterData) {
306
+ if (Array.isArray(columnFilterData.value)) {
307
+ // Not supported in current implementation
308
+ return;
309
+ }
310
+ const value = columnFilterData.value;
311
+ if (value === ProcessDefinitionStatus.ACTIVE.value || value === ProcessDefinitionScope.TENANT.value) {
312
+ filterInstance[columnFilter] = { value: 'false', type: FILTER_TYPES.SELECT };
313
+ }
314
+ else if (value === ProcessDefinitionStatus.SUSPENDED.value || value === ProcessDefinitionScope.GLOBAL.value) {
315
+ filterInstance[columnFilter] = { value: 'true', type: FILTER_TYPES.SELECT };
316
+ }
317
+ }
318
+ }
319
+ class ProcessFilter extends BaseBpmFilter {
320
+ static bpmFilterToRestApiName = {
321
+ id: 'processInstanceId',
322
+ processDefinitionId: 'processDefinitionId',
323
+ name: 'nameLikeIgnoreCase',
324
+ startUserId: 'startedBy',
325
+ businessKey: 'businessKeyLike',
326
+ startTimeBefore: 'startedBefore',
327
+ startTimeAfter: 'startedAfter',
328
+ endTimeBefore: 'finishedBefore',
329
+ endTimeAfter: 'finishedAfter',
330
+ status: 'isCompleted'
331
+ };
332
+ id;
333
+ processDefinitionId;
334
+ name;
335
+ startUserId;
336
+ startTimeBefore;
337
+ startTimeAfter;
338
+ endTimeBefore;
339
+ endTimeAfter;
340
+ businessKey;
341
+ status;
342
+ static fromAgFilterModel(tableFilters, ts) {
343
+ return this.convertFromAgFilterModel(new ProcessFilter(), tableFilters, ts);
344
+ }
345
+ static handleSelectFilter(filterInstance, columnFilter, columnFilterData) {
346
+ if (Array.isArray(columnFilterData.value)) {
347
+ // Not supported in current implementation
348
+ return;
349
+ }
350
+ const value = columnFilterData.value;
351
+ if (value === ProcessStatus.RUNNING_SUSPENDED.value) {
352
+ filterInstance[columnFilter] = { value: 'false', type: FILTER_TYPES.SELECT };
353
+ }
354
+ else if (value === ProcessStatus.COMPLETED.value) {
355
+ filterInstance[columnFilter] = { value: 'true', type: FILTER_TYPES.SELECT };
356
+ }
357
+ }
358
+ }
359
+ class TaskFilter extends BaseBpmFilter {
360
+ static bpmFilterToRestApiName = {
361
+ id: 'id',
362
+ name: 'nameLikeIgnoreCase',
363
+ status: 'isCompleted',
364
+ assignee: 'visibleTo',
365
+ owner: 'owner',
366
+ createTimeBefore: 'createdBefore',
367
+ createTimeAfter: 'createdAfter',
368
+ endTimeBefore: 'completedBefore',
369
+ endTimeAfter: 'completedAfter'
370
+ };
371
+ id;
372
+ name;
373
+ status;
374
+ assignee;
375
+ owner;
376
+ createTimeBefore;
377
+ createimeAfter;
378
+ endTimeBefore;
379
+ endTimeAfter;
380
+ static fromAgFilterModel(tableFilters, ts) {
381
+ return this.convertFromAgFilterModel(new TaskFilter(), tableFilters, ts);
382
+ }
383
+ static handleSelectFilter(filterInstance, columnFilter, columnFilterData) {
384
+ if (Array.isArray(columnFilterData.value)) {
385
+ // Not supported in current implementation
386
+ return;
387
+ }
388
+ const value = columnFilterData.value;
389
+ if (value === TaskStatus.RUNNING.value) {
390
+ filterInstance[columnFilter] = { value: 'false', type: FILTER_TYPES.SELECT };
391
+ }
392
+ else if (value === TaskStatus.COMPLETED.value) {
393
+ filterInstance[columnFilter] = { value: 'true', type: FILTER_TYPES.SELECT };
394
+ }
395
+ }
396
+ }
397
+
398
+ class YuvBpmAdminService {
399
+ static DEFAULT_PAGE_SIZE = 15;
400
+ bpmApiBase = '/bpm-engine/api';
401
+ #backendService = inject(BackendService);
402
+ getDeployments(page, size, filter) {
403
+ let filterParams = new HttpParams().set('page', page).set('size', size);
404
+ if (filter) {
405
+ for (const key in filter) {
406
+ filterParams = filterParams.set(DeploymentFilter.bpmFilterToRestApiName[key], filter[key]['value']);
407
+ }
408
+ }
409
+ return this.#backendService
410
+ .get(`${this.bpmApiBase}/deployments`, ApiBase.none, { params: filterParams });
411
+ }
412
+ getDeployment(deploymentId) {
413
+ return this.#backendService
414
+ .get(`${this.bpmApiBase}/deployments/${deploymentId}`, ApiBase.none);
415
+ }
416
+ getDeploymentResources(deploymentId) {
417
+ return this.#backendService
418
+ .get(`${this.bpmApiBase}/deployments/${deploymentId}/resources`, ApiBase.none);
419
+ }
420
+ getProcessDefinitions(page, size, filter) {
421
+ let filterParams = new HttpParams().set('page', page).set('size', size);
422
+ if (filter) {
423
+ for (const key in filter) {
424
+ filterParams = filterParams.set(ProcessDefinitionFilter.bpmFilterToRestApiName[key], filter[key]['value']);
425
+ }
426
+ }
427
+ return this.#backendService
428
+ .get(`${this.bpmApiBase}/process-definitions`, ApiBase.none, { params: filterParams });
429
+ }
430
+ getProcessDefinition(processDefinitionInstanceId) {
431
+ const params = new HttpParams().set('includeStatistics', true);
432
+ return this.#backendService.get(`${this.bpmApiBase}/process-definitions/${processDefinitionInstanceId}`, ApiBase.none, { params: params });
433
+ }
434
+ executeProcessDefinitionAction(processDefinitionInstanceId, action, includeProcesses) {
435
+ const body = {
436
+ 'action': action,
437
+ 'includeProcessInstances': includeProcesses
438
+ };
439
+ return this.#backendService
440
+ .patch(`${this.bpmApiBase}/process-definitions/${processDefinitionInstanceId}`, body, ApiBase.none)
441
+ .pipe(map(result => result));
442
+ }
443
+ getProcesses(page, size, filter) {
444
+ let filterParams = new HttpParams().set('page', page).set('size', size);
445
+ if (filter) {
446
+ for (const key in filter) {
447
+ filterParams = filterParams.set(ProcessFilter.bpmFilterToRestApiName[key], filter[key]['value']);
448
+ }
449
+ }
450
+ return this.#backendService.get(`${this.bpmApiBase}/processes`, ApiBase.none, { params: filterParams });
451
+ }
452
+ getProcess(processInstanceId) {
453
+ const params = new HttpParams().set('includeProcessVariables', true);
454
+ return this.#backendService.get(`${this.bpmApiBase}/processes/${processInstanceId}`, ApiBase.none, { params: params });
455
+ }
456
+ getProcessHistory(processInstanceId) {
457
+ return this.#backendService.get(`${this.bpmApiBase}/processes/${processInstanceId}/history`, ApiBase.none).pipe(map((result) => {
458
+ if (!result || !result.tasks)
459
+ return result;
460
+ return {
461
+ ...result,
462
+ tasks: result.tasks
463
+ .sort(Utils.sortValues('createTime'))
464
+ .reverse()
465
+ };
466
+ }));
467
+ }
468
+ getTasks(page, size, filter) {
469
+ let filterParams = new HttpParams().set('page', page).set('size', size);
470
+ if (filter) {
471
+ for (const key in filter) {
472
+ filterParams = filterParams.set(TaskFilter.bpmFilterToRestApiName[key], filter[key]['value']);
473
+ if (key === 'assignee') {
474
+ filterParams = filterParams.set('isAssigned', 'true');
475
+ }
476
+ }
477
+ }
478
+ return this.#backendService
479
+ .get(`${this.bpmApiBase}/tasks`, ApiBase.none, { params: filterParams });
480
+ }
481
+ getTask(taskId) {
482
+ const params = new HttpParams().set('includeIdentityLinks', true);
483
+ return this.#backendService.get(`${this.bpmApiBase}/tasks/${taskId}`, ApiBase.none, { params: params });
484
+ }
485
+ assignTask(taskId, assignee) {
486
+ const body = {
487
+ action: 'claim',
488
+ assignee: assignee
489
+ };
490
+ return this.#backendService.patch(`${this.bpmApiBase}/tasks/${taskId}`, body, ApiBase.none);
491
+ }
492
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvBpmAdminService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
493
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvBpmAdminService, providedIn: 'root' });
494
+ }
495
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvBpmAdminService, decorators: [{
496
+ type: Injectable,
497
+ args: [{
498
+ providedIn: 'root',
499
+ }]
500
+ }] });
501
+
502
+ class TextFilterComponent {
503
+ operators = input([FILTER_OPERATORS.EQUALS], ...(ngDevMode ? [{ debugName: "operators" }] : /* istanbul ignore next */ []));
504
+ tooltip;
505
+ filterForm = new FormGroup({
506
+ value: new FormControl(''),
507
+ operator: new FormControl(FILTER_OPERATORS.EQUALS.value)
508
+ });
509
+ icons = {
510
+ ...APP_ICONS,
511
+ };
512
+ get textControl() { return this.filterForm.get('value'); }
513
+ get operatorControl() { return this.filterForm.get('operator'); }
514
+ textInputSub = null;
515
+ lastTextValue = null;
516
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
517
+ onChange = () => { };
518
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
519
+ onTouched = () => { };
520
+ ngOnInit() {
521
+ this.operatorControl.setValue(this.operators()[0].value);
522
+ this.createTextInputSubscription();
523
+ this.operatorControl.valueChanges
524
+ .pipe(startWith(this.operators()[0].value), pairwise())
525
+ .subscribe(([prev, next]) => {
526
+ if (prev !== next) {
527
+ if (this.isActiveFilter()) {
528
+ this.fireOnChangeEvent();
529
+ }
530
+ }
531
+ });
532
+ }
533
+ onEnter() {
534
+ if (this.textControl.value === this.lastTextValue) {
535
+ return;
536
+ }
537
+ if (this.textInputSub) {
538
+ this.textInputSub.unsubscribe();
539
+ }
540
+ if (this.isActiveFilter()) {
541
+ this.fireOnChangeEvent();
542
+ }
543
+ else {
544
+ if (this.isActiveFilter(this.lastTextValue) && (this.textControl.value.toString().trim().length === 0)) {
545
+ this.clearFilter(true);
546
+ }
547
+ }
548
+ this.createTextInputSubscription();
549
+ }
550
+ createTextInputSubscription() {
551
+ this.textInputSub = this.textControl.valueChanges
552
+ .pipe(debounceTime(550), distinctUntilChanged(), startWith(null), pairwise())
553
+ .subscribe(([prev, next]) => {
554
+ if (this.isActiveFilter()) {
555
+ this.fireOnChangeEvent();
556
+ }
557
+ else if (next !== null && next !== undefined) {
558
+ if (this.isActiveFilter(prev) && (next.toString().trim().length === 0)) {
559
+ this.clearFilter(true);
560
+ }
561
+ }
562
+ });
563
+ }
564
+ isActiveFilter(value = this.textControl.value) {
565
+ return value && value.toString().trim().length > 0;
566
+ }
567
+ getCurrentOperatorOption() {
568
+ const operator = this.operatorControl.value;
569
+ return this.operators().find(op => op.value === operator) || null;
570
+ }
571
+ setOperator(operator) {
572
+ this.operatorControl.setValue(operator);
573
+ }
574
+ clearFilter(fireEvent = false) {
575
+ this.filterForm.reset({
576
+ value: null,
577
+ operator: this.operators()[0].value
578
+ }, { emitEvent: false });
579
+ if (fireEvent) {
580
+ this.fireOnChangeEvent();
581
+ }
582
+ }
583
+ toggleOperator() {
584
+ const currentOperator = this.operatorControl.value;
585
+ const currentIndex = this.operators().findIndex(op => op.value === currentOperator);
586
+ const nextIndex = (currentIndex + 1) % this.operators().length;
587
+ this.operatorControl.setValue(this.operators()[nextIndex].value);
588
+ if (this.tooltip) {
589
+ this.tooltip.hide();
590
+ setTimeout(() => {
591
+ this.tooltip?.show();
592
+ }, 0);
593
+ }
594
+ }
595
+ writeValue(value) {
596
+ if (value && value.type === FILTER_TYPES.TEXT) {
597
+ const operator = value.operator && this.operators().find(op => op.value === value.operator)
598
+ ? value.operator
599
+ : this.operators()[0].value;
600
+ this.filterForm.setValue({
601
+ value: value.value ? String(value.value) : '',
602
+ operator: operator
603
+ }, { emitEvent: false });
604
+ }
605
+ else {
606
+ this.clearFilter();
607
+ }
608
+ }
609
+ registerOnChange(fn) {
610
+ this.onChange = fn;
611
+ }
612
+ registerOnTouched(fn) {
613
+ this.onTouched = fn;
614
+ }
615
+ fireOnChangeEvent() {
616
+ this.lastTextValue = this.textControl.value;
617
+ this.onChange({
618
+ value: this.textControl.value,
619
+ operator: this.operatorControl.value,
620
+ type: FILTER_TYPES.TEXT
621
+ });
622
+ }
623
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: TextFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
624
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: TextFilterComponent, isStandalone: true, selector: "ymbpm-text-filter", inputs: { operators: { classPropertyName: "operators", publicName: "operators", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
625
+ {
626
+ provide: NG_VALUE_ACCESSOR,
627
+ useExisting: forwardRef(() => TextFilterComponent),
628
+ multi: true
629
+ }
630
+ ], viewQueries: [{ propertyName: "tooltip", first: true, predicate: MatTooltip, descendants: true }], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n @if (operators().length > 1) {\n <button mat-icon-button\n class=\"filter-options-btn\"\n (click)=\"toggleOperator()\"\n [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">\n <mat-icon>{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n </button>\n } @else {\n <mat-icon [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n }\n\n <mat-form-field appearance=\"outline\" class=\"filter-field\">\n <input matInput \n [placeholder]=\"('yuv.app.bpm-management.filters.search' | translate)\"\n [formControl]=\"textControl\"\n (keydown.enter)=\"onEnter()\">\n <mat-icon matSuffix>search</mat-icon>\n </mat-form-field>\n</div>", styles: [".filter-input-group{display:flex;align-items:center;gap:4px;width:100%;opacity:.6;transition:opacity .2s ease-in-out}.filter-input-group.active{opacity:1}.filter-field{flex:1}.filter-clear-btn{flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
631
+ }
632
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: TextFilterComponent, decorators: [{
633
+ type: Component,
634
+ args: [{ selector: 'ymbpm-text-filter', standalone: true, imports: [
635
+ CommonModule,
636
+ ReactiveFormsModule,
637
+ MatFormFieldModule,
638
+ MatInputModule,
639
+ MatIconModule,
640
+ MatButtonModule,
641
+ MatMenuModule,
642
+ MatDividerModule,
643
+ MatTooltipModule,
644
+ TranslatePipe
645
+ ], providers: [
646
+ {
647
+ provide: NG_VALUE_ACCESSOR,
648
+ useExisting: forwardRef(() => TextFilterComponent),
649
+ multi: true
650
+ }
651
+ ], template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n @if (operators().length > 1) {\n <button mat-icon-button\n class=\"filter-options-btn\"\n (click)=\"toggleOperator()\"\n [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">\n <mat-icon>{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n </button>\n } @else {\n <mat-icon [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n }\n\n <mat-form-field appearance=\"outline\" class=\"filter-field\">\n <input matInput \n [placeholder]=\"('yuv.app.bpm-management.filters.search' | translate)\"\n [formControl]=\"textControl\"\n (keydown.enter)=\"onEnter()\">\n <mat-icon matSuffix>search</mat-icon>\n </mat-form-field>\n</div>", styles: [".filter-input-group{display:flex;align-items:center;gap:4px;width:100%;opacity:.6;transition:opacity .2s ease-in-out}.filter-input-group.active{opacity:1}.filter-field{flex:1}.filter-clear-btn{flex-shrink:0}\n"] }]
652
+ }], propDecorators: { operators: [{ type: i0.Input, args: [{ isSignal: true, alias: "operators", required: false }] }], tooltip: [{
653
+ type: ViewChild,
654
+ args: [MatTooltip]
655
+ }] } });
656
+
657
+ class NumberFilterComponent {
658
+ operators = input([FILTER_OPERATORS.EQUALS], ...(ngDevMode ? [{ debugName: "operators" }] : /* istanbul ignore next */ []));
659
+ tooltip;
660
+ filterForm = new FormGroup({
661
+ value: new FormControl(null),
662
+ operator: new FormControl(FILTER_OPERATORS.EQUALS.value)
663
+ });
664
+ icons = {
665
+ ...APP_ICONS,
666
+ };
667
+ get numberControl() { return this.filterForm.get('value'); }
668
+ get operatorControl() { return this.filterForm.get('operator'); }
669
+ numberInputSub = null;
670
+ lastNumberValue = null;
671
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
672
+ onChange = () => { };
673
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
674
+ onTouched = () => { };
675
+ ngOnInit() {
676
+ this.operatorControl.setValue(this.operators()[0]);
677
+ this.createNumberInputSubscription();
678
+ this.operatorControl.valueChanges
679
+ .pipe(startWith(this.operators()[0]), pairwise())
680
+ .subscribe(([prev, next]) => {
681
+ if (prev !== next) {
682
+ if (this.isActiveFilter()) {
683
+ this.fireOnChangeEvent();
684
+ }
685
+ }
686
+ });
687
+ }
688
+ onEnter() {
689
+ if (this.numberControl.value === this.lastNumberValue) {
690
+ return;
691
+ }
692
+ if (this.numberInputSub) {
693
+ this.numberInputSub.unsubscribe();
694
+ }
695
+ this.fireOnChangeEvent();
696
+ this.createNumberInputSubscription();
697
+ }
698
+ createNumberInputSubscription() {
699
+ this.numberInputSub = this.numberControl.valueChanges
700
+ .pipe(debounceTime(300), distinctUntilChanged())
701
+ .subscribe(() => this.fireOnChangeEvent());
702
+ }
703
+ isActiveFilter() {
704
+ const value = this.numberControl.value;
705
+ return value !== null && value !== undefined && !isNaN(Number(value));
706
+ }
707
+ getCurrentOperatorOption() {
708
+ const operator = this.operatorControl.value;
709
+ return this.operators().find(op => op.value === operator) || null;
710
+ }
711
+ setOperator(operator) {
712
+ this.operatorControl.setValue(operator);
713
+ }
714
+ clearFilter(fireEvent = false) {
715
+ this.filterForm.reset({
716
+ value: null,
717
+ operator: this.operators()[0].value
718
+ }, { emitEvent: false });
719
+ if (fireEvent) {
720
+ this.fireOnChangeEvent();
721
+ }
722
+ }
723
+ toggleOperator() {
724
+ const currentOperator = this.operatorControl.value;
725
+ const currentIndex = this.operators().findIndex(op => op.value === currentOperator);
726
+ const nextIndex = (currentIndex + 1) % this.operators().length;
727
+ this.operatorControl.setValue(this.operators()[nextIndex].value);
728
+ if (this.tooltip) {
729
+ this.tooltip.hide();
730
+ setTimeout(() => {
731
+ this.tooltip?.show();
732
+ }, 0);
733
+ }
734
+ }
735
+ writeValue(value) {
736
+ if (value && value.type === FILTER_TYPES.NUMBER) {
737
+ const operator = value.operator && this.operators().find(op => op.value === value.operator)
738
+ ? value.operator
739
+ : this.operators()[0].value;
740
+ this.filterForm.setValue({
741
+ value: value.value,
742
+ operator: operator
743
+ }, { emitEvent: false });
744
+ }
745
+ else {
746
+ this.clearFilter();
747
+ }
748
+ }
749
+ registerOnChange(fn) {
750
+ this.onChange = fn;
751
+ }
752
+ registerOnTouched(fn) {
753
+ this.onTouched = fn;
754
+ }
755
+ fireOnChangeEvent() {
756
+ this.lastNumberValue = this.numberControl.value;
757
+ this.onChange({
758
+ value: this.numberControl.value,
759
+ operator: this.operatorControl.value,
760
+ type: FILTER_TYPES.NUMBER
761
+ });
762
+ }
763
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: NumberFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
764
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: NumberFilterComponent, isStandalone: true, selector: "ymbpm-number-filter", inputs: { operators: { classPropertyName: "operators", publicName: "operators", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
765
+ {
766
+ provide: NG_VALUE_ACCESSOR,
767
+ useExisting: forwardRef(() => NumberFilterComponent),
768
+ multi: true
769
+ }
770
+ ], viewQueries: [{ propertyName: "tooltip", first: true, predicate: MatTooltip, descendants: true }], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n @if (operators().length > 1) {\n <button mat-icon-button\n class=\"filter-options-btn\"\n (click)=\"toggleOperator()\"\n [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">\n <mat-icon>{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n </button>\n } @else {\n <mat-icon [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n }\n\n <mat-form-field appearance=\"outline\" class=\"filter-field\">\n <input matInput type=\"number\"\n [placeholder]=\"('yuv.app.bpm-management.filters.search' | translate)\"\n [formControl]=\"numberControl\"\n (keydown.enter)=\"onEnter()\">\n <mat-icon matSuffix>search</mat-icon>\n </mat-form-field>\n</div>", styles: [".filter-input-group{display:flex;align-items:center;gap:4px;width:100%;opacity:.6;transition:opacity .2s ease-in-out}.filter-input-group.active{opacity:1}.filter-field{flex:1}.filter-clear-btn{flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
771
+ }
772
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: NumberFilterComponent, decorators: [{
773
+ type: Component,
774
+ args: [{ selector: 'ymbpm-number-filter', standalone: true, imports: [
775
+ CommonModule,
776
+ ReactiveFormsModule,
777
+ MatFormFieldModule,
778
+ MatInputModule,
779
+ MatIconModule,
780
+ MatButtonModule,
781
+ MatMenuModule,
782
+ MatDividerModule,
783
+ MatTooltipModule,
784
+ TranslatePipe
785
+ ], providers: [
786
+ {
787
+ provide: NG_VALUE_ACCESSOR,
788
+ useExisting: forwardRef(() => NumberFilterComponent),
789
+ multi: true
790
+ }
791
+ ], template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n @if (operators().length > 1) {\n <button mat-icon-button\n class=\"filter-options-btn\"\n (click)=\"toggleOperator()\"\n [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">\n <mat-icon>{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n </button>\n } @else {\n <mat-icon [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n }\n\n <mat-form-field appearance=\"outline\" class=\"filter-field\">\n <input matInput type=\"number\"\n [placeholder]=\"('yuv.app.bpm-management.filters.search' | translate)\"\n [formControl]=\"numberControl\"\n (keydown.enter)=\"onEnter()\">\n <mat-icon matSuffix>search</mat-icon>\n </mat-form-field>\n</div>", styles: [".filter-input-group{display:flex;align-items:center;gap:4px;width:100%;opacity:.6;transition:opacity .2s ease-in-out}.filter-input-group.active{opacity:1}.filter-field{flex:1}.filter-clear-btn{flex-shrink:0}\n"] }]
792
+ }], propDecorators: { operators: [{ type: i0.Input, args: [{ isSignal: true, alias: "operators", required: false }] }], tooltip: [{
793
+ type: ViewChild,
794
+ args: [MatTooltip]
795
+ }] } });
796
+
797
+ class SelectFilterComponent {
798
+ options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
799
+ enableMultiselect = input(false, ...(ngDevMode ? [{ debugName: "enableMultiselect" }] : /* istanbul ignore next */ []));
800
+ selectControl = new FormControl();
801
+ icons = {
802
+ ...APP_ICONS,
803
+ };
804
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
805
+ onChange = () => { };
806
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
807
+ onTouched = () => { };
808
+ ngOnInit() {
809
+ if (this.enableMultiselect()) {
810
+ this.selectControl.setValue([]);
811
+ }
812
+ else {
813
+ this.selectControl.setValue('');
814
+ }
815
+ this.selectControl.valueChanges.subscribe(() => {
816
+ this.fireOnChangeEvent();
817
+ });
818
+ }
819
+ isActiveFilter() {
820
+ const value = this.selectControl.value;
821
+ if (this.enableMultiselect()) {
822
+ return value && Array.isArray(value) && value.length > 0;
823
+ }
824
+ else {
825
+ return value && value !== '';
826
+ }
827
+ }
828
+ getSelectedCount() {
829
+ if (!this.enableMultiselect())
830
+ return 0;
831
+ const values = this.selectControl.value || [];
832
+ return Array.isArray(values) ? values.length : 0;
833
+ }
834
+ clearFilter(fireEvent = false) {
835
+ this.selectControl.setValue(null, { emitEvent: false });
836
+ if (fireEvent) {
837
+ this.fireOnChangeEvent();
838
+ }
839
+ }
840
+ writeValue(value) {
841
+ if (value && value.type === FILTER_TYPES.SELECT) {
842
+ if (this.enableMultiselect()) {
843
+ this.selectControl.setValue(Array.isArray(value.value) ? value.value : [], { emitEvent: false });
844
+ }
845
+ else {
846
+ this.selectControl.setValue(value.value || '', { emitEvent: false });
847
+ }
848
+ }
849
+ else {
850
+ this.clearFilter();
851
+ }
852
+ }
853
+ registerOnChange(fn) {
854
+ this.onChange = fn;
855
+ }
856
+ registerOnTouched(fn) {
857
+ this.onTouched = fn;
858
+ }
859
+ fireOnChangeEvent() {
860
+ this.onChange({
861
+ value: this.selectControl.value,
862
+ type: FILTER_TYPES.SELECT
863
+ });
864
+ }
865
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SelectFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
866
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: SelectFilterComponent, isStandalone: true, selector: "ymbpm-select-filter", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, enableMultiselect: { classPropertyName: "enableMultiselect", publicName: "enableMultiselect", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
867
+ {
868
+ provide: NG_VALUE_ACCESSOR,
869
+ useExisting: forwardRef(() => SelectFilterComponent),
870
+ multi: true
871
+ }
872
+ ], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n <mat-form-field appearance=\"outline\" class=\"filter-field\">\n <mat-select [formControl]=\"selectControl\"\n [placeholder]=\"('yuv.app.bpm-management.filters.select' | translate)\"\n [multiple]=\"enableMultiselect()\">\n @for (option of options(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{option.label | translate}}\n </mat-option>\n }\n </mat-select>\n @if (enableMultiselect()) {\n <div matSuffix class=\"multi-select-suffix\">\n @if (getSelectedCount() > 0) {\n <mat-icon>check_circle</mat-icon>\n <span class=\"count\">{{getSelectedCount()}}</span>\n }\n </div>\n }\n </mat-form-field>\n</div>", styles: [".filter-input-group{display:flex;align-items:center;gap:4px;width:100%;opacity:.6;transition:opacity .2s ease-in-out}.filter-input-group.active{opacity:1}.filter-field{flex:1}.filter-clear-btn{flex-shrink:0}.multi-select-suffix{display:flex;align-items:center;gap:4px;color:#0009}.count{font-size:12px;font-weight:500}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i3$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
873
+ }
874
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SelectFilterComponent, decorators: [{
875
+ type: Component,
876
+ args: [{ selector: 'ymbpm-select-filter', standalone: true, imports: [
877
+ CommonModule,
878
+ ReactiveFormsModule,
879
+ MatFormFieldModule,
880
+ MatSelectModule,
881
+ MatIconModule,
882
+ MatButtonModule,
883
+ TranslatePipe,
884
+ MatTooltipModule,
885
+ ], providers: [
886
+ {
887
+ provide: NG_VALUE_ACCESSOR,
888
+ useExisting: forwardRef(() => SelectFilterComponent),
889
+ multi: true
890
+ }
891
+ ], template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n <mat-form-field appearance=\"outline\" class=\"filter-field\">\n <mat-select [formControl]=\"selectControl\"\n [placeholder]=\"('yuv.app.bpm-management.filters.select' | translate)\"\n [multiple]=\"enableMultiselect()\">\n @for (option of options(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{option.label | translate}}\n </mat-option>\n }\n </mat-select>\n @if (enableMultiselect()) {\n <div matSuffix class=\"multi-select-suffix\">\n @if (getSelectedCount() > 0) {\n <mat-icon>check_circle</mat-icon>\n <span class=\"count\">{{getSelectedCount()}}</span>\n }\n </div>\n }\n </mat-form-field>\n</div>", styles: [".filter-input-group{display:flex;align-items:center;gap:4px;width:100%;opacity:.6;transition:opacity .2s ease-in-out}.filter-input-group.active{opacity:1}.filter-field{flex:1}.filter-clear-btn{flex-shrink:0}.multi-select-suffix{display:flex;align-items:center;gap:4px;color:#0009}.count{font-size:12px;font-weight:500}\n"] }]
892
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], enableMultiselect: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableMultiselect", required: false }] }] } });
893
+
894
+ class DateFilterComponent {
895
+ tooltip;
896
+ placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
897
+ operators = input([FILTER_OPERATORS.BEFORE], ...(ngDevMode ? [{ debugName: "operators" }] : /* istanbul ignore next */ []));
898
+ filterForm = new FormGroup({
899
+ value: new FormControl(null),
900
+ endDate: new FormControl(null),
901
+ operator: new FormControl(FILTER_OPERATORS.BEFORE.value)
902
+ });
903
+ icons = {
904
+ ...APP_ICONS,
905
+ };
906
+ get valueControl() { return this.filterForm.get('value'); }
907
+ get operatorControl() { return this.filterForm.get('operator'); }
908
+ get endDateControl() { return this.filterForm.get('endDate'); }
909
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
910
+ onChange = () => { };
911
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
912
+ onTouched = () => { };
913
+ ngOnInit() {
914
+ this.operatorControl.setValue(this.operators()[0]);
915
+ this.valueControl.valueChanges
916
+ .pipe(startWith(null), pairwise())
917
+ .subscribe(([prev, next]) => {
918
+ if (this.isActiveFilter() || prev !== null && next === null) {
919
+ this.fireOnChangeEvent();
920
+ }
921
+ });
922
+ this.endDateControl.valueChanges
923
+ .pipe(startWith(null), pairwise())
924
+ .subscribe(([prev, next]) => {
925
+ if (this.isActiveFilter() || prev !== null && next === null) {
926
+ this.fireOnChangeEvent();
927
+ }
928
+ });
929
+ this.operatorControl.valueChanges
930
+ .pipe(startWith(this.operators()[0]), pairwise())
931
+ .subscribe(([prev, next]) => {
932
+ if (prev !== next) {
933
+ this.fireOnChangeEvent();
934
+ }
935
+ });
936
+ }
937
+ isActiveFilter() {
938
+ const operator = this.operatorControl.value;
939
+ if (operator === FILTER_OPERATORS.BETWEEN.value) {
940
+ const startDate = this.valueControl.value;
941
+ const endDate = this.endDateControl.value;
942
+ return startDate !== null || endDate !== null;
943
+ }
944
+ else {
945
+ const value = this.valueControl.value;
946
+ return value !== null;
947
+ }
948
+ }
949
+ isBetweenMode() {
950
+ return this.operatorControl.value === FILTER_OPERATORS.BETWEEN.value;
951
+ }
952
+ getCurrentOperatorOption() {
953
+ const operator = this.operatorControl.value;
954
+ return this.operators().find(op => op.value === operator) || null;
955
+ }
956
+ setOperator(operator) {
957
+ this.operatorControl.setValue(operator);
958
+ }
959
+ clearFilter(fireEvent = false) {
960
+ this.filterForm.reset({
961
+ value: null,
962
+ operator: this.operators()[0].value,
963
+ endDate: null
964
+ }, { emitEvent: false });
965
+ if (fireEvent) {
966
+ this.fireOnChangeEvent();
967
+ }
968
+ }
969
+ toggleOperator() {
970
+ const currentOperator = this.operatorControl.value;
971
+ const currentIndex = this.operators().findIndex(op => op.value === currentOperator);
972
+ const nextIndex = (currentIndex + 1) % this.operators().length;
973
+ this.operatorControl.setValue(this.operators()[nextIndex].value);
974
+ if (this.tooltip) {
975
+ this.tooltip.hide();
976
+ setTimeout(() => {
977
+ this.tooltip?.show();
978
+ }, 0);
979
+ }
980
+ }
981
+ writeValue(value) {
982
+ if (value && value.type === FILTER_TYPES.DATE) {
983
+ if (value.operator && value.operator === FILTER_OPERATORS.BETWEEN.value) {
984
+ this.filterForm.setValue({
985
+ value: value.value instanceof Date ? value.value : null,
986
+ operator: FILTER_OPERATORS.BETWEEN.value,
987
+ endDate: value.endDate instanceof Date ? value.endDate : null
988
+ }, { emitEvent: false });
989
+ }
990
+ else {
991
+ const operator = value.operator && this.operators().find(op => op.value === value.operator)
992
+ ? value.operator
993
+ : this.operators()[0].value;
994
+ this.filterForm.setValue({
995
+ value: value.value instanceof Date ? value.value : null,
996
+ operator: operator,
997
+ endDate: null
998
+ }, { emitEvent: false });
999
+ }
1000
+ }
1001
+ else {
1002
+ this.clearFilter();
1003
+ }
1004
+ }
1005
+ registerOnChange(fn) {
1006
+ this.onChange = fn;
1007
+ }
1008
+ registerOnTouched(fn) {
1009
+ this.onTouched = fn;
1010
+ }
1011
+ fireOnChangeEvent() {
1012
+ const operator = this.operatorControl.value;
1013
+ if (operator === FILTER_OPERATORS.BETWEEN.value) {
1014
+ const startDate = this.valueControl.value;
1015
+ const endDate = this.endDateControl.value;
1016
+ this.onChange({
1017
+ value: startDate,
1018
+ endDate: endDate,
1019
+ operator: operator,
1020
+ type: FILTER_TYPES.DATE
1021
+ });
1022
+ }
1023
+ else {
1024
+ const value = this.valueControl.value;
1025
+ this.onChange({
1026
+ value: value,
1027
+ operator: operator,
1028
+ type: FILTER_TYPES.DATE
1029
+ });
1030
+ }
1031
+ }
1032
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DateFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1033
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: DateFilterComponent, isStandalone: true, selector: "ymbpm-date-filter", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, operators: { classPropertyName: "operators", publicName: "operators", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
1034
+ {
1035
+ provide: NG_VALUE_ACCESSOR,
1036
+ useExisting: forwardRef(() => DateFilterComponent),
1037
+ multi: true
1038
+ }
1039
+ ], viewQueries: [{ propertyName: "tooltip", first: true, predicate: MatTooltip, descendants: true }], ngImport: i0, template: "<div class=\"filter-input-group date-filter\" [class.active]=\"isActiveFilter()\">\n @if (operators().length > 1) {\n <button mat-icon-button\n class=\"filter-options-btn\"\n (click)=\"toggleOperator()\"\n [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">\n <mat-icon>{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n </button>\n } @else {\n <mat-icon [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n }\n\n @if (isBetweenMode()) {\n <div class=\"date-range\">\n <yuv-datepicker\n [formControl]=\"valueControl\"\n [label]=\"''\">\n </yuv-datepicker>\n\n <yuv-datepicker\n [formControl]=\"endDateControl\"\n [label]=\"''\">\n </yuv-datepicker>\n </div>\n } @else {\n <yuv-datepicker class=\"single-date-picker\"\n [formControl]=\"valueControl\"\n [label]=\"''\">\n </yuv-datepicker>\n }\n</div>\n", styles: [".filter-input-group{display:flex;align-items:flex-start;gap:4px;width:100%;opacity:.6;min-height:40px;transition:opacity .2s ease-in-out}.filter-input-group.active{opacity:1}.filter-field{flex:1}.filter-clear-btn{flex-shrink:0}.date-field{min-width:100px}.date-range{display:flex;align-items:center;gap:8px;flex:1;width:100%;min-width:0;flex-wrap:wrap}:host ::ng-deep yuv-datepicker.single-date-picker{height:40px;display:flex;align-items:center}@media(max-width:768px){.date-range{flex-direction:column;gap:4px}.date-separator{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: DatepickerComponent, selector: "yuv-datepicker", inputs: ["label", "min"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1040
+ }
1041
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DateFilterComponent, decorators: [{
1042
+ type: Component,
1043
+ args: [{ selector: 'ymbpm-date-filter', standalone: true, imports: [
1044
+ CommonModule,
1045
+ ReactiveFormsModule,
1046
+ MatFormFieldModule,
1047
+ MatInputModule,
1048
+ MatDatepickerModule,
1049
+ MatNativeDateModule,
1050
+ MatIconModule,
1051
+ MatButtonModule,
1052
+ MatMenuModule,
1053
+ MatDividerModule,
1054
+ TranslatePipe,
1055
+ MatTooltipModule,
1056
+ DatepickerComponent
1057
+ ], providers: [
1058
+ {
1059
+ provide: NG_VALUE_ACCESSOR,
1060
+ useExisting: forwardRef(() => DateFilterComponent),
1061
+ multi: true
1062
+ }
1063
+ ], template: "<div class=\"filter-input-group date-filter\" [class.active]=\"isActiveFilter()\">\n @if (operators().length > 1) {\n <button mat-icon-button\n class=\"filter-options-btn\"\n (click)=\"toggleOperator()\"\n [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">\n <mat-icon>{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n </button>\n } @else {\n <mat-icon [matTooltip]=\"(getCurrentOperatorOption()?.label || '') | translate\">{{icons[getCurrentOperatorOption()?.icon || '']}}</mat-icon>\n }\n\n @if (isBetweenMode()) {\n <div class=\"date-range\">\n <yuv-datepicker\n [formControl]=\"valueControl\"\n [label]=\"''\">\n </yuv-datepicker>\n\n <yuv-datepicker\n [formControl]=\"endDateControl\"\n [label]=\"''\">\n </yuv-datepicker>\n </div>\n } @else {\n <yuv-datepicker class=\"single-date-picker\"\n [formControl]=\"valueControl\"\n [label]=\"''\">\n </yuv-datepicker>\n }\n</div>\n", styles: [".filter-input-group{display:flex;align-items:flex-start;gap:4px;width:100%;opacity:.6;min-height:40px;transition:opacity .2s ease-in-out}.filter-input-group.active{opacity:1}.filter-field{flex:1}.filter-clear-btn{flex-shrink:0}.date-field{min-width:100px}.date-range{display:flex;align-items:center;gap:8px;flex:1;width:100%;min-width:0;flex-wrap:wrap}:host ::ng-deep yuv-datepicker.single-date-picker{height:40px;display:flex;align-items:center}@media(max-width:768px){.date-range{flex-direction:column;gap:4px}.date-separator{display:none}}\n"] }]
1064
+ }], propDecorators: { tooltip: [{
1065
+ type: ViewChild,
1066
+ args: [MatTooltip]
1067
+ }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], operators: [{ type: i0.Input, args: [{ isSignal: true, alias: "operators", required: false }] }] } });
1068
+
1069
+ class BpmTableComponent {
1070
+ columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
1071
+ dataSource = input([], ...(ngDevMode ? [{ debugName: "dataSource" }] : /* istanbul ignore next */ []));
1072
+ enableFilters = input(false, ...(ngDevMode ? [{ debugName: "enableFilters" }] : /* istanbul ignore next */ []));
1073
+ pagination = input(...(ngDevMode ? [undefined, { debugName: "pagination" }] : /* istanbul ignore next */ []));
1074
+ selectedRow = input(...(ngDevMode ? [undefined, { debugName: "selectedRow" }] : /* istanbul ignore next */ []));
1075
+ busy = input(false, ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
1076
+ displayedColumns = computed(() => this.columns().map(c => c.name), ...(ngDevMode ? [{ debugName: "displayedColumns" }] : /* istanbul ignore next */ []));
1077
+ filters = signal({}, ...(ngDevMode ? [{ debugName: "filters" }] : /* istanbul ignore next */ []));
1078
+ filterControls = {};
1079
+ pageSizes = [10, 25, 50, 100];
1080
+ DEFAULT_PAGE_SIZE = 50;
1081
+ filtersChange = output();
1082
+ pageChange = output();
1083
+ rowSelected = output();
1084
+ icons = {
1085
+ ...APP_ICONS,
1086
+ };
1087
+ FILTER_TYPES = FILTER_TYPES;
1088
+ isClearing = false;
1089
+ ngOnInit() {
1090
+ this.initializeFilterControls();
1091
+ }
1092
+ getFilterControl(columnName) {
1093
+ return this.filterControls[columnName];
1094
+ }
1095
+ clearColumnFilter(columnName) {
1096
+ const control = this.filterControls[columnName];
1097
+ if (control) {
1098
+ control.setValue(null);
1099
+ }
1100
+ const currentFilters = { ...this.filters() };
1101
+ delete currentFilters[columnName];
1102
+ this.filters.set(currentFilters);
1103
+ this.filtersChange.emit(currentFilters);
1104
+ }
1105
+ clearAllFilters() {
1106
+ if (Object.keys(this.filters()).length === 0) {
1107
+ return;
1108
+ }
1109
+ this.isClearing = true;
1110
+ Object.keys(this.filterControls).forEach(columnName => {
1111
+ const control = this.filterControls[columnName];
1112
+ if (control) {
1113
+ control.setValue(null);
1114
+ }
1115
+ });
1116
+ this.isClearing = false;
1117
+ this.filters.set({});
1118
+ this.filtersChange.emit({});
1119
+ }
1120
+ hasActiveFilter(columnName) {
1121
+ return this.filters()[columnName] !== undefined;
1122
+ }
1123
+ isSelected(row) {
1124
+ return this.selectedRow()?.id === row?.id;
1125
+ }
1126
+ selectRow(row) {
1127
+ this.rowSelected.emit(row);
1128
+ }
1129
+ initializeFilterControls() {
1130
+ this.columns().forEach(column => {
1131
+ if (column.filter) {
1132
+ this.filterControls[column.name] = new FormControl(null);
1133
+ this.filterControls[column.name].valueChanges.subscribe(filterValue => {
1134
+ if (filterValue) {
1135
+ this.updateFilter(column.name, filterValue);
1136
+ }
1137
+ });
1138
+ }
1139
+ });
1140
+ }
1141
+ updateFilter(columnName, filterValue) {
1142
+ if (this.isClearing)
1143
+ return;
1144
+ const currentFilters = { ...this.filters() };
1145
+ if (!filterValue) {
1146
+ delete currentFilters[columnName];
1147
+ return;
1148
+ }
1149
+ if (filterValue.type === FILTER_TYPES.DATE && filterValue.operator === FILTER_OPERATORS.BETWEEN.value) {
1150
+ if (filterValue.value !== null || filterValue.endDate !== null) {
1151
+ currentFilters[columnName] = filterValue;
1152
+ }
1153
+ else {
1154
+ delete currentFilters[columnName];
1155
+ }
1156
+ }
1157
+ else {
1158
+ if (filterValue.value !== null) {
1159
+ currentFilters[columnName] = filterValue;
1160
+ }
1161
+ else {
1162
+ delete currentFilters[columnName];
1163
+ }
1164
+ }
1165
+ this.filters.set(currentFilters);
1166
+ this.filtersChange.emit(currentFilters);
1167
+ }
1168
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BpmTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1169
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: BpmTableComponent, isStandalone: true, selector: "ymbpm-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, enableFilters: { classPropertyName: "enableFilters", publicName: "enableFilters", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null }, selectedRow: { classPropertyName: "selectedRow", publicName: "selectedRow", isSignal: true, isRequired: false, transformFunction: null }, busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filtersChange: "filtersChange", pageChange: "pageChange", rowSelected: "rowSelected" }, ngImport: i0, template: "<div class=\"table-container\">\n <table mat-table [dataSource]=\"dataSource()\" class=\"bpm-table mat-elevation-z8\">\n @for (column of columns(); track column.name) {\n <ng-container [matColumnDef]=column.name>\n <!-- Header cell -->\n <th mat-header-cell *matHeaderCellDef>\n <div class=\"header-cell-content\">\n <div class=\"header-title\">\n <span>{{column.displayName | translate}}</span>\n @if (enableFilters() && column.filter && hasActiveFilter(column.name)) {\n <div class=\"header-actions\">\n <mat-icon class=\"filter-active-icon\"\n [matTooltip]=\"'yuv.app.bpm-management.filters.activeFilter' | translate\">{{icons.filterActive}}</mat-icon>\n <button mat-icon-button \n class=\"filter-clear-btn\"\n (click)=\"clearColumnFilter(column.name)\"\n [matTooltip]=\"'yuv.app.bpm-management.filters.clearOne' | translate\">\n <mat-icon>{{icons.cancel}}</mat-icon>\n </button>\n </div>\n }\n </div>\n \n <!-- Filter inputs -->\n @if (enableFilters() && column.filter && getFilterControl(column.name)) {\n <div class=\"filter-container\">\n @switch (column.filter.type) {\n @case (FILTER_TYPES.TEXT) {\n <ymbpm-text-filter [formControl]=\"getFilterControl(column.name)\" [operators]=\"column.filter.operators || []\"></ymbpm-text-filter>\n }\n @case (FILTER_TYPES.NUMBER) {\n <ymbpm-number-filter [formControl]=\"getFilterControl(column.name)\" [operators]=\"column.filter.operators || []\"></ymbpm-number-filter>\n }\n @case (FILTER_TYPES.SELECT) {\n <ymbpm-select-filter [formControl]=\"getFilterControl(column.name)\" [options]=\"column.filter.options || []\" [enableMultiselect]=\"column.filter.enableMultiselect || false\"></ymbpm-select-filter>\n }\n @case (FILTER_TYPES.DATE) {\n <ymbpm-date-filter [formControl]=\"getFilterControl(column.name)\" [operators]=\"column.filter.operators || []\"></ymbpm-date-filter>\n }\n }\n </div>\n }\n \n </div>\n </th>\n \n <!-- Data cells -->\n @if (column.template) {\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"cell-content\">\n <ng-container [ngTemplateOutlet]=\"column.template\" [ngTemplateOutletContext]=\"{ $implicit: element }\"></ng-container>\n </div>\n </td>\n } @else {\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"cell-content\">\n {{element[column.name]}}\n </div>\n </td>\n }\n </ng-container>\n }\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns(); sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns();\" \n (click)=\"selectRow(row)\" \n [class.selected-row]=\"isSelected(row)\" \n class=\"process-row\">\n </tr>\n <tr class=\"mat-row\" *matNoDataRow>\n <td class=\"mat-cell\" [attr.colspan]=\"displayedColumns().length\">\n <p class=\"no-items-label\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n </td>\n </tr>\n</table>\n</div>\n@if (busy()) {\n <mat-progress-bar mode=\"indeterminate\" class=\"progress-bar\"></mat-progress-bar>\n}\n<div class=\"footer\">\n <mat-paginator class=\"paginator\" [length]=\"pagination()?.total\" [pageSize]=\"pagination()?.pageSize\" [pageSizeOptions]=\"pageSizes\" aria-label=\"Select page\"\n (page)=\"pageChange.emit($event)\"></mat-paginator>\n</div>", styles: [":host{--mat-table-row-item-outline-color: var(--ymt-outline-variant);--split-gutter-background-color: var(--ymt-outline-variant);height:100%;width:100%;overflow:hidden;display:flex;flex-flow:column}:host .table-container{flex:1;overflow:auto;width:100%;position:relative}:host .bpm-table{width:100%;height:auto;table-layout:fixed;border-collapse:collapse}:host .bpm-table ::ng-deep .mat-mdc-header-cell{width:170px;min-width:170px;padding:2px;box-sizing:border-box;border-right:1px solid var(--ymt-outline-variant);vertical-align:top}:host .bpm-table .mat-mdc-cell{padding:6px;box-sizing:border-box;border-right:1px solid var(--ymt-outline-variant);vertical-align:middle}:host .bpm-table .mat-mdc-cell:last-child{border-right:none}:host .bpm-table .mat-mdc-cell .cell-content{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;white-space:normal;word-break:break-word;overflow-wrap:break-word;max-height:75px}:host .bpm-table .mat-mdc-cell ::ng-deep .mat-icon{height:25px;width:25px;font-size:25px;vertical-align:middle}:host .process-row{cursor:pointer}:host .process-row:hover{background-color:var(--ymt-surface-container-high)}:host .selected-row{background-color:var(--ymt-selection-background)!important}:host .clear-filters-btn{display:flex;align-items:center;gap:4px}:host .no-items-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}:host .header-cell-content{display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;gap:8px;padding:0 4px 8px;width:100%;height:100%;min-height:56px;box-sizing:border-box}:host .header-title{display:flex;height:20px;align-items:center;margin-bottom:0;gap:4px;font-weight:500}:host .header-actions{display:flex;align-items:center;gap:4px}:host .filter-active-icon{font-size:16px;height:16px;width:16px;color:var(--ymt-primary)}:host .filter-clear-btn{height:16px;width:16px;padding:0;line-height:16px;display:flex;align-items:center;justify-content:center}:host .filter-clear-btn mat-icon{font-size:16px;height:16px;width:16px}:host .filter-container{margin-top:auto;width:100%;min-width:0;min-height:40px}:host ::ng-deep .filter-options-btn{background-color:var(--ymt-surface-container);border:1px solid var(--ymt-outline);border-radius:var(--ymt-corner-s)}:host .footer{display:flex;align-items:center;padding:0 16px;border-top:2px solid var(--ymt-outline-variant);box-sizing:border-box}:host .footer .paginator{margin-left:auto}@media(max-width:768px){:host .header-cell-content{min-height:100px}:host .filter-field{min-width:60px;font-size:11px}:host .filter-options-btn,:host .filter-clear-btn{min-width:24px;width:24px;height:24px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i4$1.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i4$1.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i4$1.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i4$1.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i4$1.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i4$1.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i4$1.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i4$1.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i4$1.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i4$1.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i4$1.MatNoDataRow, selector: "ng-template[matNoDataRow]" }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i5.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: TextFilterComponent, selector: "ymbpm-text-filter", inputs: ["operators"] }, { kind: "component", type: DateFilterComponent, selector: "ymbpm-date-filter", inputs: ["placeholder", "operators"] }, { kind: "component", type: SelectFilterComponent, selector: "ymbpm-select-filter", inputs: ["options", "enableMultiselect"] }, { kind: "component", type: NumberFilterComponent, selector: "ymbpm-number-filter", inputs: ["operators"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1170
+ }
1171
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BpmTableComponent, decorators: [{
1172
+ type: Component,
1173
+ args: [{ selector: 'ymbpm-table', standalone: true, imports: [
1174
+ CommonModule,
1175
+ MatButtonModule,
1176
+ MatTooltipModule,
1177
+ MatTableModule,
1178
+ MatPaginatorModule,
1179
+ MatSortModule,
1180
+ TranslatePipe,
1181
+ MatCheckboxModule,
1182
+ MatIconModule,
1183
+ MatInputModule,
1184
+ MatFormFieldModule,
1185
+ MatSelectModule,
1186
+ MatDatepickerModule,
1187
+ MatNativeDateModule,
1188
+ MatMenuModule,
1189
+ MatDividerModule,
1190
+ FormsModule,
1191
+ ReactiveFormsModule,
1192
+ TextFilterComponent,
1193
+ DateFilterComponent,
1194
+ SelectFilterComponent,
1195
+ NumberFilterComponent,
1196
+ MatProgressBar
1197
+ ], template: "<div class=\"table-container\">\n <table mat-table [dataSource]=\"dataSource()\" class=\"bpm-table mat-elevation-z8\">\n @for (column of columns(); track column.name) {\n <ng-container [matColumnDef]=column.name>\n <!-- Header cell -->\n <th mat-header-cell *matHeaderCellDef>\n <div class=\"header-cell-content\">\n <div class=\"header-title\">\n <span>{{column.displayName | translate}}</span>\n @if (enableFilters() && column.filter && hasActiveFilter(column.name)) {\n <div class=\"header-actions\">\n <mat-icon class=\"filter-active-icon\"\n [matTooltip]=\"'yuv.app.bpm-management.filters.activeFilter' | translate\">{{icons.filterActive}}</mat-icon>\n <button mat-icon-button \n class=\"filter-clear-btn\"\n (click)=\"clearColumnFilter(column.name)\"\n [matTooltip]=\"'yuv.app.bpm-management.filters.clearOne' | translate\">\n <mat-icon>{{icons.cancel}}</mat-icon>\n </button>\n </div>\n }\n </div>\n \n <!-- Filter inputs -->\n @if (enableFilters() && column.filter && getFilterControl(column.name)) {\n <div class=\"filter-container\">\n @switch (column.filter.type) {\n @case (FILTER_TYPES.TEXT) {\n <ymbpm-text-filter [formControl]=\"getFilterControl(column.name)\" [operators]=\"column.filter.operators || []\"></ymbpm-text-filter>\n }\n @case (FILTER_TYPES.NUMBER) {\n <ymbpm-number-filter [formControl]=\"getFilterControl(column.name)\" [operators]=\"column.filter.operators || []\"></ymbpm-number-filter>\n }\n @case (FILTER_TYPES.SELECT) {\n <ymbpm-select-filter [formControl]=\"getFilterControl(column.name)\" [options]=\"column.filter.options || []\" [enableMultiselect]=\"column.filter.enableMultiselect || false\"></ymbpm-select-filter>\n }\n @case (FILTER_TYPES.DATE) {\n <ymbpm-date-filter [formControl]=\"getFilterControl(column.name)\" [operators]=\"column.filter.operators || []\"></ymbpm-date-filter>\n }\n }\n </div>\n }\n \n </div>\n </th>\n \n <!-- Data cells -->\n @if (column.template) {\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"cell-content\">\n <ng-container [ngTemplateOutlet]=\"column.template\" [ngTemplateOutletContext]=\"{ $implicit: element }\"></ng-container>\n </div>\n </td>\n } @else {\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"cell-content\">\n {{element[column.name]}}\n </div>\n </td>\n }\n </ng-container>\n }\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns(); sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns();\" \n (click)=\"selectRow(row)\" \n [class.selected-row]=\"isSelected(row)\" \n class=\"process-row\">\n </tr>\n <tr class=\"mat-row\" *matNoDataRow>\n <td class=\"mat-cell\" [attr.colspan]=\"displayedColumns().length\">\n <p class=\"no-items-label\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n </td>\n </tr>\n</table>\n</div>\n@if (busy()) {\n <mat-progress-bar mode=\"indeterminate\" class=\"progress-bar\"></mat-progress-bar>\n}\n<div class=\"footer\">\n <mat-paginator class=\"paginator\" [length]=\"pagination()?.total\" [pageSize]=\"pagination()?.pageSize\" [pageSizeOptions]=\"pageSizes\" aria-label=\"Select page\"\n (page)=\"pageChange.emit($event)\"></mat-paginator>\n</div>", styles: [":host{--mat-table-row-item-outline-color: var(--ymt-outline-variant);--split-gutter-background-color: var(--ymt-outline-variant);height:100%;width:100%;overflow:hidden;display:flex;flex-flow:column}:host .table-container{flex:1;overflow:auto;width:100%;position:relative}:host .bpm-table{width:100%;height:auto;table-layout:fixed;border-collapse:collapse}:host .bpm-table ::ng-deep .mat-mdc-header-cell{width:170px;min-width:170px;padding:2px;box-sizing:border-box;border-right:1px solid var(--ymt-outline-variant);vertical-align:top}:host .bpm-table .mat-mdc-cell{padding:6px;box-sizing:border-box;border-right:1px solid var(--ymt-outline-variant);vertical-align:middle}:host .bpm-table .mat-mdc-cell:last-child{border-right:none}:host .bpm-table .mat-mdc-cell .cell-content{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;white-space:normal;word-break:break-word;overflow-wrap:break-word;max-height:75px}:host .bpm-table .mat-mdc-cell ::ng-deep .mat-icon{height:25px;width:25px;font-size:25px;vertical-align:middle}:host .process-row{cursor:pointer}:host .process-row:hover{background-color:var(--ymt-surface-container-high)}:host .selected-row{background-color:var(--ymt-selection-background)!important}:host .clear-filters-btn{display:flex;align-items:center;gap:4px}:host .no-items-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}:host .header-cell-content{display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;gap:8px;padding:0 4px 8px;width:100%;height:100%;min-height:56px;box-sizing:border-box}:host .header-title{display:flex;height:20px;align-items:center;margin-bottom:0;gap:4px;font-weight:500}:host .header-actions{display:flex;align-items:center;gap:4px}:host .filter-active-icon{font-size:16px;height:16px;width:16px;color:var(--ymt-primary)}:host .filter-clear-btn{height:16px;width:16px;padding:0;line-height:16px;display:flex;align-items:center;justify-content:center}:host .filter-clear-btn mat-icon{font-size:16px;height:16px;width:16px}:host .filter-container{margin-top:auto;width:100%;min-width:0;min-height:40px}:host ::ng-deep .filter-options-btn{background-color:var(--ymt-surface-container);border:1px solid var(--ymt-outline);border-radius:var(--ymt-corner-s)}:host .footer{display:flex;align-items:center;padding:0 16px;border-top:2px solid var(--ymt-outline-variant);box-sizing:border-box}:host .footer .paginator{margin-left:auto}@media(max-width:768px){:host .header-cell-content{min-height:100px}:host .filter-field{min-width:60px;font-size:11px}:host .filter-options-btn,:host .filter-clear-btn{min-width:24px;width:24px;height:24px}}\n"] }]
1198
+ }], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: false }] }], enableFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableFilters", required: false }] }], pagination: [{ type: i0.Input, args: [{ isSignal: true, alias: "pagination", required: false }] }], selectedRow: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedRow", required: false }] }], busy: [{ type: i0.Input, args: [{ isSignal: true, alias: "busy", required: false }] }], filtersChange: [{ type: i0.Output, args: ["filtersChange"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], rowSelected: [{ type: i0.Output, args: ["rowSelected"] }] } });
1199
+
1200
+ class FormatDateTimePipe {
1201
+ #translateService = inject(TranslateService);
1202
+ transform(value) {
1203
+ if (!value)
1204
+ return '';
1205
+ return formatDateTime(value, this.#translateService.currentLang);
1206
+ }
1207
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: FormatDateTimePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1208
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.11", ngImport: i0, type: FormatDateTimePipe, isStandalone: true, name: "formatDateTime" });
1209
+ }
1210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: FormatDateTimePipe, decorators: [{
1211
+ type: Pipe,
1212
+ args: [{
1213
+ name: 'formatDateTime',
1214
+ standalone: true
1215
+ }]
1216
+ }] });
1217
+
1218
+ class DeploymentSummaryComponent {
1219
+ deployment = input(...(ngDevMode ? [undefined, { debugName: "deployment" }] : /* istanbul ignore next */ []));
1220
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1221
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1222
+ icons = {
1223
+ ...APP_ICONS
1224
+ };
1225
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DeploymentSummaryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1226
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: DeploymentSummaryComponent, isStandalone: true, selector: "ymbpm-deployment-summary", inputs: { deployment: { classPropertyName: "deployment", publicName: "deployment", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<table class=\"details-table\">\n <tbody>\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.category' | translate }}</td>\n <td class=\"field-value\">{{ deployment()?.category }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.deploymentTime' | translate }}</td>\n <td class=\"field-value\">{{ (deployment()?.deploymentTime ?? null) | formatDateTime }}</td>\n </tr>\n </tbody>\n</table>\n\n<div class=\"resources-section\">\n <h3 class=\"resources-title\">{{ 'yuv.app.bpm-management.deployment.details.resources' | translate }}</h3>\n\n <p *ngIf=\"!deployment()?.resources || deployment()?.resources?.length === 0\" class=\"no-resources-label\">\n {{ 'yuv.app.bpm-management.emptyResult' | translate }}\n </p>\n <table class=\"resources-table\" *ngIf=\"deployment()?.resources && deployment()?.resources?.length! > 0\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.header.id' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.deployment.details.resourceMediaType' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (resource of deployment()!.resources; track resource.id) {\n <tr>\n <td class=\"resource-id\">{{ resource.id }}</td>\n <td class=\"resource-mediatype\">{{ resource.mediaType }}</td>\n </tr>\n }\n </tbody>\n </table>\n</div>", styles: [".details-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-bottom:var(--ymt-spacing-m)}.details-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.details-table tbody tr:hover{background-color:var(--ymt-surface-container-low)}.details-table tbody tr td{padding:var(--ymt-spacing-s);vertical-align:top}.details-table tbody tr td.field-label{font-weight:700;color:var(--ymt-on-surface);font-size:.875rem;width:30%;word-break:break-word}.details-table tbody tr td.field-value{font-size:1rem;color:var(--ymt-on-surface);word-break:break-word;width:70%}.resources-section{margin-top:var(--ymt-spacing-m)}.resources-section .resources-title{font-weight:800;color:var(--ymt-on-surface);font-size:.875rem;margin-bottom:var(--ymt-spacing-s);padding-left:5px}.resources-section .no-resources-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}.resources-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-top:var(--ymt-spacing-xs);font-family:monospace;font-size:.875rem}.resources-table thead{background-color:var(--ymt-surface-container)}.resources-table thead th{text-align:left;padding:var(--ymt-spacing-s);font-weight:600;color:var(--ymt-on-surface);border-bottom:2px solid var(--ymt-outline-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.resources-table thead th:nth-child(1){width:60%}.resources-table thead th:nth-child(2){width:40%}.resources-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.resources-table tbody tr:hover{background-color:var(--ymt-surface-container-high)}.resources-table tbody tr td{padding:var(--ymt-spacing-s);color:var(--ymt-on-surface);overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;max-width:0}.resources-table tbody tr td.resource-id{font-weight:600;color:var(--ymt-primary)}.resources-table tbody tr td.resource-mediatype{color:var(--ymt-on-surface);font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }] });
1227
+ }
1228
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DeploymentSummaryComponent, decorators: [{
1229
+ type: Component,
1230
+ args: [{ selector: 'ymbpm-deployment-summary', standalone: true, imports: [
1231
+ CommonModule,
1232
+ MatCardModule,
1233
+ MatProgressSpinnerModule,
1234
+ MatButtonModule,
1235
+ MatIconModule,
1236
+ MatTooltipModule,
1237
+ TranslatePipe,
1238
+ FormatDateTimePipe
1239
+ ], template: "<table class=\"details-table\">\n <tbody>\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.category' | translate }}</td>\n <td class=\"field-value\">{{ deployment()?.category }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.deploymentTime' | translate }}</td>\n <td class=\"field-value\">{{ (deployment()?.deploymentTime ?? null) | formatDateTime }}</td>\n </tr>\n </tbody>\n</table>\n\n<div class=\"resources-section\">\n <h3 class=\"resources-title\">{{ 'yuv.app.bpm-management.deployment.details.resources' | translate }}</h3>\n\n <p *ngIf=\"!deployment()?.resources || deployment()?.resources?.length === 0\" class=\"no-resources-label\">\n {{ 'yuv.app.bpm-management.emptyResult' | translate }}\n </p>\n <table class=\"resources-table\" *ngIf=\"deployment()?.resources && deployment()?.resources?.length! > 0\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.header.id' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.deployment.details.resourceMediaType' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (resource of deployment()!.resources; track resource.id) {\n <tr>\n <td class=\"resource-id\">{{ resource.id }}</td>\n <td class=\"resource-mediatype\">{{ resource.mediaType }}</td>\n </tr>\n }\n </tbody>\n </table>\n</div>", styles: [".details-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-bottom:var(--ymt-spacing-m)}.details-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.details-table tbody tr:hover{background-color:var(--ymt-surface-container-low)}.details-table tbody tr td{padding:var(--ymt-spacing-s);vertical-align:top}.details-table tbody tr td.field-label{font-weight:700;color:var(--ymt-on-surface);font-size:.875rem;width:30%;word-break:break-word}.details-table tbody tr td.field-value{font-size:1rem;color:var(--ymt-on-surface);word-break:break-word;width:70%}.resources-section{margin-top:var(--ymt-spacing-m)}.resources-section .resources-title{font-weight:800;color:var(--ymt-on-surface);font-size:.875rem;margin-bottom:var(--ymt-spacing-s);padding-left:5px}.resources-section .no-resources-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}.resources-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-top:var(--ymt-spacing-xs);font-family:monospace;font-size:.875rem}.resources-table thead{background-color:var(--ymt-surface-container)}.resources-table thead th{text-align:left;padding:var(--ymt-spacing-s);font-weight:600;color:var(--ymt-on-surface);border-bottom:2px solid var(--ymt-outline-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.resources-table thead th:nth-child(1){width:60%}.resources-table thead th:nth-child(2){width:40%}.resources-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.resources-table tbody tr:hover{background-color:var(--ymt-surface-container-high)}.resources-table tbody tr td{padding:var(--ymt-spacing-s);color:var(--ymt-on-surface);overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;max-width:0}.resources-table tbody tr td.resource-id{font-weight:600;color:var(--ymt-primary)}.resources-table tbody tr td.resource-mediatype{color:var(--ymt-on-surface);font-style:italic}\n"] }]
1240
+ }], propDecorators: { deployment: [{ type: i0.Input, args: [{ isSignal: true, alias: "deployment", required: false }] }] } });
1241
+
1242
+ class DeploymentDefinitionsComponent {
1243
+ definitions = input([], ...(ngDevMode ? [{ debugName: "definitions" }] : /* istanbul ignore next */ []));
1244
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1245
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1246
+ icons = {
1247
+ ...APP_ICONS
1248
+ };
1249
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DeploymentDefinitionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1250
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: DeploymentDefinitionsComponent, isStandalone: true, selector: "ymbpm-deployment-process-definitions", inputs: { definitions: { classPropertyName: "definitions", publicName: "definitions", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<p *ngIf=\"!definitions() || definitions().length === 0\" class=\"no-definitions-label\">\n {{ 'yuv.app.bpm-management.emptyResult' | translate }}\n</p>\n\n<table class=\"definitions-table\" *ngIf=\"definitions() && definitions().length > 0\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.header.id' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.key' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (definition of definitions(); track definition) {\n <tr>\n <td class=\"definition-id\">{{ definition.id }}</td>\n <td class=\"definition-key\">{{ definition.key }}</td>\n </tr>\n }\n </tbody>\n</table>", styles: [":host{display:block;height:100%;overflow-y:auto}:host .no-definitions-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}:host .definitions-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-top:var(--ymt-spacing-xs);font-family:monospace;font-size:.875rem}:host .definitions-table thead{background-color:var(--ymt-surface-container)}:host .definitions-table thead th{text-align:left;padding:var(--ymt-spacing-s);font-weight:600;color:var(--ymt-on-surface);border-bottom:2px solid var(--ymt-outline-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .definitions-table thead th:nth-child(1){width:60%}:host .definitions-table thead th:nth-child(2){width:40%}:host .definitions-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}:host .definitions-table tbody tr:hover{background-color:var(--ymt-surface-container-high)}:host .definitions-table tbody tr td{padding:var(--ymt-spacing-s);color:var(--ymt-on-surface);overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;max-width:0}:host .definitions-table tbody tr td.definition-id,:host .definitions-table tbody tr td.definition-key{word-break:break-word;overflow-wrap:break-word;white-space:normal}:host .definitions-table tbody tr td.definition-id{font-weight:600}:host .definitions-table tbody tr td.definition-key{font-weight:600;color:var(--ymt-on-surface);font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1251
+ }
1252
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DeploymentDefinitionsComponent, decorators: [{
1253
+ type: Component,
1254
+ args: [{ selector: 'ymbpm-deployment-process-definitions', standalone: true, imports: [
1255
+ CommonModule,
1256
+ MatCardModule,
1257
+ MatProgressSpinnerModule,
1258
+ MatButtonModule,
1259
+ MatIconModule,
1260
+ MatTooltipModule,
1261
+ MatTabsModule,
1262
+ TranslatePipe
1263
+ ], template: "<p *ngIf=\"!definitions() || definitions().length === 0\" class=\"no-definitions-label\">\n {{ 'yuv.app.bpm-management.emptyResult' | translate }}\n</p>\n\n<table class=\"definitions-table\" *ngIf=\"definitions() && definitions().length > 0\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.header.id' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.key' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (definition of definitions(); track definition) {\n <tr>\n <td class=\"definition-id\">{{ definition.id }}</td>\n <td class=\"definition-key\">{{ definition.key }}</td>\n </tr>\n }\n </tbody>\n</table>", styles: [":host{display:block;height:100%;overflow-y:auto}:host .no-definitions-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}:host .definitions-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-top:var(--ymt-spacing-xs);font-family:monospace;font-size:.875rem}:host .definitions-table thead{background-color:var(--ymt-surface-container)}:host .definitions-table thead th{text-align:left;padding:var(--ymt-spacing-s);font-weight:600;color:var(--ymt-on-surface);border-bottom:2px solid var(--ymt-outline-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .definitions-table thead th:nth-child(1){width:60%}:host .definitions-table thead th:nth-child(2){width:40%}:host .definitions-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}:host .definitions-table tbody tr:hover{background-color:var(--ymt-surface-container-high)}:host .definitions-table tbody tr td{padding:var(--ymt-spacing-s);color:var(--ymt-on-surface);overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;max-width:0}:host .definitions-table tbody tr td.definition-id,:host .definitions-table tbody tr td.definition-key{word-break:break-word;overflow-wrap:break-word;white-space:normal}:host .definitions-table tbody tr td.definition-id{font-weight:600}:host .definitions-table tbody tr td.definition-key{font-weight:600;color:var(--ymt-on-surface);font-style:italic}\n"] }]
1264
+ }], propDecorators: { definitions: [{ type: i0.Input, args: [{ isSignal: true, alias: "definitions", required: false }] }] } });
1265
+
1266
+ class DeploymentDetailsComponent {
1267
+ #translateService = inject(TranslateService);
1268
+ #bpmAdminService = inject(YuvBpmAdminService);
1269
+ deploymentId = input(...(ngDevMode ? [undefined, { debugName: "deploymentId" }] : /* istanbul ignore next */ []));
1270
+ deployment = signal(undefined, ...(ngDevMode ? [{ debugName: "deployment" }] : /* istanbul ignore next */ []));
1271
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1272
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1273
+ selectedTabIndex = 0;
1274
+ icons = {
1275
+ ...APP_ICONS
1276
+ };
1277
+ constructor() {
1278
+ effect(() => {
1279
+ this.loadDeploymentDetails();
1280
+ });
1281
+ }
1282
+ loadDeploymentDetails() {
1283
+ this.loading.set(true);
1284
+ this.error.set(undefined);
1285
+ const id = this.deploymentId();
1286
+ if (id) {
1287
+ const definitionsFilter = new ProcessDefinitionFilter();
1288
+ definitionsFilter.deploymentId = { value: id, type: FILTER_TYPES.TEXT };
1289
+ definitionsFilter.latest = { value: false, type: FILTER_TYPES.CHECKBOX };
1290
+ forkJoin({
1291
+ deployment: this.#bpmAdminService.getDeployment(id).pipe(catchError(err => {
1292
+ this.error.set(this.#translateService.instant('yuv.app.bpm-management.details.error'));
1293
+ console.error('Error loading deployment details:', err);
1294
+ return of(null);
1295
+ })),
1296
+ resources: this.#bpmAdminService.getDeploymentResources(id).pipe(catchError(err => {
1297
+ this.error.set(this.#translateService.instant('yuv.app.bpm-management.details.error'));
1298
+ console.error('Error loading deployment resources:', err);
1299
+ return of(null);
1300
+ })),
1301
+ definitions: this.#bpmAdminService.getProcessDefinitions(0, 0, definitionsFilter).pipe(catchError(err => {
1302
+ this.error.set(this.#translateService.instant('yuv.app.bpm-management.details.error'));
1303
+ console.error('Error loading deployments process definitions:', err);
1304
+ return of(null);
1305
+ }))
1306
+ }).subscribe(({ deployment, resources, definitions }) => {
1307
+ this.deployment.set(deployment || undefined);
1308
+ if (deployment) {
1309
+ deployment.resources = resources || [];
1310
+ deployment.definitions = definitions.objects || [];
1311
+ }
1312
+ this.loading.set(false);
1313
+ });
1314
+ }
1315
+ else {
1316
+ this.deployment.set(undefined);
1317
+ }
1318
+ }
1319
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DeploymentDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1320
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: DeploymentDetailsComponent, isStandalone: true, selector: "ymbpm-deployment-details", inputs: { deploymentId: { classPropertyName: "deploymentId", publicName: "deploymentId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (loading()) {\n <div class=\"loading-container\">\n <mat-spinner diameter=\"40\"></mat-spinner>\n </div>\n} @else if (error()) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error() }}</p>\n </div>\n} @else if (deployment()) {\n <section class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n <mat-tab-group [(selectedIndex)]=\"selectedTabIndex\">\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.summary' | translate\">\n <ymbpm-deployment-summary [deployment]=\"deployment()\"></ymbpm-deployment-summary>\n </mat-tab>\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.processdefinitions' | translate\">\n <ymbpm-deployment-process-definitions [definitions]=\"deployment()?.definitions ?? []\"></ymbpm-deployment-process-definitions>\n </mat-tab>\n </mat-tab-group>\n </section>\n}\n", styles: [":host{display:block}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--ymt-spacing-xl);gap:var(--ymt-spacing-m)}.loading-container p{color:var(--ymt-on-surface)}.error-card{margin-bottom:var(--ymt-spacing-m);background-color:var(--ymt-error-container)}.error-card .error-message{color:var(--ymt-on-error-container);font-weight:500}.deployment-details-card{margin-bottom:var(--ymt-spacing-m)}.deployment-details-card mat-card-header{margin-bottom:var(--ymt-spacing-m);display:flex;align-items:flex-start}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: DeploymentSummaryComponent, selector: "ymbpm-deployment-summary", inputs: ["deployment"] }, { kind: "component", type: DeploymentDefinitionsComponent, selector: "ymbpm-deployment-process-definitions", inputs: ["definitions"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1321
+ }
1322
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DeploymentDetailsComponent, decorators: [{
1323
+ type: Component,
1324
+ args: [{ selector: 'ymbpm-deployment-details', standalone: true, imports: [
1325
+ CommonModule,
1326
+ MatCardModule,
1327
+ MatProgressSpinnerModule,
1328
+ MatButtonModule,
1329
+ MatIconModule,
1330
+ MatTooltipModule,
1331
+ TranslatePipe,
1332
+ DeploymentSummaryComponent,
1333
+ DeploymentDefinitionsComponent,
1334
+ MatTabsModule,
1335
+ ], template: "@if (loading()) {\n <div class=\"loading-container\">\n <mat-spinner diameter=\"40\"></mat-spinner>\n </div>\n} @else if (error()) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error() }}</p>\n </div>\n} @else if (deployment()) {\n <section class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n <mat-tab-group [(selectedIndex)]=\"selectedTabIndex\">\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.summary' | translate\">\n <ymbpm-deployment-summary [deployment]=\"deployment()\"></ymbpm-deployment-summary>\n </mat-tab>\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.processdefinitions' | translate\">\n <ymbpm-deployment-process-definitions [definitions]=\"deployment()?.definitions ?? []\"></ymbpm-deployment-process-definitions>\n </mat-tab>\n </mat-tab-group>\n </section>\n}\n", styles: [":host{display:block}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--ymt-spacing-xl);gap:var(--ymt-spacing-m)}.loading-container p{color:var(--ymt-on-surface)}.error-card{margin-bottom:var(--ymt-spacing-m);background-color:var(--ymt-error-container)}.error-card .error-message{color:var(--ymt-on-error-container);font-weight:500}.deployment-details-card{margin-bottom:var(--ymt-spacing-m)}.deployment-details-card mat-card-header{margin-bottom:var(--ymt-spacing-m);display:flex;align-items:flex-start}\n"] }]
1336
+ }], ctorParameters: () => [], propDecorators: { deploymentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "deploymentId", required: false }] }] } });
1337
+
1338
+ class YuvDeploymentsPageComponent {
1339
+ layoutSettingsID = APP_ID + '#root.layout.settings';
1340
+ #logger = inject(Logger);
1341
+ #translateService = inject(TranslateService);
1342
+ #bpmAdminSerice = inject(YuvBpmAdminService);
1343
+ deploymentDetailsComponent;
1344
+ bpmTableComponent;
1345
+ pagination = {
1346
+ total: 0,
1347
+ pageSize: 50,
1348
+ page: 0
1349
+ };
1350
+ actions = [];
1351
+ icons = {
1352
+ ...APP_ICONS,
1353
+ };
1354
+ get displayedColumns() {
1355
+ return [
1356
+ {
1357
+ name: 'id',
1358
+ displayName: 'yuv.app.bpm-management.header.id',
1359
+ filter: {
1360
+ type: FILTER_TYPES.TEXT,
1361
+ operators: [FILTER_OPERATORS.EQUALS]
1362
+ }
1363
+ },
1364
+ {
1365
+ name: 'name',
1366
+ displayName: 'yuv.app.bpm-management.header.name',
1367
+ filter: {
1368
+ type: FILTER_TYPES.TEXT,
1369
+ operators: [FILTER_OPERATORS.CONTAINS, FILTER_OPERATORS.EQUALS, FILTER_OPERATORS.STARTS_WITH, FILTER_OPERATORS.ENDS_WITH]
1370
+ }
1371
+ },
1372
+ {
1373
+ name: 'category',
1374
+ displayName: 'yuv.app.bpm-management.header.category',
1375
+ filter: {
1376
+ type: FILTER_TYPES.TEXT,
1377
+ operators: [FILTER_OPERATORS.EQUALS]
1378
+ }
1379
+ },
1380
+ {
1381
+ name: 'deploymentTime',
1382
+ displayName: 'yuv.app.bpm-management.header.deploymentTime'
1383
+ }
1384
+ ];
1385
+ }
1386
+ // Filter state
1387
+ filter = new DeploymentFilter();
1388
+ enableFilters = true;
1389
+ enableDetails = signal(false, ...(ngDevMode ? [{ debugName: "enableDetails" }] : /* istanbul ignore next */ []));
1390
+ layoutOptions = signal({
1391
+ resizable: true,
1392
+ detailsSize: 25,
1393
+ detailsMaxSize: 75
1394
+ }, ...(ngDevMode ? [{ debugName: "layoutOptions" }] : /* istanbul ignore next */ []));
1395
+ busy = signal(false, ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
1396
+ dataSource = signal([], ...(ngDevMode ? [{ debugName: "dataSource" }] : /* istanbul ignore next */ []));
1397
+ selection = signal(new SelectionModel(false, undefined), ...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
1398
+ currentPageSize = 50;
1399
+ ngOnInit() {
1400
+ this.#loadDeploymentsList();
1401
+ }
1402
+ refresh() {
1403
+ this.#loadDeploymentsList();
1404
+ this.deploymentDetailsComponent?.loadDeploymentDetails();
1405
+ }
1406
+ onChangePage($event) {
1407
+ this.pagination.page = $event.pageIndex;
1408
+ this.pagination.pageSize = $event.pageSize;
1409
+ this.#loadDeploymentsList();
1410
+ }
1411
+ #loadDeploymentsList() {
1412
+ this.busy.set(true);
1413
+ this.#bpmAdminSerice.getDeployments(this.pagination.page, this.pagination.pageSize, this.filter).subscribe({
1414
+ next: (response) => {
1415
+ const formattedDeploymentObjects = response.objects.map(deployment => ({
1416
+ ...deployment,
1417
+ deploymentTime: deployment.deploymentTime ? formatDateTime(deployment.deploymentTime, this.#translateService.currentLang) : deployment.deploymentTime,
1418
+ }));
1419
+ this.dataSource.set(formattedDeploymentObjects);
1420
+ this.pagination.total = response.totalNumItems;
1421
+ },
1422
+ error: (e) => {
1423
+ this.#logger.error('Failed to fetch deployments', e);
1424
+ this.busy.set(false);
1425
+ },
1426
+ complete: () => {
1427
+ // const selected = this.selection().hasValue() ? this.selection().selected[0] : undefined;
1428
+ // if (selected) {
1429
+ // if (this.dataSource().some(u => u.id === selected.id)) {
1430
+ // const updatedSelected = this.dataSource().find(u => u.id === selected.id);
1431
+ // this.select(updatedSelected);
1432
+ // } else {
1433
+ // this.#userManagementService.getUserDetails(selected.id).subscribe({
1434
+ // next: (user) => {
1435
+ // this.select(user);
1436
+ // },
1437
+ // error: (e) => {
1438
+ // this.#logger.error(`Failed to fetch data for selected user with id '${selected.id}'. Deselecting user...`, e);
1439
+ // this.deselect();
1440
+ // }
1441
+ // });
1442
+ // }
1443
+ // this.refreshUserDetails();
1444
+ // } else {
1445
+ // this.deselect();
1446
+ // }
1447
+ this.busy.set(false);
1448
+ },
1449
+ });
1450
+ }
1451
+ onRowSelected(deployment) {
1452
+ this.selection().select(deployment);
1453
+ if (!this.enableDetails()) {
1454
+ this.enableDetails.set(true);
1455
+ }
1456
+ }
1457
+ onFiltersChange(filters) {
1458
+ this.filter = DeploymentFilter.fromAgFilterModel(filters);
1459
+ this.pagination.page = 0; // Reset to first page when filtering
1460
+ this.#loadDeploymentsList();
1461
+ }
1462
+ hasActiveFilters() {
1463
+ return this.filter ? Object.keys(this.filter).length > 0 : false;
1464
+ }
1465
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvDeploymentsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1466
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: YuvDeploymentsPageComponent, isStandalone: true, selector: "ymbpm-deployments-page", viewQueries: [{ propertyName: "deploymentDetailsComponent", first: true, predicate: DeploymentDetailsComponent, descendants: true }, { propertyName: "bpmTableComponent", first: true, predicate: BpmTableComponent, descendants: true }], ngImport: i0, template: "<ng-template yuvAppHeaderSlot=\"actions\">\n</ng-template>\n\n<ymt-master-details-layout\n [detailsActive]=\"enableDetails()\"\n [options]=\"layoutOptions()\"\n [layoutSettingsID]=\"layoutSettingsID\">\n\n <ng-template ymtLayoutPane role=\"master\" [topBarActions]=\"masterPaneActions\">\n <ymt-pane-body>\n <ymbpm-table \n [busy]=\"busy()\"\n [dataSource]=\"dataSource()\"\n [columns]=\"displayedColumns\"\n [pagination]=\"pagination\"\n [selectedRow]=\"selection().selected.at(0)\"\n [enableFilters]=\"enableFilters\"\n (pageChange)=\"onChangePage($event)\"\n (rowSelected)=\"onRowSelected($event)\"\n (filtersChange)=\"onFiltersChange($event)\">\n </ymbpm-table>\n </ymt-pane-body>\n </ng-template>\n\n <ng-template ymtLayoutPane role=\"details\">\n @let selectedDeployment = selection().selected.at(0);\n <ymt-pane-header [icon]=\"selectedDeployment ? 'inventory_2' : undefined\" [title]=\"selectedDeployment ? (selectedDeployment.name || '&lt;unnamed&gt;') : ''\" [subtitle]=\"selectedDeployment ? selectedDeployment.id : ''\"></ymt-pane-header>\n <ymt-pane-body>\n <div class=\"detailsPaneContainer\">\n @if (selectedDeployment) {\n <ymbpm-deployment-details [deploymentId]=\"selectedDeployment?.id\"></ymbpm-deployment-details>\n } @else {\n <div class=\"no-selection\">\n <mat-icon>{{icons.info}}</mat-icon>\n <p>{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </div>\n </ymt-pane-body>\n </ng-template>\n</ymt-master-details-layout>\n\n<ng-template #masterPaneActions>\n <div class=\"table-actions\">\n <button mat-icon-button *ngIf=\"this.enableFilters\" [disabled]=\"!hasActiveFilters()\" (click)=\"bpmTableComponent?.clearAllFilters()\" [matTooltip]=\"'yuv.app.bpm-management.filters.clearAll' | translate\">\n <mat-icon>{{icons.clearFilter}}</mat-icon>\n </button>\n <button mat-icon-button (click)=\"refresh()\" [matTooltip]=\"'yuv.app.bpm-management.navigation.refresh.tooltip' | translate\">\n <mat-icon>{{icons.refresh}}</mat-icon>\n </button>\n </div>\n</ng-template>", styles: [":host{--mat-table-row-item-outline-color: var(--ymt-outline-variant);height:100%;overflow:hidden;display:flex;flex-flow:column}:host ymt-master-details-layout{height:100%;padding:1rem}:host ymt-master-details-layout .detailsPaneContainer{display:flex;flex-direction:column;height:100%;overflow:auto}:host ymt-master-details-layout .detailsPaneContainer .no-selection{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}:host ymt-master-details-layout .detailsPaneContainer .no-selection mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:var(--ymt-spacing-m);opacity:.5}:host ymt-master-details-layout .detailsPaneContainer .no-selection p{font-size:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "ngmodule", type: MatSortModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: YuvClientShellModule }, { kind: "directive", type: i5$1.YuvAppHeaderSlotDirective, selector: "ng-template[yuvAppHeaderSlot]", inputs: ["yuvAppHeaderSlot"] }, { kind: "ngmodule", type: YuvMasterDetailsModule }, { kind: "ngmodule", type: YuvOverflowMenuModule }, { kind: "component", type: BpmTableComponent, selector: "ymbpm-table", inputs: ["columns", "dataSource", "enableFilters", "pagination", "selectedRow", "busy"], outputs: ["filtersChange", "pageChange", "rowSelected"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: DeploymentDetailsComponent, selector: "ymbpm-deployment-details", inputs: ["deploymentId"] }, { kind: "ngmodule", type: YmtLayoutModule }, { kind: "component", type: i6.MasterDetailsLayoutComponent, selector: "ymt-master-details-layout", inputs: ["layoutSettingsID", "options", "direction", "gutterSize", "detailsActive"], outputs: ["detailsActiveChange"] }, { kind: "directive", type: i6.YmtLayoutPaneDirective, selector: "[ymtLayoutPane]", inputs: ["role", "topBarActions"] }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i7.YmtPaneHeaderComponent, selector: "ymt-pane-header", inputs: ["title", "icon", "subtitle", "actions", "badges"] }, { kind: "component", type: i7.YmtPaneBodyComponent, selector: "ymt-pane-body" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1467
+ }
1468
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvDeploymentsPageComponent, decorators: [{
1469
+ type: Component,
1470
+ args: [{ selector: 'ymbpm-deployments-page', standalone: true, imports: [
1471
+ CommonModule,
1472
+ MatButtonModule,
1473
+ MatIconModule,
1474
+ MatTooltipModule,
1475
+ MatTableModule,
1476
+ MatPaginatorModule,
1477
+ MatSortModule,
1478
+ RouterModule,
1479
+ TranslatePipe,
1480
+ YuvClientShellModule,
1481
+ YuvMasterDetailsModule,
1482
+ YuvOverflowMenuModule,
1483
+ BpmTableComponent,
1484
+ MatCheckboxModule,
1485
+ DeploymentDetailsComponent,
1486
+ YmtLayoutModule,
1487
+ YmtPanesModule
1488
+ ], template: "<ng-template yuvAppHeaderSlot=\"actions\">\n</ng-template>\n\n<ymt-master-details-layout\n [detailsActive]=\"enableDetails()\"\n [options]=\"layoutOptions()\"\n [layoutSettingsID]=\"layoutSettingsID\">\n\n <ng-template ymtLayoutPane role=\"master\" [topBarActions]=\"masterPaneActions\">\n <ymt-pane-body>\n <ymbpm-table \n [busy]=\"busy()\"\n [dataSource]=\"dataSource()\"\n [columns]=\"displayedColumns\"\n [pagination]=\"pagination\"\n [selectedRow]=\"selection().selected.at(0)\"\n [enableFilters]=\"enableFilters\"\n (pageChange)=\"onChangePage($event)\"\n (rowSelected)=\"onRowSelected($event)\"\n (filtersChange)=\"onFiltersChange($event)\">\n </ymbpm-table>\n </ymt-pane-body>\n </ng-template>\n\n <ng-template ymtLayoutPane role=\"details\">\n @let selectedDeployment = selection().selected.at(0);\n <ymt-pane-header [icon]=\"selectedDeployment ? 'inventory_2' : undefined\" [title]=\"selectedDeployment ? (selectedDeployment.name || '&lt;unnamed&gt;') : ''\" [subtitle]=\"selectedDeployment ? selectedDeployment.id : ''\"></ymt-pane-header>\n <ymt-pane-body>\n <div class=\"detailsPaneContainer\">\n @if (selectedDeployment) {\n <ymbpm-deployment-details [deploymentId]=\"selectedDeployment?.id\"></ymbpm-deployment-details>\n } @else {\n <div class=\"no-selection\">\n <mat-icon>{{icons.info}}</mat-icon>\n <p>{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </div>\n </ymt-pane-body>\n </ng-template>\n</ymt-master-details-layout>\n\n<ng-template #masterPaneActions>\n <div class=\"table-actions\">\n <button mat-icon-button *ngIf=\"this.enableFilters\" [disabled]=\"!hasActiveFilters()\" (click)=\"bpmTableComponent?.clearAllFilters()\" [matTooltip]=\"'yuv.app.bpm-management.filters.clearAll' | translate\">\n <mat-icon>{{icons.clearFilter}}</mat-icon>\n </button>\n <button mat-icon-button (click)=\"refresh()\" [matTooltip]=\"'yuv.app.bpm-management.navigation.refresh.tooltip' | translate\">\n <mat-icon>{{icons.refresh}}</mat-icon>\n </button>\n </div>\n</ng-template>", styles: [":host{--mat-table-row-item-outline-color: var(--ymt-outline-variant);height:100%;overflow:hidden;display:flex;flex-flow:column}:host ymt-master-details-layout{height:100%;padding:1rem}:host ymt-master-details-layout .detailsPaneContainer{display:flex;flex-direction:column;height:100%;overflow:auto}:host ymt-master-details-layout .detailsPaneContainer .no-selection{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}:host ymt-master-details-layout .detailsPaneContainer .no-selection mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:var(--ymt-spacing-m);opacity:.5}:host ymt-master-details-layout .detailsPaneContainer .no-selection p{font-size:1rem}\n"] }]
1489
+ }], propDecorators: { deploymentDetailsComponent: [{
1490
+ type: ViewChild,
1491
+ args: [DeploymentDetailsComponent]
1492
+ }], bpmTableComponent: [{
1493
+ type: ViewChild,
1494
+ args: [BpmTableComponent]
1495
+ }] } });
1496
+
1497
+ class ProcessDefinitionSummaryComponent {
1498
+ #translateService = inject(TranslateService);
1499
+ processDefinition = input(...(ngDevMode ? [undefined, { debugName: "processDefinition" }] : /* istanbul ignore next */ []));
1500
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1501
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1502
+ icons = {
1503
+ ...APP_ICONS
1504
+ };
1505
+ processStatusTemplate = (processDefinition) => {
1506
+ if (!processDefinition)
1507
+ return '';
1508
+ if (processDefinition.suspended) {
1509
+ return `<span class="yuv-bpmn-status suspended">${this.#translateService.instant(ProcessDefinitionStatus.SUSPENDED.label)}</span>`;
1510
+ }
1511
+ else {
1512
+ return `<span class="yuv-bpmn-status running">${this.#translateService.instant(ProcessDefinitionStatus.ACTIVE.label)}</span>`;
1513
+ }
1514
+ };
1515
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessDefinitionSummaryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1516
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.11", type: ProcessDefinitionSummaryComponent, isStandalone: true, selector: "ymbpm-process-definition-summary", inputs: { processDefinition: { classPropertyName: "processDefinition", publicName: "processDefinition", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<table class=\"details-table\">\n <tbody>\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.deploymentId' | translate }}</td>\n <td class=\"field-value\">{{ processDefinition()?.deploymentId }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.status' | translate }}</td>\n <td class=\"field-value\" [innerHTML]=\"processStatusTemplate(processDefinition())\"></td>\n </tr>\n\n <tr> \n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.description' | translate }}</td>\n <td class=\"field-value\">{{ processDefinition()?.description || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.key' | translate }}</td>\n <td class=\"field-value\">{{ processDefinition()?.key || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.category' | translate }}</td>\n <td class=\"field-value\">{{ processDefinition()?.category || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.version' | translate }}</td>\n <td class=\"field-value\">{{ (processDefinition()?.version || '-') }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.processdefinitions.scope.global' | translate }}</td>\n <td class=\"field-value\">\n <mat-checkbox class=\"global-checkbox\" [disabled]=\"true\" [checked]=\"processDefinition()?.global\"></mat-checkbox>\n </td>\n </tr>\n\n <tr class=\"sub-row\">\n <td class=\"field-label\">\n {{'yuv.app.bpm-management.processdefinitions.details.processes'|translate}}\n </td>\n <td class=\"field-value\">\n {{(processDefinition()?.statistics?.processInstanceCount?.active || 0 )+ (processDefinition()?.statistics?.processInstanceCount?.suspended || 0) + (processDefinition()?.statistics?.processInstanceCount?.completed || 0)}}\n </td>\n </tr>\n <tr class=\"sub-row\">\n <td class=\"sub-field-label\">\n {{'yuv.app.bpm-management.status.running'|translate}}\n </td>\n <td class=\"sub-field-value\">\n {{processDefinition()?.statistics?.processInstanceCount?.active || 0}}\n </td>\n </tr>\n <tr class=\"sub-row\">\n <td class=\"sub-field-label\">\n {{'yuv.app.bpm-management.status.suspended'|translate}}\n </td>\n <td class=\"sub-field-value\">\n {{processDefinition()?.statistics?.processInstanceCount?.suspended || 0}}\n </td>\n </tr>\n <tr class=\"sub-row\">\n <td class=\"sub-field-label\">\n {{'yuv.app.bpm-management.status.completed'|translate}}\n </td>\n <td class=\"sub-field-value\">\n {{processDefinition()?.statistics?.processInstanceCount?.completed || 0}}\n </td>\n </tr>\n </tbody>\n</table>", styles: [".details-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-bottom:var(--ymt-spacing-m)}.details-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.details-table tbody tr.sub-row{border:none}.details-table tbody tr:hover{background-color:var(--ymt-surface-container-low)}.details-table tbody tr td{padding:var(--ymt-spacing-s);vertical-align:top}.details-table tbody tr td.field-label{font-weight:700;color:var(--ymt-on-surface);font-size:.875rem;width:30%;word-break:break-word}.details-table tbody tr td.field-value{font-weight:300;font-size:1rem;color:var(--ymt-on-surface);word-break:break-word;width:70%}.details-table tbody tr td.sub-field-label{padding-top:0;font-weight:300;padding-left:calc(var(--ymt-spacing-s) + 30px)}.details-table tbody tr td.sub-field-value{padding-top:0;font-weight:300;color:var(--ymt-on-surface);width:70%}::ng-deep .global-checkbox>div>div.mdc-checkbox{padding:0!important}::ng-deep .global-checkbox>div>div.mdc-checkbox>.mdc-checkbox__background{top:0!important;left:0!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$4.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1517
+ }
1518
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessDefinitionSummaryComponent, decorators: [{
1519
+ type: Component,
1520
+ args: [{ selector: 'ymbpm-process-definition-summary', standalone: true, imports: [
1521
+ CommonModule,
1522
+ MatCardModule,
1523
+ MatProgressSpinnerModule,
1524
+ MatButtonModule,
1525
+ MatIconModule,
1526
+ MatTooltipModule,
1527
+ MatCheckboxModule,
1528
+ TranslatePipe
1529
+ ], template: "<table class=\"details-table\">\n <tbody>\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.deploymentId' | translate }}</td>\n <td class=\"field-value\">{{ processDefinition()?.deploymentId }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.status' | translate }}</td>\n <td class=\"field-value\" [innerHTML]=\"processStatusTemplate(processDefinition())\"></td>\n </tr>\n\n <tr> \n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.description' | translate }}</td>\n <td class=\"field-value\">{{ processDefinition()?.description || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.key' | translate }}</td>\n <td class=\"field-value\">{{ processDefinition()?.key || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.category' | translate }}</td>\n <td class=\"field-value\">{{ processDefinition()?.category || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.version' | translate }}</td>\n <td class=\"field-value\">{{ (processDefinition()?.version || '-') }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.processdefinitions.scope.global' | translate }}</td>\n <td class=\"field-value\">\n <mat-checkbox class=\"global-checkbox\" [disabled]=\"true\" [checked]=\"processDefinition()?.global\"></mat-checkbox>\n </td>\n </tr>\n\n <tr class=\"sub-row\">\n <td class=\"field-label\">\n {{'yuv.app.bpm-management.processdefinitions.details.processes'|translate}}\n </td>\n <td class=\"field-value\">\n {{(processDefinition()?.statistics?.processInstanceCount?.active || 0 )+ (processDefinition()?.statistics?.processInstanceCount?.suspended || 0) + (processDefinition()?.statistics?.processInstanceCount?.completed || 0)}}\n </td>\n </tr>\n <tr class=\"sub-row\">\n <td class=\"sub-field-label\">\n {{'yuv.app.bpm-management.status.running'|translate}}\n </td>\n <td class=\"sub-field-value\">\n {{processDefinition()?.statistics?.processInstanceCount?.active || 0}}\n </td>\n </tr>\n <tr class=\"sub-row\">\n <td class=\"sub-field-label\">\n {{'yuv.app.bpm-management.status.suspended'|translate}}\n </td>\n <td class=\"sub-field-value\">\n {{processDefinition()?.statistics?.processInstanceCount?.suspended || 0}}\n </td>\n </tr>\n <tr class=\"sub-row\">\n <td class=\"sub-field-label\">\n {{'yuv.app.bpm-management.status.completed'|translate}}\n </td>\n <td class=\"sub-field-value\">\n {{processDefinition()?.statistics?.processInstanceCount?.completed || 0}}\n </td>\n </tr>\n </tbody>\n</table>", styles: [".details-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-bottom:var(--ymt-spacing-m)}.details-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.details-table tbody tr.sub-row{border:none}.details-table tbody tr:hover{background-color:var(--ymt-surface-container-low)}.details-table tbody tr td{padding:var(--ymt-spacing-s);vertical-align:top}.details-table tbody tr td.field-label{font-weight:700;color:var(--ymt-on-surface);font-size:.875rem;width:30%;word-break:break-word}.details-table tbody tr td.field-value{font-weight:300;font-size:1rem;color:var(--ymt-on-surface);word-break:break-word;width:70%}.details-table tbody tr td.sub-field-label{padding-top:0;font-weight:300;padding-left:calc(var(--ymt-spacing-s) + 30px)}.details-table tbody tr td.sub-field-value{padding-top:0;font-weight:300;color:var(--ymt-on-surface);width:70%}::ng-deep .global-checkbox>div>div.mdc-checkbox{padding:0!important}::ng-deep .global-checkbox>div>div.mdc-checkbox>.mdc-checkbox__background{top:0!important;left:0!important}\n"] }]
1530
+ }], propDecorators: { processDefinition: [{ type: i0.Input, args: [{ isSignal: true, alias: "processDefinition", required: false }] }] } });
1531
+
1532
+ class ProcessDefinitionDetailsComponent {
1533
+ #translateService = inject(TranslateService);
1534
+ #bpmAdminService = inject(YuvBpmAdminService);
1535
+ processDefinitionId = input(...(ngDevMode ? [undefined, { debugName: "processDefinitionId" }] : /* istanbul ignore next */ []));
1536
+ processDefinition = signal(undefined, ...(ngDevMode ? [{ debugName: "processDefinition" }] : /* istanbul ignore next */ []));
1537
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1538
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1539
+ selectedTabIndex = 0;
1540
+ icons = {
1541
+ ...APP_ICONS
1542
+ };
1543
+ constructor() {
1544
+ effect(() => {
1545
+ this.loadProcessDefinitionDetails();
1546
+ });
1547
+ }
1548
+ loadProcessDefinitionDetails() {
1549
+ this.loading.set(true);
1550
+ this.error.set(undefined);
1551
+ const id = this.processDefinitionId();
1552
+ if (id) {
1553
+ this.#bpmAdminService.getProcessDefinition(id).pipe(catchError(err => {
1554
+ this.error.set(this.#translateService.instant('yuv.app.bpm-management.details.error'));
1555
+ console.error('Error loading process definition details:', err);
1556
+ this.loading.set(false);
1557
+ return of(null);
1558
+ })).subscribe(processDefinition => {
1559
+ this.processDefinition.set(processDefinition || undefined);
1560
+ this.loading.set(false);
1561
+ });
1562
+ }
1563
+ else {
1564
+ this.processDefinition.set(undefined);
1565
+ }
1566
+ }
1567
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessDefinitionDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1568
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: ProcessDefinitionDetailsComponent, isStandalone: true, selector: "ymbpm-process-definition-details", inputs: { processDefinitionId: { classPropertyName: "processDefinitionId", publicName: "processDefinitionId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (loading()) {\n <div class=\"loading-container\">\n <mat-spinner diameter=\"40\"></mat-spinner>\n </div>\n} @else if (error()) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error() }}</p>\n </div>\n} @else if (processDefinition()) {\n <section class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n <mat-tab-group [(selectedIndex)]=\"selectedTabIndex\">\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.summary' | translate\">\n <ymbpm-process-definition-summary [processDefinition]=\"processDefinition()\"></ymbpm-process-definition-summary>\n </mat-tab>\n </mat-tab-group>\n </section>\n}\n", styles: [":host{display:block}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--ymt-spacing-xl);gap:var(--ymt-spacing-m)}.loading-container p{color:var(--ymt-on-surface)}.error-card{margin-bottom:var(--ymt-spacing-m);background-color:var(--ymt-error-container)}.error-card .error-message{color:var(--ymt-on-error-container);font-weight:500}.process-definition-details-card{margin-bottom:var(--ymt-spacing-m)}.process-definition-details-card mat-card-header{margin-bottom:var(--ymt-spacing-m);display:flex;align-items:flex-start}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: ProcessDefinitionSummaryComponent, selector: "ymbpm-process-definition-summary", inputs: ["processDefinition"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1569
+ }
1570
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessDefinitionDetailsComponent, decorators: [{
1571
+ type: Component,
1572
+ args: [{ selector: 'ymbpm-process-definition-details', standalone: true, imports: [
1573
+ CommonModule,
1574
+ MatCardModule,
1575
+ MatProgressSpinnerModule,
1576
+ MatButtonModule,
1577
+ MatIconModule,
1578
+ MatTooltipModule,
1579
+ TranslatePipe,
1580
+ ProcessDefinitionSummaryComponent,
1581
+ MatTabsModule,
1582
+ ], template: "@if (loading()) {\n <div class=\"loading-container\">\n <mat-spinner diameter=\"40\"></mat-spinner>\n </div>\n} @else if (error()) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error() }}</p>\n </div>\n} @else if (processDefinition()) {\n <section class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n <mat-tab-group [(selectedIndex)]=\"selectedTabIndex\">\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.summary' | translate\">\n <ymbpm-process-definition-summary [processDefinition]=\"processDefinition()\"></ymbpm-process-definition-summary>\n </mat-tab>\n </mat-tab-group>\n </section>\n}\n", styles: [":host{display:block}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--ymt-spacing-xl);gap:var(--ymt-spacing-m)}.loading-container p{color:var(--ymt-on-surface)}.error-card{margin-bottom:var(--ymt-spacing-m);background-color:var(--ymt-error-container)}.error-card .error-message{color:var(--ymt-on-error-container);font-weight:500}.process-definition-details-card{margin-bottom:var(--ymt-spacing-m)}.process-definition-details-card mat-card-header{margin-bottom:var(--ymt-spacing-m);display:flex;align-items:flex-start}\n"] }]
1583
+ }], ctorParameters: () => [], propDecorators: { processDefinitionId: [{ type: i0.Input, args: [{ isSignal: true, alias: "processDefinitionId", required: false }] }] } });
1584
+
1585
+ class CheckboxOverlayComponent {
1586
+ #dialogRef = inject((MatDialogRef));
1587
+ inputData = inject(MAT_DIALOG_DATA);
1588
+ checkbox;
1589
+ confirm() {
1590
+ this.#dialogRef.close(this.checkbox.checked);
1591
+ }
1592
+ close() {
1593
+ this.#dialogRef.close();
1594
+ }
1595
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CheckboxOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1596
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: CheckboxOverlayComponent, isStandalone: true, selector: "ymbpm-checkbox-overlay", viewQueries: [{ propertyName: "checkbox", first: true, predicate: ["checkbox"], descendants: true }], ngImport: i0, template: "<yuv-dialog [headertitel]=\"this.inputData.title ?? ''\" []>\n <main class=\"yuv-dialog-content\">\n <mat-label>{{ this.inputData.message !== undefined ? this.inputData.message : '' }}</mat-label>\n <mat-checkbox #checkbox [checked]=\"false\">{{ this.inputData.checkboxMessage !== undefined ? this.inputData.checkboxMessage : '' }}</mat-checkbox>\n </main>\n <footer>\n <button ymtButton=\"secondary\" (click)=\"close()\">\n {{ \"yuv.app.bpm-management.action.cancel.label\" | translate }}\n </button>\n <button ymtButton=\"primary\" (click)=\"confirm()\">\n {{ this.inputData.confirmBtnLabel !== undefined ? this.inputData.confirmBtnLabel : ('yuv.app.bpm-management.action.confirm.label' | translate) }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:block;position:relative}:host main{display:flex;flex-direction:column;padding:var(--ymt-spacing-m)}::ng-deep mat-checkbox{padding:10px 0 0!important}::ng-deep mat-checkbox .mdc-checkbox{padding:0 5px 0 0!important}::ng-deep mat-checkbox .mdc-checkbox .mdc-checkbox__background{top:0!important;left:0!important}\n"], dependencies: [{ kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitle", "headertitel"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1597
+ }
1598
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: CheckboxOverlayComponent, decorators: [{
1599
+ type: Component,
1600
+ args: [{ selector: 'ymbpm-checkbox-overlay', standalone: true, imports: [
1601
+ YmtButtonDirective,
1602
+ DialogComponent,
1603
+ TranslatePipe,
1604
+ MatCheckbox,
1605
+ MatLabel
1606
+ ], template: "<yuv-dialog [headertitel]=\"this.inputData.title ?? ''\" []>\n <main class=\"yuv-dialog-content\">\n <mat-label>{{ this.inputData.message !== undefined ? this.inputData.message : '' }}</mat-label>\n <mat-checkbox #checkbox [checked]=\"false\">{{ this.inputData.checkboxMessage !== undefined ? this.inputData.checkboxMessage : '' }}</mat-checkbox>\n </main>\n <footer>\n <button ymtButton=\"secondary\" (click)=\"close()\">\n {{ \"yuv.app.bpm-management.action.cancel.label\" | translate }}\n </button>\n <button ymtButton=\"primary\" (click)=\"confirm()\">\n {{ this.inputData.confirmBtnLabel !== undefined ? this.inputData.confirmBtnLabel : ('yuv.app.bpm-management.action.confirm.label' | translate) }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:block;position:relative}:host main{display:flex;flex-direction:column;padding:var(--ymt-spacing-m)}::ng-deep mat-checkbox{padding:10px 0 0!important}::ng-deep mat-checkbox .mdc-checkbox{padding:0 5px 0 0!important}::ng-deep mat-checkbox .mdc-checkbox .mdc-checkbox__background{top:0!important;left:0!important}\n"] }]
1607
+ }], propDecorators: { checkbox: [{
1608
+ type: ViewChild,
1609
+ args: ['checkbox']
1610
+ }] } });
1611
+
1612
+ class YuvProcessDefinitionsPageComponent {
1613
+ layoutSettingsID = APP_ID + '#root.layout.settings';
1614
+ #logger = inject(Logger);
1615
+ #bpmAdminSerice = inject(YuvBpmAdminService);
1616
+ #translateService = inject(TranslateService);
1617
+ #notificationService = inject(NotificationService);
1618
+ #dialog = inject(MatDialog);
1619
+ processDefinitionDetailsComponent;
1620
+ bpmTableComponent;
1621
+ showOnlyLatestCheckbox;
1622
+ globalTemplate;
1623
+ statusTemplate;
1624
+ ProcessDefinitionScope = ProcessDefinitionScope;
1625
+ ProcessDefinitionStatus = ProcessDefinitionStatus;
1626
+ pagination = {
1627
+ total: 0,
1628
+ pageSize: 50,
1629
+ page: 0
1630
+ };
1631
+ actions = [];
1632
+ icons = {
1633
+ ...APP_ICONS,
1634
+ };
1635
+ get displayedColumns() {
1636
+ return [
1637
+ {
1638
+ name: 'global', displayName: '',
1639
+ template: this.globalTemplate,
1640
+ filter: {
1641
+ type: FILTER_TYPES.SELECT,
1642
+ enableMultiselect: false,
1643
+ options: [ProcessDefinitionScope.GLOBAL, ProcessDefinitionScope.TENANT]
1644
+ }
1645
+ },
1646
+ {
1647
+ name: 'id',
1648
+ displayName: 'yuv.app.bpm-management.header.id',
1649
+ filter: {
1650
+ type: FILTER_TYPES.TEXT,
1651
+ operators: [FILTER_OPERATORS.EQUALS],
1652
+ }
1653
+ },
1654
+ {
1655
+ name: 'name',
1656
+ displayName: 'yuv.app.bpm-management.header.name',
1657
+ filter: {
1658
+ type: FILTER_TYPES.TEXT,
1659
+ operators: [FILTER_OPERATORS.CONTAINS, FILTER_OPERATORS.EQUALS, FILTER_OPERATORS.STARTS_WITH, FILTER_OPERATORS.ENDS_WITH]
1660
+ }
1661
+ },
1662
+ {
1663
+ name: 'status',
1664
+ displayName: 'yuv.app.bpm-management.header.status',
1665
+ template: this.statusTemplate,
1666
+ filter: {
1667
+ type: FILTER_TYPES.SELECT,
1668
+ options: [ProcessDefinitionStatus.ACTIVE, ProcessDefinitionStatus.SUSPENDED]
1669
+ }
1670
+ },
1671
+ {
1672
+ name: 'category',
1673
+ displayName: 'yuv.app.bpm-management.header.category',
1674
+ filter: {
1675
+ type: FILTER_TYPES.TEXT,
1676
+ operators: [FILTER_OPERATORS.CONTAINS, FILTER_OPERATORS.EQUALS, FILTER_OPERATORS.STARTS_WITH, FILTER_OPERATORS.ENDS_WITH]
1677
+ }
1678
+ },
1679
+ {
1680
+ name: 'version',
1681
+ displayName: 'yuv.app.bpm-management.header.version',
1682
+ filter: {
1683
+ type: FILTER_TYPES.NUMBER,
1684
+ operators: [FILTER_OPERATORS.EQUALS]
1685
+ }
1686
+ },
1687
+ {
1688
+ name: 'key',
1689
+ displayName: 'yuv.app.bpm-management.header.key',
1690
+ filter: {
1691
+ type: FILTER_TYPES.TEXT,
1692
+ operators: [FILTER_OPERATORS.CONTAINS, FILTER_OPERATORS.EQUALS, FILTER_OPERATORS.STARTS_WITH, FILTER_OPERATORS.ENDS_WITH]
1693
+ }
1694
+ },
1695
+ ];
1696
+ }
1697
+ // Filter state
1698
+ tableFilter = new ProcessDefinitionFilter;
1699
+ enableTableFilters = true;
1700
+ enableDetails = signal(false, ...(ngDevMode ? [{ debugName: "enableDetails" }] : /* istanbul ignore next */ []));
1701
+ layoutOptions = signal({
1702
+ resizable: true,
1703
+ detailsSize: 25,
1704
+ detailsMaxSize: 75
1705
+ }, ...(ngDevMode ? [{ debugName: "layoutOptions" }] : /* istanbul ignore next */ []));
1706
+ busy = signal(false, ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
1707
+ dataSource = signal([], ...(ngDevMode ? [{ debugName: "dataSource" }] : /* istanbul ignore next */ []));
1708
+ selection = signal(new SelectionModel(false, undefined), ...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
1709
+ currentPageSize = 50;
1710
+ ngOnInit() {
1711
+ this.#loadProcessDefinitionList();
1712
+ }
1713
+ refresh() {
1714
+ this.#loadProcessDefinitionList();
1715
+ this.processDefinitionDetailsComponent?.loadProcessDefinitionDetails();
1716
+ }
1717
+ onChangePage($event) {
1718
+ this.pagination.page = $event.pageIndex;
1719
+ this.pagination.pageSize = $event.pageSize;
1720
+ this.#loadProcessDefinitionList();
1721
+ }
1722
+ #loadProcessDefinitionList() {
1723
+ this.busy.set(true);
1724
+ this.#bpmAdminSerice.getProcessDefinitions(this.pagination.page, this.pagination.pageSize, { ...this.tableFilter, latest: { value: this.showOnlyLatestCheckbox?.checked ?? true, type: FILTER_TYPES.CHECKBOX } }).subscribe({
1725
+ next: (response) => {
1726
+ this.dataSource.set(response.objects);
1727
+ const selectedId = this.selection().selected.at(0)?.id;
1728
+ if (selectedId) {
1729
+ const updatedSelected = this.dataSource().find(pd => pd.id === selectedId);
1730
+ if (updatedSelected) {
1731
+ this.selection().select(updatedSelected);
1732
+ this.#updateActions(updatedSelected);
1733
+ }
1734
+ }
1735
+ this.pagination.total = response.totalNumItems;
1736
+ },
1737
+ error: (e) => {
1738
+ this.#logger.error('Failed to fetch process definitions', e);
1739
+ this.busy.set(false);
1740
+ },
1741
+ complete: () => {
1742
+ // const selected = this.selection().hasValue() ? this.selection().selected[0] : undefined;
1743
+ // if (selected) {
1744
+ // if (this.dataSource().some(u => u.id === selected.id)) {
1745
+ // const updatedSelected = this.dataSource().find(u => u.id === selected.id);
1746
+ // this.select(updatedSelected);
1747
+ // } else {
1748
+ // this.#userManagementService.getUserDetails(selected.id).subscribe({
1749
+ // next: (user) => {
1750
+ // this.select(user);
1751
+ // },
1752
+ // error: (e) => {
1753
+ // this.#logger.error(`Failed to fetch data for selected user with id '${selected.id}'. Deselecting user...`, e);
1754
+ // this.deselect();
1755
+ // }
1756
+ // });
1757
+ // }
1758
+ // this.refreshUserDetails();
1759
+ // } else {
1760
+ // this.deselect();
1761
+ // }
1762
+ this.busy.set(false);
1763
+ },
1764
+ });
1765
+ }
1766
+ onTableFiltersChange(filters) {
1767
+ if (filters != null) {
1768
+ this.tableFilter = ProcessDefinitionFilter.fromAgFilterModel(filters);
1769
+ }
1770
+ this.pagination.page = 0;
1771
+ this.#loadProcessDefinitionList();
1772
+ }
1773
+ hasActiveTableFilters() {
1774
+ return this.tableFilter ? Object.keys(this.tableFilter).length > 0 : false;
1775
+ }
1776
+ onRowSelected(processDefinition) {
1777
+ this.selection().select(processDefinition);
1778
+ this.#updateActions(this.selection().selected.at(0));
1779
+ if (!this.enableDetails()) {
1780
+ this.enableDetails.set(true);
1781
+ }
1782
+ }
1783
+ #updateActions(obj) {
1784
+ this.actions = obj
1785
+ ? [
1786
+ {
1787
+ id: 'yuv.app.bpm-management.processdefinitions.actions.activate',
1788
+ icon: APP_ICONS.activate,
1789
+ label: this.#translateService.instant('yuv.app.bpm-management.processdefinitions.actions.activate.label'),
1790
+ disabled: obj.suspended === false || obj.global === true,
1791
+ callback: () => this.executeAction("activate"),
1792
+ },
1793
+ {
1794
+ id: 'yuv.app.bpm-management.processdefinitions.actions.suspend',
1795
+ icon: APP_ICONS.suspend,
1796
+ label: this.#translateService.instant('yuv.app.bpm-management.processdefinitions.actions.suspend.label'),
1797
+ disabled: obj.suspended === true || obj.global === true,
1798
+ callback: () => this.executeAction("suspend"),
1799
+ }
1800
+ ]
1801
+ : [];
1802
+ }
1803
+ executeAction(action) {
1804
+ const processDefinition = this.selection().selected.at(0);
1805
+ if (!processDefinition) {
1806
+ return;
1807
+ }
1808
+ this.#dialog.open(CheckboxOverlayComponent, {
1809
+ width: '600px',
1810
+ maxWidth: '90vw',
1811
+ data: {
1812
+ title: this.#translateService.instant('yuv.app.bpm-management.processdefinitions.actions.' + action + '.label'),
1813
+ message: this.#translateService.instant('yuv.app.bpm-management.processdefinitions.actions.' + action + '.confirm.message'),
1814
+ checkboxMessage: this.#translateService.instant('yuv.app.bpm-management.processdefinitions.actions.activateorsuspend.confirm.includeProcesses.label'),
1815
+ confirmBtnLabel: this.#translateService.instant('yuv.app.bpm-management.processdefinitions.actions.' + action + '.confirm.button.label')
1816
+ },
1817
+ }).afterClosed().subscribe((result) => {
1818
+ if (result !== undefined) {
1819
+ this.busy.set(true);
1820
+ this.#bpmAdminSerice.executeProcessDefinitionAction(processDefinition.id, action, result).subscribe({
1821
+ next: () => {
1822
+ this.#notificationService.success(this.#translateService.instant('yuv.app.bpm-management.processdefinitions.actions.' + action + '.success'));
1823
+ this.refresh();
1824
+ },
1825
+ error: (e) => {
1826
+ this.busy.set(false);
1827
+ this.#logger.error(`Failed to ${action} process definition`, e);
1828
+ this.#notificationService.error(this.#translateService.instant('yuv.app.bpm-management.processdefinitions.actions.' + action + '.error'));
1829
+ }
1830
+ });
1831
+ }
1832
+ });
1833
+ }
1834
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvProcessDefinitionsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1835
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: YuvProcessDefinitionsPageComponent, isStandalone: true, selector: "ymbpm-processdefinitions-page", viewQueries: [{ propertyName: "processDefinitionDetailsComponent", first: true, predicate: ProcessDefinitionDetailsComponent, descendants: true }, { propertyName: "bpmTableComponent", first: true, predicate: BpmTableComponent, descendants: true }, { propertyName: "showOnlyLatestCheckbox", first: true, predicate: ["showOnlyLatestCheckbox"], descendants: true }, { propertyName: "globalTemplate", first: true, predicate: ["globalTemplate"], descendants: true, static: true }, { propertyName: "statusTemplate", first: true, predicate: ["statusTemplate"], descendants: true, static: true }], ngImport: i0, template: "<ng-template yuvAppHeaderSlot=\"actions\">\n</ng-template>\n\n<ymt-master-details-layout\n [detailsActive]=\"enableDetails()\"\n [options]=\"layoutOptions()\"\n [layoutSettingsID]=\"layoutSettingsID\">\n\n <ng-template ymtLayoutPane role=\"master\" [topBarActions]=\"masterPaneActions\">\n <ymt-pane-body>\n <ymbpm-table \n [busy]=\"busy()\"\n [dataSource]=\"dataSource()\" \n [columns]=\"displayedColumns\" \n [pagination]=\"pagination\"\n [selectedRow]=\"selection().selected.at(0)\"\n [enableFilters]=\"enableTableFilters\"\n (pageChange)=\"onChangePage($event)\"\n (rowSelected)=\"onRowSelected($event)\"\n (filtersChange)=\"onTableFiltersChange($event)\">\n </ymbpm-table>\n </ymt-pane-body>\n </ng-template>\n\n <ng-template ymtLayoutPane role=\"details\">\n @let selectedDefinition = selection().selected.at(0);\n <ymt-pane-header [icon]=\"selectedDefinition ? 'flowchart' : undefined\" [title]=\"selectedDefinition ? (selectedDefinition.name || '&lt;unnamed&gt;') : ''\" [subtitle]=\"selectedDefinition ? selectedDefinition.id : ''\"></ymt-pane-header>\n <ymt-pane-body>\n <div class=\"detailsPaneContainer\">\n @if (selectedDefinition) {\n <ymbpm-process-definition-details [processDefinitionId]=\"selectedDefinition?.id\"></ymbpm-process-definition-details>\n } @else {\n <div class=\"no-selection\">\n <mat-icon>{{icons.info}}</mat-icon>\n <p>{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </div>\n </ymt-pane-body>\n </ng-template>\n</ymt-master-details-layout>\n\n<ng-template #masterPaneActions>\n <div class=\"filter-actions\"> \n <mat-checkbox #showOnlyLatestCheckbox (change)=\"this.onTableFiltersChange(null)\" [checked]=\"true\">{{'yuv.app.bpm-management.processdefinitions.filter.onlyLatest' | translate}}</mat-checkbox>\n </div>\n <div class=\"table-actions\">\n <button mat-icon-button *ngIf=\"this.enableTableFilters\" [disabled]=\"!hasActiveTableFilters()\" (click)=\"bpmTableComponent?.clearAllFilters()\" [matTooltip]=\"'yuv.app.bpm-management.filters.clearAll' | translate\">\n <mat-icon>{{icons.clearFilter}}</mat-icon>\n </button>\n <button mat-icon-button (click)=\"refresh()\" [matTooltip]=\"'yuv.app.bpm-management.navigation.refresh.tooltip' | translate\">\n <mat-icon>{{icons.refresh}}</mat-icon>\n </button>\n </div>\n</ng-template>\n\n<ng-template #listActions>\n <yuv-overflow-menu [menuItems]=\"actions\"></yuv-overflow-menu>\n</ng-template>\n\n<!-- Templates for table cells -->\n<ng-template #globalTemplate let-processDefinition>\n @if (processDefinition.global) {\n <mat-icon [matTooltip]=\"ProcessDefinitionScope.GLOBAL.label | translate\">{{icons[ProcessDefinitionScope.GLOBAL.icon]}}</mat-icon>\n } @else {\n <mat-icon [matTooltip]=\"ProcessDefinitionScope.TENANT.label | translate\">{{icons[ProcessDefinitionScope.TENANT.icon]}}</mat-icon>\n }\n</ng-template>\n\n<ng-template #statusTemplate let-processDefinition>\n @if (processDefinition.suspended) {\n <span class=\"yuv-bpmn-status suspended\">{{ProcessDefinitionStatus.SUSPENDED.label | translate}}</span>\n } @else {\n <span class=\"yuv-bpmn-status running\">{{ProcessDefinitionStatus.ACTIVE.label | translate}}</span>\n }\n</ng-template>", styles: [":host{--mat-table-row-item-outline-color: var(--ymt-outline-variant);height:100%;overflow:hidden;display:flex;flex-flow:column}:host ymt-master-details-layout{height:100%;padding:1rem}:host ymt-master-details-layout .table-actions{border-color:var(--ymt-outline-variant);border-width:0 0 0 1px;border-style:solid}:host ymt-master-details-layout .detailsPaneContainer{display:flex;flex-direction:column;height:100%;overflow:auto}:host ymt-master-details-layout .detailsPaneContainer .no-selection{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}:host ymt-master-details-layout .detailsPaneContainer .no-selection mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:var(--ymt-spacing-m);opacity:.5}:host ymt-master-details-layout .detailsPaneContainer .no-selection p{font-size:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "ngmodule", type: MatSortModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: YuvClientShellModule }, { kind: "directive", type: i5$1.YuvAppHeaderSlotDirective, selector: "ng-template[yuvAppHeaderSlot]", inputs: ["yuvAppHeaderSlot"] }, { kind: "ngmodule", type: YuvMasterDetailsModule }, { kind: "ngmodule", type: YuvOverflowMenuModule }, { kind: "component", type: i6$1.OverflowMenuComponent, selector: "yuv-overflow-menu", inputs: ["overflowIcon", "groupLabels", "menuItems", "vertical"] }, { kind: "component", type: BpmTableComponent, selector: "ymbpm-table", inputs: ["columns", "dataSource", "enableFilters", "pagination", "selectedRow", "busy"], outputs: ["filtersChange", "pageChange", "rowSelected"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: ProcessDefinitionDetailsComponent, selector: "ymbpm-process-definition-details", inputs: ["processDefinitionId"] }, { kind: "ngmodule", type: YmtLayoutModule }, { kind: "component", type: i6.MasterDetailsLayoutComponent, selector: "ymt-master-details-layout", inputs: ["layoutSettingsID", "options", "direction", "gutterSize", "detailsActive"], outputs: ["detailsActiveChange"] }, { kind: "directive", type: i6.YmtLayoutPaneDirective, selector: "[ymtLayoutPane]", inputs: ["role", "topBarActions"] }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i7.YmtPaneHeaderComponent, selector: "ymt-pane-header", inputs: ["title", "icon", "subtitle", "actions", "badges"] }, { kind: "component", type: i7.YmtPaneBodyComponent, selector: "ymt-pane-body" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1836
+ }
1837
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvProcessDefinitionsPageComponent, decorators: [{
1838
+ type: Component,
1839
+ args: [{ selector: 'ymbpm-processdefinitions-page', standalone: true, imports: [
1840
+ CommonModule,
1841
+ MatButtonModule,
1842
+ MatIconModule,
1843
+ MatTooltipModule,
1844
+ MatTableModule,
1845
+ MatPaginatorModule,
1846
+ MatSortModule,
1847
+ RouterModule,
1848
+ TranslatePipe,
1849
+ YuvClientShellModule,
1850
+ YuvMasterDetailsModule,
1851
+ YuvOverflowMenuModule,
1852
+ BpmTableComponent,
1853
+ MatCheckbox,
1854
+ ProcessDefinitionDetailsComponent,
1855
+ YmtLayoutModule,
1856
+ YmtPanesModule
1857
+ ], template: "<ng-template yuvAppHeaderSlot=\"actions\">\n</ng-template>\n\n<ymt-master-details-layout\n [detailsActive]=\"enableDetails()\"\n [options]=\"layoutOptions()\"\n [layoutSettingsID]=\"layoutSettingsID\">\n\n <ng-template ymtLayoutPane role=\"master\" [topBarActions]=\"masterPaneActions\">\n <ymt-pane-body>\n <ymbpm-table \n [busy]=\"busy()\"\n [dataSource]=\"dataSource()\" \n [columns]=\"displayedColumns\" \n [pagination]=\"pagination\"\n [selectedRow]=\"selection().selected.at(0)\"\n [enableFilters]=\"enableTableFilters\"\n (pageChange)=\"onChangePage($event)\"\n (rowSelected)=\"onRowSelected($event)\"\n (filtersChange)=\"onTableFiltersChange($event)\">\n </ymbpm-table>\n </ymt-pane-body>\n </ng-template>\n\n <ng-template ymtLayoutPane role=\"details\">\n @let selectedDefinition = selection().selected.at(0);\n <ymt-pane-header [icon]=\"selectedDefinition ? 'flowchart' : undefined\" [title]=\"selectedDefinition ? (selectedDefinition.name || '&lt;unnamed&gt;') : ''\" [subtitle]=\"selectedDefinition ? selectedDefinition.id : ''\"></ymt-pane-header>\n <ymt-pane-body>\n <div class=\"detailsPaneContainer\">\n @if (selectedDefinition) {\n <ymbpm-process-definition-details [processDefinitionId]=\"selectedDefinition?.id\"></ymbpm-process-definition-details>\n } @else {\n <div class=\"no-selection\">\n <mat-icon>{{icons.info}}</mat-icon>\n <p>{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </div>\n </ymt-pane-body>\n </ng-template>\n</ymt-master-details-layout>\n\n<ng-template #masterPaneActions>\n <div class=\"filter-actions\"> \n <mat-checkbox #showOnlyLatestCheckbox (change)=\"this.onTableFiltersChange(null)\" [checked]=\"true\">{{'yuv.app.bpm-management.processdefinitions.filter.onlyLatest' | translate}}</mat-checkbox>\n </div>\n <div class=\"table-actions\">\n <button mat-icon-button *ngIf=\"this.enableTableFilters\" [disabled]=\"!hasActiveTableFilters()\" (click)=\"bpmTableComponent?.clearAllFilters()\" [matTooltip]=\"'yuv.app.bpm-management.filters.clearAll' | translate\">\n <mat-icon>{{icons.clearFilter}}</mat-icon>\n </button>\n <button mat-icon-button (click)=\"refresh()\" [matTooltip]=\"'yuv.app.bpm-management.navigation.refresh.tooltip' | translate\">\n <mat-icon>{{icons.refresh}}</mat-icon>\n </button>\n </div>\n</ng-template>\n\n<ng-template #listActions>\n <yuv-overflow-menu [menuItems]=\"actions\"></yuv-overflow-menu>\n</ng-template>\n\n<!-- Templates for table cells -->\n<ng-template #globalTemplate let-processDefinition>\n @if (processDefinition.global) {\n <mat-icon [matTooltip]=\"ProcessDefinitionScope.GLOBAL.label | translate\">{{icons[ProcessDefinitionScope.GLOBAL.icon]}}</mat-icon>\n } @else {\n <mat-icon [matTooltip]=\"ProcessDefinitionScope.TENANT.label | translate\">{{icons[ProcessDefinitionScope.TENANT.icon]}}</mat-icon>\n }\n</ng-template>\n\n<ng-template #statusTemplate let-processDefinition>\n @if (processDefinition.suspended) {\n <span class=\"yuv-bpmn-status suspended\">{{ProcessDefinitionStatus.SUSPENDED.label | translate}}</span>\n } @else {\n <span class=\"yuv-bpmn-status running\">{{ProcessDefinitionStatus.ACTIVE.label | translate}}</span>\n }\n</ng-template>", styles: [":host{--mat-table-row-item-outline-color: var(--ymt-outline-variant);height:100%;overflow:hidden;display:flex;flex-flow:column}:host ymt-master-details-layout{height:100%;padding:1rem}:host ymt-master-details-layout .table-actions{border-color:var(--ymt-outline-variant);border-width:0 0 0 1px;border-style:solid}:host ymt-master-details-layout .detailsPaneContainer{display:flex;flex-direction:column;height:100%;overflow:auto}:host ymt-master-details-layout .detailsPaneContainer .no-selection{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}:host ymt-master-details-layout .detailsPaneContainer .no-selection mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:var(--ymt-spacing-m);opacity:.5}:host ymt-master-details-layout .detailsPaneContainer .no-selection p{font-size:1rem}\n"] }]
1858
+ }], propDecorators: { processDefinitionDetailsComponent: [{
1859
+ type: ViewChild,
1860
+ args: [ProcessDefinitionDetailsComponent]
1861
+ }], bpmTableComponent: [{
1862
+ type: ViewChild,
1863
+ args: [BpmTableComponent]
1864
+ }], showOnlyLatestCheckbox: [{
1865
+ type: ViewChild,
1866
+ args: ['showOnlyLatestCheckbox']
1867
+ }], globalTemplate: [{
1868
+ type: ViewChild,
1869
+ args: ['globalTemplate', { static: true }]
1870
+ }], statusTemplate: [{
1871
+ type: ViewChild,
1872
+ args: ['statusTemplate', { static: true }]
1873
+ }] } });
1874
+
1875
+ class ProcessSummaryComponent {
1876
+ #translateService = inject(TranslateService);
1877
+ process = input(...(ngDevMode ? [undefined, { debugName: "process" }] : /* istanbul ignore next */ []));
1878
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1879
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1880
+ icons = {
1881
+ ...APP_ICONS
1882
+ };
1883
+ processStatusTemplate = (process) => {
1884
+ if (!process)
1885
+ return '';
1886
+ if (process.endTime) {
1887
+ return `<span class="yuv-bpmn-status completed">${this.#translateService.instant(ProcessStatus.COMPLETED.label)}</span>`;
1888
+ }
1889
+ else if (process.suspended) {
1890
+ return `<span class="yuv-bpmn-status suspended">${this.#translateService.instant(ProcessStatus.SUSPENDED.label)}</span>`;
1891
+ }
1892
+ else {
1893
+ return `<span class="yuv-bpmn-status running">${this.#translateService.instant(ProcessStatus.RUNNING.label)}</span>`;
1894
+ }
1895
+ };
1896
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessSummaryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1897
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: ProcessSummaryComponent, isStandalone: true, selector: "ymbpm-process-summary", inputs: { process: { classPropertyName: "process", publicName: "process", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<table class=\"details-table\">\n <tbody>\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.processDefinitionId' | translate }}</td>\n <td class=\"field-value\">{{ process()?.processDefinitionId }}</td>\n </tr>\n \n @if (process()?.processDefinitionDescription) {\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.process.details.processDefinitionDescription' | translate }}</td>\n <td class=\"field-value\">{{ process()?.processDefinitionDescription }}</td>\n </tr>\n }\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.status' | translate }}</td>\n <td class=\"field-value\" [innerHTML]=\"processStatusTemplate(process())\"></td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.businessKey' | translate }}</td>\n <td class=\"field-value\">{{ process()?.businessKey || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.startedBy' | translate }}</td>\n <td class=\"field-value\">{{ process()?.startUserId || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.startTime' | translate }}</td>\n <td class=\"field-value\">{{ ((process()?.startTime ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.endTime' | translate }}</td>\n <td class=\"field-value\">{{ ((process()?.endTime ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n </tbody>\n</table>\n\n<div class=\"variables-section\">\n <h3 class=\"variables-title\">{{ 'yuv.app.bpm-management.details.variables' | translate }}</h3>\n\n <p *ngIf=\"!process()?.variables || process()?.variables?.length === 0\" class=\"no-variables-label\">\n {{ 'yuv.app.bpm-management.emptyResult' | translate }}\n </p>\n <table class=\"variables-table\" *ngIf=\"process()?.variables && process()?.variables?.length! > 0\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.details.variableName' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.details.variableType' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.details.variableValue' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (variable of process()!.variables; track variable.name) {\n <tr>\n <td class=\"variable-name\">{{ variable.name }}</td>\n <td class=\"variable-type\">{{ variable.type }}</td>\n <td class=\"variable-value\">{{ variable.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n</div>", styles: [".details-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-bottom:var(--ymt-spacing-m)}.details-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.details-table tbody tr:hover{background-color:var(--ymt-surface-container-low)}.details-table tbody tr td{padding:var(--ymt-spacing-s);vertical-align:top}.details-table tbody tr td.field-label{font-weight:700;color:var(--ymt-on-surface);font-size:.875rem;width:30%;word-break:break-word}.details-table tbody tr td.field-value{font-size:1rem;color:var(--ymt-on-surface);word-break:break-word;width:70%}.variables-section{margin-top:var(--ymt-spacing-m)}.variables-section .variables-title{font-weight:800;color:var(--ymt-on-surface);font-size:.875rem;margin-bottom:var(--ymt-spacing-s);padding-left:5px}.variables-section .no-variables-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}.variables-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-top:var(--ymt-spacing-xs);font-family:monospace;font-size:.875rem}.variables-table thead{background-color:var(--ymt-surface-container)}.variables-table thead th{text-align:left;padding:var(--ymt-spacing-s);font-weight:600;color:var(--ymt-on-surface);border-bottom:2px solid var(--ymt-outline-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.variables-table thead th:nth-child(1){width:20%}.variables-table thead th:nth-child(2){width:15%}.variables-table thead th:nth-child(3){width:65%}.variables-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.variables-table tbody tr:hover{background-color:var(--ymt-surface-container-high)}.variables-table tbody tr td{padding:var(--ymt-spacing-s);color:var(--ymt-on-surface);overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;max-width:0}.variables-table tbody tr td.variable-name{font-weight:600;color:var(--ymt-primary)}.variables-table tbody tr td.variable-type{color:var(--ymt-on-surface);font-style:italic}.variables-table tbody tr td.variable-value{word-break:break-word;overflow-wrap:break-word;white-space:normal}.variables-table tbody tr td.variable-scope{color:var(--ymt-tertiary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }] });
1898
+ }
1899
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessSummaryComponent, decorators: [{
1900
+ type: Component,
1901
+ args: [{ selector: 'ymbpm-process-summary', standalone: true, imports: [
1902
+ CommonModule,
1903
+ MatCardModule,
1904
+ MatProgressSpinnerModule,
1905
+ MatButtonModule,
1906
+ MatIconModule,
1907
+ MatTooltipModule,
1908
+ TranslatePipe,
1909
+ FormatDateTimePipe
1910
+ ], template: "<table class=\"details-table\">\n <tbody>\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.processDefinitionId' | translate }}</td>\n <td class=\"field-value\">{{ process()?.processDefinitionId }}</td>\n </tr>\n \n @if (process()?.processDefinitionDescription) {\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.process.details.processDefinitionDescription' | translate }}</td>\n <td class=\"field-value\">{{ process()?.processDefinitionDescription }}</td>\n </tr>\n }\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.status' | translate }}</td>\n <td class=\"field-value\" [innerHTML]=\"processStatusTemplate(process())\"></td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.businessKey' | translate }}</td>\n <td class=\"field-value\">{{ process()?.businessKey || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.startedBy' | translate }}</td>\n <td class=\"field-value\">{{ process()?.startUserId || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.startTime' | translate }}</td>\n <td class=\"field-value\">{{ ((process()?.startTime ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.endTime' | translate }}</td>\n <td class=\"field-value\">{{ ((process()?.endTime ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n </tbody>\n</table>\n\n<div class=\"variables-section\">\n <h3 class=\"variables-title\">{{ 'yuv.app.bpm-management.details.variables' | translate }}</h3>\n\n <p *ngIf=\"!process()?.variables || process()?.variables?.length === 0\" class=\"no-variables-label\">\n {{ 'yuv.app.bpm-management.emptyResult' | translate }}\n </p>\n <table class=\"variables-table\" *ngIf=\"process()?.variables && process()?.variables?.length! > 0\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.details.variableName' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.details.variableType' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.details.variableValue' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (variable of process()!.variables; track variable.name) {\n <tr>\n <td class=\"variable-name\">{{ variable.name }}</td>\n <td class=\"variable-type\">{{ variable.type }}</td>\n <td class=\"variable-value\">{{ variable.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n</div>", styles: [".details-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-bottom:var(--ymt-spacing-m)}.details-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.details-table tbody tr:hover{background-color:var(--ymt-surface-container-low)}.details-table tbody tr td{padding:var(--ymt-spacing-s);vertical-align:top}.details-table tbody tr td.field-label{font-weight:700;color:var(--ymt-on-surface);font-size:.875rem;width:30%;word-break:break-word}.details-table tbody tr td.field-value{font-size:1rem;color:var(--ymt-on-surface);word-break:break-word;width:70%}.variables-section{margin-top:var(--ymt-spacing-m)}.variables-section .variables-title{font-weight:800;color:var(--ymt-on-surface);font-size:.875rem;margin-bottom:var(--ymt-spacing-s);padding-left:5px}.variables-section .no-variables-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}.variables-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-top:var(--ymt-spacing-xs);font-family:monospace;font-size:.875rem}.variables-table thead{background-color:var(--ymt-surface-container)}.variables-table thead th{text-align:left;padding:var(--ymt-spacing-s);font-weight:600;color:var(--ymt-on-surface);border-bottom:2px solid var(--ymt-outline-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.variables-table thead th:nth-child(1){width:20%}.variables-table thead th:nth-child(2){width:15%}.variables-table thead th:nth-child(3){width:65%}.variables-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.variables-table tbody tr:hover{background-color:var(--ymt-surface-container-high)}.variables-table tbody tr td{padding:var(--ymt-spacing-s);color:var(--ymt-on-surface);overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;max-width:0}.variables-table tbody tr td.variable-name{font-weight:600;color:var(--ymt-primary)}.variables-table tbody tr td.variable-type{color:var(--ymt-on-surface);font-style:italic}.variables-table tbody tr td.variable-value{word-break:break-word;overflow-wrap:break-word;white-space:normal}.variables-table tbody tr td.variable-scope{color:var(--ymt-tertiary)}\n"] }]
1911
+ }], propDecorators: { process: [{ type: i0.Input, args: [{ isSignal: true, alias: "process", required: false }] }] } });
1912
+
1913
+ class ProcessTasksComponent {
1914
+ tasks = input([], ...(ngDevMode ? [{ debugName: "tasks" }] : /* istanbul ignore next */ []));
1915
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1916
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1917
+ icons = {
1918
+ ...APP_ICONS
1919
+ };
1920
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessTasksComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1921
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: ProcessTasksComponent, isStandalone: true, selector: "ymbpm-process-tasks", inputs: { tasks: { classPropertyName: "tasks", publicName: "tasks", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<p *ngIf=\"!tasks() || tasks().length === 0\" class=\"no-tasks-label\">\n {{ 'yuv.app.bpm-management.emptyResult' | translate }}\n</p>\n\n<table class=\"tasks-table\" *ngIf=\"tasks() && tasks().length > 0\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.header.id' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.name' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.assignee' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.owner' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.createTime' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.endTime' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (task of tasks(); track task) {\n <tr>\n <td class=\"task-id\">{{ task.id }}</td>\n <td class=\"task-name\">{{ task.name }}</td>\n <td class=\"task-assignee\">{{ task.assignee }}</td>\n <td class=\"task-owner\">{{ task.owner }}</td>\n <td class=\"task-createTime\">{{ task.createTime | formatDateTime }}</td>\n <td class=\"task-endTime\">{{ task.endTime | formatDateTime }}</td>\n </tr>\n }\n </tbody>\n </table>", styles: [":host{display:block;height:100%;overflow-y:auto}:host .no-tasks-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}:host .tasks-table{width:100%;table-layout:fixed;border-collapse:collapse;font-family:monospace;font-size:.875rem}:host .tasks-table thead{background-color:var(--ymt-surface-container)}:host .tasks-table thead th{text-align:left;padding:var(--ymt-spacing-s);font-weight:600;color:var(--ymt-on-surface);border-bottom:2px solid var(--ymt-outline-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .tasks-table thead th:nth-child(1){width:20%}:host .tasks-table thead th:nth-child(2){width:16%}:host .tasks-table thead th:nth-child(3){width:16%}:host .tasks-table thead th:nth-child(4){width:16%}:host .tasks-table thead th:nth-child(5){width:16%}:host .tasks-table thead th:nth-child(6){width:16%}:host .tasks-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}:host .tasks-table tbody tr:hover{background-color:var(--ymt-surface-container-high)}:host .tasks-table tbody tr td{padding:var(--ymt-spacing-s);color:var(--ymt-on-surface);overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;max-width:0}:host .tasks-table tbody tr td.task-id,:host .tasks-table tbody tr td.task-name,:host .tasks-table tbody tr td.task-assignee,:host .tasks-table tbody tr td.task-owner,:host .tasks-table tbody tr td.task-createTime,:host .tasks-table tbody tr td.task-endTime{font-weight:600;word-break:break-word;overflow-wrap:break-word;white-space:normal}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }] });
1922
+ }
1923
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessTasksComponent, decorators: [{
1924
+ type: Component,
1925
+ args: [{ selector: 'ymbpm-process-tasks', standalone: true, imports: [
1926
+ CommonModule,
1927
+ MatCardModule,
1928
+ MatProgressSpinnerModule,
1929
+ MatButtonModule,
1930
+ MatIconModule,
1931
+ MatTooltipModule,
1932
+ MatTabsModule,
1933
+ TranslatePipe,
1934
+ FormatDateTimePipe
1935
+ ], template: "<p *ngIf=\"!tasks() || tasks().length === 0\" class=\"no-tasks-label\">\n {{ 'yuv.app.bpm-management.emptyResult' | translate }}\n</p>\n\n<table class=\"tasks-table\" *ngIf=\"tasks() && tasks().length > 0\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.header.id' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.name' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.assignee' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.owner' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.createTime' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.header.endTime' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (task of tasks(); track task) {\n <tr>\n <td class=\"task-id\">{{ task.id }}</td>\n <td class=\"task-name\">{{ task.name }}</td>\n <td class=\"task-assignee\">{{ task.assignee }}</td>\n <td class=\"task-owner\">{{ task.owner }}</td>\n <td class=\"task-createTime\">{{ task.createTime | formatDateTime }}</td>\n <td class=\"task-endTime\">{{ task.endTime | formatDateTime }}</td>\n </tr>\n }\n </tbody>\n </table>", styles: [":host{display:block;height:100%;overflow-y:auto}:host .no-tasks-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}:host .tasks-table{width:100%;table-layout:fixed;border-collapse:collapse;font-family:monospace;font-size:.875rem}:host .tasks-table thead{background-color:var(--ymt-surface-container)}:host .tasks-table thead th{text-align:left;padding:var(--ymt-spacing-s);font-weight:600;color:var(--ymt-on-surface);border-bottom:2px solid var(--ymt-outline-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .tasks-table thead th:nth-child(1){width:20%}:host .tasks-table thead th:nth-child(2){width:16%}:host .tasks-table thead th:nth-child(3){width:16%}:host .tasks-table thead th:nth-child(4){width:16%}:host .tasks-table thead th:nth-child(5){width:16%}:host .tasks-table thead th:nth-child(6){width:16%}:host .tasks-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}:host .tasks-table tbody tr:hover{background-color:var(--ymt-surface-container-high)}:host .tasks-table tbody tr td{padding:var(--ymt-spacing-s);color:var(--ymt-on-surface);overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;max-width:0}:host .tasks-table tbody tr td.task-id,:host .tasks-table tbody tr td.task-name,:host .tasks-table tbody tr td.task-assignee,:host .tasks-table tbody tr td.task-owner,:host .tasks-table tbody tr td.task-createTime,:host .tasks-table tbody tr td.task-endTime{font-weight:600;word-break:break-word;overflow-wrap:break-word;white-space:normal}\n"] }]
1936
+ }], propDecorators: { tasks: [{ type: i0.Input, args: [{ isSignal: true, alias: "tasks", required: false }] }] } });
1937
+
1938
+ class ProcessHistoryComponent {
1939
+ translateService = inject(TranslateService);
1940
+ formatDateTime = formatDateTime;
1941
+ tasks = input([], ...(ngDevMode ? [{ debugName: "tasks" }] : /* istanbul ignore next */ []));
1942
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1943
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1944
+ icons = {
1945
+ ...APP_ICONS
1946
+ };
1947
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessHistoryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1948
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.11", type: ProcessHistoryComponent, isStandalone: true, selector: "ymbpm-process-history", inputs: { tasks: { classPropertyName: "tasks", publicName: "tasks", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<p *ngIf=\"!tasks() || tasks().length === 0\" class=\"no-tasks-label\">\n {{ 'yuv.app.bpm-management.emptyResult' | translate }}\n</p>\n\n<div class=\"process-history-container\">\n <div class=\"timeline-container\" *ngIf=\"tasks() && tasks().length > 0\" [ngClass]=\"{singleEntry: tasks().length === 1}\">\n <div class=\"timeline-item\" *ngFor=\"let task of tasks()\">\n <div class=\"timeline-datetime\" [matTooltip]=\"'yuv.app.bpm-management.header.startTime' | translate\">\n <div class=\"date\">{{ formatDateTime(task.createTime, translateService.currentLang, 'date') }}</div>\n <div class=\"time\">{{ formatDateTime(task.createTime, translateService.currentLang, 'time') }}</div>\n </div>\n \n <div class=\"timeline-line\"></div>\n \n <div class=\"timeline-content\">\n <div class=\"task-card\">\n <div class=\"task-title\" [matTooltip]=\"'yuv.app.bpm-management.header.name' | translate\">{{ task.name || '&lt;unnamed&gt;' }}</div>\n <div class=\"task-details\">\n <div class=\"task-assignee\" [matTooltip]=\"'yuv.app.bpm-management.header.assignee' | translate\">\n <mat-icon>person</mat-icon>\n <span>{{ task.assignee || '-'}}</span>\n </div>\n <div class=\"task-owner\" *ngIf=\"task.owner\" [matTooltip]=\"'yuv.app.bpm-management.header.owner' | translate\">\n <mat-icon>supervisor_account</mat-icon>\n <span>{{ task.owner }}</span>\n </div>\n <div class=\"task-endtime\" *ngIf=\"task.endTime\" [matTooltip]=\"'yuv.app.bpm-management.header.endTime' | translate\">\n <mat-icon>event_available</mat-icon>\n <span>{{ task.endTime | formatDateTime }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [":host{display:block;height:100%;overflow-y:auto}:host .process-history-container{max-width:800px;margin:0 auto}:host .no-tasks-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}:host .timeline-container{display:flex;flex-flow:column;overflow-y:auto;align-items:center;padding:5px 0}:host .timeline-container:not(.singleEntry) .timeline-item .timeline-line:after{content:\"\";width:53%;display:block;border-width:0 3px 0 0;border-style:solid;border-color:var(--ymt-outline-variant);position:absolute;top:0;bottom:0;z-index:1}:host .timeline-container:not(.singleEntry) .timeline-item:first-child .timeline-line:after{top:initial;height:50%}:host .timeline-container:not(.singleEntry) .timeline-item:last-child .timeline-line:after{bottom:initial;height:50%}:host .timeline-container .timeline-item{display:grid;grid-template-rows:1fr;grid-template-columns:1fr auto 4fr;grid-template-areas:\"created timeline content\"}:host .timeline-container .timeline-item .timeline-datetime{grid-area:created;display:flex;flex-flow:column;justify-content:center;padding:0 var(--ymt-spacing-xs);width:100px}:host .timeline-container .timeline-item .timeline-datetime .date{font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);font-weight:500;color:var(--ymt-on-surface);line-height:1.2}:host .timeline-container .timeline-item .timeline-datetime .time{font-family:var(--ymt-font-body-subtle-font);font-size:var(--ymt-font-body-subtle-size);font-weight:var(--ymt-font-body-subtle-weight);line-height:var(--ymt-font-body-subtle-line-height);color:var(--ymt-on-surface-type-subtle);margin-top:var(--ymt-spacing-3xs)}:host .timeline-container .timeline-item .timeline-line{grid-area:timeline;display:flex;flex-flow:column;justify-content:center;width:var(--ymt-sizing-3xl);position:relative}:host .timeline-container .timeline-item .timeline-line:before{content:\"\";display:block;width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);border-radius:50%;background-color:var(--ymt-primary);border:3px solid var(--ymt-surface);box-shadow:0 0 0 2px var(--ymt-primary);z-index:2;align-self:center}:host .timeline-container .timeline-item .timeline-content{grid-area:content;padding:var(--ymt-spacing-xs);box-sizing:border-box;display:flex}:host .timeline-container .timeline-item .timeline-content .task-card{width:100%;min-width:300px;background-color:var(--ymt-surface-container-high);border:var(--ymt-outline-width) solid var(--ymt-outline-variant-emphasized);border-radius:var(--ymt-corner-m);padding:var(--ymt-spacing-xs) var(--ymt-spacing-m);display:flex;flex-direction:column;gap:var(--ymt-spacing-s)}:host .timeline-container .timeline-item .timeline-content .task-card .task-title{font-family:var(--ymt-font-title-smallest-font);font-size:var(--ymt-font-title-smallest-size);font-weight:var(--ymt-font-title-smallest-weight);line-height:var(--ymt-font-title-smallest-line-height);color:var(--ymt-on-surface)}:host .timeline-container .timeline-item .timeline-content .task-card .task-details{display:flex;flex-direction:column;flex-wrap:wrap;gap:var(--ymt-spacing-2xs)}:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-assignee,:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-owner,:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-endtime{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);color:var(--ymt-on-surface)}:is(:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-assignee,:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-owner,:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-endtime) mat-icon{font-size:14px;width:14px;height:14px}:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-assignee mat-icon,:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-owner mat-icon{color:var(--ymt-primary)}@media(max-width:600px){:host .timeline-date{flex:0 0 100px;font-size:11px}:host .timeline-content{padding-left:12px}:host .task-card{padding:10px 12px}:host .task-title{font-size:13px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }] });
1949
+ }
1950
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessHistoryComponent, decorators: [{
1951
+ type: Component,
1952
+ args: [{ selector: 'ymbpm-process-history', standalone: true, imports: [
1953
+ CommonModule,
1954
+ MatCardModule,
1955
+ MatProgressSpinnerModule,
1956
+ MatButtonModule,
1957
+ MatIconModule,
1958
+ MatTooltipModule,
1959
+ TranslatePipe,
1960
+ FormatDateTimePipe
1961
+ ], template: "<p *ngIf=\"!tasks() || tasks().length === 0\" class=\"no-tasks-label\">\n {{ 'yuv.app.bpm-management.emptyResult' | translate }}\n</p>\n\n<div class=\"process-history-container\">\n <div class=\"timeline-container\" *ngIf=\"tasks() && tasks().length > 0\" [ngClass]=\"{singleEntry: tasks().length === 1}\">\n <div class=\"timeline-item\" *ngFor=\"let task of tasks()\">\n <div class=\"timeline-datetime\" [matTooltip]=\"'yuv.app.bpm-management.header.startTime' | translate\">\n <div class=\"date\">{{ formatDateTime(task.createTime, translateService.currentLang, 'date') }}</div>\n <div class=\"time\">{{ formatDateTime(task.createTime, translateService.currentLang, 'time') }}</div>\n </div>\n \n <div class=\"timeline-line\"></div>\n \n <div class=\"timeline-content\">\n <div class=\"task-card\">\n <div class=\"task-title\" [matTooltip]=\"'yuv.app.bpm-management.header.name' | translate\">{{ task.name || '&lt;unnamed&gt;' }}</div>\n <div class=\"task-details\">\n <div class=\"task-assignee\" [matTooltip]=\"'yuv.app.bpm-management.header.assignee' | translate\">\n <mat-icon>person</mat-icon>\n <span>{{ task.assignee || '-'}}</span>\n </div>\n <div class=\"task-owner\" *ngIf=\"task.owner\" [matTooltip]=\"'yuv.app.bpm-management.header.owner' | translate\">\n <mat-icon>supervisor_account</mat-icon>\n <span>{{ task.owner }}</span>\n </div>\n <div class=\"task-endtime\" *ngIf=\"task.endTime\" [matTooltip]=\"'yuv.app.bpm-management.header.endTime' | translate\">\n <mat-icon>event_available</mat-icon>\n <span>{{ task.endTime | formatDateTime }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [":host{display:block;height:100%;overflow-y:auto}:host .process-history-container{max-width:800px;margin:0 auto}:host .no-tasks-label{text-align:center;color:var(--ymt-on-surface);font-style:italic;margin:32px 0}:host .timeline-container{display:flex;flex-flow:column;overflow-y:auto;align-items:center;padding:5px 0}:host .timeline-container:not(.singleEntry) .timeline-item .timeline-line:after{content:\"\";width:53%;display:block;border-width:0 3px 0 0;border-style:solid;border-color:var(--ymt-outline-variant);position:absolute;top:0;bottom:0;z-index:1}:host .timeline-container:not(.singleEntry) .timeline-item:first-child .timeline-line:after{top:initial;height:50%}:host .timeline-container:not(.singleEntry) .timeline-item:last-child .timeline-line:after{bottom:initial;height:50%}:host .timeline-container .timeline-item{display:grid;grid-template-rows:1fr;grid-template-columns:1fr auto 4fr;grid-template-areas:\"created timeline content\"}:host .timeline-container .timeline-item .timeline-datetime{grid-area:created;display:flex;flex-flow:column;justify-content:center;padding:0 var(--ymt-spacing-xs);width:100px}:host .timeline-container .timeline-item .timeline-datetime .date{font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);font-weight:500;color:var(--ymt-on-surface);line-height:1.2}:host .timeline-container .timeline-item .timeline-datetime .time{font-family:var(--ymt-font-body-subtle-font);font-size:var(--ymt-font-body-subtle-size);font-weight:var(--ymt-font-body-subtle-weight);line-height:var(--ymt-font-body-subtle-line-height);color:var(--ymt-on-surface-type-subtle);margin-top:var(--ymt-spacing-3xs)}:host .timeline-container .timeline-item .timeline-line{grid-area:timeline;display:flex;flex-flow:column;justify-content:center;width:var(--ymt-sizing-3xl);position:relative}:host .timeline-container .timeline-item .timeline-line:before{content:\"\";display:block;width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);border-radius:50%;background-color:var(--ymt-primary);border:3px solid var(--ymt-surface);box-shadow:0 0 0 2px var(--ymt-primary);z-index:2;align-self:center}:host .timeline-container .timeline-item .timeline-content{grid-area:content;padding:var(--ymt-spacing-xs);box-sizing:border-box;display:flex}:host .timeline-container .timeline-item .timeline-content .task-card{width:100%;min-width:300px;background-color:var(--ymt-surface-container-high);border:var(--ymt-outline-width) solid var(--ymt-outline-variant-emphasized);border-radius:var(--ymt-corner-m);padding:var(--ymt-spacing-xs) var(--ymt-spacing-m);display:flex;flex-direction:column;gap:var(--ymt-spacing-s)}:host .timeline-container .timeline-item .timeline-content .task-card .task-title{font-family:var(--ymt-font-title-smallest-font);font-size:var(--ymt-font-title-smallest-size);font-weight:var(--ymt-font-title-smallest-weight);line-height:var(--ymt-font-title-smallest-line-height);color:var(--ymt-on-surface)}:host .timeline-container .timeline-item .timeline-content .task-card .task-details{display:flex;flex-direction:column;flex-wrap:wrap;gap:var(--ymt-spacing-2xs)}:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-assignee,:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-owner,:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-endtime{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);color:var(--ymt-on-surface)}:is(:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-assignee,:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-owner,:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-endtime) mat-icon{font-size:14px;width:14px;height:14px}:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-assignee mat-icon,:host .timeline-container .timeline-item .timeline-content .task-card .task-details .task-owner mat-icon{color:var(--ymt-primary)}@media(max-width:600px){:host .timeline-date{flex:0 0 100px;font-size:11px}:host .timeline-content{padding-left:12px}:host .task-card{padding:10px 12px}:host .task-title{font-size:13px}}\n"] }]
1962
+ }], propDecorators: { tasks: [{ type: i0.Input, args: [{ isSignal: true, alias: "tasks", required: false }] }] } });
1963
+
1964
+ class ProcessDetailsComponent {
1965
+ #translateService = inject(TranslateService);
1966
+ #bpmAdminService = inject(YuvBpmAdminService);
1967
+ processInstanceId = input(...(ngDevMode ? [undefined, { debugName: "processInstanceId" }] : /* istanbul ignore next */ []));
1968
+ process = signal(undefined, ...(ngDevMode ? [{ debugName: "process" }] : /* istanbul ignore next */ []));
1969
+ tasks = signal([], ...(ngDevMode ? [{ debugName: "tasks" }] : /* istanbul ignore next */ []));
1970
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
1971
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1972
+ selectedTabIndex = 0;
1973
+ icons = {
1974
+ ...APP_ICONS
1975
+ };
1976
+ constructor() {
1977
+ effect(() => {
1978
+ this.loadProcessDetails();
1979
+ });
1980
+ }
1981
+ loadProcessDetails() {
1982
+ this.loading.set(true);
1983
+ this.error.set(undefined);
1984
+ const id = this.processInstanceId();
1985
+ if (id) {
1986
+ forkJoin({
1987
+ process: this.#bpmAdminService.getProcess(id).pipe(catchError(err => {
1988
+ this.error.set(this.#translateService.instant('yuv.app.bpm-management.details.error'));
1989
+ console.error('Error loading process details:', err);
1990
+ return of(null);
1991
+ })),
1992
+ history: this.#bpmAdminService.getProcessHistory(id).pipe(catchError(err => {
1993
+ this.error.set(this.#translateService.instant('yuv.app.bpm-management.details.error'));
1994
+ console.error('Error loading process history:', err);
1995
+ return of(null);
1996
+ }))
1997
+ }).subscribe(({ process, history }) => {
1998
+ this.process.set(process || undefined);
1999
+ this.tasks.set(history?.tasks || []);
2000
+ this.loading.set(false);
2001
+ });
2002
+ }
2003
+ else {
2004
+ this.process.set(undefined);
2005
+ }
2006
+ }
2007
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2008
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: ProcessDetailsComponent, isStandalone: true, selector: "ymbpm-process-details", inputs: { processInstanceId: { classPropertyName: "processInstanceId", publicName: "processInstanceId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (loading()) {\n <div class=\"loading-container\">\n <mat-spinner diameter=\"40\"></mat-spinner>\n </div>\n} @else if (error()) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error() }}</p>\n </div>\n} @else if (process() && tasks()) {\n <section class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n <mat-tab-group [(selectedIndex)]=\"selectedTabIndex\">\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.summary' | translate\">\n <ymbpm-process-summary [process]=\"process()\"></ymbpm-process-summary>\n </mat-tab>\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.tasks' | translate\">\n <ymbpm-process-tasks [tasks]=\"tasks()\"></ymbpm-process-tasks>\n </mat-tab>\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.history' | translate\">\n <ymbpm-process-history [tasks]=\"tasks()\"></ymbpm-process-history>\n </mat-tab>\n </mat-tab-group>\n </section>\n}", styles: [":host{display:block}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--ymt-spacing-xl);gap:var(--ymt-spacing-m)}.loading-container p{color:var(--ymt-on-surface)}.error-card{margin-bottom:var(--ymt-spacing-m);background-color:var(--ymt-error-container)}.error-card .error-message{color:var(--ymt-on-error-container);font-weight:500}.process-details-card{margin-bottom:var(--ymt-spacing-m)}.process-details-card mat-card-header{margin-bottom:var(--ymt-spacing-m);display:flex;align-items:flex-start}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: ProcessSummaryComponent, selector: "ymbpm-process-summary", inputs: ["process"] }, { kind: "component", type: ProcessTasksComponent, selector: "ymbpm-process-tasks", inputs: ["tasks"] }, { kind: "component", type: ProcessHistoryComponent, selector: "ymbpm-process-history", inputs: ["tasks"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2009
+ }
2010
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ProcessDetailsComponent, decorators: [{
2011
+ type: Component,
2012
+ args: [{ selector: 'ymbpm-process-details', standalone: true, imports: [
2013
+ CommonModule,
2014
+ MatCardModule,
2015
+ MatProgressSpinnerModule,
2016
+ MatButtonModule,
2017
+ MatIconModule,
2018
+ MatTooltipModule,
2019
+ TranslatePipe,
2020
+ ProcessSummaryComponent,
2021
+ ProcessTasksComponent,
2022
+ ProcessHistoryComponent,
2023
+ MatTabsModule
2024
+ ], template: "@if (loading()) {\n <div class=\"loading-container\">\n <mat-spinner diameter=\"40\"></mat-spinner>\n </div>\n} @else if (error()) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error() }}</p>\n </div>\n} @else if (process() && tasks()) {\n <section class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n <mat-tab-group [(selectedIndex)]=\"selectedTabIndex\">\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.summary' | translate\">\n <ymbpm-process-summary [process]=\"process()\"></ymbpm-process-summary>\n </mat-tab>\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.tasks' | translate\">\n <ymbpm-process-tasks [tasks]=\"tasks()\"></ymbpm-process-tasks>\n </mat-tab>\n <mat-tab [label]=\"'yuv.app.bpm-management.tabs.history' | translate\">\n <ymbpm-process-history [tasks]=\"tasks()\"></ymbpm-process-history>\n </mat-tab>\n </mat-tab-group>\n </section>\n}", styles: [":host{display:block}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--ymt-spacing-xl);gap:var(--ymt-spacing-m)}.loading-container p{color:var(--ymt-on-surface)}.error-card{margin-bottom:var(--ymt-spacing-m);background-color:var(--ymt-error-container)}.error-card .error-message{color:var(--ymt-on-error-container);font-weight:500}.process-details-card{margin-bottom:var(--ymt-spacing-m)}.process-details-card mat-card-header{margin-bottom:var(--ymt-spacing-m);display:flex;align-items:flex-start}\n"] }]
2025
+ }], ctorParameters: () => [], propDecorators: { processInstanceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "processInstanceId", required: false }] }] } });
2026
+
2027
+ class YuvProcessesPageComponent {
2028
+ layoutSettingsID = APP_ID + '#root.layout.settings';
2029
+ #logger = inject(Logger);
2030
+ #translateService = inject(TranslateService);
2031
+ #bpmAdminSerice = inject(YuvBpmAdminService);
2032
+ processDetailsComponent;
2033
+ bpmTableComponent;
2034
+ statusTemplate;
2035
+ ProcessStatus = ProcessStatus;
2036
+ pagination = {
2037
+ total: 0,
2038
+ pageSize: 50,
2039
+ page: 0
2040
+ };
2041
+ actions = [];
2042
+ icons = {
2043
+ ...APP_ICONS,
2044
+ };
2045
+ get displayedColumns() {
2046
+ return [
2047
+ {
2048
+ name: 'id',
2049
+ displayName: 'yuv.app.bpm-management.header.id',
2050
+ filter: {
2051
+ type: FILTER_TYPES.TEXT,
2052
+ operators: [FILTER_OPERATORS.EQUALS]
2053
+ }
2054
+ },
2055
+ {
2056
+ name: 'processDefinitionId',
2057
+ displayName: 'yuv.app.bpm-management.header.processDefinitionId',
2058
+ filter: {
2059
+ type: FILTER_TYPES.TEXT,
2060
+ operators: [FILTER_OPERATORS.EQUALS]
2061
+ }
2062
+ },
2063
+ {
2064
+ name: 'name',
2065
+ displayName: 'yuv.app.bpm-management.header.name',
2066
+ filter: {
2067
+ type: FILTER_TYPES.TEXT,
2068
+ operators: [FILTER_OPERATORS.CONTAINS, FILTER_OPERATORS.EQUALS, FILTER_OPERATORS.STARTS_WITH, FILTER_OPERATORS.ENDS_WITH]
2069
+ }
2070
+ },
2071
+ {
2072
+ name: 'status',
2073
+ displayName: 'yuv.app.bpm-management.header.status',
2074
+ template: this.statusTemplate,
2075
+ filter: {
2076
+ type: FILTER_TYPES.SELECT,
2077
+ options: [ProcessStatus.RUNNING_SUSPENDED, ProcessStatus.COMPLETED]
2078
+ }
2079
+ },
2080
+ {
2081
+ name: 'startUserId',
2082
+ displayName: 'yuv.app.bpm-management.header.startedBy',
2083
+ filter: {
2084
+ type: FILTER_TYPES.TEXT,
2085
+ operators: [FILTER_OPERATORS.EQUALS]
2086
+ }
2087
+ },
2088
+ {
2089
+ name: 'startTime',
2090
+ displayName: 'yuv.app.bpm-management.header.startTime',
2091
+ filter: {
2092
+ type: FILTER_TYPES.DATE,
2093
+ operators: [FILTER_OPERATORS.BEFORE, FILTER_OPERATORS.AFTER, FILTER_OPERATORS.BETWEEN]
2094
+ }
2095
+ },
2096
+ {
2097
+ name: 'endTime',
2098
+ displayName: 'yuv.app.bpm-management.header.endTime',
2099
+ filter: {
2100
+ type: FILTER_TYPES.DATE,
2101
+ operators: [FILTER_OPERATORS.BEFORE, FILTER_OPERATORS.AFTER, FILTER_OPERATORS.BETWEEN]
2102
+ }
2103
+ },
2104
+ {
2105
+ name: 'businessKey',
2106
+ displayName: 'yuv.app.bpm-management.header.businessKey',
2107
+ filter: {
2108
+ type: FILTER_TYPES.TEXT,
2109
+ operators: [FILTER_OPERATORS.CONTAINS, FILTER_OPERATORS.EQUALS, FILTER_OPERATORS.STARTS_WITH, FILTER_OPERATORS.ENDS_WITH]
2110
+ }
2111
+ },
2112
+ ];
2113
+ }
2114
+ // Filter state
2115
+ filter = new ProcessFilter();
2116
+ enableFilters = true;
2117
+ enableDetails = signal(false, ...(ngDevMode ? [{ debugName: "enableDetails" }] : /* istanbul ignore next */ []));
2118
+ layoutOptions = signal({
2119
+ resizable: true,
2120
+ detailsSize: 25,
2121
+ detailsMaxSize: 75
2122
+ }, ...(ngDevMode ? [{ debugName: "layoutOptions" }] : /* istanbul ignore next */ []));
2123
+ busy = signal(false, ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
2124
+ dataSource = signal([], ...(ngDevMode ? [{ debugName: "dataSource" }] : /* istanbul ignore next */ []));
2125
+ selection = signal(new SelectionModel(false, undefined), ...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
2126
+ currentPageSize = 50;
2127
+ ngOnInit() {
2128
+ this.#loadProcessList();
2129
+ }
2130
+ refresh() {
2131
+ this.#loadProcessList();
2132
+ this.processDetailsComponent?.loadProcessDetails();
2133
+ }
2134
+ onChangePage($event) {
2135
+ this.pagination.page = $event.pageIndex;
2136
+ this.pagination.pageSize = $event.pageSize;
2137
+ this.#loadProcessList();
2138
+ }
2139
+ onFiltersChange(filters) {
2140
+ this.filter = ProcessFilter.fromAgFilterModel(filters, this.#translateService);
2141
+ this.pagination.page = 0;
2142
+ this.#loadProcessList();
2143
+ }
2144
+ hasActiveFilters() {
2145
+ return this.filter ? Object.keys(this.filter).length > 0 : false;
2146
+ }
2147
+ #loadProcessList() {
2148
+ this.busy.set(true);
2149
+ this.#bpmAdminSerice.getProcesses(this.pagination.page, this.pagination.pageSize, this.filter).subscribe({
2150
+ next: (response) => {
2151
+ const formattedProcessObjects = response.objects.map(process => ({
2152
+ ...process,
2153
+ startTime: process.startTime ? formatDateTime(process.startTime, this.#translateService.currentLang) : process.startTime,
2154
+ endTime: process.endTime ? formatDateTime(process.endTime, this.#translateService.currentLang) : process.endTime
2155
+ }));
2156
+ this.dataSource.set(formattedProcessObjects);
2157
+ this.pagination.total = response.totalNumItems;
2158
+ },
2159
+ error: (e) => {
2160
+ this.#logger.error('Failed to fetch processes', e);
2161
+ this.busy.set(false);
2162
+ },
2163
+ complete: () => {
2164
+ this.busy.set(false);
2165
+ },
2166
+ });
2167
+ }
2168
+ onRowSelected(process) {
2169
+ this.selection().select(process);
2170
+ if (!this.enableDetails()) {
2171
+ this.enableDetails.set(true);
2172
+ }
2173
+ }
2174
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvProcessesPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2175
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: YuvProcessesPageComponent, isStandalone: true, selector: "ymbpm-processes-page", viewQueries: [{ propertyName: "processDetailsComponent", first: true, predicate: ProcessDetailsComponent, descendants: true }, { propertyName: "bpmTableComponent", first: true, predicate: BpmTableComponent, descendants: true }, { propertyName: "statusTemplate", first: true, predicate: ["statusTemplate"], descendants: true, static: true }], ngImport: i0, template: "<ng-template yuvAppHeaderSlot=\"actions\">\n</ng-template>\n\n<ymt-master-details-layout\n [detailsActive]=\"enableDetails()\"\n [options]=\"layoutOptions()\"\n [layoutSettingsID]=\"layoutSettingsID\">\n\n <ng-template ymtLayoutPane role=\"master\" [topBarActions]=\"masterPaneActions\">\n <ymt-pane-body>\n <ymbpm-table \n [busy]=\"busy()\"\n [dataSource]=\"dataSource()\" \n [columns]=\"displayedColumns\" \n [pagination]=\"pagination\" \n [selectedRow]=\"selection().selected.at(0)\"\n [enableFilters]=\"enableFilters\"\n (pageChange)=\"onChangePage($event)\"\n (rowSelected)=\"onRowSelected($event)\"\n (filtersChange)=\"onFiltersChange($event)\">\n </ymbpm-table>\n </ymt-pane-body>\n </ng-template>\n\n <ng-template ymtLayoutPane role=\"details\">\n @let selectedProcess = selection().selected.at(0);\n <ymt-pane-header [icon]=\"selectedProcess ? 'timeline' : undefined\" [title]=\"selectedProcess ? (selectedProcess.name || '&lt;unnamed&gt;') : ''\" [subtitle]=\"selectedProcess ? selectedProcess.id : ''\"></ymt-pane-header>\n <ymt-pane-body>\n <div class=\"detailsPaneContainer\">\n @if (selectedProcess) {\n <ymbpm-process-details [processInstanceId]=\"selectedProcess?.id\"></ymbpm-process-details>\n } @else {\n <div class=\"no-selection\">\n <mat-icon>{{icons.info}}</mat-icon>\n <p>{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </div>\n </ymt-pane-body>\n </ng-template>\n</ymt-master-details-layout>\n\n<ng-template #masterPaneActions>\n <div class=\"table-actions\">\n <button mat-icon-button *ngIf=\"this.enableFilters\" [disabled]=\"!hasActiveFilters()\" (click)=\"bpmTableComponent?.clearAllFilters()\" [matTooltip]=\"'yuv.app.bpm-management.filters.clearAll' | translate\">\n <mat-icon>{{icons.clearFilter}}</mat-icon>\n </button>\n <button mat-icon-button (click)=\"refresh()\" [matTooltip]=\"'yuv.app.bpm-management.navigation.refresh.tooltip' | translate\">\n <mat-icon>{{icons.refresh}}</mat-icon>\n </button>\n </div>\n</ng-template>\n\n<!-- Templates for table cells -->\n<ng-template #statusTemplate let-process>\n @if (process.endTime) {\n <span class=\"yuv-bpmn-status completed\">{{ProcessStatus.COMPLETED.label | translate}}</span>\n } @else if (process.suspended) {\n <span class=\"yuv-bpmn-status suspended\">{{ProcessStatus.SUSPENDED.label | translate}}</span>\n } @else {\n <span class=\"yuv-bpmn-status running\">{{ProcessStatus.RUNNING.label | translate}}</span>\n }\n</ng-template>", styles: [":host{--mat-table-row-item-outline-color: var(--ymt-outline-variant);height:100%;overflow:hidden;display:flex;flex-flow:column}:host ymt-master-details-layout{height:100%;padding:1rem}:host ymt-master-details-layout .detailsPaneContainer{display:flex;flex-direction:column;height:100%;overflow:auto}:host ymt-master-details-layout .detailsPaneContainer .no-selection{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}:host ymt-master-details-layout .detailsPaneContainer .no-selection mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:var(--ymt-spacing-m);opacity:.5}:host ymt-master-details-layout .detailsPaneContainer .no-selection p{font-size:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "ngmodule", type: MatSortModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: YuvClientShellModule }, { kind: "directive", type: i5$1.YuvAppHeaderSlotDirective, selector: "ng-template[yuvAppHeaderSlot]", inputs: ["yuvAppHeaderSlot"] }, { kind: "ngmodule", type: YuvMasterDetailsModule }, { kind: "ngmodule", type: YuvOverflowMenuModule }, { kind: "component", type: BpmTableComponent, selector: "ymbpm-table", inputs: ["columns", "dataSource", "enableFilters", "pagination", "selectedRow", "busy"], outputs: ["filtersChange", "pageChange", "rowSelected"] }, { kind: "component", type: ProcessDetailsComponent, selector: "ymbpm-process-details", inputs: ["processInstanceId"] }, { kind: "ngmodule", type: YmtLayoutModule }, { kind: "component", type: i6.MasterDetailsLayoutComponent, selector: "ymt-master-details-layout", inputs: ["layoutSettingsID", "options", "direction", "gutterSize", "detailsActive"], outputs: ["detailsActiveChange"] }, { kind: "directive", type: i6.YmtLayoutPaneDirective, selector: "[ymtLayoutPane]", inputs: ["role", "topBarActions"] }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i7.YmtPaneHeaderComponent, selector: "ymt-pane-header", inputs: ["title", "icon", "subtitle", "actions", "badges"] }, { kind: "component", type: i7.YmtPaneBodyComponent, selector: "ymt-pane-body" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2176
+ }
2177
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvProcessesPageComponent, decorators: [{
2178
+ type: Component,
2179
+ args: [{ selector: 'ymbpm-processes-page', standalone: true, imports: [
2180
+ CommonModule,
2181
+ MatButtonModule,
2182
+ MatIconModule,
2183
+ MatTooltipModule,
2184
+ MatTableModule,
2185
+ MatPaginatorModule,
2186
+ MatSortModule,
2187
+ RouterModule,
2188
+ TranslatePipe,
2189
+ YuvClientShellModule,
2190
+ YuvMasterDetailsModule,
2191
+ YuvOverflowMenuModule,
2192
+ BpmTableComponent,
2193
+ ProcessDetailsComponent,
2194
+ YmtLayoutModule,
2195
+ YmtPanesModule
2196
+ ], template: "<ng-template yuvAppHeaderSlot=\"actions\">\n</ng-template>\n\n<ymt-master-details-layout\n [detailsActive]=\"enableDetails()\"\n [options]=\"layoutOptions()\"\n [layoutSettingsID]=\"layoutSettingsID\">\n\n <ng-template ymtLayoutPane role=\"master\" [topBarActions]=\"masterPaneActions\">\n <ymt-pane-body>\n <ymbpm-table \n [busy]=\"busy()\"\n [dataSource]=\"dataSource()\" \n [columns]=\"displayedColumns\" \n [pagination]=\"pagination\" \n [selectedRow]=\"selection().selected.at(0)\"\n [enableFilters]=\"enableFilters\"\n (pageChange)=\"onChangePage($event)\"\n (rowSelected)=\"onRowSelected($event)\"\n (filtersChange)=\"onFiltersChange($event)\">\n </ymbpm-table>\n </ymt-pane-body>\n </ng-template>\n\n <ng-template ymtLayoutPane role=\"details\">\n @let selectedProcess = selection().selected.at(0);\n <ymt-pane-header [icon]=\"selectedProcess ? 'timeline' : undefined\" [title]=\"selectedProcess ? (selectedProcess.name || '&lt;unnamed&gt;') : ''\" [subtitle]=\"selectedProcess ? selectedProcess.id : ''\"></ymt-pane-header>\n <ymt-pane-body>\n <div class=\"detailsPaneContainer\">\n @if (selectedProcess) {\n <ymbpm-process-details [processInstanceId]=\"selectedProcess?.id\"></ymbpm-process-details>\n } @else {\n <div class=\"no-selection\">\n <mat-icon>{{icons.info}}</mat-icon>\n <p>{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </div>\n </ymt-pane-body>\n </ng-template>\n</ymt-master-details-layout>\n\n<ng-template #masterPaneActions>\n <div class=\"table-actions\">\n <button mat-icon-button *ngIf=\"this.enableFilters\" [disabled]=\"!hasActiveFilters()\" (click)=\"bpmTableComponent?.clearAllFilters()\" [matTooltip]=\"'yuv.app.bpm-management.filters.clearAll' | translate\">\n <mat-icon>{{icons.clearFilter}}</mat-icon>\n </button>\n <button mat-icon-button (click)=\"refresh()\" [matTooltip]=\"'yuv.app.bpm-management.navigation.refresh.tooltip' | translate\">\n <mat-icon>{{icons.refresh}}</mat-icon>\n </button>\n </div>\n</ng-template>\n\n<!-- Templates for table cells -->\n<ng-template #statusTemplate let-process>\n @if (process.endTime) {\n <span class=\"yuv-bpmn-status completed\">{{ProcessStatus.COMPLETED.label | translate}}</span>\n } @else if (process.suspended) {\n <span class=\"yuv-bpmn-status suspended\">{{ProcessStatus.SUSPENDED.label | translate}}</span>\n } @else {\n <span class=\"yuv-bpmn-status running\">{{ProcessStatus.RUNNING.label | translate}}</span>\n }\n</ng-template>", styles: [":host{--mat-table-row-item-outline-color: var(--ymt-outline-variant);height:100%;overflow:hidden;display:flex;flex-flow:column}:host ymt-master-details-layout{height:100%;padding:1rem}:host ymt-master-details-layout .detailsPaneContainer{display:flex;flex-direction:column;height:100%;overflow:auto}:host ymt-master-details-layout .detailsPaneContainer .no-selection{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}:host ymt-master-details-layout .detailsPaneContainer .no-selection mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:var(--ymt-spacing-m);opacity:.5}:host ymt-master-details-layout .detailsPaneContainer .no-selection p{font-size:1rem}\n"] }]
2197
+ }], propDecorators: { processDetailsComponent: [{
2198
+ type: ViewChild,
2199
+ args: [ProcessDetailsComponent]
2200
+ }], bpmTableComponent: [{
2201
+ type: ViewChild,
2202
+ args: [BpmTableComponent]
2203
+ }], statusTemplate: [{
2204
+ type: ViewChild,
2205
+ args: ['statusTemplate', { static: true }]
2206
+ }] } });
2207
+
2208
+ class TaskSummaryComponent {
2209
+ task = input(...(ngDevMode ? [undefined, { debugName: "task" }] : /* istanbul ignore next */ []));
2210
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
2211
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
2212
+ icons = {
2213
+ ...APP_ICONS
2214
+ };
2215
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: TaskSummaryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2216
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: TaskSummaryComponent, isStandalone: true, selector: "ymbpm-task-summary", inputs: { task: { classPropertyName: "task", publicName: "task", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<table class=\"details-table\">\n <tbody>\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.processInstanceId' | translate }}</td>\n <td class=\"field-value\">{{ task()?.processInstanceId }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.processInstanceName' | translate }}</td>\n <td class=\"field-value\">{{ task()?.processInstanceName || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.status' | translate }}</td>\n <td class=\"field-value\">\n @if (task()?.endTime) {\n <span class=\"yuv-bpmn-status completed\">{{ 'yuv.app.bpm-management.status.completed' | translate }}</span>\n } @else {\n <span class=\"yuv-bpmn-status running\">{{ 'yuv.app.bpm-management.status.running' | translate }}</span>\n }\n @if (task()?.delegationState) {\n @if (task()?.delegationState === 'pending') {\n <span class=\"yuv-bpmn-status running\">\n <mat-icon>{{ icons.delegated }}</mat-icon>\n {{ 'yuv.app.bpm-management.task.delegationState.pending' | translate }}\n </span>\n } @else {\n <span class=\"yuv-bpmn-status completed\">\n <mat-icon>{{ icons.resolved }}</mat-icon>\n {{ 'yuv.app.bpm-management.task.delegationState.resolved' | translate }}\n </span>\n }\n }\n </td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.description' | translate }}</td>\n <td class=\"field-value\">{{ task()?.description || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.assignee' | translate }}</td>\n <td class=\"field-value\">{{ task()?.assignee || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.owner' | translate }}</td>\n <td class=\"field-value\">{{ task()?.owner || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.taskDefinitionKey' | translate }}</td>\n <td class=\"field-value\">{{ task()?.taskDefinitionKey }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.formKey' | translate }}</td>\n <td class=\"field-value\">{{ task()?.formKey || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.createTime' | translate }}</td>\n <td class=\"field-value\">{{ ((task()?.createTime ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.claimTime' | translate }}</td>\n <td class=\"field-value\">{{ ((task()?.claimTime ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.dueDate' | translate }}</td>\n <td class=\"field-value\">{{ ((task()?.dueDate ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.endTime' | translate }}</td>\n <td class=\"field-value\">{{ ((task()?.endTime ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n \n </tbody>\n</table>\n", styles: [".details-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-bottom:var(--ymt-spacing-m)}.details-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.details-table tbody tr:hover{background-color:var(--ymt-surface-container-low)}.details-table tbody tr td{padding:var(--ymt-spacing-s);vertical-align:top}.details-table tbody tr td.field-label{font-weight:700;color:var(--ymt-on-surface);font-size:.875rem;word-break:break-word;width:20%}.details-table tbody tr td.field-value{font-size:1rem;color:var(--ymt-on-surface);word-break:break-word;width:80%}.details-table tbody tr td.field-value ::ng-deep .yuv-bpmn-status{margin-right:5px;display:inline-flex;align-items:center;gap:4px;vertical-align:middle}.details-table tbody tr td.field-value ::ng-deep .yuv-bpmn-status mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.variables-section{margin-top:var(--ymt-spacing-m)}.variables-section .variables-title{font-weight:500;color:var(--ymt-on-surface);font-size:.875rem;margin-bottom:var(--ymt-spacing-s);font-weight:700}.variables-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-top:var(--ymt-spacing-xs);font-family:monospace;font-size:.875rem}.variables-table thead{background-color:var(--ymt-surface-container)}.variables-table thead th{text-align:left;padding:var(--ymt-spacing-s);font-weight:600;color:var(--ymt-on-surface);border-bottom:2px solid var(--ymt-outline-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.variables-table thead th:nth-child(1){width:20%}.variables-table thead th:nth-child(2){width:15%}.variables-table thead th:nth-child(3){width:65%}.variables-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.variables-table tbody tr:hover{background-color:var(--ymt-surface-container-high)}.variables-table tbody tr td{padding:var(--ymt-spacing-s);color:var(--ymt-on-surface);overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;max-width:0}.variables-table tbody tr td.variable-name{font-weight:600;color:var(--ymt-primary)}.variables-table tbody tr td.variable-type{color:var(--ymt-on-surface);font-style:italic}.variables-table tbody tr td.variable-value{word-break:break-word;overflow-wrap:break-word;white-space:normal}.variables-table tbody tr td.variable-scope{color:var(--ymt-tertiary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }] });
2217
+ }
2218
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: TaskSummaryComponent, decorators: [{
2219
+ type: Component,
2220
+ args: [{ selector: 'ymbpm-task-summary', standalone: true, imports: [
2221
+ CommonModule,
2222
+ MatCardModule,
2223
+ MatProgressSpinnerModule,
2224
+ MatButtonModule,
2225
+ MatIconModule,
2226
+ MatTooltipModule,
2227
+ TranslatePipe,
2228
+ FormatDateTimePipe
2229
+ ], template: "<table class=\"details-table\">\n <tbody>\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.processInstanceId' | translate }}</td>\n <td class=\"field-value\">{{ task()?.processInstanceId }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.processInstanceName' | translate }}</td>\n <td class=\"field-value\">{{ task()?.processInstanceName || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.status' | translate }}</td>\n <td class=\"field-value\">\n @if (task()?.endTime) {\n <span class=\"yuv-bpmn-status completed\">{{ 'yuv.app.bpm-management.status.completed' | translate }}</span>\n } @else {\n <span class=\"yuv-bpmn-status running\">{{ 'yuv.app.bpm-management.status.running' | translate }}</span>\n }\n @if (task()?.delegationState) {\n @if (task()?.delegationState === 'pending') {\n <span class=\"yuv-bpmn-status running\">\n <mat-icon>{{ icons.delegated }}</mat-icon>\n {{ 'yuv.app.bpm-management.task.delegationState.pending' | translate }}\n </span>\n } @else {\n <span class=\"yuv-bpmn-status completed\">\n <mat-icon>{{ icons.resolved }}</mat-icon>\n {{ 'yuv.app.bpm-management.task.delegationState.resolved' | translate }}\n </span>\n }\n }\n </td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.description' | translate }}</td>\n <td class=\"field-value\">{{ task()?.description || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.assignee' | translate }}</td>\n <td class=\"field-value\">{{ task()?.assignee || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.owner' | translate }}</td>\n <td class=\"field-value\">{{ task()?.owner || '-' }}</td>\n </tr>\n\n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.taskDefinitionKey' | translate }}</td>\n <td class=\"field-value\">{{ task()?.taskDefinitionKey }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.formKey' | translate }}</td>\n <td class=\"field-value\">{{ task()?.formKey || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.createTime' | translate }}</td>\n <td class=\"field-value\">{{ ((task()?.createTime ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.claimTime' | translate }}</td>\n <td class=\"field-value\">{{ ((task()?.claimTime ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.task.details.dueDate' | translate }}</td>\n <td class=\"field-value\">{{ ((task()?.dueDate ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n \n <tr>\n <td class=\"field-label\">{{ 'yuv.app.bpm-management.header.endTime' | translate }}</td>\n <td class=\"field-value\">{{ ((task()?.endTime ?? null) | formatDateTime) || '-' }}</td>\n </tr>\n \n </tbody>\n</table>\n", styles: [".details-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-bottom:var(--ymt-spacing-m)}.details-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.details-table tbody tr:hover{background-color:var(--ymt-surface-container-low)}.details-table tbody tr td{padding:var(--ymt-spacing-s);vertical-align:top}.details-table tbody tr td.field-label{font-weight:700;color:var(--ymt-on-surface);font-size:.875rem;word-break:break-word;width:20%}.details-table tbody tr td.field-value{font-size:1rem;color:var(--ymt-on-surface);word-break:break-word;width:80%}.details-table tbody tr td.field-value ::ng-deep .yuv-bpmn-status{margin-right:5px;display:inline-flex;align-items:center;gap:4px;vertical-align:middle}.details-table tbody tr td.field-value ::ng-deep .yuv-bpmn-status mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.variables-section{margin-top:var(--ymt-spacing-m)}.variables-section .variables-title{font-weight:500;color:var(--ymt-on-surface);font-size:.875rem;margin-bottom:var(--ymt-spacing-s);font-weight:700}.variables-table{width:100%;table-layout:fixed;border-collapse:collapse;margin-top:var(--ymt-spacing-xs);font-family:monospace;font-size:.875rem}.variables-table thead{background-color:var(--ymt-surface-container)}.variables-table thead th{text-align:left;padding:var(--ymt-spacing-s);font-weight:600;color:var(--ymt-on-surface);border-bottom:2px solid var(--ymt-outline-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.variables-table thead th:nth-child(1){width:20%}.variables-table thead th:nth-child(2){width:15%}.variables-table thead th:nth-child(3){width:65%}.variables-table tbody tr{border-bottom:1px solid var(--ymt-outline-variant)}.variables-table tbody tr:hover{background-color:var(--ymt-surface-container-high)}.variables-table tbody tr td{padding:var(--ymt-spacing-s);color:var(--ymt-on-surface);overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;max-width:0}.variables-table tbody tr td.variable-name{font-weight:600;color:var(--ymt-primary)}.variables-table tbody tr td.variable-type{color:var(--ymt-on-surface);font-style:italic}.variables-table tbody tr td.variable-value{word-break:break-word;overflow-wrap:break-word;white-space:normal}.variables-table tbody tr td.variable-scope{color:var(--ymt-tertiary)}\n"] }]
2230
+ }], propDecorators: { task: [{ type: i0.Input, args: [{ isSignal: true, alias: "task", required: false }] }] } });
2231
+
2232
+ class EditorHistoryComponent {
2233
+ translateService = inject(TranslateService);
2234
+ task = input(...(ngDevMode ? [undefined, { debugName: "task" }] : /* istanbul ignore next */ []));
2235
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
2236
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
2237
+ formatDateTime = formatDateTime;
2238
+ icons = {
2239
+ ...APP_ICONS
2240
+ };
2241
+ get candidateUsers() {
2242
+ return this.task()?.identityLinks?.candidates?.users || [];
2243
+ }
2244
+ get candidateRoles() {
2245
+ return this.task()?.identityLinks?.candidates?.roles || [];
2246
+ }
2247
+ get assignmentHistory() {
2248
+ return this.task()?.identityLinks?.assignmentHistory || [];
2249
+ }
2250
+ getActionIcon(type, assignee) {
2251
+ switch (type) {
2252
+ case 'ASSIGNMENT':
2253
+ return assignee !== null ? 'person_add' : 'person_off';
2254
+ case 'DELEGATION':
2255
+ return this.icons.delegated;
2256
+ case 'RESOLVE':
2257
+ return this.icons.resolved;
2258
+ default:
2259
+ return 'info';
2260
+ }
2261
+ }
2262
+ getActionLabel(type, assignee) {
2263
+ if (type === 'ASSIGNMENT') {
2264
+ return assignee !== null ?
2265
+ 'yuv.app.bpm-management.task.details.actionType.assignment'
2266
+ : 'yuv.app.bpm-management.task.details.actionType.assignmentRemoved';
2267
+ }
2268
+ return `yuv.app.bpm-management.task.details.actionType.${type.toLowerCase()}`;
2269
+ }
2270
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EditorHistoryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2271
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EditorHistoryComponent, isStandalone: true, selector: "ymbpm-editor-history", inputs: { task: { classPropertyName: "task", publicName: "task", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"editor-history-container\">\n <!-- Candidate Users Section -->\n <div class=\"candidates-section\">\n <h3 class=\"section-title\">\n <mat-icon>person</mat-icon>\n {{ 'yuv.app.bpm-management.task.details.candidateUsers' | translate }}\n </h3>\n @if (candidateUsers.length > 0) {\n <div class=\"candidates-list\">\n @for (user of candidateUsers; track user) {\n <span class=\"candidate-chip\">\n <mat-icon>person</mat-icon>\n {{ user }}\n </span>\n }\n </div>\n } @else {\n <p class=\"no-data\">{{ 'yuv.app.bpm-management.task.details.noCandidateUsers' | translate }}</p>\n }\n </div>\n\n <!-- Candidate Roles Section -->\n <div class=\"candidates-section\">\n <h3 class=\"section-title\">\n <mat-icon>group</mat-icon>\n {{ 'yuv.app.bpm-management.task.details.candidateRoles' | translate }}\n </h3>\n @if (candidateRoles.length > 0) {\n <div class=\"candidates-list\">\n @for (role of candidateRoles; track role) {\n <span class=\"candidate-chip\">\n <mat-icon>group</mat-icon>\n {{ role }}\n </span>\n }\n </div>\n } @else {\n <p class=\"no-data\">{{ 'yuv.app.bpm-management.task.details.noCandidateRoles' | translate }}</p>\n }\n </div>\n\n <!-- Assignment History Section -->\n <div class=\"history-section\">\n <h3 class=\"section-title\">\n <mat-icon>history</mat-icon>\n {{ 'yuv.app.bpm-management.task.details.assignmentHistory' | translate }}\n </h3>\n \n @if (assignmentHistory.length === 0) {\n <p class=\"no-data\">{{ 'yuv.app.bpm-management.task.details.noAssignmentHistory' | translate }}</p>\n } @else {\n <div class=\"timeline-container\" [ngClass]=\"{singleEntry: assignmentHistory.length === 1}\">\n @for (entry of assignmentHistory; track entry.timestamp) {\n <div class=\"timeline-item\">\n <div class=\"timeline-datetime\">\n <div class=\"date\">{{ formatDateTime(entry.timestamp, translateService.currentLang, 'date') }}</div>\n <div class=\"time\">{{ formatDateTime(entry.timestamp, translateService.currentLang, 'time') }}</div>\n </div>\n \n <div class=\"timeline-line\"></div>\n \n <div class=\"timeline-content\">\n <div class=\"history-card\">\n <div class=\"action-header\">\n <mat-icon class=\"action-icon\">{{ getActionIcon(entry.type, entry.assignee) }}</mat-icon>\n <span class=\"action-label\">{{ getActionLabel(entry.type, entry.assignee) | translate }}</span>\n </div>\n @if (entry.assignee) {\n <div class=\"assignee-info\">\n <span class=\"label\">{{ 'yuv.app.bpm-management.task.details.assignee' | translate }}:</span>\n <span>{{ entry.assignee }}</span>\n </div>\n }\n @if (entry.owner && entry.type !== 'RESOLVE') {\n <div class=\"assignee-info\">\n <span class=\"label\">{{ 'yuv.app.bpm-management.task.details.owner' | translate }}:</span>\n <span>{{ entry.owner }}</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;padding:var(--ymt-spacing-m)}.editor-history-container{display:flex;flex-direction:column;gap:var(--ymt-spacing-3xl)}.candidates-section .section-title,.history-section .section-title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-m) 0;font-family:var(--ymt-font-title-small-font);font-size:var(--ymt-font-title-small-size);font-weight:var(--ymt-font-title-small-weight);line-height:var(--ymt-font-title-small-line-height);color:var(--ymt-on-surface)}.candidates-section .section-title mat-icon,.history-section .section-title mat-icon{font-size:var(--ymt-sizing-m);width:var(--ymt-sizing-m);height:var(--ymt-sizing-m);color:var(--ymt-primary)}.candidates-section .no-data,.history-section .no-data{color:var(--ymt-on-surface-type-subtle);font-family:var(--ymt-font-body-subtle-font);font-size:var(--ymt-font-body-subtle-size);font-weight:var(--ymt-font-body-subtle-weight);line-height:var(--ymt-font-body-subtle-line-height);font-style:italic;margin:0}.candidates-list{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-s)}.candidate-chip{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-s);background-color:var(--ymt-surface-container);border-radius:var(--ymt-corner-full);font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);font-weight:var(--ymt-font-body-weight);line-height:var(--ymt-font-body-line-height);color:var(--ymt-on-surface)}.candidate-chip mat-icon{font-size:var(--ymt-sizing-xs);width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs);color:var(--ymt-on-surface-type-subtle)}.timeline-container{display:flex;flex-flow:column;overflow-y:auto;align-items:center;padding:var(--ymt-spacing-xs) 0}.timeline-container:not(.singleEntry) .timeline-item .timeline-line:after{content:\"\";width:53%;display:block;border-width:0 3px 0 0;border-style:solid;border-color:var(--ymt-outline-variant);position:absolute;top:0;bottom:0;z-index:1}.timeline-container:not(.singleEntry) .timeline-item:first-child .timeline-line:after{top:initial;height:50%}.timeline-container:not(.singleEntry) .timeline-item:last-child .timeline-line:after{bottom:initial;height:50%}.timeline-container .timeline-item{display:grid;grid-template-rows:1fr;grid-template-columns:1fr auto 4fr;grid-template-areas:\"created timeline content\"}.timeline-container .timeline-item:last-child{margin-bottom:0}.timeline-container .timeline-item .timeline-datetime{grid-area:created;display:flex;flex-flow:column;justify-content:center;padding:0 var(--ymt-spacing-xs);width:100px}.timeline-container .timeline-item .timeline-datetime .date{font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);font-weight:500;color:var(--ymt-on-surface);line-height:1.2}.timeline-container .timeline-item .timeline-datetime .time{font-family:var(--ymt-font-body-subtle-font);font-size:var(--ymt-font-body-subtle-size);font-weight:var(--ymt-font-body-subtle-weight);line-height:var(--ymt-font-body-subtle-line-height);color:var(--ymt-on-surface-type-subtle);margin-top:var(--ymt-spacing-3xs)}.timeline-container .timeline-item .timeline-line{grid-area:timeline;display:flex;flex-flow:column;justify-content:center;width:var(--ymt-sizing-3xl);position:relative}.timeline-container .timeline-item .timeline-line:before{content:\"\";display:block;width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);border-radius:50%;background-color:var(--ymt-primary);border:3px solid var(--ymt-surface);box-shadow:0 0 0 2px var(--ymt-primary);z-index:2;align-self:center}.timeline-container .timeline-item .timeline-content{grid-area:content;padding:var(--ymt-spacing-xs);box-sizing:border-box;display:flex}.timeline-container .timeline-item .timeline-content .history-card{width:100%;min-width:420px;background-color:var(--ymt-surface-container-high);border:var(--ymt-outline-width) solid var(--ymt-outline-variant-emphasized);border-radius:var(--ymt-corner-m);padding:var(--ymt-spacing-m);display:flex;flex-direction:column;gap:var(--ymt-spacing-s)}.timeline-container .timeline-item .timeline-content .history-card .action-header{display:flex;align-items:center;gap:var(--ymt-spacing-xs)}.timeline-container .timeline-item .timeline-content .history-card .action-header .action-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);color:var(--ymt-primary)}.timeline-container .timeline-item .timeline-content .history-card .action-header .action-label{font-family:var(--ymt-font-title-smallest-font);font-size:var(--ymt-font-title-smallest-size);font-weight:var(--ymt-font-title-smallest-weight);line-height:var(--ymt-font-title-smallest-line-height);color:var(--ymt-on-surface)}.timeline-container .timeline-item .timeline-content .history-card .assignee-info{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);padding-left:var(--ymt-spacing-2xl);font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);font-weight:var(--ymt-font-body-weight);line-height:var(--ymt-font-body-line-height);color:var(--ymt-on-surface)}.timeline-container .timeline-item .timeline-content .history-card .assignee-info .label{font-family:var(--ymt-font-body-subtle-font);font-size:var(--ymt-font-body-subtle-size);font-weight:var(--ymt-font-body-subtle-weight);line-height:var(--ymt-font-body-subtle-line-height);color:var(--ymt-on-surface-type-subtle)}@media(max-width:768px){.timeline-datetime{min-width:80px;padding-right:var(--ymt-spacing-xs)}.timeline-datetime .date{font-size:12px}.timeline-datetime .time{font-size:11px}.timeline-content{padding-left:var(--ymt-spacing-xs)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2272
+ }
2273
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EditorHistoryComponent, decorators: [{
2274
+ type: Component,
2275
+ args: [{ selector: 'ymbpm-editor-history', standalone: true, imports: [
2276
+ CommonModule,
2277
+ MatCardModule,
2278
+ MatProgressSpinnerModule,
2279
+ MatButtonModule,
2280
+ MatIconModule,
2281
+ MatTooltipModule,
2282
+ TranslatePipe
2283
+ ], template: "<div class=\"editor-history-container\">\n <!-- Candidate Users Section -->\n <div class=\"candidates-section\">\n <h3 class=\"section-title\">\n <mat-icon>person</mat-icon>\n {{ 'yuv.app.bpm-management.task.details.candidateUsers' | translate }}\n </h3>\n @if (candidateUsers.length > 0) {\n <div class=\"candidates-list\">\n @for (user of candidateUsers; track user) {\n <span class=\"candidate-chip\">\n <mat-icon>person</mat-icon>\n {{ user }}\n </span>\n }\n </div>\n } @else {\n <p class=\"no-data\">{{ 'yuv.app.bpm-management.task.details.noCandidateUsers' | translate }}</p>\n }\n </div>\n\n <!-- Candidate Roles Section -->\n <div class=\"candidates-section\">\n <h3 class=\"section-title\">\n <mat-icon>group</mat-icon>\n {{ 'yuv.app.bpm-management.task.details.candidateRoles' | translate }}\n </h3>\n @if (candidateRoles.length > 0) {\n <div class=\"candidates-list\">\n @for (role of candidateRoles; track role) {\n <span class=\"candidate-chip\">\n <mat-icon>group</mat-icon>\n {{ role }}\n </span>\n }\n </div>\n } @else {\n <p class=\"no-data\">{{ 'yuv.app.bpm-management.task.details.noCandidateRoles' | translate }}</p>\n }\n </div>\n\n <!-- Assignment History Section -->\n <div class=\"history-section\">\n <h3 class=\"section-title\">\n <mat-icon>history</mat-icon>\n {{ 'yuv.app.bpm-management.task.details.assignmentHistory' | translate }}\n </h3>\n \n @if (assignmentHistory.length === 0) {\n <p class=\"no-data\">{{ 'yuv.app.bpm-management.task.details.noAssignmentHistory' | translate }}</p>\n } @else {\n <div class=\"timeline-container\" [ngClass]=\"{singleEntry: assignmentHistory.length === 1}\">\n @for (entry of assignmentHistory; track entry.timestamp) {\n <div class=\"timeline-item\">\n <div class=\"timeline-datetime\">\n <div class=\"date\">{{ formatDateTime(entry.timestamp, translateService.currentLang, 'date') }}</div>\n <div class=\"time\">{{ formatDateTime(entry.timestamp, translateService.currentLang, 'time') }}</div>\n </div>\n \n <div class=\"timeline-line\"></div>\n \n <div class=\"timeline-content\">\n <div class=\"history-card\">\n <div class=\"action-header\">\n <mat-icon class=\"action-icon\">{{ getActionIcon(entry.type, entry.assignee) }}</mat-icon>\n <span class=\"action-label\">{{ getActionLabel(entry.type, entry.assignee) | translate }}</span>\n </div>\n @if (entry.assignee) {\n <div class=\"assignee-info\">\n <span class=\"label\">{{ 'yuv.app.bpm-management.task.details.assignee' | translate }}:</span>\n <span>{{ entry.assignee }}</span>\n </div>\n }\n @if (entry.owner && entry.type !== 'RESOLVE') {\n <div class=\"assignee-info\">\n <span class=\"label\">{{ 'yuv.app.bpm-management.task.details.owner' | translate }}:</span>\n <span>{{ entry.owner }}</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;padding:var(--ymt-spacing-m)}.editor-history-container{display:flex;flex-direction:column;gap:var(--ymt-spacing-3xl)}.candidates-section .section-title,.history-section .section-title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-m) 0;font-family:var(--ymt-font-title-small-font);font-size:var(--ymt-font-title-small-size);font-weight:var(--ymt-font-title-small-weight);line-height:var(--ymt-font-title-small-line-height);color:var(--ymt-on-surface)}.candidates-section .section-title mat-icon,.history-section .section-title mat-icon{font-size:var(--ymt-sizing-m);width:var(--ymt-sizing-m);height:var(--ymt-sizing-m);color:var(--ymt-primary)}.candidates-section .no-data,.history-section .no-data{color:var(--ymt-on-surface-type-subtle);font-family:var(--ymt-font-body-subtle-font);font-size:var(--ymt-font-body-subtle-size);font-weight:var(--ymt-font-body-subtle-weight);line-height:var(--ymt-font-body-subtle-line-height);font-style:italic;margin:0}.candidates-list{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-s)}.candidate-chip{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-s);background-color:var(--ymt-surface-container);border-radius:var(--ymt-corner-full);font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);font-weight:var(--ymt-font-body-weight);line-height:var(--ymt-font-body-line-height);color:var(--ymt-on-surface)}.candidate-chip mat-icon{font-size:var(--ymt-sizing-xs);width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs);color:var(--ymt-on-surface-type-subtle)}.timeline-container{display:flex;flex-flow:column;overflow-y:auto;align-items:center;padding:var(--ymt-spacing-xs) 0}.timeline-container:not(.singleEntry) .timeline-item .timeline-line:after{content:\"\";width:53%;display:block;border-width:0 3px 0 0;border-style:solid;border-color:var(--ymt-outline-variant);position:absolute;top:0;bottom:0;z-index:1}.timeline-container:not(.singleEntry) .timeline-item:first-child .timeline-line:after{top:initial;height:50%}.timeline-container:not(.singleEntry) .timeline-item:last-child .timeline-line:after{bottom:initial;height:50%}.timeline-container .timeline-item{display:grid;grid-template-rows:1fr;grid-template-columns:1fr auto 4fr;grid-template-areas:\"created timeline content\"}.timeline-container .timeline-item:last-child{margin-bottom:0}.timeline-container .timeline-item .timeline-datetime{grid-area:created;display:flex;flex-flow:column;justify-content:center;padding:0 var(--ymt-spacing-xs);width:100px}.timeline-container .timeline-item .timeline-datetime .date{font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);font-weight:500;color:var(--ymt-on-surface);line-height:1.2}.timeline-container .timeline-item .timeline-datetime .time{font-family:var(--ymt-font-body-subtle-font);font-size:var(--ymt-font-body-subtle-size);font-weight:var(--ymt-font-body-subtle-weight);line-height:var(--ymt-font-body-subtle-line-height);color:var(--ymt-on-surface-type-subtle);margin-top:var(--ymt-spacing-3xs)}.timeline-container .timeline-item .timeline-line{grid-area:timeline;display:flex;flex-flow:column;justify-content:center;width:var(--ymt-sizing-3xl);position:relative}.timeline-container .timeline-item .timeline-line:before{content:\"\";display:block;width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);border-radius:50%;background-color:var(--ymt-primary);border:3px solid var(--ymt-surface);box-shadow:0 0 0 2px var(--ymt-primary);z-index:2;align-self:center}.timeline-container .timeline-item .timeline-content{grid-area:content;padding:var(--ymt-spacing-xs);box-sizing:border-box;display:flex}.timeline-container .timeline-item .timeline-content .history-card{width:100%;min-width:420px;background-color:var(--ymt-surface-container-high);border:var(--ymt-outline-width) solid var(--ymt-outline-variant-emphasized);border-radius:var(--ymt-corner-m);padding:var(--ymt-spacing-m);display:flex;flex-direction:column;gap:var(--ymt-spacing-s)}.timeline-container .timeline-item .timeline-content .history-card .action-header{display:flex;align-items:center;gap:var(--ymt-spacing-xs)}.timeline-container .timeline-item .timeline-content .history-card .action-header .action-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);color:var(--ymt-primary)}.timeline-container .timeline-item .timeline-content .history-card .action-header .action-label{font-family:var(--ymt-font-title-smallest-font);font-size:var(--ymt-font-title-smallest-size);font-weight:var(--ymt-font-title-smallest-weight);line-height:var(--ymt-font-title-smallest-line-height);color:var(--ymt-on-surface)}.timeline-container .timeline-item .timeline-content .history-card .assignee-info{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);padding-left:var(--ymt-spacing-2xl);font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);font-weight:var(--ymt-font-body-weight);line-height:var(--ymt-font-body-line-height);color:var(--ymt-on-surface)}.timeline-container .timeline-item .timeline-content .history-card .assignee-info .label{font-family:var(--ymt-font-body-subtle-font);font-size:var(--ymt-font-body-subtle-size);font-weight:var(--ymt-font-body-subtle-weight);line-height:var(--ymt-font-body-subtle-line-height);color:var(--ymt-on-surface-type-subtle)}@media(max-width:768px){.timeline-datetime{min-width:80px;padding-right:var(--ymt-spacing-xs)}.timeline-datetime .date{font-size:12px}.timeline-datetime .time{font-size:11px}.timeline-content{padding-left:var(--ymt-spacing-xs)}}\n"] }]
2284
+ }], propDecorators: { task: [{ type: i0.Input, args: [{ isSignal: true, alias: "task", required: false }] }] } });
2285
+
2286
+ class TaskDetailsComponent {
2287
+ #translateService = inject(TranslateService);
2288
+ #bpmAdminService = inject(YuvBpmAdminService);
2289
+ taskId = input(...(ngDevMode ? [undefined, { debugName: "taskId" }] : /* istanbul ignore next */ []));
2290
+ task = signal(undefined, ...(ngDevMode ? [{ debugName: "task" }] : /* istanbul ignore next */ []));
2291
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
2292
+ error = signal(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
2293
+ selectedTabIndex = 0;
2294
+ constructor() {
2295
+ effect(() => {
2296
+ this.loadTaskDetails();
2297
+ });
2298
+ }
2299
+ loadTaskDetails() {
2300
+ this.loading.set(true);
2301
+ this.error.set(undefined);
2302
+ const id = this.taskId();
2303
+ if (id) {
2304
+ forkJoin({
2305
+ task: this.#bpmAdminService.getTask(id).pipe(catchError(err => {
2306
+ this.error.set(this.#translateService.instant('yuv.app.bpm-management.details.error'));
2307
+ console.error('Error loading process details:', err);
2308
+ return of(null);
2309
+ }))
2310
+ }).subscribe(({ task }) => {
2311
+ this.task.set(task || undefined);
2312
+ this.loading.set(false);
2313
+ });
2314
+ }
2315
+ else {
2316
+ this.task.set(undefined);
2317
+ }
2318
+ }
2319
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: TaskDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2320
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: TaskDetailsComponent, isStandalone: true, selector: "ymbpm-task-details", inputs: { taskId: { classPropertyName: "taskId", publicName: "taskId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (loading()) {\n <div class=\"loading-container\">\n <mat-spinner diameter=\"40\"></mat-spinner>\n </div>\n} @else if (error()) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error() }}</p>\n </div>\n} @else if (task()) {\n <section class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n <mat-tab-group [(selectedIndex)]=\"selectedTabIndex\">\n <mat-tab label=\"{{ 'yuv.app.bpm-management.tabs.summary' | translate }}\">\n <ymbpm-task-summary [task]=\"task()\"></ymbpm-task-summary>\n </mat-tab>\n <mat-tab label=\"{{ 'yuv.app.bpm-management.tabs.editorHistory' | translate }}\">\n <ymbpm-editor-history [task]=\"task()\"></ymbpm-editor-history>\n </mat-tab>\n </mat-tab-group>\n </section>\n}\n", styles: [":host{display:block}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--ymt-spacing-xl);gap:var(--ymt-spacing-m)}.loading-container p{color:var(--ymt-on-surface)}.error-card{margin-bottom:var(--ymt-spacing-m);background-color:var(--ymt-error-container)}.error-card .error-message{color:var(--ymt-on-error-container);font-weight:500}.task-details-card{margin-bottom:var(--ymt-spacing-m)}.task-details-card mat-card-header{margin-bottom:var(--ymt-spacing-m);display:flex;align-items:flex-start}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatCardModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: TaskSummaryComponent, selector: "ymbpm-task-summary", inputs: ["task"] }, { kind: "component", type: EditorHistoryComponent, selector: "ymbpm-editor-history", inputs: ["task"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2321
+ }
2322
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: TaskDetailsComponent, decorators: [{
2323
+ type: Component,
2324
+ args: [{ selector: 'ymbpm-task-details', standalone: true, imports: [
2325
+ CommonModule,
2326
+ MatCardModule,
2327
+ MatProgressSpinnerModule,
2328
+ MatButtonModule,
2329
+ MatIconModule,
2330
+ MatTooltipModule,
2331
+ TranslatePipe,
2332
+ MatTabsModule,
2333
+ TaskSummaryComponent,
2334
+ EditorHistoryComponent
2335
+ ], template: "@if (loading()) {\n <div class=\"loading-container\">\n <mat-spinner diameter=\"40\"></mat-spinner>\n </div>\n} @else if (error()) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error() }}</p>\n </div>\n} @else if (task()) {\n <section class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n <mat-tab-group [(selectedIndex)]=\"selectedTabIndex\">\n <mat-tab label=\"{{ 'yuv.app.bpm-management.tabs.summary' | translate }}\">\n <ymbpm-task-summary [task]=\"task()\"></ymbpm-task-summary>\n </mat-tab>\n <mat-tab label=\"{{ 'yuv.app.bpm-management.tabs.editorHistory' | translate }}\">\n <ymbpm-editor-history [task]=\"task()\"></ymbpm-editor-history>\n </mat-tab>\n </mat-tab-group>\n </section>\n}\n", styles: [":host{display:block}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--ymt-spacing-xl);gap:var(--ymt-spacing-m)}.loading-container p{color:var(--ymt-on-surface)}.error-card{margin-bottom:var(--ymt-spacing-m);background-color:var(--ymt-error-container)}.error-card .error-message{color:var(--ymt-on-error-container);font-weight:500}.task-details-card{margin-bottom:var(--ymt-spacing-m)}.task-details-card mat-card-header{margin-bottom:var(--ymt-spacing-m);display:flex;align-items:flex-start}\n"] }]
2336
+ }], ctorParameters: () => [], propDecorators: { taskId: [{ type: i0.Input, args: [{ isSignal: true, alias: "taskId", required: false }] }] } });
2337
+
2338
+ class TaskAssignOverlayComponent {
2339
+ #dialogRef = inject((MatDialogRef));
2340
+ data = inject(MAT_DIALOG_DATA);
2341
+ userControl = new FormControl('');
2342
+ close() {
2343
+ this.#dialogRef.close();
2344
+ }
2345
+ confirm() {
2346
+ const assignee = this.userControl.value;
2347
+ if (assignee && assignee.trim()) {
2348
+ this.#dialogRef.close(assignee.trim());
2349
+ }
2350
+ }
2351
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: TaskAssignOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2352
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: TaskAssignOverlayComponent, isStandalone: true, selector: "ymbpm-task-assign-overlay", ngImport: i0, template: "<yuv-dialog [headertitle]=\"'yuv.app.bpm-management.task.actions.assign.label' | translate\">\n <main >\n <mat-label>{{ 'yuv.app.bpm-management.task.actions.assign.assignee.label' | translate }}</mat-label>\n <yuv-organization [formControl]=\"userControl\" [excludeMe]='false' />\n </main>\n <footer>\n <button ymtButton=\"secondary\" (click)=\"close()\" type=\"button\">\n {{ \"yuv.app.bpm-management.action.cancel.label\" | translate }}\n </button>\n <button ymtButton=\"primary\" (click)=\"confirm()\" type=\"button\" [disabled]=\"this.userControl.touched && this.userControl.dirty\">\n {{ 'yuv.app.bpm-management.task.actions.assign.confirm' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:contents}:host main{padding:var(--ymt-spacing-m)}:host yuv-organization{border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-s);padding:var(--ymt-spacing-xs)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: OrganizationComponent, selector: "yuv-organization", inputs: ["situation", "multiselect", "classifications", "readonly", "excludeMe", "withMetadata"] }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitle", "headertitel"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2353
+ }
2354
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: TaskAssignOverlayComponent, decorators: [{
2355
+ type: Component,
2356
+ args: [{ selector: 'ymbpm-task-assign-overlay', imports: [
2357
+ CommonModule,
2358
+ ReactiveFormsModule,
2359
+ MatDialogModule,
2360
+ MatFormFieldModule,
2361
+ MatInputModule,
2362
+ MatButtonModule,
2363
+ TranslatePipe,
2364
+ OrganizationComponent,
2365
+ DialogComponent,
2366
+ YmtButtonDirective
2367
+ ], standalone: true, template: "<yuv-dialog [headertitle]=\"'yuv.app.bpm-management.task.actions.assign.label' | translate\">\n <main >\n <mat-label>{{ 'yuv.app.bpm-management.task.actions.assign.assignee.label' | translate }}</mat-label>\n <yuv-organization [formControl]=\"userControl\" [excludeMe]='false' />\n </main>\n <footer>\n <button ymtButton=\"secondary\" (click)=\"close()\" type=\"button\">\n {{ \"yuv.app.bpm-management.action.cancel.label\" | translate }}\n </button>\n <button ymtButton=\"primary\" (click)=\"confirm()\" type=\"button\" [disabled]=\"this.userControl.touched && this.userControl.dirty\">\n {{ 'yuv.app.bpm-management.task.actions.assign.confirm' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:contents}:host main{padding:var(--ymt-spacing-m)}:host yuv-organization{border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-s);padding:var(--ymt-spacing-xs)}\n"] }]
2368
+ }] });
2369
+
2370
+ class YuvTasksPageComponent {
2371
+ layoutSettingsID = APP_ID + '#root.layout.settings';
2372
+ #logger = inject(Logger);
2373
+ #translateService = inject(TranslateService);
2374
+ #bpmAdminSerice = inject(YuvBpmAdminService);
2375
+ #dialog = inject(MatDialog);
2376
+ #notificationService = inject(NotificationService);
2377
+ taskDetailsComponent;
2378
+ bpmTableComponent;
2379
+ statusTemplate;
2380
+ TaskStatus = TaskStatus;
2381
+ pagination = {
2382
+ total: 0,
2383
+ pageSize: 50,
2384
+ page: 0
2385
+ };
2386
+ actions = [];
2387
+ icons = {
2388
+ ...APP_ICONS,
2389
+ };
2390
+ get displayedColumns() {
2391
+ return [
2392
+ {
2393
+ name: 'id',
2394
+ displayName: 'yuv.app.bpm-management.header.id',
2395
+ filter: {
2396
+ type: FILTER_TYPES.TEXT,
2397
+ operators: [FILTER_OPERATORS.EQUALS]
2398
+ }
2399
+ },
2400
+ {
2401
+ name: 'name',
2402
+ displayName: 'yuv.app.bpm-management.header.name',
2403
+ filter: {
2404
+ type: FILTER_TYPES.TEXT,
2405
+ operators: [FILTER_OPERATORS.CONTAINS, FILTER_OPERATORS.EQUALS, FILTER_OPERATORS.STARTS_WITH, FILTER_OPERATORS.ENDS_WITH]
2406
+ }
2407
+ },
2408
+ {
2409
+ name: 'status',
2410
+ displayName: 'yuv.app.bpm-management.header.status',
2411
+ template: this.statusTemplate,
2412
+ filter: {
2413
+ type: FILTER_TYPES.SELECT,
2414
+ options: [TaskStatus.RUNNING, TaskStatus.COMPLETED]
2415
+ }
2416
+ },
2417
+ {
2418
+ name: 'assignee',
2419
+ displayName: 'yuv.app.bpm-management.header.assignee',
2420
+ filter: {
2421
+ type: FILTER_TYPES.TEXT,
2422
+ operators: [FILTER_OPERATORS.EQUALS]
2423
+ }
2424
+ },
2425
+ {
2426
+ name: 'owner',
2427
+ displayName: 'yuv.app.bpm-management.header.owner',
2428
+ filter: {
2429
+ type: FILTER_TYPES.TEXT,
2430
+ operators: [FILTER_OPERATORS.EQUALS]
2431
+ }
2432
+ },
2433
+ {
2434
+ name: 'createTime',
2435
+ displayName: 'yuv.app.bpm-management.header.createTime',
2436
+ filter: {
2437
+ type: FILTER_TYPES.DATE,
2438
+ operators: [FILTER_OPERATORS.BEFORE, FILTER_OPERATORS.AFTER, FILTER_OPERATORS.BETWEEN]
2439
+ }
2440
+ },
2441
+ {
2442
+ name: 'endTime',
2443
+ displayName: 'yuv.app.bpm-management.header.endTime',
2444
+ filter: {
2445
+ type: FILTER_TYPES.DATE,
2446
+ operators: [FILTER_OPERATORS.BEFORE, FILTER_OPERATORS.AFTER, FILTER_OPERATORS.BETWEEN]
2447
+ }
2448
+ }
2449
+ ];
2450
+ }
2451
+ // Filter state
2452
+ filter = new TaskFilter();
2453
+ enableFilters = true;
2454
+ enableDetails = signal(false, ...(ngDevMode ? [{ debugName: "enableDetails" }] : /* istanbul ignore next */ []));
2455
+ layoutOptions = signal({
2456
+ resizable: true,
2457
+ detailsSize: 25,
2458
+ detailsMaxSize: 75
2459
+ }, ...(ngDevMode ? [{ debugName: "layoutOptions" }] : /* istanbul ignore next */ []));
2460
+ busy = signal(false, ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
2461
+ dataSource = signal([], ...(ngDevMode ? [{ debugName: "dataSource" }] : /* istanbul ignore next */ []));
2462
+ selection = signal(new SelectionModel(false, undefined), ...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
2463
+ currentPageSize = 50;
2464
+ ngOnInit() {
2465
+ this.#loadTaskList();
2466
+ }
2467
+ refresh() {
2468
+ this.#loadTaskList();
2469
+ this.taskDetailsComponent?.loadTaskDetails();
2470
+ }
2471
+ onChangePage($event) {
2472
+ this.pagination.page = $event.pageIndex;
2473
+ this.pagination.pageSize = $event.pageSize;
2474
+ this.#loadTaskList();
2475
+ }
2476
+ onFiltersChange(filters) {
2477
+ this.filter = TaskFilter.fromAgFilterModel(filters, this.#translateService);
2478
+ this.pagination.page = 0; // Reset to first page when filtering
2479
+ this.#loadTaskList();
2480
+ }
2481
+ hasActiveFilters() {
2482
+ return this.filter ? Object.keys(this.filter).length > 0 : false;
2483
+ }
2484
+ #loadTaskList() {
2485
+ this.busy.set(true);
2486
+ this.#bpmAdminSerice.getTasks(this.pagination.page, this.pagination.pageSize, this.filter).subscribe({
2487
+ next: (response) => {
2488
+ const formattedTaskObjects = response.objects.map(task => ({
2489
+ ...task,
2490
+ createTime: task.createTime ? formatDateTime(task.createTime, this.#translateService.currentLang) : task.createTime,
2491
+ endTime: task.endTime ? formatDateTime(task.endTime, this.#translateService.currentLang) : task.endTime
2492
+ }));
2493
+ this.dataSource.set(formattedTaskObjects);
2494
+ const selectedId = this.selection().selected.at(0)?.id;
2495
+ if (selectedId) {
2496
+ const updatedSelected = this.dataSource().find(pd => pd.id === selectedId);
2497
+ if (updatedSelected) {
2498
+ this.selection().select(updatedSelected);
2499
+ this.#updateActions(updatedSelected);
2500
+ }
2501
+ }
2502
+ this.pagination.total = response.totalNumItems;
2503
+ },
2504
+ error: (e) => {
2505
+ this.#logger.error('Failed to fetch tasks', e);
2506
+ this.busy.set(false);
2507
+ },
2508
+ complete: () => {
2509
+ this.busy.set(false);
2510
+ },
2511
+ });
2512
+ }
2513
+ onRowSelected(task) {
2514
+ this.selection().select(task);
2515
+ this.#updateActions(this.selection().selected.at(0));
2516
+ if (!this.enableDetails()) {
2517
+ this.enableDetails.set(true);
2518
+ }
2519
+ }
2520
+ #updateActions(obj) {
2521
+ this.actions = obj
2522
+ ? [
2523
+ {
2524
+ id: 'yuv.app.bpm-management.task.actions.unassign',
2525
+ icon: APP_ICONS.unassign,
2526
+ label: this.#translateService.instant('yuv.app.bpm-management.task.actions.unassign.label'),
2527
+ disabled: obj.assignee == null || obj.endTime != null,
2528
+ callback: () => this.unassign(),
2529
+ },
2530
+ {
2531
+ id: 'yuv.app.bpm-management.task.actions.assign',
2532
+ icon: APP_ICONS.assign,
2533
+ label: this.#translateService.instant('yuv.app.bpm-management.task.actions.assign.label'),
2534
+ disabled: obj.assignee != null || obj.endTime != null,
2535
+ callback: () => this.assign(),
2536
+ }
2537
+ ]
2538
+ : [];
2539
+ }
2540
+ unassign() {
2541
+ const task = this.selection().selected.at(0);
2542
+ if (!task) {
2543
+ return;
2544
+ }
2545
+ this.#dialog.open(ConfirmComponent, {
2546
+ width: '400px',
2547
+ maxWidth: '90vw',
2548
+ data: {
2549
+ title: this.#translateService.instant('yuv.app.bpm-management.task.actions.unassign.label'),
2550
+ message: this.#translateService.instant('yuv.app.bpm-management.task.actions.unassign.confirm.message')
2551
+ },
2552
+ }).afterClosed().subscribe((confirm) => {
2553
+ if (confirm) {
2554
+ this.#bpmAdminSerice.assignTask(task.id, null).subscribe({
2555
+ next: () => {
2556
+ this.#notificationService.success(this.#translateService.instant('yuv.app.bpm-management.task.actions.unassign.success'));
2557
+ this.refresh();
2558
+ },
2559
+ error: (e) => {
2560
+ this.busy.set(false);
2561
+ this.#logger.error(`Failed to unassign task`, e);
2562
+ this.#notificationService.error(this.#translateService.instant('yuv.app.bpm-management.task.actions.assign.error'));
2563
+ }
2564
+ });
2565
+ }
2566
+ });
2567
+ }
2568
+ assign() {
2569
+ const task = this.selection().selected.at(0);
2570
+ if (!task) {
2571
+ return;
2572
+ }
2573
+ this.#dialog.open(TaskAssignOverlayComponent, {
2574
+ width: '400px',
2575
+ maxWidth: '90vw',
2576
+ data: {
2577
+ taskId: task.id,
2578
+ taskName: task.name
2579
+ },
2580
+ }).afterClosed().subscribe((assignee) => {
2581
+ if (assignee) {
2582
+ this.#bpmAdminSerice.assignTask(task.id, assignee).subscribe({
2583
+ next: () => {
2584
+ this.#notificationService.success(this.#translateService.instant('yuv.app.bpm-management.task.actions.assign.success'));
2585
+ this.refresh();
2586
+ },
2587
+ error: (e) => {
2588
+ this.busy.set(false);
2589
+ this.#logger.error(`Failed to assign task`, e);
2590
+ this.#notificationService.error(this.#translateService.instant('yuv.app.bpm-management.task.actions.assign.error'));
2591
+ }
2592
+ });
2593
+ }
2594
+ });
2595
+ }
2596
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvTasksPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2597
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: YuvTasksPageComponent, isStandalone: true, selector: "ymbpm-tasks-page", viewQueries: [{ propertyName: "taskDetailsComponent", first: true, predicate: TaskDetailsComponent, descendants: true }, { propertyName: "bpmTableComponent", first: true, predicate: BpmTableComponent, descendants: true }, { propertyName: "statusTemplate", first: true, predicate: ["statusTemplate"], descendants: true, static: true }], ngImport: i0, template: "<ng-template yuvAppHeaderSlot=\"actions\">\n</ng-template>\n\n<ymt-master-details-layout\n [detailsActive]=\"enableDetails()\"\n [options]=\"layoutOptions()\"\n [layoutSettingsID]=\"layoutSettingsID\">\n\n <ng-template ymtLayoutPane role=\"master\" [topBarActions]=\"masterPaneActions\">\n <ymt-pane-body>\n <ymbpm-table \n [dataSource]=\"dataSource()\" \n [columns]=\"displayedColumns\" \n [pagination]=\"pagination\" \n [selectedRow]=\"selection().selected.at(0)\"\n [enableFilters]=\"enableFilters\"\n (pageChange)=\"onChangePage($event)\"\n (rowSelected)=\"onRowSelected($event)\"\n (filtersChange)=\"onFiltersChange($event)\"\n [busy]=\"busy()\">\n </ymbpm-table>\n </ymt-pane-body>\n </ng-template>\n \n <ng-template ymtLayoutPane role=\"details\">\n @let selectedTask = selection().selected.at(0);\n <ymt-pane-header [icon]=\"selectedTask ? 'task' : undefined\" [title]=\"selectedTask ? (selectedTask.name || '&lt;unnamed&gt;') : ''\" [subtitle]=\"selectedTask ? selectedTask.id : ''\" [actions]=\"listActions\"></ymt-pane-header>\n <ymt-pane-body>\n <div class=\"detailsPaneContainer\">\n @if (selectedTask) {\n <ymbpm-task-details [taskId]=\"selectedTask?.id\"></ymbpm-task-details>\n } @else {\n <div class=\"no-selection\">\n <mat-icon>{{icons.info}}</mat-icon>\n <p>{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </div>\n </ymt-pane-body>\n </ng-template>\n</ymt-master-details-layout>\n\n<ng-template #masterPaneActions>\n <div class=\"table-actions\">\n <button mat-icon-button *ngIf=\"this.enableFilters\" [disabled]=\"!hasActiveFilters()\" (click)=\"bpmTableComponent?.clearAllFilters()\" [matTooltip]=\"'yuv.app.bpm-management.filters.clearAll' | translate\">\n <mat-icon>{{icons.clearFilter}}</mat-icon>\n </button>\n <button mat-icon-button (click)=\"refresh()\" [matTooltip]=\"'yuv.app.bpm-management.navigation.refresh.tooltip' | translate\">\n <mat-icon>{{icons.refresh}}</mat-icon>\n </button>\n </div>\n</ng-template>\n\n<ng-template #listActions>\n <yuv-overflow-menu [menuItems]=\"actions\"></yuv-overflow-menu>\n</ng-template>\n\n<!-- Templates for table cells -->\n<ng-template #statusTemplate let-task>\n @if (task.endTime) {\n <span class=\"yuv-bpmn-status completed\">{{TaskStatus.COMPLETED.label | translate}}</span>\n } @else {\n <span class=\"yuv-bpmn-status running\">{{TaskStatus.RUNNING.label | translate}}</span>\n }\n</ng-template>", styles: [":host{--mat-table-row-item-outline-color: var(--ymt-outline-variant);height:100%;overflow:hidden;display:flex;flex-flow:column}:host ymt-master-details-layout{height:100%;padding:1rem}:host ymt-master-details-layout .detailsPaneContainer{display:flex;flex-direction:column;height:100%;overflow:auto}:host ymt-master-details-layout .detailsPaneContainer .no-selection{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}:host ymt-master-details-layout .detailsPaneContainer .no-selection mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:var(--ymt-spacing-m);opacity:.5}:host ymt-master-details-layout .detailsPaneContainer .no-selection p{font-size:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "ngmodule", type: MatSortModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: YuvClientShellModule }, { kind: "directive", type: i5$1.YuvAppHeaderSlotDirective, selector: "ng-template[yuvAppHeaderSlot]", inputs: ["yuvAppHeaderSlot"] }, { kind: "ngmodule", type: YuvMasterDetailsModule }, { kind: "ngmodule", type: YuvOverflowMenuModule }, { kind: "component", type: i6$1.OverflowMenuComponent, selector: "yuv-overflow-menu", inputs: ["overflowIcon", "groupLabels", "menuItems", "vertical"] }, { kind: "component", type: BpmTableComponent, selector: "ymbpm-table", inputs: ["columns", "dataSource", "enableFilters", "pagination", "selectedRow", "busy"], outputs: ["filtersChange", "pageChange", "rowSelected"] }, { kind: "component", type: TaskDetailsComponent, selector: "ymbpm-task-details", inputs: ["taskId"] }, { kind: "ngmodule", type: YmtLayoutModule }, { kind: "component", type: i6.MasterDetailsLayoutComponent, selector: "ymt-master-details-layout", inputs: ["layoutSettingsID", "options", "direction", "gutterSize", "detailsActive"], outputs: ["detailsActiveChange"] }, { kind: "directive", type: i6.YmtLayoutPaneDirective, selector: "[ymtLayoutPane]", inputs: ["role", "topBarActions"] }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i7.YmtPaneHeaderComponent, selector: "ymt-pane-header", inputs: ["title", "icon", "subtitle", "actions", "badges"] }, { kind: "component", type: i7.YmtPaneBodyComponent, selector: "ymt-pane-body" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2598
+ }
2599
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: YuvTasksPageComponent, decorators: [{
2600
+ type: Component,
2601
+ args: [{ selector: 'ymbpm-tasks-page', standalone: true, imports: [
2602
+ CommonModule,
2603
+ MatButtonModule,
2604
+ MatIconModule,
2605
+ MatTooltipModule,
2606
+ MatTableModule,
2607
+ MatPaginatorModule,
2608
+ MatSortModule,
2609
+ RouterModule,
2610
+ TranslatePipe,
2611
+ YuvClientShellModule,
2612
+ YuvMasterDetailsModule,
2613
+ YuvOverflowMenuModule,
2614
+ BpmTableComponent,
2615
+ TaskDetailsComponent,
2616
+ YmtLayoutModule,
2617
+ YmtPanesModule
2618
+ ], template: "<ng-template yuvAppHeaderSlot=\"actions\">\n</ng-template>\n\n<ymt-master-details-layout\n [detailsActive]=\"enableDetails()\"\n [options]=\"layoutOptions()\"\n [layoutSettingsID]=\"layoutSettingsID\">\n\n <ng-template ymtLayoutPane role=\"master\" [topBarActions]=\"masterPaneActions\">\n <ymt-pane-body>\n <ymbpm-table \n [dataSource]=\"dataSource()\" \n [columns]=\"displayedColumns\" \n [pagination]=\"pagination\" \n [selectedRow]=\"selection().selected.at(0)\"\n [enableFilters]=\"enableFilters\"\n (pageChange)=\"onChangePage($event)\"\n (rowSelected)=\"onRowSelected($event)\"\n (filtersChange)=\"onFiltersChange($event)\"\n [busy]=\"busy()\">\n </ymbpm-table>\n </ymt-pane-body>\n </ng-template>\n \n <ng-template ymtLayoutPane role=\"details\">\n @let selectedTask = selection().selected.at(0);\n <ymt-pane-header [icon]=\"selectedTask ? 'task' : undefined\" [title]=\"selectedTask ? (selectedTask.name || '&lt;unnamed&gt;') : ''\" [subtitle]=\"selectedTask ? selectedTask.id : ''\" [actions]=\"listActions\"></ymt-pane-header>\n <ymt-pane-body>\n <div class=\"detailsPaneContainer\">\n @if (selectedTask) {\n <ymbpm-task-details [taskId]=\"selectedTask?.id\"></ymbpm-task-details>\n } @else {\n <div class=\"no-selection\">\n <mat-icon>{{icons.info}}</mat-icon>\n <p>{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </div>\n </ymt-pane-body>\n </ng-template>\n</ymt-master-details-layout>\n\n<ng-template #masterPaneActions>\n <div class=\"table-actions\">\n <button mat-icon-button *ngIf=\"this.enableFilters\" [disabled]=\"!hasActiveFilters()\" (click)=\"bpmTableComponent?.clearAllFilters()\" [matTooltip]=\"'yuv.app.bpm-management.filters.clearAll' | translate\">\n <mat-icon>{{icons.clearFilter}}</mat-icon>\n </button>\n <button mat-icon-button (click)=\"refresh()\" [matTooltip]=\"'yuv.app.bpm-management.navigation.refresh.tooltip' | translate\">\n <mat-icon>{{icons.refresh}}</mat-icon>\n </button>\n </div>\n</ng-template>\n\n<ng-template #listActions>\n <yuv-overflow-menu [menuItems]=\"actions\"></yuv-overflow-menu>\n</ng-template>\n\n<!-- Templates for table cells -->\n<ng-template #statusTemplate let-task>\n @if (task.endTime) {\n <span class=\"yuv-bpmn-status completed\">{{TaskStatus.COMPLETED.label | translate}}</span>\n } @else {\n <span class=\"yuv-bpmn-status running\">{{TaskStatus.RUNNING.label | translate}}</span>\n }\n</ng-template>", styles: [":host{--mat-table-row-item-outline-color: var(--ymt-outline-variant);height:100%;overflow:hidden;display:flex;flex-flow:column}:host ymt-master-details-layout{height:100%;padding:1rem}:host ymt-master-details-layout .detailsPaneContainer{display:flex;flex-direction:column;height:100%;overflow:auto}:host ymt-master-details-layout .detailsPaneContainer .no-selection{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}:host ymt-master-details-layout .detailsPaneContainer .no-selection mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:var(--ymt-spacing-m);opacity:.5}:host ymt-master-details-layout .detailsPaneContainer .no-selection p{font-size:1rem}\n"] }]
2619
+ }], propDecorators: { taskDetailsComponent: [{
2620
+ type: ViewChild,
2621
+ args: [TaskDetailsComponent]
2622
+ }], bpmTableComponent: [{
2623
+ type: ViewChild,
2624
+ args: [BpmTableComponent]
2625
+ }], statusTemplate: [{
2626
+ type: ViewChild,
2627
+ args: ['statusTemplate', { static: true }]
2628
+ }] } });
2629
+
2630
+ const YuvBpmManagementRoutes = [
2631
+ {
2632
+ path: '',
2633
+ component: YuvBpmManagementComponent,
2634
+ children: [
2635
+ { path: 'deployments', component: YuvDeploymentsPageComponent },
2636
+ { path: 'processdefinitions', component: YuvProcessDefinitionsPageComponent },
2637
+ { path: 'processes', component: YuvProcessesPageComponent },
2638
+ { path: 'tasks', component: YuvTasksPageComponent },
2639
+ { path: '', redirectTo: 'processes', pathMatch: 'full' }
2640
+ ]
2641
+ }
2642
+ ];
2643
+
2644
+ /**
2645
+ * Generated bundle index. Do not edit.
2646
+ */
2647
+
2648
+ export { APP_ICONS, APP_ID, FILTER_OPERATORS, FILTER_TYPES, ProcessDefinitionScope, ProcessDefinitionStatus, ProcessStatus, TaskStatus, YuvBpmAdminService, YuvBpmManagementRoutes, formatDateTime };
2649
+ //# sourceMappingURL=yuuvis-bpm-management-app.mjs.map