@yuuvis/app-invoice 2.3.4 → 2.3.6

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,7 +1,24 @@
1
1
  import { AbstractApplyObjectFlavorComponent } from '@yuuvis/client-framework/object-flavor';
2
+ import { FormStatusChangedEvent, IObjectFormElementExtension, ObjectFormComponent, ObjectFormOptions } from '@yuuvis/client-framework/object-form';
2
3
  import * as i0 from "@angular/core";
3
4
  export declare class ApplyFlavorComponent extends AbstractApplyObjectFlavorComponent {
4
5
  #private;
6
+ private translate;
7
+ private userService;
8
+ objectForm: import("@angular/core").Signal<ObjectFormComponent | undefined>;
9
+ flavorLabel: import("@angular/core").Signal<any>;
10
+ error: import("@angular/core").WritableSignal<boolean>;
11
+ applyDisabled: import("@angular/core").WritableSignal<boolean>;
12
+ supportsExtraction: import("@angular/core").WritableSignal<boolean>;
13
+ busyLoading: import("@angular/core").WritableSignal<boolean>;
14
+ busySaving: import("@angular/core").WritableSignal<boolean>;
15
+ busyExtracting: import("@angular/core").WritableSignal<boolean>;
16
+ formOptions: import("@angular/core").WritableSignal<ObjectFormOptions | null>;
17
+ extensions: import("@angular/core").WritableSignal<IObjectFormElementExtension[]>;
18
+ immediateExtract: any;
19
+ headline?: string;
20
+ extract(): void;
21
+ onFormStatusChanged(status: FormStatusChangedEvent): void;
5
22
  applyFlavor(): void;
6
23
  close(): void;
7
24
  static ɵfac: i0.ɵɵFactoryDeclaration<ApplyFlavorComponent, never>;
@@ -1,22 +1,31 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, effect, untracked, Component, Injectable, signal, DestroyRef, ElementRef } from '@angular/core';
2
+ import { inject, signal, Injectable, DestroyRef, ElementRef, effect, untracked, Component, viewChild, computed } from '@angular/core';
3
3
  import { AbstractContextAction, SelectionRange, ActionsService } from '@yuuvis/client-framework/actions';
4
4
  import { ShellService } from '@yuuvis/client-shell-core';
5
5
  import { Router } from '@angular/router';
6
6
  import { TranslateService } from '@ngx-translate/core';
7
- import { of, tap } from 'rxjs';
7
+ import { of, tap, finalize } from 'rxjs';
8
8
  import { marker } from '@colsen1991/ngx-translate-extract-marker';
9
9
  import * as i3 from '@yuuvis/client-core';
10
- import { SystemType, DmsService, PredictionService, SystemService, TranslateModule } from '@yuuvis/client-core';
11
- import * as i1 from '@angular/common';
10
+ import { PredictionService, SystemService, TranslateModule, TranslateService as TranslateService$1, UserService, Situation, SystemType, DmsService } from '@yuuvis/client-core';
11
+ import * as i1$1 from '@angular/common';
12
12
  import { CommonModule } from '@angular/common';
13
+ import { MatButtonModule } from '@angular/material/button';
14
+ import * as i4 from '@angular/material/dialog';
15
+ import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
16
+ import { BusyOverlayDirective, DialogComponent } from '@yuuvis/client-framework/common';
13
17
  import { AbstractApplyObjectFlavorComponent, AbstractApplyCreateFlavorComponent } from '@yuuvis/client-framework/object-flavor';
14
- import { MatDialogRef } from '@angular/material/dialog';
18
+ import { ObjectFormElementExtension, ObjectFormComponent } from '@yuuvis/client-framework/object-form';
19
+ import { ObjectPreviewComponent } from '@yuuvis/client-framework/object-preview';
20
+ import * as i2$1 from '@yuuvis/client-framework/split-view';
21
+ import { YuvSplitViewModule } from '@yuuvis/client-framework/split-view';
15
22
  import * as i2 from '@angular/material/icon';
16
23
  import { MatIconModule } from '@angular/material/icon';
17
- import * as i1$1 from '@angular/material/menu';
24
+ import * as i1 from '@angular/material/menu';
18
25
  import { MatMenuModule } from '@angular/material/menu';
19
- import { ObjectFormElementExtension } from '@yuuvis/client-framework/object-form';
26
+ import { YmtButtonDirective } from '@yuuvis/material';
27
+ import * as i5 from '@angular/material/tooltip';
28
+ import { MatTooltipModule } from '@angular/material/tooltip';
20
29
 
21
30
  class OpenEmailAction extends AbstractContextAction {
22
31
  translate = inject(TranslateService);
@@ -45,40 +54,206 @@ class OpenEmailAction extends AbstractContextAction {
45
54
  }
46
55
  }
47
56
 
57
+ class ApplyFlavorService {
58
+ #predict = inject(PredictionService);
59
+ #extractedDataSource = signal(null);
60
+ extractedData = this.#extractedDataSource.asReadonly();
61
+ extract(schemaObjectTypeId, objectID) {
62
+ return this.#predict
63
+ .extract(schemaObjectTypeId, [objectID])
64
+ .pipe(tap((res) => this.#extractedDataSource.set(res[objectID].properties)));
65
+ }
66
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplyFlavorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
67
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplyFlavorService });
68
+ }
69
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplyFlavorService, decorators: [{
70
+ type: Injectable
71
+ }] });
72
+
73
+ /**
74
+ * This object form field extension inserts AI-extracted values into an
75
+ * object-form. Once the AI service has extracted a value, this extension
76
+ * will change the form field to display the extracted value and show the
77
+ * value for the probability of the extraction right next to the field.
78
+ *
79
+ * If there are multiple extractions, the extension will insert the value
80
+ * with the highest probability and provide a picker for the other values.
81
+ *
82
+ * This way the user can easily accept the extracted value or choose a
83
+ * different one from the list of extracted values.
84
+ */
85
+ class AiExtractedPropertyComponent extends ObjectFormElementExtension {
86
+ #applyFlavorService = inject(ApplyFlavorService);
87
+ #destroyRef = inject(DestroyRef);
88
+ #system = inject(SystemService);
89
+ #elRef = inject(ElementRef);
90
+ predictionValues = [];
91
+ currentValueProbability = signal(undefined);
92
+ #currentValueProbabilityEffect = effect(() => {
93
+ const cp = this.currentValueProbability();
94
+ if (!cp)
95
+ return;
96
+ // set the probability color
97
+ const color = cp < 30 ? '--ymt-danger' : cp < 60 ? '--ymt-warning' : '--ymt-success';
98
+ this.#elRef.nativeElement.style.setProperty('--current-value-probability-color', `var(${color})`);
99
+ });
100
+ extractedData = this.#applyFlavorService.extractedData;
101
+ extractedDataEffect = effect(() => {
102
+ const extData = this.extractedData();
103
+ if (extData) {
104
+ untracked(() => {
105
+ const fcn = this.input().formControlName;
106
+ this.predictionValues = extData[fcn] || [];
107
+ this.#applyPredictionValues();
108
+ });
109
+ }
110
+ });
111
+ #internalFieldType;
112
+ #applyPredictionValues() {
113
+ // set the value of the form field to the extracted value with
114
+ // the highest probability
115
+ const pv = this.predictionValues;
116
+ if (pv.length) {
117
+ pv.sort((a, b) => b.probability - a.probability);
118
+ this.selectOption(pv[0]);
119
+ }
120
+ else {
121
+ this.currentValueProbability.set(undefined);
122
+ }
123
+ }
124
+ // map extracted string to a proper format to be used
125
+ // within the form elements
126
+ #mapValueToType(value) {
127
+ if (this.#internalFieldType === 'datetime') {
128
+ // dates will always be returned as german formatted strings (24.12.2024)
129
+ // no matter what the locale of the processed document is. So we need to
130
+ // convert the string to a proper date object
131
+ const dateParts = value.split('.');
132
+ return dateParts.length === 3 ? new Date(+dateParts[2], +dateParts[1] - 1, +dateParts[0]) : value;
133
+ }
134
+ else {
135
+ return value;
136
+ }
137
+ }
138
+ selectOptionByIndex(idx) {
139
+ this.selectOption(this.predictionValues[idx]);
140
+ }
141
+ selectOption(pr) {
142
+ this.setValue(this.#mapValueToType(pr.value));
143
+ this.currentValueProbability.set(pr.probability);
144
+ }
145
+ ngOnInit() {
146
+ this.#internalFieldType = this.#system.getObjectTypeField(this.input().formControlName)?._internalType;
147
+ }
148
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AiExtractedPropertyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
149
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: AiExtractedPropertyComponent, isStandalone: true, selector: "yin-ai-extracted-property", usesInheritance: true, ngImport: i0, template: "@if (predictionValues.length === 1) {\n <span class=\"probability\">\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n </span\n >\n} @else if (predictionValues.length > 1) {\n <button class=\"probability\" [matMenuTriggerFor]=\"menu\">\n <!-- (click)=\"openValueOptions(options, $event)\"> -->\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n <mat-icon class=\"ymt-icon--size-s\">arrow_drop_down</mat-icon>\n </button>\n\n <mat-menu #menu=\"matMenu\">\n @for (pv of predictionValues; track $index) {\n <button mat-menu-item (click)=\"selectOptionByIndex($index)\">{{ pv.value }\n <span>{{ 'yuv.app.invoice.ai.probability' | translate: { probability: pv.probability } }}</span>\n </button>\n }\n </mat-menu>\n}\n", styles: [":host{--current-value-probability-color: var(--ymt-success)}:host .probability{padding:2px;background-color:rgb(from var(--current-value-probability-color) r g b/.1);border:1px solid rgb(from var(--current-value-probability-color) r g b/.3);color:var(--current-value-probability-color);display:flex;border-radius:.25em;gap:var(--ymt-spacing-2xs);font:var(--ymt-font-body-subtle);align-items:center;line-height:1em;--icon-size: 14px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
150
+ }
151
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AiExtractedPropertyComponent, decorators: [{
152
+ type: Component,
153
+ args: [{ selector: 'yin-ai-extracted-property', standalone: true, imports: [CommonModule, MatMenuModule, MatIconModule, TranslateModule], template: "@if (predictionValues.length === 1) {\n <span class=\"probability\">\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n </span\n >\n} @else if (predictionValues.length > 1) {\n <button class=\"probability\" [matMenuTriggerFor]=\"menu\">\n <!-- (click)=\"openValueOptions(options, $event)\"> -->\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n <mat-icon class=\"ymt-icon--size-s\">arrow_drop_down</mat-icon>\n </button>\n\n <mat-menu #menu=\"matMenu\">\n @for (pv of predictionValues; track $index) {\n <button mat-menu-item (click)=\"selectOptionByIndex($index)\">{{ pv.value }\n <span>{{ 'yuv.app.invoice.ai.probability' | translate: { probability: pv.probability } }}</span>\n </button>\n }\n </mat-menu>\n}\n", styles: [":host{--current-value-probability-color: var(--ymt-success)}:host .probability{padding:2px;background-color:rgb(from var(--current-value-probability-color) r g b/.1);border:1px solid rgb(from var(--current-value-probability-color) r g b/.3);color:var(--current-value-probability-color);display:flex;border-radius:.25em;gap:var(--ymt-spacing-2xs);font:var(--ymt-font-body-subtle);align-items:center;line-height:1em;--icon-size: 14px}\n"] }]
154
+ }] });
155
+
156
+ const COMPONENTS = [
157
+ YuvSplitViewModule,
158
+ TranslateModule,
159
+ BusyOverlayDirective,
160
+ ObjectFormComponent,
161
+ ObjectPreviewComponent,
162
+ DialogComponent,
163
+ YmtButtonDirective
164
+ ];
165
+ const MATERIAL = [MatButtonModule, MatDialogModule, MatTooltipModule];
48
166
  class ApplyFlavorComponent extends AbstractApplyObjectFlavorComponent {
49
- #router = inject(Router);
167
+ #system = inject(SystemService);
50
168
  #shell = inject(ShellService);
51
- #app = this.#shell.getApp('io.yuuvis.app.drive');
169
+ #applyFlavorService = inject(ApplyFlavorService);
170
+ translate = inject(TranslateService$1);
171
+ userService = inject(UserService);
172
+ objectForm = viewChild(ObjectFormComponent);
173
+ flavorLabel = computed(() => this.#shell.getFlavorLabel(this.flavor().id));
174
+ #flavorEffect = effect(() => {
175
+ const f = this.flavor();
176
+ untracked(() => {
177
+ if (f)
178
+ this.#loadForm(f);
179
+ });
180
+ });
52
181
  #dmsObjectEffect = effect(() => {
53
- this.dmsObject();
182
+ const o = this.dmsObject();
54
183
  untracked(() => {
55
- this.applyFlavor();
184
+ this.supportsExtraction.set(!!o.content && o.content.mimeType === 'application/pdf'
185
+ && this.userService.getCurrentUser().authorities.includes('YUUVIS_AI_PREDICT'));
56
186
  });
57
187
  });
58
- applyFlavor() {
59
- const objectId = this.dmsObject().id;
60
- this.#shell
61
- .applyObjectFlavor(this.dmsObject(), this.flavor())
188
+ error = signal(false);
189
+ applyDisabled = signal(true);
190
+ supportsExtraction = signal(true);
191
+ busyLoading = signal(false);
192
+ busySaving = signal(false);
193
+ busyExtracting = signal(false);
194
+ formOptions = signal(null);
195
+ extensions = signal([]);
196
+ immediateExtract = (this.data() && this.data().immediateExtract) || false;
197
+ headline = this.data() && this.data().headline;
198
+ #loadForm(f) {
199
+ this.busyLoading.set(true);
200
+ if (this.userService.getCurrentUser().authorities.includes('YUUVIS_AI_PREDICT')) {
201
+ const sot = this.#system.getSecondaryObjectType(f.sot);
202
+ this.extensions.set((sot?.fields || []).map((field) => ({
203
+ property: field.id,
204
+ cmp: AiExtractedPropertyComponent
205
+ })));
206
+ }
207
+ this.#system
208
+ .getObjectTypeForm(f.sot, Situation.EDIT)
209
+ .pipe(finalize(() => this.busyLoading.set(false)))
210
+ .subscribe({
211
+ next: (form) => {
212
+ this.formOptions.set({
213
+ formModel: form,
214
+ data: {}
215
+ });
216
+ }
217
+ });
218
+ }
219
+ extract() {
220
+ this.busyExtracting.set(true);
221
+ this.#applyFlavorService
222
+ .extract(this.flavor().sot, this.dmsObject().id)
223
+ .pipe(finalize(() => this.busyExtracting.set(false)))
62
224
  .subscribe({
63
225
  next: () => {
64
- this.close();
65
- this.#router.navigateByUrl(`/${this.#app ? this.#app.path : 'drive'}/object/${objectId}`).then();
226
+ this.error.set(false);
66
227
  },
67
228
  error: () => {
68
- // TODO: handle error
69
- this.close();
229
+ this.error.set(true);
70
230
  }
71
231
  });
72
232
  }
233
+ onFormStatusChanged(status) {
234
+ this.applyDisabled.set(status.invalid);
235
+ }
236
+ applyFlavor() {
237
+ const of = this.objectForm();
238
+ const data = of ? of.getFormData() : {};
239
+ this.busySaving.set(true);
240
+ this.#shell
241
+ .applyObjectFlavor(this.dmsObject(), this.flavor(), data)
242
+ .pipe(finalize(() => this.busySaving.set(false)))
243
+ .subscribe({
244
+ next: () => this.close()
245
+ // TODO: handle error
246
+ });
247
+ }
73
248
  close() {
74
249
  this.dialogRef.close();
75
250
  }
76
251
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplyFlavorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
77
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: ApplyFlavorComponent, isStandalone: true, selector: "yin-apply-flavor", usesInheritance: true, ngImport: i0, template: "\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
252
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: ApplyFlavorComponent, isStandalone: true, selector: "yin-apply-flavor", providers: [ApplyFlavorService], viewQueries: [{ propertyName: "objectForm", first: true, predicate: ObjectFormComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<yuv-dialog [headertitel]=\"headline || ('yuv.app.invoice.apply-flavor.headline' | translate: { name: flavorLabel() })\">\n <main>\n <yuv-split-view [gutterSize]=\"1\">\n <ng-template yuvSplitArea [size]=\"60\">\n @if (dmsObject() && dmsObject().content) {\n <yuv-object-preview [objectId]=\"dmsObject().id\"></yuv-object-preview>\n }\n </ng-template>\n\n <ng-template yuvSplitArea [size]=\"40\">\n <div class=\"metadata\" [yuvBusyOverlay]=\"busyLoading()\">\n <div class=\"ai\">\n @if (supportsExtraction()) {\n @if (error()) {\n <mat-icon class=\"warning\" [matTooltip]=\"'yuv.app.invoice.apply-flavor.button.extract.error' | translate\">warning</mat-icon>\n }\n @if (busyExtracting()) {\n <div class=\"spinner\"></div>\n }\n <button ymtButton=\"secondary\" class=\"ai-extract\" [ngClass]=\"{ spinning: busyExtracting() }\" (click)=\"extract()\">\n <mat-icon>robot_2</mat-icon>\n {{ 'yuv.app.invoice.apply-flavor.button.extract' | translate }}\n </button>\n }\n </div>\n\n @let fo = formOptions();\n @if (fo) {\n <yuv-object-form\n [elementExtensions]=\"extensions()\"\n [inert]=\"busySaving() || busyExtracting()\"\n [formOptions]=\"fo\"\n (statusChanged)=\"onFormStatusChanged($event)\"\n ></yuv-object-form>\n }\n </div>\n </ng-template>\n </yuv-split-view>\n </main>\n\n <footer>\n <button ymtButton=\"secondary\" mat-dialog-close [disabled]=\"busySaving() || busyExtracting()\">\n {{ 'yuv.app.invoice.apply-flavor.button.cancel' | translate }}\n </button>\n <button\n ymtButton=\"primary\"\n mat-dialog-close\n cdkFocusInitial\n class=\"primary\"\n [ngClass]=\"{ spinning: busySaving() }\"\n [disabled]=\"applyDisabled() || busyExtracting()\"\n (click)=\"applyFlavor()\"\n >\n {{ 'yuv.app.invoice.apply-flavor.button.apply' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{width:90vw;--ymt-dialog-content-display: block}:host .spinning{opacity:.5;pointer-events:none}:host main{height:65vh}:host yuv-split-view{--split-gutter-background-color: var(--ymt-outline-variant);flex:1}:host .metadata{display:flex;flex-flow:column;height:100%;overflow:hidden}:host .metadata .ai{display:flex;flex:0 0 auto;justify-content:end;padding:0 var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant);align-items:center;gap:1em}:host .metadata .ai mat-icon.warning{--icon-size: 18px;color:var(--ymt-warning)}:host .metadata .ai button{display:flex;margin-block:var(--ymt-spacing-2xs);padding:.25em 1.5em}:host .metadata .ai button mat-icon{--icon-size: 18px;color:var(--ymt-text-color-subtle)}:host .metadata yuv-object-form{display:block;background-color:var(--ymt-surface-panel);border:1px solid var(--ymt-outline-variant);max-width:100%;margin-inline:auto;box-sizing:border-box;overflow:auto}:host .spinner{color:var(--mat-sys-primary)}:host .spinner,:host .spinner:after{box-sizing:border-box}:host .spinner{display:inline-block;width:40px;height:40px}:host .spinner:after{content:\" \";display:block;width:32px;height:32px;margin:4px;border-radius:50%;border:6.4px solid currentColor;border-color:currentColor transparent currentColor transparent;animation:spinner 1.2s linear infinite}@keyframes spinner{0%{transform:rotate(0)}to{transform:rotate(360deg)}}::ng-deep .cdk-overlay-pane.mat-mdc-dialog-panel{max-width:unset!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: YuvSplitViewModule }, { kind: "directive", type: i2$1.SplitAreaDirective, selector: "[yuvSplitArea]", inputs: ["size", "minSize", "maxSize", "panelClass", "visible", "lockSize"] }, { kind: "component", type: i2$1.SplitViewComponent, selector: "yuv-split-view", inputs: ["direction", "gutterSize", "restrictMove", "disabled", "layoutSettingsID"], outputs: ["layoutSettingsChange", "dragStart", "dragEnd", "gutterClick", "gutterDblClick"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "directive", type: BusyOverlayDirective, selector: "[yuvBusyOverlay]", inputs: ["yuvBusyOverlay", "yuvBusyOverlayConfig", "yuvBusyError"], outputs: ["yuvBusyErrorDismiss"] }, { kind: "component", type: ObjectFormComponent, selector: "yuv-object-form", inputs: ["formOptions", "inert", "readonly", "elementExtensions", "isInnerTableForm"], outputs: ["statusChanged", "onFormReady"] }, { kind: "component", type: ObjectPreviewComponent, selector: "yuv-object-preview", inputs: ["objectId", "dmsObject", "version", "metadata"] }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitle", "headertitel"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i4.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
78
253
  }
79
254
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplyFlavorComponent, decorators: [{
80
255
  type: Component,
81
- args: [{ selector: 'yin-apply-flavor', standalone: true, imports: [CommonModule], template: "\n" }]
256
+ args: [{ selector: 'yin-apply-flavor', standalone: true, providers: [ApplyFlavorService], imports: [CommonModule, ...COMPONENTS, ...MATERIAL, MatIconModule], template: "<yuv-dialog [headertitel]=\"headline || ('yuv.app.invoice.apply-flavor.headline' | translate: { name: flavorLabel() })\">\n <main>\n <yuv-split-view [gutterSize]=\"1\">\n <ng-template yuvSplitArea [size]=\"60\">\n @if (dmsObject() && dmsObject().content) {\n <yuv-object-preview [objectId]=\"dmsObject().id\"></yuv-object-preview>\n }\n </ng-template>\n\n <ng-template yuvSplitArea [size]=\"40\">\n <div class=\"metadata\" [yuvBusyOverlay]=\"busyLoading()\">\n <div class=\"ai\">\n @if (supportsExtraction()) {\n @if (error()) {\n <mat-icon class=\"warning\" [matTooltip]=\"'yuv.app.invoice.apply-flavor.button.extract.error' | translate\">warning</mat-icon>\n }\n @if (busyExtracting()) {\n <div class=\"spinner\"></div>\n }\n <button ymtButton=\"secondary\" class=\"ai-extract\" [ngClass]=\"{ spinning: busyExtracting() }\" (click)=\"extract()\">\n <mat-icon>robot_2</mat-icon>\n {{ 'yuv.app.invoice.apply-flavor.button.extract' | translate }}\n </button>\n }\n </div>\n\n @let fo = formOptions();\n @if (fo) {\n <yuv-object-form\n [elementExtensions]=\"extensions()\"\n [inert]=\"busySaving() || busyExtracting()\"\n [formOptions]=\"fo\"\n (statusChanged)=\"onFormStatusChanged($event)\"\n ></yuv-object-form>\n }\n </div>\n </ng-template>\n </yuv-split-view>\n </main>\n\n <footer>\n <button ymtButton=\"secondary\" mat-dialog-close [disabled]=\"busySaving() || busyExtracting()\">\n {{ 'yuv.app.invoice.apply-flavor.button.cancel' | translate }}\n </button>\n <button\n ymtButton=\"primary\"\n mat-dialog-close\n cdkFocusInitial\n class=\"primary\"\n [ngClass]=\"{ spinning: busySaving() }\"\n [disabled]=\"applyDisabled() || busyExtracting()\"\n (click)=\"applyFlavor()\"\n >\n {{ 'yuv.app.invoice.apply-flavor.button.apply' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host{width:90vw;--ymt-dialog-content-display: block}:host .spinning{opacity:.5;pointer-events:none}:host main{height:65vh}:host yuv-split-view{--split-gutter-background-color: var(--ymt-outline-variant);flex:1}:host .metadata{display:flex;flex-flow:column;height:100%;overflow:hidden}:host .metadata .ai{display:flex;flex:0 0 auto;justify-content:end;padding:0 var(--ymt-spacing-m);border-block-end:1px solid var(--ymt-outline-variant);align-items:center;gap:1em}:host .metadata .ai mat-icon.warning{--icon-size: 18px;color:var(--ymt-warning)}:host .metadata .ai button{display:flex;margin-block:var(--ymt-spacing-2xs);padding:.25em 1.5em}:host .metadata .ai button mat-icon{--icon-size: 18px;color:var(--ymt-text-color-subtle)}:host .metadata yuv-object-form{display:block;background-color:var(--ymt-surface-panel);border:1px solid var(--ymt-outline-variant);max-width:100%;margin-inline:auto;box-sizing:border-box;overflow:auto}:host .spinner{color:var(--mat-sys-primary)}:host .spinner,:host .spinner:after{box-sizing:border-box}:host .spinner{display:inline-block;width:40px;height:40px}:host .spinner:after{content:\" \";display:block;width:32px;height:32px;margin:4px;border-radius:50%;border:6.4px solid currentColor;border-color:currentColor transparent currentColor transparent;animation:spinner 1.2s linear infinite}@keyframes spinner{0%{transform:rotate(0)}to{transform:rotate(360deg)}}::ng-deep .cdk-overlay-pane.mat-mdc-dialog-panel{max-width:unset!important}\n"] }]
82
257
  }] });
83
258
 
84
259
  // use marker to extract the labels for the app schema types
@@ -147,11 +322,13 @@ class ApplyCreateFlavorComponent extends AbstractApplyCreateFlavorComponent {
147
322
  },
148
323
  cmp: flavor.applyComponent
149
324
  };
150
- this.#dialogRef.close();
325
+ if (dmsObject.content?.mimeType === 'application/x-os-invoice-xml') {
326
+ this.#dialogRef.close();
327
+ }
151
328
  });
152
329
  }
153
330
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplyCreateFlavorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
154
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: ApplyCreateFlavorComponent, isStandalone: true, selector: "yin-apply-create-flavor", usesInheritance: true, ngImport: i0, template: "@if (sc && sc.cmp) {\n <ng-container *ngComponentOutlet=\"sc.cmp; inputs: sc.inputs\"></ng-container>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] });
331
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: ApplyCreateFlavorComponent, isStandalone: true, selector: "yin-apply-create-flavor", usesInheritance: true, ngImport: i0, template: "@if (sc && sc.cmp) {\n <ng-container *ngComponentOutlet=\"sc.cmp; inputs: sc.inputs\"></ng-container>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] });
155
332
  }
156
333
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplyCreateFlavorComponent, decorators: [{
157
334
  type: Component,
@@ -198,105 +375,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
198
375
  type: Injectable
199
376
  }] });
200
377
 
201
- class ApplyFlavorService {
202
- #predict = inject(PredictionService);
203
- #extractedDataSource = signal(null);
204
- extractedData = this.#extractedDataSource.asReadonly();
205
- extract(schemaObjectTypeId, objectID) {
206
- return this.#predict
207
- .extract(schemaObjectTypeId, [objectID])
208
- .pipe(tap((res) => this.#extractedDataSource.set(res[objectID].properties)));
209
- }
210
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplyFlavorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
211
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplyFlavorService });
212
- }
213
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplyFlavorService, decorators: [{
214
- type: Injectable
215
- }] });
216
-
217
- /**
218
- * This object form field extension inserts AI-extracted values into an
219
- * object-form. Once the AI service has extracted a value, this extension
220
- * will change the form field to display the extracted value and show the
221
- * value for the probability of the extraction right next to the field.
222
- *
223
- * If there are multiple extractions, the extension will insert the value
224
- * with the highest probability and provide a picker for the other values.
225
- *
226
- * This way the user can easily accept the extracted value or choose a
227
- * different one from the list of extracted values.
228
- */
229
- class AiExtractedPropertyComponent extends ObjectFormElementExtension {
230
- #applyFlavorService = inject(ApplyFlavorService);
231
- #destroyRef = inject(DestroyRef);
232
- #system = inject(SystemService);
233
- #elRef = inject(ElementRef);
234
- predictionValues = [];
235
- currentValueProbability = signal(undefined);
236
- #currentValueProbabilityEffect = effect(() => {
237
- const cp = this.currentValueProbability();
238
- if (!cp)
239
- return;
240
- // set the probability color
241
- const color = cp < 30 ? '--ymt-danger' : cp < 60 ? '--ymt-warning' : '--ymt-success';
242
- this.#elRef.nativeElement.style.setProperty('--current-value-probability-color', `var(${color})`);
243
- });
244
- extractedData = this.#applyFlavorService.extractedData;
245
- extractedDataEffect = effect(() => {
246
- const extData = this.extractedData();
247
- if (extData) {
248
- untracked(() => {
249
- const fcn = this.input().formControlName;
250
- this.predictionValues = extData[fcn] || [];
251
- this.#applyPredictionValues();
252
- });
253
- }
254
- });
255
- #internalFieldType;
256
- #applyPredictionValues() {
257
- // set the value of the form field to the extracted value with
258
- // the highest probability
259
- const pv = this.predictionValues;
260
- if (pv.length) {
261
- pv.sort((a, b) => b.probability - a.probability);
262
- this.selectOption(pv[0]);
263
- }
264
- else {
265
- this.currentValueProbability.set(undefined);
266
- }
267
- }
268
- // map extracted string to a proper format to be used
269
- // within the form elements
270
- #mapValueToType(value) {
271
- if (this.#internalFieldType === 'datetime') {
272
- // dates will always be returned as german formatted strings (24.12.2024)
273
- // no matter what the locale of the processed document is. So we need to
274
- // convert the string to a proper date object
275
- const dateParts = value.split('.');
276
- return dateParts.length === 3 ? new Date(+dateParts[2], +dateParts[1] - 1, +dateParts[0]) : value;
277
- }
278
- else {
279
- return value;
280
- }
281
- }
282
- selectOptionByIndex(idx) {
283
- this.selectOption(this.predictionValues[idx]);
284
- }
285
- selectOption(pr) {
286
- this.setValue(this.#mapValueToType(pr.value));
287
- this.currentValueProbability.set(pr.probability);
288
- }
289
- ngOnInit() {
290
- this.#internalFieldType = this.#system.getObjectTypeField(this.input().formControlName)?._internalType;
291
- }
292
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AiExtractedPropertyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
293
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: AiExtractedPropertyComponent, isStandalone: true, selector: "yin-ai-extracted-property", usesInheritance: true, ngImport: i0, template: "@if (predictionValues.length === 1) {\n <span class=\"probability\">\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n </span\n >\n} @else if (predictionValues.length > 1) {\n <button class=\"probability\" [matMenuTriggerFor]=\"menu\">\n <!-- (click)=\"openValueOptions(options, $event)\"> -->\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n <mat-icon class=\"ymt-icon--size-s\">arrow_drop_down</mat-icon>\n </button>\n\n <mat-menu #menu=\"matMenu\">\n @for (pv of predictionValues; track $index) {\n <button mat-menu-item (click)=\"selectOptionByIndex($index)\">{{ pv.value }\n <span>{{ 'yuv.app.invoice.ai.probability' | translate: { probability: pv.probability } }}</span>\n </button>\n }\n </mat-menu>\n}\n", styles: [":host{--current-value-probability-color: var(--ymt-success)}:host .probability{padding:2px;background-color:rgb(from var(--current-value-probability-color) r g b/.1);border:1px solid rgb(from var(--current-value-probability-color) r g b/.3);color:var(--current-value-probability-color);display:flex;border-radius:.25em;gap:var(--ymt-spacing-2xs);font:var(--ymt-font-body-subtle);align-items:center;line-height:1em;--icon-size: 14px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
294
- }
295
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AiExtractedPropertyComponent, decorators: [{
296
- type: Component,
297
- args: [{ selector: 'yin-ai-extracted-property', standalone: true, imports: [CommonModule, MatMenuModule, MatIconModule, TranslateModule], template: "@if (predictionValues.length === 1) {\n <span class=\"probability\">\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n </span\n >\n} @else if (predictionValues.length > 1) {\n <button class=\"probability\" [matMenuTriggerFor]=\"menu\">\n <!-- (click)=\"openValueOptions(options, $event)\"> -->\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n <mat-icon class=\"ymt-icon--size-s\">arrow_drop_down</mat-icon>\n </button>\n\n <mat-menu #menu=\"matMenu\">\n @for (pv of predictionValues; track $index) {\n <button mat-menu-item (click)=\"selectOptionByIndex($index)\">{{ pv.value }\n <span>{{ 'yuv.app.invoice.ai.probability' | translate: { probability: pv.probability } }}</span>\n </button>\n }\n </mat-menu>\n}\n", styles: [":host{--current-value-probability-color: var(--ymt-success)}:host .probability{padding:2px;background-color:rgb(from var(--current-value-probability-color) r g b/.1);border:1px solid rgb(from var(--current-value-probability-color) r g b/.3);color:var(--current-value-probability-color);display:flex;border-radius:.25em;gap:var(--ymt-spacing-2xs);font:var(--ymt-font-body-subtle);align-items:center;line-height:1em;--icon-size: 14px}\n"] }]
298
- }] });
299
-
300
378
  /**
301
379
  * Generated bundle index. Do not edit.
302
380
  */
@@ -1 +1 @@
1
- {"version":3,"file":"yuuvis-app-invoice-extensions.mjs","sources":["../../../../projects/yuuvis/app-invoice/extensions/src/lib/actions/open-email/open-email.action.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/apply-flavor/apply-flavor.component.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/apply-flavor/apply-flavor.component.html","../../../../projects/yuuvis/app-invoice/extensions/src/lib/invoice.schema.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/apply-create-flavor/apply-create-flavor.component.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/apply-create-flavor/apply-create-flavor.component.html","../../../../projects/yuuvis/app-invoice/extensions/src/lib/invoice.flavor.create.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/services/extensions.service.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/services/apply-flavor.service.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/form-extensions/ai-extracted-property/ai-extracted-property.component.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/form-extensions/ai-extracted-property/ai-extracted-property.component.html","../../../../projects/yuuvis/app-invoice/extensions/src/yuuvis-app-invoice-extensions.ts"],"sourcesContent":["import { inject } from '@angular/core';\nimport { Router } from '@angular/router';\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 { ShellService } from '@yuuvis/client-shell-core';\nimport { Observable, of } from 'rxjs';\n\nexport class OpenEmailAction extends AbstractContextAction implements Action {\n private translate = inject(TranslateService);\n private router = inject(Router);\n #shell = inject(ShellService);\n\n id = 'app.invoice.open-email';\n label = this.translate.instant('yuv.app.invoice.action.open-email.label');\n description = this.translate.instant(\n 'yuv.app.invoice.action.open-email.description'\n );\n priority = 3;\n icon = 'mail';\n group = 'common';\n range = SelectionRange.SINGLE_SELECT;\n supports: ActionSupport = {};\n\n #app = this.#shell.getApp('io.yuuvis.app.drive');\n\n isExecutable(selection: DmsObject[]) {\n const o = selection[0];\n return of(\n o &&\n o.sots.includes('appSysteminvoice:invoice') &&\n !!o.data['appClassifypro:emailReference']\n );\n }\n\n run(selection: DmsObject[]): Observable<boolean> {\n const o = selection[0];\n const emailReference = o.data['appClassifypro:emailReference'];\n this.router.navigateByUrl(\n `/${this.#app ? this.#app.path : 'drive'}/object/${emailReference}`\n );\n return of(true);\n }\n}\n","import { CommonModule } from '@angular/common';\nimport { Component, effect, inject, untracked } from '@angular/core';\nimport { AbstractApplyObjectFlavorComponent } from '@yuuvis/client-framework/object-flavor';\nimport { ShellService } from '@yuuvis/client-shell-core';\nimport {Router} from '@angular/router';\n\n@Component({\n selector: 'yin-apply-flavor',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './apply-flavor.component.html',\n styleUrl: './apply-flavor.component.scss'\n})\nexport class ApplyFlavorComponent extends AbstractApplyObjectFlavorComponent {\n #router = inject(Router);\n #shell = inject(ShellService);\n #app = this.#shell.getApp('io.yuuvis.app.drive');\n\n #dmsObjectEffect = effect(() => {\n this.dmsObject();\n untracked(() => {\n this.applyFlavor();\n });\n });\n\n applyFlavor() {\n const objectId = this.dmsObject().id;\n this.#shell\n .applyObjectFlavor(this.dmsObject(), this.flavor())\n .subscribe({\n next: () => {\n this.close();\n this.#router.navigateByUrl(`/${this.#app ? this.#app.path : 'drive'}/object/${objectId}`).then();\n },\n error: () => {\n // TODO: handle error\n this.close();\n }\n });\n }\n\n close() {\n this.dialogRef.close();\n }\n}\n","\n","import { marker } from '@colsen1991/ngx-translate-extract-marker';\nimport { SystemType } from '@yuuvis/client-core';\nimport { AppFlavor } from '@yuuvis/client-shell-core';\nimport { ApplyFlavorComponent } from './components/apply-flavor/apply-flavor.component';\n\n// use marker to extract the labels for the app schema types\n// make sure to provide a marker for each type/flavor ID\nmarker('io.yuuvis.app.invoice.flavor.invoice');\nmarker('io.yuuvis.app.invoice.flavor.invoice.description');\n\nexport const APP_ROLE = 'YM_APP_INVOICE';\nexport const APP_PREFIX = 'appSysteminvoice:';\nexport const APP_CLASSIFY_PRO_PREFIX = 'appClassifypro:';\nexport const APP_ID = 'io.yuuvis.app.invoice';\nexport const RETENTION_PERIOD = 10;\n\nexport const APP_FLAVORS: AppFlavor[] = [\n {\n id: 'io.yuuvis.app.invoice.flavor.invoice',\n descriptionKey: 'io.yuuvis.app.invoice.flavor.invoice.description',\n icon: 'local_atm',\n objectTypeID: SystemType.DOCUMENT,\n sot: `${APP_PREFIX}invoice`,\n applicableTo: {\n mimeTypes: ['*/*']\n },\n applyComponent: ApplyFlavorComponent\n },\n {\n id: 'io.yuuvis.app.invoice.flavor.sotFolderClassifypro',\n descriptionKey: 'io.yuuvis.app.invoice.flavor.sotFolderClassifypro.description',\n icon: 'extension',\n objectTypeID: SystemType.FOLDER,\n sot: `${APP_CLASSIFY_PRO_PREFIX}sotFolderClassifypro`,\n applicableTo: {\n mimeTypes: ['*/*']\n },\n preventRemove: true,\n preventApply: true\n },\n {\n id: 'io.yuuvis.app.invoice.flavor.sotInvClassifypro',\n descriptionKey: 'io.yuuvis.app.invoice.flavor.sotInvClassifypro.description',\n icon: 'extension',\n objectTypeID: SystemType.DOCUMENT,\n sot: `${APP_CLASSIFY_PRO_PREFIX}sotInvClassifypro`,\n applicableTo: {\n mimeTypes: ['*/*']\n },\n preventRemove: true,\n preventApply: true\n }\n];\n","import { CommonModule } from '@angular/common';\nimport { Component, effect, inject, Type, untracked } from '@angular/core';\nimport { DmsService } from '@yuuvis/client-core';\nimport { MatDialogRef } from '@angular/material/dialog';\nimport { APP_FLAVORS } from '../../invoice.schema';\nimport { AbstractApplyCreateFlavorComponent } from '@yuuvis/client-framework/object-flavor';\n\n@Component({\n selector: 'yin-apply-create-flavor',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './apply-create-flavor.component.html',\n styleUrl: './apply-create-flavor.component.scss'\n})\nexport class ApplyCreateFlavorComponent extends AbstractApplyCreateFlavorComponent {\n #dms = inject(DmsService);\n readonly #dialogRef = inject(MatDialogRef<ApplyCreateFlavorComponent>);\n\n #dataEffect = effect(() => {\n untracked(() => {\n this.#setupApplyComponent();\n });\n });\n\n sc?: { cmp: Type<any>; inputs: any };\n\n #setupApplyComponent() {\n const flavor = APP_FLAVORS.find((f) => f.id === 'io.yuuvis.app.invoice.flavor.invoice')!\n\n this.#dms.getDmsObject(this.createdObjectIDs()[0]).subscribe((dmsObject) => {\n this.sc = {\n inputs: {\n dmsObject,\n flavor: flavor\n },\n cmp: flavor.applyComponent!\n };\n\n this.#dialogRef.close();\n });\n }\n}\n\n","@if (sc && sc.cmp) {\n <ng-container *ngComponentOutlet=\"sc.cmp; inputs: sc.inputs\"></ng-container>\n}\n","import { ObjectCreateFlavor } from \"@yuuvis/client-core\";\nimport { APP_PREFIX } from \"./invoice.schema\";\nimport { ApplyCreateFlavorComponent } from './components/apply-create-flavor/apply-create-flavor.component';\n\nexport const APP_CREATE_FLAVORS: ObjectCreateFlavor[] = [\n {\n id: 'io.yuuvis.app.invoice.flavor.invoice',\n descriptionKey: 'io.yuuvis.app.invoice.flavor.invoice.description',\n icon: 'local_atm',\n withFileUpload: {\n applicableTo: {\n mimeTypes: ['application/pdf']\n }\n },\n sot: `${APP_PREFIX}invoice`,\n applyComponent: ApplyCreateFlavorComponent\n }\n];\n","import { Injectable, inject } from '@angular/core';\nimport { ActionsService } from '@yuuvis/client-framework/actions';\nimport { ClientShellExtension, ShellService } from '@yuuvis/client-shell-core';\nimport { OpenEmailAction } from '../actions/open-email/open-email.action';\nimport { InvoiceRetentionAction } from '../actions/retention/retention.action';\nimport { APP_CREATE_FLAVORS } from '../invoice.flavor.create';\nimport { APP_FLAVORS } from '../invoice.schema';\n\n@Injectable()\nexport class AppInvoiceExtension implements ClientShellExtension {\n #shell = inject(ShellService);\n #actionsService = inject(ActionsService);\n\n #actions = [\n //{ id: 'app.invoice.retention', action: InvoiceRetentionAction },\n { id: 'app.invoice.open-email', action: OpenEmailAction },\n ];\n\n init(): Promise<any> {\n this.#enableExtension();\n return Promise.resolve();\n }\n\n #enableExtension() {\n // expose flavors\n this.#shell.exposeObjectFlavors(APP_FLAVORS);\n this.#shell.exposeObjectCreateFlavors(APP_CREATE_FLAVORS);\n // register actions\n this.#actionsService.registerActions(this.#actions);\n }\n}\n","import { inject, Injectable, Signal, signal } from '@angular/core';\nimport { PredictionExtractResult, PredictionExtractResultItem, PredictionService } from '@yuuvis/client-core';\nimport { Observable, tap } from 'rxjs';\n\n@Injectable()\nexport class ApplyFlavorService {\n #predict = inject(PredictionService);\n\n #extractedDataSource = signal<Record<string, PredictionExtractResultItem[]> | null>(null);\n extractedData: Signal<Record<string, PredictionExtractResultItem[]> | null> = this.#extractedDataSource.asReadonly();\n\n extract(schemaObjectTypeId: string, objectID: string): Observable<any> {\n return this.#predict\n .extract(schemaObjectTypeId, [objectID])\n .pipe(tap((res: Record<string, PredictionExtractResult>) => this.#extractedDataSource.set(res[objectID].properties)));\n }\n}\n","import { CommonModule } from '@angular/common';\nimport { Component, DestroyRef, effect, ElementRef, inject, OnInit, signal, TemplateRef, untracked } from '@angular/core';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatMenuModule } from '@angular/material/menu';\nimport {PredictionExtractResultItem, SystemService, TranslateModule} from '@yuuvis/client-core';\nimport { ObjectFormElementExtension } from '@yuuvis/client-framework/object-form';\nimport { ApplyFlavorService } from '../../../services/apply-flavor.service';\n\n/**\n * This object form field extension inserts AI-extracted values into an\n * object-form. Once the AI service has extracted a value, this extension\n * will change the form field to display the extracted value and show the\n * value for the probability of the extraction right next to the field.\n *\n * If there are multiple extractions, the extension will insert the value\n * with the highest probability and provide a picker for the other values.\n *\n * This way the user can easily accept the extracted value or choose a\n * different one from the list of extracted values.\n */\n@Component({\n selector: 'yin-ai-extracted-property',\n standalone: true,\n imports: [CommonModule, MatMenuModule, MatIconModule, TranslateModule],\n templateUrl: './ai-extracted-property.component.html',\n styleUrl: './ai-extracted-property.component.scss'\n})\nexport class AiExtractedPropertyComponent extends ObjectFormElementExtension implements OnInit {\n #applyFlavorService = inject(ApplyFlavorService);\n #destroyRef = inject(DestroyRef);\n #system = inject(SystemService);\n #elRef = inject(ElementRef);\n\n predictionValues: PredictionExtractResultItem[] = [];\n currentValueProbability = signal<number | undefined>(undefined);\n #currentValueProbabilityEffect = effect(() => {\n const cp = this.currentValueProbability();\n if (!cp) return;\n // set the probability color\n const color = cp < 30 ? '--ymt-danger' : cp < 60 ? '--ymt-warning' : '--ymt-success';\n (this.#elRef.nativeElement as HTMLElement).style.setProperty('--current-value-probability-color', `var(${color})`);\n });\n\n extractedData = this.#applyFlavorService.extractedData;\n extractedDataEffect = effect(() => {\n const extData = this.extractedData();\n if (extData) {\n untracked(() => {\n const fcn = this.input().formControlName;\n this.predictionValues = extData[fcn] || [];\n this.#applyPredictionValues();\n });\n }\n });\n\n #internalFieldType?: string;\n\n #applyPredictionValues() {\n // set the value of the form field to the extracted value with\n // the highest probability\n const pv = this.predictionValues;\n if (pv.length) {\n pv.sort((a, b) => b.probability - a.probability);\n this.selectOption(pv[0]);\n } else {\n this.currentValueProbability.set(undefined);\n }\n }\n\n // map extracted string to a proper format to be used\n // within the form elements\n #mapValueToType(value: any): unknown {\n if (this.#internalFieldType === 'datetime') {\n // dates will always be returned as german formatted strings (24.12.2024)\n // no matter what the locale of the processed document is. So we need to\n // convert the string to a proper date object\n const dateParts = value.split('.');\n return dateParts.length === 3 ? new Date(+dateParts[2], +dateParts[1] - 1, +dateParts[0]) : value;\n } else {\n return value;\n }\n }\n\n selectOptionByIndex(idx: number) {\n this.selectOption(this.predictionValues[idx]);\n }\n\n selectOption(pr: PredictionExtractResultItem) {\n this.setValue(this.#mapValueToType(pr.value));\n this.currentValueProbability.set(pr.probability);\n }\n\n ngOnInit() {\n this.#internalFieldType = this.#system.getObjectTypeField(this.input().formControlName)?._internalType;\n }\n}\n","@if (predictionValues.length === 1) {\n <span class=\"probability\">\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n </span\n >\n} @else if (predictionValues.length > 1) {\n <button class=\"probability\" [matMenuTriggerFor]=\"menu\">\n <!-- (click)=\"openValueOptions(options, $event)\"> -->\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n <mat-icon class=\"ymt-icon--size-s\">arrow_drop_down</mat-icon>\n </button>\n\n <mat-menu #menu=\"matMenu\">\n @for (pv of predictionValues; track $index) {\n <button mat-menu-item (click)=\"selectOptionByIndex($index)\">{{ pv.value }\n <span>{{ 'yuv.app.invoice.ai.probability' | translate: { probability: pv.probability } }}</span>\n </button>\n }\n </mat-menu>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"yuuvis-app-invoice-extensions.mjs","sources":["../../../../projects/yuuvis/app-invoice/extensions/src/lib/actions/open-email/open-email.action.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/services/apply-flavor.service.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/form-extensions/ai-extracted-property/ai-extracted-property.component.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/form-extensions/ai-extracted-property/ai-extracted-property.component.html","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/apply-flavor/apply-flavor.component.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/apply-flavor/apply-flavor.component.html","../../../../projects/yuuvis/app-invoice/extensions/src/lib/invoice.schema.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/apply-create-flavor/apply-create-flavor.component.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/components/apply-create-flavor/apply-create-flavor.component.html","../../../../projects/yuuvis/app-invoice/extensions/src/lib/invoice.flavor.create.ts","../../../../projects/yuuvis/app-invoice/extensions/src/lib/services/extensions.service.ts","../../../../projects/yuuvis/app-invoice/extensions/src/yuuvis-app-invoice-extensions.ts"],"sourcesContent":["import { inject } from '@angular/core';\nimport { Router } from '@angular/router';\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 { ShellService } from '@yuuvis/client-shell-core';\nimport { Observable, of } from 'rxjs';\n\nexport class OpenEmailAction extends AbstractContextAction implements Action {\n private translate = inject(TranslateService);\n private router = inject(Router);\n #shell = inject(ShellService);\n\n id = 'app.invoice.open-email';\n label = this.translate.instant('yuv.app.invoice.action.open-email.label');\n description = this.translate.instant(\n 'yuv.app.invoice.action.open-email.description'\n );\n priority = 3;\n icon = 'mail';\n group = 'common';\n range = SelectionRange.SINGLE_SELECT;\n supports: ActionSupport = {};\n\n #app = this.#shell.getApp('io.yuuvis.app.drive');\n\n isExecutable(selection: DmsObject[]) {\n const o = selection[0];\n return of(\n o &&\n o.sots.includes('appSysteminvoice:invoice') &&\n !!o.data['appClassifypro:emailReference']\n );\n }\n\n run(selection: DmsObject[]): Observable<boolean> {\n const o = selection[0];\n const emailReference = o.data['appClassifypro:emailReference'];\n this.router.navigateByUrl(\n `/${this.#app ? this.#app.path : 'drive'}/object/${emailReference}`\n );\n return of(true);\n }\n}\n","import { inject, Injectable, Signal, signal } from '@angular/core';\nimport { PredictionExtractResult, PredictionExtractResultItem, PredictionService } from '@yuuvis/client-core';\nimport { Observable, tap } from 'rxjs';\n\n@Injectable()\nexport class ApplyFlavorService {\n #predict = inject(PredictionService);\n\n #extractedDataSource = signal<Record<string, PredictionExtractResultItem[]> | null>(null);\n extractedData: Signal<Record<string, PredictionExtractResultItem[]> | null> = this.#extractedDataSource.asReadonly();\n\n extract(schemaObjectTypeId: string, objectID: string): Observable<any> {\n return this.#predict\n .extract(schemaObjectTypeId, [objectID])\n .pipe(tap((res: Record<string, PredictionExtractResult>) => this.#extractedDataSource.set(res[objectID].properties)));\n }\n}\n","import { CommonModule } from '@angular/common';\nimport { Component, DestroyRef, effect, ElementRef, inject, OnInit, signal, TemplateRef, untracked } from '@angular/core';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatMenuModule } from '@angular/material/menu';\nimport {PredictionExtractResultItem, SystemService, TranslateModule} from '@yuuvis/client-core';\nimport { ObjectFormElementExtension } from '@yuuvis/client-framework/object-form';\nimport { ApplyFlavorService } from '../../../services/apply-flavor.service';\n\n/**\n * This object form field extension inserts AI-extracted values into an\n * object-form. Once the AI service has extracted a value, this extension\n * will change the form field to display the extracted value and show the\n * value for the probability of the extraction right next to the field.\n *\n * If there are multiple extractions, the extension will insert the value\n * with the highest probability and provide a picker for the other values.\n *\n * This way the user can easily accept the extracted value or choose a\n * different one from the list of extracted values.\n */\n@Component({\n selector: 'yin-ai-extracted-property',\n standalone: true,\n imports: [CommonModule, MatMenuModule, MatIconModule, TranslateModule],\n templateUrl: './ai-extracted-property.component.html',\n styleUrl: './ai-extracted-property.component.scss'\n})\nexport class AiExtractedPropertyComponent extends ObjectFormElementExtension implements OnInit {\n #applyFlavorService = inject(ApplyFlavorService);\n #destroyRef = inject(DestroyRef);\n #system = inject(SystemService);\n #elRef = inject(ElementRef);\n\n predictionValues: PredictionExtractResultItem[] = [];\n currentValueProbability = signal<number | undefined>(undefined);\n #currentValueProbabilityEffect = effect(() => {\n const cp = this.currentValueProbability();\n if (!cp) return;\n // set the probability color\n const color = cp < 30 ? '--ymt-danger' : cp < 60 ? '--ymt-warning' : '--ymt-success';\n (this.#elRef.nativeElement as HTMLElement).style.setProperty('--current-value-probability-color', `var(${color})`);\n });\n\n extractedData = this.#applyFlavorService.extractedData;\n extractedDataEffect = effect(() => {\n const extData = this.extractedData();\n if (extData) {\n untracked(() => {\n const fcn = this.input().formControlName;\n this.predictionValues = extData[fcn] || [];\n this.#applyPredictionValues();\n });\n }\n });\n\n #internalFieldType?: string;\n\n #applyPredictionValues() {\n // set the value of the form field to the extracted value with\n // the highest probability\n const pv = this.predictionValues;\n if (pv.length) {\n pv.sort((a, b) => b.probability - a.probability);\n this.selectOption(pv[0]);\n } else {\n this.currentValueProbability.set(undefined);\n }\n }\n\n // map extracted string to a proper format to be used\n // within the form elements\n #mapValueToType(value: any): unknown {\n if (this.#internalFieldType === 'datetime') {\n // dates will always be returned as german formatted strings (24.12.2024)\n // no matter what the locale of the processed document is. So we need to\n // convert the string to a proper date object\n const dateParts = value.split('.');\n return dateParts.length === 3 ? new Date(+dateParts[2], +dateParts[1] - 1, +dateParts[0]) : value;\n } else {\n return value;\n }\n }\n\n selectOptionByIndex(idx: number) {\n this.selectOption(this.predictionValues[idx]);\n }\n\n selectOption(pr: PredictionExtractResultItem) {\n this.setValue(this.#mapValueToType(pr.value));\n this.currentValueProbability.set(pr.probability);\n }\n\n ngOnInit() {\n this.#internalFieldType = this.#system.getObjectTypeField(this.input().formControlName)?._internalType;\n }\n}\n","@if (predictionValues.length === 1) {\n <span class=\"probability\">\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n </span\n >\n} @else if (predictionValues.length > 1) {\n <button class=\"probability\" [matMenuTriggerFor]=\"menu\">\n <!-- (click)=\"openValueOptions(options, $event)\"> -->\n <mat-icon class=\"ymt-icon--size-s\">robot_2</mat-icon>\n {{ 'yuv.app.invoice.ai.probability' | translate: { probability: currentValueProbability() } }}\n <mat-icon class=\"ymt-icon--size-s\">arrow_drop_down</mat-icon>\n </button>\n\n <mat-menu #menu=\"matMenu\">\n @for (pv of predictionValues; track $index) {\n <button mat-menu-item (click)=\"selectOptionByIndex($index)\">{{ pv.value }\n <span>{{ 'yuv.app.invoice.ai.probability' | translate: { probability: pv.probability } }}</span>\n </button>\n }\n </mat-menu>\n}\n","import { CommonModule } from '@angular/common';\nimport { Component, computed, effect, inject, signal, untracked, viewChild } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatDialogModule } from '@angular/material/dialog';\nimport { Situation, SystemService, TranslateModule, TranslateService, UserService } from '@yuuvis/client-core';\nimport { BusyOverlayDirective, DialogComponent } from '@yuuvis/client-framework/common';\nimport { AbstractApplyObjectFlavorComponent } from '@yuuvis/client-framework/object-flavor';\nimport { FormStatusChangedEvent, IObjectFormElementExtension, ObjectFormComponent, ObjectFormOptions } from '@yuuvis/client-framework/object-form';\nimport { ObjectPreviewComponent } from '@yuuvis/client-framework/object-preview';\nimport { YuvSplitViewModule } from '@yuuvis/client-framework/split-view';\nimport { ObjectFlavor, ShellService } from '@yuuvis/client-shell-core';\nimport { finalize } from 'rxjs';\nimport { ApplyFlavorService } from '../../services/apply-flavor.service';\nimport { AiExtractedPropertyComponent } from '../form-extensions/ai-extracted-property/ai-extracted-property.component';\nimport { YmtButtonDirective } from '@yuuvis/material';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { MatIconModule } from '@angular/material/icon';\n\nconst COMPONENTS = [\n YuvSplitViewModule,\n TranslateModule,\n BusyOverlayDirective,\n ObjectFormComponent,\n ObjectPreviewComponent,\n DialogComponent,\n YmtButtonDirective\n];\nconst MATERIAL = [MatButtonModule, MatDialogModule, MatTooltipModule];\n\n@Component({\n selector: 'yin-apply-flavor',\n standalone: true,\n providers: [ApplyFlavorService],\n imports: [CommonModule, ...COMPONENTS, ...MATERIAL, MatIconModule],\n templateUrl: './apply-flavor.component.html',\n styleUrl: './apply-flavor.component.scss'\n})\nexport class ApplyFlavorComponent extends AbstractApplyObjectFlavorComponent {\n #system = inject(SystemService);\n #shell = inject(ShellService);\n #applyFlavorService = inject(ApplyFlavorService);\n private translate = inject(TranslateService);\n private userService = inject(UserService);\n\n objectForm = viewChild(ObjectFormComponent);\n flavorLabel = computed(() => this.#shell.getFlavorLabel(this.flavor().id));\n #flavorEffect = effect(() => {\n const f = this.flavor();\n untracked(() => {\n if (f) this.#loadForm(f);\n });\n });\n #dmsObjectEffect = effect(() => {\n const o = this.dmsObject();\n untracked(() => {\n this.supportsExtraction.set(!!o.content && o.content.mimeType === 'application/pdf'\n && this.userService.getCurrentUser().authorities.includes('YUUVIS_AI_PREDICT'));\n });\n });\n\n error = signal<boolean>(false);\n\n applyDisabled = signal<boolean>(true);\n supportsExtraction = signal<boolean>(true);\n busyLoading = signal<boolean>(false);\n busySaving = signal<boolean>(false);\n busyExtracting = signal<boolean>(false);\n formOptions = signal<ObjectFormOptions | null>(null);\n extensions = signal<IObjectFormElementExtension[]>([]);\n immediateExtract = (this.data() && this.data().immediateExtract) || false;\n headline?: string = this.data() && this.data().headline;\n\n #loadForm(f: ObjectFlavor) {\n this.busyLoading.set(true);\n\n if (this.userService.getCurrentUser().authorities.includes('YUUVIS_AI_PREDICT')) {\n const sot = this.#system.getSecondaryObjectType(f.sot);\n this.extensions.set(\n (sot?.fields || []).map((field) => ({\n property: field.id,\n cmp: AiExtractedPropertyComponent\n }))\n );\n }\n\n this.#system\n .getObjectTypeForm(f.sot, Situation.EDIT)\n .pipe(finalize(() => this.busyLoading.set(false)))\n .subscribe({\n next: (form) => {\n this.formOptions.set({\n formModel: form,\n data: {}\n });\n }\n });\n }\n\n extract() {\n this.busyExtracting.set(true);\n this.#applyFlavorService\n .extract(this.flavor().sot, this.dmsObject().id)\n .pipe(finalize(() => this.busyExtracting.set(false)))\n .subscribe({\n next: () => {\n this.error.set(false);\n },\n error: () => {\n this.error.set(true);\n }\n });\n }\n\n onFormStatusChanged(status: FormStatusChangedEvent) {\n this.applyDisabled.set(status.invalid);\n }\n\n applyFlavor() {\n const of = this.objectForm();\n const data: Record<string, unknown> = of ? of.getFormData() : {};\n this.busySaving.set(true);\n this.#shell\n .applyObjectFlavor(this.dmsObject(), this.flavor(), data)\n .pipe(finalize(() => this.busySaving.set(false)))\n .subscribe({\n next: () => this.close()\n // TODO: handle error\n });\n }\n\n close() {\n this.dialogRef.close();\n }\n}\n","<yuv-dialog [headertitel]=\"headline || ('yuv.app.invoice.apply-flavor.headline' | translate: { name: flavorLabel() })\">\n <main>\n <yuv-split-view [gutterSize]=\"1\">\n <ng-template yuvSplitArea [size]=\"60\">\n @if (dmsObject() && dmsObject().content) {\n <yuv-object-preview [objectId]=\"dmsObject().id\"></yuv-object-preview>\n }\n </ng-template>\n\n <ng-template yuvSplitArea [size]=\"40\">\n <div class=\"metadata\" [yuvBusyOverlay]=\"busyLoading()\">\n <div class=\"ai\">\n @if (supportsExtraction()) {\n @if (error()) {\n <mat-icon class=\"warning\" [matTooltip]=\"'yuv.app.invoice.apply-flavor.button.extract.error' | translate\">warning</mat-icon>\n }\n @if (busyExtracting()) {\n <div class=\"spinner\"></div>\n }\n <button ymtButton=\"secondary\" class=\"ai-extract\" [ngClass]=\"{ spinning: busyExtracting() }\" (click)=\"extract()\">\n <mat-icon>robot_2</mat-icon>\n {{ 'yuv.app.invoice.apply-flavor.button.extract' | translate }}\n </button>\n }\n </div>\n\n @let fo = formOptions();\n @if (fo) {\n <yuv-object-form\n [elementExtensions]=\"extensions()\"\n [inert]=\"busySaving() || busyExtracting()\"\n [formOptions]=\"fo\"\n (statusChanged)=\"onFormStatusChanged($event)\"\n ></yuv-object-form>\n }\n </div>\n </ng-template>\n </yuv-split-view>\n </main>\n\n <footer>\n <button ymtButton=\"secondary\" mat-dialog-close [disabled]=\"busySaving() || busyExtracting()\">\n {{ 'yuv.app.invoice.apply-flavor.button.cancel' | translate }}\n </button>\n <button\n ymtButton=\"primary\"\n mat-dialog-close\n cdkFocusInitial\n class=\"primary\"\n [ngClass]=\"{ spinning: busySaving() }\"\n [disabled]=\"applyDisabled() || busyExtracting()\"\n (click)=\"applyFlavor()\"\n >\n {{ 'yuv.app.invoice.apply-flavor.button.apply' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n","import { marker } from '@colsen1991/ngx-translate-extract-marker';\nimport { SystemType } from '@yuuvis/client-core';\nimport { AppFlavor } from '@yuuvis/client-shell-core';\nimport { ApplyFlavorComponent } from './components/apply-flavor/apply-flavor.component';\n\n// use marker to extract the labels for the app schema types\n// make sure to provide a marker for each type/flavor ID\nmarker('io.yuuvis.app.invoice.flavor.invoice');\nmarker('io.yuuvis.app.invoice.flavor.invoice.description');\n\nexport const APP_ROLE = 'YM_APP_INVOICE';\nexport const APP_PREFIX = 'appSysteminvoice:';\nexport const APP_CLASSIFY_PRO_PREFIX = 'appClassifypro:';\nexport const APP_ID = 'io.yuuvis.app.invoice';\nexport const RETENTION_PERIOD = 10;\n\nexport const APP_FLAVORS: AppFlavor[] = [\n {\n id: 'io.yuuvis.app.invoice.flavor.invoice',\n descriptionKey: 'io.yuuvis.app.invoice.flavor.invoice.description',\n icon: 'local_atm',\n objectTypeID: SystemType.DOCUMENT,\n sot: `${APP_PREFIX}invoice`,\n applicableTo: {\n mimeTypes: ['*/*']\n },\n applyComponent: ApplyFlavorComponent\n },\n {\n id: 'io.yuuvis.app.invoice.flavor.sotFolderClassifypro',\n descriptionKey: 'io.yuuvis.app.invoice.flavor.sotFolderClassifypro.description',\n icon: 'extension',\n objectTypeID: SystemType.FOLDER,\n sot: `${APP_CLASSIFY_PRO_PREFIX}sotFolderClassifypro`,\n applicableTo: {\n mimeTypes: ['*/*']\n },\n preventRemove: true,\n preventApply: true\n },\n {\n id: 'io.yuuvis.app.invoice.flavor.sotInvClassifypro',\n descriptionKey: 'io.yuuvis.app.invoice.flavor.sotInvClassifypro.description',\n icon: 'extension',\n objectTypeID: SystemType.DOCUMENT,\n sot: `${APP_CLASSIFY_PRO_PREFIX}sotInvClassifypro`,\n applicableTo: {\n mimeTypes: ['*/*']\n },\n preventRemove: true,\n preventApply: true\n }\n];\n","import { CommonModule } from '@angular/common';\nimport { Component, effect, inject, Type, untracked } from '@angular/core';\nimport { DmsService } from '@yuuvis/client-core';\nimport { MatDialogRef } from '@angular/material/dialog';\nimport { APP_FLAVORS } from '../../invoice.schema';\nimport { AbstractApplyCreateFlavorComponent } from '@yuuvis/client-framework/object-flavor';\n\n@Component({\n selector: 'yin-apply-create-flavor',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './apply-create-flavor.component.html',\n styleUrl: './apply-create-flavor.component.scss'\n})\nexport class ApplyCreateFlavorComponent extends AbstractApplyCreateFlavorComponent {\n #dms = inject(DmsService);\n readonly #dialogRef = inject(MatDialogRef<ApplyCreateFlavorComponent>);\n\n #dataEffect = effect(() => {\n untracked(() => {\n this.#setupApplyComponent();\n });\n });\n\n sc?: { cmp: Type<any>; inputs: any };\n\n #setupApplyComponent() {\n const flavor = APP_FLAVORS.find((f) => f.id === 'io.yuuvis.app.invoice.flavor.invoice')!\n\n this.#dms.getDmsObject(this.createdObjectIDs()[0]).subscribe((dmsObject) => {\n this.sc = {\n inputs: {\n dmsObject,\n flavor: flavor\n },\n cmp: flavor.applyComponent!\n };\n\n if (dmsObject.content?.mimeType === 'application/x-os-invoice-xml') {\n this.#dialogRef.close();\n }\n });\n }\n}\n\n","@if (sc && sc.cmp) {\n <ng-container *ngComponentOutlet=\"sc.cmp; inputs: sc.inputs\"></ng-container>\n}\n","import { ObjectCreateFlavor } from \"@yuuvis/client-core\";\nimport { APP_PREFIX } from \"./invoice.schema\";\nimport { ApplyCreateFlavorComponent } from './components/apply-create-flavor/apply-create-flavor.component';\n\nexport const APP_CREATE_FLAVORS: ObjectCreateFlavor[] = [\n {\n id: 'io.yuuvis.app.invoice.flavor.invoice',\n descriptionKey: 'io.yuuvis.app.invoice.flavor.invoice.description',\n icon: 'local_atm',\n withFileUpload: {\n applicableTo: {\n mimeTypes: ['application/pdf']\n }\n },\n sot: `${APP_PREFIX}invoice`,\n applyComponent: ApplyCreateFlavorComponent\n }\n];\n","import { Injectable, inject } from '@angular/core';\nimport { ActionsService } from '@yuuvis/client-framework/actions';\nimport { ClientShellExtension, ShellService } from '@yuuvis/client-shell-core';\nimport { OpenEmailAction } from '../actions/open-email/open-email.action';\nimport { InvoiceRetentionAction } from '../actions/retention/retention.action';\nimport { APP_CREATE_FLAVORS } from '../invoice.flavor.create';\nimport { APP_FLAVORS } from '../invoice.schema';\n\n@Injectable()\nexport class AppInvoiceExtension implements ClientShellExtension {\n #shell = inject(ShellService);\n #actionsService = inject(ActionsService);\n\n #actions = [\n //{ id: 'app.invoice.retention', action: InvoiceRetentionAction },\n { id: 'app.invoice.open-email', action: OpenEmailAction },\n ];\n\n init(): Promise<any> {\n this.#enableExtension();\n return Promise.resolve();\n }\n\n #enableExtension() {\n // expose flavors\n this.#shell.exposeObjectFlavors(APP_FLAVORS);\n this.#shell.exposeObjectCreateFlavors(APP_CREATE_FLAVORS);\n // register actions\n this.#actionsService.registerActions(this.#actions);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["TranslateService","i1","i6"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuuvis/app-invoice",
3
- "version": "2.3.4",
3
+ "version": "2.3.6",
4
4
  "author": "OPTIMAL SYSTEMS GmbH <npm@optimal-systems.de>",
5
5
  "license": "MIT",
6
6
  "peerDependencies": {