@yuuvis/app-inbox 0.9.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.
- package/README.md +45 -0
- package/extensions/README.md +3 -0
- package/extensions/index.d.ts +1 -0
- package/extensions/lib/actions/start-process/start-process.action.d.ts +17 -0
- package/extensions/lib/actions/start-process/start-process.component.d.ts +45 -0
- package/extensions/lib/services/extensions.service.d.ts +8 -0
- package/fesm2022/yuuvis-app-inbox-extensions.mjs +208 -0
- package/fesm2022/yuuvis-app-inbox-extensions.mjs.map +1 -0
- package/fesm2022/yuuvis-app-inbox-shared.mjs +93 -0
- package/fesm2022/yuuvis-app-inbox-shared.mjs.map +1 -0
- package/fesm2022/yuuvis-app-inbox.mjs +663 -0
- package/fesm2022/yuuvis-app-inbox.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/app-inbox.component.d.ts +6 -0
- package/lib/app-inbox.service.d.ts +57 -0
- package/lib/components/search/search.component.d.ts +9 -0
- package/lib/components/sort/sort.component.d.ts +33 -0
- package/lib/components/task/task.component.d.ts +23 -0
- package/lib/lib.routes.d.ts +2 -0
- package/lib/pages/inbox/inbox.component.d.ts +52 -0
- package/package.json +32 -0
- package/public-api.d.ts +3 -0
- package/shared/inbox.interface.d.ts +111 -0
- package/shared/inbox.schema.d.ts +3 -0
- package/shared/index.d.ts +3 -0
- package/shared/utils.d.ts +17 -0
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# @yuuvis/app-inbox
|
|
2
|
+
@yuuvis/app-inbox is a yuuvis® MOMENTUM client app that implements a multi-purpose inbox solution.
|
|
3
|
+
|
|
4
|
+
## Installation
|
|
5
|
+
|
|
6
|
+
The app can be installed in a custom client project as follows:
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
npm install @yuuvis/app-inbox --save
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Enable extension
|
|
13
|
+
In your `app.config.ts` add the `InboxExtensions` to the providers:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { InboxExtensions } from '@yuuvis/app-inbox/extensions';
|
|
17
|
+
|
|
18
|
+
export const appConfig: ApplicationConfig = {
|
|
19
|
+
providers: [
|
|
20
|
+
importShellExtensions([
|
|
21
|
+
InboxExtensions
|
|
22
|
+
])
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## Enable app
|
|
29
|
+
In your `app.routes.ts` add a new lazy loaded route for the `@yuuvis/app-inbox` package:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
|
|
33
|
+
export const app: App[] = [
|
|
34
|
+
{
|
|
35
|
+
id: 'io.yuuvis.app.inbox',
|
|
36
|
+
title: 'yuuvis Inbox',
|
|
37
|
+
path: 'inbox',
|
|
38
|
+
iconName: 'move_to_inbox',
|
|
39
|
+
loadChildren: () => import('@yuuvis/app-inbox').then((m) => m.AppInboxRoutes),
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib/services/extensions.service';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { DmsObject } from '@yuuvis/client-core';
|
|
2
|
+
import { AbstractContextAction, Action, ActionSupport, SelectionRange } from '@yuuvis/client-framework/actions';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
export declare class StartProcessAction extends AbstractContextAction implements Action {
|
|
5
|
+
#private;
|
|
6
|
+
private translate;
|
|
7
|
+
id: string;
|
|
8
|
+
label: any;
|
|
9
|
+
description: any;
|
|
10
|
+
priority: number;
|
|
11
|
+
icon: string;
|
|
12
|
+
group: string;
|
|
13
|
+
range: SelectionRange;
|
|
14
|
+
supports: ActionSupport;
|
|
15
|
+
isExecutable(selection: DmsObject[]): Observable<boolean>;
|
|
16
|
+
run(selection: DmsObject[]): Observable<boolean>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { OnInit } from '@angular/core';
|
|
2
|
+
import { DmsObject, TranslateService } from '@yuuvis/client-core';
|
|
3
|
+
import { FormStatusChangedEvent, ObjectFormComponent, ObjectFormOptions } from '@yuuvis/client-framework/object-form';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export declare class StartProcessComponent implements OnInit {
|
|
6
|
+
#private;
|
|
7
|
+
readonly translate: TranslateService;
|
|
8
|
+
startForm: import("@angular/core").Signal<ObjectFormComponent | undefined>;
|
|
9
|
+
processDefinitions: import("@angular/core").WritableSignal<ProcessDefinition[]>;
|
|
10
|
+
selectedProcess: import("@angular/core").WritableSignal<ProcessDefinition | null>;
|
|
11
|
+
startFormOptions: import("@angular/core").WritableSignal<ObjectFormOptions | null>;
|
|
12
|
+
disableControls: import("@angular/core").WritableSignal<boolean>;
|
|
13
|
+
object: import("@angular/core").InputSignal<DmsObject | null>;
|
|
14
|
+
busy: import("@angular/core").WritableSignal<boolean>;
|
|
15
|
+
itemSelected(idx: number[]): void;
|
|
16
|
+
startProcess(of?: ObjectFormComponent): void;
|
|
17
|
+
resetSelectedProcess(): void;
|
|
18
|
+
onFormStatusChanged(evt: FormStatusChangedEvent): void;
|
|
19
|
+
close(): void;
|
|
20
|
+
ngOnInit(): void;
|
|
21
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StartProcessComponent, never>;
|
|
22
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StartProcessComponent, "ymi-start-process", never, { "object": { "alias": "object"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
23
|
+
}
|
|
24
|
+
export interface ProcessDefinition {
|
|
25
|
+
category: string;
|
|
26
|
+
description: string;
|
|
27
|
+
global: boolean;
|
|
28
|
+
id: string;
|
|
29
|
+
key: string;
|
|
30
|
+
name: string;
|
|
31
|
+
startFormDefined: true;
|
|
32
|
+
suspended: false;
|
|
33
|
+
version: number;
|
|
34
|
+
}
|
|
35
|
+
export interface LoggedInUser {
|
|
36
|
+
username: string;
|
|
37
|
+
id: string;
|
|
38
|
+
email: string;
|
|
39
|
+
firstname: string;
|
|
40
|
+
lastname: string;
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
tenant: string;
|
|
43
|
+
authorities: string[];
|
|
44
|
+
displayName: string;
|
|
45
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ClientShellExtension } from '@yuuvis/client-shell-core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class InboxExtensions implements ClientShellExtension {
|
|
4
|
+
#private;
|
|
5
|
+
init(): Promise<any>;
|
|
6
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<InboxExtensions, never>;
|
|
7
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<InboxExtensions>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, viewChild, signal, input, Component, Injectable } from '@angular/core';
|
|
3
|
+
import { AbstractContextAction, SelectionRange, ActionsService } from '@yuuvis/client-framework/actions';
|
|
4
|
+
import { MAT_DIALOG_DATA, MatDialogRef, MatDialog } from '@angular/material/dialog';
|
|
5
|
+
import { TranslateService as TranslateService$1 } from '@ngx-translate/core';
|
|
6
|
+
import { finalize, expand, EMPTY, tap, skipWhile, map, of } from 'rxjs';
|
|
7
|
+
import * as i1 from '@angular/common';
|
|
8
|
+
import { CommonModule } from '@angular/common';
|
|
9
|
+
import * as i3 from '@angular/material/button';
|
|
10
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
11
|
+
import * as i2 from '@angular/material/icon';
|
|
12
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
13
|
+
import { MatProgressBar } from '@angular/material/progress-bar';
|
|
14
|
+
import { AppInboxUtils } from '@yuuvis/app-inbox/shared';
|
|
15
|
+
import * as i4 from '@yuuvis/client-core';
|
|
16
|
+
import { BackendService, TranslateService, UserService, ApiBase, TranslateModule } from '@yuuvis/client-core';
|
|
17
|
+
import { DialogComponent } from '@yuuvis/client-framework/common';
|
|
18
|
+
import { ListComponent, ListItemDirective } from '@yuuvis/client-framework/list';
|
|
19
|
+
import { ObjectFormComponent } from '@yuuvis/client-framework/object-form';
|
|
20
|
+
import { YmtButtonDirective } from '@yuuvis/material';
|
|
21
|
+
|
|
22
|
+
class StartProcessComponent {
|
|
23
|
+
#backend = inject(BackendService);
|
|
24
|
+
translate = inject(TranslateService);
|
|
25
|
+
#userService = inject(UserService);
|
|
26
|
+
#dialogData = inject(MAT_DIALOG_DATA);
|
|
27
|
+
#dialogRef = inject((MatDialogRef));
|
|
28
|
+
startForm = viewChild(ObjectFormComponent);
|
|
29
|
+
processDefinitions = signal([]);
|
|
30
|
+
selectedProcess = signal(null);
|
|
31
|
+
startFormOptions = signal(null);
|
|
32
|
+
disableControls = signal(false);
|
|
33
|
+
object = input(this.#dialogData);
|
|
34
|
+
busy = signal(false);
|
|
35
|
+
itemSelected(idx) {
|
|
36
|
+
this.#onItemSelect(this.processDefinitions()[idx[0]]);
|
|
37
|
+
}
|
|
38
|
+
#onItemSelect(p) {
|
|
39
|
+
this.busy.set(true);
|
|
40
|
+
this.selectedProcess.set(p);
|
|
41
|
+
const formKey = `${p.key}-startform`;
|
|
42
|
+
this.#backend.get(`/resources/config/${formKey}`).subscribe({
|
|
43
|
+
next: (res) => {
|
|
44
|
+
this.busy.set(false);
|
|
45
|
+
const formModel = AppInboxUtils.fixFormModel(res.tenant || res.global);
|
|
46
|
+
this.startFormOptions.set(formModel
|
|
47
|
+
? {
|
|
48
|
+
formModel,
|
|
49
|
+
data: {},
|
|
50
|
+
}
|
|
51
|
+
: null);
|
|
52
|
+
},
|
|
53
|
+
error: (err) => {
|
|
54
|
+
this.busy.set(false);
|
|
55
|
+
console.error('Error fetching start form:', err);
|
|
56
|
+
this.startFormOptions.set(null);
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
startProcess(of) {
|
|
61
|
+
const process = this.selectedProcess();
|
|
62
|
+
if (!of || !process)
|
|
63
|
+
return;
|
|
64
|
+
const formData = of.getFormData();
|
|
65
|
+
const formElements = of.getFormElements();
|
|
66
|
+
const variables = Object.keys(formData).map((key) => AppInboxUtils.getProcessVariables(formData[key], formElements[key], key));
|
|
67
|
+
const o = this.object();
|
|
68
|
+
const attachments = o?.id ? [o.id] : [];
|
|
69
|
+
const payload = {
|
|
70
|
+
processDefinitionKey: process.key,
|
|
71
|
+
variables,
|
|
72
|
+
name: this.translate.instant(process.name) || process.name,
|
|
73
|
+
attachments,
|
|
74
|
+
};
|
|
75
|
+
this.busy.set(true);
|
|
76
|
+
this.#startProcess(payload)
|
|
77
|
+
.pipe(finalize(() => this.busy.set(false)))
|
|
78
|
+
.subscribe({
|
|
79
|
+
next: (res) => {
|
|
80
|
+
this.#dialogRef.close(res);
|
|
81
|
+
},
|
|
82
|
+
error: (err) => {
|
|
83
|
+
console.error('Error starting process:', err);
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Start a process. This will create a new process instance.
|
|
89
|
+
* @param payload Payload to be send with the start process request (may contain attachments, a new subject or variables)
|
|
90
|
+
*/
|
|
91
|
+
#startProcess(payload) {
|
|
92
|
+
return this.#backend.post(`/bpm/processes`, payload);
|
|
93
|
+
}
|
|
94
|
+
resetSelectedProcess() {
|
|
95
|
+
this.startFormOptions.set(null);
|
|
96
|
+
this.selectedProcess.set(null);
|
|
97
|
+
}
|
|
98
|
+
onFormStatusChanged(evt) {
|
|
99
|
+
this.disableControls.set(evt.invalid);
|
|
100
|
+
}
|
|
101
|
+
#getAllProcessDefinitions() {
|
|
102
|
+
let items = [];
|
|
103
|
+
let i = 0;
|
|
104
|
+
const currentUserId = this.#userService.getCurrentUser().id;
|
|
105
|
+
this.busy.set(true);
|
|
106
|
+
return this.#getPage(currentUserId, i).pipe(expand((res) => {
|
|
107
|
+
i++;
|
|
108
|
+
return res.hasMoreItems ? this.#getPage(currentUserId, i) : EMPTY;
|
|
109
|
+
}), tap((res) => {
|
|
110
|
+
// TODO: this.#iconRegistry.addSvgIconLiteralInNamespace(
|
|
111
|
+
items = [...items, ...res.objects];
|
|
112
|
+
}), skipWhile((res) => res.hasMoreItems), map(() => items), finalize(() => this.busy.set(false)));
|
|
113
|
+
}
|
|
114
|
+
#getPage(startableByUser, index, category) {
|
|
115
|
+
return this.#backend.get(`/bpm-engine/api/process-definitions?page=${index}&startableByUser=${startableByUser}`, ApiBase.none);
|
|
116
|
+
}
|
|
117
|
+
close() {
|
|
118
|
+
this.#dialogRef.close();
|
|
119
|
+
}
|
|
120
|
+
ngOnInit() {
|
|
121
|
+
this.#getAllProcessDefinitions()
|
|
122
|
+
.pipe(tap((processDefinitions) => {
|
|
123
|
+
processDefinitions = Array.from(processDefinitions
|
|
124
|
+
// Remove object if key is 'follow-up' or 'osdrive_adhoc_demo';
|
|
125
|
+
.filter((p) => p.key !== 'follow-up' && p.key !== 'osdrive_adhoc_demo')
|
|
126
|
+
// Remove duplicates by key, keeping only the one with the highest version
|
|
127
|
+
.reduce((acc, cur) => {
|
|
128
|
+
const prev = acc.get(cur.key);
|
|
129
|
+
if (!prev || cur.version > prev.version) {
|
|
130
|
+
acc.set(cur.key, cur);
|
|
131
|
+
}
|
|
132
|
+
return acc;
|
|
133
|
+
}, new Map())
|
|
134
|
+
.values());
|
|
135
|
+
this.processDefinitions.set(processDefinitions || []);
|
|
136
|
+
}))
|
|
137
|
+
.subscribe();
|
|
138
|
+
}
|
|
139
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: StartProcessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
140
|
+
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: ObjectFormComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@let sfo = startFormOptions();\n\n<yuv-dialog\n [headertitel]=\"'io.yuuvis.app.inbox.action.start-process.label' | translate\"\n>\n <!-- eader>\n <h2>{{ selectedProcess()?.name }}</h2>\n } @else {\n <h2>{{ \"io.yuuvis.app.inbox.action.start-process.label\" | translate }}</h2>\n }\n </header> -->\n\n <main>\n @if(sfo) {\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 selectedProcess()?.name ||\n (\"io.yuuvis.app.inbox.action.start-process.label\" | translate)\n }}\n </h3>\n </div>\n }\n\n <mat-progress-bar\n mode=\"indeterminate\"\n [ngClass]=\"{ busy: busy() }\"\n ></mat-progress-bar>\n\n @if(sfo) {\n <!-- start form of the selected process -->\n <div class=\"form\">\n <yuv-object-form\n #startForm\n [formOptions]=\"sfo\"\n (statusChanged)=\"onFormStatusChanged($event)\"\n ></yuv-object-form>\n </div>\n } @else {\n <!-- list of all available processes -->\n <yuv-list (itemSelect)=\"itemSelected($event)\">\n @for(process of processDefinitions(); track process.id){\n <div yuvListItem>\n {{ process.name }}\n <span class=\"desc\">{{ process.description }}</span>\n </div>\n }\n </yuv-list>\n }\n </main>\n\n <footer>\n <button\n ymtButton=\"secondary\"\n type=\"button\"\n (click)=\"close()\"\n [disabled]=\"busy()\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.cancel\" | translate }}\n </button>\n\n @if(sfo) {\n <button\n ymtButton=\"primary\"\n [disabled]=\"disableControls() || busy()\"\n (click)=\"startProcess(startForm())\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.start\" | translate }}\n </button>\n }\n\n <!-- <button class=\"secondary\" [disabled]=\"busy()\" (click)=\"overlayRef.close()\">\n {{\n \"io.yuuvis.app.inbox.actions.startProcess.button.cancel\" | translate\n }}</button -->\n <!-- >} -->\n </footer>\n</yuv-dialog>\n", styles: [":host{display:flex;flex-flow:column;height:100%}:host main{flex:1;overflow:hidden;min-height:200px}: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: "component", type: ObjectFormComponent, selector: "yuv-object-form", inputs: ["formOptions", "inert", "elementExtensions", "isInnerTableForm"], outputs: ["statusChanged", "onFormReady"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: ListComponent, selector: "yuv-list", inputs: ["multiselect", "selfHandleSelection", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i4.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"] }] });
|
|
141
|
+
}
|
|
142
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: StartProcessComponent, decorators: [{
|
|
143
|
+
type: Component,
|
|
144
|
+
args: [{ selector: 'ymi-start-process', standalone: true, imports: [
|
|
145
|
+
CommonModule,
|
|
146
|
+
ObjectFormComponent,
|
|
147
|
+
MatIconModule,
|
|
148
|
+
MatButtonModule,
|
|
149
|
+
ListComponent,
|
|
150
|
+
ListItemDirective,
|
|
151
|
+
TranslateModule,
|
|
152
|
+
DialogComponent,
|
|
153
|
+
YmtButtonDirective,
|
|
154
|
+
MatProgressBar,
|
|
155
|
+
], template: "@let sfo = startFormOptions();\n\n<yuv-dialog\n [headertitel]=\"'io.yuuvis.app.inbox.action.start-process.label' | translate\"\n>\n <!-- eader>\n <h2>{{ selectedProcess()?.name }}</h2>\n } @else {\n <h2>{{ \"io.yuuvis.app.inbox.action.start-process.label\" | translate }}</h2>\n }\n </header> -->\n\n <main>\n @if(sfo) {\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 selectedProcess()?.name ||\n (\"io.yuuvis.app.inbox.action.start-process.label\" | translate)\n }}\n </h3>\n </div>\n }\n\n <mat-progress-bar\n mode=\"indeterminate\"\n [ngClass]=\"{ busy: busy() }\"\n ></mat-progress-bar>\n\n @if(sfo) {\n <!-- start form of the selected process -->\n <div class=\"form\">\n <yuv-object-form\n #startForm\n [formOptions]=\"sfo\"\n (statusChanged)=\"onFormStatusChanged($event)\"\n ></yuv-object-form>\n </div>\n } @else {\n <!-- list of all available processes -->\n <yuv-list (itemSelect)=\"itemSelected($event)\">\n @for(process of processDefinitions(); track process.id){\n <div yuvListItem>\n {{ process.name }}\n <span class=\"desc\">{{ process.description }}</span>\n </div>\n }\n </yuv-list>\n }\n </main>\n\n <footer>\n <button\n ymtButton=\"secondary\"\n type=\"button\"\n (click)=\"close()\"\n [disabled]=\"busy()\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.cancel\" | translate }}\n </button>\n\n @if(sfo) {\n <button\n ymtButton=\"primary\"\n [disabled]=\"disableControls() || busy()\"\n (click)=\"startProcess(startForm())\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.start\" | translate }}\n </button>\n }\n\n <!-- <button class=\"secondary\" [disabled]=\"busy()\" (click)=\"overlayRef.close()\">\n {{\n \"io.yuuvis.app.inbox.actions.startProcess.button.cancel\" | translate\n }}</button -->\n <!-- >} -->\n </footer>\n</yuv-dialog>\n", styles: [":host{display:flex;flex-flow:column;height:100%}:host main{flex:1;overflow:hidden;min-height:200px}: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"] }]
|
|
156
|
+
}] });
|
|
157
|
+
|
|
158
|
+
class StartProcessAction extends AbstractContextAction {
|
|
159
|
+
translate = inject(TranslateService$1);
|
|
160
|
+
#dialog = inject(MatDialog);
|
|
161
|
+
id = 'io.yuuvis.app.inbox.action.start-process';
|
|
162
|
+
label = this.translate.instant('io.yuuvis.app.inbox.action.start-process.label');
|
|
163
|
+
description = this.translate.instant('io.yuuvis.app.inbox.action.start-process.description');
|
|
164
|
+
priority = 2;
|
|
165
|
+
icon = 'flowsheet';
|
|
166
|
+
group = 'common';
|
|
167
|
+
range = SelectionRange.SINGLE_SELECT;
|
|
168
|
+
supports = {};
|
|
169
|
+
isExecutable(selection) {
|
|
170
|
+
const o = selection[0];
|
|
171
|
+
return of(!!o);
|
|
172
|
+
}
|
|
173
|
+
run(selection) {
|
|
174
|
+
this.#dialog.open(StartProcessComponent, {
|
|
175
|
+
minWidth: '400px',
|
|
176
|
+
maxHeight: '90vh',
|
|
177
|
+
data: selection[0],
|
|
178
|
+
});
|
|
179
|
+
return of(true);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
class InboxExtensions {
|
|
184
|
+
#actionsService = inject(ActionsService);
|
|
185
|
+
#actions = [
|
|
186
|
+
{
|
|
187
|
+
id: 'io.yuuvis.app.inbox.action.start-process',
|
|
188
|
+
action: StartProcessAction,
|
|
189
|
+
},
|
|
190
|
+
];
|
|
191
|
+
init() {
|
|
192
|
+
// register actions
|
|
193
|
+
this.#actionsService.registerActions(this.#actions);
|
|
194
|
+
return Promise.resolve();
|
|
195
|
+
}
|
|
196
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: InboxExtensions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
197
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: InboxExtensions });
|
|
198
|
+
}
|
|
199
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: InboxExtensions, decorators: [{
|
|
200
|
+
type: Injectable
|
|
201
|
+
}] });
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Generated bundle index. Do not edit.
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
export { InboxExtensions };
|
|
208
|
+
//# sourceMappingURL=yuuvis-app-inbox-extensions.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yuuvis-app-inbox-extensions.mjs","sources":["../../../../projects/yuuvis/app-inbox/extensions/src/lib/actions/start-process/start-process.component.ts","../../../../projects/yuuvis/app-inbox/extensions/src/lib/actions/start-process/start-process.component.html","../../../../projects/yuuvis/app-inbox/extensions/src/lib/actions/start-process/start-process.action.ts","../../../../projects/yuuvis/app-inbox/extensions/src/lib/services/extensions.service.ts","../../../../projects/yuuvis/app-inbox/extensions/src/yuuvis-app-inbox-extensions.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport {\n Component,\n inject,\n input,\n OnInit,\n signal,\n viewChild,\n} from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatProgressBar } from '@angular/material/progress-bar';\nimport {\n AppInboxUtils,\n ProcessCreatePayload,\n ProcessVariable,\n} from '@yuuvis/app-inbox/shared';\nimport {\n ApiBase,\n BackendService,\n DmsObject,\n TranslateModule,\n TranslateService,\n UserService,\n} from '@yuuvis/client-core';\nimport { DialogComponent } from '@yuuvis/client-framework/common';\nimport {\n ListComponent,\n ListItemDirective,\n} from '@yuuvis/client-framework/list';\nimport {\n FormStatusChangedEvent,\n ObjectFormComponent,\n ObjectFormOptions,\n} from '@yuuvis/client-framework/object-form';\nimport { YmtButtonDirective } from '@yuuvis/material';\nimport { EMPTY, expand, finalize, map, Observable, skipWhile, tap } from 'rxjs';\n\n@Component({\n selector: 'ymi-start-process',\n standalone: true,\n imports: [\n CommonModule,\n ObjectFormComponent,\n MatIconModule,\n MatButtonModule,\n ListComponent,\n ListItemDirective,\n TranslateModule,\n DialogComponent,\n YmtButtonDirective,\n MatProgressBar,\n ],\n templateUrl: './start-process.component.html',\n styleUrl: './start-process.component.scss',\n})\nexport class StartProcessComponent implements OnInit {\n #backend = inject(BackendService);\n readonly translate = inject(TranslateService);\n #userService = inject(UserService);\n #dialogData = inject<DmsObject>(MAT_DIALOG_DATA);\n readonly #dialogRef = inject(MatDialogRef<StartProcessComponent>);\n\n startForm = viewChild(ObjectFormComponent);\n\n processDefinitions = signal<ProcessDefinition[]>([]);\n\n selectedProcess = signal<ProcessDefinition | null>(null);\n startFormOptions = signal<ObjectFormOptions | null>(null);\n disableControls = signal<boolean>(false);\n\n object = input<DmsObject | null>(this.#dialogData);\n busy = signal<boolean>(false);\n\n itemSelected(idx: number[]) {\n this.#onItemSelect(this.processDefinitions()[idx[0]]);\n }\n\n #onItemSelect(p: ProcessDefinition) {\n this.busy.set(true);\n this.selectedProcess.set(p);\n const formKey = `${p.key}-startform`;\n this.#backend.get(`/resources/config/${formKey}`).subscribe({\n next: (res) => {\n this.busy.set(false);\n const formModel = AppInboxUtils.fixFormModel(res.tenant || res.global);\n this.startFormOptions.set(\n formModel\n ? {\n formModel,\n data: {},\n }\n : null\n );\n },\n error: (err) => {\n this.busy.set(false);\n console.error('Error fetching start form:', err);\n this.startFormOptions.set(null);\n },\n });\n }\n\n startProcess(of?: ObjectFormComponent) {\n const process = this.selectedProcess();\n if (!of || !process) return;\n const formData: Record<string, unknown> = of.getFormData();\n const formElements: Record<string, unknown & { type: string }> =\n of.getFormElements();\n const variables: ProcessVariable[] = Object.keys(formData).map((key) =>\n AppInboxUtils.getProcessVariables(formData[key], formElements[key], key)\n );\n\n const o = this.object();\n const attachments = o?.id ? [o.id] : [];\n\n const payload: ProcessCreatePayload = {\n processDefinitionKey: process.key,\n variables,\n name: this.translate.instant(process.name) || process.name,\n attachments,\n };\n\n this.busy.set(true);\n this.#startProcess(payload)\n .pipe(finalize(() => this.busy.set(false)))\n .subscribe({\n next: (res) => {\n this.#dialogRef.close(res);\n },\n error: (err) => {\n console.error('Error starting process:', err);\n },\n });\n }\n /**\n * Start a process. This will create a new process instance.\n * @param payload Payload to be send with the start process request (may contain attachments, a new subject or variables)\n */\n #startProcess(payload: ProcessCreatePayload): Observable<any> {\n return this.#backend.post(`/bpm/processes`, payload);\n }\n\n resetSelectedProcess() {\n this.startFormOptions.set(null);\n this.selectedProcess.set(null);\n }\n\n onFormStatusChanged(evt: FormStatusChangedEvent) {\n this.disableControls.set(evt.invalid);\n }\n\n #getAllProcessDefinitions(): Observable<ProcessDefinition[]> {\n let items: ProcessDefinition[] = [];\n let i = 0;\n const currentUserId = this.#userService.getCurrentUser().id;\n\n this.busy.set(true);\n\n return this.#getPage(currentUserId, i).pipe(\n expand((res: any) => {\n i++;\n return res.hasMoreItems ? this.#getPage(currentUserId, i) : EMPTY;\n }),\n tap((res: any) => {\n // TODO: this.#iconRegistry.addSvgIconLiteralInNamespace(\n items = [...items, ...res.objects];\n }),\n skipWhile((res: any) => res.hasMoreItems),\n map(() => items),\n finalize(() => this.busy.set(false))\n );\n }\n\n #getPage(\n startableByUser: string,\n index?: number,\n category?: string\n ): Observable<any> {\n return this.#backend.get(\n `/bpm-engine/api/process-definitions?page=${index}&startableByUser=${startableByUser}`,\n ApiBase.none\n );\n }\n\n close() {\n this.#dialogRef.close();\n }\n\n ngOnInit(): void {\n this.#getAllProcessDefinitions()\n .pipe(\n tap((processDefinitions) => {\n processDefinitions = Array.from(\n processDefinitions\n // Remove object if key is 'follow-up' or 'osdrive_adhoc_demo';\n .filter(\n (p) => p.key !== 'follow-up' && p.key !== 'osdrive_adhoc_demo'\n )\n // Remove duplicates by key, keeping only the one with the highest version\n .reduce<Map<string, ProcessDefinition>>((acc, cur) => {\n const prev = acc.get(cur.key);\n if (!prev || cur.version > prev.version) {\n acc.set(cur.key, cur);\n }\n return acc;\n }, new Map())\n .values()\n );\n\n this.processDefinitions.set(processDefinitions || []);\n })\n )\n .subscribe();\n }\n}\n\nexport interface ProcessDefinition {\n category: string;\n description: string;\n global: boolean;\n id: string;\n key: string;\n name: string;\n startFormDefined: true;\n suspended: false;\n version: number;\n}\n\nexport interface LoggedInUser {\n username: string;\n id: string;\n email: string;\n firstname: string;\n lastname: string;\n enabled: boolean;\n tenant: string;\n authorities: string[];\n displayName: string;\n}\n","@let sfo = startFormOptions();\n\n<yuv-dialog\n [headertitel]=\"'io.yuuvis.app.inbox.action.start-process.label' | translate\"\n>\n <!-- eader>\n <h2>{{ selectedProcess()?.name }}</h2>\n } @else {\n <h2>{{ \"io.yuuvis.app.inbox.action.start-process.label\" | translate }}</h2>\n }\n </header> -->\n\n <main>\n @if(sfo) {\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 selectedProcess()?.name ||\n (\"io.yuuvis.app.inbox.action.start-process.label\" | translate)\n }}\n </h3>\n </div>\n }\n\n <mat-progress-bar\n mode=\"indeterminate\"\n [ngClass]=\"{ busy: busy() }\"\n ></mat-progress-bar>\n\n @if(sfo) {\n <!-- start form of the selected process -->\n <div class=\"form\">\n <yuv-object-form\n #startForm\n [formOptions]=\"sfo\"\n (statusChanged)=\"onFormStatusChanged($event)\"\n ></yuv-object-form>\n </div>\n } @else {\n <!-- list of all available processes -->\n <yuv-list (itemSelect)=\"itemSelected($event)\">\n @for(process of processDefinitions(); track process.id){\n <div yuvListItem>\n {{ process.name }}\n <span class=\"desc\">{{ process.description }}</span>\n </div>\n }\n </yuv-list>\n }\n </main>\n\n <footer>\n <button\n ymtButton=\"secondary\"\n type=\"button\"\n (click)=\"close()\"\n [disabled]=\"busy()\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.cancel\" | translate }}\n </button>\n\n @if(sfo) {\n <button\n ymtButton=\"primary\"\n [disabled]=\"disableControls() || busy()\"\n (click)=\"startProcess(startForm())\"\n >\n {{ \"io.yuuvis.app.inbox.actions.startProcess.button.start\" | translate }}\n </button>\n }\n\n <!-- <button class=\"secondary\" [disabled]=\"busy()\" (click)=\"overlayRef.close()\">\n {{\n \"io.yuuvis.app.inbox.actions.startProcess.button.cancel\" | translate\n }}</button -->\n <!-- >} -->\n </footer>\n</yuv-dialog>\n","import { inject } from '@angular/core';\nimport { MatDialog } from '@angular/material/dialog';\nimport { TranslateService } from '@ngx-translate/core';\nimport { DmsObject } from '@yuuvis/client-core';\nimport {\n AbstractContextAction,\n Action,\n ActionSupport,\n SelectionRange,\n} from '@yuuvis/client-framework/actions';\nimport { Observable, of } from 'rxjs';\nimport { StartProcessComponent } from './start-process.component';\n\nexport class StartProcessAction\n extends AbstractContextAction\n implements Action\n{\n private translate = inject(TranslateService);\n #dialog = inject(MatDialog);\n\n id = 'io.yuuvis.app.inbox.action.start-process';\n label = this.translate.instant(\n 'io.yuuvis.app.inbox.action.start-process.label'\n );\n description = this.translate.instant(\n 'io.yuuvis.app.inbox.action.start-process.description'\n );\n priority = 2;\n icon = 'flowsheet';\n group = 'common';\n range = SelectionRange.SINGLE_SELECT;\n supports: ActionSupport = {};\n\n isExecutable(selection: DmsObject[]) {\n const o = selection[0];\n return of(!!o);\n }\n\n run(selection: DmsObject[]): Observable<boolean> {\n this.#dialog.open(StartProcessComponent, {\n minWidth: '400px',\n maxHeight: '90vh',\n data: selection[0],\n });\n return of(true);\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { ActionsService } from '@yuuvis/client-framework/actions';\nimport { StartProcessAction } from '../actions/start-process/start-process.action';\nimport { ClientShellExtension } from '@yuuvis/client-shell-core';\n\n@Injectable()\nexport class InboxExtensions implements ClientShellExtension {\n #actionsService = inject(ActionsService);\n #actions = [\n {\n id: 'io.yuuvis.app.inbox.action.start-process',\n action: StartProcessAction,\n },\n ];\n\n init(): Promise<any> {\n // register actions\n this.#actionsService.registerActions(this.#actions);\n return Promise.resolve();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["TranslateService"],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const ProcessAction = {
|
|
2
|
+
complete: 'complete',
|
|
3
|
+
claim: 'claim',
|
|
4
|
+
delegate: 'delegate',
|
|
5
|
+
resolve: 'resolve',
|
|
6
|
+
save: 'save',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
class AppInboxUtils {
|
|
10
|
+
/**
|
|
11
|
+
* Fixes the form model by ensuring that it contains 'core' and 'data' elements.
|
|
12
|
+
* If these elements are missing, they are added to the form model.
|
|
13
|
+
* @param formModel The form model to be fixed.
|
|
14
|
+
* @returns The fixed form model
|
|
15
|
+
*/
|
|
16
|
+
static fixFormModel(formModel) {
|
|
17
|
+
if (!formModel.elements.find((e) => e.name === 'core')) {
|
|
18
|
+
formModel.elements.push({
|
|
19
|
+
name: 'core',
|
|
20
|
+
type: 'o2mGroup',
|
|
21
|
+
elements: [],
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (!formModel.elements.find((e) => e.name === 'data')) {
|
|
25
|
+
formModel.elements.push({
|
|
26
|
+
name: 'data',
|
|
27
|
+
type: 'o2mGroupStack',
|
|
28
|
+
elements: [],
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return formModel;
|
|
32
|
+
}
|
|
33
|
+
static getIconKey(processIdPrefix) {
|
|
34
|
+
return `${encodeURIComponent('bpm:' + processIdPrefix)}`;
|
|
35
|
+
}
|
|
36
|
+
static getIconNamespace() {
|
|
37
|
+
return `io.yuuvis.app.inbox`;
|
|
38
|
+
}
|
|
39
|
+
static getVariableType(element) {
|
|
40
|
+
if (element.cardinality === 'multi')
|
|
41
|
+
return 'json';
|
|
42
|
+
switch (element.type) {
|
|
43
|
+
case 'o2mGroup':
|
|
44
|
+
case 'o2mGroupStack':
|
|
45
|
+
return 'object';
|
|
46
|
+
case 'o2mList':
|
|
47
|
+
return 'array';
|
|
48
|
+
case 'o2mTable':
|
|
49
|
+
case 'table':
|
|
50
|
+
return 'table';
|
|
51
|
+
case 'o2mForm':
|
|
52
|
+
return 'form';
|
|
53
|
+
case 'datetime':
|
|
54
|
+
return 'date';
|
|
55
|
+
case 'decimal':
|
|
56
|
+
return 'double';
|
|
57
|
+
default:
|
|
58
|
+
return element.type;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
static getVariableValue(formValue, type) {
|
|
62
|
+
switch (type) {
|
|
63
|
+
case 'table':
|
|
64
|
+
if (formValue)
|
|
65
|
+
formValue.forEach((row) => Object.keys(row).forEach((k) => {
|
|
66
|
+
if (k.endsWith('_title')) {
|
|
67
|
+
delete row[k];
|
|
68
|
+
}
|
|
69
|
+
}));
|
|
70
|
+
return formValue;
|
|
71
|
+
default:
|
|
72
|
+
return formValue;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
static getProcessVariables(formData, formElements, name) {
|
|
76
|
+
return {
|
|
77
|
+
name,
|
|
78
|
+
value: AppInboxUtils.getVariableValue(formData, formElements.type),
|
|
79
|
+
type: AppInboxUtils.getVariableType(formElements),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const APP_INBOX_ID = 'io.yuuvis.app.inbox';
|
|
85
|
+
const APP_INBOX_NAME = 'yuuvis Inbox';
|
|
86
|
+
const APP_INBOX_ICON = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-120H640q-30 38-71.5 59T480-240q-47 0-88.5-21T320-320H200v120Zm280-120q38 0 69-22t43-58h168v-360H200v360h168q12 36 43 58t69 22Zm0-80L320-560l56-58 64 64v-166h80v166l64-64 56 58-160 160ZM200-200h560-560Z"/></svg>';
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Generated bundle index. Do not edit.
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
export { APP_INBOX_ICON, APP_INBOX_ID, APP_INBOX_NAME, AppInboxUtils, ProcessAction };
|
|
93
|
+
//# sourceMappingURL=yuuvis-app-inbox-shared.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yuuvis-app-inbox-shared.mjs","sources":["../../../../projects/yuuvis/app-inbox/shared/src/inbox.interface.ts","../../../../projects/yuuvis/app-inbox/shared/src/utils.ts","../../../../projects/yuuvis/app-inbox/shared/src/inbox.schema.ts","../../../../projects/yuuvis/app-inbox/shared/src/yuuvis-app-inbox-shared.ts"],"sourcesContent":["import { Pagination } from '@yuuvis/client-framework/pagination';\nexport interface ProcessVariable {\n name: string;\n type?: string;\n value: any;\n // TODO: Not yet supported by BPM-Engine\n readonly?: boolean;\n scope?: string;\n}\n\nexport const ProcessAction = {\n complete: 'complete',\n claim: 'claim',\n delegate: 'delegate',\n resolve: 'resolve',\n save: 'save',\n};\n\nexport interface TasksResponse {\n objects: Task[];\n hasMoreItems: boolean;\n totalNumItems: number;\n numItems: number;\n}\n\n// State emitted by the inbox service\nexport interface InboxState {\n tasks: Task[];\n pagination?: Pagination;\n sort: string;\n isAssigned: boolean,\n searchConditions?: InboxSearchConditions;\n}\n\nexport interface InboxSearchConditions {\n nameLikeIgnoreCase?: string;\n}\n\n/**\n * A task is an entry in a users inbox.\n */\nexport interface Task {\n id: string;\n // ID of the process instance that contains this task/activity\n processInstanceId: string;\n taskDefinitionKey: string;\n assignee: ProcessUser;\n claimTime: Date;\n createTime: Date;\n dueDate: Date;\n description: string;\n taskMessages?: TaskMessage[];\n taskForm?: {\n schemaProperties?: string[];\n model?: any;\n data?: any;\n outcomes?: TaskOutcome[];\n };\n delegationState?: string;\n formKey: string;\n initiator: ProcessUser;\n name: string;\n owner: ProcessUser;\n parentTaskId: string;\n processDefinition: {\n id: string;\n idPrefix: string;\n name: string;\n description: string;\n };\n suspended: false;\n variables: ProcessVariable[];\n resolvedValues?: { [id: string]: string };\n attachments: string[];\n}\n\nexport interface ProcessUser {\n id: string;\n title: string;\n}\n\nexport interface TaskMessage {\n level?: string;\n type?: string;\n message: string;\n}\n\n/**\n * A task outcome is basically an action that will be rendered as a button in the\n * task form. When the button is clicked, the outcome will be triggered.\n */\nexport interface TaskOutcome {\n // the outcomes technical name (also used for translations)\n name: string;\n // Name of the variable that this outcome will write to process vars\n variable: string;\n // The vaue that this outcome will write to process vars\n value: any;\n /**\n * Optional form model. Could be the model object as well as a string (Id\n * to fetch a form model from the backend).\n *\n * If you provide a model, triggering the outcome will display/render this form\n * alongside with the tasks form. Values of all rendered forms will be put into\n * the process variables\n */\n model?: any;\n /**\n * Outcomes will be rendered as primary buttons. If you want an outcome\n * to be less prominent you could set this property to 'true'\n */\n secondary?: boolean;\n}\n\nexport interface ProcessCreatePayload extends ProcessPostPayload {\n processDefinitionKey: string;\n name?: string;\n businessKey?: string;\n returnVariables?: boolean;\n}\n// payload for post requests to the bpm backend\nexport interface ProcessPostPayload {\n variables?: ProcessVariable[];\n attachments?: string[];\n}\n","import { APP_INBOX_NAME } from './inbox.schema';\nimport { ProcessVariable } from './inbox.interface';\n\nexport class AppInboxUtils {\n /**\n * Fixes the form model by ensuring that it contains 'core' and 'data' elements.\n * If these elements are missing, they are added to the form model.\n * @param formModel The form model to be fixed.\n * @returns The fixed form model\n */\n static fixFormModel(formModel: any): any {\n if (!formModel.elements.find((e: any) => e.name === 'core')) {\n formModel.elements.push({\n name: 'core',\n type: 'o2mGroup',\n elements: [],\n });\n }\n if (!formModel.elements.find((e: any) => e.name === 'data')) {\n formModel.elements.push({\n name: 'data',\n type: 'o2mGroupStack',\n elements: [],\n });\n }\n return formModel;\n }\n\n static getIconKey(processIdPrefix: string) {\n return `${encodeURIComponent('bpm:' + processIdPrefix)}`;\n }\n\n static getIconNamespace() {\n return `io.yuuvis.app.inbox`;\n }\n\n static getVariableType(element: any): string {\n if (element.cardinality === 'multi') return 'json';\n switch (element.type) {\n case 'o2mGroup':\n case 'o2mGroupStack':\n return 'object';\n case 'o2mList':\n return 'array';\n case 'o2mTable':\n case 'table':\n return 'table';\n case 'o2mForm':\n return 'form';\n case 'datetime':\n return 'date';\n case 'decimal':\n return 'double';\n default:\n return element.type;\n }\n }\n\n static getVariableValue(formValue: any, type: string): any {\n switch (type) {\n case 'table':\n if (formValue)\n formValue.forEach((row: any) =>\n Object.keys(row).forEach((k) => {\n if (k.endsWith('_title')) {\n delete row[k];\n }\n })\n );\n return formValue;\n default:\n return formValue;\n }\n }\n\n static getProcessVariables(\n formData: unknown,\n formElements: unknown & { type: string },\n name: string\n ): ProcessVariable {\n return {\n name,\n value: AppInboxUtils.getVariableValue(formData, formElements.type),\n type: AppInboxUtils.getVariableType(formElements),\n };\n }\n}\n","\n\nexport const APP_INBOX_ID = 'io.yuuvis.app.inbox';\nexport const APP_INBOX_NAME = 'yuuvis Inbox';\nexport const APP_INBOX_ICON =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"#e8eaed\"><path d=\"M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-120H640q-30 38-71.5 59T480-240q-47 0-88.5-21T320-320H200v120Zm280-120q38 0 69-22t43-58h168v-360H200v360h168q12 36 43 58t69 22Zm0-80L320-560l56-58 64 64v-166h80v166l64-64 56 58-160 160ZM200-200h560-560Z\"/></svg>';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"AAUa,MAAA,aAAa,GAAG;AAC3B,IAAA,QAAQ,EAAE,UAAU;AACpB,IAAA,KAAK,EAAE,OAAO;AACd,IAAA,QAAQ,EAAE,UAAU;AACpB,IAAA,OAAO,EAAE,SAAS;AAClB,IAAA,IAAI,EAAE,MAAM;;;MCZD,aAAa,CAAA;AACxB;;;;;AAKG;IACH,OAAO,YAAY,CAAC,SAAc,EAAA;AAChC,QAAA,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAM,KAAK,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE;AAC3D,YAAA,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;AACtB,gBAAA,IAAI,EAAE,MAAM;AACZ,gBAAA,IAAI,EAAE,UAAU;AAChB,gBAAA,QAAQ,EAAE,EAAE;AACb,aAAA,CAAC;;AAEJ,QAAA,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAM,KAAK,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE;AAC3D,YAAA,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;AACtB,gBAAA,IAAI,EAAE,MAAM;AACZ,gBAAA,IAAI,EAAE,eAAe;AACrB,gBAAA,QAAQ,EAAE,EAAE;AACb,aAAA,CAAC;;AAEJ,QAAA,OAAO,SAAS;;IAGlB,OAAO,UAAU,CAAC,eAAuB,EAAA;QACvC,OAAO,CAAA,EAAG,kBAAkB,CAAC,MAAM,GAAG,eAAe,CAAC,EAAE;;AAG1D,IAAA,OAAO,gBAAgB,GAAA;AACrB,QAAA,OAAO,qBAAqB;;IAG9B,OAAO,eAAe,CAAC,OAAY,EAAA;AACjC,QAAA,IAAI,OAAO,CAAC,WAAW,KAAK,OAAO;AAAE,YAAA,OAAO,MAAM;AAClD,QAAA,QAAQ,OAAO,CAAC,IAAI;AAClB,YAAA,KAAK,UAAU;AACf,YAAA,KAAK,eAAe;AAClB,gBAAA,OAAO,QAAQ;AACjB,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,OAAO;AAChB,YAAA,KAAK,UAAU;AACf,YAAA,KAAK,OAAO;AACV,gBAAA,OAAO,OAAO;AAChB,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,MAAM;AACf,YAAA,KAAK,UAAU;AACb,gBAAA,OAAO,MAAM;AACf,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,QAAQ;AACjB,YAAA;gBACE,OAAO,OAAO,CAAC,IAAI;;;AAIzB,IAAA,OAAO,gBAAgB,CAAC,SAAc,EAAE,IAAY,EAAA;QAClD,QAAQ,IAAI;AACV,YAAA,KAAK,OAAO;AACV,gBAAA,IAAI,SAAS;oBACX,SAAS,CAAC,OAAO,CAAC,CAAC,GAAQ,KACzB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAI;AAC7B,wBAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;AACxB,4BAAA,OAAO,GAAG,CAAC,CAAC,CAAC;;qBAEhB,CAAC,CACH;AACH,gBAAA,OAAO,SAAS;AAClB,YAAA;AACE,gBAAA,OAAO,SAAS;;;AAItB,IAAA,OAAO,mBAAmB,CACxB,QAAiB,EACjB,YAAwC,EACxC,IAAY,EAAA;QAEZ,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC;AAClE,YAAA,IAAI,EAAE,aAAa,CAAC,eAAe,CAAC,YAAY,CAAC;SAClD;;AAEJ;;ACpFM,MAAM,YAAY,GAAG;AACrB,MAAM,cAAc,GAAG;AACvB,MAAM,cAAc,GACzB;;ACLF;;AAEG;;;;"}
|