ngx-histaff-alpha 6.6.2 → 6.6.4

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 (60) hide show
  1. package/fesm2022/{ngx-histaff-alpha-ai-hint-for-table.component-DbeU8RbE.mjs → ngx-histaff-alpha-ai-hint-for-table.component-JXH8uW2J.mjs} +2 -2
  2. package/fesm2022/{ngx-histaff-alpha-ai-hint-for-table.component-DbeU8RbE.mjs.map → ngx-histaff-alpha-ai-hint-for-table.component-JXH8uW2J.mjs.map} +1 -1
  3. package/fesm2022/{ngx-histaff-alpha-core-form-design.component-Q7Mkj3Sw.mjs → ngx-histaff-alpha-core-form-design.component-Cy_mOM1n.mjs} +4 -4
  4. package/fesm2022/{ngx-histaff-alpha-core-form-design.component-Q7Mkj3Sw.mjs.map → ngx-histaff-alpha-core-form-design.component-Cy_mOM1n.mjs.map} +1 -1
  5. package/fesm2022/{ngx-histaff-alpha-core-sys-action.component-sdc_nA__.mjs → ngx-histaff-alpha-core-sys-action.component-DSjGTh1K.mjs} +2 -2
  6. package/fesm2022/{ngx-histaff-alpha-core-sys-action.component-sdc_nA__.mjs.map → ngx-histaff-alpha-core-sys-action.component-DSjGTh1K.mjs.map} +1 -1
  7. package/fesm2022/{ngx-histaff-alpha-core-template-editor.component-KuEdnw6J.mjs → ngx-histaff-alpha-core-template-editor.component-D1XlpSNr.mjs} +2 -2
  8. package/fesm2022/{ngx-histaff-alpha-core-template-editor.component-KuEdnw6J.mjs.map → ngx-histaff-alpha-core-template-editor.component-D1XlpSNr.mjs.map} +1 -1
  9. package/fesm2022/{ngx-histaff-alpha-core-toast-loading.component-CQpoTAyX.mjs → ngx-histaff-alpha-core-toast-loading.component-ClmryTzj.mjs} +2 -2
  10. package/fesm2022/{ngx-histaff-alpha-core-toast-loading.component-CQpoTAyX.mjs.map → ngx-histaff-alpha-core-toast-loading.component-ClmryTzj.mjs.map} +1 -1
  11. package/fesm2022/{ngx-histaff-alpha-core-workflow-consume.component-BX_Z-pZt.mjs → ngx-histaff-alpha-core-workflow-consume.component-DV84nxOo.mjs} +2 -2
  12. package/fesm2022/{ngx-histaff-alpha-core-workflow-consume.component-BX_Z-pZt.mjs.map → ngx-histaff-alpha-core-workflow-consume.component-DV84nxOo.mjs.map} +1 -1
  13. package/fesm2022/{ngx-histaff-alpha-db-settings.component-DET37h-d.mjs → ngx-histaff-alpha-db-settings.component-AwS6B8Ne.mjs} +5 -5
  14. package/fesm2022/{ngx-histaff-alpha-db-settings.component-DET37h-d.mjs.map → ngx-histaff-alpha-db-settings.component-AwS6B8Ne.mjs.map} +1 -1
  15. package/fesm2022/{ngx-histaff-alpha-design-wrapper.component-Duk6i0JF.mjs → ngx-histaff-alpha-design-wrapper.component-C_EM0bEs.mjs} +324 -446
  16. package/fesm2022/ngx-histaff-alpha-design-wrapper.component-C_EM0bEs.mjs.map +1 -0
  17. package/fesm2022/{ngx-histaff-alpha-design-wrapper.route-C6VCPmmi.mjs → ngx-histaff-alpha-design-wrapper.route-DIZLQKWJ.mjs} +5 -5
  18. package/fesm2022/{ngx-histaff-alpha-design-wrapper.route-C6VCPmmi.mjs.map → ngx-histaff-alpha-design-wrapper.route-DIZLQKWJ.mjs.map} +1 -1
  19. package/fesm2022/{ngx-histaff-alpha-hrm-schema.component-CkXimjGa.mjs → ngx-histaff-alpha-hrm-schema.component-DPqZBYnx.mjs} +2 -2
  20. package/fesm2022/{ngx-histaff-alpha-hrm-schema.component-CkXimjGa.mjs.map → ngx-histaff-alpha-hrm-schema.component-DPqZBYnx.mjs.map} +1 -1
  21. package/fesm2022/{ngx-histaff-alpha-live-form.component-C-d4utoe.mjs → ngx-histaff-alpha-live-form.component-CatM7zte.mjs} +2 -2
  22. package/fesm2022/{ngx-histaff-alpha-live-form.component-C-d4utoe.mjs.map → ngx-histaff-alpha-live-form.component-CatM7zte.mjs.map} +1 -1
  23. package/fesm2022/{ngx-histaff-alpha-ngx-histaff-alpha-q6N_damo.mjs → ngx-histaff-alpha-ngx-histaff-alpha-BZdzGBj5.mjs} +536 -30
  24. package/fesm2022/ngx-histaff-alpha-ngx-histaff-alpha-BZdzGBj5.mjs.map +1 -0
  25. package/fesm2022/{ngx-histaff-alpha-simple-chat.component-oUfod5Lj.mjs → ngx-histaff-alpha-simple-chat.component-CQvQzfwA.mjs} +2 -2
  26. package/fesm2022/{ngx-histaff-alpha-simple-chat.component-oUfod5Lj.mjs.map → ngx-histaff-alpha-simple-chat.component-CQvQzfwA.mjs.map} +1 -1
  27. package/fesm2022/{ngx-histaff-alpha-sys-smtp-client-edit.component-Ry4FeUPi.mjs → ngx-histaff-alpha-sys-smtp-client-edit.component-DQyeSL3y.mjs} +2 -2
  28. package/fesm2022/{ngx-histaff-alpha-sys-smtp-client-edit.component-Ry4FeUPi.mjs.map → ngx-histaff-alpha-sys-smtp-client-edit.component-DQyeSL3y.mjs.map} +1 -1
  29. package/fesm2022/{ngx-histaff-alpha-sys-smtp-client.component-B7BhlGDm.mjs → ngx-histaff-alpha-sys-smtp-client.component-5f4Hm6sZ.mjs} +2 -2
  30. package/fesm2022/{ngx-histaff-alpha-sys-smtp-client.component-B7BhlGDm.mjs.map → ngx-histaff-alpha-sys-smtp-client.component-5f4Hm6sZ.mjs.map} +1 -1
  31. package/fesm2022/{ngx-histaff-alpha-template-list.component-wXg-VmYD.mjs → ngx-histaff-alpha-template-list.component-Hxk1mvGh.mjs} +2 -2
  32. package/fesm2022/{ngx-histaff-alpha-template-list.component-wXg-VmYD.mjs.map → ngx-histaff-alpha-template-list.component-Hxk1mvGh.mjs.map} +1 -1
  33. package/fesm2022/{ngx-histaff-alpha-tracker-studio.component-BanWB1v7.mjs → ngx-histaff-alpha-tracker-studio.component-Dhp9w826.mjs} +2 -2
  34. package/fesm2022/{ngx-histaff-alpha-tracker-studio.component-BanWB1v7.mjs.map → ngx-histaff-alpha-tracker-studio.component-Dhp9w826.mjs.map} +1 -1
  35. package/fesm2022/{ngx-histaff-alpha-wf-form-assign.component-BXbhksfX.mjs → ngx-histaff-alpha-wf-form-assign.component-ClY5trbS.mjs} +2 -2
  36. package/fesm2022/{ngx-histaff-alpha-wf-form-assign.component-BXbhksfX.mjs.map → ngx-histaff-alpha-wf-form-assign.component-ClY5trbS.mjs.map} +1 -1
  37. package/fesm2022/{ngx-histaff-alpha-wf-global-config.component-DtSoCMp9.mjs → ngx-histaff-alpha-wf-global-config.component-Cr5x7Ejg.mjs} +2 -2
  38. package/fesm2022/{ngx-histaff-alpha-wf-global-config.component-DtSoCMp9.mjs.map → ngx-histaff-alpha-wf-global-config.component-Cr5x7Ejg.mjs.map} +1 -1
  39. package/fesm2022/{ngx-histaff-alpha-wf-instance-status.component-BgR1sAaE.mjs → ngx-histaff-alpha-wf-instance-status.component-BIvdd1YN.mjs} +2 -2
  40. package/fesm2022/{ngx-histaff-alpha-wf-instance-status.component-BgR1sAaE.mjs.map → ngx-histaff-alpha-wf-instance-status.component-BIvdd1YN.mjs.map} +1 -1
  41. package/fesm2022/{ngx-histaff-alpha-wf-instance-step-react.component-xdLSFaSv.mjs → ngx-histaff-alpha-wf-instance-step-react.component-1yYa-SfK.mjs} +3 -3
  42. package/fesm2022/{ngx-histaff-alpha-wf-instance-step-react.component-xdLSFaSv.mjs.map → ngx-histaff-alpha-wf-instance-step-react.component-1yYa-SfK.mjs.map} +1 -1
  43. package/fesm2022/{ngx-histaff-alpha-wf-lab.component-BZAQ2s5T.mjs → ngx-histaff-alpha-wf-lab.component-mbJjrJ6v.mjs} +2 -2
  44. package/fesm2022/{ngx-histaff-alpha-wf-lab.component-BZAQ2s5T.mjs.map → ngx-histaff-alpha-wf-lab.component-mbJjrJ6v.mjs.map} +1 -1
  45. package/fesm2022/ngx-histaff-alpha.mjs +1 -1
  46. package/lib/app/enum/EnumFormBaseContolType.d.ts +2 -1
  47. package/lib/app/libraries/core-form-design/core-form-design.component.d.ts +1 -1
  48. package/lib/app/libraries/core-form-design/core-form-group-editor.component.d.ts +1 -1
  49. package/lib/app/libraries/core-rule-set/core-rule-set.component.d.ts +16 -0
  50. package/lib/app/libraries/core-rule-tree/core-rule-tree.component.d.ts +6 -6
  51. package/lib/app/libraries/core-rule-tree/core-rule-tree.service.d.ts +2 -0
  52. package/lib/app/libraries/core-workflow-builder/core-workflow.service.d.ts +5 -0
  53. package/lib/app/libraries/core-workflow-builder/interfaces/IUiDelegation.d.ts +14 -0
  54. package/lib/app/libraries/core-workflow-builder/interfaces/IWfWorkflow.d.ts +3 -0
  55. package/lib/app/libraries/core-workflow-builder/wf-delegation/wf-delegation.component.d.ts +45 -0
  56. package/lib/app/libraries/core-workflow-builder/wf-process-design/current-header/current-header.component.d.ts +2 -0
  57. package/lib/app/libraries/services/core-datetime.service.d.ts +2 -0
  58. package/package.json +2 -2
  59. package/fesm2022/ngx-histaff-alpha-design-wrapper.component-Duk6i0JF.mjs.map +0 -1
  60. package/fesm2022/ngx-histaff-alpha-ngx-histaff-alpha-q6N_damo.mjs.map +0 -1
@@ -1,18 +1,18 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ChangeDetectionStrategy, Component, Injector, runInInjectionContext, effect, Input, EventEmitter, ElementRef, ViewChild, Output, Renderer2, input, isDevMode, signal, computed, Injectable, output, viewChild, ChangeDetectorRef, Directive, Pipe, ViewChildren } from '@angular/core';
3
- import { B as BaseComponent, n as CoreWorkflowService, y as CoreFormDesignService, b as AlertService, z as EnumWorkflowStepType, w as alertOptions, E as EnumFormBaseContolType, M as MultiLanguageService, T as TooltipDirective, e as TranslatePipe, h as BaseEditComponent, i as DialogService, A as AppService, j as CorePageEditComponent, F as FullscreenModalLoaderComponent, G as DomService, H as CoreDropdownComponent, J as CoreChecklistComponent, K as CoreDatePickerComponent, L as CoreFormControlSeekerComponent, N as CoreCurrencyInputComponent, o as EnumCoreFormControlSeekerSourceType, O as EnumActorSourceType, P as CoreParamControlComponent, Q as CoreRadioGroupComponent, R as GptService, U as CoreStickerCollectionComponent, V as ApplicationHelpService, W as HotKeysDirective, X as EnumCorePageEditMode, Y as CoreFormComponent, Z as NavigatorService, _ as JsonService } from './ngx-histaff-alpha-ngx-histaff-alpha-q6N_damo.mjs';
2
+ import { inject, Component, Injector, runInInjectionContext, effect, Input, ChangeDetectionStrategy, EventEmitter, ElementRef, ViewChild, Output, Renderer2, output, computed, signal, viewChild, ChangeDetectorRef, Injectable, Directive, Pipe, ViewChildren } from '@angular/core';
3
+ import { B as BaseComponent, n as CoreWorkflowService, y as CoreFormDesignService, b as AlertService, z as EnumWorkflowStepType, w as alertOptions, E as EnumFormBaseContolType, M as MultiLanguageService, T as TooltipDirective, e as TranslatePipe, h as BaseEditComponent, i as DialogService, A as AppService, j as CorePageEditComponent, F as FullscreenModalLoaderComponent, G as DomService, o as EnumCoreFormControlSeekerSourceType, H as EnumActorSourceType, J as CoreParamControlComponent, K as CoreRadioGroupComponent, L as GptService, N as CoreRuleTreeService, O as CoreRuleTreeComponent, P as CoreStickerCollectionComponent, Q as ApplicationHelpService, R as HotKeysDirective, U as CoreDatetimeService, p as CoreFormService, V as EnumCorePageEditMode, W as CoreFormComponent, X as NavigatorService, Y as JsonService } from './ngx-histaff-alpha-ngx-histaff-alpha-BZdzGBj5.mjs';
4
4
  import * as i1$1 from '@angular/router';
5
5
  import { Router, ActivatedRoute, RouterOutlet } from '@angular/router';
6
6
  import { catchError, of, BehaviorSubject, distinctUntilChanged } from 'rxjs';
7
7
  import { EnumTranslateKey } from 'alpha-global-constants';
8
- import { AsyncPipe, NgTemplateOutlet, LowerCasePipe, NgStyle } from '@angular/common';
8
+ import { AsyncPipe, LowerCasePipe, NgStyle, NgTemplateOutlet } from '@angular/common';
9
9
  import * as i1 from '@angular/forms';
10
- import { Validators, ReactiveFormsModule, FormGroup, FormControl, FormArray, FormsModule } from '@angular/forms';
11
- import { CoreFormDesignComponent } from './ngx-histaff-alpha-core-form-design.component-Q7Mkj3Sw.mjs';
12
- import { trigger, state, transition, style, animate } from '@angular/animations';
10
+ import { Validators, FormsModule } from '@angular/forms';
11
+ import { CoreFormDesignComponent } from './ngx-histaff-alpha-core-form-design.component-Cy_mOM1n.mjs';
13
12
  import { HttpClient } from '@angular/common/http';
14
- import { C as CoreToastLoadingComponent } from './ngx-histaff-alpha-core-toast-loading.component-CQpoTAyX.mjs';
15
- import { R as RoutingPreviewPanelComponent } from './ngx-histaff-alpha-live-form.component-C-d4utoe.mjs';
13
+ import { C as CoreToastLoadingComponent } from './ngx-histaff-alpha-core-toast-loading.component-ClmryTzj.mjs';
14
+ import { R as RoutingPreviewPanelComponent } from './ngx-histaff-alpha-live-form.component-CatM7zte.mjs';
15
+ import { trigger, state, transition, style, animate } from '@angular/animations';
16
16
 
17
17
  class CurrentHeaderComponent extends BaseComponent {
18
18
  constructor(mls) {
@@ -29,7 +29,8 @@ class CurrentHeaderComponent extends BaseComponent {
29
29
  { index: 1, label: 'Basic Info', changed: this.wfs.$basicInfoChanged, onClick: () => this.goToBasicInfo() },
30
30
  { index: 2, label: 'Form Design', changed: this.wfs.$formDesignChanged, onClick: () => this.goToFormDesign() },
31
31
  { index: 3, label: 'Process Design', changed: this.wfs.$processDesignChanged, onClick: () => this.goToProcessDesign() },
32
- { index: 4, label: 'Email Templates', changed: this.wfs.$moreChanged, onClick: () => this.goToEmailTemplates() }
32
+ { index: 4, label: 'Delegation', changed: this.wfs.$processDesignChanged, onClick: () => this.goToDelegation() },
33
+ { index: 5, label: 'Email Templates', changed: this.wfs.$moreChanged, onClick: () => this.goToEmailTemplates() }
33
34
  ];
34
35
  }
35
36
  findStepMissingFallback(steps) {
@@ -58,11 +59,18 @@ class CurrentHeaderComponent extends BaseComponent {
58
59
  this.$activeTab.set(1); // Jump to Basic Info tab
59
60
  return;
60
61
  }
62
+ if (this.wfs.delegationForm.invalid) {
63
+ this.alertService.warn('Invalid Delegation', alertOptions);
64
+ this.wfs.delegationFormCheckError$.next(true);
65
+ setTimeout(() => this.wfs.delegationFormCheckError$.next(false), 5000);
66
+ this.$activeTab.set(4); // Jump to Basic Info tab
67
+ return;
68
+ }
61
69
  if (this.wfs.emailTemplatesForm.invalid) {
62
70
  this.alertService.warn('Invalid Email Templates', alertOptions);
63
71
  this.wfs.emailTemplatesFormCheckError$.next(true);
64
72
  setTimeout(() => this.wfs.emailTemplatesFormCheckError$.next(false), 5000);
65
- this.$activeTab.set(4); // Jump to Email Templates tab
73
+ this.$activeTab.set(5); // Jump to Email Templates tab
66
74
  return;
67
75
  }
68
76
  if (this.fds.$placeholderSections().some(x => x.rows.some(r => r?.cells.some(c => !c.control)))) {
@@ -110,6 +118,14 @@ class CurrentHeaderComponent extends BaseComponent {
110
118
  this.wfs.$currentFlow.update(flow => {
111
119
  if (flow) {
112
120
  flow.afInstanceDTO = afInstanceDTO;
121
+ const rawDelegation = this.wfs.delegationForm.getRawValue();
122
+ rawDelegation.delegationRows
123
+ ?.filter(x => !x.delegationId)
124
+ .forEach(row => {
125
+ row.vfUtc = this.normalizeToStartOfDay(row.vfUtc);
126
+ row.vtUtc = this.normalizeToStartOfDay(row.vtUtc);
127
+ });
128
+ flow.delegationJson = JSON.stringify(rawDelegation);
113
129
  const templates = this.wfs.emailTemplatesForm.getRawValue();
114
130
  const { submitSubject, submitBody, reactSubject, reactBody, fullyApproveSubject, fullyApproveBody, rejectSubject, rejectBody, cancelSubject, cancelBody, terminateSubject, terminateBody, revokeSubject, revokeBody, ccSubject, ccBody } = templates;
115
131
  flow.submitSubject = submitSubject;
@@ -147,11 +163,21 @@ class CurrentHeaderComponent extends BaseComponent {
147
163
  this.wfs.$initialBasicInfoJson.set(this.wfs.$currentBasicInfoJson());
148
164
  this.wfs.$initialFormDesignJson.set(this.wfs.$currentFormDesignJson());
149
165
  this.wfs.$initialProcessDesignJson.set(this.wfs.$currentProcessDesignJson());
166
+ this.wfs.$initialDelegationJson.set(this.wfs.$currentDelegationJson());
150
167
  this.router.navigate(['design', x.body.innerBody.id], { relativeTo: this.route.parent?.parent });
151
168
  this.wfs.basicInfoForm.get('id')?.patchValue(x.body.innerBody.id);
152
169
  }
153
170
  }));
154
171
  }
172
+ normalizeToStartOfDay(date) {
173
+ if (date === null)
174
+ return date;
175
+ if (date === undefined)
176
+ return null;
177
+ const d = new Date(date);
178
+ d.setHours(0, 0, 0, 0);
179
+ return d;
180
+ }
155
181
  preview() {
156
182
  if (!!this.fds.$afInstance().normalMode) {
157
183
  this.router.navigate([this.wfs.$currentFlow()?.afInstanceId], {
@@ -186,15 +212,18 @@ class CurrentHeaderComponent extends BaseComponent {
186
212
  goToProcessDesign() {
187
213
  this.$activeTab.set(3);
188
214
  }
189
- goToEmailTemplates() {
215
+ goToDelegation() {
190
216
  this.$activeTab.set(4);
191
217
  }
218
+ goToEmailTemplates() {
219
+ this.$activeTab.set(5);
220
+ }
192
221
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CurrentHeaderComponent, deps: [{ token: MultiLanguageService }], target: i0.ɵɵFactoryTarget.Component }); }
193
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: CurrentHeaderComponent, isStandalone: true, selector: "current-header", usesInheritance: true, ngImport: i0, template: "<div class=\"current-header-container\">\r\n <div class=\"left pointer\" (click)=\"backToList()\">\r\n\r\n <div class=\"icon-wrapper\" [appTooltip]=\"'Back to list' | translate : lang\" [showAnyway]=\"true\">\r\n <i class=\"feather-chevron-left\"></i>\r\n </div>\r\n <div class=\"current-flow-name\" [appTooltip]=\"wfs.$currentFlow()?.name || ''\">\r\n {{ wfs.$currentFlow()?.name || 'New Workflow' }}\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"stages\">\r\n @for (step of steps; track step.index) {\r\n <div\r\n class=\"step-wrapper\"\r\n [class.active]=\"$activeTab() === step.index\"\r\n [class.changed]=\"step.changed()\"\r\n (click)=\"step.onClick()\"\r\n (keydown.enter)=\"step.onClick()\"\r\n >\r\n <div class=\"order\">{{ step.index }}</div>\r\n <div class=\"step\">{{ step.label }}</div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"right\">\r\n <button type=\"button\" class=\"btn preview\" (click)=\"preview()\">Preview</button>\r\n <button type=\"button\" class=\"btn publish\" (click)=\"publish()\">Save</button>\r\n </div>\r\n </div>\r\n ", styles: [".current-header-container{height:50px;display:flex;gap:24px;overflow:visible;justify-content:space-between;align-items:center;border-bottom:1px solid #e0e0e0}.current-header-container .left{height:50px;display:flex;gap:24px;justify-content:flex-start;align-items:center}.current-header-container .left .icon-wrapper{cursor:pointer}.current-header-container .left .icon-wrapper i{font-size:24px}.current-header-container .left .current-flow-name{max-width:190px;overflow:hidden;text-overflow:ellipsis;text-wrap:nowrap}.current-header-container .stages{height:50px;display:flex;gap:36px;justify-content:center;align-items:center;overflow:visible}.current-header-container .stages .step-wrapper{display:flex;position:relative;align-items:center;justify-content:flex-start;height:50px;cursor:pointer;transition:all .5s ease-out}.current-header-container .stages .step-wrapper .order{display:flex;align-items:center;justify-content:center;width:35px;height:35px;margin-right:8px;border:1px solid #bbb;border-radius:50%;transform:none;transition:all .5s ease-out}.current-header-container .stages .step-wrapper .step{display:flex;align-items:center;justify-content:flex-start;font-size:14px;color:#666;height:50px;position:relative;transition:all .5s ease-out}.current-header-container .stages .step-wrapper .step:after{content:\"\";position:absolute;width:0px;height:0px;display:block;left:0;bottom:15px;border:1px dashed #848484;opacity:0;transition:width opacity .25s ease-out}.current-header-container .stages .step-wrapper.active:after{content:\"\";display:block;position:absolute;left:0;bottom:-3px;width:100%;height:3px;background-color:#87ceeb;z-index:1}.current-header-container .stages .step-wrapper.active .order{background-color:#87ceeb;color:#fff;backface-visibility:hidden;-webkit-font-smoothing:antialiased;box-shadow:#88a5bf7a 6px 2px 16px,#fffc -6px -2px 16px}.current-header-container .stages .step-wrapper.active .step{font-weight:700;color:#007bff}.current-header-container .stages .step-wrapper.changed .step:after{width:100%;opacity:1}.current-header-container .right{display:flex;align-items:center;justify-content:flex-end}.current-header-container .right button.preview{background-color:#87ceeb;color:#fff;border-radius:0;height:35px;font-size:13px;margin-right:8px}.current-header-container .right button.publish{background-color:#000;color:#fff;border-radius:0;height:35px;font-size:13px}@media (max-width: 992px){.current-header-container .step{width:0px;display:none!important}.current-header-container .order{margin:0!important}}@media (max-width: 768px){.current-header-container .stages{gap:8px}}\n"], dependencies: [{ kind: "directive", type: TooltipDirective, selector: "[appTooltip]", inputs: ["appTooltip", "showAnyway", "color", "backgroundColor", "position"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
222
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: CurrentHeaderComponent, isStandalone: true, selector: "current-header", usesInheritance: true, ngImport: i0, template: "<div class=\"current-header-container\">\r\n <div class=\"left pointer\" (click)=\"backToList()\">\r\n\r\n <div class=\"icon-wrapper\" [appTooltip]=\"'Back to list' | translate : lang\" [showAnyway]=\"true\">\r\n <i class=\"feather-chevron-left\"></i>\r\n </div>\r\n <div class=\"current-flow-name\" [appTooltip]=\"wfs.$currentFlow()?.name || ''\">\r\n {{ wfs.$currentFlow()?.name || 'New Workflow' }}\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"stages\">\r\n @for (step of steps; track step.index) {\r\n <div\r\n class=\"step-wrapper\"\r\n [class.active]=\"$activeTab() === step.index\"\r\n [class.changed]=\"step.changed()\"\r\n (click)=\"step.onClick()\"\r\n (keydown.enter)=\"step.onClick()\"\r\n >\r\n <div class=\"order\">{{ step.index }}</div>\r\n <div class=\"step\">{{ step.label }}</div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"right\">\r\n <button type=\"button\" class=\"btn preview\" (click)=\"preview()\">Preview</button>\r\n <button type=\"button\" class=\"btn publish\" (click)=\"publish()\">Save</button>\r\n </div>\r\n </div>\r\n ", styles: [".current-header-container{height:50px;display:flex;gap:24px;overflow:visible;justify-content:space-between;align-items:center;border-bottom:1px solid #e0e0e0}.current-header-container .left{height:50px;display:flex;gap:24px;justify-content:flex-start;align-items:center}.current-header-container .left .icon-wrapper{cursor:pointer}.current-header-container .left .icon-wrapper i{font-size:24px}.current-header-container .left .current-flow-name{max-width:190px;overflow:hidden;text-overflow:ellipsis;text-wrap:nowrap}.current-header-container .stages{height:50px;display:flex;gap:36px;justify-content:center;align-items:center;overflow:visible}.current-header-container .stages .step-wrapper{display:flex;position:relative;align-items:center;justify-content:flex-start;height:50px;cursor:pointer;transition:all .5s ease-out}.current-header-container .stages .step-wrapper .order{display:flex;align-items:center;justify-content:center;width:35px;height:35px;margin-right:8px;border:1px solid #bbb;border-radius:50%;transform:none;transition:all .5s ease-out}.current-header-container .stages .step-wrapper .step{display:flex;align-items:center;justify-content:flex-start;font-size:14px;color:#666;height:50px;position:relative;transition:all .5s ease-out}.current-header-container .stages .step-wrapper .step:after{content:\"\";position:absolute;width:0px;height:0px;display:block;left:0;bottom:15px;border:1px dashed #848484;opacity:0;transition:width opacity .25s ease-out}.current-header-container .stages .step-wrapper.active:after{content:\"\";display:block;position:absolute;left:0;bottom:-3px;width:100%;height:3px;background-color:#87ceeb;z-index:1}.current-header-container .stages .step-wrapper.active .order{background-color:#87ceeb;color:#fff;backface-visibility:hidden;-webkit-font-smoothing:antialiased;box-shadow:#88a5bf7a 6px 2px 16px,#fffc -6px -2px 16px}.current-header-container .stages .step-wrapper.active .step{font-weight:700;color:#007bff}.current-header-container .stages .step-wrapper.changed .step:after{width:100%;opacity:1}.current-header-container .right{display:flex;align-items:center;justify-content:flex-end}.current-header-container .right button.preview{background-color:#87ceeb;color:#fff;border-radius:0;height:35px;font-size:13px;margin-right:8px}.current-header-container .right button.publish{background-color:#000;color:#fff;border-radius:0;height:35px;font-size:13px}@media (max-width: 992px){.current-header-container .step{width:0px;display:none!important}.current-header-container .order{margin:0!important}}@media (max-width: 768px){.current-header-container .stages{gap:8px}}\n"], dependencies: [{ kind: "directive", type: TooltipDirective, selector: "[appTooltip]", inputs: ["appTooltip", "showAnyway", "color", "backgroundColor", "position"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
194
223
  }
195
224
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CurrentHeaderComponent, decorators: [{
196
225
  type: Component,
197
- args: [{ selector: 'current-header', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
226
+ args: [{ selector: 'current-header', imports: [
198
227
  TooltipDirective,
199
228
  TranslatePipe
200
229
  ], template: "<div class=\"current-header-container\">\r\n <div class=\"left pointer\" (click)=\"backToList()\">\r\n\r\n <div class=\"icon-wrapper\" [appTooltip]=\"'Back to list' | translate : lang\" [showAnyway]=\"true\">\r\n <i class=\"feather-chevron-left\"></i>\r\n </div>\r\n <div class=\"current-flow-name\" [appTooltip]=\"wfs.$currentFlow()?.name || ''\">\r\n {{ wfs.$currentFlow()?.name || 'New Workflow' }}\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"stages\">\r\n @for (step of steps; track step.index) {\r\n <div\r\n class=\"step-wrapper\"\r\n [class.active]=\"$activeTab() === step.index\"\r\n [class.changed]=\"step.changed()\"\r\n (click)=\"step.onClick()\"\r\n (keydown.enter)=\"step.onClick()\"\r\n >\r\n <div class=\"order\">{{ step.index }}</div>\r\n <div class=\"step\">{{ step.label }}</div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"right\">\r\n <button type=\"button\" class=\"btn preview\" (click)=\"preview()\">Preview</button>\r\n <button type=\"button\" class=\"btn publish\" (click)=\"publish()\">Save</button>\r\n </div>\r\n </div>\r\n ", styles: [".current-header-container{height:50px;display:flex;gap:24px;overflow:visible;justify-content:space-between;align-items:center;border-bottom:1px solid #e0e0e0}.current-header-container .left{height:50px;display:flex;gap:24px;justify-content:flex-start;align-items:center}.current-header-container .left .icon-wrapper{cursor:pointer}.current-header-container .left .icon-wrapper i{font-size:24px}.current-header-container .left .current-flow-name{max-width:190px;overflow:hidden;text-overflow:ellipsis;text-wrap:nowrap}.current-header-container .stages{height:50px;display:flex;gap:36px;justify-content:center;align-items:center;overflow:visible}.current-header-container .stages .step-wrapper{display:flex;position:relative;align-items:center;justify-content:flex-start;height:50px;cursor:pointer;transition:all .5s ease-out}.current-header-container .stages .step-wrapper .order{display:flex;align-items:center;justify-content:center;width:35px;height:35px;margin-right:8px;border:1px solid #bbb;border-radius:50%;transform:none;transition:all .5s ease-out}.current-header-container .stages .step-wrapper .step{display:flex;align-items:center;justify-content:flex-start;font-size:14px;color:#666;height:50px;position:relative;transition:all .5s ease-out}.current-header-container .stages .step-wrapper .step:after{content:\"\";position:absolute;width:0px;height:0px;display:block;left:0;bottom:15px;border:1px dashed #848484;opacity:0;transition:width opacity .25s ease-out}.current-header-container .stages .step-wrapper.active:after{content:\"\";display:block;position:absolute;left:0;bottom:-3px;width:100%;height:3px;background-color:#87ceeb;z-index:1}.current-header-container .stages .step-wrapper.active .order{background-color:#87ceeb;color:#fff;backface-visibility:hidden;-webkit-font-smoothing:antialiased;box-shadow:#88a5bf7a 6px 2px 16px,#fffc -6px -2px 16px}.current-header-container .stages .step-wrapper.active .step{font-weight:700;color:#007bff}.current-header-container .stages .step-wrapper.changed .step:after{width:100%;opacity:1}.current-header-container .right{display:flex;align-items:center;justify-content:flex-end}.current-header-container .right button.preview{background-color:#87ceeb;color:#fff;border-radius:0;height:35px;font-size:13px;margin-right:8px}.current-header-container .right button.publish{background-color:#000;color:#fff;border-radius:0;height:35px;font-size:13px}@media (max-width: 992px){.current-header-container .step{width:0px;display:none!important}.current-header-container .order{margin:0!important}}@media (max-width: 768px){.current-header-container .stages{gap:8px}}\n"] }]
@@ -377,7 +406,7 @@ class WfBasicInfoComponent extends BaseEditComponent {
377
406
  .subscribe(x => {
378
407
  if (x.ok && x.status === 200 && x.body?.statusCode === 200) {
379
408
  const newGroupOptions = [];
380
- x.body?.innerBody.forEach(e => {
409
+ x.body?.innerBody.forEach((e) => {
381
410
  newGroupOptions.push({
382
411
  value: e.id,
383
412
  text: e.name
@@ -396,7 +425,7 @@ class WfBasicInfoComponent extends BaseEditComponent {
396
425
  return null;
397
426
  }
398
427
  else {
399
- Object.keys(values).forEach(key => {
428
+ Object.keys(values).forEach((key) => {
400
429
  currentFlow[key] = values[key];
401
430
  });
402
431
  return { ...currentFlow };
@@ -593,432 +622,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
593
622
  args: ['plusContainer']
594
623
  }] } });
595
624
 
596
- class CoreControlValueOnlyComponent {
597
- constructor() {
598
- this.$control = input.required();
599
- this.$form = input.required();
600
- this.$fieldName = input();
601
- this.as = inject(AlertService);
602
- effect(() => {
603
- const control = this.$control();
604
- const form = this.$form();
605
- form.get(control?.field)?.valueChanges.subscribe(x => {
606
- this.coerceControlValue();
607
- });
608
- });
609
- }
610
- coerceControlValue() {
611
- const controlType = this.$control()?.controlType;
612
- switch (controlType) {
613
- case EnumFormBaseContolType.TEXTBOX:
614
- this.coerceNumber();
615
- break;
616
- case EnumFormBaseContolType.DATEPICKER:
617
- this.coerceDate();
618
- break;
619
- }
620
- }
621
- coerceDate() {
622
- const field = this.$fieldName() || this.$control().field;
623
- const control = this.$form().get(field);
624
- const value = control?.value;
625
- if (this.$control()?.type === 'date') {
626
- if (value instanceof Date) {
627
- const normalized = this.formatDateOnly(value);
628
- control?.setValue(normalized, { emitEvent: false });
629
- }
630
- else if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T/.test(value)) {
631
- const normalized = value.split('T')[0];
632
- control?.setValue(normalized, { emitEvent: false });
633
- }
634
- }
635
- }
636
- formatDateOnly(date) {
637
- const y = date.getFullYear();
638
- const m = String(date.getMonth() + 1).padStart(2, '0');
639
- const d = String(date.getDate()).padStart(2, '0');
640
- return `${y}-${m}-${d}`;
641
- }
642
- coerceNumber() {
643
- const field = this.$fieldName() || this.$control().field;
644
- const control = this.$form().get(field);
645
- const value = control?.value;
646
- if (this.$control()?.type === 'number' && typeof value === 'string') {
647
- const trimmed = value.trim();
648
- if (trimmed === '') {
649
- control?.setValue(null, { emitEvent: false }); // ✅ treat empty string as null
650
- return;
651
- }
652
- if (!isNaN(+trimmed)) {
653
- control?.setValue(Number(trimmed), { emitEvent: false });
654
- }
655
- }
656
- }
657
- ngOnInit() {
658
- const field = this.$fieldName() || this.$control().field;
659
- const control = this.$form().get(field);
660
- if (!control) {
661
- if (isDevMode()) {
662
- this.as.error("control is undefined|null", alertOptions);
663
- }
664
- return;
665
- }
666
- this.coerceControlValue(); // Run once on init
667
- control.valueChanges.subscribe(() => {
668
- this.coerceControlValue(); // Run on every input change
669
- });
670
- }
671
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreControlValueOnlyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
672
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: CoreControlValueOnlyComponent, isStandalone: true, selector: "core-control-value-only", inputs: { $control: { classPropertyName: "$control", publicName: "$control", isSignal: true, isRequired: true, transformFunction: null }, $form: { classPropertyName: "$form", publicName: "$form", isSignal: true, isRequired: true, transformFunction: null }, $fieldName: { classPropertyName: "$fieldName", publicName: "$fieldName", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [formGroup]=\"$form()\">\r\n @switch ($control()?.controlType) {\r\n @case ('TEXTBOX') {\r\n <input class=\"form-control\" [formControlName]=\"$fieldName() || $control()?.field || ''\" [type]=\"$control()?.type || 'text'\"\r\n [placeholder]=\"$control()?.placeholder || ''\" [readonly]=\"$control()?.readonly\" />\r\n }\r\n @case ('CURRENCY') {\r\n <core-currency-input [formControlName]=\"$fieldName() || $control()?.field || ''\"\r\n [placeholder]=\"$control()?.placeholder || ''\">\r\n </core-currency-input>\r\n }\r\n @case ('DROPDOWN') {\r\n @if ($control()?.dropdownOptions$) {\r\n <core-dropdown \r\n [formControlName]=\"$fieldName() || $control()?.field || ''\" \r\n [options$]=\"$control()?.dropdownOptions$!\"\r\n [getByIdObject$]=\"$control()?.getByIdObject$!\"\r\n [shownFrom]=\"$control()?.shownFrom!\"\r\n\r\n [optionApiDriven]=\"$control()?.optionApiDriven!\"\r\n [optionApi]=\"$control()?.optionApi!\"\r\n [optionHttpVerb]=\"$control()?.optionHttpVerb!\"\r\n [optionHttpPayload]=\"$control()?.optionHttpPayload!\"\r\n [optionValueFrom]=\"$control()?.optionValueFrom!\"\r\n [optionTextFrom]=\"$control()?.optionTextFrom!\"\r\n >\r\n </core-dropdown>\r\n }\r\n }\r\n @case ('CHECKLIST') {\r\n @if ($control()?.checklistOptions$) {\r\n <core-checklist [formControlName]=\"$fieldName() || $control()?.field || ''\" [options$]=\"$control()?.checklistOptions$!\">\r\n </core-checklist>\r\n }\r\n }\r\n @case ('DATEPICKER') {\r\n <core-date-picker [formControlName]=\"$fieldName() || $control()?.field || ''\" [rangeLimit]=\"$control()?.rangeLimit!\"\r\n [popupAlign]=\"$control()?.popupAlign!\" [placeholder]=\"$control()?.placeholder || ''\"\r\n [readonly]=\"$control()?.readonly!\">\r\n </core-date-picker>\r\n }\r\n @case ('SEEKER') {\r\n <core-form-control-seeker [formControlName]=\"$fieldName() || $control()?.field || ''\"\r\n [seekerSourceType]=\"$control()?.seekerSourceType!\" [shownFrom]=\"$control()?.shownFrom!\"\r\n [multiMode]=\"$control()?.multiMode!\"\r\n [boundFrom]=\"$control()?.boundFrom!\" [objectList$]=\"$control()?.objectList$!\">\r\n </core-form-control-seeker>\r\n }\r\n @default {\r\n <input class=\"form-control\" [formControlName]=\"$fieldName() || $control()?.field || ''\" type=\"text\"\r\n [placeholder]=\"$control()?.placeholder || ''\" [readonly]=\"$control()?.readonly\" />\r\n }\r\n }\r\n</div>", styles: [":host{display:block}input.form-control,core-dropdown,core-checklist,core-date-picker,core-currency-input,core-form-control-seeker{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: CoreDropdownComponent, selector: "core-dropdown", inputs: ["getByIdObject$", "paramMode", "shownFrom", "options$", "height", "placeholder", "loading", "warningDisable", "clearDisable", "fitHeightWithItemCount", "itemHeight", "optionApiDriven", "optionApi", "optionHttpVerb", "optionHttpPayload", "optionValueFrom", "optionTextFrom"] }, { kind: "component", type: CoreChecklistComponent, selector: "core-checklist", inputs: ["paramMode", "getByIdObject$", "shownFrom", "options$", "height", "placeholder", "loading", "readonly", "disabled"] }, { kind: "component", type: CoreDatePickerComponent, selector: "core-date-picker", inputs: ["enableTimeZoneConverter", "showPlaceholder", "popupWidth", "popupXPadding", "popupAlign", "rangeLimit", "placeholder", "readonly", "disabled"] }, { kind: "component", type: CoreFormControlSeekerComponent, selector: "core-form-control-seeker", inputs: ["title", "showPageHeader", "preDefinedOuterParam$", "preDefinedOuterFilter$", "click$", "getByIdObject$", "getByIdApi", "paramMode", "multiMode", "objectList$", "useTheseColumns", "hideOrgTree", "excludedColumns", "excludeExistingList", "placeholder", "sourceSpaceHeight", "indirectBinding", "bindGridIdTo", "multiModeExtendedColumns", "multiModeExtendedSections", "editBufferData$", "multiModeTableHeight", "multiModeRowHeight", "seekerSourceType", "boundFrom", "shownFrom", "alsoBindTo", "seekerVerifyIgnore", "disabledDoubleClick", "selfEnrichmentApiDriven", "selfEnrichmentApi", "selfEnrichmentHttpVerb", "selfEnrichmentHttpPayload", "selfEnrichmentShownFrom"], outputs: ["onDoubleClick", "selectedDataChange", "fullValueRowChange"] }, { kind: "component", type: CoreCurrencyInputComponent, selector: "core-currency-input", inputs: ["currencySign", "placeholder"], outputs: ["onLeftFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
673
- }
674
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreControlValueOnlyComponent, decorators: [{
675
- type: Component,
676
- args: [{ selector: 'core-control-value-only', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
677
- ReactiveFormsModule,
678
- CoreDropdownComponent,
679
- CoreChecklistComponent,
680
- CoreDatePickerComponent,
681
- CoreFormControlSeekerComponent,
682
- CoreCurrencyInputComponent
683
- ], template: "<div [formGroup]=\"$form()\">\r\n @switch ($control()?.controlType) {\r\n @case ('TEXTBOX') {\r\n <input class=\"form-control\" [formControlName]=\"$fieldName() || $control()?.field || ''\" [type]=\"$control()?.type || 'text'\"\r\n [placeholder]=\"$control()?.placeholder || ''\" [readonly]=\"$control()?.readonly\" />\r\n }\r\n @case ('CURRENCY') {\r\n <core-currency-input [formControlName]=\"$fieldName() || $control()?.field || ''\"\r\n [placeholder]=\"$control()?.placeholder || ''\">\r\n </core-currency-input>\r\n }\r\n @case ('DROPDOWN') {\r\n @if ($control()?.dropdownOptions$) {\r\n <core-dropdown \r\n [formControlName]=\"$fieldName() || $control()?.field || ''\" \r\n [options$]=\"$control()?.dropdownOptions$!\"\r\n [getByIdObject$]=\"$control()?.getByIdObject$!\"\r\n [shownFrom]=\"$control()?.shownFrom!\"\r\n\r\n [optionApiDriven]=\"$control()?.optionApiDriven!\"\r\n [optionApi]=\"$control()?.optionApi!\"\r\n [optionHttpVerb]=\"$control()?.optionHttpVerb!\"\r\n [optionHttpPayload]=\"$control()?.optionHttpPayload!\"\r\n [optionValueFrom]=\"$control()?.optionValueFrom!\"\r\n [optionTextFrom]=\"$control()?.optionTextFrom!\"\r\n >\r\n </core-dropdown>\r\n }\r\n }\r\n @case ('CHECKLIST') {\r\n @if ($control()?.checklistOptions$) {\r\n <core-checklist [formControlName]=\"$fieldName() || $control()?.field || ''\" [options$]=\"$control()?.checklistOptions$!\">\r\n </core-checklist>\r\n }\r\n }\r\n @case ('DATEPICKER') {\r\n <core-date-picker [formControlName]=\"$fieldName() || $control()?.field || ''\" [rangeLimit]=\"$control()?.rangeLimit!\"\r\n [popupAlign]=\"$control()?.popupAlign!\" [placeholder]=\"$control()?.placeholder || ''\"\r\n [readonly]=\"$control()?.readonly!\">\r\n </core-date-picker>\r\n }\r\n @case ('SEEKER') {\r\n <core-form-control-seeker [formControlName]=\"$fieldName() || $control()?.field || ''\"\r\n [seekerSourceType]=\"$control()?.seekerSourceType!\" [shownFrom]=\"$control()?.shownFrom!\"\r\n [multiMode]=\"$control()?.multiMode!\"\r\n [boundFrom]=\"$control()?.boundFrom!\" [objectList$]=\"$control()?.objectList$!\">\r\n </core-form-control-seeker>\r\n }\r\n @default {\r\n <input class=\"form-control\" [formControlName]=\"$fieldName() || $control()?.field || ''\" type=\"text\"\r\n [placeholder]=\"$control()?.placeholder || ''\" [readonly]=\"$control()?.readonly\" />\r\n }\r\n }\r\n</div>", styles: [":host{display:block}input.form-control,core-dropdown,core-checklist,core-date-picker,core-currency-input,core-form-control-seeker{width:100%}\n"] }]
684
- }], ctorParameters: () => [] });
685
-
686
- class CoreRuleTreeService {
687
- constructor() {
688
- this.$formValue = signal(null); // Manual form value signal
689
- this.$filterFormJsonString = signal('{}');
690
- this.$filterString = computed(() => {
691
- const json = this.$filterFormJsonString();
692
- if (!json)
693
- return '()';
694
- try {
695
- const cleaned = JSON.parse(json);
696
- return this.getFilterString(cleaned);
697
- }
698
- catch {
699
- return '()';
700
- }
701
- });
702
- }
703
- cleanEmptyFilters(node) {
704
- if (!node || typeof node !== 'object')
705
- return node;
706
- // If it's a group with filters
707
- if (Array.isArray(node.filters)) {
708
- node.filters = node.filters
709
- .map(f => this.cleanEmptyFilters(f))
710
- .filter(f => f !== null); // optional: skip nulls
711
- if (node.filters.length === 0) {
712
- delete node.filters; // ← Clean!
713
- }
714
- }
715
- return node;
716
- }
717
- getFilterString(filter) {
718
- if (!filter || Object.keys(filter).length === 0)
719
- return '()';
720
- let str = '(';
721
- for (let i = 0; i < filter.filters?.length; i++) {
722
- if (i > 0)
723
- str += ` ${filter.logicalOperator} `;
724
- const f = filter.filters[i];
725
- if (f?.filters?.length) {
726
- str += this.getFilterString(f);
727
- }
728
- else {
729
- const rawVal = f.value;
730
- let formattedVal = rawVal;
731
- if (rawVal instanceof Date) {
732
- formattedVal = this.formatDateToYMD(rawVal);
733
- }
734
- else if (typeof rawVal === 'string' && /^\d{4}-\d{2}-\d{2}T/.test(rawVal)) {
735
- // parse ISO string if needed
736
- try {
737
- formattedVal = this.formatDateToYMD(new Date(rawVal));
738
- }
739
- catch { }
740
- }
741
- str += `${f.name} ${f.relationalOperator} '${formattedVal}'`;
742
- }
743
- }
744
- return str + ')';
745
- }
746
- formatDateToYMD(date) {
747
- const yyyy = date.getFullYear();
748
- const mm = String(date.getMonth() + 1).padStart(2, '0'); // Months are 0-based
749
- const dd = String(date.getDate()).padStart(2, '0');
750
- return `${yyyy}-${mm}-${dd}`;
751
- }
752
- buildFormGroupFromStep(config) {
753
- const logicalOperator = config?.logicalOperator ?? 'AND';
754
- const buildFilter = (f) => {
755
- // If it has logicalOperator and filters → it's a nested group
756
- if (f?.logicalOperator && Array.isArray(f.filters)) {
757
- return this.buildFormGroupFromStep(f);
758
- }
759
- return new FormGroup({
760
- name: new FormControl(f?.name ?? null),
761
- value: new FormControl(f?.value ?? null),
762
- relationalOperator: new FormControl(f?.relationalOperator ?? 'EQUAL'),
763
- defaultMessage: new FormControl(f?.defaultMessage ?? ''),
764
- englishMessage: new FormControl(f?.englishMessage ?? '')
765
- });
766
- };
767
- const filters = Array.isArray(config?.filters)
768
- ? config.filters.map(buildFilter)
769
- : [];
770
- const form = new FormGroup({
771
- logicalOperator: new FormControl(logicalOperator),
772
- filters: new FormArray(filters)
773
- });
774
- // Only once all controls exist
775
- setTimeout(() => this.$formValue.set(form.getRawValue()));
776
- return form;
777
- }
778
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreRuleTreeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
779
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreRuleTreeService, providedIn: 'root' }); }
780
- }
781
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreRuleTreeService, decorators: [{
782
- type: Injectable,
783
- args: [{
784
- providedIn: 'root'
785
- }]
786
- }], ctorParameters: () => [] });
787
-
788
- var EnumCoreRuleTreeOparator;
789
- (function (EnumCoreRuleTreeOparator) {
790
- EnumCoreRuleTreeOparator["EQUAL"] = "EQUAL";
791
- EnumCoreRuleTreeOparator["GREATER_THAN"] = "GREATER_THAN";
792
- EnumCoreRuleTreeOparator["LESS_THAN"] = "LESS_THAN";
793
- EnumCoreRuleTreeOparator["GREATER_OR_EQUAL_THAN"] = "GREATER_OR_EQUAL_THAN";
794
- EnumCoreRuleTreeOparator["LESS_OR_EQUAL_THAN"] = "LESS_OR_EQUAL_THAN";
795
- EnumCoreRuleTreeOparator["STARTS_WITH"] = "STARTS_WITH";
796
- EnumCoreRuleTreeOparator["ENDS_WITH"] = "ENDS_WITH";
797
- EnumCoreRuleTreeOparator["CONTAINS"] = "CONTAINS";
798
- EnumCoreRuleTreeOparator["IN"] = "IN";
799
- EnumCoreRuleTreeOparator["NOT_EQUAL"] = "NOT_EQUAL";
800
- EnumCoreRuleTreeOparator["NOT_STARTS_WITH"] = "NOT_STARTS_WITH";
801
- EnumCoreRuleTreeOparator["NOT_ENDS_WITH"] = "NOT_ENDS_WITH";
802
- EnumCoreRuleTreeOparator["NOT_CONTAINS"] = "NOT_CONTAINS";
803
- EnumCoreRuleTreeOparator["NOT_IN"] = "NOT_IN";
804
- EnumCoreRuleTreeOparator["IS_NULL"] = "IS_NULL";
805
- EnumCoreRuleTreeOparator["IS_NOT_NULL"] = "IS_NOT_NULL";
806
- })(EnumCoreRuleTreeOparator || (EnumCoreRuleTreeOparator = {}));
807
-
808
- class CoreRuleTreeComponent extends BaseComponent {
809
- getColLabelTooltip(filterGroup) {
810
- const selectedField = filterGroup.get('name')?.value;
811
- if (!selectedField)
812
- return;
813
- const match = this.$totalCols().find(col => col.field === selectedField);
814
- return match?.label || selectedField;
815
- }
816
- shouldShowValueControl(operator) {
817
- return operator !== 'IS_NULL' && operator !== 'IS_NOT_NULL';
818
- }
819
- toggleCollapse(group) {
820
- const current = this.collapsedGroups.get(group) || false;
821
- this.collapsedGroups.set(group, !current);
822
- }
823
- isCollapsed(group) {
824
- return this.collapsedGroups.get(group) || false;
825
- }
826
- field() {
827
- return new FormGroup({
828
- name: new FormControl(null),
829
- value: new FormControl(null),
830
- relationalOperator: new FormControl('EQUAL'),
831
- defaultMessage: new FormControl(''),
832
- englishMessage: new FormControl('')
833
- });
834
- }
835
- filter() {
836
- return new FormGroup({
837
- logicalOperator: new FormControl('AND'),
838
- filters: new FormArray([])
839
- });
840
- }
841
- constructor(mls, cdr) {
842
- super(mls);
843
- this.mls = mls;
844
- this.cdr = cdr;
845
- // Inputs
846
- this.$totalCols = input([]);
847
- this.$mainForm = input(new FormGroup({
848
- logicalOperator: new FormControl('AND')
849
- }));
850
- this.$filterStringInput = input();
851
- this.$expressionInput = input();
852
- // Outputs
853
- this.$jsonEmitter = output();
854
- this.crts = inject(CoreRuleTreeService);
855
- this.$rawValue = computed(() => JSON.stringify(this.$mainForm().getRawValue(), null, 2));
856
- // Track collapsed groups manually
857
- this.collapsedGroups = new WeakMap();
858
- this.operatorFriendlyMap = {
859
- [EnumCoreRuleTreeOparator.EQUAL]: 'Equals (=)',
860
- [EnumCoreRuleTreeOparator.NOT_EQUAL]: 'Does not equal (≠)',
861
- [EnumCoreRuleTreeOparator.STARTS_WITH]: 'Starts with (→)',
862
- [EnumCoreRuleTreeOparator.ENDS_WITH]: 'Ends with (←)',
863
- [EnumCoreRuleTreeOparator.CONTAINS]: 'Contains (∈)',
864
- [EnumCoreRuleTreeOparator.NOT_STARTS_WITH]: 'Does NOT start with (↛)',
865
- [EnumCoreRuleTreeOparator.NOT_ENDS_WITH]: 'Does NOT end with (↚)',
866
- [EnumCoreRuleTreeOparator.NOT_CONTAINS]: 'Does NOT contain (∉)',
867
- [EnumCoreRuleTreeOparator.GREATER_THAN]: 'Greater than (>)',
868
- [EnumCoreRuleTreeOparator.LESS_THAN]: 'Less than (<)',
869
- [EnumCoreRuleTreeOparator.GREATER_OR_EQUAL_THAN]: 'Greater or equal (≥)',
870
- [EnumCoreRuleTreeOparator.LESS_OR_EQUAL_THAN]: 'Less or equal (≤)',
871
- [EnumCoreRuleTreeOparator.IN]: 'In list (∈)',
872
- [EnumCoreRuleTreeOparator.NOT_IN]: 'Not in list (∉)',
873
- [EnumCoreRuleTreeOparator.IS_NULL]: 'Is null',
874
- [EnumCoreRuleTreeOparator.IS_NOT_NULL]: 'Is not null',
875
- };
876
- this.relationalOperator = Object.values(EnumCoreRuleTreeOparator);
877
- this.prevJson = signal('{}');
878
- effect((onCleanup) => {
879
- const form = this.$mainForm();
880
- if (!!form) {
881
- const sub = form.valueChanges.subscribe(value => {
882
- const updateOperators = (group) => {
883
- const filters = group.get('filters');
884
- if (!filters)
885
- return;
886
- filters.controls.forEach(control => {
887
- if (!(control instanceof FormGroup))
888
- return;
889
- const operator = control.get('relationalOperator')?.value;
890
- const valueControl = control.get('value');
891
- if (operator === 'IS_NULL' || operator === 'IS_NOT_NULL') {
892
- valueControl?.setValue(null, { emitEvent: false });
893
- valueControl?.disable({ emitEvent: false });
894
- }
895
- else {
896
- valueControl?.enable({ emitEvent: false });
897
- }
898
- // 🌀 Recurse safely if this nested control has subfilters
899
- const subFilters = control.get('filters');
900
- if (subFilters && control instanceof FormGroup) {
901
- updateOperators(control);
902
- }
903
- });
904
- };
905
- updateOperators(form);
906
- // 🔁 Now that the form has been normalized, update the signal
907
- this.crts.$formValue.set(form.getRawValue());
908
- });
909
- onCleanup(() => sub.unsubscribe());
910
- }
911
- });
912
- // ➡️ Separate reaction effect for serialization
913
- effect(() => {
914
- const formValue = this.crts.$formValue();
915
- if (!formValue)
916
- return;
917
- const cleaned = this.crts.cleanEmptyFilters(formValue); // 👈 apply cleaning here
918
- const json = JSON.stringify(cleaned, null, 2);
919
- if (json !== this.prevJson()) {
920
- this.crts.$filterFormJsonString.set(json.trim());
921
- this.$jsonEmitter.emit(json);
922
- this.prevJson.set(json);
923
- }
924
- });
925
- effect(() => {
926
- const _ = this.$mainForm().getRawValue();
927
- const updateAll = (formGroup) => {
928
- const filters = formGroup.get('filters');
929
- if (!filters)
930
- return;
931
- filters.controls.forEach(control => {
932
- // Handle nested groups
933
- const subFilters = control.get('filters');
934
- if (subFilters)
935
- updateAll(control);
936
- });
937
- };
938
- updateAll(this.$mainForm());
939
- });
940
- // Initialize immediately based on initial form
941
- this.crts.$formValue.set(this.$mainForm().getRawValue());
942
- }
943
- addGroup(groupForm) {
944
- const filtersArray = groupForm.get('filters');
945
- if (filtersArray) {
946
- const newGroup = this.filter(); // 🛠 use your existing filter() factory method
947
- filtersArray.push(newGroup);
948
- }
949
- }
950
- removeGroup(groupForm, index) {
951
- const filtersArray = groupForm.get('filters');
952
- if (filtersArray && filtersArray.length > index) {
953
- setTimeout(() => filtersArray.removeAt(index));
954
- }
955
- }
956
- addCondition(groupForm) {
957
- const filtersArray = groupForm.get('filters');
958
- if (filtersArray) {
959
- const newCondition = this.field();
960
- filtersArray.push(newCondition);
961
- }
962
- }
963
- removeCondition(filterGroup, index) {
964
- const filtersArray = filterGroup.get('filters');
965
- if (filtersArray && filtersArray.length > index) {
966
- setTimeout(() => filtersArray.removeAt(index));
967
- }
968
- }
969
- resolveControl(fieldName) {
970
- const cols = this.$totalCols();
971
- if (!cols || !fieldName)
972
- return undefined;
973
- const tryfind = cols.find(x => x.field === fieldName);
974
- return tryfind;
975
- }
976
- safeStringify(obj) {
977
- const seen = new WeakSet();
978
- return JSON.stringify(obj, (key, value) => {
979
- if (typeof value === 'object' && value !== null) {
980
- if (seen.has(value)) {
981
- return undefined; // ✋ Skip circular reference
982
- }
983
- seen.add(value);
984
- }
985
- return value;
986
- });
987
- }
988
- isCalculatedField(fieldName) {
989
- const control = this.resolveControl(fieldName);
990
- return control?.controlType === 'CALCULATED';
991
- }
992
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreRuleTreeComponent, deps: [{ token: MultiLanguageService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
993
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: CoreRuleTreeComponent, isStandalone: true, selector: "core-rule-tree", inputs: { $totalCols: { classPropertyName: "$totalCols", publicName: "$totalCols", isSignal: true, isRequired: false, transformFunction: null }, $mainForm: { classPropertyName: "$mainForm", publicName: "$mainForm", isSignal: true, isRequired: false, transformFunction: null }, $filterStringInput: { classPropertyName: "$filterStringInput", publicName: "$filterStringInput", isSignal: true, isRequired: false, transformFunction: null }, $expressionInput: { classPropertyName: "$expressionInput", publicName: "$expressionInput", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { $jsonEmitter: "$jsonEmitter" }, usesInheritance: true, ngImport: i0, template: "<div class=\"core-rule-tree-container\">\r\n\r\n <form [formGroup]=\"$mainForm()\" (ngSubmit)=\"null\" class=\"core-rule-tree-form\">\r\n\r\n <div class=\"top-bar\">\r\n <div class=\"expression-box\">\r\n Expression = {{ crts.$filterString() || '()' }}\r\n </div>\r\n \r\n </div>\r\n \r\n <div class=\"query-builder\">\r\n <ng-template #queryTemplate let-filter=\"filter\" let-groupToRemove=\"groupToRemove\">\r\n \r\n <div class=\"group-card\">\r\n\r\n <div class=\"group-header\">\r\n\r\n <div class=\"logical-operator\">\r\n\r\n <select class=\"form-control pointer\" [formControl]=\"filter.get('logicalOperator')\">\r\n <option value=\"AND\">AND</option>\r\n <option value=\"OR\">OR</option>\r\n </select>\r\n\r\n <!-- Collapse/Expand Button -->\r\n @if (!!filter.value.filters?.length) {\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\"\r\n (click)=\"toggleCollapse(filter)\"\r\n [appTooltip]=\"isCollapsed(filter) ? 'Expand Group' : 'Collapse Group'\">\r\n <i class=\"feather\" [class.feather-plus]=\"isCollapsed(filter)\" [class.feather-minus]=\"!isCollapsed(filter)\"></i>\r\n </button>\r\n }\r\n <div class=\"local-action-buttons\">\r\n <button type=\"button\" class=\"btn btn-success feather-file-plus\"\r\n (click)=\"addCondition(filter)\"\r\n [appTooltip]=\"'Add Condition to this Group'\" [position]=\"'above'\">\r\n </button>\r\n <button type=\"button\" class=\"btn btn-success feather-folder-plus\"\r\n (click)=\"addGroup(filter)\"\r\n [appTooltip]=\"'Add Subgroup to this Group'\" [position]=\"'above'\">\r\n </button>\r\n @if (!!groupToRemove) {\r\n <button type=\"button\" class=\"btn btn-danger feather-trash\"\r\n (click)=\"removeGroup(groupToRemove.group, groupToRemove.index)\"\r\n [appTooltip]=\"'Remove Group'\" [position]=\"'above'\">\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"group-content\">\r\n \r\n @if (!isCollapsed(filter)) {\r\n\r\n @if (!!filter.value.filters?.length) {\r\n <div class=\"filter-list\" formArrayName=\"filters\">\r\n @for (childFilter of filter.get('filters').controls; track $index; let idx = $index) {\r\n <div class=\"filter-row\" [formGroup]=\"childFilter\">\r\n \r\n @if (!childFilter.value.logicalOperator) {\r\n\r\n <div class=\"filter-raw\">\r\n\r\n <div class=\"field-cell\">\r\n <select class=\"form-control\"\r\n [appTooltip]=\"getColLabelTooltip(childFilter)\"\r\n [showAnyway]=\"true\"\r\n formControlName=\"name\">\r\n @for (col of $totalCols(); track $index) {\r\n <option [value]=\"col.field\">{{ col.label || col.field }}</option>\r\n }\r\n </select>\r\n\r\n </div>\r\n\r\n <div class=\"operator-cell\">\r\n <select class=\"form-control\" formControlName=\"relationalOperator\">\r\n @for (op of relationalOperator; track $index) {\r\n <option [value]=\"op\">{{ operatorFriendlyMap[op] || op }}</option>\r\n }\r\n </select>\r\n </div> \r\n\r\n <div class=\"value-cell\">\r\n @if (shouldShowValueControl(childFilter.value.relationalOperator)) {\r\n <core-control-value-only\r\n @fadeSwitch\r\n [$control]=\"resolveControl(childFilter.value.name)!\"\r\n [$form]=\"childFilter\"\r\n [$fieldName]=\"'value'\"\r\n >\r\n </core-control-value-only>\r\n }\r\n </div>\r\n\r\n <div class=\"action-cell\">\r\n <button type=\"button\" class=\"btn btn-danger btn-sm feather-trash-2\"\r\n (click)=\"removeCondition(filter, idx)\"\r\n [appTooltip]=\"'Remove Condition'\">\r\n </button>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"filter-message default\">\r\n <input type=\"text\"\r\n class=\"form-control\"\r\n placeholder=\"Default message...\"\r\n formControlName=\"defaultMessage\" />\r\n </div>\r\n\r\n <div class=\"filter-message english\">\r\n <input type=\"text\"\r\n class=\"form-control\"\r\n placeholder=\"English message...\"\r\n formControlName=\"englishMessage\" />\r\n </div>\r\n\r\n } @else {\r\n <!-- Recursive nested groups -->\r\n <ng-container *ngTemplateOutlet=\"queryTemplate; context: { filter: childFilter, groupToRemove: { group: filter, index: idx } }\"></ng-container>\r\n }\r\n \r\n </div>\r\n }\r\n </div>\r\n }\r\n \r\n\r\n }\r\n\r\n </div>\r\n\r\n </div>\r\n \r\n </ng-template>\r\n \r\n <ng-container\r\n *ngTemplateOutlet=\"queryTemplate; context: { filter: $mainForm(), groupToRemove: null }\">\r\n </ng-container>\r\n \r\n </div>\r\n \r\n </form>\r\n \r\n <div class=\"dev-json-view\">\r\n <pre class=\"json-preview\">{{ crts.$filterFormJsonString() }}</pre>\r\n </div>\r\n \r\n </div>\r\n", styles: [".core-rule-tree-container{display:flex;flex-direction:column;width:100%;overflow-y:auto}.core-rule-tree-container button{border-radius:0}.expression-box{background:#e0f2fe;padding:6px 12px;font-weight:500;font-size:14px}.top-controls{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px;padding:8px}.expression-display{background-color:#e0f2fe;padding:8px 16px;font-family:monospace;font-size:14px;color:#0369a1}.query-builder{flex-grow:1;overflow-y:visible}.json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;border-radius:10px;box-shadow:0 2px 6px #00000014;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;overflow-x:auto;line-height:1.5;margin-top:15px}.core-rule-tree-form{display:flex;flex-direction:column;gap:16px}.top-bar{display:flex;justify-content:space-between;align-items:center}.expression-box{background:#e0f2fe;padding:6px 12px;font-weight:500;font-size:14px;margin-right:8px}.query-builder{display:flex;flex-direction:column;gap:16px}.group-card{padding:15px;background:#f9f9f9;display:flex;flex-direction:column;gap:8px;position:relative}.group-card .group-header{display:block;position:relative}.group-card .logical-operator{display:flex;align-items:center;align-self:flex-start;gap:8px}.group-card .logical-operator select{width:57px;background-color:#fff4ce}.group-card .logical-operator .local-action-buttons{margin-left:auto;display:flex;gap:4px}.group-card .logical-operator:hover .local-action-buttons{display:flex}.filter-list{display:flex;flex-direction:column;gap:8px}.filter-row{margin:8px 0}.filter-row .filter-raw{display:flex;align-items:center;gap:8px}.field-cell,.operator-cell,.value-cell{flex:1}.field-cell select{width:136px;overflow:hidden;text-overflow:ellipsis;text-wrap:nowrap}.filter-message{margin-top:8px}.action-cell{flex-shrink:0}.btn-xs{padding:2px 6px;font-size:10px}.rule-group-container:hover{background-color:#f9f9f9}.group-content{pointer-events:none}.group-content>*{pointer-events:auto}.logical-operator-label{display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;border:1px solid #ced4da;background-color:#fff4ce;color:#495057;font-size:14px;font-weight:500;min-width:100px;width:57px;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: CoreControlValueOnlyComponent, selector: "core-control-value-only", inputs: ["$control", "$form", "$fieldName"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TooltipDirective, selector: "[appTooltip]", inputs: ["appTooltip", "showAnyway", "color", "backgroundColor", "position"] }], animations: [
994
- trigger('fadeSwitch', [
995
- state('visible', style({ opacity: 1 })),
996
- state('hidden', style({ opacity: 0 })),
997
- transition('hidden => visible', [animate('250ms ease-in')]),
998
- transition('visible => hidden', [animate('150ms ease-out')]),
999
- ])
1000
- ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1001
- }
1002
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreRuleTreeComponent, decorators: [{
1003
- type: Component,
1004
- args: [{ selector: 'core-rule-tree', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1005
- FormsModule,
1006
- ReactiveFormsModule,
1007
- CoreControlValueOnlyComponent,
1008
- NgTemplateOutlet,
1009
- CoreDropdownComponent,
1010
- TooltipDirective,
1011
- TranslatePipe
1012
- ], animations: [
1013
- trigger('fadeSwitch', [
1014
- state('visible', style({ opacity: 1 })),
1015
- state('hidden', style({ opacity: 0 })),
1016
- transition('hidden => visible', [animate('250ms ease-in')]),
1017
- transition('visible => hidden', [animate('150ms ease-out')]),
1018
- ])
1019
- ], template: "<div class=\"core-rule-tree-container\">\r\n\r\n <form [formGroup]=\"$mainForm()\" (ngSubmit)=\"null\" class=\"core-rule-tree-form\">\r\n\r\n <div class=\"top-bar\">\r\n <div class=\"expression-box\">\r\n Expression = {{ crts.$filterString() || '()' }}\r\n </div>\r\n \r\n </div>\r\n \r\n <div class=\"query-builder\">\r\n <ng-template #queryTemplate let-filter=\"filter\" let-groupToRemove=\"groupToRemove\">\r\n \r\n <div class=\"group-card\">\r\n\r\n <div class=\"group-header\">\r\n\r\n <div class=\"logical-operator\">\r\n\r\n <select class=\"form-control pointer\" [formControl]=\"filter.get('logicalOperator')\">\r\n <option value=\"AND\">AND</option>\r\n <option value=\"OR\">OR</option>\r\n </select>\r\n\r\n <!-- Collapse/Expand Button -->\r\n @if (!!filter.value.filters?.length) {\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\"\r\n (click)=\"toggleCollapse(filter)\"\r\n [appTooltip]=\"isCollapsed(filter) ? 'Expand Group' : 'Collapse Group'\">\r\n <i class=\"feather\" [class.feather-plus]=\"isCollapsed(filter)\" [class.feather-minus]=\"!isCollapsed(filter)\"></i>\r\n </button>\r\n }\r\n <div class=\"local-action-buttons\">\r\n <button type=\"button\" class=\"btn btn-success feather-file-plus\"\r\n (click)=\"addCondition(filter)\"\r\n [appTooltip]=\"'Add Condition to this Group'\" [position]=\"'above'\">\r\n </button>\r\n <button type=\"button\" class=\"btn btn-success feather-folder-plus\"\r\n (click)=\"addGroup(filter)\"\r\n [appTooltip]=\"'Add Subgroup to this Group'\" [position]=\"'above'\">\r\n </button>\r\n @if (!!groupToRemove) {\r\n <button type=\"button\" class=\"btn btn-danger feather-trash\"\r\n (click)=\"removeGroup(groupToRemove.group, groupToRemove.index)\"\r\n [appTooltip]=\"'Remove Group'\" [position]=\"'above'\">\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"group-content\">\r\n \r\n @if (!isCollapsed(filter)) {\r\n\r\n @if (!!filter.value.filters?.length) {\r\n <div class=\"filter-list\" formArrayName=\"filters\">\r\n @for (childFilter of filter.get('filters').controls; track $index; let idx = $index) {\r\n <div class=\"filter-row\" [formGroup]=\"childFilter\">\r\n \r\n @if (!childFilter.value.logicalOperator) {\r\n\r\n <div class=\"filter-raw\">\r\n\r\n <div class=\"field-cell\">\r\n <select class=\"form-control\"\r\n [appTooltip]=\"getColLabelTooltip(childFilter)\"\r\n [showAnyway]=\"true\"\r\n formControlName=\"name\">\r\n @for (col of $totalCols(); track $index) {\r\n <option [value]=\"col.field\">{{ col.label || col.field }}</option>\r\n }\r\n </select>\r\n\r\n </div>\r\n\r\n <div class=\"operator-cell\">\r\n <select class=\"form-control\" formControlName=\"relationalOperator\">\r\n @for (op of relationalOperator; track $index) {\r\n <option [value]=\"op\">{{ operatorFriendlyMap[op] || op }}</option>\r\n }\r\n </select>\r\n </div> \r\n\r\n <div class=\"value-cell\">\r\n @if (shouldShowValueControl(childFilter.value.relationalOperator)) {\r\n <core-control-value-only\r\n @fadeSwitch\r\n [$control]=\"resolveControl(childFilter.value.name)!\"\r\n [$form]=\"childFilter\"\r\n [$fieldName]=\"'value'\"\r\n >\r\n </core-control-value-only>\r\n }\r\n </div>\r\n\r\n <div class=\"action-cell\">\r\n <button type=\"button\" class=\"btn btn-danger btn-sm feather-trash-2\"\r\n (click)=\"removeCondition(filter, idx)\"\r\n [appTooltip]=\"'Remove Condition'\">\r\n </button>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"filter-message default\">\r\n <input type=\"text\"\r\n class=\"form-control\"\r\n placeholder=\"Default message...\"\r\n formControlName=\"defaultMessage\" />\r\n </div>\r\n\r\n <div class=\"filter-message english\">\r\n <input type=\"text\"\r\n class=\"form-control\"\r\n placeholder=\"English message...\"\r\n formControlName=\"englishMessage\" />\r\n </div>\r\n\r\n } @else {\r\n <!-- Recursive nested groups -->\r\n <ng-container *ngTemplateOutlet=\"queryTemplate; context: { filter: childFilter, groupToRemove: { group: filter, index: idx } }\"></ng-container>\r\n }\r\n \r\n </div>\r\n }\r\n </div>\r\n }\r\n \r\n\r\n }\r\n\r\n </div>\r\n\r\n </div>\r\n \r\n </ng-template>\r\n \r\n <ng-container\r\n *ngTemplateOutlet=\"queryTemplate; context: { filter: $mainForm(), groupToRemove: null }\">\r\n </ng-container>\r\n \r\n </div>\r\n \r\n </form>\r\n \r\n <div class=\"dev-json-view\">\r\n <pre class=\"json-preview\">{{ crts.$filterFormJsonString() }}</pre>\r\n </div>\r\n \r\n </div>\r\n", styles: [".core-rule-tree-container{display:flex;flex-direction:column;width:100%;overflow-y:auto}.core-rule-tree-container button{border-radius:0}.expression-box{background:#e0f2fe;padding:6px 12px;font-weight:500;font-size:14px}.top-controls{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px;padding:8px}.expression-display{background-color:#e0f2fe;padding:8px 16px;font-family:monospace;font-size:14px;color:#0369a1}.query-builder{flex-grow:1;overflow-y:visible}.json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;border-radius:10px;box-shadow:0 2px 6px #00000014;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;overflow-x:auto;line-height:1.5;margin-top:15px}.core-rule-tree-form{display:flex;flex-direction:column;gap:16px}.top-bar{display:flex;justify-content:space-between;align-items:center}.expression-box{background:#e0f2fe;padding:6px 12px;font-weight:500;font-size:14px;margin-right:8px}.query-builder{display:flex;flex-direction:column;gap:16px}.group-card{padding:15px;background:#f9f9f9;display:flex;flex-direction:column;gap:8px;position:relative}.group-card .group-header{display:block;position:relative}.group-card .logical-operator{display:flex;align-items:center;align-self:flex-start;gap:8px}.group-card .logical-operator select{width:57px;background-color:#fff4ce}.group-card .logical-operator .local-action-buttons{margin-left:auto;display:flex;gap:4px}.group-card .logical-operator:hover .local-action-buttons{display:flex}.filter-list{display:flex;flex-direction:column;gap:8px}.filter-row{margin:8px 0}.filter-row .filter-raw{display:flex;align-items:center;gap:8px}.field-cell,.operator-cell,.value-cell{flex:1}.field-cell select{width:136px;overflow:hidden;text-overflow:ellipsis;text-wrap:nowrap}.filter-message{margin-top:8px}.action-cell{flex-shrink:0}.btn-xs{padding:2px 6px;font-size:10px}.rule-group-container:hover{background-color:#f9f9f9}.group-content{pointer-events:none}.group-content>*{pointer-events:auto}.logical-operator-label{display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;border:1px solid #ced4da;background-color:#fff4ce;color:#495057;font-size:14px;font-weight:500;min-width:100px;width:57px;-webkit-user-select:none;user-select:none}\n"] }]
1020
- }], ctorParameters: () => [{ type: MultiLanguageService }, { type: i0.ChangeDetectorRef }] });
1021
-
1022
625
  class WfActorSelectorComponent extends BaseComponent {
1023
626
  constructor(mls) {
1024
627
  super(mls);
@@ -1380,7 +983,7 @@ class RuleConfigShellComponent {
1380
983
  });
1381
984
  }
1382
985
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: RuleConfigShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1383
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: RuleConfigShellComponent, isStandalone: true, selector: "rule-config-shell", ngImport: i0, template: "<div class=\"rule-config-shell-container\">\r\n\r\n <div class=\"rule-tree-header\">\r\n <div class=\"title\">Rule Conditions</div>\r\n <div class=\"subtitle\">\r\n Define logic that must be satisfied for this step to proceed. These conditions will be evaluated\r\n automatically.\r\n </div>\r\n </div>\r\n\r\n <div class=\"fallback-type-header\">\r\n <div class=\"title\">Fallback Behavior</div>\r\n <div class=\"subtitle\">\r\n\r\n @if ($stepType() !== enumType.BranchCard) {\r\n Choose what happens when the rule condition evaluates to <strong>false (0)</strong> at runtime:\r\n <ul>\r\n <li><strong>Hard Block</strong> Step will be auto-rejected.</li>\r\n <li><strong>Soft Warn</strong> User will see a warning but may continue.</li>\r\n </ul>\r\n\r\n } @else {\r\n When the condition evaluates to <strong>false (0)</strong>, the next branch (by order) will be triggered automatically.\r\n }\r\n </div>\r\n @if ($stepType() !== enumType.BranchCard) {\r\n <core-radio-group\r\n [options$]=\"fallbackTypeOptions$\"\r\n [vertical]=\"true\"\r\n [gapY]=\"8\"\r\n [ngModel]=\"$fallbackType()\"\r\n (ngModelChange)=\"onFallbackTypeChanged($event)\" \r\n />\r\n }\r\n\r\n </div>\r\n\r\n @if ($stepType() !== enumType.BranchCard) {\r\n <div class=\"fallback-message-wrapper\">\r\n <label for=\"fallback-message\" class=\"form-label\">Optional Warning Message</label>\r\n <textarea\r\n id=\"fallback-message\"\r\n class=\"form-control\"\r\n placeholder=\"Enter a message to show when this fallback is triggered...\"\r\n rows=\"3\"\r\n [ngModel]=\"$fallbackMessage()\"\r\n (ngModelChange)=\"onFallbackMessageChanged($event)\"\r\n ></textarea>\r\n </div>\r\n }\r\n\r\n <div class=\"rule-tree-wrapper\">\r\n\r\n <core-rule-tree [$totalCols]=\"wfs.$availableCols()\" [$mainForm]=\"$stepFormGroup()\"\r\n ($jsonEmitter)=\"onRuleTreeJsonChange($event)\" />\r\n\r\n </div>\r\n</div>", styles: [".rule-tree-header{background:linear-gradient(135deg,#f0f8ff,#e6f7ff);border:1px solid #cde4f9;padding:1rem 1.25rem;border-radius:8px;margin-bottom:1rem;box-shadow:0 1px 3px #0040800d}.rule-tree-header .title{font-size:1.1rem;font-weight:600;color:#036;margin-bottom:.25rem}.rule-tree-header .subtitle{font-size:.9rem;color:#444;line-height:1.4}.fallback-type-header{background:linear-gradient(135deg,#fefce8,#fff9c4);border:1px solid #f5e96c;padding:1rem 1.25rem;border-radius:8px;margin-bottom:1rem;box-shadow:0 1px 3px #8060000d}.fallback-type-header .title{font-size:1.05rem;font-weight:600;color:#8a6d00;margin-bottom:.25rem}.fallback-type-header .subtitle{font-size:.9rem;color:#5f4700;line-height:1.5}.fallback-type-header .subtitle ul{padding-left:1.2rem;margin-top:.5rem}.fallback-type-header .subtitle ul li{margin-bottom:.25rem}.fallback-message-wrapper{margin-top:1rem}.fallback-message-wrapper .form-label{font-weight:500;color:#444;margin-bottom:.5rem;display:inline-block}.fallback-message-wrapper textarea.form-control{width:100%;resize:vertical;min-height:80px;font-family:system-ui,sans-serif;font-size:14px;padding:.5rem .75rem;border-radius:6px;background:#fefefe}.rule-tree-wrapper{margin-top:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CoreRuleTreeComponent, selector: "core-rule-tree", inputs: ["$totalCols", "$mainForm", "$filterStringInput", "$expressionInput"], outputs: ["$jsonEmitter"] }, { kind: "component", type: CoreRadioGroupComponent, selector: "core-radio-group", inputs: ["options$", "vertical", "columnCount", "gapY", "defaultValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
986
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: RuleConfigShellComponent, isStandalone: true, selector: "rule-config-shell", ngImport: i0, template: "<div class=\"rule-config-shell-container\">\r\n\r\n <div class=\"rule-tree-header\">\r\n <div class=\"title\">Rule Conditions</div>\r\n <div class=\"subtitle\">\r\n Define logic that must be satisfied for this step to proceed. These conditions will be evaluated\r\n automatically.\r\n </div>\r\n </div>\r\n\r\n <div class=\"fallback-type-header\">\r\n <div class=\"title\">Fallback Behavior</div>\r\n <div class=\"subtitle\">\r\n\r\n @if ($stepType() !== enumType.BranchCard) {\r\n Choose what happens when the rule condition evaluates to <strong>false (0)</strong> at runtime:\r\n <ul>\r\n <li><strong>Hard Block</strong> Step will be auto-rejected.</li>\r\n <li><strong>Soft Warn</strong> User will see a warning but may continue.</li>\r\n </ul>\r\n\r\n } @else {\r\n When the condition evaluates to <strong>false (0)</strong>, the next branch (by order) will be triggered automatically.\r\n }\r\n </div>\r\n @if ($stepType() !== enumType.BranchCard) {\r\n <core-radio-group\r\n [options$]=\"fallbackTypeOptions$\"\r\n [vertical]=\"true\"\r\n [gapY]=\"8\"\r\n [ngModel]=\"$fallbackType()\"\r\n (ngModelChange)=\"onFallbackTypeChanged($event)\" \r\n />\r\n }\r\n\r\n </div>\r\n\r\n @if ($stepType() !== enumType.BranchCard) {\r\n <div class=\"fallback-message-wrapper\">\r\n <label for=\"fallback-message\" class=\"form-label\">Optional Warning Message</label>\r\n <textarea\r\n id=\"fallback-message\"\r\n class=\"form-control\"\r\n placeholder=\"Enter a message to show when this fallback is triggered...\"\r\n rows=\"3\"\r\n [ngModel]=\"$fallbackMessage()\"\r\n (ngModelChange)=\"onFallbackMessageChanged($event)\"\r\n ></textarea>\r\n </div>\r\n }\r\n\r\n <div class=\"rule-tree-wrapper\">\r\n\r\n <core-rule-tree [$totalCols]=\"wfs.$availableCols()\" [$mainForm]=\"$stepFormGroup()\"\r\n ($jsonEmitter)=\"onRuleTreeJsonChange($event)\" />\r\n\r\n </div>\r\n</div>", styles: [".rule-tree-header{background:linear-gradient(135deg,#f0f8ff,#e6f7ff);border:1px solid #cde4f9;padding:1rem 1.25rem;border-radius:8px;margin-bottom:1rem;box-shadow:0 1px 3px #0040800d}.rule-tree-header .title{font-size:1.1rem;font-weight:600;color:#036;margin-bottom:.25rem}.rule-tree-header .subtitle{font-size:.9rem;color:#444;line-height:1.4}.fallback-type-header{background:linear-gradient(135deg,#fefce8,#fff9c4);border:1px solid #f5e96c;padding:1rem 1.25rem;border-radius:8px;margin-bottom:1rem;box-shadow:0 1px 3px #8060000d}.fallback-type-header .title{font-size:1.05rem;font-weight:600;color:#8a6d00;margin-bottom:.25rem}.fallback-type-header .subtitle{font-size:.9rem;color:#5f4700;line-height:1.5}.fallback-type-header .subtitle ul{padding-left:1.2rem;margin-top:.5rem}.fallback-type-header .subtitle ul li{margin-bottom:.25rem}.fallback-message-wrapper{margin-top:1rem}.fallback-message-wrapper .form-label{font-weight:500;color:#444;margin-bottom:.5rem;display:inline-block}.fallback-message-wrapper textarea.form-control{width:100%;resize:vertical;min-height:80px;font-family:system-ui,sans-serif;font-size:14px;padding:.5rem .75rem;border-radius:6px;background:#fefefe}.rule-tree-wrapper{margin-top:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CoreRuleTreeComponent, selector: "core-rule-tree", inputs: ["$totalCols", "$mainForm", "$filterStringInput", "$expressionInput", "$form", "$field"], outputs: ["$jsonEmitter"] }, { kind: "component", type: CoreRadioGroupComponent, selector: "core-radio-group", inputs: ["options$", "vertical", "columnCount", "gapY", "defaultValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1384
987
  }
1385
988
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: RuleConfigShellComponent, decorators: [{
1386
989
  type: Component,
@@ -2272,6 +1875,280 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
2272
1875
  ], template: "<div class=\"wf-process-design-container\">\r\n\r\n @if (!!wfs.$currentFlow()) {\r\n <wf-workflow-canvas></wf-workflow-canvas>\r\n }\r\n\r\n @if ($loading()) {\r\n <core-toast-loading></core-toast-loading>\r\n }\r\n</div>" }]
2273
1876
  }], ctorParameters: () => [{ type: MultiLanguageService }, { type: i1$1.ActivatedRoute }] });
2274
1877
 
1878
+ class WfDelegationComponent extends BaseEditComponent {
1879
+ constructor(dialogService) {
1880
+ super(dialogService);
1881
+ this.dialogService = dialogService;
1882
+ this.wfs = inject(CoreWorkflowService);
1883
+ this.alertService = inject(AlertService);
1884
+ this.fds = inject(CoreFormDesignService);
1885
+ this.cdr = inject(ChangeDetectorRef);
1886
+ this.cdts = inject(CoreDatetimeService);
1887
+ this.appService = inject(AppService);
1888
+ this.timezoneOptions$ = new BehaviorSubject([]);
1889
+ this.injector = inject(Injector);
1890
+ this.cfs = inject(CoreFormService);
1891
+ this.router = inject(Router);
1892
+ this.route = inject(ActivatedRoute);
1893
+ this.loading = false;
1894
+ this.entityTable = "WF_WORKFLOW";
1895
+ this.subscriptions = [];
1896
+ this.sections = [
1897
+ {
1898
+ rows: [
1899
+ [
1900
+ {
1901
+ flexSize: 0,
1902
+ label: "UI_ENTITY_FIELD_CAPTION_COMMON_ID",
1903
+ field: 'id',
1904
+ value: null,
1905
+ hidden: true,
1906
+ controlType: EnumFormBaseContolType.TEXTBOX,
1907
+ },
1908
+ {
1909
+ flexSize: 12,
1910
+ label: "Delegation rows",
1911
+ field: 'delegationRows',
1912
+ value: [],
1913
+ controlType: EnumFormBaseContolType.FORM_ARRAY,
1914
+ type: 'object',
1915
+ formArraySections: [
1916
+ {
1917
+ rows: [
1918
+ [
1919
+ {
1920
+ field: 'delegationId',
1921
+ label: 'delegationId',
1922
+ value: '',
1923
+ flexSize: 0,
1924
+ controlType: EnumFormBaseContolType.TEXTBOX,
1925
+ hidden: true,
1926
+ disabled: true
1927
+ },
1928
+ {
1929
+ field: 'lastUsedAtUtc',
1930
+ label: 'lastUsedAtUtc',
1931
+ value: null,
1932
+ flexSize: 0,
1933
+ controlType: EnumFormBaseContolType.TEXTBOX,
1934
+ hidden: true,
1935
+ disabled: true
1936
+ },
1937
+ {
1938
+ field: 'fromPositionId',
1939
+ label: 'From position',
1940
+ boundFrom: 'id',
1941
+ shownFrom: 'name',
1942
+ seekerVerifyIgnore: true,
1943
+ value: null,
1944
+ flexSize: 2,
1945
+ controlType: EnumFormBaseContolType.SEEKER,
1946
+ seekerSourceType: EnumCoreFormControlSeekerSourceType.POSITION_SEEK,
1947
+ selfEnrichmentApiDriven: true,
1948
+ selfEnrichmentApi: '/api/BaseHuPosition/GetById',
1949
+ selfEnrichmentHttpVerb: 'HttpGet',
1950
+ selfEnrichmentShownFrom: 'name',
1951
+ validators: [
1952
+ {
1953
+ name: 'required',
1954
+ validator: Validators.required,
1955
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_REQUIRED
1956
+ }
1957
+ ]
1958
+ },
1959
+ {
1960
+ field: 'toPositionId',
1961
+ label: 'To position',
1962
+ boundFrom: 'id',
1963
+ shownFrom: 'name',
1964
+ seekerVerifyIgnore: true,
1965
+ value: null,
1966
+ flexSize: 2,
1967
+ controlType: EnumFormBaseContolType.SEEKER,
1968
+ seekerSourceType: EnumCoreFormControlSeekerSourceType.POSITION_SEEK,
1969
+ selfEnrichmentApiDriven: true,
1970
+ selfEnrichmentApi: '/api/BaseHuPosition/GetById',
1971
+ selfEnrichmentHttpVerb: 'HttpGet',
1972
+ selfEnrichmentShownFrom: 'name',
1973
+ validators: [
1974
+ {
1975
+ name: 'required',
1976
+ validator: Validators.required,
1977
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_REQUIRED
1978
+ }
1979
+ ]
1980
+ },
1981
+ {
1982
+ field: 'conditionJson',
1983
+ label: 'Condition',
1984
+ value: "",
1985
+ flexSize: 2,
1986
+ controlType: EnumFormBaseContolType.RULE_SET,
1987
+ },
1988
+ {
1989
+ field: 'vfUtc',
1990
+ label: 'Valid from',
1991
+ value: null,
1992
+ flexSize: 2,
1993
+ controlType: EnumFormBaseContolType.DATEPICKER,
1994
+ validators: [
1995
+ {
1996
+ name: 'required',
1997
+ validator: Validators.required,
1998
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_REQUIRED
1999
+ }
2000
+ ]
2001
+ },
2002
+ {
2003
+ field: 'vtUtc',
2004
+ label: 'Valid to (not included)',
2005
+ value: null,
2006
+ flexSize: 2,
2007
+ controlType: EnumFormBaseContolType.DATEPICKER,
2008
+ },
2009
+ {
2010
+ field: 'timezoneId',
2011
+ label: 'Timezone',
2012
+ value: Intl.DateTimeFormat().resolvedOptions().timeZone,
2013
+ flexSize: 2,
2014
+ controlType: EnumFormBaseContolType.DROPDOWN,
2015
+ dropdownOptions$: this.timezoneOptions$,
2016
+ getByIdObject$: new BehaviorSubject({}),
2017
+ shownFrom: 'text',
2018
+ validators: [
2019
+ {
2020
+ name: 'required',
2021
+ validator: Validators.required,
2022
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_REQUIRED
2023
+ }
2024
+ ]
2025
+ },
2026
+ ]
2027
+ ]
2028
+ }
2029
+ ]
2030
+ },
2031
+ ]
2032
+ ]
2033
+ }
2034
+ ];
2035
+ if (!this.captionCode) {
2036
+ this.captionCode = "UI_COMPONENT_TITLE_WF_WORKFLOW_GROUP";
2037
+ }
2038
+ this.crud = {
2039
+ c: '/api/WfWorkflow/Create',
2040
+ r: '/api/WfWorkflow/GetByIdWithAfInstance',
2041
+ u: '/api/WfWorkflow/Update',
2042
+ d: '/api/WfWorkflow/Delete',
2043
+ };
2044
+ // const groupIdString = this.route.snapshot.queryParamMap.get('groupId');
2045
+ // if (!!groupIdString) {
2046
+ // const groupId = Number(groupIdString);
2047
+ // if (this.wfs.$allGroups().length) {
2048
+ // this.wfs.$currentGroup.set(this.wfs.$allGroups().filter(g => g.id === groupId)[0])
2049
+ // } else {
2050
+ // //this.wfs.refresh('/api/WfWorkflowGroup/GetAllWithWorkflows', '', groupId);
2051
+ // }
2052
+ // } else if (this.wfs.$designActiveTab() === 1) {
2053
+ // this.alertService.warn("The Query Params lack of groupId", alertOptions);
2054
+ // }
2055
+ effect(() => {
2056
+ const tzs = this.cdts.$timeZones();
2057
+ const ops = [];
2058
+ tzs.forEach(tz => {
2059
+ ops.push({
2060
+ value: tz, text: tz
2061
+ });
2062
+ });
2063
+ this.timezoneOptions$.next(ops);
2064
+ });
2065
+ }
2066
+ ngAfterViewInit() {
2067
+ setTimeout(() => {
2068
+ });
2069
+ }
2070
+ // private updateCurrentFlow(values: any) {
2071
+ // if (!values) return;
2072
+ // this.wfs.$currentFlow.update(currentFlow => {
2073
+ // if (!currentFlow) {
2074
+ // return null
2075
+ // } else {
2076
+ // Object.keys(values).forEach((key: string) => {
2077
+ // (currentFlow as any)[key] = values[key]
2078
+ // })
2079
+ // return { ...currentFlow }
2080
+ // }
2081
+ // })
2082
+ // }
2083
+ // private updateCurrentFlowByKey(key: string, value: any) {
2084
+ // this.wfs.$currentFlow.update(currentFlow => {
2085
+ // if (!currentFlow) {
2086
+ // return null
2087
+ // } else {
2088
+ // (currentFlow as any)[key] = value
2089
+ // return { ...currentFlow }
2090
+ // }
2091
+ // })
2092
+ // }
2093
+ // private updateCurrentAfInstance(formValue: any): void {
2094
+ // console.log("[WfBasicInfoComponent][updateCurrentAfInstance]: $afInstance is being updated");
2095
+ // this.fds.$afInstance.update(current => {
2096
+ // if (!current) return current;
2097
+ // return {
2098
+ // ...current,
2099
+ // name: formValue.name,
2100
+ // code: formValue.code
2101
+ // };
2102
+ // });
2103
+ // }
2104
+ onFormCreated(e) {
2105
+ this.wfs.delegationForm = e;
2106
+ e.valueChanges.subscribe(x => {
2107
+ this.wfs.$currentDelegationJson.set(JSON.stringify(x));
2108
+ // this.updateCurrentFlow(x);
2109
+ // this.updateCurrentAfInstance(x);
2110
+ });
2111
+ runInInjectionContext(this.injector, () => {
2112
+ effect(() => {
2113
+ const form = this.wfs.delegationForm;
2114
+ if (form) {
2115
+ this.wfs.$currentDelegationJson.set(JSON.stringify(form.getRawValue()));
2116
+ }
2117
+ });
2118
+ });
2119
+ }
2120
+ /* To allow form to be deactivated */
2121
+ onFormReinit(e) {
2122
+ this.wfs.$initialDelegationJson.set(e);
2123
+ this.formInitStringValue = e;
2124
+ }
2125
+ onSubmitSuccess(e) {
2126
+ //this.wfs.refresh(undefined, '');
2127
+ this.router.navigate([{ outlets: { workflowAux: null } }], { relativeTo: this.route.parent });
2128
+ }
2129
+ onGotById(e) {
2130
+ //this.wfs.emailTemplatesForm.patchValue(e);
2131
+ if (e.uiDelegation) {
2132
+ this.cfs.syncAllFormArraysBeforePatch(this.wfs.delegationForm, e.uiDelegation);
2133
+ this.wfs.delegationForm.patchValue(e.uiDelegation);
2134
+ }
2135
+ }
2136
+ ngOnDestroy() {
2137
+ this.wfs.$initialDelegationJson.set('{}');
2138
+ this.subscriptions.map(x => x?.unsubscribe());
2139
+ }
2140
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: WfDelegationComponent, deps: [{ token: DialogService }], target: i0.ɵɵFactoryTarget.Component }); }
2141
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: WfDelegationComponent, isStandalone: true, selector: "wf-delegation", usesInheritance: true, ngImport: i0, template: "<div class=\"wf-delegation-container\">\r\n\r\n <div class=\"container container-fluid\">\r\n\r\n <core-page-edit\r\n [normalMode]=\"true\"\r\n [captionCode]=\"''\"\r\n [sections]=\"sections\" [crud]=\"crud\" [entityTable]=\"entityTable\" [hasIdOfStringType]=\"true\"\r\n [stayAfterSubmit]=\"true\" (onFormCreated)=\"onFormCreated($event)\"\r\n [idAsInput]=\"true\"\r\n [id]=\"wfs.$currentFlow()?.id\"\r\n [hideButtons]=\"true\"\r\n [checkError$]=\"wfs.basicInfoFormCheckError$\"\r\n (onGotById)=\"onGotById($event)\"\r\n (onInitialValueStringReady)=\"onFormReinit($event)\"\r\n (onSubmitSuccess)=\"onSubmitSuccess($event)\">\r\n </core-page-edit>\r\n\r\n </div>\r\n\r\n</div>\r\n\r\n@if (loading) {\r\n<app-fullscreen-modal-loader></app-fullscreen-modal-loader>\r\n}", styles: [""], dependencies: [{ kind: "component", type: CorePageEditComponent, selector: "core-page-edit", inputs: ["stayAfterSubmit", "width", "entityTable", "hasIdOfStringType", "captionCode", "leftInputSections", "leftInputSectionsFlexSize", "sections", "normalMode", "bottomTemplateRef", "autoGetByIdOff", "autoSubmitLogicOff", "autoCancelLogicOff", "customFormButtonItems", "mixedMode", "checkError$", "showSaveButton", "disableSaveButton", "disableCancelButton", "forceListRefreshOnCreateOrUpdate", "wrapEachSectionInAccordion", "gridMode", "crud", "entityUniqueIndexs", "idAsInput", "id", "hideButtons"], outputs: ["submitLogic", "onFormCreated", "onSubmitSuccess", "onButtonClick", "cancelLogic", "onGotById", "onInitialValueStringReady"] }] }); }
2142
+ }
2143
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: WfDelegationComponent, decorators: [{
2144
+ type: Component,
2145
+ args: [{ selector: 'wf-delegation', imports: [
2146
+ CorePageEditComponent,
2147
+ NgTemplateOutlet,
2148
+ CoreRuleTreeComponent
2149
+ ], template: "<div class=\"wf-delegation-container\">\r\n\r\n <div class=\"container container-fluid\">\r\n\r\n <core-page-edit\r\n [normalMode]=\"true\"\r\n [captionCode]=\"''\"\r\n [sections]=\"sections\" [crud]=\"crud\" [entityTable]=\"entityTable\" [hasIdOfStringType]=\"true\"\r\n [stayAfterSubmit]=\"true\" (onFormCreated)=\"onFormCreated($event)\"\r\n [idAsInput]=\"true\"\r\n [id]=\"wfs.$currentFlow()?.id\"\r\n [hideButtons]=\"true\"\r\n [checkError$]=\"wfs.basicInfoFormCheckError$\"\r\n (onGotById)=\"onGotById($event)\"\r\n (onInitialValueStringReady)=\"onFormReinit($event)\"\r\n (onSubmitSuccess)=\"onSubmitSuccess($event)\">\r\n </core-page-edit>\r\n\r\n </div>\r\n\r\n</div>\r\n\r\n@if (loading) {\r\n<app-fullscreen-modal-loader></app-fullscreen-modal-loader>\r\n}" }]
2150
+ }], ctorParameters: () => [{ type: DialogService }] });
2151
+
2275
2152
  const EMAIL_ICON = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-mail"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>';
2276
2153
  const TEMPLATE_TYPES = [
2277
2154
  { key: 'submit', caption: 'UI_WORKFLOW_EMAIL_TEMPLATE_SECTION_SUBMIT' },
@@ -2295,7 +2172,7 @@ class WfEmailTemplatesComponent extends BaseEditComponent {
2295
2172
  this.as = inject(AlertService);
2296
2173
  this.$wysGroups = computed(() => this.fds.extractWysGroups(this.fds.$placeholderSections()));
2297
2174
  this.mode$ = new BehaviorSubject(EnumCorePageEditMode.CREATE);
2298
- this.availableTokens = ['webappStatusUrl', 'portalStatusUrl', 'webappReactUrl', 'portalReactUrl', 'workflowName', 'firstActorFullName', 'submitterFullName', 'actorFullName'];
2175
+ this.availableTokens = ['webappStatusUrl', 'portalStatusUrl', 'webappReactUrl', 'portalReactUrl', 'workflowName', 'firstActorFullName', 'firstActorManagerFullName', 'submitterFullName', 'actorFullName'];
2299
2176
  this.loading = false;
2300
2177
  this.entityTable = "WF_WORKFLOW";
2301
2178
  this.subscriptions = [];
@@ -2475,7 +2352,7 @@ class DesignWrapperComponent {
2475
2352
  }
2476
2353
  }
2477
2354
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DesignWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2478
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: DesignWrapperComponent, isStandalone: true, selector: "design-wrapper", ngImport: i0, template: "<current-header></current-header>\r\n\r\n<div class=\"all-tabs\" [hotKeys]=\"['F7', 'Escape']\">\r\n\r\n <div class=\"tab-content basic-info\" [class.d-none]=\"wfs.$designActiveTab() !== 1\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 1 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-basic-info></wf-basic-info>\r\n </div>\r\n\r\n <div class=\"tab-content form-design\" [class.d-none]=\"wfs.$designActiveTab() !== 2\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 2 ? 'visible' : 'hidden'\"\r\n >\r\n <core-form-design [$idAsInput]=\"true\" [$id]=\"wfs.$currentFlow()?.afInstanceId\" />\r\n </div>\r\n\r\n <div class=\"tab-content process-design\" [class.d-none]=\"wfs.$designActiveTab() !== 3\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 3 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-process-design></wf-process-design>\r\n </div>\r\n\r\n <div class=\"tab-content more\" [class.d-none]=\"wfs.$designActiveTab() !== 4\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 4 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-email-templates></wf-email-templates>\r\n </div>\r\n\r\n\r\n</div>\r\n\r\n<router-outlet name=\"preview\" [hotKeys]=\"['Escape']\"></router-outlet>\r\n\r\n<div class=\"state\" [class.shown]=\"$showInitialState()\"\r\n [ngStyle]=\"{ width: !!(ns.wideMode$ | async) ? 'calc(100vw - 280px - 15px)' : 'calc(100vw - 66px - 15px)' }\">\r\n\r\n <div class=\"scroll-container\">\r\n\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"debugClick()\">FormDesign Compare</button>\r\n\r\n <div class=\"tab-info\">\r\n\r\n <div class=\"value-caption\">initialBasicInfoJson:</div>\r\n <pre [class.d-none]=\"!wfs.$initialBasicInfoJson()\">{{ wfs.$initialBasicInfoJson() }}</pre>\r\n\r\n <div class=\"value-caption\">currentBasicInfoJson:</div>\r\n <pre [class.d-none]=\"!wfs.$currentBasicInfoJson()\">{{ wfs.$currentBasicInfoJson() }}</pre>\r\n\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialFormDesignJson:</div>\r\n <pre><code class=\"lang-json\">{{ wfs.$initialFormDesignJson() }}</code></pre>\r\n\r\n <div class=\"value-caption\">currentFormDesignJson:</div>\r\n <pre><code class=\"lang-json\">{{ wfs.$currentFormDesignJson() }}</code></pre>\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialProcessDesignJson:</div>\r\n <pre>{{ wfs.$initialProcessDesignJson() }}</pre>\r\n\r\n <div class=\"value-caption\">currentProcessDesignJson:</div>\r\n <pre>{{ wfs.$currentProcessDesignJson() }}</pre>\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialEmailTemplatesJson:</div>\r\n <pre>{{ wfs.$initialEmailTemplatesJson() }}</pre>\r\n </div>\r\n\r\n </div>\r\n\r\n</div>", styles: [".all-tabs .tab-content.more{display:flex;position:relative;width:100%;height:500px;justify-content:center}.all-tabs .tab-content.more>*{width:100%;max-width:1000px}.state{background-color:#fff;height:50vh;display:block;position:fixed;z-index:9;bottom:-50vh;box-shadow:#0000001a 0 10px 50px;transition:opacity bottom .5s ease-out}.state.shown{bottom:0}.state .scroll-container{position:relative;padding:15px;height:50vh;overflow-y:auto}.state .scroll-container .tab-info{padding:15ox;box-shadow:#0000001a 0 10px 50px;margin-bottom:50px}.state .scroll-container .tab-info .value-caption{padding-left:24px;font-family:Fira Code,monospace;font-size:.85rem;font-weight:700}.state .scroll-container .tab-info pre{background-color:#fff;color:#333;padding:1rem 1.5rem;font-family:Fira Code,monospace;font-size:.85rem;overflow-x:auto;line-height:1.5;width:100%;margin:0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: WfBasicInfoComponent, selector: "wf-basic-info", inputs: ["captionCode"] }, { kind: "component", type: CoreFormDesignComponent, selector: "core-form-design", inputs: ["$idAsInput", "$id"] }, { kind: "component", type: WfProcessDesignComponent, selector: "wf-process-design" }, { kind: "component", type: WfEmailTemplatesComponent, selector: "wf-email-templates", inputs: ["captionCode"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: HotKeysDirective, selector: "[hotKeys]", inputs: ["hotKeys"] }, { kind: "component", type: CurrentHeaderComponent, selector: "current-header" }], animations: [
2355
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: DesignWrapperComponent, isStandalone: true, selector: "design-wrapper", ngImport: i0, template: "<current-header></current-header>\r\n\r\n<div class=\"all-tabs\" [hotKeys]=\"['F7', 'Escape']\">\r\n\r\n <div class=\"tab-content basic-info\" [class.d-none]=\"wfs.$designActiveTab() !== 1\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 1 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-basic-info></wf-basic-info>\r\n </div>\r\n\r\n <div class=\"tab-content form-design\" [class.d-none]=\"wfs.$designActiveTab() !== 2\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 2 ? 'visible' : 'hidden'\"\r\n >\r\n <core-form-design [$idAsInput]=\"true\" [$id]=\"wfs.$currentFlow()?.afInstanceId\" />\r\n </div>\r\n\r\n <div class=\"tab-content process-design\" [class.d-none]=\"wfs.$designActiveTab() !== 3\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 3 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-process-design></wf-process-design>\r\n </div>\r\n\r\n <div class=\"tab-content delegation\" [class.d-none]=\"wfs.$designActiveTab() !== 4\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 4 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-delegation />\r\n </div>\r\n\r\n <div class=\"tab-content more\" [class.d-none]=\"wfs.$designActiveTab() !== 5\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 5 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-email-templates></wf-email-templates>\r\n </div>\r\n\r\n\r\n</div>\r\n\r\n<router-outlet name=\"preview\" [hotKeys]=\"['Escape']\"></router-outlet>\r\n\r\n<div class=\"state\" [class.shown]=\"$showInitialState()\"\r\n [ngStyle]=\"{ width: !!(ns.wideMode$ | async) ? 'calc(100vw - 280px - 15px)' : 'calc(100vw - 66px - 15px)' }\">\r\n\r\n <div class=\"scroll-container\">\r\n\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"debugClick()\">FormDesign Compare</button>\r\n\r\n <div class=\"tab-info\">\r\n\r\n <div class=\"value-caption\">initialBasicInfoJson:</div>\r\n <pre [class.d-none]=\"!wfs.$initialBasicInfoJson()\">{{ wfs.$initialBasicInfoJson() }}</pre>\r\n\r\n <div class=\"value-caption\">currentBasicInfoJson:</div>\r\n <pre [class.d-none]=\"!wfs.$currentBasicInfoJson()\">{{ wfs.$currentBasicInfoJson() }}</pre>\r\n\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialFormDesignJson:</div>\r\n <pre><code class=\"lang-json\">{{ wfs.$initialFormDesignJson() }}</code></pre>\r\n\r\n <div class=\"value-caption\">currentFormDesignJson:</div>\r\n <pre><code class=\"lang-json\">{{ wfs.$currentFormDesignJson() }}</code></pre>\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialProcessDesignJson:</div>\r\n <pre>{{ wfs.$initialProcessDesignJson() }}</pre>\r\n\r\n <div class=\"value-caption\">currentProcessDesignJson:</div>\r\n <pre>{{ wfs.$currentProcessDesignJson() }}</pre>\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialEmailTemplatesJson:</div>\r\n <pre>{{ wfs.$initialEmailTemplatesJson() }}</pre>\r\n </div>\r\n\r\n </div>\r\n\r\n</div>", styles: [".all-tabs .tab-content.more{display:flex;position:relative;width:100%;height:500px;justify-content:center}.all-tabs .tab-content.more>*{width:100%;max-width:1000px}.state{background-color:#fff;height:50vh;display:block;position:fixed;z-index:9;bottom:-50vh;box-shadow:#0000001a 0 10px 50px;transition:opacity bottom .5s ease-out}.state.shown{bottom:0}.state .scroll-container{position:relative;padding:15px;height:50vh;overflow-y:auto}.state .scroll-container .tab-info{padding:15ox;box-shadow:#0000001a 0 10px 50px;margin-bottom:50px}.state .scroll-container .tab-info .value-caption{padding-left:24px;font-family:Fira Code,monospace;font-size:.85rem;font-weight:700}.state .scroll-container .tab-info pre{background-color:#fff;color:#333;padding:1rem 1.5rem;font-family:Fira Code,monospace;font-size:.85rem;overflow-x:auto;line-height:1.5;width:100%;margin:0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: WfBasicInfoComponent, selector: "wf-basic-info", inputs: ["captionCode"] }, { kind: "component", type: CoreFormDesignComponent, selector: "core-form-design", inputs: ["$idAsInput", "$id"] }, { kind: "component", type: WfProcessDesignComponent, selector: "wf-process-design" }, { kind: "component", type: WfDelegationComponent, selector: "wf-delegation" }, { kind: "component", type: WfEmailTemplatesComponent, selector: "wf-email-templates", inputs: ["captionCode"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: HotKeysDirective, selector: "[hotKeys]", inputs: ["hotKeys"] }, { kind: "component", type: CurrentHeaderComponent, selector: "current-header" }], animations: [
2479
2356
  trigger('fadeSwitch', [
2480
2357
  state('visible', style({ opacity: 1 })),
2481
2358
  state('hidden', style({ opacity: 0 })),
@@ -2492,6 +2369,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
2492
2369
  WfBasicInfoComponent,
2493
2370
  CoreFormDesignComponent,
2494
2371
  WfProcessDesignComponent,
2372
+ WfDelegationComponent,
2495
2373
  WfEmailTemplatesComponent,
2496
2374
  NgStyle,
2497
2375
  AsyncPipe,
@@ -2504,8 +2382,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
2504
2382
  transition('hidden => visible', [animate('250ms ease-in')]),
2505
2383
  transition('visible => hidden', [animate('150ms ease-out')]),
2506
2384
  ])
2507
- ], template: "<current-header></current-header>\r\n\r\n<div class=\"all-tabs\" [hotKeys]=\"['F7', 'Escape']\">\r\n\r\n <div class=\"tab-content basic-info\" [class.d-none]=\"wfs.$designActiveTab() !== 1\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 1 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-basic-info></wf-basic-info>\r\n </div>\r\n\r\n <div class=\"tab-content form-design\" [class.d-none]=\"wfs.$designActiveTab() !== 2\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 2 ? 'visible' : 'hidden'\"\r\n >\r\n <core-form-design [$idAsInput]=\"true\" [$id]=\"wfs.$currentFlow()?.afInstanceId\" />\r\n </div>\r\n\r\n <div class=\"tab-content process-design\" [class.d-none]=\"wfs.$designActiveTab() !== 3\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 3 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-process-design></wf-process-design>\r\n </div>\r\n\r\n <div class=\"tab-content more\" [class.d-none]=\"wfs.$designActiveTab() !== 4\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 4 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-email-templates></wf-email-templates>\r\n </div>\r\n\r\n\r\n</div>\r\n\r\n<router-outlet name=\"preview\" [hotKeys]=\"['Escape']\"></router-outlet>\r\n\r\n<div class=\"state\" [class.shown]=\"$showInitialState()\"\r\n [ngStyle]=\"{ width: !!(ns.wideMode$ | async) ? 'calc(100vw - 280px - 15px)' : 'calc(100vw - 66px - 15px)' }\">\r\n\r\n <div class=\"scroll-container\">\r\n\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"debugClick()\">FormDesign Compare</button>\r\n\r\n <div class=\"tab-info\">\r\n\r\n <div class=\"value-caption\">initialBasicInfoJson:</div>\r\n <pre [class.d-none]=\"!wfs.$initialBasicInfoJson()\">{{ wfs.$initialBasicInfoJson() }}</pre>\r\n\r\n <div class=\"value-caption\">currentBasicInfoJson:</div>\r\n <pre [class.d-none]=\"!wfs.$currentBasicInfoJson()\">{{ wfs.$currentBasicInfoJson() }}</pre>\r\n\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialFormDesignJson:</div>\r\n <pre><code class=\"lang-json\">{{ wfs.$initialFormDesignJson() }}</code></pre>\r\n\r\n <div class=\"value-caption\">currentFormDesignJson:</div>\r\n <pre><code class=\"lang-json\">{{ wfs.$currentFormDesignJson() }}</code></pre>\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialProcessDesignJson:</div>\r\n <pre>{{ wfs.$initialProcessDesignJson() }}</pre>\r\n\r\n <div class=\"value-caption\">currentProcessDesignJson:</div>\r\n <pre>{{ wfs.$currentProcessDesignJson() }}</pre>\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialEmailTemplatesJson:</div>\r\n <pre>{{ wfs.$initialEmailTemplatesJson() }}</pre>\r\n </div>\r\n\r\n </div>\r\n\r\n</div>", styles: [".all-tabs .tab-content.more{display:flex;position:relative;width:100%;height:500px;justify-content:center}.all-tabs .tab-content.more>*{width:100%;max-width:1000px}.state{background-color:#fff;height:50vh;display:block;position:fixed;z-index:9;bottom:-50vh;box-shadow:#0000001a 0 10px 50px;transition:opacity bottom .5s ease-out}.state.shown{bottom:0}.state .scroll-container{position:relative;padding:15px;height:50vh;overflow-y:auto}.state .scroll-container .tab-info{padding:15ox;box-shadow:#0000001a 0 10px 50px;margin-bottom:50px}.state .scroll-container .tab-info .value-caption{padding-left:24px;font-family:Fira Code,monospace;font-size:.85rem;font-weight:700}.state .scroll-container .tab-info pre{background-color:#fff;color:#333;padding:1rem 1.5rem;font-family:Fira Code,monospace;font-size:.85rem;overflow-x:auto;line-height:1.5;width:100%;margin:0;white-space:pre-wrap;word-break:break-word}\n"] }]
2385
+ ], template: "<current-header></current-header>\r\n\r\n<div class=\"all-tabs\" [hotKeys]=\"['F7', 'Escape']\">\r\n\r\n <div class=\"tab-content basic-info\" [class.d-none]=\"wfs.$designActiveTab() !== 1\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 1 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-basic-info></wf-basic-info>\r\n </div>\r\n\r\n <div class=\"tab-content form-design\" [class.d-none]=\"wfs.$designActiveTab() !== 2\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 2 ? 'visible' : 'hidden'\"\r\n >\r\n <core-form-design [$idAsInput]=\"true\" [$id]=\"wfs.$currentFlow()?.afInstanceId\" />\r\n </div>\r\n\r\n <div class=\"tab-content process-design\" [class.d-none]=\"wfs.$designActiveTab() !== 3\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 3 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-process-design></wf-process-design>\r\n </div>\r\n\r\n <div class=\"tab-content delegation\" [class.d-none]=\"wfs.$designActiveTab() !== 4\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 4 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-delegation />\r\n </div>\r\n\r\n <div class=\"tab-content more\" [class.d-none]=\"wfs.$designActiveTab() !== 5\"\r\n [@fadeSwitch]=\"wfs.$designActiveTab() === 5 ? 'visible' : 'hidden'\"\r\n >\r\n <wf-email-templates></wf-email-templates>\r\n </div>\r\n\r\n\r\n</div>\r\n\r\n<router-outlet name=\"preview\" [hotKeys]=\"['Escape']\"></router-outlet>\r\n\r\n<div class=\"state\" [class.shown]=\"$showInitialState()\"\r\n [ngStyle]=\"{ width: !!(ns.wideMode$ | async) ? 'calc(100vw - 280px - 15px)' : 'calc(100vw - 66px - 15px)' }\">\r\n\r\n <div class=\"scroll-container\">\r\n\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"debugClick()\">FormDesign Compare</button>\r\n\r\n <div class=\"tab-info\">\r\n\r\n <div class=\"value-caption\">initialBasicInfoJson:</div>\r\n <pre [class.d-none]=\"!wfs.$initialBasicInfoJson()\">{{ wfs.$initialBasicInfoJson() }}</pre>\r\n\r\n <div class=\"value-caption\">currentBasicInfoJson:</div>\r\n <pre [class.d-none]=\"!wfs.$currentBasicInfoJson()\">{{ wfs.$currentBasicInfoJson() }}</pre>\r\n\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialFormDesignJson:</div>\r\n <pre><code class=\"lang-json\">{{ wfs.$initialFormDesignJson() }}</code></pre>\r\n\r\n <div class=\"value-caption\">currentFormDesignJson:</div>\r\n <pre><code class=\"lang-json\">{{ wfs.$currentFormDesignJson() }}</code></pre>\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialProcessDesignJson:</div>\r\n <pre>{{ wfs.$initialProcessDesignJson() }}</pre>\r\n\r\n <div class=\"value-caption\">currentProcessDesignJson:</div>\r\n <pre>{{ wfs.$currentProcessDesignJson() }}</pre>\r\n </div>\r\n\r\n <div class=\"tab-info\">\r\n <div class=\"value-caption\">initialEmailTemplatesJson:</div>\r\n <pre>{{ wfs.$initialEmailTemplatesJson() }}</pre>\r\n </div>\r\n\r\n </div>\r\n\r\n</div>", styles: [".all-tabs .tab-content.more{display:flex;position:relative;width:100%;height:500px;justify-content:center}.all-tabs .tab-content.more>*{width:100%;max-width:1000px}.state{background-color:#fff;height:50vh;display:block;position:fixed;z-index:9;bottom:-50vh;box-shadow:#0000001a 0 10px 50px;transition:opacity bottom .5s ease-out}.state.shown{bottom:0}.state .scroll-container{position:relative;padding:15px;height:50vh;overflow-y:auto}.state .scroll-container .tab-info{padding:15ox;box-shadow:#0000001a 0 10px 50px;margin-bottom:50px}.state .scroll-container .tab-info .value-caption{padding-left:24px;font-family:Fira Code,monospace;font-size:.85rem;font-weight:700}.state .scroll-container .tab-info pre{background-color:#fff;color:#333;padding:1rem 1.5rem;font-family:Fira Code,monospace;font-size:.85rem;overflow-x:auto;line-height:1.5;width:100%;margin:0;white-space:pre-wrap;word-break:break-word}\n"] }]
2508
2386
  }], ctorParameters: () => [] });
2509
2387
 
2510
2388
  export { DesignWrapperComponent };
2511
- //# sourceMappingURL=ngx-histaff-alpha-design-wrapper.component-Duk6i0JF.mjs.map
2389
+ //# sourceMappingURL=ngx-histaff-alpha-design-wrapper.component-C_EM0bEs.mjs.map