@yuuvis/bpm-management-app 1.1.0-alpha.2 → 1.1.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,23 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Injectable, signal, input, output, ChangeDetectionStrategy, Component, DestroyRef, forwardRef, computed, ChangeDetectorRef, ViewChild, ElementRef, Injector, viewChild, afterNextRender, Pipe, effect, untracked, afterRenderEffect } from '@angular/core';
2
+ import { inject, Injectable, ViewChild, Component, signal, input, output, ChangeDetectionStrategy, DestroyRef, forwardRef, computed, ChangeDetectorRef, ElementRef, Injector, viewChild, afterNextRender, Pipe, viewChildren, effect, untracked, afterRenderEffect } from '@angular/core';
3
3
  import { Router, ActivatedRoute } from '@angular/router';
4
+ import { Clipboard } from '@angular/cdk/clipboard';
4
5
  import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
5
- import * as i1 from '@angular/material/button-toggle';
6
+ import * as i1$1 from '@angular/material/button-toggle';
6
7
  import { MatButtonToggleModule } from '@angular/material/button-toggle';
7
8
  import * as i2$3 from '@angular/material/divider';
8
9
  import { MatDividerModule } from '@angular/material/divider';
9
- import * as i1$1 from '@angular/material/icon';
10
+ import * as i1$2 from '@angular/material/icon';
10
11
  import { MatIconModule } from '@angular/material/icon';
11
- import * as i3 from '@angular/material/menu';
12
- import { MatMenuModule } from '@angular/material/menu';
12
+ import * as i4 from '@angular/material/menu';
13
+ import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
13
14
  import * as i5 from '@angular/material/paginator';
14
15
  import { MatPaginatorModule } from '@angular/material/paginator';
15
- import * as i3$1 from '@angular/material/tooltip';
16
+ import * as i3 from '@angular/material/tooltip';
16
17
  import { MatTooltipModule, MatTooltip } from '@angular/material/tooltip';
17
18
  import { Title } from '@angular/platform-browser';
18
19
  import * as i8 from '@yuuvis/client-components/list';
19
- import { YuvListModule } from '@yuuvis/client-components/list';
20
+ import { ListComponent, YuvListModule } from '@yuuvis/client-components/list';
20
21
  import * as i9 from '@yuuvis/client-components/split-view';
21
22
  import { YuvSplitViewModule } from '@yuuvis/client-components/split-view';
22
23
  import { BackendService, ApiBase, Utils, TranslatePipe, TranslateService, NotificationService, Logger } from '@yuuvis/client-core';
@@ -24,36 +25,36 @@ import { SimpleSearchComponent } from '@yuuvis/client-framework/simple-search';
24
25
  import * as i7 from '@yuuvis/client-shell';
25
26
  import { YuvClientShellModule } from '@yuuvis/client-shell';
26
27
  import { ShellService } from '@yuuvis/client-shell-core';
27
- import { YmtIconButtonDirective, YmtButtonDirective } from '@yuuvis/material';
28
+ import { YmtButtonDirective, YmtIconButtonDirective } from '@yuuvis/material';
28
29
  import { YmtBadge } from '@yuuvis/material/badge';
29
30
  import * as i10 from '@yuuvis/material/panes';
30
31
  import { YmtPanesModule } from '@yuuvis/material/panes';
31
- import { map, Subject, merge, startWith, pairwise, debounceTime, distinctUntilChanged, forkJoin, catchError, of } from 'rxjs';
32
+ import { map, filter, switchMap, of, catchError, EMPTY, Subject, merge, startWith, pairwise, debounceTime, distinctUntilChanged, finalize, forkJoin } from 'rxjs';
33
+ import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
34
+ import { DialogComponent, ConfirmComponent, LayoutSettingsService } from '@yuuvis/client-components/common';
35
+ import { HttpParams } from '@angular/common/http';
32
36
  import * as i1$4 from '@angular/common';
33
37
  import { formatDate, CommonModule } from '@angular/common';
34
- import { HttpParams } from '@angular/common/http';
35
- import { LayoutSettingsService, DialogComponent, ConfirmComponent } from '@yuuvis/client-components/common';
38
+ import { MatSlideToggle } from '@angular/material/slide-toggle';
39
+ import * as i3$1 from '@angular/material/input';
40
+ import { MatLabel, MatInputModule } from '@angular/material/input';
41
+ import * as i1 from '@angular/forms';
42
+ import { FormControl, ReactiveFormsModule, NgControl, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
43
+ import * as i2 from '@angular/material/form-field';
44
+ import { MatFormFieldModule, MatFormFieldControl } from '@angular/material/form-field';
45
+ import { MatButtonModule } from '@angular/material/button';
46
+ import { OrganizationComponent } from '@yuuvis/client-framework/forms';
47
+ import * as i3$2 from '@angular/material/select';
48
+ import { MatLabel as MatLabel$1, MatSelectModule } from '@angular/material/select';
36
49
  import * as i1$3 from '@angular/cdk/overlay';
37
50
  import { CdkConnectedOverlay, OverlayModule } from '@angular/cdk/overlay';
38
- import * as i1$2 from '@angular/forms';
39
- import { FormControl, NgControl, ReactiveFormsModule, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
40
51
  import { OrganizationRendererComponent } from '@yuuvis/client-framework/renderer';
41
- import * as i2$1 from '@angular/material/form-field';
42
- import { MatFormFieldControl, MatFormFieldModule } from '@angular/material/form-field';
43
- import * as i2 from '@yuuvis/client-framework/datepicker';
52
+ import * as i2$1 from '@yuuvis/client-framework/datepicker';
44
53
  import { YuvDatepickerModule } from '@yuuvis/client-framework/datepicker';
45
- import * as i3$2 from '@angular/material/input';
46
- import { MatInputModule, MatLabel } from '@angular/material/input';
47
- import { MatButtonModule } from '@angular/material/button';
48
- import * as i3$3 from '@angular/material/select';
49
- import { MatSelectModule, MatLabel as MatLabel$1 } from '@angular/material/select';
50
- import { OrganizationComponent } from '@yuuvis/client-framework/forms';
51
- import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
52
54
  import * as i2$2 from '@angular/material/tabs';
53
55
  import { MatTabsModule } from '@angular/material/tabs';
54
56
  import { MatCardModule } from '@angular/material/card';
55
57
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
56
- import { MatSlideToggle } from '@angular/material/slide-toggle';
57
58
 
58
59
  const APP_ID = 'io.yuuvis.app.bpm-management';
59
60
  const ProcessDefinitionScope = {
@@ -82,6 +83,7 @@ const APP_ICONS = {
82
83
  assign: 'person_add',
83
84
  cancel: 'cancel',
84
85
  unassign: 'person_remove',
86
+ editCandidates: 'manage_accounts',
85
87
  clearFilter: 'filter_alt_off',
86
88
  dockToLeft: 'dock_to_left',
87
89
  filterActive: 'filter_alt',
@@ -99,7 +101,7 @@ const APP_ICONS = {
99
101
  refresh: 'refresh',
100
102
  radioButtonChecked: 'radio_button_checked',
101
103
  radioButtonUnchecked: 'radio_button_unchecked',
102
- tenant: 'groups',
104
+ tenant: 'lock',
103
105
  delegated: 'assignment',
104
106
  resolved: 'order_approve',
105
107
  activate: 'not_started',
@@ -193,9 +195,14 @@ function definitionSeverity(d) {
193
195
  return d.suspended ? 'neutral' : 'primary';
194
196
  }
195
197
  /** The icon of a process definition. Always the default for now, definitions will get custom icons. */
198
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars -- the definition will choose its icon
196
199
  function definitionIcon(_d) {
197
200
  return BPM_ENTITY_META.definitions.itemIcon;
198
201
  }
202
+ /** Global definitions are shared by all tenants, the others belong to the tenant. */
203
+ function definitionScope(d) {
204
+ return d.global ? ProcessDefinitionScope.GLOBAL : ProcessDefinitionScope.TENANT;
205
+ }
199
206
  function definitionStatusLabel(d) {
200
207
  return (d.suspended ? ProcessDefinitionStatus.SUSPENDED : ProcessDefinitionStatus.ACTIVE).label;
201
208
  }
@@ -281,14 +288,16 @@ class BaseBpmFilter {
281
288
  * @returns The converted BPM filter instance
282
289
  */
283
290
  static convertFromAgFilterModel(filterInstance, tableFilters, ts) {
291
+ // a generic type can only be read by index, its base can be written
292
+ const target = filterInstance;
284
293
  for (const columnFilter in tableFilters) {
285
294
  const columnFilterData = tableFilters[columnFilter];
286
295
  switch (columnFilterData['type']) {
287
296
  case FILTER_TYPES.TEXT:
288
- filterInstance[columnFilter] = this.handleTextFilter(columnFilterData);
297
+ target[columnFilter] = this.handleTextFilter(columnFilterData);
289
298
  break;
290
299
  case FILTER_TYPES.NUMBER:
291
- filterInstance[columnFilter] = { value: columnFilterData.value, type: FILTER_TYPES.NUMBER };
300
+ target[columnFilter] = { value: columnFilterData.value, type: FILTER_TYPES.NUMBER };
292
301
  break;
293
302
  case FILTER_TYPES.DATE:
294
303
  this.handleDateFilter(filterInstance, columnFilter, columnFilterData, ts);
@@ -314,34 +323,35 @@ class BaseBpmFilter {
314
323
  return { value: columnFilterData.value, type: FILTER_TYPES.TEXT };
315
324
  }
316
325
  }
326
+ /** A date criterion becomes `<column>After` and/or `<column>Before`. */
317
327
  static handleDateFilter(filterInstance, columnFilter, columnFilterData, ts) {
318
328
  if (!ts)
319
329
  return;
320
- if (columnFilterData.operator === FILTER_OPERATORS.BETWEEN.value) {
321
- if (columnFilterData.value !== null && columnFilterData.value instanceof Date) {
322
- const formattedStartDate = formatDate(columnFilterData.value, 'yyyy-MM-ddTHH:mm:ss', ts.currentLang, 'UTC');
323
- filterInstance[columnFilter + 'After'] = { value: formattedStartDate, type: FILTER_TYPES.DATE };
324
- }
325
- if (columnFilterData.endDate !== null && columnFilterData.endDate instanceof Date) {
326
- const formattedEndDate = formatDate(columnFilterData.endDate, 'yyyy-MM-ddTHH:mm:ss', ts.currentLang, 'UTC');
327
- filterInstance[columnFilter + 'Before'] = { value: formattedEndDate, type: FILTER_TYPES.DATE };
330
+ const set = (suffix, date) => {
331
+ if (date instanceof Date) {
332
+ filterInstance[columnFilter + suffix] = { value: formatDate(date, 'yyyy-MM-ddTHH:mm:ss', ts.currentLang, 'UTC'), type: FILTER_TYPES.DATE };
328
333
  }
329
- }
330
- else if (columnFilterData.operator === FILTER_OPERATORS.AFTER.value) {
331
- if (columnFilterData.value !== null && columnFilterData.value instanceof Date) {
332
- const formattedDate = formatDate(columnFilterData.value, 'yyyy-MM-ddTHH:mm:ss', ts.currentLang, 'UTC');
333
- filterInstance[columnFilter + 'After'] = { value: formattedDate, type: FILTER_TYPES.DATE };
334
- }
335
- }
336
- else if (columnFilterData.operator === FILTER_OPERATORS.BEFORE.value) {
337
- if (columnFilterData.value !== null && columnFilterData.value instanceof Date) {
338
- const formattedDate = formatDate(columnFilterData.value, 'yyyy-MM-ddTHH:mm:ss', ts.currentLang, 'UTC');
339
- filterInstance[columnFilter + 'Before'] = { value: formattedDate, type: FILTER_TYPES.DATE };
340
- }
341
- }
342
- }
343
- static handleSelectFilter(_filterInstance, _columnFilter, _columnFilterData) {
344
- return;
334
+ };
335
+ switch (columnFilterData.operator) {
336
+ case FILTER_OPERATORS.BETWEEN.value:
337
+ set('After', columnFilterData.value);
338
+ set('Before', columnFilterData.endDate);
339
+ break;
340
+ case FILTER_OPERATORS.AFTER.value:
341
+ set('After', columnFilterData.value);
342
+ break;
343
+ case FILTER_OPERATORS.BEFORE.value:
344
+ set('Before', columnFilterData.value);
345
+ break;
346
+ }
347
+ }
348
+ /** The REST value (`'true'`/`'false'`) of each select option; select filters mean something else per entity. */
349
+ static selectValues = {};
350
+ /** Several options at once are not supported. */
351
+ static handleSelectFilter(filterInstance, columnFilter, columnFilterData) {
352
+ const value = typeof columnFilterData.value === 'string' ? this.selectValues[columnFilterData.value] : undefined;
353
+ if (value)
354
+ filterInstance[columnFilter] = { value, type: FILTER_TYPES.SELECT };
345
355
  }
346
356
  }
347
357
  class DeploymentFilter extends BaseBpmFilter {
@@ -366,22 +376,16 @@ class ProcessDefinitionFilter extends BaseBpmFilter {
366
376
  global: 'global',
367
377
  latest: 'latest'
368
378
  };
379
+ /** status -> `suspended`, scope -> `global` */
380
+ static selectValues = {
381
+ [ProcessDefinitionStatus.ACTIVE.value]: 'false',
382
+ [ProcessDefinitionStatus.SUSPENDED.value]: 'true',
383
+ [ProcessDefinitionScope.TENANT.value]: 'false',
384
+ [ProcessDefinitionScope.GLOBAL.value]: 'true'
385
+ };
369
386
  static fromAgFilterModel(tableFilters) {
370
387
  return this.convertFromAgFilterModel(new ProcessDefinitionFilter(), tableFilters);
371
388
  }
372
- static handleSelectFilter(filterInstance, columnFilter, columnFilterData) {
373
- if (Array.isArray(columnFilterData.value)) {
374
- // Not supported in current implementation
375
- return;
376
- }
377
- const value = columnFilterData.value;
378
- if (value === ProcessDefinitionStatus.ACTIVE.value || value === ProcessDefinitionScope.TENANT.value) {
379
- filterInstance[columnFilter] = { value: 'false', type: FILTER_TYPES.SELECT };
380
- }
381
- else if (value === ProcessDefinitionStatus.SUSPENDED.value || value === ProcessDefinitionScope.GLOBAL.value) {
382
- filterInstance[columnFilter] = { value: 'true', type: FILTER_TYPES.SELECT };
383
- }
384
- }
385
389
  }
386
390
  class ProcessFilter extends BaseBpmFilter {
387
391
  static bpmFilterToRestApiName = {
@@ -396,22 +400,15 @@ class ProcessFilter extends BaseBpmFilter {
396
400
  endTimeAfter: 'finishedAfter',
397
401
  status: 'isCompleted'
398
402
  };
403
+ /** status -> `isCompleted` */
404
+ static selectValues = {
405
+ [ProcessStatus.RUNNING_SUSPENDED.value]: 'false',
406
+ [ProcessStatus.COMPLETED.value]: 'true'
407
+ };
408
+ /** `ts` formats the dates; without it date criteria are left out. */
399
409
  static fromAgFilterModel(tableFilters, ts) {
400
410
  return this.convertFromAgFilterModel(new ProcessFilter(), tableFilters, ts);
401
411
  }
402
- static handleSelectFilter(filterInstance, columnFilter, columnFilterData) {
403
- if (Array.isArray(columnFilterData.value)) {
404
- // Not supported in current implementation
405
- return;
406
- }
407
- const value = columnFilterData.value;
408
- if (value === ProcessStatus.RUNNING_SUSPENDED.value) {
409
- filterInstance[columnFilter] = { value: 'false', type: FILTER_TYPES.SELECT };
410
- }
411
- else if (value === ProcessStatus.COMPLETED.value) {
412
- filterInstance[columnFilter] = { value: 'true', type: FILTER_TYPES.SELECT };
413
- }
414
- }
415
412
  }
416
413
  class TaskFilter extends BaseBpmFilter {
417
414
  static bpmFilterToRestApiName = {
@@ -427,22 +424,15 @@ class TaskFilter extends BaseBpmFilter {
427
424
  endTimeBefore: 'completedBefore',
428
425
  endTimeAfter: 'completedAfter'
429
426
  };
427
+ /** status -> `isCompleted` */
428
+ static selectValues = {
429
+ [TaskStatus.RUNNING.value]: 'false',
430
+ [TaskStatus.COMPLETED.value]: 'true'
431
+ };
432
+ /** `ts` formats the dates; without it date criteria are left out. */
430
433
  static fromAgFilterModel(tableFilters, ts) {
431
434
  return this.convertFromAgFilterModel(new TaskFilter(), tableFilters, ts);
432
435
  }
433
- static handleSelectFilter(filterInstance, columnFilter, columnFilterData) {
434
- if (Array.isArray(columnFilterData.value)) {
435
- // Not supported in current implementation
436
- return;
437
- }
438
- const value = columnFilterData.value;
439
- if (value === TaskStatus.RUNNING.value) {
440
- filterInstance[columnFilter] = { value: 'false', type: FILTER_TYPES.SELECT };
441
- }
442
- else if (value === TaskStatus.COMPLETED.value) {
443
- filterInstance[columnFilter] = { value: 'true', type: FILTER_TYPES.SELECT };
444
- }
445
- }
446
436
  }
447
437
 
448
438
  class YuvBpmManagementService {
@@ -485,9 +475,7 @@ class YuvBpmManagementService {
485
475
  'action': action,
486
476
  'includeProcessInstances': includeProcesses
487
477
  };
488
- return this.#backendService
489
- .patch(`${this.bpmApiBase}/process-definitions/${processDefinitionInstanceId}`, body, ApiBase.none)
490
- .pipe(map(result => result));
478
+ return this.#backendService.patch(`${this.bpmApiBase}/process-definitions/${processDefinitionInstanceId}`, body, ApiBase.none);
491
479
  }
492
480
  executeProcessAction(processInstanceId, action) {
493
481
  return this.#backendService.patch(`${this.bpmApiBase}/processes/${processInstanceId}`, { action }, ApiBase.none);
@@ -552,6 +540,216 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
552
540
  }]
553
541
  }] });
554
542
 
543
+ class CheckboxOverlayComponent {
544
+ #dialogRef = inject((MatDialogRef));
545
+ inputData = inject(MAT_DIALOG_DATA);
546
+ toggle;
547
+ confirm() {
548
+ this.#dialogRef.close(this.toggle.checked);
549
+ }
550
+ close() {
551
+ this.#dialogRef.close();
552
+ }
553
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: CheckboxOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
554
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", type: CheckboxOverlayComponent, isStandalone: true, selector: "ymbpm-checkbox-overlay", viewQueries: [{ propertyName: "toggle", first: true, predicate: ["toggle"], descendants: true }], ngImport: i0, template: "<yuv-dialog [headertitle]=\"this.inputData.title ?? ''\" []>\n <main class=\"yuv-dialog-content\">\n <mat-label>{{ this.inputData.message !== undefined ? this.inputData.message : '' }}</mat-label>\n </main>\n <footer>\n <mat-slide-toggle #toggle class=\"footer-toggle\" [checked]=\"false\">{{ this.inputData.checkboxMessage !== undefined ? this.inputData.checkboxMessage : '' }}</mat-slide-toggle>\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)}:host mat-label{white-space:pre-line}footer{display:flex;flex:1 1 auto;align-items:center;gap:inherit}.footer-toggle{margin-inline-end:auto}\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: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
555
+ }
556
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: CheckboxOverlayComponent, decorators: [{
557
+ type: Component,
558
+ args: [{ selector: 'ymbpm-checkbox-overlay', standalone: true, imports: [
559
+ YmtButtonDirective,
560
+ DialogComponent,
561
+ TranslatePipe,
562
+ MatSlideToggle,
563
+ MatLabel
564
+ ], template: "<yuv-dialog [headertitle]=\"this.inputData.title ?? ''\" []>\n <main class=\"yuv-dialog-content\">\n <mat-label>{{ this.inputData.message !== undefined ? this.inputData.message : '' }}</mat-label>\n </main>\n <footer>\n <mat-slide-toggle #toggle class=\"footer-toggle\" [checked]=\"false\">{{ this.inputData.checkboxMessage !== undefined ? this.inputData.checkboxMessage : '' }}</mat-slide-toggle>\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)}:host mat-label{white-space:pre-line}footer{display:flex;flex:1 1 auto;align-items:center;gap:inherit}.footer-toggle{margin-inline-end:auto}\n"] }]
565
+ }], propDecorators: { toggle: [{
566
+ type: ViewChild,
567
+ args: ['toggle']
568
+ }] } });
569
+
570
+ class TaskAssignOverlayComponent {
571
+ #dialogRef = inject((MatDialogRef));
572
+ data = inject(MAT_DIALOG_DATA);
573
+ userControl = new FormControl('');
574
+ close() {
575
+ this.#dialogRef.close();
576
+ }
577
+ confirm() {
578
+ const assignee = this.userControl.value;
579
+ if (assignee && assignee.trim()) {
580
+ this.#dialogRef.close(assignee.trim());
581
+ }
582
+ }
583
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: TaskAssignOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
584
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", 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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "directive", type: i2.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", "allowFreeText"] }, { 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" }] });
585
+ }
586
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: TaskAssignOverlayComponent, decorators: [{
587
+ type: Component,
588
+ args: [{ selector: 'ymbpm-task-assign-overlay', imports: [
589
+ CommonModule,
590
+ ReactiveFormsModule,
591
+ MatDialogModule,
592
+ MatFormFieldModule,
593
+ MatInputModule,
594
+ MatButtonModule,
595
+ TranslatePipe,
596
+ OrganizationComponent,
597
+ DialogComponent,
598
+ YmtButtonDirective
599
+ ], 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"] }]
600
+ }] });
601
+
602
+ class TaskCandidatesOverlayComponent {
603
+ #dialogRef = inject((MatDialogRef));
604
+ data = inject(MAT_DIALOG_DATA);
605
+ usersControl = new FormControl(this.data.currentUsers?.length ? this.data.currentUsers : null);
606
+ rolesControl = new FormControl(this.data.currentRoles?.length ? this.data.currentRoles : null);
607
+ close() {
608
+ this.#dialogRef.close();
609
+ }
610
+ confirm() {
611
+ const usersValue = this.usersControl.value;
612
+ const rolesValue = this.rolesControl.value;
613
+ const result = {
614
+ users: Array.isArray(usersValue) ? usersValue.filter(Boolean) : usersValue ? [usersValue] : [],
615
+ roles: Array.isArray(rolesValue) ? rolesValue.filter(Boolean) : rolesValue ? [rolesValue] : []
616
+ };
617
+ this.#dialogRef.close(result);
618
+ }
619
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: TaskCandidatesOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
620
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", type: TaskCandidatesOverlayComponent, isStandalone: true, selector: "ymbpm-task-candidates-overlay", ngImport: i0, template: "<yuv-dialog [headertitle]=\"'yuv.app.bpm-management.task.actions.editCandidates.label' | translate\">\n <main>\n <div class=\"field-group\">\n <mat-label>{{ 'yuv.app.bpm-management.task.details.candidateUsers' | translate }}</mat-label>\n <yuv-organization [formControl]=\"usersControl\" [multiselect]=\"true\" [excludeMe]=\"false\" [classifications]=\"['id:organization:set[user]']\" />\n </div>\n <div class=\"field-group\">\n <mat-label>{{ 'yuv.app.bpm-management.task.details.candidateRoles' | translate }}</mat-label>\n <yuv-organization [formControl]=\"rolesControl\" [multiselect]=\"true\" [excludeMe]=\"false\" [classifications]=\"['id:organization:set[role]']\" />\n </div>\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\">\n {{ 'yuv.app.bpm-management.action.confirm.label' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:contents}:host main{display:flex;flex-direction:column;padding:var(--ymt-spacing-m);gap: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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: OrganizationComponent, selector: "yuv-organization", inputs: ["situation", "multiselect", "classifications", "readonly", "excludeMe", "withMetadata", "allowFreeText"] }, { 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: "directive", type: MatLabel$1, selector: "mat-label" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
621
+ }
622
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: TaskCandidatesOverlayComponent, decorators: [{
623
+ type: Component,
624
+ args: [{ selector: 'ymbpm-task-candidates-overlay', standalone: true, imports: [
625
+ CommonModule,
626
+ ReactiveFormsModule,
627
+ MatDialogModule,
628
+ MatButtonModule,
629
+ TranslatePipe,
630
+ OrganizationComponent,
631
+ DialogComponent,
632
+ YmtButtonDirective,
633
+ MatLabel$1
634
+ ], template: "<yuv-dialog [headertitle]=\"'yuv.app.bpm-management.task.actions.editCandidates.label' | translate\">\n <main>\n <div class=\"field-group\">\n <mat-label>{{ 'yuv.app.bpm-management.task.details.candidateUsers' | translate }}</mat-label>\n <yuv-organization [formControl]=\"usersControl\" [multiselect]=\"true\" [excludeMe]=\"false\" [classifications]=\"['id:organization:set[user]']\" />\n </div>\n <div class=\"field-group\">\n <mat-label>{{ 'yuv.app.bpm-management.task.details.candidateRoles' | translate }}</mat-label>\n <yuv-organization [formControl]=\"rolesControl\" [multiselect]=\"true\" [excludeMe]=\"false\" [classifications]=\"['id:organization:set[role]']\" />\n </div>\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\">\n {{ 'yuv.app.bpm-management.action.confirm.label' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:contents}:host main{display:flex;flex-direction:column;padding:var(--ymt-spacing-m);gap: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"] }]
635
+ }] });
636
+
637
+ /**
638
+ * The actions on a single item (the details header and the row menu of the list). Every action
639
+ * asks first; the returned observable emits once what has to be reloaded when it succeeded and
640
+ * completes without a value when it was cancelled or failed (failures are notified here).
641
+ */
642
+ class BpmManagementActionsService {
643
+ #dialog = inject(MatDialog);
644
+ #service = inject(YuvBpmManagementService);
645
+ #translate = inject(TranslateService);
646
+ #notifications = inject(NotificationService);
647
+ #logger = inject(Logger);
648
+ /** The status action a definition offers (what is not the case yet); global definitions are shared and cannot be changed. */
649
+ definitionAction(definition) {
650
+ return definition.global ? undefined : definition.suspended ? 'activate' : 'suspend';
651
+ }
652
+ /** The status action of a process; ended processes have none. */
653
+ processAction(process) {
654
+ return process.endTime ? undefined : process.suspended ? 'activate' : 'suspend';
655
+ }
656
+ /** Completed tasks have no actions. */
657
+ hasTaskActions(task) {
658
+ return !task.endTime;
659
+ }
660
+ /** Only an assigned task can lose its assignee. */
661
+ canUnassign(task) {
662
+ return !!task.assignee;
663
+ }
664
+ /** Activates or suspends the definition, optionally together with its processes. */
665
+ changeDefinitionStatus(definition, action) {
666
+ const key = `yuv.app.bpm-management.definitions.actions.${action}`;
667
+ return this.#dialog
668
+ .open(CheckboxOverlayComponent, {
669
+ width: '600px',
670
+ maxWidth: '90vw',
671
+ data: {
672
+ title: this.#translate.instant(`${key}.label`),
673
+ message: this.#translate.instant(`${key}.confirm.message`),
674
+ checkboxMessage: this.#translate.instant(`${key}.confirm.includeProcesses.label`),
675
+ confirmBtnLabel: this.#translate.instant(`${key}.confirm.button.label`)
676
+ }
677
+ })
678
+ .afterClosed()
679
+ .pipe(filter((includeProcesses) => includeProcesses !== undefined), switchMap(includeProcesses => this.#service.executeProcessDefinitionAction(definition.id, action, includeProcesses)),
680
+ // the status is shown in the list too, and the process counts change
681
+ this.#result('both', `${key}.success`, `${key}.error`, `Failed to ${action} the process definition`));
682
+ }
683
+ /** Suspends or resumes a running process. */
684
+ changeProcessStatus(process, action) {
685
+ const key = `yuv.app.bpm-management.process.actions.${action}`;
686
+ return this.#confirm('600px', {
687
+ title: this.#translate.instant(`${key}.label`),
688
+ message: this.#translate.instant(`${key}.confirm.message`),
689
+ confirmBtnLabel: this.#translate.instant(`${key}.confirm.button.label`)
690
+ }).pipe(switchMap(() => this.#service.executeProcessAction(process.id, action)),
691
+ // the status is shown in the list too
692
+ this.#result('both', `${key}.success`, `${key}.error`, `Failed to ${action} the process`));
693
+ }
694
+ assignTask(task) {
695
+ return this.#dialog
696
+ .open(TaskAssignOverlayComponent, { width: '400px', maxWidth: '90vw', data: { taskId: task.id, taskName: task.name } })
697
+ .afterClosed()
698
+ .pipe(filter((assignee) => !!assignee), switchMap(assignee => this.#updateAssignee(task.id, assignee, 'yuv.app.bpm-management.task.actions.assign.success')));
699
+ }
700
+ unassignTask(task) {
701
+ return this.#confirm('400px', {
702
+ title: this.#translate.instant('yuv.app.bpm-management.task.actions.unassign.label'),
703
+ message: this.#translate.instant('yuv.app.bpm-management.task.actions.unassign.confirm.message')
704
+ }).pipe(switchMap(() => this.#updateAssignee(task.id, null, 'yuv.app.bpm-management.task.actions.unassign.success')));
705
+ }
706
+ /** The candidates are only part of the details of a task, a list row loads them first. */
707
+ editTaskCandidates(task) {
708
+ const withCandidates = task.identityLinks ? of(task) : this.#service.getTask(task.id);
709
+ return withCandidates.pipe(switchMap(t => this.#dialog
710
+ .open(TaskCandidatesOverlayComponent, {
711
+ width: '600px',
712
+ maxWidth: '95vw',
713
+ data: {
714
+ currentUsers: [...(t?.identityLinks?.candidates?.users ?? [])],
715
+ currentRoles: [...(t?.identityLinks?.candidates?.roles ?? [])]
716
+ }
717
+ })
718
+ .afterClosed()), filter((result) => result !== undefined), switchMap(result => this.#service.setTaskCandidates(task.id, result)),
719
+ // candidates are not shown in the list
720
+ this.#result('details', 'yuv.app.bpm-management.task.candidates.update.success', 'yuv.app.bpm-management.task.candidates.update.error', 'Failed to update the candidates of the task'));
721
+ }
722
+ /** Asks with the shared confirm dialog; emits only when confirmed. */
723
+ #confirm(width, data) {
724
+ return this.#dialog
725
+ .open(ConfirmComponent, { width, maxWidth: '90vw', data })
726
+ .afterClosed()
727
+ .pipe(filter((confirm) => !!confirm));
728
+ }
729
+ #updateAssignee(taskId, assignee, successKey) {
730
+ return this.#service
731
+ .assignTask(taskId, assignee)
732
+ .pipe(this.#result('both', successKey, 'yuv.app.bpm-management.task.actions.assign.error', 'Failed to change the assignee of the task'));
733
+ }
734
+ /** Notifies the outcome of the backend call and maps a success to the reload scope. */
735
+ #result(scope, successKey, errorKey, logMessage) {
736
+ return (source) => source.pipe(map(() => {
737
+ this.#notifications.success(this.#translate.instant(successKey));
738
+ return scope;
739
+ }), catchError((e) => {
740
+ this.#logger.error(logMessage, e);
741
+ this.#notifications.error(this.#translate.instant(errorKey));
742
+ return EMPTY;
743
+ }));
744
+ }
745
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: BpmManagementActionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
746
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: BpmManagementActionsService, providedIn: 'root' });
747
+ }
748
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: BpmManagementActionsService, decorators: [{
749
+ type: Injectable,
750
+ args: [{ providedIn: 'root' }]
751
+ }] });
752
+
555
753
  const PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
556
754
  const DEFAULT_PAGE_SIZE = 50;
557
755
  const initialView = (entity) => ({
@@ -605,11 +803,11 @@ class EntitySwitchComponent {
605
803
  value = input.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
606
804
  valueChange = output();
607
805
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: EntitySwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
608
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: EntitySwitchComponent, isStandalone: true, selector: "ymbpm-entity-switch", inputs: { entities: { classPropertyName: "entities", publicName: "entities", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"bar\">\n<mat-button-toggle-group\n class=\"toggles\"\n hideSingleSelectionIndicator\n [value]=\"value()\"\n (change)=\"valueChange.emit($event.value)\"\n [attr.aria-label]=\"'yuv.app.bpm-management.entity.switch.aria' | translate\"\n>\n @for (entity of entities(); track entity) {\n <mat-button-toggle [value]=\"entity\" [matTooltip]=\"ENTITY_META[entity].label | translate\">\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[entity].icon }}</mat-icon>\n <span class=\"label\">{{ ENTITY_META[entity].label | translate }}</span>\n </mat-button-toggle>\n }\n</mat-button-toggle-group>\n\n<!-- little space: the toggles collapse into one toggle with the current entity, which opens the menu -->\n<mat-button-toggle-group class=\"compact\" hideSingleSelectionIndicator [value]=\"value()\">\n <mat-button-toggle\n [value]=\"value()\"\n [matMenuTriggerFor]=\"entityMenu\"\n [matTooltip]=\"ENTITY_META[value()].label | translate\"\n [aria-label]=\"('yuv.app.bpm-management.entity.switch.aria' | translate) + ': ' + (ENTITY_META[value()].label | translate)\"\n >\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[value()].icon }}</mat-icon>\n <mat-icon aria-hidden=\"true\">arrow_drop_down</mat-icon>\n </mat-button-toggle>\n</mat-button-toggle-group>\n<mat-menu #entityMenu=\"matMenu\">\n @for (entity of entities(); track entity) {\n <button mat-menu-item role=\"menuitemradio\" [attr.aria-checked]=\"entity === value()\" (click)=\"valueChange.emit(entity)\">\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[entity].icon }}</mat-icon>\n {{ ENTITY_META[entity].label | translate }}\n </button>\n }\n</mat-menu>\n</div>\n", styles: [".mat-mdc-menu-item[aria-checked=true]{background:var(--ymt-primary-container);--mat-menu-item-label-text-color: var(--ymt-on-primary-container);--mat-menu-item-icon-color: var(--ymt-on-primary-container)}:host{display:block;container-type:inline-size;min-width:0}.bar{display:inline-flex;align-items:center}mat-button-toggle-group{--mat-button-toggle-height: var(--ymt-sizing-3xl);--mat-button-toggle-divider-color: color-mix(in srgb, var(--ymt-outline) 50%, var(--ymt-outline-variant));--mat-button-toggle-selected-state-background-color: var(--ymt-primary-container);--mat-button-toggle-selected-state-text-color: var(--ymt-on-primary-container)}mat-button-toggle{min-width:var(--ymt-sizing-7xl)}mat-icon{margin-right:var(--ymt-spacing-xs)}.compact{display:none}@container (max-width: 34rem){.label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}mat-button-toggle{min-width:0}mat-icon{margin-right:0}}@container (max-width: 12rem){.toggles{display:none}.compact{display:inline-flex}}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
806
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: EntitySwitchComponent, isStandalone: true, selector: "ymbpm-entity-switch", inputs: { entities: { classPropertyName: "entities", publicName: "entities", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"bar\">\n<mat-button-toggle-group\n class=\"toggles\"\n hideSingleSelectionIndicator\n [value]=\"value()\"\n (change)=\"valueChange.emit($event.value)\"\n [attr.aria-label]=\"'yuv.app.bpm-management.entity.switch.aria' | translate\"\n>\n @for (entity of entities(); track entity) {\n <mat-button-toggle [value]=\"entity\" [matTooltip]=\"ENTITY_META[entity].label | translate\">\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[entity].icon }}</mat-icon>\n <span class=\"label\">{{ ENTITY_META[entity].label | translate }}</span>\n </mat-button-toggle>\n }\n</mat-button-toggle-group>\n\n<!-- little space: the toggles collapse into one toggle with the current entity, which opens the menu -->\n<mat-button-toggle-group class=\"compact\" hideSingleSelectionIndicator [value]=\"value()\">\n <mat-button-toggle\n [value]=\"value()\"\n [matMenuTriggerFor]=\"entityMenu\"\n [matTooltip]=\"ENTITY_META[value()].label | translate\"\n [aria-label]=\"('yuv.app.bpm-management.entity.switch.aria' | translate) + ': ' + (ENTITY_META[value()].label | translate)\"\n >\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[value()].icon }}</mat-icon>\n <mat-icon aria-hidden=\"true\">arrow_drop_down</mat-icon>\n </mat-button-toggle>\n</mat-button-toggle-group>\n<mat-menu #entityMenu=\"matMenu\">\n @for (entity of entities(); track entity) {\n <button mat-menu-item role=\"menuitemradio\" [attr.aria-checked]=\"entity === value()\" (click)=\"valueChange.emit(entity)\">\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[entity].icon }}</mat-icon>\n {{ ENTITY_META[entity].label | translate }}\n </button>\n }\n</mat-menu>\n</div>\n", styles: [".mat-mdc-menu-item[aria-checked=true]{background:var(--ymt-primary-container);--mat-menu-item-label-text-color: var(--ymt-on-primary-container);--mat-menu-item-icon-color: var(--ymt-on-primary-container)}:host{display:block;container-type:inline-size;min-width:calc(2 * var(--ymt-sizing-m) + 2 * var(--ymt-spacing-s) + 2 * var(--ymt-outline-width))}.bar{display:inline-flex;align-items:center}mat-button-toggle-group{--mat-button-toggle-height: var(--ymt-sizing-3xl);--mat-button-toggle-divider-color: color-mix(in srgb, var(--ymt-outline) 50%, var(--ymt-outline-variant));--mat-button-toggle-selected-state-background-color: var(--ymt-primary-container);--mat-button-toggle-selected-state-text-color: var(--ymt-on-primary-container)}mat-button-toggle{min-width:var(--ymt-sizing-7xl)}mat-icon{margin-right:var(--ymt-spacing-xs)}.compact{display:none}@container (max-width: 34rem){.label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}mat-button-toggle{min-width:0}mat-icon{margin-right:0}}@container (max-width: 12rem){.toggles{display:none}.compact{display:inline-flex}}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i1$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i1$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
609
807
  }
610
808
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: EntitySwitchComponent, decorators: [{
611
809
  type: Component,
612
- args: [{ selector: 'ymbpm-entity-switch', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatButtonToggleModule, MatIconModule, MatMenuModule, MatTooltipModule, TranslatePipe], template: "<div class=\"bar\">\n<mat-button-toggle-group\n class=\"toggles\"\n hideSingleSelectionIndicator\n [value]=\"value()\"\n (change)=\"valueChange.emit($event.value)\"\n [attr.aria-label]=\"'yuv.app.bpm-management.entity.switch.aria' | translate\"\n>\n @for (entity of entities(); track entity) {\n <mat-button-toggle [value]=\"entity\" [matTooltip]=\"ENTITY_META[entity].label | translate\">\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[entity].icon }}</mat-icon>\n <span class=\"label\">{{ ENTITY_META[entity].label | translate }}</span>\n </mat-button-toggle>\n }\n</mat-button-toggle-group>\n\n<!-- little space: the toggles collapse into one toggle with the current entity, which opens the menu -->\n<mat-button-toggle-group class=\"compact\" hideSingleSelectionIndicator [value]=\"value()\">\n <mat-button-toggle\n [value]=\"value()\"\n [matMenuTriggerFor]=\"entityMenu\"\n [matTooltip]=\"ENTITY_META[value()].label | translate\"\n [aria-label]=\"('yuv.app.bpm-management.entity.switch.aria' | translate) + ': ' + (ENTITY_META[value()].label | translate)\"\n >\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[value()].icon }}</mat-icon>\n <mat-icon aria-hidden=\"true\">arrow_drop_down</mat-icon>\n </mat-button-toggle>\n</mat-button-toggle-group>\n<mat-menu #entityMenu=\"matMenu\">\n @for (entity of entities(); track entity) {\n <button mat-menu-item role=\"menuitemradio\" [attr.aria-checked]=\"entity === value()\" (click)=\"valueChange.emit(entity)\">\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[entity].icon }}</mat-icon>\n {{ ENTITY_META[entity].label | translate }}\n </button>\n }\n</mat-menu>\n</div>\n", styles: [".mat-mdc-menu-item[aria-checked=true]{background:var(--ymt-primary-container);--mat-menu-item-label-text-color: var(--ymt-on-primary-container);--mat-menu-item-icon-color: var(--ymt-on-primary-container)}:host{display:block;container-type:inline-size;min-width:0}.bar{display:inline-flex;align-items:center}mat-button-toggle-group{--mat-button-toggle-height: var(--ymt-sizing-3xl);--mat-button-toggle-divider-color: color-mix(in srgb, var(--ymt-outline) 50%, var(--ymt-outline-variant));--mat-button-toggle-selected-state-background-color: var(--ymt-primary-container);--mat-button-toggle-selected-state-text-color: var(--ymt-on-primary-container)}mat-button-toggle{min-width:var(--ymt-sizing-7xl)}mat-icon{margin-right:var(--ymt-spacing-xs)}.compact{display:none}@container (max-width: 34rem){.label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}mat-button-toggle{min-width:0}mat-icon{margin-right:0}}@container (max-width: 12rem){.toggles{display:none}.compact{display:inline-flex}}\n"] }]
810
+ args: [{ selector: 'ymbpm-entity-switch', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatButtonToggleModule, MatIconModule, MatMenuModule, MatTooltipModule, TranslatePipe], template: "<div class=\"bar\">\n<mat-button-toggle-group\n class=\"toggles\"\n hideSingleSelectionIndicator\n [value]=\"value()\"\n (change)=\"valueChange.emit($event.value)\"\n [attr.aria-label]=\"'yuv.app.bpm-management.entity.switch.aria' | translate\"\n>\n @for (entity of entities(); track entity) {\n <mat-button-toggle [value]=\"entity\" [matTooltip]=\"ENTITY_META[entity].label | translate\">\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[entity].icon }}</mat-icon>\n <span class=\"label\">{{ ENTITY_META[entity].label | translate }}</span>\n </mat-button-toggle>\n }\n</mat-button-toggle-group>\n\n<!-- little space: the toggles collapse into one toggle with the current entity, which opens the menu -->\n<mat-button-toggle-group class=\"compact\" hideSingleSelectionIndicator [value]=\"value()\">\n <mat-button-toggle\n [value]=\"value()\"\n [matMenuTriggerFor]=\"entityMenu\"\n [matTooltip]=\"ENTITY_META[value()].label | translate\"\n [aria-label]=\"('yuv.app.bpm-management.entity.switch.aria' | translate) + ': ' + (ENTITY_META[value()].label | translate)\"\n >\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[value()].icon }}</mat-icon>\n <mat-icon aria-hidden=\"true\">arrow_drop_down</mat-icon>\n </mat-button-toggle>\n</mat-button-toggle-group>\n<mat-menu #entityMenu=\"matMenu\">\n @for (entity of entities(); track entity) {\n <button mat-menu-item role=\"menuitemradio\" [attr.aria-checked]=\"entity === value()\" (click)=\"valueChange.emit(entity)\">\n <mat-icon aria-hidden=\"true\">{{ ENTITY_META[entity].icon }}</mat-icon>\n {{ ENTITY_META[entity].label | translate }}\n </button>\n }\n</mat-menu>\n</div>\n", styles: [".mat-mdc-menu-item[aria-checked=true]{background:var(--ymt-primary-container);--mat-menu-item-label-text-color: var(--ymt-on-primary-container);--mat-menu-item-icon-color: var(--ymt-on-primary-container)}:host{display:block;container-type:inline-size;min-width:calc(2 * var(--ymt-sizing-m) + 2 * var(--ymt-spacing-s) + 2 * var(--ymt-outline-width))}.bar{display:inline-flex;align-items:center}mat-button-toggle-group{--mat-button-toggle-height: var(--ymt-sizing-3xl);--mat-button-toggle-divider-color: color-mix(in srgb, var(--ymt-outline) 50%, var(--ymt-outline-variant));--mat-button-toggle-selected-state-background-color: var(--ymt-primary-container);--mat-button-toggle-selected-state-text-color: var(--ymt-on-primary-container)}mat-button-toggle{min-width:var(--ymt-sizing-7xl)}mat-icon{margin-right:var(--ymt-spacing-xs)}.compact{display:none}@container (max-width: 34rem){.label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}mat-button-toggle{min-width:0}mat-icon{margin-right:0}}@container (max-width: 12rem){.toggles{display:none}.compact{display:inline-flex}}\n"] }]
613
811
  }], propDecorators: { entities: [{ type: i0.Input, args: [{ isSignal: true, alias: "entities", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
614
812
 
615
813
  /**
@@ -630,7 +828,7 @@ class FilterClearComponent {
630
828
  >
631
829
  <mat-icon>close</mat-icon>
632
830
  </button>
633
- `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding-inline:var(--ymt-spacing-2xs)}\n"], dependencies: [{ kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
831
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding-inline:var(--ymt-spacing-2xs)}\n"], dependencies: [{ kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
634
832
  }
635
833
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: FilterClearComponent, decorators: [{
636
834
  type: Component,
@@ -734,7 +932,7 @@ class DateTimeFieldComponent {
734
932
  this.stateChanges.next();
735
933
  }
736
934
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: DateTimeFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
737
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", type: DateTimeFieldComponent, isStandalone: true, selector: "ymbpm-date-time-field", host: { listeners: { "focusin": "onFocusIn()", "focusout": "onFocusOut()" }, properties: { "id": "id", "attr.aria-describedby": "describedBy" } }, providers: [{ provide: MatFormFieldControl, useExisting: forwardRef(() => DateTimeFieldComponent) }], ngImport: i0, template: `<yuv-datepicker [formControl]="inner" [withTime]="true" [calendar]="true" [locale]="locale" />`, isInline: true, styles: [":host{display:flex;align-items:center;min-width:0;padding-inline-end:var(--ymt-spacing-2xs)}yuv-datepicker{flex:1;min-width:0}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: YuvDatepickerModule }, { kind: "component", type: i2.DatepickerComponent, selector: "yuv-datepicker", inputs: ["calendar", "readonly", "hour12", "locale", "labels", "withTime", "onlyFutureDates", "minDate", "maxDate", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
935
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", type: DateTimeFieldComponent, isStandalone: true, selector: "ymbpm-date-time-field", host: { listeners: { "focusin": "onFocusIn()", "focusout": "onFocusOut()" }, properties: { "id": "id", "attr.aria-describedby": "describedBy" } }, providers: [{ provide: MatFormFieldControl, useExisting: forwardRef(() => DateTimeFieldComponent) }], ngImport: i0, template: `<yuv-datepicker [formControl]="inner" [withTime]="true" [calendar]="true" [locale]="locale" />`, isInline: true, styles: [":host{display:flex;align-items:center;min-width:0;padding-inline-end:var(--ymt-spacing-2xs)}yuv-datepicker{flex:1;min-width:0}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: YuvDatepickerModule }, { kind: "component", type: i2$1.DatepickerComponent, selector: "yuv-datepicker", inputs: ["calendar", "readonly", "hour12", "locale", "labels", "withTime", "onlyFutureDates", "minDate", "maxDate", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
738
936
  }
739
937
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: DateTimeFieldComponent, decorators: [{
740
938
  type: Component,
@@ -808,7 +1006,7 @@ class DateTimeRangeFieldComponent {
808
1006
  <yuv-datepicker [formControl]="start()" [withTime]="true" [calendar]="true" [locale]="locale" />
809
1007
  <span class="separator" aria-hidden="true">–</span>
810
1008
  <yuv-datepicker [formControl]="end()" [withTime]="true" [calendar]="true" [locale]="locale" />
811
- `, isInline: true, styles: [":host{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);min-width:0;padding-inline-end:var(--ymt-spacing-2xs)}yuv-datepicker{flex:1 1 0;min-width:0}.separator{color:var(--ymt-text-color-subtle)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: YuvDatepickerModule }, { kind: "component", type: i2.DatepickerComponent, selector: "yuv-datepicker", inputs: ["calendar", "readonly", "hour12", "locale", "labels", "withTime", "onlyFutureDates", "minDate", "maxDate", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1009
+ `, isInline: true, styles: [":host{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);min-width:0;padding-inline-end:var(--ymt-spacing-2xs)}yuv-datepicker{flex:1 1 0;min-width:0}.separator{color:var(--ymt-text-color-subtle)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: YuvDatepickerModule }, { kind: "component", type: i2$1.DatepickerComponent, selector: "yuv-datepicker", inputs: ["calendar", "readonly", "hour12", "locale", "labels", "withTime", "onlyFutureDates", "minDate", "maxDate", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
812
1010
  }
813
1011
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: DateTimeRangeFieldComponent, decorators: [{
814
1012
  type: Component,
@@ -857,7 +1055,7 @@ class FilterOperatorComponent {
857
1055
  </button>
858
1056
  }
859
1057
  }
860
- `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding-inline:var(--ymt-spacing-2xs)}.fixed{color:var(--ymt-text-color-subtle);cursor:default}\n"], dependencies: [{ kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1058
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding-inline:var(--ymt-spacing-2xs)}.fixed{color:var(--ymt-text-color-subtle);cursor:default}\n"], dependencies: [{ kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
861
1059
  }
862
1060
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: FilterOperatorComponent, decorators: [{
863
1061
  type: Component,
@@ -1036,7 +1234,7 @@ class DateFilterComponent {
1036
1234
  useExisting: forwardRef(() => DateFilterComponent),
1037
1235
  multi: true
1038
1236
  }
1039
- ], viewQueries: [{ propertyName: "tooltip", first: true, predicate: MatTooltip, descendants: true }], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n <mat-form-field class=\"filter-field\">\n <mat-label>{{ label() | translate }}</mat-label>\n <ymbpm-filter-operator matPrefix [operators]=\"operators()\" [value]=\"operatorControl.value\" (valueChange)=\"setOperator($event)\" />\n @if (isBetweenMode()) {\n <ymbpm-date-time-range-field [start]=\"valueControl\" [end]=\"endDateControl\" />\n } @else {\n <ymbpm-date-time-field [formControl]=\"valueControl\" />\n }\n @if (isActiveFilter()) {\n <ymbpm-filter-clear matSuffix (cleared)=\"clearFilter(true)\" />\n }\n </mat-form-field>\n</div>\n", styles: [".filter-input-group{display:flex;flex-direction:column;width:100%;min-width:0}.filter-field{min-width:0}.filter-field ::ng-deep .mat-mdc-text-field-wrapper{padding-inline-end:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.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.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: FilterClearComponent, selector: "ymbpm-filter-clear", outputs: ["cleared"] }, { kind: "component", type: FilterOperatorComponent, selector: "ymbpm-filter-operator", inputs: ["operators", "value"], outputs: ["valueChange"] }, { kind: "component", type: DateTimeFieldComponent, selector: "ymbpm-date-time-field" }, { kind: "component", type: DateTimeRangeFieldComponent, selector: "ymbpm-date-time-range-field", inputs: ["start", "end"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1237
+ ], viewQueries: [{ propertyName: "tooltip", first: true, predicate: MatTooltip, descendants: true }], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n <mat-form-field class=\"filter-field\">\n <mat-label>{{ label() | translate }}</mat-label>\n <ymbpm-filter-operator matPrefix [operators]=\"operators()\" [value]=\"operatorControl.value\" (valueChange)=\"setOperator($event)\" />\n @if (isBetweenMode()) {\n <ymbpm-date-time-range-field [start]=\"valueControl\" [end]=\"endDateControl\" />\n } @else {\n <ymbpm-date-time-field [formControl]=\"valueControl\" />\n }\n @if (isActiveFilter()) {\n <ymbpm-filter-clear matSuffix (cleared)=\"clearFilter(true)\" />\n }\n </mat-form-field>\n</div>\n", styles: [".filter-input-group{display:flex;flex-direction:column;width:100%;min-width:0}.filter-field{min-width:0}.filter-field ::ng-deep .mat-mdc-text-field-wrapper{padding-inline-end:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: FilterClearComponent, selector: "ymbpm-filter-clear", outputs: ["cleared"] }, { kind: "component", type: FilterOperatorComponent, selector: "ymbpm-filter-operator", inputs: ["operators", "value"], outputs: ["valueChange"] }, { kind: "component", type: DateTimeFieldComponent, selector: "ymbpm-date-time-field" }, { kind: "component", type: DateTimeRangeFieldComponent, selector: "ymbpm-date-time-range-field", inputs: ["start", "end"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1040
1238
  }
1041
1239
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: DateFilterComponent, decorators: [{
1042
1240
  type: Component,
@@ -1169,7 +1367,7 @@ class NumberFilterComponent {
1169
1367
  ? value.operator
1170
1368
  : this.operators()[0].value;
1171
1369
  this.filterForm.setValue({
1172
- value: value.value,
1370
+ value: typeof value.value === 'number' ? value.value : null,
1173
1371
  operator: operator
1174
1372
  }, { emitEvent: false });
1175
1373
  }
@@ -1198,7 +1396,7 @@ class NumberFilterComponent {
1198
1396
  useExisting: forwardRef(() => NumberFilterComponent),
1199
1397
  multi: true
1200
1398
  }
1201
- ], viewQueries: [{ propertyName: "tooltip", first: true, predicate: MatTooltip, descendants: true }], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n <mat-form-field class=\"filter-field\">\n <mat-label>{{ label() | translate }}</mat-label>\n <ymbpm-filter-operator matPrefix [operators]=\"operators()\" [value]=\"operatorControl.value\" (valueChange)=\"setOperator($event)\" />\n <input matInput type=\"number\" [attr.min]=\"min()\"\n [formControl]=\"numberControl\"\n (keydown.enter)=\"onEnter()\">\n @if (isActiveFilter()) {\n <ymbpm-filter-clear matSuffix (cleared)=\"clearFilter(true)\" />\n }\n </mat-form-field>\n</div>", styles: [".filter-input-group{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);width:100%;min-width:0}.filter-field{flex:1;min-width:0}.filter-clear-btn{flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.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$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.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.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.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: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: FilterClearComponent, selector: "ymbpm-filter-clear", outputs: ["cleared"] }, { kind: "component", type: FilterOperatorComponent, selector: "ymbpm-filter-operator", inputs: ["operators", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1399
+ ], viewQueries: [{ propertyName: "tooltip", first: true, predicate: MatTooltip, descendants: true }], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n <mat-form-field class=\"filter-field\">\n <mat-label>{{ label() | translate }}</mat-label>\n <ymbpm-filter-operator matPrefix [operators]=\"operators()\" [value]=\"operatorControl.value\" (valueChange)=\"setOperator($event)\" />\n <input matInput type=\"number\" [attr.min]=\"min()\"\n [formControl]=\"numberControl\"\n (keydown.enter)=\"onEnter()\">\n @if (isActiveFilter()) {\n <ymbpm-filter-clear matSuffix (cleared)=\"clearFilter(true)\" />\n }\n </mat-form-field>\n</div>", styles: [".filter-input-group{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);width:100%;min-width:0}.filter-field{flex:1;min-width:0}.filter-clear-btn{flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.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: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: FilterClearComponent, selector: "ymbpm-filter-clear", outputs: ["cleared"] }, { kind: "component", type: FilterOperatorComponent, selector: "ymbpm-filter-operator", inputs: ["operators", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1202
1400
  }
1203
1401
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: NumberFilterComponent, decorators: [{
1204
1402
  type: Component,
@@ -1315,7 +1513,7 @@ class SelectFilterComponent {
1315
1513
  useExisting: forwardRef(() => SelectFilterComponent),
1316
1514
  multi: true
1317
1515
  }
1318
- ], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n <mat-form-field class=\"filter-field\" floatLabel=\"always\">\n <mat-label>{{ label() | translate }}</mat-label>\n @if (!enableMultiselect()) {\n <ymbpm-filter-operator matPrefix [operators]=\"equals\" value=\"equals\" />\n }\n <mat-select [formControl]=\"selectControl\"\n [placeholder]=\"placeholder() ? (placeholder() | translate) : ''\"\n [multiple]=\"enableMultiselect()\">\n @if (!enableMultiselect()) {\n <mat-select-trigger>\n @if (selectedOption(); as selected) {\n @if (selected.icon) {\n <mat-icon class=\"option-icon\">{{ icons[selected.icon] }}</mat-icon>\n }\n {{ selected.label | translate }}\n }\n </mat-select-trigger>\n }\n @for (option of options(); track option.value) {\n <mat-option [value]=\"option.value\">\n @if (option.icon) {\n <mat-icon class=\"option-icon\">{{ icons[option.icon] }}</mat-icon>\n }\n {{option.label | translate}}\n </mat-option>\n }\n </mat-select>\n @if (isActiveFilter()) {\n <ymbpm-filter-clear matSuffix (cleared)=\"clearFilter(true)\" />\n }\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>\n", styles: [".filter-input-group{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);width:100%}.filter-field{flex:1}.filter-clear-btn{flex-shrink:0}.multi-select-suffix{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);color:var(--ymt-text-color-subtle)}.option-icon{vertical-align:middle;margin-inline-end:var(--ymt-spacing-xs)}.count{font:var(--ymt-font-body-subtle)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.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.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3$3.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: "directive", type: i3$3.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i3$3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: FilterClearComponent, selector: "ymbpm-filter-clear", outputs: ["cleared"] }, { kind: "component", type: FilterOperatorComponent, selector: "ymbpm-filter-operator", inputs: ["operators", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1516
+ ], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n <mat-form-field class=\"filter-field\" floatLabel=\"always\">\n <mat-label>{{ label() | translate }}</mat-label>\n @if (!enableMultiselect()) {\n <ymbpm-filter-operator matPrefix [operators]=\"equals\" value=\"equals\" />\n }\n <mat-select [formControl]=\"selectControl\"\n [placeholder]=\"placeholder() ? (placeholder() | translate) : ''\"\n [multiple]=\"enableMultiselect()\">\n @if (!enableMultiselect()) {\n <mat-select-trigger>\n @if (selectedOption(); as selected) {\n @if (selected.icon) {\n <mat-icon class=\"option-icon\">{{ icons[selected.icon] }}</mat-icon>\n }\n {{ selected.label | translate }}\n }\n </mat-select-trigger>\n }\n @for (option of options(); track option.value) {\n <mat-option [value]=\"option.value\">\n @if (option.icon) {\n <mat-icon class=\"option-icon\">{{ icons[option.icon] }}</mat-icon>\n }\n {{option.label | translate}}\n </mat-option>\n }\n </mat-select>\n @if (isActiveFilter()) {\n <ymbpm-filter-clear matSuffix (cleared)=\"clearFilter(true)\" />\n }\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>\n", styles: [".filter-input-group{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);width:100%}.filter-field{flex:1}.filter-clear-btn{flex-shrink:0}.multi-select-suffix{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);color:var(--ymt-text-color-subtle)}.option-icon{vertical-align:middle;margin-inline-end:var(--ymt-spacing-xs)}.count{font:var(--ymt-font-body-subtle)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2.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: "directive", type: i3$2.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i3$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: FilterClearComponent, selector: "ymbpm-filter-clear", outputs: ["cleared"] }, { kind: "component", type: FilterOperatorComponent, selector: "ymbpm-filter-operator", inputs: ["operators", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1319
1517
  }
1320
1518
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: SelectFilterComponent, decorators: [{
1321
1519
  type: Component,
@@ -1476,7 +1674,7 @@ class TextFilterComponent {
1476
1674
  useExisting: forwardRef(() => TextFilterComponent),
1477
1675
  multi: true
1478
1676
  }
1479
- ], viewQueries: [{ propertyName: "tooltip", first: true, predicate: MatTooltip, descendants: true }], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n <mat-form-field class=\"filter-field\">\n <mat-label>{{ label() | translate }}</mat-label>\n <ymbpm-filter-operator matPrefix [operators]=\"operators()\" [value]=\"operatorControl.value\" (valueChange)=\"setOperator($event)\" />\n <input matInput \n [formControl]=\"textControl\"\n (keydown.enter)=\"onEnter()\">\n @if (isActiveFilter()) {\n <ymbpm-filter-clear matSuffix (cleared)=\"clearFilter(true)\" />\n }\n </mat-form-field>\n</div>", styles: [".filter-input-group{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);width:100%;min-width:0}.filter-field{flex:1;min-width:0}.filter-clear-btn{flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.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.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.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: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: FilterClearComponent, selector: "ymbpm-filter-clear", outputs: ["cleared"] }, { kind: "component", type: FilterOperatorComponent, selector: "ymbpm-filter-operator", inputs: ["operators", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1677
+ ], viewQueries: [{ propertyName: "tooltip", first: true, predicate: MatTooltip, descendants: true }], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"isActiveFilter()\">\n <mat-form-field class=\"filter-field\">\n <mat-label>{{ label() | translate }}</mat-label>\n <ymbpm-filter-operator matPrefix [operators]=\"operators()\" [value]=\"operatorControl.value\" (valueChange)=\"setOperator($event)\" />\n <input matInput \n [formControl]=\"textControl\"\n (keydown.enter)=\"onEnter()\">\n @if (isActiveFilter()) {\n <ymbpm-filter-clear matSuffix (cleared)=\"clearFilter(true)\" />\n }\n </mat-form-field>\n</div>", styles: [".filter-input-group{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);width:100%;min-width:0}.filter-field{flex:1;min-width:0}.filter-clear-btn{flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.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: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: FilterClearComponent, selector: "ymbpm-filter-clear", outputs: ["cleared"] }, { kind: "component", type: FilterOperatorComponent, selector: "ymbpm-filter-operator", inputs: ["operators", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1480
1678
  }
1481
1679
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: TextFilterComponent, decorators: [{
1482
1680
  type: Component,
@@ -1566,7 +1764,7 @@ class UserFilterComponent {
1566
1764
  useExisting: forwardRef(() => UserFilterComponent),
1567
1765
  multi: true
1568
1766
  }
1569
- ], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"!!orgControl.value\">\n <mat-form-field class=\"filter-field\">\n <mat-label>{{ label() | translate }}</mat-label>\n <ymbpm-filter-operator matPrefix [operators]=\"equals\" value=\"equals\" />\n @if (showOrganization()) {\n <yuv-organization [formControl]=\"orgControl\" [excludeMe]=\"false\" situation=\"SEARCH\"></yuv-organization>\n }\n @if (orgControl.value) {\n <ymbpm-filter-clear matSuffix (cleared)=\"clearFilter(true)\" />\n }\n </mat-form-field>\n</div>\n", styles: [".filter-input-group{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);width:100%;min-width:0}.filter-field{flex:1}.filter-field ::ng-deep yuv-organization mat-icon{display:none}.filter-field ::ng-deep yuv-organization input{min-height:0!important;font-weight:400!important}.filter-field ::ng-deep yuv-organization button{display:none!important}.filter-field ::ng-deep yuv-organization mat-chip-row,.filter-field ::ng-deep yuv-organization .mat-mdc-chip-row{max-width:100%!important;flex-shrink:1!important}.filter-field ::ng-deep yuv-organization .mdc-evolution-chip__cell--primary,.filter-field ::ng-deep yuv-organization .mdc-evolution-chip__action--primary{max-width:100%!important;overflow:hidden!important;padding-inline-end:var(--ymt-spacing-xs)!important}.filter-field ::ng-deep yuv-organization .mdc-evolution-chip__text-label,.filter-field ::ng-deep yuv-organization .mat-mdc-chip-action-label{max-width:100%!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.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.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: OrganizationComponent, selector: "yuv-organization", inputs: ["situation", "multiselect", "classifications", "readonly", "excludeMe", "withMetadata", "allowFreeText"] }, { kind: "component", type: FilterClearComponent, selector: "ymbpm-filter-clear", outputs: ["cleared"] }, { kind: "component", type: FilterOperatorComponent, selector: "ymbpm-filter-operator", inputs: ["operators", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1767
+ ], ngImport: i0, template: "<div class=\"filter-input-group\" [class.active]=\"!!orgControl.value\">\n <mat-form-field class=\"filter-field\">\n <mat-label>{{ label() | translate }}</mat-label>\n <ymbpm-filter-operator matPrefix [operators]=\"equals\" value=\"equals\" />\n @if (showOrganization()) {\n <yuv-organization [formControl]=\"orgControl\" [excludeMe]=\"false\" situation=\"SEARCH\"></yuv-organization>\n }\n @if (orgControl.value) {\n <ymbpm-filter-clear matSuffix (cleared)=\"clearFilter(true)\" />\n }\n </mat-form-field>\n</div>\n", styles: [".filter-input-group{display:flex;align-items:center;gap:var(--ymt-spacing-2xs);width:100%;min-width:0}.filter-field{flex:1}.filter-field ::ng-deep yuv-organization mat-icon{display:none}.filter-field ::ng-deep yuv-organization input{min-height:0!important;font-weight:400!important}.filter-field ::ng-deep yuv-organization button{display:none!important}.filter-field ::ng-deep yuv-organization mat-chip-row,.filter-field ::ng-deep yuv-organization .mat-mdc-chip-row{max-width:100%!important;flex-shrink:1!important}.filter-field ::ng-deep yuv-organization .mdc-evolution-chip__cell--primary,.filter-field ::ng-deep yuv-organization .mdc-evolution-chip__action--primary{max-width:100%!important;overflow:hidden!important;padding-inline-end:var(--ymt-spacing-xs)!important}.filter-field ::ng-deep yuv-organization .mdc-evolution-chip__text-label,.filter-field ::ng-deep yuv-organization .mat-mdc-chip-action-label{max-width:100%!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: OrganizationComponent, selector: "yuv-organization", inputs: ["situation", "multiselect", "classifications", "readonly", "excludeMe", "withMetadata", "allowFreeText"] }, { kind: "component", type: FilterClearComponent, selector: "ymbpm-filter-clear", outputs: ["cleared"] }, { kind: "component", type: FilterOperatorComponent, selector: "ymbpm-filter-operator", inputs: ["operators", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1570
1768
  }
1571
1769
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: UserFilterComponent, decorators: [{
1572
1770
  type: Component,
@@ -1634,7 +1832,7 @@ class FilterBarComponent {
1634
1832
  const label = this.#translate.instant(column.displayName);
1635
1833
  return {
1636
1834
  column,
1637
- userId: column.filter?.type === FILTER_TYPES.USER ? filter.value : null,
1835
+ userId: column.filter?.type === FILTER_TYPES.USER && typeof filter.value === 'string' ? filter.value : null,
1638
1836
  text: this.#describe(column, filter, true),
1639
1837
  title: `${label}: ${this.#describe(column, filter, false)}`
1640
1838
  };
@@ -1719,7 +1917,9 @@ class FilterBarComponent {
1719
1917
  }
1720
1918
  /** Same format as the dates of the lists and details. */
1721
1919
  #date(value) {
1722
- return value ? formatDateTime(new Date(value).toISOString(), this.#translate.currentLang) : '';
1920
+ return value instanceof Date || (typeof value === 'string' && value)
1921
+ ? formatDateTime(new Date(value).toISOString(), this.#translate.currentLang)
1922
+ : '';
1723
1923
  }
1724
1924
  #update(name, value) {
1725
1925
  const filters = { ...this.filters() };
@@ -1734,7 +1934,7 @@ class FilterBarComponent {
1734
1934
  this.filtersChange.emit(filters);
1735
1935
  }
1736
1936
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: FilterBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1737
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: FilterBarComponent, isStandalone: true, selector: "ymbpm-filter-bar", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filtersChange: "filtersChange", searchClear: "searchClear" }, host: { properties: { "class.empty": "!hasChips()" } }, viewQueries: [{ propertyName: "overlay", first: true, predicate: CdkConnectedOverlay, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"chips\" role=\"group\" [attr.aria-label]=\"'yuv.app.bpm-management.filters.title' | translate\">\n @if (search()) {\n <span class=\"chip\">\n <span class=\"chip__main chip__main--static\">\n <span class=\"chip__name\">{{ 'yuv.app.bpm-management.filters.search' | translate }}</span>\n <span class=\"chip__value\">{{ search() }}</span>\n </span>\n <button type=\"button\" class=\"chip__remove\" [attr.aria-label]=\"('yuv.app.bpm-management.filters.remove' | translate) + ': ' + ('yuv.app.bpm-management.filters.search' | translate)\" (click)=\"searchClear.emit()\">\n <mat-icon>close</mat-icon>\n </button>\n </span>\n }\n @for (chip of chips(); track chip.column.name) {\n <span class=\"chip\" [class.chip--editing]=\"editing()?.column === chip.column\">\n <button type=\"button\" class=\"chip__main\" #chipButton [attr.title]=\"chip.userId ? null : chip.title\" (click)=\"edit(chip.column, chipButton)\">\n <span class=\"chip__name\">{{ chip.column.displayName | translate }}</span>\n @if (chip.userId) {\n <yuv-organization-renderer propertyName=\"user\" [value]=\"chip.userId ?? null\"></yuv-organization-renderer>\n } @else {\n <span class=\"chip__value\">{{ chip.text }}</span>\n }\n </button>\n <button type=\"button\" class=\"chip__remove\" [attr.aria-label]=\"('yuv.app.bpm-management.filters.remove' | translate) + ': ' + (chip.column.displayName | translate)\" (click)=\"remove(chip.column)\">\n <mat-icon>close</mat-icon>\n </button>\n </span>\n }\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOpen]=\"!!editing()\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n (backdropClick)=\"close()\"\n (overlayKeydown)=\"onKeydown($event)\"\n (attach)=\"focusEditor()\"\n>\n @if (editing(); as current) {\n <div class=\"popover\" role=\"dialog\" [attr.aria-label]=\"current.column.displayName | translate\">\n @let column = current.column;\n @switch (column.filter?.type) {\n @case (FILTER_TYPES.TEXT) {\n <ymbpm-text-filter [label]=\"column.displayName\" [formControl]=\"control\" [operators]=\"$any(column.filter).operators || []\"></ymbpm-text-filter>\n }\n @case (FILTER_TYPES.NUMBER) {\n <ymbpm-number-filter [label]=\"column.displayName\" [formControl]=\"control\" [min]=\"$any(column.filter).minValue ?? null\" [operators]=\"$any(column.filter).operators || []\"></ymbpm-number-filter>\n }\n @case (FILTER_TYPES.SELECT) {\n <ymbpm-select-filter [label]=\"column.displayName\" [placeholder]=\"$any(column.filter).placeholder ?? 'yuv.app.bpm-management.filters.select'\" [formControl]=\"control\" [options]=\"$any(column.filter).options || []\" [enableMultiselect]=\"!!$any(column.filter).enableMultiselect\"></ymbpm-select-filter>\n }\n @case (FILTER_TYPES.DATE) {\n <ymbpm-date-filter [label]=\"column.displayName\" [formControl]=\"control\" [operators]=\"$any(column.filter).operators || []\"></ymbpm-date-filter>\n }\n @case (FILTER_TYPES.USER) {\n <ymbpm-user-filter [label]=\"column.displayName\" [formControl]=\"control\"></ymbpm-user-filter>\n }\n }\n </div>\n }\n</ng-template>\n", styles: [":host{display:block;padding:var(--ymt-spacing-s) var(--ymt-spacing-m);position:sticky;inset-block-start:0;z-index:1;background-color:var(--ymt-surface-container-low);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}:host.empty{display:none}.chips{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ymt-spacing-2xs)}.chip{display:inline-flex;align-items:center;max-width:100%;height:var(--ymt-sizing-m);border:var(--ymt-outline-width) solid var(--ymt-primary);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container);font:var(--ymt-font-body-subtle);overflow:hidden}.chip.chip--editing{background-color:var(--ymt-primary);color:var(--ymt-on-primary)}.chip mat-icon{font-size:var(--ymt-sizing-xs);width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs)}.chip__main,.chip__remove{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs);border:0;background:transparent;color:inherit;font:inherit;cursor:pointer}.chip__main:focus-visible,.chip__remove:focus-visible{outline:var(--ymt-focus-indicator-size) solid var(--ymt-primary);outline-offset:calc(-1 * var(--ymt-focus-indicator-size))}.chip__main{min-width:0;padding:0 var(--ymt-spacing-2xs) 0 var(--ymt-spacing-s)}.chip__main.chip__main--static{cursor:default}.chip__name{font-weight:700;white-space:nowrap}.chip__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chip__remove{align-self:stretch;padding:0 var(--ymt-spacing-xs) 0 var(--ymt-spacing-2xs);opacity:.75}.chip__remove:hover{opacity:1}.popover{width:min(24rem,100vw - 2rem);padding:var(--ymt-spacing-m);background-color:var(--ymt-surface);border:var(--ymt-outline-width) solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-m);box-shadow:0 6px 24px color-mix(in srgb,black 18%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$3.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: OrganizationRendererComponent, selector: "yuv-organization-renderer" }, { kind: "component", type: TextFilterComponent, selector: "ymbpm-text-filter", inputs: ["label", "operators"] }, { kind: "component", type: NumberFilterComponent, selector: "ymbpm-number-filter", inputs: ["label", "operators", "min"] }, { kind: "component", type: SelectFilterComponent, selector: "ymbpm-select-filter", inputs: ["label", "options", "enableMultiselect", "placeholder"] }, { kind: "component", type: DateFilterComponent, selector: "ymbpm-date-filter", inputs: ["label", "placeholder", "operators"] }, { kind: "component", type: UserFilterComponent, selector: "ymbpm-user-filter", inputs: ["label"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1937
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: FilterBarComponent, isStandalone: true, selector: "ymbpm-filter-bar", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filtersChange: "filtersChange", searchClear: "searchClear" }, host: { properties: { "class.empty": "!hasChips()" } }, viewQueries: [{ propertyName: "overlay", first: true, predicate: CdkConnectedOverlay, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"chips\" role=\"group\" [attr.aria-label]=\"'yuv.app.bpm-management.filters.title' | translate\">\n @if (search()) {\n <span class=\"chip\">\n <span class=\"chip__main chip__main--static\">\n <span class=\"chip__name\">{{ 'yuv.app.bpm-management.filters.search' | translate }}</span>\n <span class=\"chip__value\">{{ search() }}</span>\n </span>\n <button type=\"button\" class=\"chip__remove\" [attr.aria-label]=\"('yuv.app.bpm-management.filters.remove' | translate) + ': ' + ('yuv.app.bpm-management.filters.search' | translate)\" (click)=\"searchClear.emit()\">\n <mat-icon>close</mat-icon>\n </button>\n </span>\n }\n @for (chip of chips(); track chip.column.name) {\n <span class=\"chip\" [class.chip--editing]=\"editing()?.column === chip.column\">\n <button type=\"button\" class=\"chip__main\" #chipButton [attr.title]=\"chip.userId ? null : chip.title\" (click)=\"edit(chip.column, chipButton)\">\n <span class=\"chip__name\">{{ chip.column.displayName | translate }}</span>\n @if (chip.userId) {\n <yuv-organization-renderer propertyName=\"user\" [value]=\"chip.userId ?? null\"></yuv-organization-renderer>\n } @else {\n <span class=\"chip__value\">{{ chip.text }}</span>\n }\n </button>\n <button type=\"button\" class=\"chip__remove\" [attr.aria-label]=\"('yuv.app.bpm-management.filters.remove' | translate) + ': ' + (chip.column.displayName | translate)\" (click)=\"remove(chip.column)\">\n <mat-icon>close</mat-icon>\n </button>\n </span>\n }\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOpen]=\"!!editing()\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n (backdropClick)=\"close()\"\n (overlayKeydown)=\"onKeydown($event)\"\n (attach)=\"focusEditor()\"\n>\n @if (editing(); as current) {\n <div class=\"popover\" role=\"dialog\" [attr.aria-label]=\"current.column.displayName | translate\">\n @let column = current.column;\n @switch (column.filter?.type) {\n @case (FILTER_TYPES.TEXT) {\n <ymbpm-text-filter [label]=\"column.displayName\" [formControl]=\"control\" [operators]=\"$any(column.filter).operators || []\"></ymbpm-text-filter>\n }\n @case (FILTER_TYPES.NUMBER) {\n <ymbpm-number-filter [label]=\"column.displayName\" [formControl]=\"control\" [min]=\"$any(column.filter).minValue ?? null\" [operators]=\"$any(column.filter).operators || []\"></ymbpm-number-filter>\n }\n @case (FILTER_TYPES.SELECT) {\n <ymbpm-select-filter [label]=\"column.displayName\" [placeholder]=\"$any(column.filter).placeholder ?? 'yuv.app.bpm-management.filters.select'\" [formControl]=\"control\" [options]=\"$any(column.filter).options || []\" [enableMultiselect]=\"!!$any(column.filter).enableMultiselect\"></ymbpm-select-filter>\n }\n @case (FILTER_TYPES.DATE) {\n <ymbpm-date-filter [label]=\"column.displayName\" [formControl]=\"control\" [operators]=\"$any(column.filter).operators || []\"></ymbpm-date-filter>\n }\n @case (FILTER_TYPES.USER) {\n <ymbpm-user-filter [label]=\"column.displayName\" [formControl]=\"control\"></ymbpm-user-filter>\n }\n }\n </div>\n }\n</ng-template>\n", styles: [":host{display:block;padding:var(--ymt-spacing-s) var(--ymt-spacing-m);position:sticky;inset-block-start:0;z-index:1;background-color:var(--ymt-surface-container-low);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}:host.empty{display:none}.chips{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ymt-spacing-2xs)}.chip{display:inline-flex;align-items:center;max-width:100%;height:var(--ymt-sizing-m);border:var(--ymt-outline-width) solid var(--ymt-primary);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container);font:var(--ymt-font-body-subtle);overflow:hidden}.chip.chip--editing{background-color:var(--ymt-primary);color:var(--ymt-on-primary)}.chip mat-icon{font-size:var(--ymt-sizing-xs);width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs)}.chip__main,.chip__remove{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs);border:0;background:transparent;color:inherit;font:inherit;cursor:pointer}.chip__main:focus-visible,.chip__remove:focus-visible{outline:var(--ymt-focus-indicator-size) solid var(--ymt-primary);outline-offset:calc(-1 * var(--ymt-focus-indicator-size))}.chip__main{min-width:0;padding:0 var(--ymt-spacing-2xs) 0 var(--ymt-spacing-s)}.chip__main.chip__main--static{cursor:default}.chip__name{font-weight:700;white-space:nowrap}.chip__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chip__remove{align-self:stretch;padding:0 var(--ymt-spacing-xs) 0 var(--ymt-spacing-2xs);opacity:.75}.chip__remove:hover{opacity:1}.popover{width:min(24rem,100vw - 2rem);padding:var(--ymt-spacing-m);background-color:var(--ymt-surface);border:var(--ymt-outline-width) solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-m);box-shadow:0 6px 24px color-mix(in srgb,black 18%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$3.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: OrganizationRendererComponent, selector: "yuv-organization-renderer" }, { kind: "component", type: TextFilterComponent, selector: "ymbpm-text-filter", inputs: ["label", "operators"] }, { kind: "component", type: NumberFilterComponent, selector: "ymbpm-number-filter", inputs: ["label", "operators", "min"] }, { kind: "component", type: SelectFilterComponent, selector: "ymbpm-select-filter", inputs: ["label", "options", "enableMultiselect", "placeholder"] }, { kind: "component", type: DateFilterComponent, selector: "ymbpm-date-filter", inputs: ["label", "placeholder", "operators"] }, { kind: "component", type: UserFilterComponent, selector: "ymbpm-user-filter", inputs: ["label"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1738
1938
  }
1739
1939
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: FilterBarComponent, decorators: [{
1740
1940
  type: Component,
@@ -1770,7 +1970,7 @@ class PaneGutterComponent {
1770
1970
  flipLabel = input(false, ...(ngDevMode ? [{ debugName: "flipLabel" }] : /* istanbul ignore next */ []));
1771
1971
  expand = output();
1772
1972
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: PaneGutterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1773
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.25", type: PaneGutterComponent, isStandalone: true, selector: "ymbpm-pane-gutter", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: true, transformFunction: null }, flipLabel: { classPropertyName: "flipLabel", publicName: "flipLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expand: "expand" }, ngImport: i0, template: "<ymt-pane>\n <ymt-pane-body>\n <div\n class=\"pane-gutter\"\n role=\"button\"\n tabindex=\"0\"\n [matTooltip]=\"tooltip()\"\n [attr.aria-label]=\"tooltip()\"\n (click)=\"expand.emit()\"\n (keydown.enter)=\"expand.emit()\"\n (keydown.space)=\"$event.preventDefault(); expand.emit()\"\n >\n <mat-icon class=\"icon\" aria-hidden=\"true\">{{ icon() }}</mat-icon>\n <span class=\"label\" [class.label--btt]=\"flipLabel()\">{{ label() }}</span>\n </div>\n </ymt-pane-body>\n</ymt-pane>\n", styles: [":host{display:flex;flex:0 0 var(--ymt-sizing-3xl);width:var(--ymt-sizing-3xl)}ymt-pane{width:100%}.pane-gutter{height:100%;display:flex;flex-flow:column;align-items:center;gap:var(--ymt-spacing-s);padding-block-start:var(--ymt-spacing-xs);opacity:calc(1 - var(--ymt-disabled-opacity));cursor:pointer}.pane-gutter .icon{height:var(--ymt-sizing-s);width:var(--ymt-sizing-s);font-size:var(--ymt-sizing-s);line-height:1}.pane-gutter .label{font:var(--ymt-font-body-subtle);writing-mode:vertical-rl;white-space:nowrap}.pane-gutter .label--btt{transform:rotate(180deg)}.pane-gutter:focus,.pane-gutter:hover{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i10.YmtPaneComponent, selector: "ymt-pane", inputs: ["topBarActions", "busy", "noAnimation", "plain"] }, { kind: "component", type: i10.YmtPaneBodyComponent, selector: "ymt-pane-body" }] });
1973
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.25", type: PaneGutterComponent, isStandalone: true, selector: "ymbpm-pane-gutter", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: true, transformFunction: null }, flipLabel: { classPropertyName: "flipLabel", publicName: "flipLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expand: "expand" }, ngImport: i0, template: "<ymt-pane>\n <ymt-pane-body>\n <div\n class=\"pane-gutter\"\n role=\"button\"\n tabindex=\"0\"\n [matTooltip]=\"tooltip()\"\n [attr.aria-label]=\"tooltip()\"\n (click)=\"expand.emit()\"\n (keydown.enter)=\"expand.emit()\"\n (keydown.space)=\"$event.preventDefault(); expand.emit()\"\n >\n <mat-icon class=\"icon\" aria-hidden=\"true\">{{ icon() }}</mat-icon>\n <span class=\"label\" [class.label--btt]=\"flipLabel()\">{{ label() }}</span>\n </div>\n </ymt-pane-body>\n</ymt-pane>\n", styles: [":host{display:flex;flex:0 0 var(--ymt-sizing-3xl);width:var(--ymt-sizing-3xl)}ymt-pane{width:100%}.pane-gutter{height:100%;display:flex;flex-flow:column;align-items:center;gap:var(--ymt-spacing-s);padding-block-start:var(--ymt-spacing-xs);opacity:calc(1 - var(--ymt-disabled-opacity));cursor:pointer}.pane-gutter .icon{height:var(--ymt-sizing-s);width:var(--ymt-sizing-s);font-size:var(--ymt-sizing-s);line-height:1}.pane-gutter .label{font:var(--ymt-font-body-subtle);writing-mode:vertical-rl;white-space:nowrap}.pane-gutter .label--btt{transform:rotate(180deg)}.pane-gutter:focus,.pane-gutter:hover{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i10.YmtPaneComponent, selector: "ymt-pane", inputs: ["topBarActions", "busy", "noAnimation", "plain"] }, { kind: "component", type: i10.YmtPaneBodyComponent, selector: "ymt-pane-body" }] });
1774
1974
  }
1775
1975
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: PaneGutterComponent, decorators: [{
1776
1976
  type: Component,
@@ -1786,7 +1986,7 @@ class PaneToggleButtonComponent {
1786
1986
  tooltip = input.required(...(ngDevMode ? [{ debugName: "tooltip" }] : /* istanbul ignore next */ []));
1787
1987
  toggled = output();
1788
1988
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: PaneToggleButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1789
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.25", type: PaneToggleButtonComponent, isStandalone: true, selector: "ymbpm-pane-toggle-button", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { toggled: "toggled" }, ngImport: i0, template: "<button\n ymtIconButton\n icon-button-size=\"small\"\n [matTooltip]=\"tooltip()\"\n [attr.aria-label]=\"tooltip()\"\n (click)=\"toggled.emit()\"\n>\n <mat-icon>{{ icon() }}</mat-icon>\n</button>\n", styles: ["button{opacity:calc(1 - var(--ymt-disabled-opacity))}button:focus,button:hover{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }] });
1989
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.25", type: PaneToggleButtonComponent, isStandalone: true, selector: "ymbpm-pane-toggle-button", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { toggled: "toggled" }, ngImport: i0, template: "<button\n ymtIconButton\n icon-button-size=\"small\"\n [matTooltip]=\"tooltip()\"\n [attr.aria-label]=\"tooltip()\"\n (click)=\"toggled.emit()\"\n>\n <mat-icon>{{ icon() }}</mat-icon>\n</button>\n", styles: ["button{opacity:calc(1 - var(--ymt-disabled-opacity))}button:focus,button:hover{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }] });
1790
1990
  }
1791
1991
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: PaneToggleButtonComponent, decorators: [{
1792
1992
  type: Component,
@@ -1820,11 +2020,11 @@ class DeploymentDetailsComponent {
1820
2020
  definitionSeverity = definitionSeverity;
1821
2021
  definitionStatusLabel = definitionStatusLabel;
1822
2022
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: DeploymentDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1823
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: DeploymentDetailsComponent, isStandalone: true, selector: "ymbpm-deployment-details", inputs: { deployment: { classPropertyName: "deployment", publicName: "deployment", isSignal: true, isRequired: true, transformFunction: null }, canOpenDefinition: { classPropertyName: "canOpenDefinition", publicName: "canOpenDefinition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openDefinition: "openDefinition" }, ngImport: i0, template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.deploymentTime' | translate }}</span>\n <span>{{ (deployment().deploymentTime | formatDateTime) || '-' }}</span>\n </div>\n @if (deployment().category; as category) {\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.category' | translate }}</span>\n <ymt-badge class=\"category\" [outline]=\"true\">{{ category }}</ymt-badge>\n </div>\n }\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.entity.definitions' | translate }}\n <ymt-badge class=\"count\">{{ deployment().definitions?.length ?? 0 }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!deployment().definitions?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <table class=\"table\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.column.name' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.key' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.version' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.status' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (definition of deployment().definitions; track definition.id) {\n <tr>\n <td>\n @if (canOpenDefinition()) {\n <a class=\"link\" tabindex=\"0\" role=\"link\" (click)=\"openDefinition.emit(definition.id)\" (keydown.enter)=\"openDefinition.emit(definition.id)\">\n {{ definition.name || definition.id }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n {{ definition.name || definition.id }}\n }\n </td>\n <td class=\"mono\">{{ definition.key }}</td>\n <td>{{ definition.version }}</td>\n <td>\n <ymt-badge [severity]=\"definitionSeverity(definition)\">\n {{ definitionStatusLabel(definition) | translate }}\n </ymt-badge>\n </td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.deployment.details.resources' | translate }}\n <ymt-badge class=\"count\">{{ deployment().resources?.length ?? 0 }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!deployment().resources?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <table class=\"table\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.column.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=\"mono\">{{ resource.id }}</td>\n <td>{{ resource.mediaType }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.category{align-self:flex-start}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i2$2.MatTabContent, selector: "[matTabContent]" }, { kind: "directive", type: i2$2.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.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: YmtBadge, selector: "ymt-badge", inputs: ["severity", "outline", "aura"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2023
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: DeploymentDetailsComponent, isStandalone: true, selector: "ymbpm-deployment-details", inputs: { deployment: { classPropertyName: "deployment", publicName: "deployment", isSignal: true, isRequired: true, transformFunction: null }, canOpenDefinition: { classPropertyName: "canOpenDefinition", publicName: "canOpenDefinition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openDefinition: "openDefinition" }, ngImport: i0, template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.deploymentTime' | translate }}</span>\n <span>{{ (deployment().deploymentTime | formatDateTime) || '-' }}</span>\n </div>\n @if (deployment().category; as category) {\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.category' | translate }}</span>\n <ymt-badge class=\"category\" [outline]=\"true\">{{ category }}</ymt-badge>\n </div>\n }\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.entity.definitions' | translate }}\n <ymt-badge class=\"count\">{{ deployment().definitions?.length ?? 0 }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!deployment().definitions?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <table class=\"table\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.column.name' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.key' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.version' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.status' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (definition of deployment().definitions; track definition.id) {\n <tr>\n <td>\n @if (canOpenDefinition()) {\n <a class=\"link\" tabindex=\"0\" role=\"link\" (click)=\"openDefinition.emit(definition.id)\" (keydown.enter)=\"openDefinition.emit(definition.id)\">\n {{ definition.name || definition.id }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n {{ definition.name || definition.id }}\n }\n </td>\n <td class=\"mono\">{{ definition.key }}</td>\n <td>{{ definition.version }}</td>\n <td>\n <ymt-badge [aura]=\"true\" [severity]=\"definitionSeverity(definition)\">\n {{ definitionStatusLabel(definition) | translate }}\n </ymt-badge>\n </td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.deployment.details.resources' | translate }}\n <ymt-badge class=\"count\">{{ deployment().resources?.length ?? 0 }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!deployment().resources?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <table class=\"table\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.column.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=\"mono\">{{ resource.id }}</td>\n <td>{{ resource.mediaType }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.category{align-self:flex-start}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i2$2.MatTabContent, selector: "[matTabContent]" }, { kind: "directive", type: i2$2.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.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: YmtBadge, selector: "ymt-badge", inputs: ["severity", "outline", "aura"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1824
2024
  }
1825
2025
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: DeploymentDetailsComponent, decorators: [{
1826
2026
  type: Component,
1827
- args: [{ selector: 'ymbpm-deployment-details', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatTabsModule, TranslatePipe, YmtBadge, FormatDateTimePipe], template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.deploymentTime' | translate }}</span>\n <span>{{ (deployment().deploymentTime | formatDateTime) || '-' }}</span>\n </div>\n @if (deployment().category; as category) {\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.category' | translate }}</span>\n <ymt-badge class=\"category\" [outline]=\"true\">{{ category }}</ymt-badge>\n </div>\n }\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.entity.definitions' | translate }}\n <ymt-badge class=\"count\">{{ deployment().definitions?.length ?? 0 }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!deployment().definitions?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <table class=\"table\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.column.name' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.key' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.version' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.status' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (definition of deployment().definitions; track definition.id) {\n <tr>\n <td>\n @if (canOpenDefinition()) {\n <a class=\"link\" tabindex=\"0\" role=\"link\" (click)=\"openDefinition.emit(definition.id)\" (keydown.enter)=\"openDefinition.emit(definition.id)\">\n {{ definition.name || definition.id }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n {{ definition.name || definition.id }}\n }\n </td>\n <td class=\"mono\">{{ definition.key }}</td>\n <td>{{ definition.version }}</td>\n <td>\n <ymt-badge [severity]=\"definitionSeverity(definition)\">\n {{ definitionStatusLabel(definition) | translate }}\n </ymt-badge>\n </td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.deployment.details.resources' | translate }}\n <ymt-badge class=\"count\">{{ deployment().resources?.length ?? 0 }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!deployment().resources?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <table class=\"table\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.column.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=\"mono\">{{ resource.id }}</td>\n <td>{{ resource.mediaType }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.category{align-self:flex-start}\n"] }]
2027
+ args: [{ selector: 'ymbpm-deployment-details', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatTabsModule, TranslatePipe, YmtBadge, FormatDateTimePipe], template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.deploymentTime' | translate }}</span>\n <span>{{ (deployment().deploymentTime | formatDateTime) || '-' }}</span>\n </div>\n @if (deployment().category; as category) {\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.category' | translate }}</span>\n <ymt-badge class=\"category\" [outline]=\"true\">{{ category }}</ymt-badge>\n </div>\n }\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.entity.definitions' | translate }}\n <ymt-badge class=\"count\">{{ deployment().definitions?.length ?? 0 }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!deployment().definitions?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <table class=\"table\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.column.name' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.key' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.version' | translate }}</th>\n <th>{{ 'yuv.app.bpm-management.column.status' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (definition of deployment().definitions; track definition.id) {\n <tr>\n <td>\n @if (canOpenDefinition()) {\n <a class=\"link\" tabindex=\"0\" role=\"link\" (click)=\"openDefinition.emit(definition.id)\" (keydown.enter)=\"openDefinition.emit(definition.id)\">\n {{ definition.name || definition.id }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n {{ definition.name || definition.id }}\n }\n </td>\n <td class=\"mono\">{{ definition.key }}</td>\n <td>{{ definition.version }}</td>\n <td>\n <ymt-badge [aura]=\"true\" [severity]=\"definitionSeverity(definition)\">\n {{ definitionStatusLabel(definition) | translate }}\n </ymt-badge>\n </td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.deployment.details.resources' | translate }}\n <ymt-badge class=\"count\">{{ deployment().resources?.length ?? 0 }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!deployment().resources?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <table class=\"table\">\n <thead>\n <tr>\n <th>{{ 'yuv.app.bpm-management.column.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=\"mono\">{{ resource.id }}</td>\n <td>{{ resource.mediaType }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.category{align-self:flex-start}\n"] }]
1828
2028
  }], propDecorators: { deployment: [{ type: i0.Input, args: [{ isSignal: true, alias: "deployment", required: true }] }], canOpenDefinition: [{ type: i0.Input, args: [{ isSignal: true, alias: "canOpenDefinition", required: false }] }], openDefinition: [{ type: i0.Output, args: ["openDefinition"] }] } });
1829
2029
 
1830
2030
  /** Process definition details: facts on top, then a tab with the process statistics. */
@@ -1865,11 +2065,11 @@ class ProcessDefinitionDetailsComponent {
1865
2065
  this.showProcesses.emit({ definitionId: this.definition().id, quick });
1866
2066
  }
1867
2067
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: ProcessDefinitionDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1868
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: ProcessDefinitionDetailsComponent, isStandalone: true, selector: "ymbpm-process-definition-details", inputs: { definition: { classPropertyName: "definition", publicName: "definition", isSignal: true, isRequired: true, transformFunction: null }, canOpenDeployment: { classPropertyName: "canOpenDeployment", publicName: "canOpenDeployment", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openDeployment: "openDeployment", showProcesses: "showProcesses" }, ngImport: i0, template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.deploymentId' | translate }}</span>\n @if (canOpenDeployment() && !definition().global && definition().deploymentId; as deploymentId) {\n <a class=\"link mono\" tabindex=\"0\" role=\"link\" (click)=\"openDeployment.emit(deploymentId)\" (keydown.enter)=\"openDeployment.emit(deploymentId)\">\n {{ deploymentId }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n <span class=\"mono\">{{ definition().deploymentId || '-' }}</span>\n }\n </div>\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.key' | translate }}</span>\n <span class=\"mono\">{{ definition().key || '-' }}</span>\n </div>\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.version' | translate }}</span>\n <span>{{ definition().version || '-' }}</span>\n </div>\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.category' | translate }}</span>\n <span>{{ definition().category || '-' }}</span>\n </div>\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.description' | translate }}</span>\n <span>{{ definition().description || '-' }}</span>\n </div>\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.entity.processes' | translate }}\n <ymt-badge class=\"count\">{{ total() }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n <div class=\"cards\">\n @for (card of cards(); track card.quick) {\n <button type=\"button\" class=\"card\" (click)=\"show(card.quick)\">\n <span class=\"card__status\"><mat-icon aria-hidden=\"true\">{{ card.icon }}</mat-icon>{{ card.label | translate }}</span>\n <span class=\"card__count\">{{ card.count }}</span>\n <span class=\"card__hint\">{{ card.hint | translate: card.hintParams }}</span>\n <span class=\"card__link\">{{ 'yuv.app.bpm-management.definitions.showProcesses' | translate }}<mat-icon aria-hidden=\"true\">arrow_forward</mat-icon></span>\n </button>\n }\n </div>\n <button type=\"button\" ymtButton=\"secondary\" class=\"all-link\" (click)=\"show('all')\">\n {{ 'yuv.app.bpm-management.definitions.details.showAll' | translate }}<mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </button>\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.fact--column{flex:1 1 12rem;overflow-wrap:anywhere}.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));gap:var(--ymt-spacing-m)}.card{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ymt-spacing-2xs);padding:var(--ymt-spacing-l);border:var(--ymt-outline-width) solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-xs);background:var(--ymt-surface);color:var(--ymt-text-color);font:inherit;text-align:start;cursor:pointer}.card:hover{border-color:var(--ymt-primary)}.card:focus-visible{outline:var(--ymt-focus-indicator-size) solid var(--ymt-primary);outline-offset:calc(-1 * var(--ymt-focus-indicator-size))}.card__status{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs);font:var(--ymt-font-title-small)}.card__count{font:var(--ymt-font-headline-large);font-variant-numeric:tabular-nums}.card__hint{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.card__link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);margin-top:var(--ymt-spacing-2xs);color:var(--ymt-text-color-primary)}.all-link{width:100%;margin-top:var(--ymt-spacing-m)}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i2$2.MatTabContent, selector: "[matTabContent]" }, { kind: "directive", type: i2$2.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.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: YmtBadge, selector: "ymt-badge", inputs: ["severity", "outline", "aura"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2068
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: ProcessDefinitionDetailsComponent, isStandalone: true, selector: "ymbpm-process-definition-details", inputs: { definition: { classPropertyName: "definition", publicName: "definition", isSignal: true, isRequired: true, transformFunction: null }, canOpenDeployment: { classPropertyName: "canOpenDeployment", publicName: "canOpenDeployment", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openDeployment: "openDeployment", showProcesses: "showProcesses" }, ngImport: i0, template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.deploymentId' | translate }}</span>\n @if (canOpenDeployment() && !definition().global && definition().deploymentId; as deploymentId) {\n <a class=\"link mono\" tabindex=\"0\" role=\"link\" (click)=\"openDeployment.emit(deploymentId)\" (keydown.enter)=\"openDeployment.emit(deploymentId)\">\n {{ deploymentId }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n <span class=\"mono\">{{ definition().deploymentId || '-' }}</span>\n }\n </div>\n <!-- the order of the list row: category, then version and key -->\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.category' | translate }}</span>\n <span>{{ definition().category || '-' }}</span>\n </div>\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.version' | translate }}</span>\n <span>{{ definition().version || '-' }}</span>\n </div>\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.key' | translate }}</span>\n <span class=\"mono\">{{ definition().key || '-' }}</span>\n </div>\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.description' | translate }}</span>\n <span>{{ definition().description || '-' }}</span>\n </div>\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.entity.processes' | translate }}\n <ymt-badge class=\"count\">{{ total() }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n <div class=\"cards\">\n @for (card of cards(); track card.quick) {\n <button type=\"button\" class=\"card\" (click)=\"show(card.quick)\">\n <span class=\"card__status\"><mat-icon aria-hidden=\"true\">{{ card.icon }}</mat-icon>{{ card.label | translate }}</span>\n <span class=\"card__count\">{{ card.count }}</span>\n <span class=\"card__hint\">{{ card.hint | translate: card.hintParams }}</span>\n <span class=\"card__link\">{{ 'yuv.app.bpm-management.definitions.showProcesses' | translate }}<mat-icon aria-hidden=\"true\">arrow_forward</mat-icon></span>\n </button>\n }\n </div>\n <button type=\"button\" ymtButton=\"secondary\" class=\"all-link\" (click)=\"show('all')\">\n {{ 'yuv.app.bpm-management.definitions.details.showAll' | translate }}<mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </button>\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.fact--column{flex:1 1 12rem;overflow-wrap:anywhere}.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));gap:var(--ymt-spacing-m)}.card{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ymt-spacing-2xs);padding:var(--ymt-spacing-l);border:var(--ymt-outline-width) solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-xs);background:var(--ymt-surface);color:var(--ymt-text-color);font:inherit;text-align:start;cursor:pointer}.card:hover{border-color:var(--ymt-primary)}.card:focus-visible{outline:var(--ymt-focus-indicator-size) solid var(--ymt-primary);outline-offset:calc(-1 * var(--ymt-focus-indicator-size))}.card__status{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs);font:var(--ymt-font-title-small)}.card__count{font:var(--ymt-font-headline-large);font-variant-numeric:tabular-nums}.card__hint{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.card__link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);margin-top:var(--ymt-spacing-2xs);color:var(--ymt-text-color-primary)}.all-link{width:100%;margin-top:var(--ymt-spacing-m)}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i2$2.MatTabContent, selector: "[matTabContent]" }, { kind: "directive", type: i2$2.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.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: YmtBadge, selector: "ymt-badge", inputs: ["severity", "outline", "aura"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1869
2069
  }
1870
2070
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: ProcessDefinitionDetailsComponent, decorators: [{
1871
2071
  type: Component,
1872
- args: [{ selector: 'ymbpm-process-definition-details', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatTabsModule, TranslatePipe, YmtBadge, YmtButtonDirective], template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.deploymentId' | translate }}</span>\n @if (canOpenDeployment() && !definition().global && definition().deploymentId; as deploymentId) {\n <a class=\"link mono\" tabindex=\"0\" role=\"link\" (click)=\"openDeployment.emit(deploymentId)\" (keydown.enter)=\"openDeployment.emit(deploymentId)\">\n {{ deploymentId }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n <span class=\"mono\">{{ definition().deploymentId || '-' }}</span>\n }\n </div>\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.key' | translate }}</span>\n <span class=\"mono\">{{ definition().key || '-' }}</span>\n </div>\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.version' | translate }}</span>\n <span>{{ definition().version || '-' }}</span>\n </div>\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.category' | translate }}</span>\n <span>{{ definition().category || '-' }}</span>\n </div>\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.description' | translate }}</span>\n <span>{{ definition().description || '-' }}</span>\n </div>\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.entity.processes' | translate }}\n <ymt-badge class=\"count\">{{ total() }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n <div class=\"cards\">\n @for (card of cards(); track card.quick) {\n <button type=\"button\" class=\"card\" (click)=\"show(card.quick)\">\n <span class=\"card__status\"><mat-icon aria-hidden=\"true\">{{ card.icon }}</mat-icon>{{ card.label | translate }}</span>\n <span class=\"card__count\">{{ card.count }}</span>\n <span class=\"card__hint\">{{ card.hint | translate: card.hintParams }}</span>\n <span class=\"card__link\">{{ 'yuv.app.bpm-management.definitions.showProcesses' | translate }}<mat-icon aria-hidden=\"true\">arrow_forward</mat-icon></span>\n </button>\n }\n </div>\n <button type=\"button\" ymtButton=\"secondary\" class=\"all-link\" (click)=\"show('all')\">\n {{ 'yuv.app.bpm-management.definitions.details.showAll' | translate }}<mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </button>\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.fact--column{flex:1 1 12rem;overflow-wrap:anywhere}.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));gap:var(--ymt-spacing-m)}.card{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ymt-spacing-2xs);padding:var(--ymt-spacing-l);border:var(--ymt-outline-width) solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-xs);background:var(--ymt-surface);color:var(--ymt-text-color);font:inherit;text-align:start;cursor:pointer}.card:hover{border-color:var(--ymt-primary)}.card:focus-visible{outline:var(--ymt-focus-indicator-size) solid var(--ymt-primary);outline-offset:calc(-1 * var(--ymt-focus-indicator-size))}.card__status{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs);font:var(--ymt-font-title-small)}.card__count{font:var(--ymt-font-headline-large);font-variant-numeric:tabular-nums}.card__hint{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.card__link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);margin-top:var(--ymt-spacing-2xs);color:var(--ymt-text-color-primary)}.all-link{width:100%;margin-top:var(--ymt-spacing-m)}\n"] }]
2072
+ args: [{ selector: 'ymbpm-process-definition-details', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatTabsModule, TranslatePipe, YmtBadge, YmtButtonDirective], template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.deploymentId' | translate }}</span>\n @if (canOpenDeployment() && !definition().global && definition().deploymentId; as deploymentId) {\n <a class=\"link mono\" tabindex=\"0\" role=\"link\" (click)=\"openDeployment.emit(deploymentId)\" (keydown.enter)=\"openDeployment.emit(deploymentId)\">\n {{ deploymentId }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n <span class=\"mono\">{{ definition().deploymentId || '-' }}</span>\n }\n </div>\n <!-- the order of the list row: category, then version and key -->\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.category' | translate }}</span>\n <span>{{ definition().category || '-' }}</span>\n </div>\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.version' | translate }}</span>\n <span>{{ definition().version || '-' }}</span>\n </div>\n <div class=\"fact fact--column\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.key' | translate }}</span>\n <span class=\"mono\">{{ definition().key || '-' }}</span>\n </div>\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.description' | translate }}</span>\n <span>{{ definition().description || '-' }}</span>\n </div>\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab>\n <ng-template mat-tab-label>\n {{ 'yuv.app.bpm-management.entity.processes' | translate }}\n <ymt-badge class=\"count\">{{ total() }}</ymt-badge>\n </ng-template>\n <ng-template matTabContent>\n <div class=\"tab-content\">\n <div class=\"cards\">\n @for (card of cards(); track card.quick) {\n <button type=\"button\" class=\"card\" (click)=\"show(card.quick)\">\n <span class=\"card__status\"><mat-icon aria-hidden=\"true\">{{ card.icon }}</mat-icon>{{ card.label | translate }}</span>\n <span class=\"card__count\">{{ card.count }}</span>\n <span class=\"card__hint\">{{ card.hint | translate: card.hintParams }}</span>\n <span class=\"card__link\">{{ 'yuv.app.bpm-management.definitions.showProcesses' | translate }}<mat-icon aria-hidden=\"true\">arrow_forward</mat-icon></span>\n </button>\n }\n </div>\n <button type=\"button\" ymtButton=\"secondary\" class=\"all-link\" (click)=\"show('all')\">\n {{ 'yuv.app.bpm-management.definitions.details.showAll' | translate }}<mat-icon aria-hidden=\"true\">arrow_forward</mat-icon>\n </button>\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.fact--column{flex:1 1 12rem;overflow-wrap:anywhere}.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));gap:var(--ymt-spacing-m)}.card{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ymt-spacing-2xs);padding:var(--ymt-spacing-l);border:var(--ymt-outline-width) solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-xs);background:var(--ymt-surface);color:var(--ymt-text-color);font:inherit;text-align:start;cursor:pointer}.card:hover{border-color:var(--ymt-primary)}.card:focus-visible{outline:var(--ymt-focus-indicator-size) solid var(--ymt-primary);outline-offset:calc(-1 * var(--ymt-focus-indicator-size))}.card__status{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs);font:var(--ymt-font-title-small)}.card__count{font:var(--ymt-font-headline-large);font-variant-numeric:tabular-nums}.card__hint{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.card__link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);margin-top:var(--ymt-spacing-2xs);color:var(--ymt-text-color-primary)}.all-link{width:100%;margin-top:var(--ymt-spacing-m)}\n"] }]
1873
2073
  }], propDecorators: { definition: [{ type: i0.Input, args: [{ isSignal: true, alias: "definition", required: true }] }], canOpenDeployment: [{ type: i0.Input, args: [{ isSignal: true, alias: "canOpenDeployment", required: false }] }], openDeployment: [{ type: i0.Output, args: ["openDeployment"] }], showProcesses: [{ type: i0.Output, args: ["showProcesses"] }] } });
1874
2074
 
1875
2075
  /**
@@ -1877,6 +2077,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
1877
2077
  */
1878
2078
  class ProcessDetailsComponent {
1879
2079
  #translate = inject(TranslateService);
2080
+ processStatusIcon = processStatusIcon;
1880
2081
  taskSeverity = taskSeverity;
1881
2082
  taskStatusLabel = taskStatusLabel;
1882
2083
  process = input.required(...(ngDevMode ? [{ debugName: "process" }] : /* istanbul ignore next */ []));
@@ -1912,11 +2113,11 @@ class ProcessDetailsComponent {
1912
2113
  .join(' ');
1913
2114
  }
1914
2115
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: ProcessDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1915
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: ProcessDetailsComponent, isStandalone: true, selector: "ymbpm-process-details", inputs: { process: { classPropertyName: "process", publicName: "process", isSignal: true, isRequired: true, transformFunction: null }, tasks: { classPropertyName: "tasks", publicName: "tasks", isSignal: true, isRequired: false, transformFunction: null }, canOpenDefinition: { classPropertyName: "canOpenDefinition", publicName: "canOpenDefinition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openTask: "openTask", openDefinition: "openDefinition" }, ngImport: i0, template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.processDefinitionId' | translate }}</span>\n @if (canOpenDefinition()) {\n <a class=\"link mono\" tabindex=\"0\" role=\"link\" [matTooltip]=\"process().processDefinitionName || ''\" (click)=\"openDefinition.emit(process().processDefinitionId)\" (keydown.enter)=\"openDefinition.emit(process().processDefinitionId)\">\n {{ process().processDefinitionId }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n <span class=\"mono\" [matTooltip]=\"process().processDefinitionName || ''\">{{ process().processDefinitionId }}</span>\n }\n </div>\n @if (process().processDefinitionDescription) {\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.process.details.processDefinitionDescription' | translate }}</span>\n <span>{{ process().processDefinitionDescription }}</span>\n </div>\n }\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.businessKey' | translate }}</span>\n <span>{{ process().businessKey || '-' }}</span>\n </div>\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab [label]=\"'yuv.app.bpm-management.process.details.history' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content timeline-tab\">\n <ol class=\"timeline\">\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ process().startTime | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--start\"><mat-icon aria-hidden=\"true\">play_arrow</mat-icon></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\"><strong>{{ 'yuv.app.bpm-management.process.details.started' | translate }}</strong></div>\n <div class=\"timeline__people\">\n <yuv-organization-renderer propertyName=\"user\" [value]=\"process().startUserId ?? null\"></yuv-organization-renderer>\n </div>\n </div>\n </li>\n @for (task of shownTasks(); track task.id) {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ (task.endTime ?? task.createTime) | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot\" [class.timeline__dot--done]=\"task.endTime\" [class.timeline__dot--suspended]=\"!task.endTime && task.suspended\">\n @if (task.endTime) {\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n } @else if (task.suspended) {\n <mat-icon aria-hidden=\"true\">pause</mat-icon>\n }\n </span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <a class=\"link timeline__task\" tabindex=\"0\" role=\"link\"\n [attr.aria-label]=\"('yuv.app.bpm-management.task.open' | translate) + ': ' + (task.name || '')\"\n (click)=\"openTask.emit(task.id)\" (keydown.enter)=\"openTask.emit(task.id)\">\n <strong>{{ task.name || '&lt;unnamed&gt;' }}</strong>\n </a>\n <ymt-badge class=\"timeline__state\" [severity]=\"taskSeverity(task)\">\n {{ taskStatusLabel(task) | translate }}\n </ymt-badge>\n </div>\n @if (task.description) {\n <p class=\"timeline__description\">{{ task.description }}</p>\n }\n @if (task.claimTime || task.dueDate) {\n <dl class=\"timeline__life\">\n @if (task.claimTime) {\n <div>\n <dt>{{ 'yuv.app.bpm-management.task.details.claimTime' | translate }}</dt>\n <dd>{{ task.claimTime | formatDateTime }}</dd>\n </div>\n }\n @if (task.dueDate) {\n <div>\n <dt>{{ 'yuv.app.bpm-management.task.details.dueDate' | translate }}</dt>\n <dd>{{ task.dueDate | formatDateTime }}</dd>\n </div>\n }\n </dl>\n }\n @if (task.assignee || task.owner) {\n <div class=\"timeline__people\">\n @if (task.assignee) {\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task.assignee ?? null\"></yuv-organization-renderer>\n }\n @if (task.owner) {\n <span class=\"timeline__label\">{{ 'yuv.app.bpm-management.task.details.owner' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task.owner ?? null\"></yuv-organization-renderer>\n }\n </div>\n }\n <!-- a suspended task has no meaningful running time: the suspension is not part of the data -->\n @if (task.endTime || !task.suspended) {\n <div class=\"timeline__foot\">\n {{ (task.endTime ? 'yuv.app.bpm-management.process.details.took' : 'yuv.app.bpm-management.process.details.openFor') | translate: { duration: duration(task.createTime, task.endTime) } }}\n </div>\n }\n </div>\n </li>\n }\n @if (process().endTime) {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ process().endTime | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot\" [class.timeline__dot--done]=\"!process().deleteReason\" [class.timeline__dot--canceled]=\"process().deleteReason\">\n <mat-icon aria-hidden=\"true\">{{ process().deleteReason ? 'close' : 'check' }}</mat-icon>\n </span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ (process().deleteReason ? 'yuv.app.bpm-management.process.details.canceled' : 'yuv.app.bpm-management.process.details.completed') | translate }}</strong>\n </div>\n @if (process().deleteReason) {\n <p class=\"timeline__description\">{{ process().deleteReason }}</p>\n }\n <div class=\"timeline__foot\">{{ 'yuv.app.bpm-management.process.details.took' | translate: { duration: duration(process().startTime, process().endTime) } }}</div>\n </div>\n </li>\n } @else {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\"></div>\n @if (process().suspended) {\n <!-- the time of the suspension is not part of the data, so no running time is shown -->\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--suspended\"><mat-icon aria-hidden=\"true\">pause</mat-icon></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ 'yuv.app.bpm-management.status.suspended' | translate }}</strong>\n </div>\n </div>\n } @else {\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--now\"></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ 'yuv.app.bpm-management.process.details.running' | translate }}</strong>\n <ymt-badge severity=\"primary\">{{ duration(process().startTime) }}</ymt-badge>\n </div>\n </div>\n }\n </li>\n }\n </ol>\n </div>\n </ng-template>\n </mat-tab>\n <mat-tab [label]=\"'yuv.app.bpm-management.details.variables' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!process().variables?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <input class=\"variables__filter\" type=\"search\"\n [attr.aria-label]=\"'yuv.app.bpm-management.details.variableFilter' | translate\"\n [placeholder]=\"'yuv.app.bpm-management.details.variableFilter' | translate\"\n (input)=\"variableFilter.set($any($event.target).value)\">\n <table class=\"table\">\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 variables(); track variable.name) {\n <tr>\n <td class=\"mono\">{{ variable.name }}</td>\n <td>{{ variable.type }}</td>\n <td class=\"mono\">{{ variable.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.timeline{--timeline-dot-size: var(--ymt-sizing-m);--timeline-dot-top: var(--ymt-spacing-s);--timeline-dot-center: calc(var(--timeline-dot-top) + var(--timeline-dot-size) / 2);list-style:none;margin:0;padding:0}.timeline__item{display:grid;grid-template-columns:var(--ymt-sizing-7xl) var(--timeline-dot-size) minmax(0,1fr);grid-template-areas:\"when rail card\";gap:var(--ymt-spacing-xs)}.timeline__when{grid-area:when;text-align:right;padding-top:var(--ymt-spacing-s);font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__rail{grid-area:rail;position:relative}.timeline__rail:before{content:\"\";position:absolute;left:calc(50% - var(--ymt-spacing-3xs) / 2);top:0;bottom:0;width:var(--ymt-spacing-3xs);background-color:var(--ymt-outline-variant)}.timeline__item:first-child .timeline__rail:before{top:var(--timeline-dot-center)}.timeline__item:last-child .timeline__rail:before{bottom:calc(100% - var(--timeline-dot-center))}.timeline__item:only-child .timeline__rail:before{display:none}.timeline__dot{position:absolute;inset-block-start:var(--timeline-dot-top);inset-inline:0;height:var(--timeline-dot-size);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary);border:var(--ymt-spacing-3xs) solid var(--ymt-surface);display:flex;align-items:center;justify-content:center;color:var(--ymt-surface)}.timeline__dot mat-icon{width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs);font-size:var(--ymt-sizing-xs)}.timeline__dot.timeline__dot--done{background-color:var(--ymt-success);color:var(--ymt-on-success)}.timeline__dot.timeline__dot--canceled{background-color:var(--ymt-warning);color:var(--ymt-on-warning)}.timeline__dot.timeline__dot--start,.timeline__dot.timeline__dot--suspended{background-color:var(--ymt-text-color-subtle)}.timeline__dot.timeline__dot--now{background-color:var(--ymt-surface);border-color:var(--ymt-primary)}.timeline__card{grid-area:card;display:flex;flex-direction:column;gap:var(--ymt-spacing-xs);min-width:0;margin:var(--ymt-spacing-2xs) 0 var(--ymt-spacing-s);padding:var(--ymt-spacing-s);border:var(--ymt-outline-width) solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-xs);background:var(--ymt-surface)}.timeline__head{display:flex;align-items:center;gap:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);flex-wrap:wrap}.timeline__head strong{font:var(--ymt-font-title-smallest)}.timeline__task{text-decoration:underline}.timeline__state{margin-inline-start:auto}.timeline__description{margin:0;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__life{display:grid;grid-template-columns:repeat(auto-fit,minmax(7.5rem,1fr));gap:var(--ymt-spacing-2xs) var(--ymt-spacing-m);margin:0;padding-block:var(--ymt-spacing-xs);border-block:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.timeline__life dt{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__life dd{margin:0;font-variant-numeric:tabular-nums}.timeline__people{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ymt-spacing-2xs) var(--ymt-spacing-xs)}.timeline__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__label:not(:first-child){margin-inline-start:var(--ymt-spacing-xs)}.timeline__foot{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline-tab{container-type:inline-size}@container (max-width: 26rem){.timeline__item{grid-template-columns:var(--timeline-dot-size) minmax(0,1fr);grid-template-areas:\"rail when\" \"rail card\"}.timeline__when{text-align:left;padding-top:var(--ymt-spacing-xs)}.timeline{--timeline-dot-top: var(--ymt-spacing-xs)}}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i2$2.MatTabContent, selector: "[matTabContent]" }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.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: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: YmtBadge, selector: "ymt-badge", inputs: ["severity", "outline", "aura"] }, { kind: "component", type: OrganizationRendererComponent, selector: "yuv-organization-renderer" }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2116
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: ProcessDetailsComponent, isStandalone: true, selector: "ymbpm-process-details", inputs: { process: { classPropertyName: "process", publicName: "process", isSignal: true, isRequired: true, transformFunction: null }, tasks: { classPropertyName: "tasks", publicName: "tasks", isSignal: true, isRequired: false, transformFunction: null }, canOpenDefinition: { classPropertyName: "canOpenDefinition", publicName: "canOpenDefinition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openTask: "openTask", openDefinition: "openDefinition" }, ngImport: i0, template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.processDefinitionId' | translate }}</span>\n @if (canOpenDefinition()) {\n <a class=\"link mono\" tabindex=\"0\" role=\"link\" [matTooltip]=\"process().processDefinitionName || ''\" (click)=\"openDefinition.emit(process().processDefinitionId)\" (keydown.enter)=\"openDefinition.emit(process().processDefinitionId)\">\n {{ process().processDefinitionId }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n <span class=\"mono\" [matTooltip]=\"process().processDefinitionName || ''\">{{ process().processDefinitionId }}</span>\n }\n </div>\n @if (process().processDefinitionDescription) {\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.process.details.processDefinitionDescription' | translate }}</span>\n <span>{{ process().processDefinitionDescription }}</span>\n </div>\n }\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.businessKey' | translate }}</span>\n <span>{{ process().businessKey || '-' }}</span>\n </div>\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab [label]=\"'yuv.app.bpm-management.process.details.history' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content timeline-tab\">\n <ol class=\"timeline\">\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ process().startTime | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--start\"><mat-icon aria-hidden=\"true\">play_arrow</mat-icon></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\"><strong>{{ 'yuv.app.bpm-management.process.details.started' | translate }}</strong></div>\n <div class=\"timeline__people\">\n <yuv-organization-renderer propertyName=\"user\" [value]=\"process().startUserId ?? null\"></yuv-organization-renderer>\n </div>\n </div>\n </li>\n @for (task of shownTasks(); track task.id) {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ (task.endTime ?? task.createTime) | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot\" [class.timeline__dot--done]=\"task.endTime\" [class.timeline__dot--suspended]=\"!task.endTime && task.suspended\">\n @if (task.endTime) {\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n } @else if (task.suspended) {\n <mat-icon aria-hidden=\"true\">pause</mat-icon>\n }\n </span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <a class=\"link timeline__task\" tabindex=\"0\" role=\"link\"\n [attr.aria-label]=\"('yuv.app.bpm-management.task.open' | translate) + ': ' + (task.name || '')\"\n (click)=\"openTask.emit(task.id)\" (keydown.enter)=\"openTask.emit(task.id)\">\n <strong>{{ task.name || '&lt;unnamed&gt;' }}</strong>\n </a>\n <ymt-badge class=\"timeline__state\" [aura]=\"true\" [severity]=\"taskSeverity(task)\">\n {{ taskStatusLabel(task) | translate }}\n </ymt-badge>\n </div>\n @if (task.description) {\n <p class=\"timeline__description\">{{ task.description }}</p>\n }\n @if (task.claimTime || task.dueDate) {\n <dl class=\"timeline__life\">\n @if (task.claimTime) {\n <div>\n <dt>{{ 'yuv.app.bpm-management.task.details.claimTime' | translate }}</dt>\n <dd>{{ task.claimTime | formatDateTime }}</dd>\n </div>\n }\n @if (task.dueDate) {\n <div>\n <dt>{{ 'yuv.app.bpm-management.task.details.dueDate' | translate }}</dt>\n <dd>{{ task.dueDate | formatDateTime }}</dd>\n </div>\n }\n </dl>\n }\n @if (task.assignee || task.owner) {\n <div class=\"timeline__people\">\n @if (task.assignee) {\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task.assignee ?? null\"></yuv-organization-renderer>\n }\n @if (task.owner) {\n <span class=\"timeline__label\">{{ 'yuv.app.bpm-management.task.details.owner' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task.owner ?? null\"></yuv-organization-renderer>\n }\n </div>\n }\n <!-- a suspended task has no meaningful running time: the suspension is not part of the data -->\n @if (task.endTime || !task.suspended) {\n <div class=\"timeline__foot\">\n {{ (task.endTime ? 'yuv.app.bpm-management.process.details.took' : 'yuv.app.bpm-management.process.details.openFor') | translate: { duration: duration(task.createTime, task.endTime) } }}\n </div>\n }\n </div>\n </li>\n }\n @if (process().endTime) {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ process().endTime | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot\" [class.timeline__dot--done]=\"!process().deleteReason\" [class.timeline__dot--canceled]=\"process().deleteReason\">\n <mat-icon aria-hidden=\"true\">{{ process().deleteReason ? 'close' : 'check' }}</mat-icon>\n </span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ (process().deleteReason ? 'yuv.app.bpm-management.process.details.canceled' : 'yuv.app.bpm-management.process.details.completed') | translate }}</strong>\n </div>\n @if (process().deleteReason) {\n <p class=\"timeline__description\">{{ process().deleteReason }}</p>\n }\n <div class=\"timeline__foot\">{{ 'yuv.app.bpm-management.process.details.took' | translate: { duration: duration(process().startTime, process().endTime) } }}</div>\n </div>\n </li>\n } @else {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\"></div>\n @if (process().suspended) {\n <!-- the time of the suspension is not part of the data, so no running time is shown -->\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--suspended\"><mat-icon aria-hidden=\"true\">pause</mat-icon></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ 'yuv.app.bpm-management.status.suspended' | translate }}</strong>\n </div>\n </div>\n } @else {\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--now\"><mat-icon aria-hidden=\"true\">{{ processStatusIcon(process()) }}</mat-icon></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ 'yuv.app.bpm-management.process.details.running' | translate }}</strong>\n <ymt-badge severity=\"primary\">{{ duration(process().startTime) }}</ymt-badge>\n </div>\n </div>\n }\n </li>\n }\n </ol>\n </div>\n </ng-template>\n </mat-tab>\n <mat-tab [label]=\"'yuv.app.bpm-management.details.variables' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!process().variables?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <input class=\"variables__filter\" type=\"search\"\n [attr.aria-label]=\"'yuv.app.bpm-management.details.variableFilter' | translate\"\n [placeholder]=\"'yuv.app.bpm-management.details.variableFilter' | translate\"\n (input)=\"variableFilter.set($any($event.target).value)\">\n <table class=\"table\">\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 variables(); track variable.name) {\n <tr>\n <td class=\"mono\">{{ variable.name }}</td>\n <td>{{ variable.type }}</td>\n <td class=\"mono\">{{ variable.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.timeline{--timeline-dot-size: var(--ymt-sizing-m);--timeline-dot-top: var(--ymt-spacing-s);--timeline-dot-center: calc(var(--timeline-dot-top) + var(--timeline-dot-size) / 2);list-style:none;margin:0;padding:0}.timeline__item{display:grid;grid-template-columns:var(--ymt-sizing-7xl) var(--timeline-dot-size) minmax(0,1fr);grid-template-areas:\"when rail card\";gap:var(--ymt-spacing-xs)}.timeline__when{grid-area:when;text-align:right;padding-top:var(--ymt-spacing-s);font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__rail{grid-area:rail;position:relative}.timeline__rail:before{content:\"\";position:absolute;left:calc(50% - var(--ymt-spacing-3xs) / 2);top:0;bottom:0;width:var(--ymt-spacing-3xs);background-color:var(--ymt-outline-variant)}.timeline__item:first-child .timeline__rail:before{top:var(--timeline-dot-center)}.timeline__item:last-child .timeline__rail:before{bottom:calc(100% - var(--timeline-dot-center))}.timeline__item:only-child .timeline__rail:before{display:none}.timeline__dot{position:absolute;inset-block-start:var(--timeline-dot-top);inset-inline:0;height:var(--timeline-dot-size);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary);border:var(--ymt-spacing-3xs) solid var(--ymt-surface);display:flex;align-items:center;justify-content:center;color:var(--ymt-surface)}.timeline__dot mat-icon{width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs);font-size:var(--ymt-sizing-xs)}.timeline__dot.timeline__dot--done{background-color:var(--ymt-success);color:var(--ymt-on-success)}.timeline__dot.timeline__dot--canceled{background-color:var(--ymt-warning);color:var(--ymt-on-warning)}.timeline__dot.timeline__dot--start,.timeline__dot.timeline__dot--suspended{background-color:var(--ymt-text-color-subtle)}.timeline__dot.timeline__dot--now{background-color:var(--ymt-surface);border-color:var(--ymt-primary);color:var(--ymt-primary)}.timeline__card{grid-area:card;display:flex;flex-direction:column;gap:var(--ymt-spacing-xs);min-width:0;margin:var(--ymt-spacing-2xs) 0 var(--ymt-spacing-s);padding:var(--ymt-spacing-s);border:var(--ymt-outline-width) solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-xs);background:var(--ymt-surface)}.timeline__head{display:flex;align-items:center;gap:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);flex-wrap:wrap}.timeline__head strong{font:var(--ymt-font-title-smallest)}.timeline__task{text-decoration:underline}.timeline__state{margin-inline-start:auto}.timeline__description{margin:0;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__life{display:grid;grid-template-columns:repeat(auto-fit,minmax(7.5rem,1fr));gap:var(--ymt-spacing-2xs) var(--ymt-spacing-m);margin:0;padding-block:var(--ymt-spacing-xs);border-block:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.timeline__life dt{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__life dd{margin:0;font-variant-numeric:tabular-nums}.timeline__people{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ymt-spacing-2xs) var(--ymt-spacing-xs)}.timeline__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__label:not(:first-child){margin-inline-start:var(--ymt-spacing-xs)}.timeline__foot{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline-tab{container-type:inline-size}@container (max-width: 26rem){.timeline__item{grid-template-columns:var(--timeline-dot-size) minmax(0,1fr);grid-template-areas:\"rail when\" \"rail card\"}.timeline__when{text-align:left;padding-top:var(--ymt-spacing-xs)}.timeline{--timeline-dot-top: var(--ymt-spacing-xs)}}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i2$2.MatTabContent, selector: "[matTabContent]" }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.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: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: YmtBadge, selector: "ymt-badge", inputs: ["severity", "outline", "aura"] }, { kind: "component", type: OrganizationRendererComponent, selector: "yuv-organization-renderer" }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1916
2117
  }
1917
2118
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: ProcessDetailsComponent, decorators: [{
1918
2119
  type: Component,
1919
- args: [{ selector: 'ymbpm-process-details', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatTabsModule, MatTooltipModule, TranslatePipe, YmtBadge, FormatDateTimePipe, OrganizationRendererComponent], template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.processDefinitionId' | translate }}</span>\n @if (canOpenDefinition()) {\n <a class=\"link mono\" tabindex=\"0\" role=\"link\" [matTooltip]=\"process().processDefinitionName || ''\" (click)=\"openDefinition.emit(process().processDefinitionId)\" (keydown.enter)=\"openDefinition.emit(process().processDefinitionId)\">\n {{ process().processDefinitionId }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n <span class=\"mono\" [matTooltip]=\"process().processDefinitionName || ''\">{{ process().processDefinitionId }}</span>\n }\n </div>\n @if (process().processDefinitionDescription) {\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.process.details.processDefinitionDescription' | translate }}</span>\n <span>{{ process().processDefinitionDescription }}</span>\n </div>\n }\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.businessKey' | translate }}</span>\n <span>{{ process().businessKey || '-' }}</span>\n </div>\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab [label]=\"'yuv.app.bpm-management.process.details.history' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content timeline-tab\">\n <ol class=\"timeline\">\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ process().startTime | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--start\"><mat-icon aria-hidden=\"true\">play_arrow</mat-icon></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\"><strong>{{ 'yuv.app.bpm-management.process.details.started' | translate }}</strong></div>\n <div class=\"timeline__people\">\n <yuv-organization-renderer propertyName=\"user\" [value]=\"process().startUserId ?? null\"></yuv-organization-renderer>\n </div>\n </div>\n </li>\n @for (task of shownTasks(); track task.id) {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ (task.endTime ?? task.createTime) | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot\" [class.timeline__dot--done]=\"task.endTime\" [class.timeline__dot--suspended]=\"!task.endTime && task.suspended\">\n @if (task.endTime) {\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n } @else if (task.suspended) {\n <mat-icon aria-hidden=\"true\">pause</mat-icon>\n }\n </span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <a class=\"link timeline__task\" tabindex=\"0\" role=\"link\"\n [attr.aria-label]=\"('yuv.app.bpm-management.task.open' | translate) + ': ' + (task.name || '')\"\n (click)=\"openTask.emit(task.id)\" (keydown.enter)=\"openTask.emit(task.id)\">\n <strong>{{ task.name || '&lt;unnamed&gt;' }}</strong>\n </a>\n <ymt-badge class=\"timeline__state\" [severity]=\"taskSeverity(task)\">\n {{ taskStatusLabel(task) | translate }}\n </ymt-badge>\n </div>\n @if (task.description) {\n <p class=\"timeline__description\">{{ task.description }}</p>\n }\n @if (task.claimTime || task.dueDate) {\n <dl class=\"timeline__life\">\n @if (task.claimTime) {\n <div>\n <dt>{{ 'yuv.app.bpm-management.task.details.claimTime' | translate }}</dt>\n <dd>{{ task.claimTime | formatDateTime }}</dd>\n </div>\n }\n @if (task.dueDate) {\n <div>\n <dt>{{ 'yuv.app.bpm-management.task.details.dueDate' | translate }}</dt>\n <dd>{{ task.dueDate | formatDateTime }}</dd>\n </div>\n }\n </dl>\n }\n @if (task.assignee || task.owner) {\n <div class=\"timeline__people\">\n @if (task.assignee) {\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task.assignee ?? null\"></yuv-organization-renderer>\n }\n @if (task.owner) {\n <span class=\"timeline__label\">{{ 'yuv.app.bpm-management.task.details.owner' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task.owner ?? null\"></yuv-organization-renderer>\n }\n </div>\n }\n <!-- a suspended task has no meaningful running time: the suspension is not part of the data -->\n @if (task.endTime || !task.suspended) {\n <div class=\"timeline__foot\">\n {{ (task.endTime ? 'yuv.app.bpm-management.process.details.took' : 'yuv.app.bpm-management.process.details.openFor') | translate: { duration: duration(task.createTime, task.endTime) } }}\n </div>\n }\n </div>\n </li>\n }\n @if (process().endTime) {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ process().endTime | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot\" [class.timeline__dot--done]=\"!process().deleteReason\" [class.timeline__dot--canceled]=\"process().deleteReason\">\n <mat-icon aria-hidden=\"true\">{{ process().deleteReason ? 'close' : 'check' }}</mat-icon>\n </span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ (process().deleteReason ? 'yuv.app.bpm-management.process.details.canceled' : 'yuv.app.bpm-management.process.details.completed') | translate }}</strong>\n </div>\n @if (process().deleteReason) {\n <p class=\"timeline__description\">{{ process().deleteReason }}</p>\n }\n <div class=\"timeline__foot\">{{ 'yuv.app.bpm-management.process.details.took' | translate: { duration: duration(process().startTime, process().endTime) } }}</div>\n </div>\n </li>\n } @else {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\"></div>\n @if (process().suspended) {\n <!-- the time of the suspension is not part of the data, so no running time is shown -->\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--suspended\"><mat-icon aria-hidden=\"true\">pause</mat-icon></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ 'yuv.app.bpm-management.status.suspended' | translate }}</strong>\n </div>\n </div>\n } @else {\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--now\"></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ 'yuv.app.bpm-management.process.details.running' | translate }}</strong>\n <ymt-badge severity=\"primary\">{{ duration(process().startTime) }}</ymt-badge>\n </div>\n </div>\n }\n </li>\n }\n </ol>\n </div>\n </ng-template>\n </mat-tab>\n <mat-tab [label]=\"'yuv.app.bpm-management.details.variables' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!process().variables?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <input class=\"variables__filter\" type=\"search\"\n [attr.aria-label]=\"'yuv.app.bpm-management.details.variableFilter' | translate\"\n [placeholder]=\"'yuv.app.bpm-management.details.variableFilter' | translate\"\n (input)=\"variableFilter.set($any($event.target).value)\">\n <table class=\"table\">\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 variables(); track variable.name) {\n <tr>\n <td class=\"mono\">{{ variable.name }}</td>\n <td>{{ variable.type }}</td>\n <td class=\"mono\">{{ variable.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.timeline{--timeline-dot-size: var(--ymt-sizing-m);--timeline-dot-top: var(--ymt-spacing-s);--timeline-dot-center: calc(var(--timeline-dot-top) + var(--timeline-dot-size) / 2);list-style:none;margin:0;padding:0}.timeline__item{display:grid;grid-template-columns:var(--ymt-sizing-7xl) var(--timeline-dot-size) minmax(0,1fr);grid-template-areas:\"when rail card\";gap:var(--ymt-spacing-xs)}.timeline__when{grid-area:when;text-align:right;padding-top:var(--ymt-spacing-s);font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__rail{grid-area:rail;position:relative}.timeline__rail:before{content:\"\";position:absolute;left:calc(50% - var(--ymt-spacing-3xs) / 2);top:0;bottom:0;width:var(--ymt-spacing-3xs);background-color:var(--ymt-outline-variant)}.timeline__item:first-child .timeline__rail:before{top:var(--timeline-dot-center)}.timeline__item:last-child .timeline__rail:before{bottom:calc(100% - var(--timeline-dot-center))}.timeline__item:only-child .timeline__rail:before{display:none}.timeline__dot{position:absolute;inset-block-start:var(--timeline-dot-top);inset-inline:0;height:var(--timeline-dot-size);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary);border:var(--ymt-spacing-3xs) solid var(--ymt-surface);display:flex;align-items:center;justify-content:center;color:var(--ymt-surface)}.timeline__dot mat-icon{width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs);font-size:var(--ymt-sizing-xs)}.timeline__dot.timeline__dot--done{background-color:var(--ymt-success);color:var(--ymt-on-success)}.timeline__dot.timeline__dot--canceled{background-color:var(--ymt-warning);color:var(--ymt-on-warning)}.timeline__dot.timeline__dot--start,.timeline__dot.timeline__dot--suspended{background-color:var(--ymt-text-color-subtle)}.timeline__dot.timeline__dot--now{background-color:var(--ymt-surface);border-color:var(--ymt-primary)}.timeline__card{grid-area:card;display:flex;flex-direction:column;gap:var(--ymt-spacing-xs);min-width:0;margin:var(--ymt-spacing-2xs) 0 var(--ymt-spacing-s);padding:var(--ymt-spacing-s);border:var(--ymt-outline-width) solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-xs);background:var(--ymt-surface)}.timeline__head{display:flex;align-items:center;gap:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);flex-wrap:wrap}.timeline__head strong{font:var(--ymt-font-title-smallest)}.timeline__task{text-decoration:underline}.timeline__state{margin-inline-start:auto}.timeline__description{margin:0;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__life{display:grid;grid-template-columns:repeat(auto-fit,minmax(7.5rem,1fr));gap:var(--ymt-spacing-2xs) var(--ymt-spacing-m);margin:0;padding-block:var(--ymt-spacing-xs);border-block:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.timeline__life dt{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__life dd{margin:0;font-variant-numeric:tabular-nums}.timeline__people{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ymt-spacing-2xs) var(--ymt-spacing-xs)}.timeline__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__label:not(:first-child){margin-inline-start:var(--ymt-spacing-xs)}.timeline__foot{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline-tab{container-type:inline-size}@container (max-width: 26rem){.timeline__item{grid-template-columns:var(--timeline-dot-size) minmax(0,1fr);grid-template-areas:\"rail when\" \"rail card\"}.timeline__when{text-align:left;padding-top:var(--ymt-spacing-xs)}.timeline{--timeline-dot-top: var(--ymt-spacing-xs)}}\n"] }]
2120
+ args: [{ selector: 'ymbpm-process-details', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatTabsModule, MatTooltipModule, TranslatePipe, YmtBadge, FormatDateTimePipe, OrganizationRendererComponent], template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.processDefinitionId' | translate }}</span>\n @if (canOpenDefinition()) {\n <a class=\"link mono\" tabindex=\"0\" role=\"link\" [matTooltip]=\"process().processDefinitionName || ''\" (click)=\"openDefinition.emit(process().processDefinitionId)\" (keydown.enter)=\"openDefinition.emit(process().processDefinitionId)\">\n {{ process().processDefinitionId }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n <span class=\"mono\" [matTooltip]=\"process().processDefinitionName || ''\">{{ process().processDefinitionId }}</span>\n }\n </div>\n @if (process().processDefinitionDescription) {\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.process.details.processDefinitionDescription' | translate }}</span>\n <span>{{ process().processDefinitionDescription }}</span>\n </div>\n }\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.businessKey' | translate }}</span>\n <span>{{ process().businessKey || '-' }}</span>\n </div>\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab [label]=\"'yuv.app.bpm-management.process.details.history' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content timeline-tab\">\n <ol class=\"timeline\">\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ process().startTime | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--start\"><mat-icon aria-hidden=\"true\">play_arrow</mat-icon></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\"><strong>{{ 'yuv.app.bpm-management.process.details.started' | translate }}</strong></div>\n <div class=\"timeline__people\">\n <yuv-organization-renderer propertyName=\"user\" [value]=\"process().startUserId ?? null\"></yuv-organization-renderer>\n </div>\n </div>\n </li>\n @for (task of shownTasks(); track task.id) {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ (task.endTime ?? task.createTime) | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot\" [class.timeline__dot--done]=\"task.endTime\" [class.timeline__dot--suspended]=\"!task.endTime && task.suspended\">\n @if (task.endTime) {\n <mat-icon aria-hidden=\"true\">check</mat-icon>\n } @else if (task.suspended) {\n <mat-icon aria-hidden=\"true\">pause</mat-icon>\n }\n </span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <a class=\"link timeline__task\" tabindex=\"0\" role=\"link\"\n [attr.aria-label]=\"('yuv.app.bpm-management.task.open' | translate) + ': ' + (task.name || '')\"\n (click)=\"openTask.emit(task.id)\" (keydown.enter)=\"openTask.emit(task.id)\">\n <strong>{{ task.name || '&lt;unnamed&gt;' }}</strong>\n </a>\n <ymt-badge class=\"timeline__state\" [aura]=\"true\" [severity]=\"taskSeverity(task)\">\n {{ taskStatusLabel(task) | translate }}\n </ymt-badge>\n </div>\n @if (task.description) {\n <p class=\"timeline__description\">{{ task.description }}</p>\n }\n @if (task.claimTime || task.dueDate) {\n <dl class=\"timeline__life\">\n @if (task.claimTime) {\n <div>\n <dt>{{ 'yuv.app.bpm-management.task.details.claimTime' | translate }}</dt>\n <dd>{{ task.claimTime | formatDateTime }}</dd>\n </div>\n }\n @if (task.dueDate) {\n <div>\n <dt>{{ 'yuv.app.bpm-management.task.details.dueDate' | translate }}</dt>\n <dd>{{ task.dueDate | formatDateTime }}</dd>\n </div>\n }\n </dl>\n }\n @if (task.assignee || task.owner) {\n <div class=\"timeline__people\">\n @if (task.assignee) {\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task.assignee ?? null\"></yuv-organization-renderer>\n }\n @if (task.owner) {\n <span class=\"timeline__label\">{{ 'yuv.app.bpm-management.task.details.owner' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task.owner ?? null\"></yuv-organization-renderer>\n }\n </div>\n }\n <!-- a suspended task has no meaningful running time: the suspension is not part of the data -->\n @if (task.endTime || !task.suspended) {\n <div class=\"timeline__foot\">\n {{ (task.endTime ? 'yuv.app.bpm-management.process.details.took' : 'yuv.app.bpm-management.process.details.openFor') | translate: { duration: duration(task.createTime, task.endTime) } }}\n </div>\n }\n </div>\n </li>\n }\n @if (process().endTime) {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\">{{ process().endTime | formatDateTime }}</div>\n <div class=\"timeline__rail\"><span class=\"timeline__dot\" [class.timeline__dot--done]=\"!process().deleteReason\" [class.timeline__dot--canceled]=\"process().deleteReason\">\n <mat-icon aria-hidden=\"true\">{{ process().deleteReason ? 'close' : 'check' }}</mat-icon>\n </span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ (process().deleteReason ? 'yuv.app.bpm-management.process.details.canceled' : 'yuv.app.bpm-management.process.details.completed') | translate }}</strong>\n </div>\n @if (process().deleteReason) {\n <p class=\"timeline__description\">{{ process().deleteReason }}</p>\n }\n <div class=\"timeline__foot\">{{ 'yuv.app.bpm-management.process.details.took' | translate: { duration: duration(process().startTime, process().endTime) } }}</div>\n </div>\n </li>\n } @else {\n <li class=\"timeline__item\">\n <div class=\"timeline__when\"></div>\n @if (process().suspended) {\n <!-- the time of the suspension is not part of the data, so no running time is shown -->\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--suspended\"><mat-icon aria-hidden=\"true\">pause</mat-icon></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ 'yuv.app.bpm-management.status.suspended' | translate }}</strong>\n </div>\n </div>\n } @else {\n <div class=\"timeline__rail\"><span class=\"timeline__dot timeline__dot--now\"><mat-icon aria-hidden=\"true\">{{ processStatusIcon(process()) }}</mat-icon></span></div>\n <div class=\"timeline__card\">\n <div class=\"timeline__head\">\n <strong>{{ 'yuv.app.bpm-management.process.details.running' | translate }}</strong>\n <ymt-badge severity=\"primary\">{{ duration(process().startTime) }}</ymt-badge>\n </div>\n </div>\n }\n </li>\n }\n </ol>\n </div>\n </ng-template>\n </mat-tab>\n <mat-tab [label]=\"'yuv.app.bpm-management.details.variables' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content\">\n @if (!process().variables?.length) {\n <p class=\"empty\">{{ 'yuv.app.bpm-management.emptyResult' | translate }}</p>\n } @else {\n <input class=\"variables__filter\" type=\"search\"\n [attr.aria-label]=\"'yuv.app.bpm-management.details.variableFilter' | translate\"\n [placeholder]=\"'yuv.app.bpm-management.details.variableFilter' | translate\"\n (input)=\"variableFilter.set($any($event.target).value)\">\n <table class=\"table\">\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 variables(); track variable.name) {\n <tr>\n <td class=\"mono\">{{ variable.name }}</td>\n <td>{{ variable.type }}</td>\n <td class=\"mono\">{{ variable.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </ng-template>\n </mat-tab>\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}.timeline{--timeline-dot-size: var(--ymt-sizing-m);--timeline-dot-top: var(--ymt-spacing-s);--timeline-dot-center: calc(var(--timeline-dot-top) + var(--timeline-dot-size) / 2);list-style:none;margin:0;padding:0}.timeline__item{display:grid;grid-template-columns:var(--ymt-sizing-7xl) var(--timeline-dot-size) minmax(0,1fr);grid-template-areas:\"when rail card\";gap:var(--ymt-spacing-xs)}.timeline__when{grid-area:when;text-align:right;padding-top:var(--ymt-spacing-s);font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__rail{grid-area:rail;position:relative}.timeline__rail:before{content:\"\";position:absolute;left:calc(50% - var(--ymt-spacing-3xs) / 2);top:0;bottom:0;width:var(--ymt-spacing-3xs);background-color:var(--ymt-outline-variant)}.timeline__item:first-child .timeline__rail:before{top:var(--timeline-dot-center)}.timeline__item:last-child .timeline__rail:before{bottom:calc(100% - var(--timeline-dot-center))}.timeline__item:only-child .timeline__rail:before{display:none}.timeline__dot{position:absolute;inset-block-start:var(--timeline-dot-top);inset-inline:0;height:var(--timeline-dot-size);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary);border:var(--ymt-spacing-3xs) solid var(--ymt-surface);display:flex;align-items:center;justify-content:center;color:var(--ymt-surface)}.timeline__dot mat-icon{width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs);font-size:var(--ymt-sizing-xs)}.timeline__dot.timeline__dot--done{background-color:var(--ymt-success);color:var(--ymt-on-success)}.timeline__dot.timeline__dot--canceled{background-color:var(--ymt-warning);color:var(--ymt-on-warning)}.timeline__dot.timeline__dot--start,.timeline__dot.timeline__dot--suspended{background-color:var(--ymt-text-color-subtle)}.timeline__dot.timeline__dot--now{background-color:var(--ymt-surface);border-color:var(--ymt-primary);color:var(--ymt-primary)}.timeline__card{grid-area:card;display:flex;flex-direction:column;gap:var(--ymt-spacing-xs);min-width:0;margin:var(--ymt-spacing-2xs) 0 var(--ymt-spacing-s);padding:var(--ymt-spacing-s);border:var(--ymt-outline-width) solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-xs);background:var(--ymt-surface)}.timeline__head{display:flex;align-items:center;gap:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);flex-wrap:wrap}.timeline__head strong{font:var(--ymt-font-title-smallest)}.timeline__task{text-decoration:underline}.timeline__state{margin-inline-start:auto}.timeline__description{margin:0;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__life{display:grid;grid-template-columns:repeat(auto-fit,minmax(7.5rem,1fr));gap:var(--ymt-spacing-2xs) var(--ymt-spacing-m);margin:0;padding-block:var(--ymt-spacing-xs);border-block:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.timeline__life dt{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__life dd{margin:0;font-variant-numeric:tabular-nums}.timeline__people{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ymt-spacing-2xs) var(--ymt-spacing-xs)}.timeline__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline__label:not(:first-child){margin-inline-start:var(--ymt-spacing-xs)}.timeline__foot{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.timeline-tab{container-type:inline-size}@container (max-width: 26rem){.timeline__item{grid-template-columns:var(--timeline-dot-size) minmax(0,1fr);grid-template-areas:\"rail when\" \"rail card\"}.timeline__when{text-align:left;padding-top:var(--ymt-spacing-xs)}.timeline{--timeline-dot-top: var(--ymt-spacing-xs)}}\n"] }]
1920
2121
  }], propDecorators: { process: [{ type: i0.Input, args: [{ isSignal: true, alias: "process", required: true }] }], tasks: [{ type: i0.Input, args: [{ isSignal: true, alias: "tasks", required: false }] }], canOpenDefinition: [{ type: i0.Input, args: [{ isSignal: true, alias: "canOpenDefinition", required: false }] }], openTask: [{ type: i0.Output, args: ["openTask"] }], openDefinition: [{ type: i0.Output, args: ["openDefinition"] }] } });
1921
2122
 
1922
2123
  class EditorHistoryComponent {
@@ -1958,7 +2159,7 @@ class EditorHistoryComponent {
1958
2159
  return `yuv.app.bpm-management.task.details.actionType.${type.toLowerCase()}`;
1959
2160
  }
1960
2161
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: EditorHistoryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1961
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", 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 <yuv-organization-renderer propertyName=\"user\" [value]=\"user ?? null\"></yuv-organization-renderer>\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 <yuv-organization-renderer propertyName=\"user\" [value]=\"entry.assignee ?? null\"></yuv-organization-renderer>\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 <yuv-organization-renderer propertyName=\"user\" [value]=\"entry.owner ?? null\"></yuv-organization-renderer>\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 var(--ymt-spacing-3xs) 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:var(--ymt-sizing-7xl)}.timeline-container .timeline-item .timeline-datetime .date{font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);font-weight:var(--ymt-font-title-smallest-weight);color:var(--ymt-on-surface);line-height:var(--ymt-font-body-line-height)}.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:var(--ymt-spacing-3xs) solid var(--ymt-surface);box-shadow:0 0 0 var(--ymt-spacing-3xs) 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:0;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{color:var(--ymt-on-surface-type-subtle)}@media(max-width:768px){.timeline-datetime{min-width:var(--ymt-sizing-6xl);padding-right:var(--ymt-spacing-xs)}.timeline-datetime .date,.timeline-datetime .time{font-size:var(--ymt-font-body-subtle-size)}.timeline-content{padding-left:var(--ymt-spacing-xs)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.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: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: OrganizationRendererComponent, selector: "yuv-organization-renderer" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2162
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", 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 <yuv-organization-renderer propertyName=\"user\" [value]=\"user ?? null\"></yuv-organization-renderer>\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 <yuv-organization-renderer propertyName=\"user\" [value]=\"entry.assignee ?? null\"></yuv-organization-renderer>\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 <yuv-organization-renderer propertyName=\"user\" [value]=\"entry.owner ?? null\"></yuv-organization-renderer>\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 var(--ymt-spacing-3xs) 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:var(--ymt-sizing-7xl)}.timeline-container .timeline-item .timeline-datetime .date{font-family:var(--ymt-font-body-font);font-size:var(--ymt-font-body-size);font-weight:var(--ymt-font-title-smallest-weight);color:var(--ymt-on-surface);line-height:var(--ymt-font-body-line-height)}.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:var(--ymt-spacing-3xs) solid var(--ymt-surface);box-shadow:0 0 0 var(--ymt-spacing-3xs) 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:0;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{color:var(--ymt-on-surface-type-subtle)}@media(max-width:768px){.timeline-datetime{min-width:var(--ymt-sizing-6xl);padding-right:var(--ymt-spacing-xs)}.timeline-datetime .date,.timeline-datetime .time{font-size:var(--ymt-font-body-subtle-size)}.timeline-content{padding-left:var(--ymt-spacing-xs)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.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: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: OrganizationRendererComponent, selector: "yuv-organization-renderer" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1962
2163
  }
1963
2164
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: EditorHistoryComponent, decorators: [{
1964
2165
  type: Component,
@@ -1983,120 +2184,22 @@ class TaskDetailsComponent {
1983
2184
  task = input.required(...(ngDevMode ? [{ debugName: "task" }] : /* istanbul ignore next */ []));
1984
2185
  openProcess = output();
1985
2186
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: TaskDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1986
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: TaskDetailsComponent, isStandalone: true, selector: "ymbpm-task-details", inputs: { task: { classPropertyName: "task", publicName: "task", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { openProcess: "openProcess" }, ngImport: i0, template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.processInstanceId' | translate }}</span>\n @if (task().processInstanceId; as processId) {\n <a class=\"link mono\" tabindex=\"0\" role=\"link\" [matTooltip]=\"task().processInstanceName || ''\" (click)=\"openProcess.emit(processId)\" (keydown.enter)=\"openProcess.emit(processId)\">\n {{ processId }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n <span [matTooltip]=\"'yuv.app.bpm-management.task.details.standaloneTask.tooltip' | translate\">- <mat-icon class=\"inline\">info</mat-icon></span>\n }\n </div>\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.taskDefinitionKey' | translate }}</span>\n <span class=\"mono\">{{ task().taskDefinitionKey }}</span>\n </div>\n <div class=\"fact-row\">\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.createTime' | translate }}</span>\n <span>{{ task().createTime | formatDateTime }}</span>\n </div>\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.dueDate' | translate }}</span>\n <span>{{ (task().dueDate | formatDateTime) || '-' }}</span>\n </div>\n @if (task().endTime) {\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.endTime' | translate }}</span>\n <span>{{ task().endTime | formatDateTime }}</span>\n </div>\n }\n </div>\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.assignee' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task().assignee ?? null\"></yuv-organization-renderer>\n </div>\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.owner' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task().owner ?? null\"></yuv-organization-renderer>\n </div>\n @if (task().claimTime) {\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.claimTime' | translate }}</span>\n <span>{{ task().claimTime | formatDateTime }}</span>\n </div>\n }\n @if (task().description) {\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.description' | translate }}</span>\n <span>{{ task().description }}</span>\n </div>\n }\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab [label]=\"'yuv.app.bpm-management.task.assignment' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content\">\n <ymbpm-editor-history [task]=\"task()\"></ymbpm-editor-history>\n </div>\n </ng-template>\n </mat-tab>\n @if (task().variables?.length) {\n <mat-tab [label]=\"'yuv.app.bpm-management.details.variables' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content\">\n <table class=\"table\">\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 task().variables; track variable.name) {\n <tr>\n <td class=\"mono\">{{ variable.name }}</td>\n <td>{{ variable.type }}</td>\n <td class=\"mono\">{{ variable.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </ng-template>\n </mat-tab>\n }\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i2$2.MatTabContent, selector: "[matTabContent]" }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.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: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: OrganizationRendererComponent, selector: "yuv-organization-renderer" }, { kind: "component", type: EditorHistoryComponent, selector: "ymbpm-editor-history", inputs: ["task"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2187
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: TaskDetailsComponent, isStandalone: true, selector: "ymbpm-task-details", inputs: { task: { classPropertyName: "task", publicName: "task", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { openProcess: "openProcess" }, ngImport: i0, template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.processInstanceId' | translate }}</span>\n @if (task().processInstanceId; as processId) {\n <a class=\"link mono\" tabindex=\"0\" role=\"link\" [matTooltip]=\"task().processInstanceName || ''\" (click)=\"openProcess.emit(processId)\" (keydown.enter)=\"openProcess.emit(processId)\">\n {{ processId }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n <span [matTooltip]=\"'yuv.app.bpm-management.task.details.standaloneTask.tooltip' | translate\">- <mat-icon class=\"inline\">info</mat-icon></span>\n }\n </div>\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.taskDefinitionKey' | translate }}</span>\n <span class=\"mono\">{{ task().taskDefinitionKey }}</span>\n </div>\n <div class=\"fact-row\">\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.createTime' | translate }}</span>\n <span>{{ task().createTime | formatDateTime }}</span>\n </div>\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.dueDate' | translate }}</span>\n <span>{{ (task().dueDate | formatDateTime) || '-' }}</span>\n </div>\n @if (task().endTime) {\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.endTime' | translate }}</span>\n <span>{{ task().endTime | formatDateTime }}</span>\n </div>\n }\n </div>\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.assignee' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task().assignee ?? null\"></yuv-organization-renderer>\n </div>\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.owner' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task().owner ?? null\"></yuv-organization-renderer>\n </div>\n @if (task().claimTime) {\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.claimTime' | translate }}</span>\n <span>{{ task().claimTime | formatDateTime }}</span>\n </div>\n }\n @if (task().description) {\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.description' | translate }}</span>\n <span>{{ task().description }}</span>\n </div>\n }\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab [label]=\"'yuv.app.bpm-management.task.assignment' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content\">\n <ymbpm-editor-history [task]=\"task()\"></ymbpm-editor-history>\n </div>\n </ng-template>\n </mat-tab>\n @if (task().variables?.length) {\n <mat-tab [label]=\"'yuv.app.bpm-management.details.variables' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content\">\n <table class=\"table\">\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 task().variables; track variable.name) {\n <tr>\n <td class=\"mono\">{{ variable.name }}</td>\n <td>{{ variable.type }}</td>\n <td class=\"mono\">{{ variable.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </ng-template>\n </mat-tab>\n }\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i2$2.MatTabContent, selector: "[matTabContent]" }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.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: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: OrganizationRendererComponent, selector: "yuv-organization-renderer" }, { kind: "component", type: EditorHistoryComponent, selector: "ymbpm-editor-history", inputs: ["task"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1987
2188
  }
1988
2189
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: TaskDetailsComponent, decorators: [{
1989
2190
  type: Component,
1990
2191
  args: [{ selector: 'ymbpm-task-details', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIconModule, MatTabsModule, MatTooltipModule, TranslatePipe, FormatDateTimePipe, OrganizationRendererComponent, EditorHistoryComponent], template: "<section class=\"facts\">\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.processInstanceId' | translate }}</span>\n @if (task().processInstanceId; as processId) {\n <a class=\"link mono\" tabindex=\"0\" role=\"link\" [matTooltip]=\"task().processInstanceName || ''\" (click)=\"openProcess.emit(processId)\" (keydown.enter)=\"openProcess.emit(processId)\">\n {{ processId }}<mat-icon>arrow_forward</mat-icon>\n </a>\n } @else {\n <span [matTooltip]=\"'yuv.app.bpm-management.task.details.standaloneTask.tooltip' | translate\">- <mat-icon class=\"inline\">info</mat-icon></span>\n }\n </div>\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.taskDefinitionKey' | translate }}</span>\n <span class=\"mono\">{{ task().taskDefinitionKey }}</span>\n </div>\n <div class=\"fact-row\">\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.createTime' | translate }}</span>\n <span>{{ task().createTime | formatDateTime }}</span>\n </div>\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.dueDate' | translate }}</span>\n <span>{{ (task().dueDate | formatDateTime) || '-' }}</span>\n </div>\n @if (task().endTime) {\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.column.endTime' | translate }}</span>\n <span>{{ task().endTime | formatDateTime }}</span>\n </div>\n }\n </div>\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.assignee' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task().assignee ?? null\"></yuv-organization-renderer>\n </div>\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.owner' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"task().owner ?? null\"></yuv-organization-renderer>\n </div>\n @if (task().claimTime) {\n <div class=\"fact\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.claimTime' | translate }}</span>\n <span>{{ task().claimTime | formatDateTime }}</span>\n </div>\n }\n @if (task().description) {\n <div class=\"fact fact--wide\">\n <span class=\"fact__label\">{{ 'yuv.app.bpm-management.task.details.description' | translate }}</span>\n <span>{{ task().description }}</span>\n </div>\n }\n</section>\n\n<mat-tab-group class=\"tabs\" animationDuration=\"0ms\">\n <mat-tab [label]=\"'yuv.app.bpm-management.task.assignment' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content\">\n <ymbpm-editor-history [task]=\"task()\"></ymbpm-editor-history>\n </div>\n </ng-template>\n </mat-tab>\n @if (task().variables?.length) {\n <mat-tab [label]=\"'yuv.app.bpm-management.details.variables' | translate\">\n <ng-template matTabContent>\n <div class=\"tab-content\">\n <table class=\"table\">\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 task().variables; track variable.name) {\n <tr>\n <td class=\"mono\">{{ variable.name }}</td>\n <td>{{ variable.type }}</td>\n <td class=\"mono\">{{ variable.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </ng-template>\n </mat-tab>\n }\n</mat-tab-group>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:flex;flex-direction:column;min-height:100%}:host mat-icon{font-size:var(--ymt-sizing-s);width:var(--ymt-sizing-s);height:var(--ymt-sizing-s);vertical-align:middle}.facts{display:flex;flex-wrap:wrap;gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl);padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) 0}.facts .fact{display:flex;flex-direction:column;min-width:0}.facts .fact--wide{flex:1 1 100%}.facts .fact-row{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ymt-spacing-m) var(--ymt-spacing-3xl)}.facts .fact__label{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.link{display:inline-flex;align-items:center;gap:var(--ymt-spacing-3xs);cursor:pointer;color:var(--ymt-text-color-primary)}.link:hover{text-decoration:underline}.link .inline{color:var(--ymt-text-color-subtle)}.section{margin-top:var(--ymt-spacing-xl)}.section__title{display:flex;align-items:center;gap:var(--ymt-spacing-xs);margin:0 0 var(--ymt-spacing-xs);font:var(--ymt-font-title-small);color:var(--ymt-text-color)}.section__title mat-icon{color:var(--ymt-primary)}.count{--ymt-badge-corner: var(--ymt-corner-full);margin-inline-start:var(--ymt-spacing-xs)}.tabs{flex:1 1 auto;margin-top:var(--ymt-spacing-m)}.tabs ::ng-deep .mat-mdc-tab-body-wrapper{flex:1 1 auto;background:var(--ymt-surface-container-low)}.tab-content{padding:var(--ymt-spacing-m) var(--ymt-spacing-xl) var(--ymt-spacing-xl)}.empty{font:var(--ymt-font-body-subtle);font-style:italic;color:var(--ymt-text-color-subtle)}.mono{font-family:monospace;word-break:break-all}.table{width:100%;border-collapse:collapse}.table th{text-align:left;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}.table th,.table td{padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant)}.variables__filter{width:100%;box-sizing:border-box;margin-bottom:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);border:var(--ymt-outline-width) solid var(--ymt-outline);border-radius:var(--ymt-corner-xs);background:transparent;color:var(--ymt-text-color);font:var(--ymt-font-body)}\n"] }]
1991
2192
  }], propDecorators: { task: [{ type: i0.Input, args: [{ isSignal: true, alias: "task", required: true }] }], openProcess: [{ type: i0.Output, args: ["openProcess"] }] } });
1992
2193
 
1993
- class CheckboxOverlayComponent {
1994
- #dialogRef = inject((MatDialogRef));
1995
- inputData = inject(MAT_DIALOG_DATA);
1996
- toggle;
1997
- confirm() {
1998
- this.#dialogRef.close(this.toggle.checked);
1999
- }
2000
- close() {
2001
- this.#dialogRef.close();
2002
- }
2003
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: CheckboxOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2004
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", type: CheckboxOverlayComponent, isStandalone: true, selector: "ymbpm-checkbox-overlay", viewQueries: [{ propertyName: "toggle", first: true, predicate: ["toggle"], descendants: true }], ngImport: i0, template: "<yuv-dialog [headertitle]=\"this.inputData.title ?? ''\" []>\n <main class=\"yuv-dialog-content\">\n <mat-label>{{ this.inputData.message !== undefined ? this.inputData.message : '' }}</mat-label>\n </main>\n <footer>\n <mat-slide-toggle #toggle class=\"footer-toggle\" [checked]=\"false\">{{ this.inputData.checkboxMessage !== undefined ? this.inputData.checkboxMessage : '' }}</mat-slide-toggle>\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)}:host mat-label{white-space:pre-line}footer{display:flex;flex:1 1 auto;align-items:center;gap:inherit}.footer-toggle{margin-inline-end:auto}\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: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2005
- }
2006
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: CheckboxOverlayComponent, decorators: [{
2007
- type: Component,
2008
- args: [{ selector: 'ymbpm-checkbox-overlay', standalone: true, imports: [
2009
- YmtButtonDirective,
2010
- DialogComponent,
2011
- TranslatePipe,
2012
- MatSlideToggle,
2013
- MatLabel
2014
- ], template: "<yuv-dialog [headertitle]=\"this.inputData.title ?? ''\" []>\n <main class=\"yuv-dialog-content\">\n <mat-label>{{ this.inputData.message !== undefined ? this.inputData.message : '' }}</mat-label>\n </main>\n <footer>\n <mat-slide-toggle #toggle class=\"footer-toggle\" [checked]=\"false\">{{ this.inputData.checkboxMessage !== undefined ? this.inputData.checkboxMessage : '' }}</mat-slide-toggle>\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)}:host mat-label{white-space:pre-line}footer{display:flex;flex:1 1 auto;align-items:center;gap:inherit}.footer-toggle{margin-inline-end:auto}\n"] }]
2015
- }], propDecorators: { toggle: [{
2016
- type: ViewChild,
2017
- args: ['toggle']
2018
- }] } });
2019
-
2020
- class TaskAssignOverlayComponent {
2021
- #dialogRef = inject((MatDialogRef));
2022
- data = inject(MAT_DIALOG_DATA);
2023
- userControl = new FormControl('');
2024
- close() {
2025
- this.#dialogRef.close();
2026
- }
2027
- confirm() {
2028
- const assignee = this.userControl.value;
2029
- if (assignee && assignee.trim()) {
2030
- this.#dialogRef.close(assignee.trim());
2031
- }
2032
- }
2033
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: TaskAssignOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2034
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", 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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.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", "allowFreeText"] }, { 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" }] });
2035
- }
2036
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: TaskAssignOverlayComponent, decorators: [{
2037
- type: Component,
2038
- args: [{ selector: 'ymbpm-task-assign-overlay', imports: [
2039
- CommonModule,
2040
- ReactiveFormsModule,
2041
- MatDialogModule,
2042
- MatFormFieldModule,
2043
- MatInputModule,
2044
- MatButtonModule,
2045
- TranslatePipe,
2046
- OrganizationComponent,
2047
- DialogComponent,
2048
- YmtButtonDirective
2049
- ], 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"] }]
2050
- }] });
2051
-
2052
- class TaskCandidatesOverlayComponent {
2053
- #dialogRef = inject((MatDialogRef));
2054
- data = inject(MAT_DIALOG_DATA);
2055
- usersControl = new FormControl(this.data.currentUsers?.length ? this.data.currentUsers : null);
2056
- rolesControl = new FormControl(this.data.currentRoles?.length ? this.data.currentRoles : null);
2057
- close() {
2058
- this.#dialogRef.close();
2059
- }
2060
- confirm() {
2061
- const usersValue = this.usersControl.value;
2062
- const rolesValue = this.rolesControl.value;
2063
- const result = {
2064
- users: Array.isArray(usersValue) ? usersValue.filter(Boolean) : usersValue ? [usersValue] : [],
2065
- roles: Array.isArray(rolesValue) ? rolesValue.filter(Boolean) : rolesValue ? [rolesValue] : []
2066
- };
2067
- this.#dialogRef.close(result);
2068
- }
2069
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: TaskCandidatesOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2070
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", type: TaskCandidatesOverlayComponent, isStandalone: true, selector: "ymbpm-task-candidates-overlay", ngImport: i0, template: "<yuv-dialog [headertitle]=\"'yuv.app.bpm-management.task.actions.editCandidates.label' | translate\">\n <main>\n <div class=\"field-group\">\n <mat-label>{{ 'yuv.app.bpm-management.task.details.candidateUsers' | translate }}</mat-label>\n <yuv-organization [formControl]=\"usersControl\" [multiselect]=\"true\" [excludeMe]=\"false\" [classifications]=\"['id:organization:set[user]']\" />\n </div>\n <div class=\"field-group\">\n <mat-label>{{ 'yuv.app.bpm-management.task.details.candidateRoles' | translate }}</mat-label>\n <yuv-organization [formControl]=\"rolesControl\" [multiselect]=\"true\" [excludeMe]=\"false\" [classifications]=\"['id:organization:set[role]']\" />\n </div>\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\">\n {{ 'yuv.app.bpm-management.action.confirm.label' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:contents}:host main{display:flex;flex-direction:column;padding:var(--ymt-spacing-m);gap: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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: OrganizationComponent, selector: "yuv-organization", inputs: ["situation", "multiselect", "classifications", "readonly", "excludeMe", "withMetadata", "allowFreeText"] }, { 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: "directive", type: MatLabel$1, selector: "mat-label" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2071
- }
2072
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: TaskCandidatesOverlayComponent, decorators: [{
2073
- type: Component,
2074
- args: [{ selector: 'ymbpm-task-candidates-overlay', standalone: true, imports: [
2075
- CommonModule,
2076
- ReactiveFormsModule,
2077
- MatDialogModule,
2078
- MatButtonModule,
2079
- TranslatePipe,
2080
- OrganizationComponent,
2081
- DialogComponent,
2082
- YmtButtonDirective,
2083
- MatLabel$1
2084
- ], template: "<yuv-dialog [headertitle]=\"'yuv.app.bpm-management.task.actions.editCandidates.label' | translate\">\n <main>\n <div class=\"field-group\">\n <mat-label>{{ 'yuv.app.bpm-management.task.details.candidateUsers' | translate }}</mat-label>\n <yuv-organization [formControl]=\"usersControl\" [multiselect]=\"true\" [excludeMe]=\"false\" [classifications]=\"['id:organization:set[user]']\" />\n </div>\n <div class=\"field-group\">\n <mat-label>{{ 'yuv.app.bpm-management.task.details.candidateRoles' | translate }}</mat-label>\n <yuv-organization [formControl]=\"rolesControl\" [multiselect]=\"true\" [excludeMe]=\"false\" [classifications]=\"['id:organization:set[role]']\" />\n </div>\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\">\n {{ 'yuv.app.bpm-management.action.confirm.label' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:contents}:host main{display:flex;flex-direction:column;padding:var(--ymt-spacing-m);gap: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"] }]
2085
- }] });
2086
-
2087
2194
  /**
2088
2195
  * The details pane of the selected deployment, process definition, process or task. Owns the
2089
2196
  * header (title, status badges) and the actions of the item, the content is rendered by the
2090
2197
  * component of the entity.
2091
2198
  */
2092
2199
  class DetailsComponent {
2093
- #dialog = inject(MatDialog);
2094
- #service = inject(YuvBpmManagementService);
2095
- #translate = inject(TranslateService);
2096
- #notifications = inject(NotificationService);
2097
- #logger = inject(Logger);
2200
+ actions = inject(BpmManagementActionsService);
2098
2201
  icons = { ...APP_ICONS };
2099
- ProcessDefinitionScope = ProcessDefinitionScope;
2202
+ definitionScope = definitionScope;
2100
2203
  processSeverity = processSeverity;
2101
2204
  processStatusIcon = processStatusIcon;
2102
2205
  processStatusLabel = processStatusLabel;
@@ -2138,150 +2241,12 @@ class DetailsComponent {
2138
2241
  return item ? item.name || '<unnamed>' : '';
2139
2242
  }, ...(ngDevMode ? [{ debugName: "headerTitle" }] : /* istanbul ignore next */ []));
2140
2243
  headerSubtitle = computed(() => this.detail()?.id ?? '', ...(ngDevMode ? [{ debugName: "headerSubtitle" }] : /* istanbul ignore next */ []));
2141
- // ---- process definition actions ------------------------------------------------------------
2142
- /** Activates or suspends the definition, optionally together with its processes. */
2143
- executeDefinitionAction(action) {
2144
- const definition = this.actionDefinition();
2145
- if (!definition)
2146
- return;
2147
- const key = `yuv.app.bpm-management.definitions.actions.${action}`;
2148
- this.#dialog
2149
- .open(CheckboxOverlayComponent, {
2150
- width: '600px',
2151
- maxWidth: '90vw',
2152
- data: {
2153
- title: this.#translate.instant(`${key}.label`),
2154
- message: this.#translate.instant(`${key}.confirm.message`),
2155
- checkboxMessage: this.#translate.instant(`${key}.confirm.includeProcesses.label`),
2156
- confirmBtnLabel: this.#translate.instant(`${key}.confirm.button.label`)
2157
- }
2158
- })
2159
- .afterClosed()
2160
- .subscribe((includeProcesses) => {
2161
- if (includeProcesses === undefined)
2162
- return;
2163
- this.#service.executeProcessDefinitionAction(definition.id, action, includeProcesses).subscribe({
2164
- next: () => {
2165
- this.#notifications.success(this.#translate.instant(`${key}.success`));
2166
- // the status is shown in the list too, and the process counts change
2167
- this.changed.emit('both');
2168
- },
2169
- error: (e) => {
2170
- this.#logger.error(`Failed to ${action} the process definition`, e);
2171
- this.#notifications.error(this.#translate.instant(`${key}.error`));
2172
- }
2173
- });
2174
- });
2175
- }
2176
- // ---- process actions -----------------------------------------------------------------------
2177
- /** Suspends or resumes a running process. */
2178
- executeProcessAction(action) {
2179
- const process = this.process();
2180
- if (!process)
2181
- return;
2182
- const key = `yuv.app.bpm-management.process.actions.${action}`;
2183
- this.#dialog
2184
- .open(ConfirmComponent, {
2185
- width: '600px',
2186
- maxWidth: '90vw',
2187
- data: {
2188
- title: this.#translate.instant(`${key}.label`),
2189
- message: this.#translate.instant(`${key}.confirm.message`),
2190
- confirmBtnLabel: this.#translate.instant(`${key}.confirm.button.label`)
2191
- }
2192
- })
2193
- .afterClosed()
2194
- .subscribe((confirm) => {
2195
- if (!confirm)
2196
- return;
2197
- this.#service.executeProcessAction(process.id, action).subscribe({
2198
- next: () => {
2199
- this.#notifications.success(this.#translate.instant(`${key}.success`));
2200
- // the status is shown in the list too
2201
- this.changed.emit('both');
2202
- },
2203
- error: (e) => {
2204
- this.#logger.error(`Failed to ${action} the process`, e);
2205
- this.#notifications.error(this.#translate.instant(`${key}.error`));
2206
- }
2207
- });
2208
- });
2209
- }
2210
- // ---- task actions --------------------------------------------------------------------------
2211
- assign() {
2212
- const task = this.task();
2213
- if (!task)
2214
- return;
2215
- this.#dialog
2216
- .open(TaskAssignOverlayComponent, { width: '400px', maxWidth: '90vw', data: { taskId: task.id, taskName: task.name } })
2217
- .afterClosed()
2218
- .subscribe((assignee) => {
2219
- if (assignee) {
2220
- this.#updateAssignee(task.id, assignee, 'yuv.app.bpm-management.task.actions.assign.success');
2221
- }
2222
- });
2223
- }
2224
- unassign() {
2225
- const task = this.task();
2226
- if (!task)
2227
- return;
2228
- this.#dialog
2229
- .open(ConfirmComponent, {
2230
- width: '400px',
2231
- maxWidth: '90vw',
2232
- data: {
2233
- title: this.#translate.instant('yuv.app.bpm-management.task.actions.unassign.label'),
2234
- message: this.#translate.instant('yuv.app.bpm-management.task.actions.unassign.confirm.message')
2235
- }
2236
- })
2237
- .afterClosed()
2238
- .subscribe((confirm) => {
2239
- if (confirm) {
2240
- this.#updateAssignee(task.id, null, 'yuv.app.bpm-management.task.actions.unassign.success');
2241
- }
2242
- });
2243
- }
2244
- editCandidates() {
2245
- const task = this.task();
2246
- if (!task)
2247
- return;
2248
- this.#dialog
2249
- .open(TaskCandidatesOverlayComponent, {
2250
- width: '600px',
2251
- maxWidth: '95vw',
2252
- data: {
2253
- currentUsers: [...(task.identityLinks?.candidates?.users ?? [])],
2254
- currentRoles: [...(task.identityLinks?.candidates?.roles ?? [])]
2255
- }
2256
- })
2257
- .afterClosed()
2258
- .subscribe((result) => {
2259
- if (result === undefined)
2260
- return;
2261
- this.#service.setTaskCandidates(task.id, result).subscribe({
2262
- next: () => {
2263
- this.#notifications.success(this.#translate.instant('yuv.app.bpm-management.task.candidates.update.success'));
2264
- // candidates are not shown in the list
2265
- this.changed.emit('details');
2266
- },
2267
- error: () => this.#notifications.error(this.#translate.instant('yuv.app.bpm-management.task.candidates.update.error'))
2268
- });
2269
- });
2270
- }
2271
- #updateAssignee(taskId, assignee, successKey) {
2272
- this.#service.assignTask(taskId, assignee).subscribe({
2273
- next: () => {
2274
- this.#notifications.success(this.#translate.instant(successKey));
2275
- this.changed.emit('both');
2276
- },
2277
- error: (e) => {
2278
- this.#logger.error('Failed to change the assignee of the task', e);
2279
- this.#notifications.error(this.#translate.instant('yuv.app.bpm-management.task.actions.assign.error'));
2280
- }
2281
- });
2244
+ /** Runs an action of the header (it asks and notifies itself), the owner reloads what changed. */
2245
+ run(action) {
2246
+ action.subscribe(scope => this.changed.emit(scope));
2282
2247
  }
2283
2248
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: DetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2284
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: DetailsComponent, isStandalone: true, selector: "ymbpm-details", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, detail: { classPropertyName: "detail", publicName: "detail", isSignal: true, isRequired: false, transformFunction: null }, listItem: { classPropertyName: "listItem", publicName: "listItem", isSignal: true, isRequired: false, transformFunction: null }, processTasks: { classPropertyName: "processTasks", publicName: "processTasks", isSignal: true, isRequired: false, transformFunction: null }, busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, selectedId: { classPropertyName: "selectedId", publicName: "selectedId", isSignal: true, isRequired: false, transformFunction: null }, canOpenDefinition: { classPropertyName: "canOpenDefinition", publicName: "canOpenDefinition", isSignal: true, isRequired: false, transformFunction: null }, canOpenDeployment: { classPropertyName: "canOpenDeployment", publicName: "canOpenDeployment", isSignal: true, isRequired: false, transformFunction: null }, topBarActions: { classPropertyName: "topBarActions", publicName: "topBarActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changed: "changed", openItem: "openItem", showProcesses: "showProcesses" }, ngImport: i0, template: "<ymt-pane\n [busy]=\"busy()\"\n [topBarActions]=\"topBarActions()\"\n role=\"region\"\n [attr.aria-label]=\"'yuv.app.bpm-management.details.aria' | translate\"\n>\n <ymt-pane-header\n [icon]=\"headerTitle() ? headerIcon() : undefined\"\n [title]=\"headerTitle()\"\n [subtitle]=\"headerSubtitle()\"\n [badges]=\"detail() ? headerBadges : undefined\"\n [actions]=\"task() ? taskActions : actionDefinition() ? definitionActions : process() ? processActions : undefined\"\n ></ymt-pane-header>\n\n <ymt-pane-body>\n @if (error()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">error_outline</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.details.error' | translate }}</p>\n </div>\n } @else if (deployment(); as deployment) {\n <ymbpm-deployment-details\n [deployment]=\"deployment\"\n [canOpenDefinition]=\"canOpenDefinition()\"\n (openDefinition)=\"openItem.emit({ entity: 'definitions', id: $event })\"\n ></ymbpm-deployment-details>\n } @else if (definition(); as definition) {\n <ymbpm-process-definition-details\n [definition]=\"definition\"\n [canOpenDeployment]=\"canOpenDeployment()\"\n (openDeployment)=\"openItem.emit({ entity: 'deployments', id: $event })\"\n (showProcesses)=\"showProcesses.emit($event)\"\n ></ymbpm-process-definition-details>\n } @else if (process(); as process) {\n <ymbpm-process-details\n [process]=\"process\"\n [tasks]=\"processTasks()\"\n [canOpenDefinition]=\"canOpenDefinition()\"\n (openTask)=\"openItem.emit({ entity: 'tasks', id: $event })\"\n (openDefinition)=\"openItem.emit({ entity: 'definitions', id: $event })\"\n ></ymbpm-process-details>\n } @else if (task(); as task) {\n <ymbpm-task-details\n [task]=\"task\"\n (openProcess)=\"openItem.emit({ entity: 'processes', id: $event })\"\n ></ymbpm-task-details>\n } @else if (!busy() && !selectedId()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">{{ icons.info }}</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </ymt-pane-body>\n</ymt-pane>\n\n<!-- header: status badges -->\n<ng-template #headerBadges>\n @if (process(); as p) {\n <ymt-badge [severity]=\"processSeverity(p)\"><mat-icon>{{ processStatusIcon(p) }}</mat-icon>{{ processStatusLabel(p) | translate }}</ymt-badge>\n } @else if (task(); as t) {\n <ymt-badge [severity]=\"taskSeverity(t)\"><mat-icon>{{ taskStatusIcon(t) }}</mat-icon>{{ taskStatusLabel(t) | translate }}</ymt-badge>\n @if (t.delegationState) {\n <ymt-badge [outline]=\"true\" [severity]=\"t.delegationState === 'pending' ? 'warning' : 'success'\">\n {{ (t.delegationState === 'pending' ? 'yuv.app.bpm-management.task.delegationState.pending' : 'yuv.app.bpm-management.task.delegationState.resolved') | translate }}\n </ymt-badge>\n }\n } @else if (definition(); as d) {\n <!-- only global definitions are marked, tenant specific ones are the normal case -->\n @if (d.global) {\n <ymt-badge [outline]=\"true\">\n <mat-icon>{{ icons.globe }}</mat-icon>{{ ProcessDefinitionScope.GLOBAL.label | translate }}\n </ymt-badge>\n }\n <ymt-badge [severity]=\"definitionSeverity(d)\">{{ definitionStatusLabel(d) | translate }}</ymt-badge>\n }\n</ng-template>\n\n<!-- header: one button switches the status of a definition (it offers what is not the case yet); global definitions are shared and cannot be changed, so they get no button -->\n<ng-template #definitionActions>\n @let d = actionDefinition();\n @if (d && !d.global) {\n @let action = d.suspended ? 'activate' : 'suspend';\n @let label = ('yuv.app.bpm-management.definitions.actions.' + action + '.label') | translate;\n <button ymt-icon-button [matTooltip]=\"label\" [attr.aria-label]=\"label\" (click)=\"executeDefinitionAction(action)\">\n <mat-icon>{{ icons[action] }}</mat-icon>\n </button>\n }\n</ng-template>\n\n<!-- header: one button switches a running process between suspended and active; ended processes have no actions -->\n<ng-template #processActions>\n @let p = process();\n @if (p && !p.endTime) {\n @let action = p.suspended ? 'activate' : 'suspend';\n @let label = ('yuv.app.bpm-management.process.actions.' + action + '.label') | translate;\n <button ymt-icon-button [matTooltip]=\"label\" [attr.aria-label]=\"label\" (click)=\"executeProcessAction(action)\">\n <mat-icon>{{ icons[action] }}</mat-icon>\n </button>\n }\n</ng-template>\n\n<!-- header: actions are visible buttons instead of an overflow menu -->\n<ng-template #taskActions>\n @let t = task();\n <!-- completed tasks have no actions -->\n @if (t && !t.endTime) {\n @let assignLabel = 'yuv.app.bpm-management.task.actions.assign.label' | translate;\n @let unassignLabel = 'yuv.app.bpm-management.task.actions.unassign.label' | translate;\n @let candidatesLabel = 'yuv.app.bpm-management.task.actions.editCandidates.label' | translate;\n <button ymt-icon-button [matTooltip]=\"assignLabel\" [attr.aria-label]=\"assignLabel\" (click)=\"assign()\">\n <mat-icon>{{ icons.assign }}</mat-icon>\n </button>\n <button ymt-icon-button [disabled]=\"!t.assignee\" [matTooltip]=\"unassignLabel\" [attr.aria-label]=\"unassignLabel\" (click)=\"unassign()\">\n <mat-icon>{{ icons.unassign }}</mat-icon>\n </button>\n <button ymt-icon-button [matTooltip]=\"candidatesLabel\" [attr.aria-label]=\"candidatesLabel\" (click)=\"editCandidates()\">\n <mat-icon>manage_accounts</mat-icon>\n </button>\n }\n</ng-template>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:block;height:100%}:host .empty-state{display:grid;justify-items:center;align-items:center;align-content:center;gap:var(--ymt-spacing-m);height:100%;padding:0 var(--ymt-spacing-3xl);text-align:center;color:var(--ymt-text-color-subtle)}:host .empty-state-icon{width:var(--ymt-sizing-5xl);height:var(--ymt-sizing-5xl);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container);display:flex;align-items:center;justify-content:center;flex-shrink:0}:host .empty-state-description{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);max-width:32ch;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i10.YmtPaneComponent, selector: "ymt-pane", inputs: ["topBarActions", "busy", "noAnimation", "plain"] }, { kind: "component", type: i10.YmtPaneHeaderComponent, selector: "ymt-pane-header", inputs: ["title", "icon", "subtitle", "actions", "badges"] }, { kind: "component", type: i10.YmtPaneBodyComponent, selector: "ymt-pane-body" }, { kind: "component", type: YmtBadge, selector: "ymt-badge", inputs: ["severity", "outline", "aura"] }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: DeploymentDetailsComponent, selector: "ymbpm-deployment-details", inputs: ["deployment", "canOpenDefinition"], outputs: ["openDefinition"] }, { kind: "component", type: ProcessDefinitionDetailsComponent, selector: "ymbpm-process-definition-details", inputs: ["definition", "canOpenDeployment"], outputs: ["openDeployment", "showProcesses"] }, { kind: "component", type: ProcessDetailsComponent, selector: "ymbpm-process-details", inputs: ["process", "tasks", "canOpenDefinition"], outputs: ["openTask", "openDefinition"] }, { kind: "component", type: TaskDetailsComponent, selector: "ymbpm-task-details", inputs: ["task"], outputs: ["openProcess"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2249
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: DetailsComponent, isStandalone: true, selector: "ymbpm-details", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, detail: { classPropertyName: "detail", publicName: "detail", isSignal: true, isRequired: false, transformFunction: null }, listItem: { classPropertyName: "listItem", publicName: "listItem", isSignal: true, isRequired: false, transformFunction: null }, processTasks: { classPropertyName: "processTasks", publicName: "processTasks", isSignal: true, isRequired: false, transformFunction: null }, busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, selectedId: { classPropertyName: "selectedId", publicName: "selectedId", isSignal: true, isRequired: false, transformFunction: null }, canOpenDefinition: { classPropertyName: "canOpenDefinition", publicName: "canOpenDefinition", isSignal: true, isRequired: false, transformFunction: null }, canOpenDeployment: { classPropertyName: "canOpenDeployment", publicName: "canOpenDeployment", isSignal: true, isRequired: false, transformFunction: null }, topBarActions: { classPropertyName: "topBarActions", publicName: "topBarActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changed: "changed", openItem: "openItem", showProcesses: "showProcesses" }, ngImport: i0, template: "<ymt-pane\n [busy]=\"busy()\"\n [topBarActions]=\"topBarActions()\"\n role=\"region\"\n [attr.aria-label]=\"'yuv.app.bpm-management.details.aria' | translate\"\n>\n <ymt-pane-header\n [icon]=\"headerTitle() ? headerIcon() : undefined\"\n [title]=\"headerTitle()\"\n [subtitle]=\"headerSubtitle()\"\n [badges]=\"detail() ? headerBadges : undefined\"\n [actions]=\"task() ? taskActions : actionDefinition() ? definitionActions : process() ? processActions : undefined\"\n ></ymt-pane-header>\n\n <ymt-pane-body>\n @if (error()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">error_outline</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.details.error' | translate }}</p>\n </div>\n } @else if (deployment(); as deployment) {\n <ymbpm-deployment-details\n [deployment]=\"deployment\"\n [canOpenDefinition]=\"canOpenDefinition()\"\n (openDefinition)=\"openItem.emit({ entity: 'definitions', id: $event })\"\n ></ymbpm-deployment-details>\n } @else if (definition(); as definition) {\n <ymbpm-process-definition-details\n [definition]=\"definition\"\n [canOpenDeployment]=\"canOpenDeployment()\"\n (openDeployment)=\"openItem.emit({ entity: 'deployments', id: $event })\"\n (showProcesses)=\"showProcesses.emit($event)\"\n ></ymbpm-process-definition-details>\n } @else if (process(); as process) {\n <ymbpm-process-details\n [process]=\"process\"\n [tasks]=\"processTasks()\"\n [canOpenDefinition]=\"canOpenDefinition()\"\n (openTask)=\"openItem.emit({ entity: 'tasks', id: $event })\"\n (openDefinition)=\"openItem.emit({ entity: 'definitions', id: $event })\"\n ></ymbpm-process-details>\n } @else if (task(); as task) {\n <ymbpm-task-details\n [task]=\"task\"\n (openProcess)=\"openItem.emit({ entity: 'processes', id: $event })\"\n ></ymbpm-task-details>\n } @else if (!busy() && !selectedId()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">{{ icons.info }}</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </ymt-pane-body>\n</ymt-pane>\n\n<!-- header: status badges -->\n<ng-template #headerBadges>\n @if (process(); as p) {\n <ymt-badge [aura]=\"true\" [severity]=\"processSeverity(p)\"><mat-icon>{{ processStatusIcon(p) }}</mat-icon>{{ processStatusLabel(p) | translate }}</ymt-badge>\n } @else if (task(); as t) {\n <ymt-badge [aura]=\"true\" [severity]=\"taskSeverity(t)\"><mat-icon>{{ taskStatusIcon(t) }}</mat-icon>{{ taskStatusLabel(t) | translate }}</ymt-badge>\n @if (t.delegationState) {\n <ymt-badge [aura]=\"true\" [outline]=\"true\" [severity]=\"t.delegationState === 'pending' ? 'warning' : 'success'\">\n {{ (t.delegationState === 'pending' ? 'yuv.app.bpm-management.task.delegationState.pending' : 'yuv.app.bpm-management.task.delegationState.resolved') | translate }}\n </ymt-badge>\n }\n } @else if (definition(); as d) {\n <!-- the scope, global or private, with the symbol the list row shows -->\n @let scope = definitionScope(d);\n <ymt-badge [outline]=\"true\">\n <mat-icon>{{ icons[scope.icon] }}</mat-icon>{{ scope.label | translate }}\n </ymt-badge>\n <ymt-badge [aura]=\"true\" [severity]=\"definitionSeverity(d)\">{{ definitionStatusLabel(d) | translate }}</ymt-badge>\n }\n</ng-template>\n\n<!-- header: one button switches the status of a definition (it offers what is not the case yet); global definitions are shared and cannot be changed, so they get no button -->\n<ng-template #definitionActions>\n @let d = actionDefinition();\n @let action = d ? actions.definitionAction(d) : undefined;\n @if (d && action) {\n @let label = ('yuv.app.bpm-management.definitions.actions.' + action + '.label') | translate;\n <button ymt-icon-button [matTooltip]=\"label\" [attr.aria-label]=\"label\" (click)=\"run(actions.changeDefinitionStatus(d, action))\">\n <mat-icon>{{ icons[action] }}</mat-icon>\n </button>\n }\n</ng-template>\n\n<!-- header: one button switches a running process between suspended and active; ended processes have no actions -->\n<ng-template #processActions>\n @let p = process();\n @let action = p ? actions.processAction(p) : undefined;\n @if (p && action) {\n @let label = ('yuv.app.bpm-management.process.actions.' + action + '.label') | translate;\n <button ymt-icon-button [matTooltip]=\"label\" [attr.aria-label]=\"label\" (click)=\"run(actions.changeProcessStatus(p, action))\">\n <mat-icon>{{ icons[action] }}</mat-icon>\n </button>\n }\n</ng-template>\n\n<!-- header: actions are visible buttons instead of an overflow menu -->\n<ng-template #taskActions>\n @let t = task();\n @if (t && actions.hasTaskActions(t)) {\n @let assignLabel = 'yuv.app.bpm-management.task.actions.assign.label' | translate;\n @let unassignLabel = 'yuv.app.bpm-management.task.actions.unassign.label' | translate;\n @let candidatesLabel = 'yuv.app.bpm-management.task.actions.editCandidates.label' | translate;\n <button ymt-icon-button [matTooltip]=\"assignLabel\" [attr.aria-label]=\"assignLabel\" (click)=\"run(actions.assignTask(t))\">\n <mat-icon>{{ icons.assign }}</mat-icon>\n </button>\n <button ymt-icon-button [disabled]=\"!actions.canUnassign(t)\" [matTooltip]=\"unassignLabel\" [attr.aria-label]=\"unassignLabel\" (click)=\"run(actions.unassignTask(t))\">\n <mat-icon>{{ icons.unassign }}</mat-icon>\n </button>\n <button ymt-icon-button [matTooltip]=\"candidatesLabel\" [attr.aria-label]=\"candidatesLabel\" (click)=\"run(actions.editTaskCandidates(t))\">\n <mat-icon>{{ icons.editCandidates }}</mat-icon>\n </button>\n }\n</ng-template>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:block;height:100%}:host .empty-state{display:grid;justify-items:center;align-items:center;align-content:center;gap:var(--ymt-spacing-m);height:100%;padding:0 var(--ymt-spacing-3xl);text-align:center;color:var(--ymt-text-color-subtle)}:host .empty-state-icon{width:var(--ymt-sizing-5xl);height:var(--ymt-sizing-5xl);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container);display:flex;align-items:center;justify-content:center;flex-shrink:0}:host .empty-state-description{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);max-width:32ch;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i10.YmtPaneComponent, selector: "ymt-pane", inputs: ["topBarActions", "busy", "noAnimation", "plain"] }, { kind: "component", type: i10.YmtPaneHeaderComponent, selector: "ymt-pane-header", inputs: ["title", "icon", "subtitle", "actions", "badges"] }, { kind: "component", type: i10.YmtPaneBodyComponent, selector: "ymt-pane-body" }, { kind: "component", type: YmtBadge, selector: "ymt-badge", inputs: ["severity", "outline", "aura"] }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: DeploymentDetailsComponent, selector: "ymbpm-deployment-details", inputs: ["deployment", "canOpenDefinition"], outputs: ["openDefinition"] }, { kind: "component", type: ProcessDefinitionDetailsComponent, selector: "ymbpm-process-definition-details", inputs: ["definition", "canOpenDeployment"], outputs: ["openDeployment", "showProcesses"] }, { kind: "component", type: ProcessDetailsComponent, selector: "ymbpm-process-details", inputs: ["process", "tasks", "canOpenDefinition"], outputs: ["openTask", "openDefinition"] }, { kind: "component", type: TaskDetailsComponent, selector: "ymbpm-task-details", inputs: ["task"], outputs: ["openProcess"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2285
2250
  }
2286
2251
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: DetailsComponent, decorators: [{
2287
2252
  type: Component,
@@ -2296,7 +2261,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
2296
2261
  ProcessDefinitionDetailsComponent,
2297
2262
  ProcessDetailsComponent,
2298
2263
  TaskDetailsComponent
2299
- ], template: "<ymt-pane\n [busy]=\"busy()\"\n [topBarActions]=\"topBarActions()\"\n role=\"region\"\n [attr.aria-label]=\"'yuv.app.bpm-management.details.aria' | translate\"\n>\n <ymt-pane-header\n [icon]=\"headerTitle() ? headerIcon() : undefined\"\n [title]=\"headerTitle()\"\n [subtitle]=\"headerSubtitle()\"\n [badges]=\"detail() ? headerBadges : undefined\"\n [actions]=\"task() ? taskActions : actionDefinition() ? definitionActions : process() ? processActions : undefined\"\n ></ymt-pane-header>\n\n <ymt-pane-body>\n @if (error()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">error_outline</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.details.error' | translate }}</p>\n </div>\n } @else if (deployment(); as deployment) {\n <ymbpm-deployment-details\n [deployment]=\"deployment\"\n [canOpenDefinition]=\"canOpenDefinition()\"\n (openDefinition)=\"openItem.emit({ entity: 'definitions', id: $event })\"\n ></ymbpm-deployment-details>\n } @else if (definition(); as definition) {\n <ymbpm-process-definition-details\n [definition]=\"definition\"\n [canOpenDeployment]=\"canOpenDeployment()\"\n (openDeployment)=\"openItem.emit({ entity: 'deployments', id: $event })\"\n (showProcesses)=\"showProcesses.emit($event)\"\n ></ymbpm-process-definition-details>\n } @else if (process(); as process) {\n <ymbpm-process-details\n [process]=\"process\"\n [tasks]=\"processTasks()\"\n [canOpenDefinition]=\"canOpenDefinition()\"\n (openTask)=\"openItem.emit({ entity: 'tasks', id: $event })\"\n (openDefinition)=\"openItem.emit({ entity: 'definitions', id: $event })\"\n ></ymbpm-process-details>\n } @else if (task(); as task) {\n <ymbpm-task-details\n [task]=\"task\"\n (openProcess)=\"openItem.emit({ entity: 'processes', id: $event })\"\n ></ymbpm-task-details>\n } @else if (!busy() && !selectedId()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">{{ icons.info }}</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </ymt-pane-body>\n</ymt-pane>\n\n<!-- header: status badges -->\n<ng-template #headerBadges>\n @if (process(); as p) {\n <ymt-badge [severity]=\"processSeverity(p)\"><mat-icon>{{ processStatusIcon(p) }}</mat-icon>{{ processStatusLabel(p) | translate }}</ymt-badge>\n } @else if (task(); as t) {\n <ymt-badge [severity]=\"taskSeverity(t)\"><mat-icon>{{ taskStatusIcon(t) }}</mat-icon>{{ taskStatusLabel(t) | translate }}</ymt-badge>\n @if (t.delegationState) {\n <ymt-badge [outline]=\"true\" [severity]=\"t.delegationState === 'pending' ? 'warning' : 'success'\">\n {{ (t.delegationState === 'pending' ? 'yuv.app.bpm-management.task.delegationState.pending' : 'yuv.app.bpm-management.task.delegationState.resolved') | translate }}\n </ymt-badge>\n }\n } @else if (definition(); as d) {\n <!-- only global definitions are marked, tenant specific ones are the normal case -->\n @if (d.global) {\n <ymt-badge [outline]=\"true\">\n <mat-icon>{{ icons.globe }}</mat-icon>{{ ProcessDefinitionScope.GLOBAL.label | translate }}\n </ymt-badge>\n }\n <ymt-badge [severity]=\"definitionSeverity(d)\">{{ definitionStatusLabel(d) | translate }}</ymt-badge>\n }\n</ng-template>\n\n<!-- header: one button switches the status of a definition (it offers what is not the case yet); global definitions are shared and cannot be changed, so they get no button -->\n<ng-template #definitionActions>\n @let d = actionDefinition();\n @if (d && !d.global) {\n @let action = d.suspended ? 'activate' : 'suspend';\n @let label = ('yuv.app.bpm-management.definitions.actions.' + action + '.label') | translate;\n <button ymt-icon-button [matTooltip]=\"label\" [attr.aria-label]=\"label\" (click)=\"executeDefinitionAction(action)\">\n <mat-icon>{{ icons[action] }}</mat-icon>\n </button>\n }\n</ng-template>\n\n<!-- header: one button switches a running process between suspended and active; ended processes have no actions -->\n<ng-template #processActions>\n @let p = process();\n @if (p && !p.endTime) {\n @let action = p.suspended ? 'activate' : 'suspend';\n @let label = ('yuv.app.bpm-management.process.actions.' + action + '.label') | translate;\n <button ymt-icon-button [matTooltip]=\"label\" [attr.aria-label]=\"label\" (click)=\"executeProcessAction(action)\">\n <mat-icon>{{ icons[action] }}</mat-icon>\n </button>\n }\n</ng-template>\n\n<!-- header: actions are visible buttons instead of an overflow menu -->\n<ng-template #taskActions>\n @let t = task();\n <!-- completed tasks have no actions -->\n @if (t && !t.endTime) {\n @let assignLabel = 'yuv.app.bpm-management.task.actions.assign.label' | translate;\n @let unassignLabel = 'yuv.app.bpm-management.task.actions.unassign.label' | translate;\n @let candidatesLabel = 'yuv.app.bpm-management.task.actions.editCandidates.label' | translate;\n <button ymt-icon-button [matTooltip]=\"assignLabel\" [attr.aria-label]=\"assignLabel\" (click)=\"assign()\">\n <mat-icon>{{ icons.assign }}</mat-icon>\n </button>\n <button ymt-icon-button [disabled]=\"!t.assignee\" [matTooltip]=\"unassignLabel\" [attr.aria-label]=\"unassignLabel\" (click)=\"unassign()\">\n <mat-icon>{{ icons.unassign }}</mat-icon>\n </button>\n <button ymt-icon-button [matTooltip]=\"candidatesLabel\" [attr.aria-label]=\"candidatesLabel\" (click)=\"editCandidates()\">\n <mat-icon>manage_accounts</mat-icon>\n </button>\n }\n</ng-template>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:block;height:100%}:host .empty-state{display:grid;justify-items:center;align-items:center;align-content:center;gap:var(--ymt-spacing-m);height:100%;padding:0 var(--ymt-spacing-3xl);text-align:center;color:var(--ymt-text-color-subtle)}:host .empty-state-icon{width:var(--ymt-sizing-5xl);height:var(--ymt-sizing-5xl);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container);display:flex;align-items:center;justify-content:center;flex-shrink:0}:host .empty-state-description{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);max-width:32ch;margin:0}\n"] }]
2264
+ ], template: "<ymt-pane\n [busy]=\"busy()\"\n [topBarActions]=\"topBarActions()\"\n role=\"region\"\n [attr.aria-label]=\"'yuv.app.bpm-management.details.aria' | translate\"\n>\n <ymt-pane-header\n [icon]=\"headerTitle() ? headerIcon() : undefined\"\n [title]=\"headerTitle()\"\n [subtitle]=\"headerSubtitle()\"\n [badges]=\"detail() ? headerBadges : undefined\"\n [actions]=\"task() ? taskActions : actionDefinition() ? definitionActions : process() ? processActions : undefined\"\n ></ymt-pane-header>\n\n <ymt-pane-body>\n @if (error()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">error_outline</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.details.error' | translate }}</p>\n </div>\n } @else if (deployment(); as deployment) {\n <ymbpm-deployment-details\n [deployment]=\"deployment\"\n [canOpenDefinition]=\"canOpenDefinition()\"\n (openDefinition)=\"openItem.emit({ entity: 'definitions', id: $event })\"\n ></ymbpm-deployment-details>\n } @else if (definition(); as definition) {\n <ymbpm-process-definition-details\n [definition]=\"definition\"\n [canOpenDeployment]=\"canOpenDeployment()\"\n (openDeployment)=\"openItem.emit({ entity: 'deployments', id: $event })\"\n (showProcesses)=\"showProcesses.emit($event)\"\n ></ymbpm-process-definition-details>\n } @else if (process(); as process) {\n <ymbpm-process-details\n [process]=\"process\"\n [tasks]=\"processTasks()\"\n [canOpenDefinition]=\"canOpenDefinition()\"\n (openTask)=\"openItem.emit({ entity: 'tasks', id: $event })\"\n (openDefinition)=\"openItem.emit({ entity: 'definitions', id: $event })\"\n ></ymbpm-process-details>\n } @else if (task(); as task) {\n <ymbpm-task-details\n [task]=\"task\"\n (openProcess)=\"openItem.emit({ entity: 'processes', id: $event })\"\n ></ymbpm-task-details>\n } @else if (!busy() && !selectedId()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">{{ icons.info }}</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.details.noSelection.label' | translate }}</p>\n </div>\n }\n </ymt-pane-body>\n</ymt-pane>\n\n<!-- header: status badges -->\n<ng-template #headerBadges>\n @if (process(); as p) {\n <ymt-badge [aura]=\"true\" [severity]=\"processSeverity(p)\"><mat-icon>{{ processStatusIcon(p) }}</mat-icon>{{ processStatusLabel(p) | translate }}</ymt-badge>\n } @else if (task(); as t) {\n <ymt-badge [aura]=\"true\" [severity]=\"taskSeverity(t)\"><mat-icon>{{ taskStatusIcon(t) }}</mat-icon>{{ taskStatusLabel(t) | translate }}</ymt-badge>\n @if (t.delegationState) {\n <ymt-badge [aura]=\"true\" [outline]=\"true\" [severity]=\"t.delegationState === 'pending' ? 'warning' : 'success'\">\n {{ (t.delegationState === 'pending' ? 'yuv.app.bpm-management.task.delegationState.pending' : 'yuv.app.bpm-management.task.delegationState.resolved') | translate }}\n </ymt-badge>\n }\n } @else if (definition(); as d) {\n <!-- the scope, global or private, with the symbol the list row shows -->\n @let scope = definitionScope(d);\n <ymt-badge [outline]=\"true\">\n <mat-icon>{{ icons[scope.icon] }}</mat-icon>{{ scope.label | translate }}\n </ymt-badge>\n <ymt-badge [aura]=\"true\" [severity]=\"definitionSeverity(d)\">{{ definitionStatusLabel(d) | translate }}</ymt-badge>\n }\n</ng-template>\n\n<!-- header: one button switches the status of a definition (it offers what is not the case yet); global definitions are shared and cannot be changed, so they get no button -->\n<ng-template #definitionActions>\n @let d = actionDefinition();\n @let action = d ? actions.definitionAction(d) : undefined;\n @if (d && action) {\n @let label = ('yuv.app.bpm-management.definitions.actions.' + action + '.label') | translate;\n <button ymt-icon-button [matTooltip]=\"label\" [attr.aria-label]=\"label\" (click)=\"run(actions.changeDefinitionStatus(d, action))\">\n <mat-icon>{{ icons[action] }}</mat-icon>\n </button>\n }\n</ng-template>\n\n<!-- header: one button switches a running process between suspended and active; ended processes have no actions -->\n<ng-template #processActions>\n @let p = process();\n @let action = p ? actions.processAction(p) : undefined;\n @if (p && action) {\n @let label = ('yuv.app.bpm-management.process.actions.' + action + '.label') | translate;\n <button ymt-icon-button [matTooltip]=\"label\" [attr.aria-label]=\"label\" (click)=\"run(actions.changeProcessStatus(p, action))\">\n <mat-icon>{{ icons[action] }}</mat-icon>\n </button>\n }\n</ng-template>\n\n<!-- header: actions are visible buttons instead of an overflow menu -->\n<ng-template #taskActions>\n @let t = task();\n @if (t && actions.hasTaskActions(t)) {\n @let assignLabel = 'yuv.app.bpm-management.task.actions.assign.label' | translate;\n @let unassignLabel = 'yuv.app.bpm-management.task.actions.unassign.label' | translate;\n @let candidatesLabel = 'yuv.app.bpm-management.task.actions.editCandidates.label' | translate;\n <button ymt-icon-button [matTooltip]=\"assignLabel\" [attr.aria-label]=\"assignLabel\" (click)=\"run(actions.assignTask(t))\">\n <mat-icon>{{ icons.assign }}</mat-icon>\n </button>\n <button ymt-icon-button [disabled]=\"!actions.canUnassign(t)\" [matTooltip]=\"unassignLabel\" [attr.aria-label]=\"unassignLabel\" (click)=\"run(actions.unassignTask(t))\">\n <mat-icon>{{ icons.unassign }}</mat-icon>\n </button>\n <button ymt-icon-button [matTooltip]=\"candidatesLabel\" [attr.aria-label]=\"candidatesLabel\" (click)=\"run(actions.editTaskCandidates(t))\">\n <mat-icon>{{ icons.editCandidates }}</mat-icon>\n </button>\n }\n</ng-template>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}:host{display:block;height:100%}:host .empty-state{display:grid;justify-items:center;align-items:center;align-content:center;gap:var(--ymt-spacing-m);height:100%;padding:0 var(--ymt-spacing-3xl);text-align:center;color:var(--ymt-text-color-subtle)}:host .empty-state-icon{width:var(--ymt-sizing-5xl);height:var(--ymt-sizing-5xl);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container);display:flex;align-items:center;justify-content:center;flex-shrink:0}:host .empty-state-description{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);max-width:32ch;margin:0}\n"] }]
2300
2265
  }], propDecorators: { entity: [{ type: i0.Input, args: [{ isSignal: true, alias: "entity", required: true }] }], detail: [{ type: i0.Input, args: [{ isSignal: true, alias: "detail", required: false }] }], listItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "listItem", required: false }] }], processTasks: [{ type: i0.Input, args: [{ isSignal: true, alias: "processTasks", required: false }] }], busy: [{ type: i0.Input, args: [{ isSignal: true, alias: "busy", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], selectedId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedId", required: false }] }], canOpenDefinition: [{ type: i0.Input, args: [{ isSignal: true, alias: "canOpenDefinition", required: false }] }], canOpenDeployment: [{ type: i0.Input, args: [{ isSignal: true, alias: "canOpenDeployment", required: false }] }], topBarActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "topBarActions", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }], openItem: [{ type: i0.Output, args: ["openItem"] }], showProcesses: [{ type: i0.Output, args: ["showProcesses"] }] } });
2301
2266
 
2302
2267
  /**
@@ -2323,7 +2288,7 @@ class YuvBpmManagementComponent {
2323
2288
  Area = { MASTER: 0, DETAILS: 1 };
2324
2289
  icons = { ...APP_ICONS };
2325
2290
  ENTITY_META = BPM_ENTITY_META;
2326
- ProcessDefinitionScope = ProcessDefinitionScope;
2291
+ definitionScope = definitionScope;
2327
2292
  processSeverity = processSeverity;
2328
2293
  processStatusLabel = processStatusLabel;
2329
2294
  taskSeverity = taskSeverity;
@@ -2339,12 +2304,19 @@ class YuvBpmManagementComponent {
2339
2304
  #logger = inject(Logger);
2340
2305
  #state = inject(BpmManagementStateService);
2341
2306
  #host = inject(ElementRef);
2307
+ #clipboard = inject(Clipboard);
2308
+ #notifications = inject(NotificationService);
2309
+ /** The actions of the row menu (the same the details header offers). */
2310
+ actions = inject(BpmManagementActionsService);
2342
2311
  // the same app may be registered several times, so use the entry this route was loaded through
2343
2312
  #appConfig = resolveAppConfig(this.#route.snapshot);
2344
2313
  #app = this.#shell.getApp(this.#appConfig.appId ?? APP_ID);
2345
2314
  appName = this.#app?.title;
2346
2315
  /** The chips of the active filters; the "add filter" menu of the pane header adds to them. */
2347
2316
  filterBar = viewChild(FilterBarComponent, ...(ngDevMode ? [{ debugName: "filterBar" }] : /* istanbul ignore next */ []));
2317
+ list = viewChild(ListComponent, ...(ngDevMode ? [{ debugName: "list" }] : /* istanbul ignore next */ []));
2318
+ /** The ⋮ of every row, in the order of `items`. */
2319
+ rowMenuTriggers = viewChildren('rowMenuTrigger', { ...(ngDevMode ? { debugName: "rowMenuTriggers" } : /* istanbul ignore next */ {}), read: MatMenuTrigger });
2348
2320
  /** Deployments and process definitions are optional, the host shell client enables them. */
2349
2321
  deploymentsEnabled = isDeploymentsEnabled(this.#route.snapshot);
2350
2322
  definitionsEnabled = isProcessDefinitionsEnabled(this.#route.snapshot);
@@ -2463,6 +2435,36 @@ class YuvBpmManagementComponent {
2463
2435
  this.#navigate(this.entity(), item.id, true);
2464
2436
  }
2465
2437
  }
2438
+ // ---- row menu ------------------------------------------------------------------------------
2439
+ /**
2440
+ * The context menu key or Shift+F10 on the list opens the menu of the active row. They fire on the
2441
+ * list itself (it has the focus, the rows are its active descendants); a right click on a row keeps
2442
+ * the menu of the browser.
2443
+ */
2444
+ onListContextMenu(event) {
2445
+ if (event.target !== event.currentTarget)
2446
+ return;
2447
+ // the selection follows the active row (onItemFocus), so the selected row is the active one
2448
+ const index = this.items().findIndex(i => i.id === this.selectedId());
2449
+ if (index < 0)
2450
+ return;
2451
+ event.preventDefault();
2452
+ this.rowMenuTriggers()[index]?.openMenu();
2453
+ }
2454
+ /** The ⋮ cannot take the focus back (it is not focusable), so it goes back to the list. */
2455
+ onRowMenuClosed() {
2456
+ if (!this.#host.nativeElement.contains(document.activeElement))
2457
+ this.list()?.focus();
2458
+ }
2459
+ /** Runs an action of the row menu: reloads what it changed, then the focus returns to the list. */
2460
+ runAction(action) {
2461
+ action.pipe(finalize(() => setTimeout(() => this.list()?.focus()))).subscribe(scope => this.onDetailsChanged(scope));
2462
+ }
2463
+ copyId(id) {
2464
+ if (this.#clipboard.copy(id)) {
2465
+ this.#notifications.success(this.#translate.instant('yuv.app.bpm-management.list.actions.copyId.success'));
2466
+ }
2467
+ }
2466
2468
  switchEntity(entity) {
2467
2469
  if (entity !== this.entity()) {
2468
2470
  this.#navigate(entity, null);
@@ -2689,7 +2691,7 @@ class YuvBpmManagementComponent {
2689
2691
  ]
2690
2692
  };
2691
2693
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: YuvBpmManagementComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2692
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: YuvBpmManagementComponent, isStandalone: true, selector: "ymbpm-root", viewQueries: [{ propertyName: "filterBar", first: true, predicate: FilterBarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- the entity switch lives in the shell's app header -->\n<ng-template yuvAppHeaderSlot=\"actions\">\n <ymbpm-entity-switch [entities]=\"availableEntities\" [value]=\"entity()\" (valueChange)=\"switchEntity($event)\" />\n</ng-template>\n\n<!-- search lives in the shell's app header -->\n<ng-template yuvAppHeaderSlot=\"search\">\n <yuv-simple-search [query]=\"searchQuery()\" (querySubmit)=\"onQueryChange($event)\" (clearInput)=\"onQueryChange({ term: '' })\"></yuv-simple-search>\n</ng-template>\n\n<!-- A named region, not <main>: the shell already wraps the routed app in its own main landmark. -->\n<div role=\"region\" class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n @if (!split.isAreaVisible(Area.MASTER)) {\n <ymbpm-pane-gutter\n icon=\"left_panel_open\"\n [flipLabel]=\"true\"\n [label]=\"ENTITY_META[entity()].label | translate\"\n [tooltip]=\"'yuv.app.bpm-management.pane.showList.tooltip' | translate\"\n (expand)=\"split.showArea(Area.MASTER)\" />\n }\n\n <yuv-split-view #split [layoutSettingsID]=\"layoutSettingsID\" class=\"content-split\">\n\n <!-- ===================================== MASTER ===================================== -->\n <ng-template yuvSplitArea [size]=\"61.8\">\n <ymt-pane [busy]=\"busy()\" [topBarActions]=\"masterActions\" role=\"region\" [attr.aria-label]=\"ENTITY_META[entity()].label | translate\">\n <ymt-pane-header\n [icon]=\"ENTITY_META[entity()].icon\"\n [title]=\"ENTITY_META[entity()].label | translate\"\n [actions]=\"listActions\"\n ></ymt-pane-header>\n\n <ymt-pane-body class=\"list-body\">\n <ymbpm-filter-bar\n [columns]=\"filterColumns()\"\n [filters]=\"view().advanced\"\n [search]=\"searchTerm()\"\n (filtersChange)=\"onAdvancedFilters($event)\"\n (searchClear)=\"onQueryChange({ term: '' })\" />\n @if (items().length === 0 && !busy()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">search_off</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.list.empty' | translate }}</p>\n @if (hasActiveFilters()) {\n <button ymtButton=\"secondary\" (click)=\"clearFilters()\">{{ 'yuv.app.bpm-management.filters.clearAll' | translate }}</button>\n }\n </div>\n } @else {\n <yuv-list class=\"items\" [attr.aria-label]=\"ENTITY_META[entity()].label | translate\" [externalSelectionVisuals]=\"true\" (itemFocus)=\"onItemFocus($event)\">\n @for (item of items(); track item.id) {\n <div yuvListItem role=\"option\" class=\"item\" [attr.data-item-id]=\"item.id\" [class.item--suspended]=\"isSuspended(item)\" [selected]=\"item.id === selectedId()\">\n @switch (entity()) {\n @case ('deployments') {\n @let d = asDeployment(item);\n <mat-icon class=\"item__icon\" aria-hidden=\"true\">{{ ENTITY_META.deployments.itemIcon }}</mat-icon>\n <div class=\"item__main\">\n <span class=\"item__title\">{{ d.name || '&lt;unnamed&gt;' }}</span>\n </div>\n <span class=\"item__time\">{{ d.deploymentTime | formatDateTime }}</span>\n }\n @case ('definitions') {\n @let pd = asDefinition(item);\n @let definitionStatus = definitionStatusLabel(pd) | translate;\n <span class=\"item__marker\" role=\"img\" [attr.data-severity]=\"definitionSeverity(pd)\" [matTooltip]=\"definitionStatus\" matTooltipPosition=\"right\" [attr.aria-label]=\"definitionStatus\"></span>\n <div class=\"item__main\">\n <span class=\"item__heading item__heading--split\">\n <span class=\"item__title\">{{ pd.name || '&lt;unnamed&gt;' }}</span>\n <!-- only global definitions are marked, tenant specific ones are the normal case -->\n @if (pd.global) {\n <ymt-badge class=\"item__scope\" [outline]=\"true\">\n <mat-icon>{{ icons.globe }}</mat-icon>{{ ProcessDefinitionScope.GLOBAL.label | translate }}\n </ymt-badge>\n }\n </span>\n <span class=\"item__meta\">\n <span class=\"item__key\"><mat-icon>key</mat-icon><span class=\"item__key-text\" [title]=\"pd.key\">{{ pd.key }}</span></span>\n <span class=\"item__version\"><mat-icon>layers</mat-icon>v{{ pd.version }}</span>\n <!-- always rendered, so key and category keep their equal columns -->\n <span class=\"item__category\">\n @if (pd.category) {\n <mat-icon>category</mat-icon><span class=\"item__key-text\" [title]=\"pd.category\">{{ pd.category }}</span>\n }\n </span>\n </span>\n </div>\n }\n @case ('processes') {\n @let p = asProcess(item);\n @let statusLabel = processStatusLabel(p) | translate;\n <span class=\"item__marker\" role=\"img\" [attr.data-severity]=\"processSeverity(p)\" [matTooltip]=\"statusLabel\" matTooltipPosition=\"right\" [attr.aria-label]=\"statusLabel\"></span>\n <div class=\"item__main\">\n <span class=\"item__heading item__heading--split\">\n <span class=\"item__title\">{{ p.name || '&lt;unnamed&gt;' }}</span>\n <ymt-badge class=\"item__definition\" [outline]=\"true\" [title]=\"p.processDefinitionName || ''\">\n <mat-icon>{{ ENTITY_META.definitions.itemIcon }}</mat-icon><span class=\"item__key-text\">{{ p.processDefinitionName || '-' }}</span>\n </ymt-badge>\n </span>\n <span class=\"item__meta item__meta--process\">\n <span class=\"item__started\">\n <mat-icon>schedule</mat-icon>{{ p.startTime | formatDateTime }}\n <span class=\"item__started-by\">{{ 'yuv.app.bpm-management.process.startedByShort' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"p.startUserId ?? null\"></yuv-organization-renderer>\n </span>\n @if (p.businessKey) {\n <span class=\"item__business-key\">\n <mat-icon>tag</mat-icon><span class=\"item__key-text\" [title]=\"p.businessKey\">{{ p.businessKey }}</span>\n </span>\n }\n @if (p.endTime) {\n <span class=\"item__ended\"><mat-icon>flag</mat-icon>{{ p.endTime | formatDateTime }}</span>\n }\n </span>\n </div>\n }\n @case ('tasks') {\n @let t = asTask(item);\n @let taskStatus = taskStatusLabel(t) | translate;\n <span class=\"item__marker\" role=\"img\" [attr.data-severity]=\"taskSeverity(t)\" [matTooltip]=\"taskStatus\" matTooltipPosition=\"right\" [attr.aria-label]=\"taskStatus\"></span>\n <div class=\"item__main\">\n <span class=\"item__title\">{{ t.name || '&lt;unnamed&gt;' }}</span>\n <span class=\"item__meta item__meta--slots item__meta--task\">\n <span class=\"item__started\">\n <mat-icon>schedule</mat-icon>{{ t.createTime | formatDateTime }}\n <yuv-organization-renderer propertyName=\"user\" [value]=\"t.assignee ?? null\"></yuv-organization-renderer>\n </span>\n <span>\n <mat-icon>{{ ENTITY_META.processes.itemIcon }}</mat-icon><span class=\"item__key-text\" [title]=\"t.processInstanceName || ''\">{{ t.processInstanceName || '-' }}</span>\n </span>\n <span>\n @if (t.endTime) {\n <mat-icon>flag</mat-icon>{{ t.endTime | formatDateTime }}\n }\n </span>\n </span>\n </div>\n }\n }\n </div>\n }\n </yuv-list>\n }\n </ymt-pane-body>\n\n <ymt-pane-footer>\n <mat-paginator class=\"paginator\"\n [length]=\"total()\"\n [pageIndex]=\"view().page\"\n [pageSize]=\"view().pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [attr.aria-label]=\"'yuv.app.bpm-management.pagination.aria' | translate\"\n (page)=\"onChangePage($event)\">\n </mat-paginator>\n </ymt-pane-footer>\n\n </ymt-pane>\n </ng-template>\n\n <!-- ===================================== DETAILS ==================================== -->\n <ng-template yuvSplitArea [size]=\"38.2\">\n <ymbpm-details\n [entity]=\"entity()\"\n [detail]=\"detail()\"\n [listItem]=\"selectedItem()\"\n [processTasks]=\"processTasks()\"\n [busy]=\"detailsBusy()\"\n [error]=\"detailsError()\"\n [selectedId]=\"selectedId()\"\n [canOpenDefinition]=\"definitionsEnabled\"\n [canOpenDeployment]=\"deploymentsEnabled\"\n [topBarActions]=\"detailsTopBarActions\"\n (changed)=\"onDetailsChanged($event)\"\n (openItem)=\"openItem($event.entity, $event.id)\"\n (showProcesses)=\"showProcessesOfDefinition($event)\" ></ymbpm-details>\n </ng-template>\n </yuv-split-view>\n\n @if (!split.isAreaVisible(Area.DETAILS)) {\n <ymbpm-pane-gutter\n icon=\"right_panel_open\"\n [label]=\"'yuv.app.bpm-management.details.aria' | translate\"\n [tooltip]=\"'yuv.app.bpm-management.pane.showDetails.tooltip' | translate\"\n (expand)=\"split.showArea(Area.DETAILS)\" />\n }\n</div>\n\n<!-- master header: filter panel toggle -->\n<ng-template #listActions>\n @if (quickFilters().length) {\n <mat-button-toggle-group class=\"quick-toggle\" [value]=\"view().quick\" (change)=\"onQuick($event.value)\"\n [attr.aria-label]=\"'yuv.app.bpm-management.statusFilter.aria' | translate\">\n @for (quick of quickFilters(); track quick.value) {\n <mat-button-toggle [value]=\"quick.value\">{{ quick.label | translate }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n }\n @let bar = filterBar();\n @let addable = bar?.addableColumns() ?? [];\n <button ymt-icon-button #addFilter\n [matMenuTriggerFor]=\"addFilterMenu\"\n [matMenuTriggerRestoreFocus]=\"false\"\n [disabled]=\"!addable.length && !showLatestOnly()\"\n [matTooltip]=\"'yuv.app.bpm-management.filters.add' | translate\"\n [attr.aria-label]=\"'yuv.app.bpm-management.filters.add' | translate\">\n <mat-icon>filter_list</mat-icon>\n </button>\n <mat-menu #addFilterMenu=\"matMenu\">\n @for (column of addable; track column.name) {\n <button mat-menu-item (click)=\"bar?.edit(column, addFilter)\">{{ column.displayName | translate }}</button>\n }\n @if (showLatestOnly()) {\n @if (addable.length) {\n <mat-divider></mat-divider>\n }\n <button mat-menu-item role=\"menuitemcheckbox\" [attr.aria-checked]=\"view().latestOnly\" (click)=\"toggleLatestOnly()\">\n <mat-icon>{{ view().latestOnly ? 'check' : '' }}</mat-icon>{{ 'yuv.app.bpm-management.definitions.filter.onlyLatest' | translate }}\n </button>\n }\n </mat-menu>\n @if (sortFields().length) {\n <button ymt-icon-button\n [matMenuTriggerFor]=\"sortMenu\"\n [matTooltip]=\"'yuv.sort.tooltip' | translate\"\n [attr.aria-label]=\"'yuv.sort.tooltip' | translate\">\n <mat-icon>swap_vert</mat-icon>\n </button>\n <mat-menu #sortMenu=\"matMenu\">\n @for (field of sortFields(); track field.value) {\n <button mat-menu-item class=\"radio-item\" role=\"menuitemradio\" [attr.aria-checked]=\"view().sortBy === field.value\" (click)=\"patchView({ sortBy: field.value })\">\n <mat-icon>{{ view().sortBy === field.value ? icons.radioButtonChecked : '' }}</mat-icon>{{ field.label | translate }}\n </button>\n }\n <mat-divider></mat-divider>\n @for (order of sortOrders; track order.value) {\n <button mat-menu-item class=\"radio-item\" role=\"menuitemradio\" [attr.aria-checked]=\"view().sortOrder === order.value\" (click)=\"patchView({ sortOrder: order.value })\">\n <mat-icon>{{ view().sortOrder === order.value ? icons.radioButtonChecked : '' }}</mat-icon>{{ order.label | translate }}\n </button>\n }\n </mat-menu>\n }\n</ng-template>\n\n<!-- list pane top bar: hides the list (right aligned, next to the gutter it collapses into) -->\n<ng-template #masterActions>\n <ymbpm-pane-toggle-button\n icon=\"left_panel_close\"\n [tooltip]=\"'yuv.app.bpm-management.pane.hideList.tooltip' | translate\"\n (toggled)=\"split.hideArea(Area.MASTER)\" />\n</ng-template>\n\n<!-- details pane top bar: hides the details (left aligned, next to the gutter it collapses into) -->\n<ng-template #detailsTopBarActions>\n <ymbpm-pane-toggle-button\n align=\"start\"\n icon=\"right_panel_close\"\n [tooltip]=\"'yuv.app.bpm-management.pane.hideDetails.tooltip' | translate\"\n (toggled)=\"split.hideArea(Area.DETAILS)\" />\n</ng-template>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}.mat-mdc-menu-item[aria-checked=true]{background:var(--ymt-primary-container);--mat-menu-item-label-text-color: var(--ymt-on-primary-container);--mat-menu-item-icon-color: var(--ymt-on-primary-container)}.mat-mdc-menu-item.radio-item[aria-checked=true]{background:none;--mat-menu-item-label-text-color: unset;--mat-menu-item-icon-color: unset}.mat-mdc-menu-item.radio-item[aria-checked=true] .mat-icon{scale:.5}:host{display:flex;flex-flow:column;height:100%;overflow:hidden}:host .bpmmgmt-main__content{flex:1;min-height:0;display:flex;flex-flow:row;overflow:hidden;gap:var(--ymt-spacing-s);padding:var(--ymt-spacing-m)}:host .content-split{flex:1;min-width:0}:host ymt-pane-footer{--footer-block-padding: 0;--footer-inline-padding: 0}:host .paginator{flex:1;background:transparent}:host .quick-toggle{--mat-button-toggle-height: 32px;--mat-button-toggle-shape: 999px;--mat-button-toggle-divider-color: transparent;--mat-button-toggle-background-color: var(--ymt-surface-container-high);--mat-button-toggle-selected-state-background-color: var(--ymt-primary-container);--mat-button-toggle-selected-state-text-color: var(--ymt-on-primary-container);border-color:transparent}:host .items{display:block}:host .item{position:relative;display:flex;align-items:center;gap:var(--ymt-spacing-s);padding:var(--ymt-spacing-xs) var(--ymt-spacing-m);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant);cursor:pointer}:host .item:hover:not(.selected){background-color:var(--ymt-hover-background)}:host .item.selected{background-color:var(--ymt-selection-background);color:var(--ymt-on-selection-background)}:host .item.item--suspended:not(.selected){color:var(--ymt-text-color-subtle)}:host .items:focus-visible .item[aria-current=true]{outline:var(--ymt-focus-indicator-size) solid var(--ymt-primary);outline-offset:calc(-1 * var(--ymt-focus-indicator-size))}:host .items:focus-within .item.selected{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}:host .items:focus-within .item.selected .item__meta{color:var(--ymt-on-primary-container)}:host .item__marker{position:absolute;inset-block:var(--ymt-spacing-xs);inset-inline-start:var(--ymt-spacing-2xs);width:var(--ymt-spacing-2xs);border-radius:var(--ymt-spacing-2xs);background-color:var(--ymt-surface-container-highest)}:host .item__marker[data-severity=primary]{background-color:var(--ymt-primary-container)}:host .item__marker[data-severity=success]{background-color:var(--ymt-success-container)}:host .item__marker[data-severity=warning]{background-color:var(--ymt-warning-container)}:host .item__main{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--ymt-spacing-xs)}:host .item__time{flex:none;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);font-variant-numeric:tabular-nums}:host .item__title{font:var(--ymt-font-title-smallest);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .item__heading{display:flex;align-items:center;gap:var(--ymt-spacing-xs);min-width:0}:host .item__heading--split{justify-content:space-between}:host .item__heading--split .item__title{min-width:0}:host .item__definition{flex:0 1 auto;min-width:0;max-width:50%}:host .item__meta>.item__version,:host .item__meta>.item__key,:host .item__meta>.item__category{flex:1 1 8rem;min-width:0;white-space:nowrap}:host .item__meta>.item__version mat-icon,:host .item__meta>.item__key mat-icon,:host .item__meta>.item__category mat-icon{flex:none}:host .item__key-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .item__icon{flex:none;width:var(--ymt-sizing-m);height:var(--ymt-sizing-m);font-size:var(--ymt-sizing-m);color:var(--ymt-text-color-subtle)}:host .item__scope{flex:none;white-space:nowrap}:host .item__scope mat-icon{width:1em;height:1em;font-size:1em;line-height:1}:host .item__meta{display:flex;flex-wrap:wrap;gap:0 var(--ymt-spacing-m);font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}:host .item__meta>span{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs)}:host .item__meta mat-icon{font-size:var(--ymt-sizing-xs);width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs)}:host .item__meta--slots{display:grid;gap:0 var(--ymt-spacing-m)}:host .item__meta--slots>span{min-width:0;overflow:hidden;white-space:nowrap}:host .item__meta--slots mat-icon{flex:none}:host .item__meta--process{flex-wrap:nowrap}:host .item__meta--process>span{min-width:0;white-space:nowrap}:host .item__meta--process mat-icon{flex:none}:host .item__started{flex:1 1 auto;overflow:hidden}:host .item__started yuv-organization-renderer{min-width:0}:host .item__started yuv-organization-renderer ::ng-deep .node{border:0;padding:0;overflow:hidden;text-overflow:ellipsis}:host .item__business-key{flex:0 1 auto;max-width:12rem;overflow:hidden}:host .item__ended{flex:none;margin-inline-start:auto}:host .item__meta--task{grid-template-columns:minmax(0,1.5fr) minmax(0,1fr) 10rem}:host .item__meta--task>span:last-child{justify-content:flex-end}:host .list-body{display:flex;flex-flow:column}:host .empty-state{display:grid;justify-items:center;align-items:center;align-content:center;gap:var(--ymt-spacing-m);height:100%;padding:0 var(--ymt-spacing-3xl);text-align:center;color:var(--ymt-text-color-subtle);flex:1;min-height:0;height:auto}:host .empty-state-icon{width:var(--ymt-sizing-5xl);height:var(--ymt-sizing-5xl);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container);display:flex;align-items:center;justify-content:center;flex-shrink:0}:host .empty-state-description{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);max-width:32ch;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i2$3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { 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: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: YuvClientShellModule }, { kind: "directive", type: i7.YuvAppHeaderSlotDirective, selector: "ng-template[yuvAppHeaderSlot]", inputs: ["yuvAppHeaderSlot"] }, { kind: "component", type: SimpleSearchComponent, selector: "yuv-simple-search", inputs: ["query"], outputs: ["querySubmit", "clearInput", "targetSelectionChanged", "queryChange", "typeAggregation"] }, { kind: "ngmodule", type: YuvListModule }, { kind: "component", type: i8.ListComponent, selector: "yuv-list", inputs: ["preventChangeUntil", "multiselect", "selfHandleSelection", "externalSelectionVisuals", "selfHandleClick", "autoSelect", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: i8.ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "ngmodule", type: YuvSplitViewModule }, { kind: "directive", type: i9.SplitAreaDirective, selector: "[yuvSplitArea]", inputs: ["size", "minSize", "maxSize", "panelClass", "visible", "lockSize"] }, { kind: "component", type: i9.SplitViewComponent, selector: "yuv-split-view", inputs: ["direction", "gutterSize", "restrictMove", "disabled", "layoutSettingsID"], outputs: ["layoutSettingsChange", "dragStart", "dragEnd", "gutterClick", "gutterDblClick"] }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i10.YmtPaneComponent, selector: "ymt-pane", inputs: ["topBarActions", "busy", "noAnimation", "plain"] }, { kind: "component", type: i10.YmtPaneHeaderComponent, selector: "ymt-pane-header", inputs: ["title", "icon", "subtitle", "actions", "badges"] }, { kind: "component", type: i10.YmtPaneBodyComponent, selector: "ymt-pane-body" }, { kind: "component", type: i10.YmtPaneFooterComponent, selector: "ymt-pane-footer" }, { kind: "component", type: YmtBadge, selector: "ymt-badge", inputs: ["severity", "outline", "aura"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "component", type: OrganizationRendererComponent, selector: "yuv-organization-renderer" }, { kind: "component", type: PaneGutterComponent, selector: "ymbpm-pane-gutter", inputs: ["icon", "label", "tooltip", "flipLabel"], outputs: ["expand"] }, { kind: "component", type: PaneToggleButtonComponent, selector: "ymbpm-pane-toggle-button", inputs: ["icon", "tooltip"], outputs: ["toggled"] }, { kind: "component", type: EntitySwitchComponent, selector: "ymbpm-entity-switch", inputs: ["entities", "value"], outputs: ["valueChange"] }, { kind: "component", type: FilterBarComponent, selector: "ymbpm-filter-bar", inputs: ["columns", "filters", "search"], outputs: ["filtersChange", "searchClear"] }, { kind: "component", type: DetailsComponent, selector: "ymbpm-details", inputs: ["entity", "detail", "listItem", "processTasks", "busy", "error", "selectedId", "canOpenDefinition", "canOpenDeployment", "topBarActions"], outputs: ["changed", "openItem", "showProcesses"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }] });
2694
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: YuvBpmManagementComponent, isStandalone: true, selector: "ymbpm-root", viewQueries: [{ propertyName: "filterBar", first: true, predicate: FilterBarComponent, descendants: true, isSignal: true }, { propertyName: "list", first: true, predicate: ListComponent, descendants: true, isSignal: true }, { propertyName: "rowMenuTriggers", predicate: ["rowMenuTrigger"], descendants: true, read: MatMenuTrigger, isSignal: true }], ngImport: i0, template: "<!-- the entity switch lives in the shell's app header -->\n<ng-template yuvAppHeaderSlot=\"actions\">\n <ymbpm-entity-switch [entities]=\"availableEntities\" [value]=\"entity()\" (valueChange)=\"switchEntity($event)\" />\n</ng-template>\n\n<!-- search lives in the shell's app header -->\n<ng-template yuvAppHeaderSlot=\"search\">\n <yuv-simple-search [query]=\"searchQuery()\" (querySubmit)=\"onQueryChange($event)\" (clearInput)=\"onQueryChange({ term: '' })\"></yuv-simple-search>\n</ng-template>\n\n<!-- A named region, not <main>: the shell already wraps the routed app in its own main landmark. -->\n<div role=\"region\" class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n @if (!split.isAreaVisible(Area.MASTER)) {\n <ymbpm-pane-gutter\n icon=\"left_panel_open\"\n [flipLabel]=\"true\"\n [label]=\"ENTITY_META[entity()].label | translate\"\n [tooltip]=\"'yuv.app.bpm-management.pane.showList.tooltip' | translate\"\n (expand)=\"split.showArea(Area.MASTER)\" />\n }\n\n <yuv-split-view #split [layoutSettingsID]=\"layoutSettingsID\" class=\"content-split\">\n\n <!-- ===================================== MASTER ===================================== -->\n <ng-template yuvSplitArea [size]=\"61.8\">\n <ymt-pane [busy]=\"busy()\" [topBarActions]=\"masterActions\" role=\"region\" [attr.aria-label]=\"ENTITY_META[entity()].label | translate\">\n <ymt-pane-header\n [icon]=\"ENTITY_META[entity()].icon\"\n [title]=\"ENTITY_META[entity()].label | translate\"\n [actions]=\"listActions\"\n ></ymt-pane-header>\n\n <ymt-pane-body class=\"list-body\">\n <ymbpm-filter-bar\n [columns]=\"filterColumns()\"\n [filters]=\"view().advanced\"\n [search]=\"searchTerm()\"\n (filtersChange)=\"onAdvancedFilters($event)\"\n (searchClear)=\"onQueryChange({ term: '' })\" />\n @if (items().length === 0 && !busy()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">search_off</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.list.empty' | translate }}</p>\n @if (hasActiveFilters()) {\n <button ymtButton=\"secondary\" (click)=\"clearFilters()\">{{ 'yuv.app.bpm-management.filters.clearAll' | translate }}</button>\n }\n </div>\n } @else {\n <!-- Shift+F10 / the context menu key open the actions of the active row (its \u22EE is for the pointer only, see .item__menu) -->\n <yuv-list class=\"items\" [attr.aria-label]=\"ENTITY_META[entity()].label | translate\" aria-keyshortcuts=\"Shift+F10\" [externalSelectionVisuals]=\"true\"\n (itemFocus)=\"onItemFocus($event)\" (contextmenu)=\"onListContextMenu($event)\">\n @for (item of items(); track item.id) {\n <!-- [title] / meta \u00B7 meta | state badge | \u22EE -->\n <!-- aria-selected comes from the yuvListItem host binding (from [selected]), which the rule cannot see -->\n <!-- eslint-disable-next-line @angular-eslint/template/role-has-required-aria -->\n <div yuvListItem role=\"option\" class=\"item\" [attr.data-item-id]=\"item.id\" [class.item--suspended]=\"isSuspended(item)\" [selected]=\"item.id === selectedId()\">\n @switch (entity()) {\n @case ('deployments') {\n @let d = asDeployment(item);\n <div class=\"item__body\">\n <div class=\"item__title\"><span>{{ d.name || '&lt;unnamed&gt;' }}</span></div>\n <div class=\"item__meta\">\n <span>{{ d.deploymentTime | formatDateTime }}</span>\n </div>\n <div class=\"item__meta\">\n @if (d.category) {\n <span [title]=\"d.category\">{{ d.category }}</span>\n }\n </div>\n </div>\n }\n @case ('definitions') {\n @let pd = asDefinition(item);\n <div class=\"item__body\">\n <div class=\"item__title\"><span>{{ pd.name || '&lt;unnamed&gt;' }}</span></div>\n <div class=\"item__meta\">\n @if (pd.category) {\n <span [title]=\"pd.category\">{{ pd.category }}</span>\n }\n </div>\n <div class=\"item__meta\">\n <!-- the scope is only a symbol; it carries information, so it is an image with a name, not decoration -->\n @let scope = definitionScope(pd);\n @let scopeLabel = scope.label | translate;\n <span class=\"item__iconed\">\n <mat-icon role=\"img\" aria-hidden=\"false\" [attr.aria-label]=\"scopeLabel\" [matTooltip]=\"scopeLabel\">{{ icons[scope.icon] }}</mat-icon>v{{ pd.version }}\n </span>\n <span [title]=\"pd.key\">{{ pd.key }}</span>\n </div>\n </div>\n <div class=\"item__chips\">\n <ymt-badge class=\"item__state\" [aura]=\"true\" [severity]=\"definitionSeverity(pd)\">{{ definitionStatusLabel(pd) | translate }}</ymt-badge>\n </div>\n }\n @case ('processes') {\n @let p = asProcess(item);\n <div class=\"item__body\">\n <div class=\"item__title\"><span>{{ p.name || '&lt;unnamed&gt;' }}</span></div>\n <div class=\"item__meta\">\n <span [title]=\"p.processDefinitionName || ''\">{{ p.processDefinitionName || '-' }}</span>\n </div>\n <div class=\"item__meta\">\n <span class=\"item__iconed\"><mat-icon>schedule</mat-icon>{{ p.startTime | formatDateTime }}</span>\n <span class=\"item__user\"><yuv-organization-renderer propertyName=\"user\" [value]=\"p.startUserId ?? null\"></yuv-organization-renderer></span>\n @if (p.endTime) {\n <span class=\"item__iconed item__ended\"><mat-icon>flag</mat-icon>{{ p.endTime | formatDateTime }}</span>\n }\n </div>\n </div>\n <div class=\"item__chips\">\n <ymt-badge class=\"item__state\" [aura]=\"true\" [severity]=\"processSeverity(p)\">{{ processStatusLabel(p) | translate }}</ymt-badge>\n </div>\n }\n @case ('tasks') {\n @let t = asTask(item);\n <div class=\"item__body\">\n <div class=\"item__title\"><span>{{ t.name || '&lt;unnamed&gt;' }}</span></div>\n <div class=\"item__meta\">\n <span [title]=\"t.processInstanceName || ''\">{{ t.processInstanceName || '-' }}</span>\n </div>\n <div class=\"item__meta\">\n <span class=\"item__iconed\"><mat-icon>schedule</mat-icon>{{ t.createTime | formatDateTime }}</span>\n @if (t.assignee) {\n <span class=\"item__user\"><yuv-organization-renderer propertyName=\"user\" [value]=\"t.assignee\"></yuv-organization-renderer></span>\n }\n @if (t.endTime) {\n <span class=\"item__iconed item__ended\"><mat-icon>flag</mat-icon>{{ t.endTime | formatDateTime }}</span>\n }\n </div>\n </div>\n <div class=\"item__chips\">\n <ymt-badge class=\"item__state\" [aura]=\"true\" [severity]=\"taskSeverity(t)\">{{ taskStatusLabel(t) | translate }}</ymt-badge>\n </div>\n }\n }\n <!-- Not a button: a focusable element inside role=\"option\" is a nested-interactive violation (yuv-list\n even sets tabindex=\"-1\" on it). Pointer users click it, the keyboard opens the same menu with\n Shift+F10 on the list; the click also selects the row, so the menu visibly applies to it. -->\n <span class=\"item__menu\" aria-hidden=\"true\" #rowMenuTrigger=\"matMenuTrigger\"\n [matMenuTriggerFor]=\"rowMenu\" [matMenuTriggerData]=\"{ item }\" (menuClosed)=\"onRowMenuClosed()\"\n [matTooltip]=\"'yuv.app.bpm-management.list.actions.label' | translate\">\n <mat-icon>more_vert</mat-icon>\n </span>\n </div>\n }\n </yuv-list>\n }\n </ymt-pane-body>\n\n <ymt-pane-footer>\n <mat-paginator class=\"paginator\"\n [length]=\"total()\"\n [pageIndex]=\"view().page\"\n [pageSize]=\"view().pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [attr.aria-label]=\"'yuv.app.bpm-management.pagination.aria' | translate\"\n (page)=\"onChangePage($event)\">\n </mat-paginator>\n </ymt-pane-footer>\n\n </ymt-pane>\n </ng-template>\n\n <!-- ===================================== DETAILS ==================================== -->\n <ng-template yuvSplitArea [size]=\"38.2\">\n <ymbpm-details\n [entity]=\"entity()\"\n [detail]=\"detail()\"\n [listItem]=\"selectedItem()\"\n [processTasks]=\"processTasks()\"\n [busy]=\"detailsBusy()\"\n [error]=\"detailsError()\"\n [selectedId]=\"selectedId()\"\n [canOpenDefinition]=\"definitionsEnabled\"\n [canOpenDeployment]=\"deploymentsEnabled\"\n [topBarActions]=\"detailsTopBarActions\"\n (changed)=\"onDetailsChanged($event)\"\n (openItem)=\"openItem($event.entity, $event.id)\"\n (showProcesses)=\"showProcessesOfDefinition($event)\" ></ymbpm-details>\n </ng-template>\n </yuv-split-view>\n\n @if (!split.isAreaVisible(Area.DETAILS)) {\n <ymbpm-pane-gutter\n icon=\"right_panel_open\"\n [label]=\"'yuv.app.bpm-management.details.aria' | translate\"\n [tooltip]=\"'yuv.app.bpm-management.pane.showDetails.tooltip' | translate\"\n (expand)=\"split.showArea(Area.DETAILS)\" />\n }\n</div>\n\n<!-- master header: filter panel toggle -->\n<ng-template #listActions>\n @if (quickFilters().length) {\n <mat-button-toggle-group class=\"quick-toggle\" [value]=\"view().quick\" (change)=\"onQuick($event.value)\"\n [attr.aria-label]=\"'yuv.app.bpm-management.statusFilter.aria' | translate\">\n @for (quick of quickFilters(); track quick.value) {\n <mat-button-toggle [value]=\"quick.value\">{{ quick.label | translate }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n }\n @let bar = filterBar();\n @let addable = bar?.addableColumns() ?? [];\n <button ymt-icon-button #addFilter\n [matMenuTriggerFor]=\"addFilterMenu\"\n [matMenuTriggerRestoreFocus]=\"false\"\n [disabled]=\"!addable.length && !showLatestOnly()\"\n [matTooltip]=\"'yuv.app.bpm-management.filters.add' | translate\"\n [attr.aria-label]=\"'yuv.app.bpm-management.filters.add' | translate\">\n <mat-icon>filter_list</mat-icon>\n </button>\n <mat-menu #addFilterMenu=\"matMenu\">\n @for (column of addable; track column.name) {\n <button mat-menu-item (click)=\"bar?.edit(column, addFilter)\">{{ column.displayName | translate }}</button>\n }\n @if (showLatestOnly()) {\n @if (addable.length) {\n <mat-divider></mat-divider>\n }\n <button mat-menu-item role=\"menuitemcheckbox\" [attr.aria-checked]=\"view().latestOnly\" (click)=\"toggleLatestOnly()\">\n <mat-icon>{{ view().latestOnly ? 'check' : '' }}</mat-icon>{{ 'yuv.app.bpm-management.definitions.filter.onlyLatest' | translate }}\n </button>\n }\n </mat-menu>\n @if (sortFields().length) {\n <button ymt-icon-button\n [matMenuTriggerFor]=\"sortMenu\"\n [matTooltip]=\"'yuv.sort.tooltip' | translate\"\n [attr.aria-label]=\"'yuv.sort.tooltip' | translate\">\n <mat-icon>swap_vert</mat-icon>\n </button>\n <mat-menu #sortMenu=\"matMenu\">\n @for (field of sortFields(); track field.value) {\n <button mat-menu-item class=\"radio-item\" role=\"menuitemradio\" [attr.aria-checked]=\"view().sortBy === field.value\" (click)=\"patchView({ sortBy: field.value })\">\n <mat-icon>{{ view().sortBy === field.value ? icons.radioButtonChecked : '' }}</mat-icon>{{ field.label | translate }}\n </button>\n }\n <mat-divider></mat-divider>\n @for (order of sortOrders; track order.value) {\n <button mat-menu-item class=\"radio-item\" role=\"menuitemradio\" [attr.aria-checked]=\"view().sortOrder === order.value\" (click)=\"patchView({ sortOrder: order.value })\">\n <mat-icon>{{ view().sortOrder === order.value ? icons.radioButtonChecked : '' }}</mat-icon>{{ order.label | translate }}\n </button>\n }\n </mat-menu>\n }\n</ng-template>\n\n<!-- the \u22EE menu of a list row: the actions of the details header, then what every item has -->\n<mat-menu #rowMenu=\"matMenu\" [ariaLabel]=\"'yuv.app.bpm-management.list.actions.label' | translate\">\n <ng-template matMenuContent let-item=\"item\">\n @switch (entity()) {\n @case ('definitions') {\n @let pd = asDefinition(item);\n @let pdAction = actions.definitionAction(pd);\n @if (pdAction) {\n <button mat-menu-item (click)=\"runAction(actions.changeDefinitionStatus(pd, pdAction))\">\n <mat-icon>{{ icons[pdAction] }}</mat-icon>{{ ('yuv.app.bpm-management.definitions.actions.' + pdAction + '.label') | translate }}\n </button>\n }\n <button mat-menu-item (click)=\"showProcessesOfDefinition({ definitionId: pd.id, quick: 'all' })\">\n <mat-icon>{{ ENTITY_META.processes.icon }}</mat-icon>{{ 'yuv.app.bpm-management.definitions.showProcesses' | translate }}\n </button>\n <mat-divider></mat-divider>\n }\n @case ('processes') {\n @let p = asProcess(item);\n @let pAction = actions.processAction(p);\n @if (pAction) {\n <button mat-menu-item (click)=\"runAction(actions.changeProcessStatus(p, pAction))\">\n <mat-icon>{{ icons[pAction] }}</mat-icon>{{ ('yuv.app.bpm-management.process.actions.' + pAction + '.label') | translate }}\n </button>\n <mat-divider></mat-divider>\n }\n }\n @case ('tasks') {\n @let t = asTask(item);\n @if (actions.hasTaskActions(t)) {\n <button mat-menu-item (click)=\"runAction(actions.assignTask(t))\">\n <mat-icon>{{ icons.assign }}</mat-icon>{{ 'yuv.app.bpm-management.task.actions.assign.label' | translate }}\n </button>\n <button mat-menu-item [disabled]=\"!actions.canUnassign(t)\" (click)=\"runAction(actions.unassignTask(t))\">\n <mat-icon>{{ icons.unassign }}</mat-icon>{{ 'yuv.app.bpm-management.task.actions.unassign.label' | translate }}\n </button>\n <!-- the row was selected when the menu opened, so its details (with the candidates) are usually loaded -->\n <button mat-menu-item (click)=\"runAction(actions.editTaskCandidates(detail()?.id === t.id ? asTask(detail()!) : t))\">\n <mat-icon>{{ icons.editCandidates }}</mat-icon>{{ 'yuv.app.bpm-management.task.actions.editCandidates.label' | translate }}\n </button>\n <mat-divider></mat-divider>\n }\n }\n }\n <button mat-menu-item (click)=\"copyId(item.id)\">\n <mat-icon>content_copy</mat-icon>{{ 'yuv.app.bpm-management.list.actions.copyId' | translate }}\n </button>\n </ng-template>\n</mat-menu>\n\n<!-- list pane top bar: hides the list (right aligned, next to the gutter it collapses into) -->\n<ng-template #masterActions>\n <ymbpm-pane-toggle-button\n icon=\"left_panel_close\"\n [tooltip]=\"'yuv.app.bpm-management.pane.hideList.tooltip' | translate\"\n (toggled)=\"split.hideArea(Area.MASTER)\" />\n</ng-template>\n\n<!-- details pane top bar: hides the details (left aligned, next to the gutter it collapses into) -->\n<ng-template #detailsTopBarActions>\n <ymbpm-pane-toggle-button\n align=\"start\"\n icon=\"right_panel_close\"\n [tooltip]=\"'yuv.app.bpm-management.pane.hideDetails.tooltip' | translate\"\n (toggled)=\"split.hideArea(Area.DETAILS)\" />\n</ng-template>\n", styles: ["@charset \"UTF-8\";ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}.mat-mdc-menu-item[aria-checked=true]{background:var(--ymt-primary-container);--mat-menu-item-label-text-color: var(--ymt-on-primary-container);--mat-menu-item-icon-color: var(--ymt-on-primary-container)}.mat-mdc-menu-item.radio-item[aria-checked=true]{background:none;--mat-menu-item-label-text-color: unset;--mat-menu-item-icon-color: unset}.mat-mdc-menu-item.radio-item[aria-checked=true] .mat-icon{scale:.5}yuv-simple-search ::ng-deep .mat-mdc-form-field-infix{width:auto}yuv-simple-search ::ng-deep [inert=true]{display:none}:host{display:flex;flex-flow:column;height:100%;overflow:hidden}:host .bpmmgmt-main__content{flex:1;min-height:0;display:flex;flex-flow:row;overflow:hidden;gap:var(--ymt-spacing-s);padding:var(--ymt-spacing-m)}:host .content-split{flex:1;min-width:0}:host ymt-pane-footer{--footer-block-padding: 0;--footer-inline-padding: 0}:host .paginator{flex:1;background:transparent}:host .quick-toggle{--mat-button-toggle-height: 32px;--mat-button-toggle-shape: 999px;--mat-button-toggle-divider-color: transparent;--mat-button-toggle-background-color: var(--ymt-surface-container-high);--mat-button-toggle-selected-state-background-color: var(--ymt-primary-container);--mat-button-toggle-selected-state-text-color: var(--ymt-on-primary-container);border-color:transparent}:host .items{display:block}:host .item{display:flex;align-items:center;gap:var(--ymt-spacing-xs);padding:var(--ymt-spacing-s) var(--ymt-spacing-xs) var(--ymt-spacing-s) var(--ymt-spacing-m);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant);cursor:pointer}:host .item:hover:not(.selected){background-color:var(--ymt-hover-background)}:host .item.selected{background-color:var(--ymt-selection-background);color:var(--ymt-on-selection-background)}:host .item.item--suspended:not(.selected){color:var(--ymt-text-color-subtle)}:host .items:focus-visible .item[aria-current=true]{outline:var(--ymt-focus-indicator-size) solid var(--ymt-primary);outline-offset:calc(-1 * var(--ymt-focus-indicator-size))}:host .items:focus-within .item.selected{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}:host .items:focus-within .item.selected .item__meta{color:var(--ymt-on-primary-container)}:host .item__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--ymt-spacing-3xs)}:host .item__title{display:flex;min-width:0;font:var(--ymt-font-title-smallest)}:host .item__title>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .item__meta{display:flex;align-items:center;gap:var(--ymt-spacing-xs);min-width:0;min-height:1lh;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}:host .item__meta>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .item__meta>span:first-child{flex:0 0 auto;font-variant-numeric:tabular-nums}:host .item__meta>span:not(:first-child){flex:0 1 auto;min-width:0}:host .item__meta>span+span:before{content:\"\\b7\";margin-inline-end:var(--ymt-spacing-xs)}:host .item__meta>.item__iconed{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs)}:host .item__meta>.item__iconed mat-icon{flex:none;width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs);font-size:var(--ymt-sizing-xs)}:host .item__meta>.item__iconed.item__ended{flex:none}:host .item__user{display:inline-flex;align-items:center}:host .item__user yuv-organization-renderer{min-width:0}:host .item__user yuv-organization-renderer ::ng-deep .node{border:0;padding:0;overflow:hidden;text-overflow:ellipsis}:host .item__chips{flex:0 0 auto;display:flex;align-items:center;gap:var(--ymt-spacing-2xs)}:host .item__state{min-width:10ch;justify-content:center}:host .item__menu{flex:none;display:inline-flex;align-items:center;justify-content:center;width:var(--ymt-sizing-xl);height:var(--ymt-sizing-xl);border-radius:var(--ymt-corner-full);color:var(--ymt-text-color-subtle)}:host .item__menu:hover,:host .item__menu[aria-expanded=true]{background-color:var(--ymt-hover-background);color:inherit}:host .list-body{display:flex;flex-flow:column}:host .empty-state{display:grid;justify-items:center;align-items:center;align-content:center;gap:var(--ymt-spacing-m);height:100%;padding:0 var(--ymt-spacing-3xl);text-align:center;color:var(--ymt-text-color-subtle);flex:1;min-height:0;height:auto}:host .empty-state-icon{width:var(--ymt-sizing-5xl);height:var(--ymt-sizing-5xl);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container);display:flex;align-items:center;justify-content:center;flex-shrink:0}:host .empty-state-description{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);max-width:32ch;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i1$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i1$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i2$3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { 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: MatTooltipModule }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: YuvClientShellModule }, { kind: "directive", type: i7.YuvAppHeaderSlotDirective, selector: "ng-template[yuvAppHeaderSlot]", inputs: ["yuvAppHeaderSlot"] }, { kind: "component", type: SimpleSearchComponent, selector: "yuv-simple-search", inputs: ["query"], outputs: ["querySubmit", "clearInput", "targetSelectionChanged", "queryChange", "typeAggregation"] }, { kind: "ngmodule", type: YuvListModule }, { kind: "component", type: i8.ListComponent, selector: "yuv-list", inputs: ["preventChangeUntil", "multiselect", "selfHandleSelection", "externalSelectionVisuals", "selfHandleClick", "autoSelect", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: i8.ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "ngmodule", type: YuvSplitViewModule }, { kind: "directive", type: i9.SplitAreaDirective, selector: "[yuvSplitArea]", inputs: ["size", "minSize", "maxSize", "panelClass", "visible", "lockSize"] }, { kind: "component", type: i9.SplitViewComponent, selector: "yuv-split-view", inputs: ["direction", "gutterSize", "restrictMove", "disabled", "layoutSettingsID"], outputs: ["layoutSettingsChange", "dragStart", "dragEnd", "gutterClick", "gutterDblClick"] }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i10.YmtPaneComponent, selector: "ymt-pane", inputs: ["topBarActions", "busy", "noAnimation", "plain"] }, { kind: "component", type: i10.YmtPaneHeaderComponent, selector: "ymt-pane-header", inputs: ["title", "icon", "subtitle", "actions", "badges"] }, { kind: "component", type: i10.YmtPaneBodyComponent, selector: "ymt-pane-body" }, { kind: "component", type: i10.YmtPaneFooterComponent, selector: "ymt-pane-footer" }, { kind: "component", type: YmtBadge, selector: "ymt-badge", inputs: ["severity", "outline", "aura"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "component", type: OrganizationRendererComponent, selector: "yuv-organization-renderer" }, { kind: "component", type: PaneGutterComponent, selector: "ymbpm-pane-gutter", inputs: ["icon", "label", "tooltip", "flipLabel"], outputs: ["expand"] }, { kind: "component", type: PaneToggleButtonComponent, selector: "ymbpm-pane-toggle-button", inputs: ["icon", "tooltip"], outputs: ["toggled"] }, { kind: "component", type: EntitySwitchComponent, selector: "ymbpm-entity-switch", inputs: ["entities", "value"], outputs: ["valueChange"] }, { kind: "component", type: FilterBarComponent, selector: "ymbpm-filter-bar", inputs: ["columns", "filters", "search"], outputs: ["filtersChange", "searchClear"] }, { kind: "component", type: DetailsComponent, selector: "ymbpm-details", inputs: ["entity", "detail", "listItem", "processTasks", "busy", "error", "selectedId", "canOpenDefinition", "canOpenDeployment", "topBarActions"], outputs: ["changed", "openItem", "showProcesses"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormatDateTimePipe, name: "formatDateTime" }] });
2693
2695
  }
2694
2696
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: YuvBpmManagementComponent, decorators: [{
2695
2697
  type: Component,
@@ -2716,8 +2718,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
2716
2718
  EntitySwitchComponent,
2717
2719
  FilterBarComponent,
2718
2720
  DetailsComponent
2719
- ], template: "<!-- the entity switch lives in the shell's app header -->\n<ng-template yuvAppHeaderSlot=\"actions\">\n <ymbpm-entity-switch [entities]=\"availableEntities\" [value]=\"entity()\" (valueChange)=\"switchEntity($event)\" />\n</ng-template>\n\n<!-- search lives in the shell's app header -->\n<ng-template yuvAppHeaderSlot=\"search\">\n <yuv-simple-search [query]=\"searchQuery()\" (querySubmit)=\"onQueryChange($event)\" (clearInput)=\"onQueryChange({ term: '' })\"></yuv-simple-search>\n</ng-template>\n\n<!-- A named region, not <main>: the shell already wraps the routed app in its own main landmark. -->\n<div role=\"region\" class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n @if (!split.isAreaVisible(Area.MASTER)) {\n <ymbpm-pane-gutter\n icon=\"left_panel_open\"\n [flipLabel]=\"true\"\n [label]=\"ENTITY_META[entity()].label | translate\"\n [tooltip]=\"'yuv.app.bpm-management.pane.showList.tooltip' | translate\"\n (expand)=\"split.showArea(Area.MASTER)\" />\n }\n\n <yuv-split-view #split [layoutSettingsID]=\"layoutSettingsID\" class=\"content-split\">\n\n <!-- ===================================== MASTER ===================================== -->\n <ng-template yuvSplitArea [size]=\"61.8\">\n <ymt-pane [busy]=\"busy()\" [topBarActions]=\"masterActions\" role=\"region\" [attr.aria-label]=\"ENTITY_META[entity()].label | translate\">\n <ymt-pane-header\n [icon]=\"ENTITY_META[entity()].icon\"\n [title]=\"ENTITY_META[entity()].label | translate\"\n [actions]=\"listActions\"\n ></ymt-pane-header>\n\n <ymt-pane-body class=\"list-body\">\n <ymbpm-filter-bar\n [columns]=\"filterColumns()\"\n [filters]=\"view().advanced\"\n [search]=\"searchTerm()\"\n (filtersChange)=\"onAdvancedFilters($event)\"\n (searchClear)=\"onQueryChange({ term: '' })\" />\n @if (items().length === 0 && !busy()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">search_off</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.list.empty' | translate }}</p>\n @if (hasActiveFilters()) {\n <button ymtButton=\"secondary\" (click)=\"clearFilters()\">{{ 'yuv.app.bpm-management.filters.clearAll' | translate }}</button>\n }\n </div>\n } @else {\n <yuv-list class=\"items\" [attr.aria-label]=\"ENTITY_META[entity()].label | translate\" [externalSelectionVisuals]=\"true\" (itemFocus)=\"onItemFocus($event)\">\n @for (item of items(); track item.id) {\n <div yuvListItem role=\"option\" class=\"item\" [attr.data-item-id]=\"item.id\" [class.item--suspended]=\"isSuspended(item)\" [selected]=\"item.id === selectedId()\">\n @switch (entity()) {\n @case ('deployments') {\n @let d = asDeployment(item);\n <mat-icon class=\"item__icon\" aria-hidden=\"true\">{{ ENTITY_META.deployments.itemIcon }}</mat-icon>\n <div class=\"item__main\">\n <span class=\"item__title\">{{ d.name || '&lt;unnamed&gt;' }}</span>\n </div>\n <span class=\"item__time\">{{ d.deploymentTime | formatDateTime }}</span>\n }\n @case ('definitions') {\n @let pd = asDefinition(item);\n @let definitionStatus = definitionStatusLabel(pd) | translate;\n <span class=\"item__marker\" role=\"img\" [attr.data-severity]=\"definitionSeverity(pd)\" [matTooltip]=\"definitionStatus\" matTooltipPosition=\"right\" [attr.aria-label]=\"definitionStatus\"></span>\n <div class=\"item__main\">\n <span class=\"item__heading item__heading--split\">\n <span class=\"item__title\">{{ pd.name || '&lt;unnamed&gt;' }}</span>\n <!-- only global definitions are marked, tenant specific ones are the normal case -->\n @if (pd.global) {\n <ymt-badge class=\"item__scope\" [outline]=\"true\">\n <mat-icon>{{ icons.globe }}</mat-icon>{{ ProcessDefinitionScope.GLOBAL.label | translate }}\n </ymt-badge>\n }\n </span>\n <span class=\"item__meta\">\n <span class=\"item__key\"><mat-icon>key</mat-icon><span class=\"item__key-text\" [title]=\"pd.key\">{{ pd.key }}</span></span>\n <span class=\"item__version\"><mat-icon>layers</mat-icon>v{{ pd.version }}</span>\n <!-- always rendered, so key and category keep their equal columns -->\n <span class=\"item__category\">\n @if (pd.category) {\n <mat-icon>category</mat-icon><span class=\"item__key-text\" [title]=\"pd.category\">{{ pd.category }}</span>\n }\n </span>\n </span>\n </div>\n }\n @case ('processes') {\n @let p = asProcess(item);\n @let statusLabel = processStatusLabel(p) | translate;\n <span class=\"item__marker\" role=\"img\" [attr.data-severity]=\"processSeverity(p)\" [matTooltip]=\"statusLabel\" matTooltipPosition=\"right\" [attr.aria-label]=\"statusLabel\"></span>\n <div class=\"item__main\">\n <span class=\"item__heading item__heading--split\">\n <span class=\"item__title\">{{ p.name || '&lt;unnamed&gt;' }}</span>\n <ymt-badge class=\"item__definition\" [outline]=\"true\" [title]=\"p.processDefinitionName || ''\">\n <mat-icon>{{ ENTITY_META.definitions.itemIcon }}</mat-icon><span class=\"item__key-text\">{{ p.processDefinitionName || '-' }}</span>\n </ymt-badge>\n </span>\n <span class=\"item__meta item__meta--process\">\n <span class=\"item__started\">\n <mat-icon>schedule</mat-icon>{{ p.startTime | formatDateTime }}\n <span class=\"item__started-by\">{{ 'yuv.app.bpm-management.process.startedByShort' | translate }}</span>\n <yuv-organization-renderer propertyName=\"user\" [value]=\"p.startUserId ?? null\"></yuv-organization-renderer>\n </span>\n @if (p.businessKey) {\n <span class=\"item__business-key\">\n <mat-icon>tag</mat-icon><span class=\"item__key-text\" [title]=\"p.businessKey\">{{ p.businessKey }}</span>\n </span>\n }\n @if (p.endTime) {\n <span class=\"item__ended\"><mat-icon>flag</mat-icon>{{ p.endTime | formatDateTime }}</span>\n }\n </span>\n </div>\n }\n @case ('tasks') {\n @let t = asTask(item);\n @let taskStatus = taskStatusLabel(t) | translate;\n <span class=\"item__marker\" role=\"img\" [attr.data-severity]=\"taskSeverity(t)\" [matTooltip]=\"taskStatus\" matTooltipPosition=\"right\" [attr.aria-label]=\"taskStatus\"></span>\n <div class=\"item__main\">\n <span class=\"item__title\">{{ t.name || '&lt;unnamed&gt;' }}</span>\n <span class=\"item__meta item__meta--slots item__meta--task\">\n <span class=\"item__started\">\n <mat-icon>schedule</mat-icon>{{ t.createTime | formatDateTime }}\n <yuv-organization-renderer propertyName=\"user\" [value]=\"t.assignee ?? null\"></yuv-organization-renderer>\n </span>\n <span>\n <mat-icon>{{ ENTITY_META.processes.itemIcon }}</mat-icon><span class=\"item__key-text\" [title]=\"t.processInstanceName || ''\">{{ t.processInstanceName || '-' }}</span>\n </span>\n <span>\n @if (t.endTime) {\n <mat-icon>flag</mat-icon>{{ t.endTime | formatDateTime }}\n }\n </span>\n </span>\n </div>\n }\n }\n </div>\n }\n </yuv-list>\n }\n </ymt-pane-body>\n\n <ymt-pane-footer>\n <mat-paginator class=\"paginator\"\n [length]=\"total()\"\n [pageIndex]=\"view().page\"\n [pageSize]=\"view().pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [attr.aria-label]=\"'yuv.app.bpm-management.pagination.aria' | translate\"\n (page)=\"onChangePage($event)\">\n </mat-paginator>\n </ymt-pane-footer>\n\n </ymt-pane>\n </ng-template>\n\n <!-- ===================================== DETAILS ==================================== -->\n <ng-template yuvSplitArea [size]=\"38.2\">\n <ymbpm-details\n [entity]=\"entity()\"\n [detail]=\"detail()\"\n [listItem]=\"selectedItem()\"\n [processTasks]=\"processTasks()\"\n [busy]=\"detailsBusy()\"\n [error]=\"detailsError()\"\n [selectedId]=\"selectedId()\"\n [canOpenDefinition]=\"definitionsEnabled\"\n [canOpenDeployment]=\"deploymentsEnabled\"\n [topBarActions]=\"detailsTopBarActions\"\n (changed)=\"onDetailsChanged($event)\"\n (openItem)=\"openItem($event.entity, $event.id)\"\n (showProcesses)=\"showProcessesOfDefinition($event)\" ></ymbpm-details>\n </ng-template>\n </yuv-split-view>\n\n @if (!split.isAreaVisible(Area.DETAILS)) {\n <ymbpm-pane-gutter\n icon=\"right_panel_open\"\n [label]=\"'yuv.app.bpm-management.details.aria' | translate\"\n [tooltip]=\"'yuv.app.bpm-management.pane.showDetails.tooltip' | translate\"\n (expand)=\"split.showArea(Area.DETAILS)\" />\n }\n</div>\n\n<!-- master header: filter panel toggle -->\n<ng-template #listActions>\n @if (quickFilters().length) {\n <mat-button-toggle-group class=\"quick-toggle\" [value]=\"view().quick\" (change)=\"onQuick($event.value)\"\n [attr.aria-label]=\"'yuv.app.bpm-management.statusFilter.aria' | translate\">\n @for (quick of quickFilters(); track quick.value) {\n <mat-button-toggle [value]=\"quick.value\">{{ quick.label | translate }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n }\n @let bar = filterBar();\n @let addable = bar?.addableColumns() ?? [];\n <button ymt-icon-button #addFilter\n [matMenuTriggerFor]=\"addFilterMenu\"\n [matMenuTriggerRestoreFocus]=\"false\"\n [disabled]=\"!addable.length && !showLatestOnly()\"\n [matTooltip]=\"'yuv.app.bpm-management.filters.add' | translate\"\n [attr.aria-label]=\"'yuv.app.bpm-management.filters.add' | translate\">\n <mat-icon>filter_list</mat-icon>\n </button>\n <mat-menu #addFilterMenu=\"matMenu\">\n @for (column of addable; track column.name) {\n <button mat-menu-item (click)=\"bar?.edit(column, addFilter)\">{{ column.displayName | translate }}</button>\n }\n @if (showLatestOnly()) {\n @if (addable.length) {\n <mat-divider></mat-divider>\n }\n <button mat-menu-item role=\"menuitemcheckbox\" [attr.aria-checked]=\"view().latestOnly\" (click)=\"toggleLatestOnly()\">\n <mat-icon>{{ view().latestOnly ? 'check' : '' }}</mat-icon>{{ 'yuv.app.bpm-management.definitions.filter.onlyLatest' | translate }}\n </button>\n }\n </mat-menu>\n @if (sortFields().length) {\n <button ymt-icon-button\n [matMenuTriggerFor]=\"sortMenu\"\n [matTooltip]=\"'yuv.sort.tooltip' | translate\"\n [attr.aria-label]=\"'yuv.sort.tooltip' | translate\">\n <mat-icon>swap_vert</mat-icon>\n </button>\n <mat-menu #sortMenu=\"matMenu\">\n @for (field of sortFields(); track field.value) {\n <button mat-menu-item class=\"radio-item\" role=\"menuitemradio\" [attr.aria-checked]=\"view().sortBy === field.value\" (click)=\"patchView({ sortBy: field.value })\">\n <mat-icon>{{ view().sortBy === field.value ? icons.radioButtonChecked : '' }}</mat-icon>{{ field.label | translate }}\n </button>\n }\n <mat-divider></mat-divider>\n @for (order of sortOrders; track order.value) {\n <button mat-menu-item class=\"radio-item\" role=\"menuitemradio\" [attr.aria-checked]=\"view().sortOrder === order.value\" (click)=\"patchView({ sortOrder: order.value })\">\n <mat-icon>{{ view().sortOrder === order.value ? icons.radioButtonChecked : '' }}</mat-icon>{{ order.label | translate }}\n </button>\n }\n </mat-menu>\n }\n</ng-template>\n\n<!-- list pane top bar: hides the list (right aligned, next to the gutter it collapses into) -->\n<ng-template #masterActions>\n <ymbpm-pane-toggle-button\n icon=\"left_panel_close\"\n [tooltip]=\"'yuv.app.bpm-management.pane.hideList.tooltip' | translate\"\n (toggled)=\"split.hideArea(Area.MASTER)\" />\n</ng-template>\n\n<!-- details pane top bar: hides the details (left aligned, next to the gutter it collapses into) -->\n<ng-template #detailsTopBarActions>\n <ymbpm-pane-toggle-button\n align=\"start\"\n icon=\"right_panel_close\"\n [tooltip]=\"'yuv.app.bpm-management.pane.hideDetails.tooltip' | translate\"\n (toggled)=\"split.hideArea(Area.DETAILS)\" />\n</ng-template>\n", styles: ["ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}.mat-mdc-menu-item[aria-checked=true]{background:var(--ymt-primary-container);--mat-menu-item-label-text-color: var(--ymt-on-primary-container);--mat-menu-item-icon-color: var(--ymt-on-primary-container)}.mat-mdc-menu-item.radio-item[aria-checked=true]{background:none;--mat-menu-item-label-text-color: unset;--mat-menu-item-icon-color: unset}.mat-mdc-menu-item.radio-item[aria-checked=true] .mat-icon{scale:.5}:host{display:flex;flex-flow:column;height:100%;overflow:hidden}:host .bpmmgmt-main__content{flex:1;min-height:0;display:flex;flex-flow:row;overflow:hidden;gap:var(--ymt-spacing-s);padding:var(--ymt-spacing-m)}:host .content-split{flex:1;min-width:0}:host ymt-pane-footer{--footer-block-padding: 0;--footer-inline-padding: 0}:host .paginator{flex:1;background:transparent}:host .quick-toggle{--mat-button-toggle-height: 32px;--mat-button-toggle-shape: 999px;--mat-button-toggle-divider-color: transparent;--mat-button-toggle-background-color: var(--ymt-surface-container-high);--mat-button-toggle-selected-state-background-color: var(--ymt-primary-container);--mat-button-toggle-selected-state-text-color: var(--ymt-on-primary-container);border-color:transparent}:host .items{display:block}:host .item{position:relative;display:flex;align-items:center;gap:var(--ymt-spacing-s);padding:var(--ymt-spacing-xs) var(--ymt-spacing-m);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant);cursor:pointer}:host .item:hover:not(.selected){background-color:var(--ymt-hover-background)}:host .item.selected{background-color:var(--ymt-selection-background);color:var(--ymt-on-selection-background)}:host .item.item--suspended:not(.selected){color:var(--ymt-text-color-subtle)}:host .items:focus-visible .item[aria-current=true]{outline:var(--ymt-focus-indicator-size) solid var(--ymt-primary);outline-offset:calc(-1 * var(--ymt-focus-indicator-size))}:host .items:focus-within .item.selected{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}:host .items:focus-within .item.selected .item__meta{color:var(--ymt-on-primary-container)}:host .item__marker{position:absolute;inset-block:var(--ymt-spacing-xs);inset-inline-start:var(--ymt-spacing-2xs);width:var(--ymt-spacing-2xs);border-radius:var(--ymt-spacing-2xs);background-color:var(--ymt-surface-container-highest)}:host .item__marker[data-severity=primary]{background-color:var(--ymt-primary-container)}:host .item__marker[data-severity=success]{background-color:var(--ymt-success-container)}:host .item__marker[data-severity=warning]{background-color:var(--ymt-warning-container)}:host .item__main{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--ymt-spacing-xs)}:host .item__time{flex:none;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);font-variant-numeric:tabular-nums}:host .item__title{font:var(--ymt-font-title-smallest);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .item__heading{display:flex;align-items:center;gap:var(--ymt-spacing-xs);min-width:0}:host .item__heading--split{justify-content:space-between}:host .item__heading--split .item__title{min-width:0}:host .item__definition{flex:0 1 auto;min-width:0;max-width:50%}:host .item__meta>.item__version,:host .item__meta>.item__key,:host .item__meta>.item__category{flex:1 1 8rem;min-width:0;white-space:nowrap}:host .item__meta>.item__version mat-icon,:host .item__meta>.item__key mat-icon,:host .item__meta>.item__category mat-icon{flex:none}:host .item__key-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .item__icon{flex:none;width:var(--ymt-sizing-m);height:var(--ymt-sizing-m);font-size:var(--ymt-sizing-m);color:var(--ymt-text-color-subtle)}:host .item__scope{flex:none;white-space:nowrap}:host .item__scope mat-icon{width:1em;height:1em;font-size:1em;line-height:1}:host .item__meta{display:flex;flex-wrap:wrap;gap:0 var(--ymt-spacing-m);font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}:host .item__meta>span{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs)}:host .item__meta mat-icon{font-size:var(--ymt-sizing-xs);width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs)}:host .item__meta--slots{display:grid;gap:0 var(--ymt-spacing-m)}:host .item__meta--slots>span{min-width:0;overflow:hidden;white-space:nowrap}:host .item__meta--slots mat-icon{flex:none}:host .item__meta--process{flex-wrap:nowrap}:host .item__meta--process>span{min-width:0;white-space:nowrap}:host .item__meta--process mat-icon{flex:none}:host .item__started{flex:1 1 auto;overflow:hidden}:host .item__started yuv-organization-renderer{min-width:0}:host .item__started yuv-organization-renderer ::ng-deep .node{border:0;padding:0;overflow:hidden;text-overflow:ellipsis}:host .item__business-key{flex:0 1 auto;max-width:12rem;overflow:hidden}:host .item__ended{flex:none;margin-inline-start:auto}:host .item__meta--task{grid-template-columns:minmax(0,1.5fr) minmax(0,1fr) 10rem}:host .item__meta--task>span:last-child{justify-content:flex-end}:host .list-body{display:flex;flex-flow:column}:host .empty-state{display:grid;justify-items:center;align-items:center;align-content:center;gap:var(--ymt-spacing-m);height:100%;padding:0 var(--ymt-spacing-3xl);text-align:center;color:var(--ymt-text-color-subtle);flex:1;min-height:0;height:auto}:host .empty-state-icon{width:var(--ymt-sizing-5xl);height:var(--ymt-sizing-5xl);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container);display:flex;align-items:center;justify-content:center;flex-shrink:0}:host .empty-state-description{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);max-width:32ch;margin:0}\n"] }]
2720
- }], ctorParameters: () => [], propDecorators: { filterBar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FilterBarComponent), { isSignal: true }] }] } });
2721
+ ], template: "<!-- the entity switch lives in the shell's app header -->\n<ng-template yuvAppHeaderSlot=\"actions\">\n <ymbpm-entity-switch [entities]=\"availableEntities\" [value]=\"entity()\" (valueChange)=\"switchEntity($event)\" />\n</ng-template>\n\n<!-- search lives in the shell's app header -->\n<ng-template yuvAppHeaderSlot=\"search\">\n <yuv-simple-search [query]=\"searchQuery()\" (querySubmit)=\"onQueryChange($event)\" (clearInput)=\"onQueryChange({ term: '' })\"></yuv-simple-search>\n</ng-template>\n\n<!-- A named region, not <main>: the shell already wraps the routed app in its own main landmark. -->\n<div role=\"region\" class=\"bpmmgmt-main__content\" [attr.aria-label]=\"'yuv.app.bpm-management.content.aria.label' | translate\">\n @if (!split.isAreaVisible(Area.MASTER)) {\n <ymbpm-pane-gutter\n icon=\"left_panel_open\"\n [flipLabel]=\"true\"\n [label]=\"ENTITY_META[entity()].label | translate\"\n [tooltip]=\"'yuv.app.bpm-management.pane.showList.tooltip' | translate\"\n (expand)=\"split.showArea(Area.MASTER)\" />\n }\n\n <yuv-split-view #split [layoutSettingsID]=\"layoutSettingsID\" class=\"content-split\">\n\n <!-- ===================================== MASTER ===================================== -->\n <ng-template yuvSplitArea [size]=\"61.8\">\n <ymt-pane [busy]=\"busy()\" [topBarActions]=\"masterActions\" role=\"region\" [attr.aria-label]=\"ENTITY_META[entity()].label | translate\">\n <ymt-pane-header\n [icon]=\"ENTITY_META[entity()].icon\"\n [title]=\"ENTITY_META[entity()].label | translate\"\n [actions]=\"listActions\"\n ></ymt-pane-header>\n\n <ymt-pane-body class=\"list-body\">\n <ymbpm-filter-bar\n [columns]=\"filterColumns()\"\n [filters]=\"view().advanced\"\n [search]=\"searchTerm()\"\n (filtersChange)=\"onAdvancedFilters($event)\"\n (searchClear)=\"onQueryChange({ term: '' })\" />\n @if (items().length === 0 && !busy()) {\n <div class=\"empty-state\">\n <span class=\"empty-state-icon\"><mat-icon aria-hidden=\"true\">search_off</mat-icon></span>\n <p class=\"empty-state-description\">{{ 'yuv.app.bpm-management.list.empty' | translate }}</p>\n @if (hasActiveFilters()) {\n <button ymtButton=\"secondary\" (click)=\"clearFilters()\">{{ 'yuv.app.bpm-management.filters.clearAll' | translate }}</button>\n }\n </div>\n } @else {\n <!-- Shift+F10 / the context menu key open the actions of the active row (its \u22EE is for the pointer only, see .item__menu) -->\n <yuv-list class=\"items\" [attr.aria-label]=\"ENTITY_META[entity()].label | translate\" aria-keyshortcuts=\"Shift+F10\" [externalSelectionVisuals]=\"true\"\n (itemFocus)=\"onItemFocus($event)\" (contextmenu)=\"onListContextMenu($event)\">\n @for (item of items(); track item.id) {\n <!-- [title] / meta \u00B7 meta | state badge | \u22EE -->\n <!-- aria-selected comes from the yuvListItem host binding (from [selected]), which the rule cannot see -->\n <!-- eslint-disable-next-line @angular-eslint/template/role-has-required-aria -->\n <div yuvListItem role=\"option\" class=\"item\" [attr.data-item-id]=\"item.id\" [class.item--suspended]=\"isSuspended(item)\" [selected]=\"item.id === selectedId()\">\n @switch (entity()) {\n @case ('deployments') {\n @let d = asDeployment(item);\n <div class=\"item__body\">\n <div class=\"item__title\"><span>{{ d.name || '&lt;unnamed&gt;' }}</span></div>\n <div class=\"item__meta\">\n <span>{{ d.deploymentTime | formatDateTime }}</span>\n </div>\n <div class=\"item__meta\">\n @if (d.category) {\n <span [title]=\"d.category\">{{ d.category }}</span>\n }\n </div>\n </div>\n }\n @case ('definitions') {\n @let pd = asDefinition(item);\n <div class=\"item__body\">\n <div class=\"item__title\"><span>{{ pd.name || '&lt;unnamed&gt;' }}</span></div>\n <div class=\"item__meta\">\n @if (pd.category) {\n <span [title]=\"pd.category\">{{ pd.category }}</span>\n }\n </div>\n <div class=\"item__meta\">\n <!-- the scope is only a symbol; it carries information, so it is an image with a name, not decoration -->\n @let scope = definitionScope(pd);\n @let scopeLabel = scope.label | translate;\n <span class=\"item__iconed\">\n <mat-icon role=\"img\" aria-hidden=\"false\" [attr.aria-label]=\"scopeLabel\" [matTooltip]=\"scopeLabel\">{{ icons[scope.icon] }}</mat-icon>v{{ pd.version }}\n </span>\n <span [title]=\"pd.key\">{{ pd.key }}</span>\n </div>\n </div>\n <div class=\"item__chips\">\n <ymt-badge class=\"item__state\" [aura]=\"true\" [severity]=\"definitionSeverity(pd)\">{{ definitionStatusLabel(pd) | translate }}</ymt-badge>\n </div>\n }\n @case ('processes') {\n @let p = asProcess(item);\n <div class=\"item__body\">\n <div class=\"item__title\"><span>{{ p.name || '&lt;unnamed&gt;' }}</span></div>\n <div class=\"item__meta\">\n <span [title]=\"p.processDefinitionName || ''\">{{ p.processDefinitionName || '-' }}</span>\n </div>\n <div class=\"item__meta\">\n <span class=\"item__iconed\"><mat-icon>schedule</mat-icon>{{ p.startTime | formatDateTime }}</span>\n <span class=\"item__user\"><yuv-organization-renderer propertyName=\"user\" [value]=\"p.startUserId ?? null\"></yuv-organization-renderer></span>\n @if (p.endTime) {\n <span class=\"item__iconed item__ended\"><mat-icon>flag</mat-icon>{{ p.endTime | formatDateTime }}</span>\n }\n </div>\n </div>\n <div class=\"item__chips\">\n <ymt-badge class=\"item__state\" [aura]=\"true\" [severity]=\"processSeverity(p)\">{{ processStatusLabel(p) | translate }}</ymt-badge>\n </div>\n }\n @case ('tasks') {\n @let t = asTask(item);\n <div class=\"item__body\">\n <div class=\"item__title\"><span>{{ t.name || '&lt;unnamed&gt;' }}</span></div>\n <div class=\"item__meta\">\n <span [title]=\"t.processInstanceName || ''\">{{ t.processInstanceName || '-' }}</span>\n </div>\n <div class=\"item__meta\">\n <span class=\"item__iconed\"><mat-icon>schedule</mat-icon>{{ t.createTime | formatDateTime }}</span>\n @if (t.assignee) {\n <span class=\"item__user\"><yuv-organization-renderer propertyName=\"user\" [value]=\"t.assignee\"></yuv-organization-renderer></span>\n }\n @if (t.endTime) {\n <span class=\"item__iconed item__ended\"><mat-icon>flag</mat-icon>{{ t.endTime | formatDateTime }}</span>\n }\n </div>\n </div>\n <div class=\"item__chips\">\n <ymt-badge class=\"item__state\" [aura]=\"true\" [severity]=\"taskSeverity(t)\">{{ taskStatusLabel(t) | translate }}</ymt-badge>\n </div>\n }\n }\n <!-- Not a button: a focusable element inside role=\"option\" is a nested-interactive violation (yuv-list\n even sets tabindex=\"-1\" on it). Pointer users click it, the keyboard opens the same menu with\n Shift+F10 on the list; the click also selects the row, so the menu visibly applies to it. -->\n <span class=\"item__menu\" aria-hidden=\"true\" #rowMenuTrigger=\"matMenuTrigger\"\n [matMenuTriggerFor]=\"rowMenu\" [matMenuTriggerData]=\"{ item }\" (menuClosed)=\"onRowMenuClosed()\"\n [matTooltip]=\"'yuv.app.bpm-management.list.actions.label' | translate\">\n <mat-icon>more_vert</mat-icon>\n </span>\n </div>\n }\n </yuv-list>\n }\n </ymt-pane-body>\n\n <ymt-pane-footer>\n <mat-paginator class=\"paginator\"\n [length]=\"total()\"\n [pageIndex]=\"view().page\"\n [pageSize]=\"view().pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [attr.aria-label]=\"'yuv.app.bpm-management.pagination.aria' | translate\"\n (page)=\"onChangePage($event)\">\n </mat-paginator>\n </ymt-pane-footer>\n\n </ymt-pane>\n </ng-template>\n\n <!-- ===================================== DETAILS ==================================== -->\n <ng-template yuvSplitArea [size]=\"38.2\">\n <ymbpm-details\n [entity]=\"entity()\"\n [detail]=\"detail()\"\n [listItem]=\"selectedItem()\"\n [processTasks]=\"processTasks()\"\n [busy]=\"detailsBusy()\"\n [error]=\"detailsError()\"\n [selectedId]=\"selectedId()\"\n [canOpenDefinition]=\"definitionsEnabled\"\n [canOpenDeployment]=\"deploymentsEnabled\"\n [topBarActions]=\"detailsTopBarActions\"\n (changed)=\"onDetailsChanged($event)\"\n (openItem)=\"openItem($event.entity, $event.id)\"\n (showProcesses)=\"showProcessesOfDefinition($event)\" ></ymbpm-details>\n </ng-template>\n </yuv-split-view>\n\n @if (!split.isAreaVisible(Area.DETAILS)) {\n <ymbpm-pane-gutter\n icon=\"right_panel_open\"\n [label]=\"'yuv.app.bpm-management.details.aria' | translate\"\n [tooltip]=\"'yuv.app.bpm-management.pane.showDetails.tooltip' | translate\"\n (expand)=\"split.showArea(Area.DETAILS)\" />\n }\n</div>\n\n<!-- master header: filter panel toggle -->\n<ng-template #listActions>\n @if (quickFilters().length) {\n <mat-button-toggle-group class=\"quick-toggle\" [value]=\"view().quick\" (change)=\"onQuick($event.value)\"\n [attr.aria-label]=\"'yuv.app.bpm-management.statusFilter.aria' | translate\">\n @for (quick of quickFilters(); track quick.value) {\n <mat-button-toggle [value]=\"quick.value\">{{ quick.label | translate }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n }\n @let bar = filterBar();\n @let addable = bar?.addableColumns() ?? [];\n <button ymt-icon-button #addFilter\n [matMenuTriggerFor]=\"addFilterMenu\"\n [matMenuTriggerRestoreFocus]=\"false\"\n [disabled]=\"!addable.length && !showLatestOnly()\"\n [matTooltip]=\"'yuv.app.bpm-management.filters.add' | translate\"\n [attr.aria-label]=\"'yuv.app.bpm-management.filters.add' | translate\">\n <mat-icon>filter_list</mat-icon>\n </button>\n <mat-menu #addFilterMenu=\"matMenu\">\n @for (column of addable; track column.name) {\n <button mat-menu-item (click)=\"bar?.edit(column, addFilter)\">{{ column.displayName | translate }}</button>\n }\n @if (showLatestOnly()) {\n @if (addable.length) {\n <mat-divider></mat-divider>\n }\n <button mat-menu-item role=\"menuitemcheckbox\" [attr.aria-checked]=\"view().latestOnly\" (click)=\"toggleLatestOnly()\">\n <mat-icon>{{ view().latestOnly ? 'check' : '' }}</mat-icon>{{ 'yuv.app.bpm-management.definitions.filter.onlyLatest' | translate }}\n </button>\n }\n </mat-menu>\n @if (sortFields().length) {\n <button ymt-icon-button\n [matMenuTriggerFor]=\"sortMenu\"\n [matTooltip]=\"'yuv.sort.tooltip' | translate\"\n [attr.aria-label]=\"'yuv.sort.tooltip' | translate\">\n <mat-icon>swap_vert</mat-icon>\n </button>\n <mat-menu #sortMenu=\"matMenu\">\n @for (field of sortFields(); track field.value) {\n <button mat-menu-item class=\"radio-item\" role=\"menuitemradio\" [attr.aria-checked]=\"view().sortBy === field.value\" (click)=\"patchView({ sortBy: field.value })\">\n <mat-icon>{{ view().sortBy === field.value ? icons.radioButtonChecked : '' }}</mat-icon>{{ field.label | translate }}\n </button>\n }\n <mat-divider></mat-divider>\n @for (order of sortOrders; track order.value) {\n <button mat-menu-item class=\"radio-item\" role=\"menuitemradio\" [attr.aria-checked]=\"view().sortOrder === order.value\" (click)=\"patchView({ sortOrder: order.value })\">\n <mat-icon>{{ view().sortOrder === order.value ? icons.radioButtonChecked : '' }}</mat-icon>{{ order.label | translate }}\n </button>\n }\n </mat-menu>\n }\n</ng-template>\n\n<!-- the \u22EE menu of a list row: the actions of the details header, then what every item has -->\n<mat-menu #rowMenu=\"matMenu\" [ariaLabel]=\"'yuv.app.bpm-management.list.actions.label' | translate\">\n <ng-template matMenuContent let-item=\"item\">\n @switch (entity()) {\n @case ('definitions') {\n @let pd = asDefinition(item);\n @let pdAction = actions.definitionAction(pd);\n @if (pdAction) {\n <button mat-menu-item (click)=\"runAction(actions.changeDefinitionStatus(pd, pdAction))\">\n <mat-icon>{{ icons[pdAction] }}</mat-icon>{{ ('yuv.app.bpm-management.definitions.actions.' + pdAction + '.label') | translate }}\n </button>\n }\n <button mat-menu-item (click)=\"showProcessesOfDefinition({ definitionId: pd.id, quick: 'all' })\">\n <mat-icon>{{ ENTITY_META.processes.icon }}</mat-icon>{{ 'yuv.app.bpm-management.definitions.showProcesses' | translate }}\n </button>\n <mat-divider></mat-divider>\n }\n @case ('processes') {\n @let p = asProcess(item);\n @let pAction = actions.processAction(p);\n @if (pAction) {\n <button mat-menu-item (click)=\"runAction(actions.changeProcessStatus(p, pAction))\">\n <mat-icon>{{ icons[pAction] }}</mat-icon>{{ ('yuv.app.bpm-management.process.actions.' + pAction + '.label') | translate }}\n </button>\n <mat-divider></mat-divider>\n }\n }\n @case ('tasks') {\n @let t = asTask(item);\n @if (actions.hasTaskActions(t)) {\n <button mat-menu-item (click)=\"runAction(actions.assignTask(t))\">\n <mat-icon>{{ icons.assign }}</mat-icon>{{ 'yuv.app.bpm-management.task.actions.assign.label' | translate }}\n </button>\n <button mat-menu-item [disabled]=\"!actions.canUnassign(t)\" (click)=\"runAction(actions.unassignTask(t))\">\n <mat-icon>{{ icons.unassign }}</mat-icon>{{ 'yuv.app.bpm-management.task.actions.unassign.label' | translate }}\n </button>\n <!-- the row was selected when the menu opened, so its details (with the candidates) are usually loaded -->\n <button mat-menu-item (click)=\"runAction(actions.editTaskCandidates(detail()?.id === t.id ? asTask(detail()!) : t))\">\n <mat-icon>{{ icons.editCandidates }}</mat-icon>{{ 'yuv.app.bpm-management.task.actions.editCandidates.label' | translate }}\n </button>\n <mat-divider></mat-divider>\n }\n }\n }\n <button mat-menu-item (click)=\"copyId(item.id)\">\n <mat-icon>content_copy</mat-icon>{{ 'yuv.app.bpm-management.list.actions.copyId' | translate }}\n </button>\n </ng-template>\n</mat-menu>\n\n<!-- list pane top bar: hides the list (right aligned, next to the gutter it collapses into) -->\n<ng-template #masterActions>\n <ymbpm-pane-toggle-button\n icon=\"left_panel_close\"\n [tooltip]=\"'yuv.app.bpm-management.pane.hideList.tooltip' | translate\"\n (toggled)=\"split.hideArea(Area.MASTER)\" />\n</ng-template>\n\n<!-- details pane top bar: hides the details (left aligned, next to the gutter it collapses into) -->\n<ng-template #detailsTopBarActions>\n <ymbpm-pane-toggle-button\n align=\"start\"\n icon=\"right_panel_close\"\n [tooltip]=\"'yuv.app.bpm-management.pane.hideDetails.tooltip' | translate\"\n (toggled)=\"split.hideArea(Area.DETAILS)\" />\n</ng-template>\n", styles: ["@charset \"UTF-8\";ymt-badge{--ymt-badge-corner: var(--ymt-corner-xs);--badge-icon-size: var(--ymt-sizing-xs);display:inline-flex;align-items:center;gap:var(--ymt-spacing-xs);flex-shrink:0;min-width:0;max-width:100%}ymt-badge mat-icon{width:var(--badge-icon-size);height:var(--badge-icon-size);font-size:var(--badge-icon-size);line-height:1}.mat-mdc-menu-item[aria-checked=true]{background:var(--ymt-primary-container);--mat-menu-item-label-text-color: var(--ymt-on-primary-container);--mat-menu-item-icon-color: var(--ymt-on-primary-container)}.mat-mdc-menu-item.radio-item[aria-checked=true]{background:none;--mat-menu-item-label-text-color: unset;--mat-menu-item-icon-color: unset}.mat-mdc-menu-item.radio-item[aria-checked=true] .mat-icon{scale:.5}yuv-simple-search ::ng-deep .mat-mdc-form-field-infix{width:auto}yuv-simple-search ::ng-deep [inert=true]{display:none}:host{display:flex;flex-flow:column;height:100%;overflow:hidden}:host .bpmmgmt-main__content{flex:1;min-height:0;display:flex;flex-flow:row;overflow:hidden;gap:var(--ymt-spacing-s);padding:var(--ymt-spacing-m)}:host .content-split{flex:1;min-width:0}:host ymt-pane-footer{--footer-block-padding: 0;--footer-inline-padding: 0}:host .paginator{flex:1;background:transparent}:host .quick-toggle{--mat-button-toggle-height: 32px;--mat-button-toggle-shape: 999px;--mat-button-toggle-divider-color: transparent;--mat-button-toggle-background-color: var(--ymt-surface-container-high);--mat-button-toggle-selected-state-background-color: var(--ymt-primary-container);--mat-button-toggle-selected-state-text-color: var(--ymt-on-primary-container);border-color:transparent}:host .items{display:block}:host .item{display:flex;align-items:center;gap:var(--ymt-spacing-xs);padding:var(--ymt-spacing-s) var(--ymt-spacing-xs) var(--ymt-spacing-s) var(--ymt-spacing-m);border-bottom:var(--ymt-outline-width) solid var(--ymt-outline-variant);cursor:pointer}:host .item:hover:not(.selected){background-color:var(--ymt-hover-background)}:host .item.selected{background-color:var(--ymt-selection-background);color:var(--ymt-on-selection-background)}:host .item.item--suspended:not(.selected){color:var(--ymt-text-color-subtle)}:host .items:focus-visible .item[aria-current=true]{outline:var(--ymt-focus-indicator-size) solid var(--ymt-primary);outline-offset:calc(-1 * var(--ymt-focus-indicator-size))}:host .items:focus-within .item.selected{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}:host .items:focus-within .item.selected .item__meta{color:var(--ymt-on-primary-container)}:host .item__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--ymt-spacing-3xs)}:host .item__title{display:flex;min-width:0;font:var(--ymt-font-title-smallest)}:host .item__title>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .item__meta{display:flex;align-items:center;gap:var(--ymt-spacing-xs);min-width:0;min-height:1lh;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}:host .item__meta>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .item__meta>span:first-child{flex:0 0 auto;font-variant-numeric:tabular-nums}:host .item__meta>span:not(:first-child){flex:0 1 auto;min-width:0}:host .item__meta>span+span:before{content:\"\\b7\";margin-inline-end:var(--ymt-spacing-xs)}:host .item__meta>.item__iconed{display:inline-flex;align-items:center;gap:var(--ymt-spacing-2xs)}:host .item__meta>.item__iconed mat-icon{flex:none;width:var(--ymt-sizing-xs);height:var(--ymt-sizing-xs);font-size:var(--ymt-sizing-xs)}:host .item__meta>.item__iconed.item__ended{flex:none}:host .item__user{display:inline-flex;align-items:center}:host .item__user yuv-organization-renderer{min-width:0}:host .item__user yuv-organization-renderer ::ng-deep .node{border:0;padding:0;overflow:hidden;text-overflow:ellipsis}:host .item__chips{flex:0 0 auto;display:flex;align-items:center;gap:var(--ymt-spacing-2xs)}:host .item__state{min-width:10ch;justify-content:center}:host .item__menu{flex:none;display:inline-flex;align-items:center;justify-content:center;width:var(--ymt-sizing-xl);height:var(--ymt-sizing-xl);border-radius:var(--ymt-corner-full);color:var(--ymt-text-color-subtle)}:host .item__menu:hover,:host .item__menu[aria-expanded=true]{background-color:var(--ymt-hover-background);color:inherit}:host .list-body{display:flex;flex-flow:column}:host .empty-state{display:grid;justify-items:center;align-items:center;align-content:center;gap:var(--ymt-spacing-m);height:100%;padding:0 var(--ymt-spacing-3xl);text-align:center;color:var(--ymt-text-color-subtle);flex:1;min-height:0;height:auto}:host .empty-state-icon{width:var(--ymt-sizing-5xl);height:var(--ymt-sizing-5xl);border-radius:var(--ymt-corner-full);background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container);display:flex;align-items:center;justify-content:center;flex-shrink:0}:host .empty-state-description{font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle);max-width:32ch;margin:0}\n"] }]
2722
+ }], ctorParameters: () => [], propDecorators: { filterBar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FilterBarComponent), { isSignal: true }] }], list: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ListComponent), { isSignal: true }] }], rowMenuTriggers: [{ type: i0.ViewChildren, args: ['rowMenuTrigger', { ...{ read: MatMenuTrigger }, isSignal: true }] }] } });
2721
2723
  const sortField = (value) => ({ value, label: `yuv.app.bpm-management.sort.${value}` });
2722
2724
  const quickFilters = (entity, ...values) => values.map(value => ({ value, label: `yuv.app.bpm-management.statusFilter.${entity}.${value}` }));
2723
2725
  const QUICK_FILTERS = {
@@ -2743,5 +2745,5 @@ const YuvBpmManagementRoutes = [
2743
2745
  * Generated bundle index. Do not edit.
2744
2746
  */
2745
2747
 
2746
- export { APP_ICONS, APP_ID, BPM_ENTITIES, BPM_ENTITY_META, FILTER_OPERATORS, FILTER_TYPES, ProcessDefinitionScope, ProcessDefinitionStatus, ProcessStatus, TaskStatus, YuvBpmManagementRoutes, YuvBpmManagementService, definitionIcon, definitionSeverity, definitionStatusLabel, formatDateTime, processSeverity, processStatusIcon, processStatusLabel, taskSeverity, taskStatusIcon, taskStatusLabel };
2748
+ export { APP_ICONS, APP_ID, BPM_ENTITIES, BPM_ENTITY_META, FILTER_OPERATORS, FILTER_TYPES, ProcessDefinitionScope, ProcessDefinitionStatus, ProcessStatus, TaskStatus, YuvBpmManagementRoutes, YuvBpmManagementService, definitionIcon, definitionScope, definitionSeverity, definitionStatusLabel, formatDateTime, processSeverity, processStatusIcon, processStatusLabel, taskSeverity, taskStatusIcon, taskStatusLabel };
2747
2749
  //# sourceMappingURL=yuuvis-bpm-management-app.mjs.map