@yuuvis/app-inbox 0.14.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,12 @@
1
1
  import { OnInit } from '@angular/core';
2
- import { DmsObject, SystemService } from '@yuuvis/client-core';
2
+ import { DmsObject, SystemService, TranslateService } from '@yuuvis/client-core';
3
3
  import { ActionContext } from '@yuuvis/client-framework/actions';
4
4
  import { StartFormComponent } from './start-form/start-form.component';
5
5
  import { StartAdhocComponent } from './start-adhoc/start-adhoc.component';
6
6
  import * as i0 from "@angular/core";
7
7
  export declare class StartProcessComponent implements OnInit {
8
8
  #private;
9
+ readonly translate: TranslateService;
9
10
  readonly system: SystemService;
10
11
  processDefinitions: import("@angular/core").WritableSignal<ProcessDefinition[]>;
11
12
  selectedProcess: import("@angular/core").WritableSignal<ProcessDefinition | null>;
@@ -14,9 +15,10 @@ export declare class StartProcessComponent implements OnInit {
14
15
  busy: import("@angular/core").WritableSignal<boolean>;
15
16
  startForm: import("@angular/core").Signal<StartFormComponent | undefined>;
16
17
  startAdhoc: import("@angular/core").Signal<StartAdhocComponent | undefined>;
17
- startComponent: 'adhoc' | 'form' | undefined;
18
+ startComponent: 'adhoc' | 'form' | 'formless' | undefined;
18
19
  itemSelected(idx: number[]): void;
19
20
  start(): void;
21
+ startFormlessProcess(): void;
20
22
  resetSelectedProcess(): void;
21
23
  cancel(): void;
22
24
  close(res?: any): void;
@@ -3,19 +3,19 @@
3
3
  "io.yuuvis.app.inbox.action.start-process.description": "Starts a process.",
4
4
  "io.yuuvis.app.inbox.actions.startProcess.button.start": "Start",
5
5
  "io.yuuvis.app.inbox.actions.startProcess.button.cancel": "Cancel",
6
- "io.yuuvis.app.inbox.actions.startProcess.success": "Process \"{{processName}}\" has been started.",
7
- "io.yuuvis.app.inbox.actions.startProcess.error": "Process \"{{processName}}\" could not be started.",
8
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.description": "",
9
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.error.message": "Unable to start task list.",
10
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.form.notifyInitiator": "Notify when done",
11
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.form.title": "Subject",
12
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.label": "Create task list",
13
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.description": "Create a list of tasks and recipients.",
14
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.tasklist.message": "Select the recipients and tasks.",
15
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.delete": "Delete template",
16
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.save": "Save template",
17
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save": "Add as new template",
18
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save.not-unique.tooltip": "A template with this name already exists",
19
- "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.title": "Create task list",
20
- "io.yuuvis.app.inbox.templates.none": "Without template"
21
- }
6
+ "io.yuuvis.app.inbox.actions.startProcess.success": "Process \"{{processName}}\" has been started.",
7
+ "io.yuuvis.app.inbox.actions.startProcess.error": "Process \"{{processName}}\" could not be started.",
8
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.description": "",
9
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.error.message": "Unable to start task list.",
10
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.form.notifyInitiator": "Notify when done",
11
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.form.title": "Subject",
12
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.label": "Create task list",
13
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.description": "Create a list of tasks and recipients.",
14
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.tasklist.message": "Select the recipients and tasks.",
15
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.delete": "Delete template",
16
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.save": "Save template",
17
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save": "Add as new template",
18
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save.not-unique.tooltip": "A template with this name already exists.",
19
+ "io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.title": "Create task list",
20
+ "io.yuuvis.app.inbox.templates.none": "Without template"
21
+ }
@@ -12,12 +12,13 @@ import * as i3 from '@angular/material/icon';
12
12
  import { MatIconModule } from '@angular/material/icon';
13
13
  import { MatProgressBar } from '@angular/material/progress-bar';
14
14
  import * as i2 from '@yuuvis/client-core';
15
- import { BackendService, NotificationService, TranslateService, SystemService, ApiBase, TranslateModule, UserStorageService, PendingChangesService, Utils, UserService } from '@yuuvis/client-core';
15
+ import { NotificationService, TranslateService, SystemService, TranslateModule, UserStorageService, PendingChangesService, Utils, BackendService, UserService, ApiBase } from '@yuuvis/client-core';
16
16
  import { DialogComponent } from '@yuuvis/client-framework/common';
17
17
  import { ListComponent, ListItemDirective } from '@yuuvis/client-framework/list';
18
18
  import { YmtButtonDirective } from '@yuuvis/material';
19
19
  import { ObjectFormComponent } from '@yuuvis/client-framework/object-form';
20
20
  import { AppInboxUtils, APP_INBOX_ID, APP_INBOX_PROCESSES, TASK_VAR_APP_ID } from '@yuuvis/app-inbox/shared';
21
+ import { AppInboxService } from '@yuuvis/app-inbox';
21
22
  import { CdkTrapFocus } from '@angular/cdk/a11y';
22
23
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
23
24
  import * as i5 from '@angular/forms';
@@ -33,10 +34,10 @@ import { StringComponent } from '@yuuvis/client-framework/forms';
33
34
  import { SequenceListComponent } from '@yuuvis/client-framework/sequence-list';
34
35
 
35
36
  class StartFormComponent {
36
- #backend = inject(BackendService);
37
37
  #notificationService = inject(NotificationService);
38
38
  translate = inject(TranslateService);
39
39
  system = inject(SystemService);
40
+ #inboxService = inject(AppInboxService);
40
41
  busy = signal(false);
41
42
  selectedProcess = input();
42
43
  object = input();
@@ -49,7 +50,7 @@ class StartFormComponent {
49
50
  const p = this.selectedProcess();
50
51
  untracked(() => {
51
52
  this.busy.set(true);
52
- this.#backend.get(`/bpm-engine/api/process-definitions/${p?.id}/start-form`, ApiBase.none).subscribe({
53
+ this.#inboxService.getStartForm(p?.id).subscribe({
53
54
  next: (res) => {
54
55
  this.busy.set(false);
55
56
  const formModel = AppInboxUtils.fixFormModel(res);
@@ -80,7 +81,7 @@ class StartFormComponent {
80
81
  const formElements = of.getFormElements();
81
82
  const variables = Object.keys(formData).map((key) => AppInboxUtils.getProcessVariables(formData[key], formElements[key], key));
82
83
  const o = this.object();
83
- const attachments = o?.id ? [o.id] : [];
84
+ const attachments = o?.id ? [{ objectId: o.id }] : [];
84
85
  const subject = variables.find(variable => variable.name === 'title')?.value;
85
86
  const payload = {
86
87
  processDefinitionKey: process.key,
@@ -89,7 +90,7 @@ class StartFormComponent {
89
90
  attachments,
90
91
  };
91
92
  this.busy.set(true);
92
- this.#startProcess(payload)
93
+ this.#inboxService.startProcess(payload)
93
94
  .pipe(finalize(() => this.busy.set(false)))
94
95
  .subscribe({
95
96
  next: (res) => {
@@ -102,18 +103,11 @@ class StartFormComponent {
102
103
  },
103
104
  });
104
105
  }
105
- /**
106
- * Start a process. This will create a new process instance.
107
- * @param payload Payload to be send with the start process request (may contain attachments, a new subject or variables)
108
- */
109
- #startProcess(payload) {
110
- return this.#backend.post(`/bpm/processes`, payload);
111
- }
112
106
  resetSelectedProcess() {
113
107
  this.onReset.emit();
114
108
  }
115
109
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: StartFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
116
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.14", type: StartFormComponent, isStandalone: true, selector: "ymi-start-form", inputs: { selectedProcess: { classPropertyName: "selectedProcess", publicName: "selectedProcess", isSignal: true, isRequired: false, transformFunction: null }, object: { classPropertyName: "object", publicName: "object", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { finished: "finished", onReset: "onReset" }, viewQueries: [{ propertyName: "startForm", first: true, predicate: ObjectFormComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<main>\n <div class=\"header\">\n <button\n mat-icon-button\n [disabled]=\"busy()\"\n (click)=\"resetSelectedProcess()\"\n >\n <mat-icon>arrow_back</mat-icon>\n </button>\n <h3>\n {{\n system.getLocalizedLabel(selectedProcess()?.key!) || selectedProcess()?.key ||\n (\"io.yuuvis.app.inbox.action.start-process.label\" | translate)\n }}\n </h3>\n </div>\n <mat-progress-bar\n mode=\"indeterminate\"\n [ngClass]=\"{ busy: busy() }\"\n ></mat-progress-bar>\n <div class=\"form\">\n <yuv-object-form\n #startForm\n [formOptions]=\"startFormOptions()\"\n (statusChanged)=\"onFormStatusChanged($event)\"\n ></yuv-object-form>\n </div>\n</main>\n", styles: ["main{flex:1;overflow:hidden;min-height:200px}main mat-progress-bar{position:absolute;z-index:1;opacity:0}main mat-progress-bar.busy{opacity:1}main .header{flex:0 0 auto;display:flex;align-items:center;padding:var(--ymt-spacing-xs);gap:var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant)}main .header h3{margin:0}main .form{padding:var(--ymt-spacing-xs);flex:1;overflow-y:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ObjectFormComponent, selector: "yuv-object-form", inputs: ["formOptions", "inert", "elementExtensions", "isInnerTableForm"], outputs: ["statusChanged", "onFormReady"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
110
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.14", type: StartFormComponent, isStandalone: true, selector: "ymi-start-form", inputs: { selectedProcess: { classPropertyName: "selectedProcess", publicName: "selectedProcess", isSignal: true, isRequired: false, transformFunction: null }, object: { classPropertyName: "object", publicName: "object", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { finished: "finished", onReset: "onReset" }, viewQueries: [{ propertyName: "startForm", first: true, predicate: ObjectFormComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<main>\n <div class=\"header\">\n <button\n mat-icon-button\n [disabled]=\"busy()\"\n (click)=\"resetSelectedProcess()\"\n >\n <mat-icon>arrow_back</mat-icon>\n </button>\n <h3>\n {{\n system.getLocalizedLabel(selectedProcess()?.key!) || selectedProcess()?.key ||\n (\"io.yuuvis.app.inbox.action.start-process.label\" | translate)\n }}\n </h3>\n </div>\n <mat-progress-bar\n mode=\"indeterminate\"\n [ngClass]=\"{ busy: busy() }\"\n ></mat-progress-bar>\n <div class=\"form\">\n <yuv-object-form\n #startForm\n [formOptions]=\"startFormOptions()\"\n (statusChanged)=\"onFormStatusChanged($event)\"\n ></yuv-object-form>\n </div>\n</main>\n", styles: ["main{flex:1;overflow:hidden;min-height:200px}main mat-progress-bar{position:absolute;z-index:1;opacity:0}main mat-progress-bar.busy{opacity:1}main .header{flex:0 0 auto;display:flex;align-items:center;padding:var(--ymt-spacing-xs);gap:var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant)}main .header h3{margin:0}main .form{padding:var(--ymt-spacing-xs);flex:1;overflow-y:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ObjectFormComponent, selector: "yuv-object-form", inputs: ["formOptions", "inert", "readonly", "elementExtensions", "isInnerTableForm"], outputs: ["statusChanged", "onFormReady"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
117
111
  }
118
112
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: StartFormComponent, decorators: [{
119
113
  type: Component,
@@ -128,8 +122,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
128
122
  }] });
129
123
 
130
124
  class StartAdhocComponent {
125
+ #notificationService = inject(NotificationService);
131
126
  #fb = inject(FormBuilder);
132
- #backend = inject(BackendService);
127
+ #inboxService = inject(AppInboxService);
133
128
  #userStorage = inject(UserStorageService);
134
129
  #pendingChanges = inject(PendingChangesService);
135
130
  translate = inject(TranslateService);
@@ -222,8 +217,14 @@ class StartAdhocComponent {
222
217
  const { title, tasklist, comment, notifyInitiator } = this.form.value;
223
218
  this.#startAdhocFlow(dmsObject.id, title, tasklist, comment, notifyInitiator)
224
219
  .subscribe({
225
- next: () => this.finished.emit(),
226
- error: (e) => this.error.set(e)
220
+ next: () => {
221
+ this.finished.emit();
222
+ this.#notificationService.success(this.translate.instant('io.yuuvis.app.inbox.actions.startProcess.success', { processName: title }));
223
+ },
224
+ error: (e) => {
225
+ this.error.set(e);
226
+ this.#notificationService.error(this.translate.instant('io.yuuvis.app.inbox.actions.startProcess.error', { processName: title }));
227
+ }
227
228
  })
228
229
  .add(() => this.busy.set(false));
229
230
  }
@@ -253,10 +254,10 @@ class StartAdhocComponent {
253
254
  businessKey: objectID,
254
255
  name: subject,
255
256
  subject,
256
- attachments: [objectID],
257
+ attachments: [{ objectId: objectID }],
257
258
  variables
258
259
  };
259
- return this.#backend.post('/bpm/processes', payload);
260
+ return this.#inboxService.startProcess(payload);
260
261
  }
261
262
  saveTemplate() {
262
263
  if (this.form.invalid || this.nameNotUnique())
@@ -318,7 +319,7 @@ class StartAdhocComponent {
318
319
  });
319
320
  }
320
321
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: StartAdhocComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
321
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: StartAdhocComponent, isStandalone: true, selector: "ymi-start-adhoc", inputs: { actionContext: { classPropertyName: "actionContext", publicName: "actionContext", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { finished: "finished" }, host: { properties: { "class.busy": "busy()" } }, ngImport: i0, template: "<mat-progress-bar mode=\"indeterminate\" class=\"progress-bar\"></mat-progress-bar>\n<form [formGroup]=\"form\" cdkTrapFocus>\n <header>\n <p>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.description' | translate }}</p>\n <div class=\"templateSelect\">\n <mat-select formControlName=\"id\" panelWidth=\"null\">\n @for (o of templateOptions; track $index) {\n <mat-option [value]=\"o.value\">{{ o.label }}</mat-option>\n }\n </mat-select>\n @if (!form.pristine) {\n <button\n mat-icon-button\n type=\"button\"\n [ngClass]=\"{ nameNotUnique: form.valid && nameNotUnique() }\"\n [matTooltip]=\"\n nameNotUnique()\n ? ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save.not-unique.tooltip' | translate)\n : (form.value.id === NEW_TEMPLATE_ID ? ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save' | translate)\n : ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.save' | translate))\n \"\n [disabled]=\"form.invalid || nameNotUnique()\"\n class=\"icon save ymt-icon-button--size-s\"\n (click)=\"saveTemplate()\"\n >\n @if (form.value.id === NEW_TEMPLATE_ID) {\n <mat-icon>add</mat-icon>\n } @else {\n <mat-icon>save</mat-icon>\n }\n </button>\n }\n\n @if (form.value.id !== NEW_TEMPLATE_ID) {\n <button\n mat-icon-button\n class=\"icon delete ymt-icon-button--size-s\"\n type=\"button\"\n (click)=\"deleteTemplate()\"\n [matTooltip]=\"'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.delete' | translate\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n </header>\n <main class=\"adhoc-workflow-container\">\n <mat-form-field>\n <mat-label>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.form.title' | translate }}</mat-label>\n <yuv-string [autofocus]=\"true\" [required]=\"true\" formControlName=\"title\"> </yuv-string>\n </mat-form-field>\n\n <p>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.tasklist.message' | translate }}</p>\n\n <yuv-sequence-list formControlName=\"tasklist\" [matTooltip]=\"'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.tasklist.message' | translate\"></yuv-sequence-list>\n\n <mat-checkbox formControlName=\"notifyInitiator\">\n {{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.form.notifyInitiator' | translate }}\n </mat-checkbox>\n\n @if (error()) {\n <p class=\"error\">{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.error.message' | translate }}</p>\n }\n </main>\n</form>\n", styles: [":host .progress-bar{position:absolute;inset-block-start:0;inset-inline-start:0;inset-inline-end:0}:host:not(.busy) .progress-bar{opacity:0}:host form{display:flex;flex-flow:column;height:100%;min-width:300px;padding:var(--ymt-spacing-xl);padding-top:var(--ymt-spacing-m)}:host form header .templateSelect{display:grid;grid-template-columns:1fr auto auto;grid-template-areas:\"select save delete\";gap:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs);border:1px solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-s);background-color:var(--ymt-surface);align-items:center}:host form header .templateSelect mat-select{grid-area:select;justify-self:start}:host form header .templateSelect button.save{grid-area:save;pointer-events:visible}:host form header .templateSelect button.delete{grid-area:delete;--icon-size: 18px}:host form header .templateSelect button:disabled:not(.nameNotUnique){opacity:0}:host form main.adhoc-workflow-container{display:block;margin-block-start:var(--ymt-spacing-m)}:host form main.adhoc-workflow-container .error{background-color:var(--ymt-danger-container);color:var(--ymt-on-danger-container);padding:var(--ymt-spacing-xs);border-radius:var(--ymt-spacing-xs)}:host form main.adhoc-workflow-container mat-form-field{display:block}:host form main.adhoc-workflow-container yuv-sequence-list{display:block;margin:var(--ymt-spacing-3xl) auto;max-width:60ch}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i4.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: StringComponent, selector: "yuv-string", inputs: ["multiselect", "rows", "readonly", "autofocus", "classifications", "situation", "regex", "minLength", "maxLength"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i7.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: SequenceListComponent, selector: "yuv-sequence-list", inputs: ["maxLength"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }] });
322
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: StartAdhocComponent, isStandalone: true, selector: "ymi-start-adhoc", inputs: { actionContext: { classPropertyName: "actionContext", publicName: "actionContext", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { finished: "finished" }, host: { properties: { "class.busy": "busy()" } }, ngImport: i0, template: "<mat-progress-bar mode=\"indeterminate\" class=\"progress-bar\"></mat-progress-bar>\n<form [formGroup]=\"form\" cdkTrapFocus>\n <header>\n <p>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.description' | translate }}</p>\n <div class=\"templateSelect\">\n <mat-select formControlName=\"id\" panelWidth=\"null\">\n @for (o of templateOptions; track $index) {\n <mat-option [value]=\"o.value\">{{ o.label }}</mat-option>\n }\n </mat-select>\n @if (!form.pristine) {\n <button\n mat-icon-button\n type=\"button\"\n [ngClass]=\"{ nameNotUnique: form.valid && nameNotUnique() }\"\n [matTooltip]=\"\n nameNotUnique()\n ? ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save.not-unique.tooltip' | translate)\n : (form.value.id === NEW_TEMPLATE_ID ? ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save' | translate)\n : ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.save' | translate))\n \"\n [disabled]=\"form.invalid || nameNotUnique()\"\n class=\"icon save ymt-icon-button--size-s\"\n (click)=\"saveTemplate()\"\n >\n @if (form.value.id === NEW_TEMPLATE_ID) {\n <mat-icon>add</mat-icon>\n } @else {\n <mat-icon>save</mat-icon>\n }\n </button>\n }\n\n @if (form.value.id !== NEW_TEMPLATE_ID) {\n <button\n mat-icon-button\n class=\"icon delete ymt-icon-button--size-s\"\n type=\"button\"\n (click)=\"deleteTemplate()\"\n [matTooltip]=\"'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.delete' | translate\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n </header>\n <main class=\"adhoc-workflow-container\">\n <mat-form-field>\n <mat-label>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.form.title' | translate }}</mat-label>\n <yuv-string [autofocus]=\"true\" [required]=\"true\" formControlName=\"title\"> </yuv-string>\n </mat-form-field>\n\n <p>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.tasklist.message' | translate }}</p>\n\n <yuv-sequence-list formControlName=\"tasklist\" [matTooltip]=\"'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.tasklist.message' | translate\"></yuv-sequence-list>\n\n <mat-checkbox formControlName=\"notifyInitiator\">\n {{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.form.notifyInitiator' | translate }}\n </mat-checkbox>\n\n @if (error()) {\n <p class=\"error\">{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.error.message' | translate }}</p>\n }\n </main>\n</form>\n", styles: [":host .progress-bar{position:absolute;inset-block-start:0;inset-inline-start:0;inset-inline-end:0}:host:not(.busy) .progress-bar{opacity:0}:host form{display:flex;flex-flow:column;height:100%;min-width:300px;padding:var(--ymt-spacing-xl);padding-top:var(--ymt-spacing-m)}:host form header{flex:0 0 auto}:host form header .templateSelect{display:grid;grid-template-columns:1fr auto auto;grid-template-areas:\"select save delete\";gap:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs);border:1px solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-s);background-color:var(--ymt-surface);align-items:center}:host form header .templateSelect mat-select{grid-area:select;justify-self:start}:host form header .templateSelect button.save{grid-area:save;pointer-events:visible}:host form header .templateSelect button.delete{grid-area:delete;--icon-size: 18px}:host form header .templateSelect button:disabled:not(.nameNotUnique){opacity:0}:host form main.adhoc-workflow-container{flex:1;display:block;margin-block-start:var(--ymt-spacing-m);display:flex;flex-flow:column;overflow:hidden}:host form main.adhoc-workflow-container .error{background-color:var(--ymt-danger-container);color:var(--ymt-on-danger-container);padding:var(--ymt-spacing-xs);border-radius:var(--ymt-spacing-xs)}:host form main.adhoc-workflow-container mat-form-field{display:block;margin-top:1.5%}:host form main.adhoc-workflow-container yuv-sequence-list{display:block;margin:var(--ymt-spacing-3xl) auto;max-width:60ch;overflow-y:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i4.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: StringComponent, selector: "yuv-string", inputs: ["multiselect", "rows", "readonly", "autofocus", "classifications", "situation", "regex", "minLength", "maxLength"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i7.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: SequenceListComponent, selector: "yuv-sequence-list", inputs: ["maxLength"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }] });
322
323
  }
323
324
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: StartAdhocComponent, decorators: [{
324
325
  type: Component,
@@ -339,12 +340,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
339
340
  StringComponent
340
341
  ], host: {
341
342
  '[class.busy]': 'busy()'
342
- }, template: "<mat-progress-bar mode=\"indeterminate\" class=\"progress-bar\"></mat-progress-bar>\n<form [formGroup]=\"form\" cdkTrapFocus>\n <header>\n <p>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.description' | translate }}</p>\n <div class=\"templateSelect\">\n <mat-select formControlName=\"id\" panelWidth=\"null\">\n @for (o of templateOptions; track $index) {\n <mat-option [value]=\"o.value\">{{ o.label }}</mat-option>\n }\n </mat-select>\n @if (!form.pristine) {\n <button\n mat-icon-button\n type=\"button\"\n [ngClass]=\"{ nameNotUnique: form.valid && nameNotUnique() }\"\n [matTooltip]=\"\n nameNotUnique()\n ? ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save.not-unique.tooltip' | translate)\n : (form.value.id === NEW_TEMPLATE_ID ? ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save' | translate)\n : ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.save' | translate))\n \"\n [disabled]=\"form.invalid || nameNotUnique()\"\n class=\"icon save ymt-icon-button--size-s\"\n (click)=\"saveTemplate()\"\n >\n @if (form.value.id === NEW_TEMPLATE_ID) {\n <mat-icon>add</mat-icon>\n } @else {\n <mat-icon>save</mat-icon>\n }\n </button>\n }\n\n @if (form.value.id !== NEW_TEMPLATE_ID) {\n <button\n mat-icon-button\n class=\"icon delete ymt-icon-button--size-s\"\n type=\"button\"\n (click)=\"deleteTemplate()\"\n [matTooltip]=\"'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.delete' | translate\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n </header>\n <main class=\"adhoc-workflow-container\">\n <mat-form-field>\n <mat-label>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.form.title' | translate }}</mat-label>\n <yuv-string [autofocus]=\"true\" [required]=\"true\" formControlName=\"title\"> </yuv-string>\n </mat-form-field>\n\n <p>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.tasklist.message' | translate }}</p>\n\n <yuv-sequence-list formControlName=\"tasklist\" [matTooltip]=\"'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.tasklist.message' | translate\"></yuv-sequence-list>\n\n <mat-checkbox formControlName=\"notifyInitiator\">\n {{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.form.notifyInitiator' | translate }}\n </mat-checkbox>\n\n @if (error()) {\n <p class=\"error\">{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.error.message' | translate }}</p>\n }\n </main>\n</form>\n", styles: [":host .progress-bar{position:absolute;inset-block-start:0;inset-inline-start:0;inset-inline-end:0}:host:not(.busy) .progress-bar{opacity:0}:host form{display:flex;flex-flow:column;height:100%;min-width:300px;padding:var(--ymt-spacing-xl);padding-top:var(--ymt-spacing-m)}:host form header .templateSelect{display:grid;grid-template-columns:1fr auto auto;grid-template-areas:\"select save delete\";gap:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs);border:1px solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-s);background-color:var(--ymt-surface);align-items:center}:host form header .templateSelect mat-select{grid-area:select;justify-self:start}:host form header .templateSelect button.save{grid-area:save;pointer-events:visible}:host form header .templateSelect button.delete{grid-area:delete;--icon-size: 18px}:host form header .templateSelect button:disabled:not(.nameNotUnique){opacity:0}:host form main.adhoc-workflow-container{display:block;margin-block-start:var(--ymt-spacing-m)}:host form main.adhoc-workflow-container .error{background-color:var(--ymt-danger-container);color:var(--ymt-on-danger-container);padding:var(--ymt-spacing-xs);border-radius:var(--ymt-spacing-xs)}:host form main.adhoc-workflow-container mat-form-field{display:block}:host form main.adhoc-workflow-container yuv-sequence-list{display:block;margin:var(--ymt-spacing-3xl) auto;max-width:60ch}\n"] }]
343
+ }, template: "<mat-progress-bar mode=\"indeterminate\" class=\"progress-bar\"></mat-progress-bar>\n<form [formGroup]=\"form\" cdkTrapFocus>\n <header>\n <p>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.description' | translate }}</p>\n <div class=\"templateSelect\">\n <mat-select formControlName=\"id\" panelWidth=\"null\">\n @for (o of templateOptions; track $index) {\n <mat-option [value]=\"o.value\">{{ o.label }}</mat-option>\n }\n </mat-select>\n @if (!form.pristine) {\n <button\n mat-icon-button\n type=\"button\"\n [ngClass]=\"{ nameNotUnique: form.valid && nameNotUnique() }\"\n [matTooltip]=\"\n nameNotUnique()\n ? ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save.not-unique.tooltip' | translate)\n : (form.value.id === NEW_TEMPLATE_ID ? ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.new.save' | translate)\n : ('io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.save' | translate))\n \"\n [disabled]=\"form.invalid || nameNotUnique()\"\n class=\"icon save ymt-icon-button--size-s\"\n (click)=\"saveTemplate()\"\n >\n @if (form.value.id === NEW_TEMPLATE_ID) {\n <mat-icon>add</mat-icon>\n } @else {\n <mat-icon>save</mat-icon>\n }\n </button>\n }\n\n @if (form.value.id !== NEW_TEMPLATE_ID) {\n <button\n mat-icon-button\n class=\"icon delete ymt-icon-button--size-s\"\n type=\"button\"\n (click)=\"deleteTemplate()\"\n [matTooltip]=\"'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.template.option.existing.delete' | translate\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n </header>\n <main class=\"adhoc-workflow-container\">\n <mat-form-field>\n <mat-label>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.form.title' | translate }}</mat-label>\n <yuv-string [autofocus]=\"true\" [required]=\"true\" formControlName=\"title\"> </yuv-string>\n </mat-form-field>\n\n <p>{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.tasklist.message' | translate }}</p>\n\n <yuv-sequence-list formControlName=\"tasklist\" [matTooltip]=\"'io.yuuvis.app.inbox.actions.startProcess.adhoc.overlay.tasklist.message' | translate\"></yuv-sequence-list>\n\n <mat-checkbox formControlName=\"notifyInitiator\">\n {{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.form.notifyInitiator' | translate }}\n </mat-checkbox>\n\n @if (error()) {\n <p class=\"error\">{{ 'io.yuuvis.app.inbox.actions.startProcess.adhoc.error.message' | translate }}</p>\n }\n </main>\n</form>\n", styles: [":host .progress-bar{position:absolute;inset-block-start:0;inset-inline-start:0;inset-inline-end:0}:host:not(.busy) .progress-bar{opacity:0}:host form{display:flex;flex-flow:column;height:100%;min-width:300px;padding:var(--ymt-spacing-xl);padding-top:var(--ymt-spacing-m)}:host form header{flex:0 0 auto}:host form header .templateSelect{display:grid;grid-template-columns:1fr auto auto;grid-template-areas:\"select save delete\";gap:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs);border:1px solid var(--ymt-outline-variant);border-radius:var(--ymt-corner-s);background-color:var(--ymt-surface);align-items:center}:host form header .templateSelect mat-select{grid-area:select;justify-self:start}:host form header .templateSelect button.save{grid-area:save;pointer-events:visible}:host form header .templateSelect button.delete{grid-area:delete;--icon-size: 18px}:host form header .templateSelect button:disabled:not(.nameNotUnique){opacity:0}:host form main.adhoc-workflow-container{flex:1;display:block;margin-block-start:var(--ymt-spacing-m);display:flex;flex-flow:column;overflow:hidden}:host form main.adhoc-workflow-container .error{background-color:var(--ymt-danger-container);color:var(--ymt-on-danger-container);padding:var(--ymt-spacing-xs);border-radius:var(--ymt-spacing-xs)}:host form main.adhoc-workflow-container mat-form-field{display:block;margin-top:1.5%}:host form main.adhoc-workflow-container yuv-sequence-list{display:block;margin:var(--ymt-spacing-3xl) auto;max-width:60ch;overflow-y:auto}\n"] }]
343
344
  }], ctorParameters: () => [] });
344
345
 
345
346
  class StartProcessComponent {
346
347
  #backend = inject(BackendService);
348
+ #notificationService = inject(NotificationService);
349
+ translate = inject(TranslateService);
347
350
  system = inject(SystemService);
351
+ #inboxService = inject(AppInboxService);
348
352
  #userService = inject(UserService);
349
353
  #pendingChanges = inject(PendingChangesService);
350
354
  #dialogData = inject(MAT_DIALOG_DATA);
@@ -365,9 +369,12 @@ class StartProcessComponent {
365
369
  if (p.key.includes('adhoc')) {
366
370
  this.startComponent = 'adhoc';
367
371
  }
368
- else {
372
+ else if (p.startFormDefined) {
369
373
  this.startComponent = 'form';
370
374
  }
375
+ else {
376
+ this.startFormlessProcess();
377
+ }
371
378
  }
372
379
  #getAllProcessDefinitions() {
373
380
  let items = [];
@@ -393,6 +400,31 @@ class StartProcessComponent {
393
400
  this.startAdhoc()?.startAdhocFlow();
394
401
  }
395
402
  }
403
+ startFormlessProcess() {
404
+ const process = this.selectedProcess();
405
+ if (!process)
406
+ return;
407
+ const o = this.object();
408
+ const attachments = o?.id ? [{ objectId: o.id }] : [];
409
+ const payload = {
410
+ processDefinitionKey: process.key,
411
+ name: this.system.getLocalizedLabel(process.name) || process.name,
412
+ attachments
413
+ };
414
+ this.busy.set(true);
415
+ this.#inboxService.startProcess(payload)
416
+ .pipe(finalize(() => this.busy.set(false)))
417
+ .subscribe({
418
+ next: (res) => {
419
+ this.close(res);
420
+ this.#notificationService.success(this.translate.instant('io.yuuvis.app.inbox.actions.startProcess.success', { processName: payload.name }));
421
+ },
422
+ error: (err) => {
423
+ console.error('Error starting process:', err);
424
+ this.#notificationService.error(this.translate.instant('io.yuuvis.app.inbox.actions.startProcess.error', { processName: payload.name }));
425
+ },
426
+ });
427
+ }
396
428
  resetSelectedProcess() {
397
429
  this.selectedProcess.set(null);
398
430
  this.startComponent = undefined;
@@ -403,12 +435,15 @@ class StartProcessComponent {
403
435
  }
404
436
  }
405
437
  close(res) {
438
+ this.#pendingChanges.clear();
406
439
  this.#dialogRef.close(res);
407
440
  }
408
441
  ngOnInit() {
409
442
  this.#getAllProcessDefinitions()
410
443
  .pipe(tap((processDefinitions) => {
411
444
  processDefinitions = Array.from(processDefinitions.filter(pD => !pD.suspended)
445
+ // Remove object if key is 'follow-up'
446
+ .filter((p) => p.key !== 'follow-up')
412
447
  // Remove duplicates by key, keeping only the one with the highest version
413
448
  .reduce((acc, cur) => {
414
449
  const prev = acc.get(cur.key);
@@ -423,7 +458,7 @@ class StartProcessComponent {
423
458
  .subscribe();
424
459
  }
425
460
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: StartProcessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
426
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: StartProcessComponent, isStandalone: true, selector: "ymi-start-process", inputs: { object: { classPropertyName: "object", publicName: "object", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "startForm", first: true, predicate: StartFormComponent, descendants: true, isSignal: true }, { propertyName: "startAdhoc", first: true, predicate: StartAdhocComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<yuv-dialog\n [headertitel]=\"'io.yuuvis.app.inbox.action.start-process.label' | translate\"\n>\n <main>\n @if (startComponent === 'form') {\n @let p = selectedProcess();\n <ymi-start-form #startForm [selectedProcess]=\"p\" [object]=\"object()\" (finished)=\"close()\" (onReset)=\"resetSelectedProcess()\"></ymi-start-form>\n } @else if (startComponent === 'adhoc') {\n @let o = object();\n <ymi-start-adhoc #startAdhoc [items]=\"o ? [o] : []\" [actionContext]=\"context()\" (finished)=\"close()\"></ymi-start-adhoc>\n } @else {\n <mat-progress-bar\n mode=\"indeterminate\"\n [ngClass]=\"{ busy: busy() }\"\n ></mat-progress-bar>\n <!-- list of all available processes -->\n <yuv-list (itemSelect)=\"itemSelected($event)\" selectOnEnter=\"true\">\n @for (process of processDefinitions(); track process.id){\n <div yuvListItem>\n {{ system.getLocalizedLabel(process.key) || process.key }}\n <span class=\"desc\">{{ system.getLocalizedDescription(process.key) || process.description }}</span>\n </div>\n }\n </yuv-list>\n }\n </main>\n <footer>\n <button\n ymtButton=\"secondary\"\n type=\"button\"\n (click)=\"cancel()\"\n [disabled]=\"busy()\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.cancel\" | translate }}\n </button>\n <button\n ymtButton=\"primary\"\n [disabled]=\"busy()\"\n (click)=\"start()\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.start\" | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:flex;flex-flow:column;height:100%}:host main{flex:1;overflow:hidden}:host main mat-progress-bar{position:absolute;z-index:1;opacity:0}:host main mat-progress-bar.busy{opacity:1}:host main .header{flex:0 0 auto;display:flex;align-items:center;padding:var(--ymt-spacing-xs);gap:var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant)}:host main .header h3{margin:0}:host main .form{padding:var(--ymt-spacing-xs);flex:1;overflow-y:auto}:host [yuvListItem]{--list-item-hover-background: var(--ymt-focus-background);padding:var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant);font:var(--ymt-font-title-small);cursor:pointer}:host [yuvListItem] span.desc:not(:empty){display:block;max-width:66ch;line-height:1.7em;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: ListComponent, selector: "yuv-list", inputs: ["preventChangeUntil", "multiselect", "selfHandleSelection", "autoSelect", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitel"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: StartFormComponent, selector: "ymi-start-form", inputs: ["selectedProcess", "object"], outputs: ["finished", "onReset"] }, { kind: "component", type: StartAdhocComponent, selector: "ymi-start-adhoc", inputs: ["actionContext", "items"], outputs: ["finished"] }] });
461
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: StartProcessComponent, isStandalone: true, selector: "ymi-start-process", inputs: { object: { classPropertyName: "object", publicName: "object", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "startForm", first: true, predicate: StartFormComponent, descendants: true, isSignal: true }, { propertyName: "startAdhoc", first: true, predicate: StartAdhocComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<yuv-dialog\n [headertitel]=\"'io.yuuvis.app.inbox.action.start-process.label' | translate\"\n>\n <main>\n @if (startComponent === 'form') {\n @let p = selectedProcess();\n <ymi-start-form #startForm [selectedProcess]=\"p\" [object]=\"object()\" (finished)=\"close()\" (onReset)=\"resetSelectedProcess()\"></ymi-start-form>\n } @else if (startComponent === 'adhoc') {\n @let o = object();\n <ymi-start-adhoc #startAdhoc [items]=\"o ? [o] : []\" [actionContext]=\"context()\" (finished)=\"close()\"></ymi-start-adhoc>\n } @else {\n <mat-progress-bar\n mode=\"indeterminate\"\n [ngClass]=\"{ busy: busy() }\"\n ></mat-progress-bar>\n <!-- list of all available processes -->\n <yuv-list (itemSelect)=\"itemSelected($event)\" selectOnEnter=\"true\">\n @for (process of processDefinitions(); track process.id){\n <div yuvListItem>\n {{ system.getLocalizedLabel(process.key) || process.key }}\n <span class=\"desc\">{{ system.getLocalizedDescription(process.key) || process.description }}</span>\n </div>\n }\n </yuv-list>\n }\n </main>\n <footer>\n <button\n ymtButton=\"secondary\"\n type=\"button\"\n (click)=\"cancel()\"\n [disabled]=\"busy()\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.cancel\" | translate }}\n </button>\n <button\n ymtButton=\"primary\"\n [disabled]=\"busy() || startAdhoc()?.form?.invalid || startAdhoc()?.form?.pristine\n || startForm()?.startForm()?.form?.invalid || startForm()?.startForm()?.form?.pristine\"\n (click)=\"start()\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.start\" | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:flex;flex-flow:column;height:100%}:host main{flex:1;overflow:hidden;height:100%}:host main mat-progress-bar{position:absolute;z-index:1;opacity:0}:host main mat-progress-bar.busy{opacity:1}:host main .header{flex:0 0 auto;display:flex;align-items:center;padding:var(--ymt-spacing-xs);gap:var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant)}:host main .header h3{margin:0}:host main .form{padding:var(--ymt-spacing-xs);flex:1;overflow-y:auto}:host [yuvListItem]{--list-item-hover-background: var(--ymt-focus-background);padding:var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant);font:var(--ymt-font-title-small);cursor:pointer}:host [yuvListItem] span.desc:not(:empty){display:block;max-width:66ch;line-height:1.7em;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: ListComponent, selector: "yuv-list", inputs: ["preventChangeUntil", "multiselect", "selfHandleSelection", "autoSelect", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitel"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: StartFormComponent, selector: "ymi-start-form", inputs: ["selectedProcess", "object"], outputs: ["finished", "onReset"] }, { kind: "component", type: StartAdhocComponent, selector: "ymi-start-adhoc", inputs: ["actionContext", "items"], outputs: ["finished"] }] });
427
462
  }
428
463
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: StartProcessComponent, decorators: [{
429
464
  type: Component,
@@ -439,7 +474,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
439
474
  MatProgressBar,
440
475
  StartFormComponent,
441
476
  StartAdhocComponent,
442
- ], template: "<yuv-dialog\n [headertitel]=\"'io.yuuvis.app.inbox.action.start-process.label' | translate\"\n>\n <main>\n @if (startComponent === 'form') {\n @let p = selectedProcess();\n <ymi-start-form #startForm [selectedProcess]=\"p\" [object]=\"object()\" (finished)=\"close()\" (onReset)=\"resetSelectedProcess()\"></ymi-start-form>\n } @else if (startComponent === 'adhoc') {\n @let o = object();\n <ymi-start-adhoc #startAdhoc [items]=\"o ? [o] : []\" [actionContext]=\"context()\" (finished)=\"close()\"></ymi-start-adhoc>\n } @else {\n <mat-progress-bar\n mode=\"indeterminate\"\n [ngClass]=\"{ busy: busy() }\"\n ></mat-progress-bar>\n <!-- list of all available processes -->\n <yuv-list (itemSelect)=\"itemSelected($event)\" selectOnEnter=\"true\">\n @for (process of processDefinitions(); track process.id){\n <div yuvListItem>\n {{ system.getLocalizedLabel(process.key) || process.key }}\n <span class=\"desc\">{{ system.getLocalizedDescription(process.key) || process.description }}</span>\n </div>\n }\n </yuv-list>\n }\n </main>\n <footer>\n <button\n ymtButton=\"secondary\"\n type=\"button\"\n (click)=\"cancel()\"\n [disabled]=\"busy()\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.cancel\" | translate }}\n </button>\n <button\n ymtButton=\"primary\"\n [disabled]=\"busy()\"\n (click)=\"start()\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.start\" | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:flex;flex-flow:column;height:100%}:host main{flex:1;overflow:hidden}:host main mat-progress-bar{position:absolute;z-index:1;opacity:0}:host main mat-progress-bar.busy{opacity:1}:host main .header{flex:0 0 auto;display:flex;align-items:center;padding:var(--ymt-spacing-xs);gap:var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant)}:host main .header h3{margin:0}:host main .form{padding:var(--ymt-spacing-xs);flex:1;overflow-y:auto}:host [yuvListItem]{--list-item-hover-background: var(--ymt-focus-background);padding:var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant);font:var(--ymt-font-title-small);cursor:pointer}:host [yuvListItem] span.desc:not(:empty){display:block;max-width:66ch;line-height:1.7em;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}\n"] }]
477
+ ], template: "<yuv-dialog\n [headertitel]=\"'io.yuuvis.app.inbox.action.start-process.label' | translate\"\n>\n <main>\n @if (startComponent === 'form') {\n @let p = selectedProcess();\n <ymi-start-form #startForm [selectedProcess]=\"p\" [object]=\"object()\" (finished)=\"close()\" (onReset)=\"resetSelectedProcess()\"></ymi-start-form>\n } @else if (startComponent === 'adhoc') {\n @let o = object();\n <ymi-start-adhoc #startAdhoc [items]=\"o ? [o] : []\" [actionContext]=\"context()\" (finished)=\"close()\"></ymi-start-adhoc>\n } @else {\n <mat-progress-bar\n mode=\"indeterminate\"\n [ngClass]=\"{ busy: busy() }\"\n ></mat-progress-bar>\n <!-- list of all available processes -->\n <yuv-list (itemSelect)=\"itemSelected($event)\" selectOnEnter=\"true\">\n @for (process of processDefinitions(); track process.id){\n <div yuvListItem>\n {{ system.getLocalizedLabel(process.key) || process.key }}\n <span class=\"desc\">{{ system.getLocalizedDescription(process.key) || process.description }}</span>\n </div>\n }\n </yuv-list>\n }\n </main>\n <footer>\n <button\n ymtButton=\"secondary\"\n type=\"button\"\n (click)=\"cancel()\"\n [disabled]=\"busy()\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.cancel\" | translate }}\n </button>\n <button\n ymtButton=\"primary\"\n [disabled]=\"busy() || startAdhoc()?.form?.invalid || startAdhoc()?.form?.pristine\n || startForm()?.startForm()?.form?.invalid || startForm()?.startForm()?.form?.pristine\"\n (click)=\"start()\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.start\" | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:flex;flex-flow:column;height:100%}:host main{flex:1;overflow:hidden;height:100%}:host main mat-progress-bar{position:absolute;z-index:1;opacity:0}:host main mat-progress-bar.busy{opacity:1}:host main .header{flex:0 0 auto;display:flex;align-items:center;padding:var(--ymt-spacing-xs);gap:var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant)}:host main .header h3{margin:0}:host main .form{padding:var(--ymt-spacing-xs);flex:1;overflow-y:auto}:host [yuvListItem]{--list-item-hover-background: var(--ymt-focus-background);padding:var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant);font:var(--ymt-font-title-small);cursor:pointer}:host [yuvListItem] span.desc:not(:empty){display:block;max-width:66ch;line-height:1.7em;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}\n"] }]
443
478
  }] });
444
479
 
445
480
  class StartProcessAction extends AbstractContextAction {
@@ -455,7 +490,7 @@ class StartProcessAction extends AbstractContextAction {
455
490
  supports = {};
456
491
  isExecutable(selection) {
457
492
  const o = selection[0];
458
- return of(!!o);
493
+ return of(!!o && !o.isFolder);
459
494
  }
460
495
  run(selection) {
461
496
  this.#dialog.open(StartProcessComponent, {