bpm-core 0.0.131 → 0.0.132

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.
Files changed (64) hide show
  1. package/README.md +13 -8
  2. package/cli/deploy/build.js +62 -0
  3. package/cli/deploy/git-operations-handler.js +104 -0
  4. package/cli/deploy/index.js +61 -0
  5. package/cli/deploy/jenkins-manager.js +107 -0
  6. package/cli/generate/index.js +10 -0
  7. package/cli/generate/mock/form-node.js +77 -0
  8. package/cli/generate/mock/index.js +209 -0
  9. package/cli/generate/mock/lov.js +18 -0
  10. package/cli/generate/new/angular-template/.editorconfig +13 -0
  11. package/cli/generate/new/angular-template/README.md +7 -0
  12. package/cli/generate/new/angular-template/angular.json.ejs +167 -0
  13. package/cli/generate/new/angular-template/build.sh +6 -0
  14. package/cli/generate/new/angular-template/extra-webpack.config.js.ejs +5 -0
  15. package/cli/generate/new/angular-template/karma.conf.js +44 -0
  16. package/cli/generate/new/angular-template/package.json.ejs +66 -0
  17. package/cli/generate/new/angular-template/protractor.conf.js +28 -0
  18. package/cli/generate/new/angular-template/src/app/app.component.html +35 -0
  19. package/cli/generate/new/angular-template/src/app/app.component.scss +0 -0
  20. package/cli/generate/new/angular-template/src/app/app.component.ts +81 -0
  21. package/cli/generate/new/angular-template/src/app/config/segment-dynamic-loader.config.ts.ejs +8 -0
  22. package/cli/generate/new/angular-template/src/app/i18n/ar.ts.ejs +18 -0
  23. package/cli/generate/new/angular-template/src/app/i18n/en.ts.ejs +18 -0
  24. package/cli/generate/new/angular-template/src/app/page-components/@@comp-template@@/@@.component.html.ejs +33 -0
  25. package/cli/generate/new/angular-template/src/app/page-components/@@comp-template@@/@@.component.ts.ejs +128 -0
  26. package/cli/generate/new/angular-template/src/app/page-components/@@comp-template@@/_html-field.ejs +97 -0
  27. package/cli/generate/new/angular-template/src/app/page-components/@@comp-template@@/_html-table.ejs +27 -0
  28. package/cli/generate/new/angular-template/src/app/page-components/@@comp-template@@/_ts-field.ejs +3 -0
  29. package/cli/generate/new/angular-template/src/app/shared/pipes/translate.pipe.ts +32 -0
  30. package/cli/generate/new/angular-template/src/app/shared/services/i18n.service.ts +32 -0
  31. package/cli/generate/new/angular-template/src/app/shared/services/segment-dynamic-loader.service.ts.ejs +49 -0
  32. package/cli/generate/new/angular-template/src/app/shared/services/state-machine.service.ts +119 -0
  33. package/cli/generate/new/angular-template/src/app/shared/types/lov.enum.ts.ejs +7 -0
  34. package/cli/generate/new/angular-template/src/app/templates/print-section/print-section.component.html +5 -0
  35. package/cli/generate/new/angular-template/src/app/templates/print-section/print-section.component.scss +0 -0
  36. package/cli/generate/new/angular-template/src/app/templates/print-section/print-section.component.ts.ejs +156 -0
  37. package/cli/generate/new/angular-template/src/app/templates/print.ts.ejs +392 -0
  38. package/cli/generate/new/angular-template/src/environments/environment.local.ts.ejs +40 -0
  39. package/cli/generate/new/angular-template/src/environments/environment.prod.ts +25 -0
  40. package/cli/generate/new/angular-template/src/environments/environment.ts +25 -0
  41. package/cli/generate/new/angular-template/src/favicon.ico +0 -0
  42. package/cli/generate/new/angular-template/src/index.html.ejs +14 -0
  43. package/cli/generate/new/angular-template/src/main.ts +49 -0
  44. package/cli/generate/new/angular-template/src/polyfills.ts +65 -0
  45. package/cli/generate/new/angular-template/src/styles.scss.ejs +121 -0
  46. package/cli/generate/new/angular-template/src/test.ts +26 -0
  47. package/cli/generate/new/angular-template/tsconfig.app.json +15 -0
  48. package/cli/generate/new/angular-template/tsconfig.json +50 -0
  49. package/cli/generate/new/angular-template/tsconfig.spec.json +18 -0
  50. package/cli/generate/new/angular-template/tslint.json +143 -0
  51. package/cli/generate/new/copy-and-generate.js +120 -0
  52. package/cli/generate/new/field.js +4 -0
  53. package/cli/generate/new/index.js +47 -0
  54. package/cli/generate/new/service-data.js +286 -0
  55. package/cli/index.js +15 -0
  56. package/cli/utilities/current-version.js +4 -0
  57. package/cli/utilities/utilities.js +114 -0
  58. package/fb-schema.json +161 -0
  59. package/fesm2022/bpm-core.mjs +328 -386
  60. package/fesm2022/bpm-core.mjs.map +1 -1
  61. package/lib/components/shared-components/form-field/shared-imports.d.ts +1 -1
  62. package/lib/components/shared-components/form-field/table-list/table-list.component.d.ts +1 -1
  63. package/lib/testComponent/request-details-section/request-details-section.component.d.ts +11 -3
  64. package/package.json +4 -3
@@ -0,0 +1,81 @@
1
+ import {AfterViewInit, Component, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA} from '@angular/core';
2
+ import {
3
+ CoreService,
4
+ Form,
5
+ LayoutComponent,
6
+ ServiceHeaderComponent,
7
+ SidenavService,
8
+ WorkflowSectionComponent,
9
+ CoreI18nService
10
+ } from 'bpm-core';
11
+ import {DynamicComponentInjectorToken} from 'ng-dynamic-component';
12
+ import {RequestDetailsSectionComponent} from "./page-components/request-details-section/request-details-section.component";
13
+ import {SegmentDynamicLoaderService} from './shared/services/segment-dynamic-loader.service';
14
+ import {DOCUMENT, isPlatformBrowser} from "@angular/common";
15
+ import { Inject, PLATFORM_ID} from '@angular/core';
16
+ import {Router} from "@angular/router";
17
+ import {PrintSectionComponent} from "./templates/print-section/print-section.component";
18
+ import {I18nService} from "./shared/services/i18n.service";
19
+ import { TranslatePipe } from './shared/pipes/translate.pipe';
20
+
21
+ @Component({
22
+ selector: 'app-wm-root',
23
+ standalone: true,
24
+ templateUrl: './app.component.html',
25
+ styleUrl: './app.component.scss',
26
+ imports: [
27
+ LayoutComponent,
28
+ ServiceHeaderComponent,
29
+ WorkflowSectionComponent,
30
+ RequestDetailsSectionComponent,
31
+ PrintSectionComponent,
32
+ TranslatePipe
33
+ ],
34
+ schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
35
+ providers: [
36
+ {provide: DynamicComponentInjectorToken, useValue: { /* your value here */}}
37
+ ]
38
+
39
+ })
40
+ export class AppComponent implements AfterViewInit {
41
+ loading = {
42
+ form: false
43
+ }
44
+ form: Form
45
+ noError = true;
46
+ errorMessage: [];
47
+ constructor(
48
+ public segmentDynamicLoader: SegmentDynamicLoaderService,
49
+ @Inject(DOCUMENT) private readonly document: Document,
50
+ private readonly router: Router,
51
+ private readonly sidenavService: SidenavService,
52
+ public i18n: I18nService,
53
+ private readonly coreService: CoreService,
54
+ @Inject(PLATFORM_ID) private readonly platformId: any
55
+ ) {
56
+ this.loading['form'] = true
57
+ this.coreService.loadForm().subscribe({
58
+ next: (form: any) => {
59
+ if (form instanceof Form) {
60
+ this.form = form;
61
+ } else {
62
+ this.noError = false;
63
+ }
64
+ this.loading['form'] = false;
65
+ },
66
+ error: (err) => {
67
+ this.noError = false;
68
+ this.loading['form'] = false;
69
+ this.errorMessage = err?.error?.meta?.messages;
70
+ }
71
+ });
72
+ }
73
+
74
+ ngAfterViewInit() {
75
+ if (isPlatformBrowser(this.platformId)) {
76
+ const direction = this.i18n.getLanguage() == 'en' ? 'ltr' : 'rtl';
77
+ document.documentElement.setAttribute('dir', direction);
78
+ }
79
+ }
80
+
81
+ }
@@ -0,0 +1,8 @@
1
+ <% const config = getSegmentDynamicLoaderConfig() -%>
2
+ <%- config.imports %>
3
+
4
+ export default {
5
+ roleToApprovalSectionMapping: {
6
+ <%- config.roleToCompClass -%>
7
+ }
8
+ }
@@ -0,0 +1,18 @@
1
+ export default {
2
+ "fileName": "اسم الملف",
3
+ "fileDescription": "وصف الملف",
4
+ "comment": "ملاحظات",
5
+ "reset": "إعادة تهيئة",
6
+ "businessPhone": "هاتف العمل",
7
+ "nationality": "الجنسية",
8
+ "generalDepartmentName": "الإدارة العامة",
9
+ "departmentName": "القسم",
10
+ "humanResourcesLocation": "شئون الموظفين",
11
+ "employeeEmail": "البريد الإلكتروني",
12
+ "generalDepartmentCode": "رمز الإدارة العامة",
13
+ "jobPosition": "الوظيفة",
14
+ "fullName": "الإسم",
15
+ "requestDetailsTitle": "تفاصيل الطلب",
16
+ <% const arStr = JSON.stringify(ar); -%>
17
+ <%- arStr.substring(1, arStr.length - 1) %>
18
+ }
@@ -0,0 +1,18 @@
1
+ export default {
2
+ "fileName": "File Name",
3
+ "fileDescription": "File Description",
4
+ "comment":"Comments",
5
+ "reset": "Reset",
6
+ "departmentName": "Department",
7
+ "generalDepartmentName": "General Dep.Name",
8
+ "nationality": "Nationality",
9
+ "businessPhone": "Business Phone",
10
+ "fullName":"Full Name",
11
+ "jobPosition": "Job Position",
12
+ "generalDepartmentCode": "General Dep. Code",
13
+ "employeeEmail": "Email",
14
+ "humanResourcesLocation": "HR location",
15
+ "requestDetailsTitle":"Request Details",
16
+ <% const enStr = JSON.stringify(en); -%>
17
+ <%- enStr.substring(1, enStr.length - 1) %>
18
+ }
@@ -0,0 +1,33 @@
1
+ <div>
2
+ <form
3
+ [ngClass]="{
4
+ 'form-section-divide form-section': !section?.header?.readOnly,
5
+ 'info-section': section?.header?.readOnly
6
+ }"
7
+ [formGroup]="formGroup"
8
+ >
9
+ <% fields.forEach((field) => { -%>
10
+ <% if(field.componentName === 'table'){ %>
11
+ <%- include('_html-table', {field: field}) %>
12
+ <% } else { %>
13
+ <%- include('_html-field', {item: field}) %>
14
+ <% } %>
15
+ <% }); -%>
16
+ </form>
17
+ </div>
18
+
19
+ @if (!section?.header?.readOnly) {
20
+ <div class="mt-4">
21
+ <lib-action-buttons
22
+ [lovOptions]="lov?.['decision']?.options"
23
+ [lovType]="lov?.['decision']?.type"
24
+ [section]="section"
25
+ [form]="form"
26
+ [sections]="form.sections"
27
+ [showApprovalCycle]="true"
28
+ [customCall]="false"
29
+ [fieldsForm]="formGroup"
30
+ (resetFormEmit)="resetForm()"
31
+ />
32
+ </div>
33
+ }
@@ -0,0 +1,128 @@
1
+
2
+ <% importsManager.addImport(['Component', 'inject', 'Input', 'OnInit', 'CUSTOM_ELEMENTS_SCHEMA'], '@angular/core') -%>
3
+ <% importsManager.addImport(['FormControl', 'FormBuilder', 'Validators'], '@angular/forms') -%>
4
+ <% importsManager.addImport('ReactiveFormsModule', '@angular/forms', true) -%>
5
+ <% importsManager.addImport(['Section', 'Form', 'ActionStateService'], 'bpm-core') -%>
6
+ <% importsManager.addImport('ActionButtonsComponent', 'bpm-core', true) -%>
7
+ <% importsManager.addImport('TranslatePipe', 'src/app/shared/pipes/translate.pipe', true) -%>
8
+ <% importsManager.addImport('NgClass', '@angular/common', true) -%>
9
+
10
+ <% for(const field of fields){ -%>
11
+ <% if(field.componentName === 'table'){ -%>
12
+ interface <%= changeCase.pascalCase(field.arrayName + 'Item') %> {
13
+ <% for(const col of field.tableColumns){ -%>
14
+ <%= col.fieldName %>: <%= getFieldType(col) %>;
15
+ <% } -%>
16
+ }
17
+ <% } -%>
18
+ <% } -%>
19
+
20
+ @Component({
21
+ selector: 'app-<%= componentNameKebab %>',
22
+ templateUrl: './<%= componentNameKebab %>.component.html',
23
+ standalone: true,
24
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
25
+ imports: []
26
+ })
27
+ export class <%= componentNamePascal %>Component implements OnInit {
28
+ @Input() isReadOnly: boolean;
29
+ @Input() section: Section;
30
+ @Input() form: Form;
31
+ @Input() lov: any;
32
+ formGroup: ReturnType<typeof this.createForm>;
33
+ private fb = inject(FormBuilder);
34
+ private actionStateService = inject(ActionStateService);
35
+
36
+ ngOnInit(){
37
+ this.formGroup = this.createForm();
38
+ this.setFormValuesUsingSectionDetails();
39
+ if(!this.isReadOnly){
40
+ this.subscribeFormChanges();
41
+ this.formGroup.updateValueAndValidity();
42
+ }
43
+ }
44
+
45
+ createForm() {
46
+ return this.fb.group({
47
+ <% for(const field of fields){ -%>
48
+ <% if(field.componentName === 'table'){ -%>
49
+ <%=field.arrayName%>: this.fb.array<ReturnType<typeof this.<%= changeCase.camelCase(`new ${field.arrayName} Item`) %>>>([]),
50
+ <% } else { -%>
51
+ <%- include('_ts-field', {field: field, defaultValue: undefined}) -%>
52
+ <% } -%>
53
+ <% } -%>
54
+ });
55
+ }
56
+
57
+ resetForm() {
58
+ this.actionStateService.resetAction$.next();
59
+ }
60
+
61
+ <% for(const field of fields){ -%>
62
+ <% if(field.visibilityCheckCode){ -%>
63
+ get <%= changeCase.camelCase(`is ${field.fieldName || field.headerName} visible`) %>(): boolean {
64
+ return <%-field.visibilityCheckCode%>;
65
+ }
66
+ <% } -%>
67
+ <% } -%>
68
+
69
+ private subscribeFormChanges() {
70
+ this.formGroup.valueChanges.subscribe((value) => {
71
+ this.section.body.details = {
72
+ ...this.section.body.details,
73
+ ...this.formGroup.value,
74
+ };
75
+ <% if(fields.some(item => item.visibilityCheckCode)){ importsManager.addImport('updateValueAndValidity', 'bpm-core')-%>
76
+ updateValueAndValidity(this.formGroup);
77
+ <% } -%>
78
+ this.lov?.["decision"]?.options?.forEach((option) => {
79
+ let isActionValid = this.checkValidity(option.value);
80
+ this.actionStateService.setActionValid(option.value, isActionValid);
81
+ });
82
+ });
83
+ }
84
+
85
+ private checkValidity(action: string): boolean {
86
+ <% if(fields.some(item => item.fieldName === 'comment')){ -%>
87
+ switch (action) {
88
+ case "SENDBACK":
89
+ case "REJECT":
90
+ return !!this.formGroup.value?.comment;
91
+ default:
92
+ return this.formGroup.valid;
93
+ }
94
+ <% } else { -%>
95
+ return this.formGroup.valid;
96
+ <% } -%>
97
+ }
98
+
99
+ private setFormValuesUsingSectionDetails(){
100
+ this.formGroup.patchValue(this.section.body.details);
101
+ <% for(const field of fields){ -%>
102
+ <% if(field.componentName === 'table'){ -%>
103
+ <% const tableArrConstName = changeCase.camelCase(field.arrayName); -%>
104
+ <% const typeName = changeCase.pascalCase(field.arrayName + 'Item'); -%>
105
+ <% const addNewItemMethodName = changeCase.camelCase(`new ${field.arrayName} Item`); -%>
106
+ const <%= tableArrConstName %>: <%=typeName%>[] = this.section.body.details?.<%= field.arrayName %>;
107
+ if(<%= tableArrConstName %>?.length){
108
+ <%= tableArrConstName %>.forEach(item => {
109
+ this.formGroup.controls.<%= field.arrayName %>.push(this.<%=addNewItemMethodName%>(item))
110
+ })
111
+ }
112
+ <% } -%>
113
+ <% } -%>
114
+ }
115
+
116
+ <% for(const field of fields){ -%>
117
+ <% if(field.componentName === 'table'){ -%>
118
+ private <%= changeCase.camelCase(`new ${field.arrayName} Item`) %>(item?: <%= changeCase.pascalCase(field.arrayName + 'Item') %>) {
119
+ return this.fb.group({
120
+ <% for(const col of field.tableColumns){ -%>
121
+ <%- include('_ts-field', {field: col, defaultValue: `item?.${col.fieldName}`}) -%>
122
+ <% } -%>
123
+ });
124
+ }
125
+ <% } -%>
126
+ <% } -%>
127
+
128
+ }
@@ -0,0 +1,97 @@
1
+ <% if (item.visibilityCheckCode) { -%>
2
+ <% importsManager.addImport(getEnumName(item), '../../shared/types/lov.enum') -%>
3
+ @if(<%= changeCase.camelCase(`is ${item.fieldName || item.headerName} visible`) %>){
4
+ <% } -%>
5
+ <% switch(item.componentName){
6
+ case 'input': -%>
7
+ <app-input
8
+ <%- getCommonAttributes(item) -%>
9
+ <% if(item.maxLength){ -%>
10
+ maxLength="<%=item.maxLength%>"
11
+ <% } -%>
12
+ >
13
+ </app-input>
14
+ <% break; case 'textarea': -%>
15
+ <app-textarea
16
+ <%- getCommonAttributes(item) -%>
17
+ <% if(item.maxLength){ -%>
18
+ maxLength="<%=item.maxLength%>"
19
+ <% } -%>
20
+ >
21
+ </app-textarea>
22
+ <% break; case 'input-number': -%>
23
+ <app-input-number
24
+ <%- getCommonAttributes(item) -%>
25
+ >
26
+ </app-input-number>
27
+ <% break; case 'input-currency': -%>
28
+ <app-input-currency
29
+ <%- getCommonAttributes(item) -%>
30
+ >
31
+ </app-input-currency>
32
+ <% break; case 'select': -%>
33
+ <app-custom-searchable
34
+ <%- getCommonAttributes(item) -%>
35
+ [options]="lov?.<%=item.lovName%>?.options"
36
+ [key]="'value'"
37
+ [displayedLabel]="'description'"
38
+ >
39
+ </app-custom-searchable>
40
+ <% break; case 'attachment-section': -%>
41
+ <app-attachment-section
42
+ class="section-item full"
43
+ formControlName="<%=item.fieldName%>"
44
+ <% if(item.label){ %>
45
+ [label]="'<%=changeCase.camelCase(item.label)%>' | translate"
46
+ <% } %>
47
+ [mandatory]="<%=item.required%>"
48
+ [isReadOnly]="<%=item.readOnly ? 'true' : 'section?.header?.readOnly'%>"
49
+ >
50
+ </app-attachment-section>
51
+ <% break; case 'file-uploader': -%>
52
+ <app-file-uploader
53
+ <%- getCommonAttributes(item) -%>
54
+ <% if(item.maxLength){ -%>
55
+ [maxLength]="<%=item.maxLength%>"
56
+ <% } -%>
57
+ <% if(item.multiple){ -%>
58
+ [multiple]="true"
59
+ [displayedFiles]="formGroup.value?.<%=item.fieldName%>"
60
+ <% } -%>
61
+ >
62
+ </app-file-uploader>
63
+ <% break; case 'datepicker': -%>
64
+ <app-datepicker
65
+ <%- getCommonAttributes(item) -%>
66
+ <% if(item.minDate){ -%>
67
+ minDate="<%=item.minDate%>"
68
+ <% } -%>
69
+ <% if(item.maxDate){ -%>
70
+ maxDate="<%=item.maxDate%>"
71
+ <% } -%>
72
+ <% if(item.customMinDate){ -%>
73
+ customMinDate="<%=item.customMinDate%>"
74
+ <% } -%>
75
+ <% if(item.customMaxDate){ -%>
76
+ customMaxDate="<%=item.customMaxDate%>"
77
+ <% } -%>
78
+ >
79
+ </app-datepicker>
80
+ <% break; case 'panel-start': -%>
81
+ <div class="header-line full fs-12 fw-medium mb-2">
82
+ {{ "<%=changeCase.camelCase(item.headerName)%>" | translate }}
83
+ </div>
84
+ <% break; case 'hint': -%>
85
+ <ds-alert class="mb-3 full" type="<%=item.type%>" icon="<%=item.type === 'danger' ? 'close-circle' : 'info'%>">
86
+ {{'<%=changeCase.camelCase(item.headerName)%>' | translate}}
87
+ </ds-alert>
88
+ <% break; case 'search-employee': -%>
89
+ <app-search-employee
90
+ <%- getCommonAttributes(item) -%>
91
+ >
92
+ </app-search-employee>
93
+ <% break; -%>
94
+ <% } -%>
95
+ <% if (item.visibilityCheckCode) { -%>
96
+ }
97
+ <% } %>
@@ -0,0 +1,27 @@
1
+ <div class="section-item full mt-2">
2
+ <% if(field.label){ -%>
3
+ <div class="header-line full fs-12 fw-medium mb-1">{{ "<%=changeCase.camelCase(field.label)%>" | translate }}</div>
4
+ <% } -%>
5
+ <div class="gray-table-wrapper">
6
+ <table>
7
+ <thead>
8
+ <tr>
9
+ <% field.tableColumns.forEach((column) => { -%>
10
+ <th>{{'<%=changeCase.camelCase(column.label)%>' | translate}}</th>
11
+ <% }); -%>
12
+ </tr>
13
+ </thead>
14
+ <tbody formArrayName="<%=field.arrayName%>">
15
+ @for (item of section.body.details.<%=field.arrayName%>; track $index) {
16
+ <tr [formGroupName]="$index">
17
+ <% field.tableColumns.forEach((column) => { -%>
18
+ <td>
19
+ <%- include('_html-field', {item: column}) %>
20
+ </td>
21
+ <% }); -%>
22
+ </tr>
23
+ }
24
+ </tbody>
25
+ </table>
26
+ </div>
27
+ </div>
@@ -0,0 +1,3 @@
1
+ <% if(field.fieldName){ -%>
2
+ <%= field.fieldName %>: new FormControl<<%- getFieldType(field) %>>(<%- defaultValue || 'null' %><% if(field.required){ -%>, <%- getValidators(field) %><% } %>),
3
+ <% } -%>
@@ -0,0 +1,32 @@
1
+ import { Pipe, PipeTransform } from '@angular/core';
2
+ import * as en from '../../../app/i18n/en';
3
+ import * as ar from '../../../app/i18n/ar';
4
+
5
+ @Pipe({
6
+ name: 'translate',
7
+ standalone:true
8
+ })
9
+ export class TranslatePipe implements PipeTransform {
10
+ private coreLocales: { [key: string]: { [key: string]: string } };
11
+ public language: string;
12
+
13
+ constructor() {
14
+ // this.language = "en";
15
+ this.language = (window as any).wmConfig.language;
16
+ this.coreLocales = { en: en.default, ar: ar.default };
17
+ }
18
+
19
+ transform(key) {
20
+ let result = null;
21
+ try {
22
+ result = this.coreLocales[this.language][key];
23
+ } catch (e) {
24
+ result = null;
25
+ }
26
+ return result || key;
27
+ }
28
+
29
+ getLanguage() {
30
+ return this.language;
31
+ }
32
+ }
@@ -0,0 +1,32 @@
1
+ import { Injectable } from '@angular/core';
2
+ import * as en from '../../../app/i18n/en';
3
+ import * as ar from '../../../app/i18n/ar';
4
+
5
+ @Injectable({
6
+ providedIn: 'any',
7
+ })
8
+ export class I18nService {
9
+ private readonly locales: {[key: string]: {[key: string]: string}};
10
+ private readonly language : string;
11
+
12
+ constructor() {
13
+ this.language = (window as any).wmConfig.language;
14
+ // this.language = "en";
15
+ this.locales = {en: en.default, ar: ar.default};
16
+ }
17
+
18
+ translate(key) {
19
+ let result = null;
20
+ try {
21
+ result = this.locales[this.language][key];
22
+ }
23
+ catch(e) {
24
+ result = null;
25
+ }
26
+ return result || key;
27
+ }
28
+
29
+ getLanguage() {
30
+ return this.language;
31
+ }
32
+ }
@@ -0,0 +1,49 @@
1
+ import { Injectable } from '@angular/core';
2
+ import {RequestDetailsSectionComponent} from '../../page-components/request-details-section/request-details-section.component';
3
+ import segmentDynamicLoaderConfiguration from '../../config/segment-dynamic-loader.config';
4
+ import * as Constants from 'bpm-core';
5
+ import { I18nService } from './i18n.service';
6
+
7
+ @Injectable({
8
+ providedIn: 'any'
9
+ })
10
+ export class SegmentDynamicLoaderService {
11
+ requestDetailsSection = RequestDetailsSectionComponent;
12
+ roleToApprovalSectionMapping = segmentDynamicLoaderConfiguration.roleToApprovalSectionMapping;
13
+
14
+ constructor(private i18n: I18nService) {
15
+
16
+ }
17
+
18
+ getComponent(componentId: string) {
19
+ if (componentId.toLowerCase() === Constants.SECTION_ID_REQUEST_DETAILS.toLowerCase()) {
20
+ return this.requestDetailsSection;
21
+ }
22
+ let role = componentId.toLowerCase().split(Constants.SECTION_ID_APPROVAL_PARTIAL_NAME.toLowerCase())[0].toLowerCase();
23
+ return this.roleToApprovalSectionMapping[role];
24
+ }
25
+
26
+ getSectionName(componentId: string): string {
27
+ if(componentId.toLowerCase() === Constants.SECTION_ID_REQUEST_DETAILS.toLowerCase()) {
28
+ return this.i18n.translate('requestDetailsTitle');
29
+ }
30
+ else if(componentId.toLowerCase() === 'hrRequestDetails'.toLowerCase()) {
31
+ return this.i18n.translate('hrRequestDetailsTitle');
32
+ }
33
+ let role = componentId.toLowerCase().split(Constants.SECTION_ID_APPROVAL_PARTIAL_NAME.toLowerCase())[0].toLowerCase();
34
+ return this.i18n.translate(`${role.toLowerCase()}Role`);
35
+ }
36
+
37
+ getPrintPartialName (componentName: string) {
38
+ if (componentName === Constants.SECTION_ID_REQUEST_DETAILS) {
39
+ return 'sectionRequestDetails';
40
+ }
41
+ <% getRoleStages().forEach(stageInfo => { -%>
42
+ else if (componentName === "<%= stageInfo.role.toLowerCase()%>Approval") {
43
+ return "<%=stageInfo.printPartialName%>";
44
+ }
45
+ <% }); -%>
46
+ else { return 'sectionGeneralApproval' }
47
+
48
+ }
49
+ }
@@ -0,0 +1,119 @@
1
+ import {Injectable} from '@angular/core';
2
+ import {HttpClient} from '@angular/common/http';
3
+ import * as constants from "bpm-core";
4
+ import {CoreService, Messages} from "bpm-core";
5
+ import {environment} from "../../../environments/environment";
6
+
7
+ @Injectable({
8
+ providedIn: 'any',
9
+ })
10
+ export class StateMachineService {
11
+ private readonly transitions: { [key: string]: { [key: string]: Function } };
12
+ private state: string;
13
+
14
+ constructor(private http: HttpClient, private coreStateMachineService: CoreService) {
15
+ this.state = constants.STATE_MACHINE_STATUS_IDLE;
16
+ this.transitions = {
17
+ idle: {
18
+ generalApi: function (serviceName: string, ...args) {
19
+ let body = {
20
+ method: constants.HTTP_METHOD_GET, //GET - PUT - POST
21
+ destination: constants.TARGET_SERVER_WM,
22
+ serviceName: serviceName, //,
23
+ formName: environment.formName,
24
+ queryParameters: {
25
+
26
+ }
27
+ }
28
+ let options = this.coreStateMachineService.getRequestOptions();
29
+ let succ = 'serviceResponce';
30
+ return this.callPost(body, succ, options);
31
+ }
32
+ },
33
+ fetching: {
34
+ serviceResponce: function (...args: any) {
35
+ let [payload] = args;
36
+ let result = payload;
37
+ this.state = constants.STATE_MACHINE_STATUS_IDLE;
38
+ return result;
39
+ },
40
+ failure: function (...args) {
41
+ let [errors] = args;
42
+ this.state = constants.STATE_MACHINE_STATUS_ERROR;
43
+ return this.dispatch(constants.STATE_MACHINE_ACTION_HANDLE_ERROR, errors);
44
+ }
45
+ },
46
+ error: {
47
+ handleError: function (...args) {
48
+ let [errors] = args;
49
+ let result = new Messages(
50
+ {},
51
+ [],
52
+ [],
53
+ []
54
+ );
55
+ if (errors?.meta?.messages) {
56
+ errors.meta.messages.forEach((message) => {
57
+ result[message.type].push(message.message);
58
+ if (message.payloadReference) {
59
+ let payloadReferenceTokens = message.payloadReference.split('/');
60
+ payloadReferenceTokens.slice(1, payloadReferenceTokens.length - 1);
61
+ let element = result.errorFields;
62
+ payloadReferenceTokens.forEach((token) => {
63
+ element[token] = {};
64
+ element = element[token];
65
+ })
66
+ element = true;
67
+ }
68
+ });
69
+ } else if (errors?.errors) {
70
+ errors.errors.forEach((message) => {
71
+ result['error'].push(message.message);
72
+ });
73
+ }
74
+ this.state = constants.STATE_MACHINE_STATUS_IDLE;
75
+ return result;
76
+ }
77
+ },
78
+ sending: {
79
+ failure: function (...args) {
80
+ let [errors] = args;
81
+ this.state = constants.STATE_MACHINE_STATUS_ERROR;
82
+ return this.dispatch(constants.STATE_MACHINE_ACTION_HANDLE_ERROR, errors);
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ public dispatch(actionName, ...args) {
89
+ const actions = this.transitions[this.state];
90
+ const action = actions[actionName];
91
+
92
+ if (action) {
93
+ return action.apply(this, args);
94
+ }
95
+ }
96
+
97
+ public callPost(body, succ, options) {
98
+ let apiUrl = environment.proxyServiceBaseUrl + (window as any).wmConfig.language + environment.proxyFullAddress + environment.proxyServiceExecute;
99
+ return this.http.post(apiUrl, encodeURIComponent(JSON.stringify(body)), options).toPromise()
100
+ .then(
101
+ (responseObject: any) => {
102
+ let payload = responseObject;
103
+ this.state = constants.STATE_MACHINE_STATUS_FETCHING;
104
+ return this.dispatch(succ, payload);
105
+ },
106
+ ).catch(
107
+ (httpError: any) => {
108
+ let responseError = httpError.error;
109
+ if (responseError) {
110
+ this.state = constants.STATE_MACHINE_STATUS_FETCHING;
111
+ return this.dispatch(constants.STATE_MACHINE_ACTION_FAILURE, responseError);
112
+ } else {
113
+ this.state = constants.STATE_MACHINE_STATUS_IDLE;
114
+ throw httpError;
115
+ }
116
+ }
117
+ );
118
+ }
119
+ }
@@ -0,0 +1,7 @@
1
+ <% if(visibilityCodeLOVEnums) { -%>
2
+ <% Object.entries(visibilityCodeLOVEnums).forEach(([enumName, enumKeys]) => { %>
3
+ export enum <%= enumName %> {
4
+ <%- [...enumKeys].join(',\n') %>
5
+ }
6
+ <% }); %>
7
+ <% } -%>
@@ -0,0 +1,5 @@
1
+ <ds-button
2
+ square icon size="small"
3
+ (click)="print()" class="has-comments">
4
+ <ds-icon icon="print" class="fc-coral fs-20 fs-md-17"></ds-icon>
5
+ </ds-button>