@epistola.app/valtimo-plugin 0.0.1 → 0.1.1
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/package.json +9 -13
- package/ng-package.json +0 -17
- package/src/lib/assets/epistola-logo.ts +0 -4
- package/src/lib/assets/index.ts +0 -1
- package/src/lib/components/check-job-status-configuration/check-job-status-configuration.component.html +0 -51
- package/src/lib/components/check-job-status-configuration/check-job-status-configuration.component.scss +0 -1
- package/src/lib/components/check-job-status-configuration/check-job-status-configuration.component.ts +0 -71
- package/src/lib/components/data-mapping-tree/data-mapping-tree.component.html +0 -23
- package/src/lib/components/data-mapping-tree/data-mapping-tree.component.scss +0 -38
- package/src/lib/components/data-mapping-tree/data-mapping-tree.component.ts +0 -124
- package/src/lib/components/download-document-configuration/download-document-configuration.component.html +0 -29
- package/src/lib/components/download-document-configuration/download-document-configuration.component.scss +0 -1
- package/src/lib/components/download-document-configuration/download-document-configuration.component.ts +0 -71
- package/src/lib/components/epistola-configuration/epistola-configuration.component.html +0 -74
- package/src/lib/components/epistola-configuration/epistola-configuration.component.scss +0 -1
- package/src/lib/components/epistola-configuration/epistola-configuration.component.ts +0 -96
- package/src/lib/components/epistola-download/epistola-download.component.ts +0 -79
- package/src/lib/components/epistola-download/epistola-download.formio.ts +0 -19
- package/src/lib/components/field-tree/field-tree.component.html +0 -192
- package/src/lib/components/field-tree/field-tree.component.scss +0 -255
- package/src/lib/components/field-tree/field-tree.component.ts +0 -321
- package/src/lib/components/generate-document-configuration/generate-document-configuration.component.html +0 -182
- package/src/lib/components/generate-document-configuration/generate-document-configuration.component.scss +0 -150
- package/src/lib/components/generate-document-configuration/generate-document-configuration.component.ts +0 -422
- package/src/lib/epistola.module.ts +0 -50
- package/src/lib/epistola.specification.ts +0 -208
- package/src/lib/models/config.ts +0 -53
- package/src/lib/models/index.ts +0 -2
- package/src/lib/models/template.ts +0 -70
- package/src/lib/services/epistola-plugin.service.ts +0 -82
- package/src/lib/services/index.ts +0 -1
- package/src/public_api.ts +0 -16
- package/tsconfig.lib.json +0 -21
- /package/{dist/fesm2022 → fesm2022}/epistola.app-valtimo-plugin.mjs +0 -0
- /package/{dist/fesm2022 → fesm2022}/epistola.app-valtimo-plugin.mjs.map +0 -0
- /package/{dist/index.d.ts → index.d.ts} +0 -0
- /package/{dist/lib → lib}/assets/epistola-logo.d.ts +0 -0
- /package/{dist/lib → lib}/assets/index.d.ts +0 -0
- /package/{dist/lib → lib}/components/check-job-status-configuration/check-job-status-configuration.component.d.ts +0 -0
- /package/{dist/lib → lib}/components/data-mapping-tree/data-mapping-tree.component.d.ts +0 -0
- /package/{dist/lib → lib}/components/download-document-configuration/download-document-configuration.component.d.ts +0 -0
- /package/{dist/lib → lib}/components/epistola-configuration/epistola-configuration.component.d.ts +0 -0
- /package/{dist/lib → lib}/components/epistola-download/epistola-download.component.d.ts +0 -0
- /package/{dist/lib → lib}/components/epistola-download/epistola-download.formio.d.ts +0 -0
- /package/{dist/lib → lib}/components/field-tree/field-tree.component.d.ts +0 -0
- /package/{dist/lib → lib}/components/generate-document-configuration/generate-document-configuration.component.d.ts +0 -0
- /package/{dist/lib → lib}/epistola.module.d.ts +0 -0
- /package/{dist/lib → lib}/epistola.specification.d.ts +0 -0
- /package/{dist/lib → lib}/models/config.d.ts +0 -0
- /package/{dist/lib → lib}/models/index.d.ts +0 -0
- /package/{dist/lib → lib}/models/template.d.ts +0 -0
- /package/{dist/lib → lib}/services/epistola-plugin.service.d.ts +0 -0
- /package/{dist/lib → lib}/services/index.d.ts +0 -0
- /package/{dist/public_api.d.ts → public_api.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epistola.app/valtimo-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Epistola document generation plugin for Valtimo",
|
|
5
5
|
"license": "EUPL-1.2",
|
|
6
|
-
"
|
|
7
|
-
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/epistola-app/valtimo-epistola-plugin"
|
|
9
|
+
},
|
|
10
|
+
"module": "fesm2022/epistola.app-valtimo-plugin.mjs",
|
|
11
|
+
"typings": "index.d.ts",
|
|
8
12
|
"exports": {
|
|
9
13
|
"./package.json": {
|
|
10
14
|
"default": "./package.json"
|
|
11
15
|
},
|
|
12
16
|
".": {
|
|
13
|
-
"types": "./
|
|
14
|
-
"default": "./
|
|
17
|
+
"types": "./index.d.ts",
|
|
18
|
+
"default": "./fesm2022/epistola.app-valtimo-plugin.mjs"
|
|
15
19
|
}
|
|
16
20
|
},
|
|
17
21
|
"sideEffects": false,
|
|
18
|
-
"scripts": {
|
|
19
|
-
"build": "ng-packagr -p ng-package.json",
|
|
20
|
-
"watch": "ng-packagr -p ng-package.json --watch",
|
|
21
|
-
"test": "echo 'No tests configured yet'"
|
|
22
|
-
},
|
|
23
22
|
"peerDependencies": {
|
|
24
23
|
"@angular/common": ">=17.0.0",
|
|
25
24
|
"@angular/core": ">=17.0.0",
|
|
@@ -31,8 +30,5 @@
|
|
|
31
30
|
},
|
|
32
31
|
"dependencies": {
|
|
33
32
|
"tslib": "^2.6.0"
|
|
34
|
-
},
|
|
35
|
-
"devDependencies": {
|
|
36
|
-
"ng-packagr": "^19.0.0"
|
|
37
33
|
}
|
|
38
34
|
}
|
package/ng-package.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
|
3
|
-
"dest": "dist",
|
|
4
|
-
"lib": {
|
|
5
|
-
"entryFile": "src/public_api.ts"
|
|
6
|
-
},
|
|
7
|
-
"allowedNonPeerDependencies": [
|
|
8
|
-
"@angular/common",
|
|
9
|
-
"@angular/core",
|
|
10
|
-
"@angular/forms",
|
|
11
|
-
"@valtimo/plugin",
|
|
12
|
-
"@valtimo/components",
|
|
13
|
-
"@ngx-translate/core",
|
|
14
|
-
"rxjs",
|
|
15
|
-
"tslib"
|
|
16
|
-
]
|
|
17
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
// Placeholder logo - a simple document icon in SVG format, base64 encoded
|
|
2
|
-
// TODO: Replace with actual Epistola logo
|
|
3
|
-
export const EPISTOLA_PLUGIN_LOGO_BASE64 =
|
|
4
|
-
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iIzMzNjZjYyI+PHBhdGggZD0iTTE0IDJINmMtMS4xIDAtMiAuOS0yIDJ2MTZjMCAxLjEuOSAyIDIgMmgxMmMxLjEgMCAyLS45IDItMlY4bC02LTZ6bTQgMThINlY0aDd2NWg1djExeiIvPjxwYXRoIGQ9Ik04IDEyaDh2Mkg4em0wIDRoOHYtMkg4em0wLThWNmg0djJ6Ii8+PC9zdmc+';
|
package/src/lib/assets/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './epistola-logo';
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
<v-form
|
|
2
|
-
(valueChange)="formValueChange($event)"
|
|
3
|
-
*ngIf="{
|
|
4
|
-
disabled: safeDisabled$ | async,
|
|
5
|
-
prefill: prefillConfiguration$ ? (prefillConfiguration$ | async) : null
|
|
6
|
-
} as obs"
|
|
7
|
-
>
|
|
8
|
-
<v-input
|
|
9
|
-
name="requestIdVariable"
|
|
10
|
-
[title]="'requestIdVariable' | pluginTranslate: pluginId | async"
|
|
11
|
-
[tooltip]="'requestIdVariableTooltip' | pluginTranslate: pluginId | async"
|
|
12
|
-
[margin]="true"
|
|
13
|
-
[defaultValue]="obs.prefill?.requestIdVariable || 'epistolaRequestId'"
|
|
14
|
-
[disabled]="obs.disabled"
|
|
15
|
-
[required]="true"
|
|
16
|
-
>
|
|
17
|
-
</v-input>
|
|
18
|
-
|
|
19
|
-
<v-input
|
|
20
|
-
name="statusVariable"
|
|
21
|
-
[title]="'statusVariable' | pluginTranslate: pluginId | async"
|
|
22
|
-
[tooltip]="'statusVariableTooltip' | pluginTranslate: pluginId | async"
|
|
23
|
-
[margin]="true"
|
|
24
|
-
[defaultValue]="obs.prefill?.statusVariable || 'epistolaStatus'"
|
|
25
|
-
[disabled]="obs.disabled"
|
|
26
|
-
[required]="true"
|
|
27
|
-
>
|
|
28
|
-
</v-input>
|
|
29
|
-
|
|
30
|
-
<v-input
|
|
31
|
-
name="documentIdVariable"
|
|
32
|
-
[title]="'documentIdVariable' | pluginTranslate: pluginId | async"
|
|
33
|
-
[tooltip]="'documentIdVariableTooltip' | pluginTranslate: pluginId | async"
|
|
34
|
-
[margin]="true"
|
|
35
|
-
[defaultValue]="obs.prefill?.documentIdVariable || 'epistolaDocumentId'"
|
|
36
|
-
[disabled]="obs.disabled"
|
|
37
|
-
[required]="false"
|
|
38
|
-
>
|
|
39
|
-
</v-input>
|
|
40
|
-
|
|
41
|
-
<v-input
|
|
42
|
-
name="errorMessageVariable"
|
|
43
|
-
[title]="'errorMessageVariable' | pluginTranslate: pluginId | async"
|
|
44
|
-
[tooltip]="'errorMessageVariableTooltip' | pluginTranslate: pluginId | async"
|
|
45
|
-
[margin]="true"
|
|
46
|
-
[defaultValue]="obs.prefill?.errorMessageVariable || 'epistolaErrorMessage'"
|
|
47
|
-
[disabled]="obs.disabled"
|
|
48
|
-
[required]="false"
|
|
49
|
-
>
|
|
50
|
-
</v-input>
|
|
51
|
-
</v-form>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// Check job status configuration styles
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
|
|
2
|
-
import {CommonModule} from '@angular/common';
|
|
3
|
-
import {FunctionConfigurationComponent, PluginTranslatePipeModule} from '@valtimo/plugin';
|
|
4
|
-
import {FormModule, FormOutput, InputModule} from '@valtimo/components';
|
|
5
|
-
import {BehaviorSubject, combineLatest, Observable, Subscription, take} from 'rxjs';
|
|
6
|
-
import {delay, startWith} from 'rxjs/operators';
|
|
7
|
-
import {CheckJobStatusConfig} from '../../models';
|
|
8
|
-
|
|
9
|
-
@Component({
|
|
10
|
-
selector: 'epistola-check-job-status-configuration',
|
|
11
|
-
templateUrl: './check-job-status-configuration.component.html',
|
|
12
|
-
styleUrls: ['./check-job-status-configuration.component.scss'],
|
|
13
|
-
standalone: true,
|
|
14
|
-
imports: [CommonModule, PluginTranslatePipeModule, FormModule, InputModule]
|
|
15
|
-
})
|
|
16
|
-
export class CheckJobStatusConfigurationComponent
|
|
17
|
-
implements FunctionConfigurationComponent, OnInit, OnDestroy
|
|
18
|
-
{
|
|
19
|
-
@Input() save$!: Observable<void>;
|
|
20
|
-
@Input() disabled$!: Observable<boolean>;
|
|
21
|
-
@Input() pluginId!: string;
|
|
22
|
-
@Input() prefillConfiguration$!: Observable<CheckJobStatusConfig>;
|
|
23
|
-
|
|
24
|
-
@Output() valid: EventEmitter<boolean> = new EventEmitter<boolean>();
|
|
25
|
-
@Output() configuration: EventEmitter<CheckJobStatusConfig> = new EventEmitter<CheckJobStatusConfig>();
|
|
26
|
-
|
|
27
|
-
private saveSubscription!: Subscription;
|
|
28
|
-
private readonly formValue$ = new BehaviorSubject<CheckJobStatusConfig | null>(null);
|
|
29
|
-
private readonly valid$ = new BehaviorSubject<boolean>(false);
|
|
30
|
-
|
|
31
|
-
safeDisabled$!: Observable<boolean>;
|
|
32
|
-
|
|
33
|
-
ngOnInit(): void {
|
|
34
|
-
this.safeDisabled$ = this.disabled$.pipe(
|
|
35
|
-
startWith(true),
|
|
36
|
-
delay(0)
|
|
37
|
-
);
|
|
38
|
-
this.openSaveSubscription();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
ngOnDestroy() {
|
|
42
|
-
this.saveSubscription?.unsubscribe();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
formValueChange(formOutput: FormOutput): void {
|
|
46
|
-
const formValue = formOutput as unknown as CheckJobStatusConfig;
|
|
47
|
-
this.formValue$.next(formValue);
|
|
48
|
-
this.handleValid(formValue);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
private handleValid(formValue: CheckJobStatusConfig): void {
|
|
52
|
-
const valid = !!(
|
|
53
|
-
formValue?.requestIdVariable &&
|
|
54
|
-
formValue?.statusVariable
|
|
55
|
-
);
|
|
56
|
-
this.valid$.next(valid);
|
|
57
|
-
this.valid.emit(valid);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private openSaveSubscription(): void {
|
|
61
|
-
this.saveSubscription = this.save$?.subscribe(() => {
|
|
62
|
-
combineLatest([this.formValue$, this.valid$])
|
|
63
|
-
.pipe(take(1))
|
|
64
|
-
.subscribe(([formValue, valid]) => {
|
|
65
|
-
if (valid && formValue) {
|
|
66
|
-
this.configuration.emit(formValue);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
<div class="data-mapping-tree">
|
|
2
|
-
<div class="mapping-header">
|
|
3
|
-
<h5>{{ 'dataMappingTitle' | pluginTranslate: pluginId | async }}</h5>
|
|
4
|
-
<p class="helper-text">{{ 'dataMappingDescription' | pluginTranslate: pluginId | async }}</p>
|
|
5
|
-
</div>
|
|
6
|
-
|
|
7
|
-
<div class="field-tree-root" *ngIf="templateFields.length > 0">
|
|
8
|
-
<epistola-field-tree
|
|
9
|
-
*ngFor="let field of templateFields"
|
|
10
|
-
[field]="field"
|
|
11
|
-
[value]="getFieldValue(field.name)"
|
|
12
|
-
[pluginId]="pluginId"
|
|
13
|
-
[caseDefinitionKey]="caseDefinitionKey"
|
|
14
|
-
[processVariables]="processVariables"
|
|
15
|
-
[disabled]="disabled"
|
|
16
|
-
(valueChange)="onFieldValueChange(field.name, $event)"
|
|
17
|
-
></epistola-field-tree>
|
|
18
|
-
</div>
|
|
19
|
-
|
|
20
|
-
<div class="no-fields" *ngIf="templateFields.length === 0">
|
|
21
|
-
<p>{{ 'noTemplateFields' | pluginTranslate: pluginId | async }}</p>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
.data-mapping-tree {
|
|
2
|
-
margin-top: 1rem;
|
|
3
|
-
margin-bottom: 1rem;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.mapping-header {
|
|
7
|
-
margin-bottom: 0.75rem;
|
|
8
|
-
|
|
9
|
-
h5 {
|
|
10
|
-
margin-bottom: 0.25rem;
|
|
11
|
-
font-weight: 600;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.helper-text {
|
|
15
|
-
color: #6c757d;
|
|
16
|
-
font-size: 0.875rem;
|
|
17
|
-
margin-bottom: 0;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.field-tree-root {
|
|
22
|
-
border: 1px solid #e0e0e0;
|
|
23
|
-
border-radius: 4px;
|
|
24
|
-
padding: 0.5rem 0.75rem;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.no-fields {
|
|
28
|
-
padding: 1rem;
|
|
29
|
-
text-align: center;
|
|
30
|
-
color: #6c757d;
|
|
31
|
-
background-color: #f8f9fa;
|
|
32
|
-
border: 1px solid #dee2e6;
|
|
33
|
-
border-radius: 4px;
|
|
34
|
-
|
|
35
|
-
p {
|
|
36
|
-
margin-bottom: 0;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
|
|
2
|
-
import {CommonModule} from '@angular/common';
|
|
3
|
-
import {PluginTranslatePipeModule} from '@valtimo/plugin';
|
|
4
|
-
import {Observable, Subject} from 'rxjs';
|
|
5
|
-
import {takeUntil} from 'rxjs/operators';
|
|
6
|
-
import {TemplateField} from '../../models';
|
|
7
|
-
import {FieldTreeComponent} from '../field-tree/field-tree.component';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Top-level wrapper that hosts FieldTreeComponent instances for each top-level template field.
|
|
11
|
-
* Manages the full nested mapping object, completeness tracking, and emits mapping changes.
|
|
12
|
-
*/
|
|
13
|
-
@Component({
|
|
14
|
-
selector: 'epistola-data-mapping-tree',
|
|
15
|
-
templateUrl: './data-mapping-tree.component.html',
|
|
16
|
-
styleUrls: ['./data-mapping-tree.component.scss'],
|
|
17
|
-
standalone: true,
|
|
18
|
-
imports: [
|
|
19
|
-
CommonModule,
|
|
20
|
-
PluginTranslatePipeModule,
|
|
21
|
-
FieldTreeComponent
|
|
22
|
-
]
|
|
23
|
-
})
|
|
24
|
-
export class DataMappingTreeComponent implements OnInit, OnDestroy {
|
|
25
|
-
@Input() pluginId!: string;
|
|
26
|
-
@Input() templateFields$!: Observable<TemplateField[]>;
|
|
27
|
-
@Input() prefillMapping$!: Observable<Record<string, any>>;
|
|
28
|
-
@Input() disabled$!: Observable<boolean>;
|
|
29
|
-
@Input() caseDefinitionKey: string | null = null;
|
|
30
|
-
@Input() processVariables: string[] = [];
|
|
31
|
-
|
|
32
|
-
@Output() mappingChange = new EventEmitter<Record<string, any>>();
|
|
33
|
-
@Output() requiredFieldsStatus = new EventEmitter<{mapped: number; total: number}>();
|
|
34
|
-
|
|
35
|
-
templateFields: TemplateField[] = [];
|
|
36
|
-
mapping: Record<string, any> = {};
|
|
37
|
-
disabled = false;
|
|
38
|
-
|
|
39
|
-
private readonly destroy$ = new Subject<void>();
|
|
40
|
-
|
|
41
|
-
ngOnInit(): void {
|
|
42
|
-
this.templateFields$.pipe(
|
|
43
|
-
takeUntil(this.destroy$)
|
|
44
|
-
).subscribe(fields => {
|
|
45
|
-
this.templateFields = fields;
|
|
46
|
-
this.emitRequiredFieldsStatus();
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
this.prefillMapping$.pipe(
|
|
50
|
-
takeUntil(this.destroy$)
|
|
51
|
-
).subscribe(mapping => {
|
|
52
|
-
if (mapping && Object.keys(mapping).length > 0) {
|
|
53
|
-
this.mapping = {...mapping};
|
|
54
|
-
}
|
|
55
|
-
this.emitRequiredFieldsStatus();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
this.disabled$.pipe(
|
|
59
|
-
takeUntil(this.destroy$)
|
|
60
|
-
).subscribe(disabled => {
|
|
61
|
-
this.disabled = disabled;
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
ngOnDestroy(): void {
|
|
66
|
-
this.destroy$.next();
|
|
67
|
-
this.destroy$.complete();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
onFieldValueChange(fieldName: string, value: any): void {
|
|
71
|
-
if (value === undefined || value === null || value === '') {
|
|
72
|
-
const {[fieldName]: _, ...rest} = this.mapping;
|
|
73
|
-
this.mapping = rest;
|
|
74
|
-
} else {
|
|
75
|
-
this.mapping = {...this.mapping, [fieldName]: value};
|
|
76
|
-
}
|
|
77
|
-
this.mappingChange.emit(this.mapping);
|
|
78
|
-
this.emitRequiredFieldsStatus();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
getFieldValue(fieldName: string): any {
|
|
82
|
-
return this.mapping[fieldName];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private emitRequiredFieldsStatus(): void {
|
|
86
|
-
const stats = this.countRequiredMapped(this.templateFields, this.mapping);
|
|
87
|
-
this.requiredFieldsStatus.emit(stats);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
private countRequiredMapped(
|
|
91
|
-
fields: TemplateField[],
|
|
92
|
-
mapping: Record<string, any>
|
|
93
|
-
): {mapped: number; total: number} {
|
|
94
|
-
let mapped = 0;
|
|
95
|
-
let total = 0;
|
|
96
|
-
for (const field of fields) {
|
|
97
|
-
if (field.fieldType === 'SCALAR' && field.required) {
|
|
98
|
-
total++;
|
|
99
|
-
const val = mapping[field.name];
|
|
100
|
-
if (typeof val === 'string' && val.trim().length > 0) {
|
|
101
|
-
mapped++;
|
|
102
|
-
}
|
|
103
|
-
} else if (field.fieldType === 'ARRAY' && field.required) {
|
|
104
|
-
total++;
|
|
105
|
-
const val = mapping[field.name];
|
|
106
|
-
if (typeof val === 'string' && val.trim().length > 0) {
|
|
107
|
-
mapped++;
|
|
108
|
-
} else if (typeof val === 'object' && val !== null && '_source' in val) {
|
|
109
|
-
if (typeof val['_source'] === 'string' && val['_source'].trim().length > 0) {
|
|
110
|
-
mapped++;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
} else if (field.fieldType === 'OBJECT' && field.children) {
|
|
114
|
-
const nested = (typeof mapping[field.name] === 'object' && mapping[field.name] !== null)
|
|
115
|
-
? mapping[field.name]
|
|
116
|
-
: {};
|
|
117
|
-
const childStats = this.countRequiredMapped(field.children, nested);
|
|
118
|
-
mapped += childStats.mapped;
|
|
119
|
-
total += childStats.total;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return {mapped, total};
|
|
123
|
-
}
|
|
124
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<v-form
|
|
2
|
-
(valueChange)="formValueChange($event)"
|
|
3
|
-
*ngIf="{
|
|
4
|
-
disabled: safeDisabled$ | async,
|
|
5
|
-
prefill: prefillConfiguration$ ? (prefillConfiguration$ | async) : null
|
|
6
|
-
} as obs"
|
|
7
|
-
>
|
|
8
|
-
<v-input
|
|
9
|
-
name="documentIdVariable"
|
|
10
|
-
[title]="'documentIdVariable' | pluginTranslate: pluginId | async"
|
|
11
|
-
[tooltip]="'documentIdVariableTooltip' | pluginTranslate: pluginId | async"
|
|
12
|
-
[margin]="true"
|
|
13
|
-
[defaultValue]="obs.prefill?.documentIdVariable || 'epistolaDocumentId'"
|
|
14
|
-
[disabled]="obs.disabled"
|
|
15
|
-
[required]="true"
|
|
16
|
-
>
|
|
17
|
-
</v-input>
|
|
18
|
-
|
|
19
|
-
<v-input
|
|
20
|
-
name="contentVariable"
|
|
21
|
-
[title]="'contentVariable' | pluginTranslate: pluginId | async"
|
|
22
|
-
[tooltip]="'contentVariableTooltip' | pluginTranslate: pluginId | async"
|
|
23
|
-
[margin]="true"
|
|
24
|
-
[defaultValue]="obs.prefill?.contentVariable || 'documentContent'"
|
|
25
|
-
[disabled]="obs.disabled"
|
|
26
|
-
[required]="true"
|
|
27
|
-
>
|
|
28
|
-
</v-input>
|
|
29
|
-
</v-form>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// Download document configuration styles
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
|
|
2
|
-
import {CommonModule} from '@angular/common';
|
|
3
|
-
import {FunctionConfigurationComponent, PluginTranslatePipeModule} from '@valtimo/plugin';
|
|
4
|
-
import {FormModule, FormOutput, InputModule} from '@valtimo/components';
|
|
5
|
-
import {BehaviorSubject, combineLatest, Observable, Subscription, take} from 'rxjs';
|
|
6
|
-
import {delay, startWith} from 'rxjs/operators';
|
|
7
|
-
import {DownloadDocumentConfig} from '../../models';
|
|
8
|
-
|
|
9
|
-
@Component({
|
|
10
|
-
selector: 'epistola-download-document-configuration',
|
|
11
|
-
templateUrl: './download-document-configuration.component.html',
|
|
12
|
-
styleUrls: ['./download-document-configuration.component.scss'],
|
|
13
|
-
standalone: true,
|
|
14
|
-
imports: [CommonModule, PluginTranslatePipeModule, FormModule, InputModule]
|
|
15
|
-
})
|
|
16
|
-
export class DownloadDocumentConfigurationComponent
|
|
17
|
-
implements FunctionConfigurationComponent, OnInit, OnDestroy
|
|
18
|
-
{
|
|
19
|
-
@Input() save$!: Observable<void>;
|
|
20
|
-
@Input() disabled$!: Observable<boolean>;
|
|
21
|
-
@Input() pluginId!: string;
|
|
22
|
-
@Input() prefillConfiguration$!: Observable<DownloadDocumentConfig>;
|
|
23
|
-
|
|
24
|
-
@Output() valid: EventEmitter<boolean> = new EventEmitter<boolean>();
|
|
25
|
-
@Output() configuration: EventEmitter<DownloadDocumentConfig> = new EventEmitter<DownloadDocumentConfig>();
|
|
26
|
-
|
|
27
|
-
private saveSubscription!: Subscription;
|
|
28
|
-
private readonly formValue$ = new BehaviorSubject<DownloadDocumentConfig | null>(null);
|
|
29
|
-
private readonly valid$ = new BehaviorSubject<boolean>(false);
|
|
30
|
-
|
|
31
|
-
safeDisabled$!: Observable<boolean>;
|
|
32
|
-
|
|
33
|
-
ngOnInit(): void {
|
|
34
|
-
this.safeDisabled$ = this.disabled$.pipe(
|
|
35
|
-
startWith(true),
|
|
36
|
-
delay(0)
|
|
37
|
-
);
|
|
38
|
-
this.openSaveSubscription();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
ngOnDestroy() {
|
|
42
|
-
this.saveSubscription?.unsubscribe();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
formValueChange(formOutput: FormOutput): void {
|
|
46
|
-
const formValue = formOutput as unknown as DownloadDocumentConfig;
|
|
47
|
-
this.formValue$.next(formValue);
|
|
48
|
-
this.handleValid(formValue);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
private handleValid(formValue: DownloadDocumentConfig): void {
|
|
52
|
-
const valid = !!(
|
|
53
|
-
formValue?.documentIdVariable &&
|
|
54
|
-
formValue?.contentVariable
|
|
55
|
-
);
|
|
56
|
-
this.valid$.next(valid);
|
|
57
|
-
this.valid.emit(valid);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private openSaveSubscription(): void {
|
|
61
|
-
this.saveSubscription = this.save$?.subscribe(() => {
|
|
62
|
-
combineLatest([this.formValue$, this.valid$])
|
|
63
|
-
.pipe(take(1))
|
|
64
|
-
.subscribe(([formValue, valid]) => {
|
|
65
|
-
if (valid && formValue) {
|
|
66
|
-
this.configuration.emit(formValue);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
<v-form
|
|
2
|
-
(valueChange)="formValueChange($event)"
|
|
3
|
-
*ngIf="{
|
|
4
|
-
disabled: safeDisabled$ | async,
|
|
5
|
-
prefill: prefillConfiguration$ ? (prefillConfiguration$ | async) : null
|
|
6
|
-
} as obs"
|
|
7
|
-
>
|
|
8
|
-
<v-input
|
|
9
|
-
name="configurationTitle"
|
|
10
|
-
[title]="'configurationTitle' | pluginTranslate: pluginId | async"
|
|
11
|
-
[margin]="true"
|
|
12
|
-
[defaultValue]="obs.prefill?.configurationTitle"
|
|
13
|
-
[disabled]="obs.disabled"
|
|
14
|
-
[required]="true"
|
|
15
|
-
>
|
|
16
|
-
</v-input>
|
|
17
|
-
|
|
18
|
-
<v-input
|
|
19
|
-
name="baseUrl"
|
|
20
|
-
[title]="'baseUrl' | pluginTranslate: pluginId | async"
|
|
21
|
-
[tooltip]="'baseUrlTooltip' | pluginTranslate: pluginId | async"
|
|
22
|
-
[margin]="true"
|
|
23
|
-
[defaultValue]="obs.prefill?.baseUrl"
|
|
24
|
-
[disabled]="obs.disabled"
|
|
25
|
-
[required]="true"
|
|
26
|
-
>
|
|
27
|
-
</v-input>
|
|
28
|
-
|
|
29
|
-
<v-input
|
|
30
|
-
name="apiKey"
|
|
31
|
-
[title]="'apiKey' | pluginTranslate: pluginId | async"
|
|
32
|
-
[tooltip]="'apiKeyTooltip' | pluginTranslate: pluginId | async"
|
|
33
|
-
[margin]="true"
|
|
34
|
-
[defaultValue]="obs.prefill?.apiKey"
|
|
35
|
-
[disabled]="obs.disabled"
|
|
36
|
-
[required]="true"
|
|
37
|
-
type="password"
|
|
38
|
-
>
|
|
39
|
-
</v-input>
|
|
40
|
-
|
|
41
|
-
<v-input
|
|
42
|
-
name="tenantId"
|
|
43
|
-
[title]="'tenantId' | pluginTranslate: pluginId | async"
|
|
44
|
-
[tooltip]="'tenantIdTooltip' | pluginTranslate: pluginId | async"
|
|
45
|
-
[margin]="true"
|
|
46
|
-
[defaultValue]="obs.prefill?.tenantId"
|
|
47
|
-
[disabled]="obs.disabled"
|
|
48
|
-
[required]="true"
|
|
49
|
-
>
|
|
50
|
-
</v-input>
|
|
51
|
-
|
|
52
|
-
<v-input
|
|
53
|
-
name="defaultEnvironmentId"
|
|
54
|
-
[title]="'defaultEnvironmentId' | pluginTranslate: pluginId | async"
|
|
55
|
-
[tooltip]="'defaultEnvironmentIdTooltip' | pluginTranslate: pluginId | async"
|
|
56
|
-
[margin]="true"
|
|
57
|
-
[defaultValue]="obs.prefill?.defaultEnvironmentId"
|
|
58
|
-
[disabled]="obs.disabled"
|
|
59
|
-
[required]="false"
|
|
60
|
-
>
|
|
61
|
-
</v-input>
|
|
62
|
-
|
|
63
|
-
<v-input
|
|
64
|
-
name="templateSyncEnabled"
|
|
65
|
-
type="checkbox"
|
|
66
|
-
[title]="'templateSyncEnabled' | pluginTranslate: pluginId | async"
|
|
67
|
-
[tooltip]="'templateSyncEnabledTooltip' | pluginTranslate: pluginId | async"
|
|
68
|
-
[margin]="true"
|
|
69
|
-
[defaultValue]="obs.prefill?.templateSyncEnabled ? 'true' : ''"
|
|
70
|
-
[disabled]="obs.disabled"
|
|
71
|
-
[required]="false"
|
|
72
|
-
>
|
|
73
|
-
</v-input>
|
|
74
|
-
</v-form>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// Epistola plugin configuration styles
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
|
|
2
|
-
import {CommonModule} from '@angular/common';
|
|
3
|
-
import {PluginConfigurationComponent, PluginTranslatePipeModule} from '@valtimo/plugin';
|
|
4
|
-
import {FormModule, FormOutput, InputModule} from '@valtimo/components';
|
|
5
|
-
import {BehaviorSubject, combineLatest, Observable, Subscription, take} from 'rxjs';
|
|
6
|
-
import {delay, startWith} from 'rxjs/operators';
|
|
7
|
-
import {EpistolaPluginConfig} from '../../models';
|
|
8
|
-
|
|
9
|
-
@Component({
|
|
10
|
-
selector: 'epistola-configuration',
|
|
11
|
-
templateUrl: './epistola-configuration.component.html',
|
|
12
|
-
styleUrls: ['./epistola-configuration.component.scss'],
|
|
13
|
-
standalone: true,
|
|
14
|
-
imports: [CommonModule, PluginTranslatePipeModule, FormModule, InputModule]
|
|
15
|
-
})
|
|
16
|
-
export class EpistolaConfigurationComponent
|
|
17
|
-
implements PluginConfigurationComponent, OnInit, OnDestroy
|
|
18
|
-
{
|
|
19
|
-
@Input() save$!: Observable<void>;
|
|
20
|
-
@Input() disabled$!: Observable<boolean>;
|
|
21
|
-
@Input() pluginId!: string;
|
|
22
|
-
@Input() prefillConfiguration$!: Observable<EpistolaPluginConfig>;
|
|
23
|
-
|
|
24
|
-
@Output() valid: EventEmitter<boolean> = new EventEmitter<boolean>();
|
|
25
|
-
@Output() configuration: EventEmitter<EpistolaPluginConfig> = new EventEmitter<EpistolaPluginConfig>();
|
|
26
|
-
|
|
27
|
-
/** Epistola slug pattern: lowercase alphanumeric with hyphens, no leading/trailing hyphens. */
|
|
28
|
-
private static readonly SLUG_PATTERN = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
29
|
-
|
|
30
|
-
private saveSubscription!: Subscription;
|
|
31
|
-
private readonly formValue$ = new BehaviorSubject<EpistolaPluginConfig | null>(null);
|
|
32
|
-
private readonly valid$ = new BehaviorSubject<boolean>(false);
|
|
33
|
-
|
|
34
|
-
safeDisabled$!: Observable<boolean>;
|
|
35
|
-
|
|
36
|
-
ngOnInit(): void {
|
|
37
|
-
// Wrap disabled$ with startWith and delay to prevent NG0100 ExpressionChangedAfterItHasBeenCheckedError
|
|
38
|
-
// The disabled$ observable from Valtimo's plugin framework can emit value changes after Angular's
|
|
39
|
-
// change detection cycle completes, causing the error.
|
|
40
|
-
this.safeDisabled$ = this.disabled$.pipe(
|
|
41
|
-
startWith(true),
|
|
42
|
-
delay(0)
|
|
43
|
-
);
|
|
44
|
-
this.openSaveSubscription();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
ngOnDestroy() {
|
|
48
|
-
this.saveSubscription?.unsubscribe();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
formValueChange(formOutput: FormOutput): void {
|
|
52
|
-
const formValue = formOutput as unknown as EpistolaPluginConfig;
|
|
53
|
-
this.formValue$.next(formValue);
|
|
54
|
-
this.handleValid(formValue);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
private handleValid(formValue: EpistolaPluginConfig): void {
|
|
58
|
-
const valid = !!(
|
|
59
|
-
formValue?.configurationTitle &&
|
|
60
|
-
formValue?.baseUrl &&
|
|
61
|
-
formValue?.apiKey &&
|
|
62
|
-
formValue?.tenantId &&
|
|
63
|
-
this.isValidSlug(formValue.tenantId, 3, 63) &&
|
|
64
|
-
this.isValidOptionalSlug(formValue.defaultEnvironmentId, 3, 30)
|
|
65
|
-
);
|
|
66
|
-
this.valid$.next(valid);
|
|
67
|
-
this.valid.emit(valid);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
private isValidSlug(value: string, minLength: number, maxLength: number): boolean {
|
|
71
|
-
return (
|
|
72
|
-
value.length >= minLength &&
|
|
73
|
-
value.length <= maxLength &&
|
|
74
|
-
EpistolaConfigurationComponent.SLUG_PATTERN.test(value)
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
private isValidOptionalSlug(value: string | undefined, minLength: number, maxLength: number): boolean {
|
|
79
|
-
if (!value) {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
return this.isValidSlug(value, minLength, maxLength);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private openSaveSubscription(): void {
|
|
86
|
-
this.saveSubscription = this.save$?.subscribe(() => {
|
|
87
|
-
combineLatest([this.formValue$, this.valid$])
|
|
88
|
-
.pipe(take(1))
|
|
89
|
-
.subscribe(([formValue, valid]) => {
|
|
90
|
-
if (valid) {
|
|
91
|
-
this.configuration.emit(formValue);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}
|