ngx-histaff-alpha 5.9.1 → 5.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/{ngx-histaff-alpha-ai-hint-for-table.component-ClNRMk6B.mjs → ngx-histaff-alpha-ai-hint-for-table.component-BO_Ci77l.mjs} +3 -3
- package/fesm2022/{ngx-histaff-alpha-ai-hint-for-table.component-ClNRMk6B.mjs.map → ngx-histaff-alpha-ai-hint-for-table.component-BO_Ci77l.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-core-form-design.component-KQsI4L2g.mjs → ngx-histaff-alpha-core-form-design.component-CGf-jOqR.mjs} +996 -154
- package/fesm2022/ngx-histaff-alpha-core-form-design.component-CGf-jOqR.mjs.map +1 -0
- package/fesm2022/{ngx-histaff-alpha-core-sticker-collection.component-ZJ29hnW7.mjs → ngx-histaff-alpha-core-sticker-collection.component-zkrmzfmx.mjs} +3 -3
- package/fesm2022/{ngx-histaff-alpha-core-sticker-collection.component-ZJ29hnW7.mjs.map → ngx-histaff-alpha-core-sticker-collection.component-zkrmzfmx.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-core-toast-loading.component-D4lPsJ_K.mjs → ngx-histaff-alpha-core-toast-loading.component-BLGPX2ov.mjs} +2 -2
- package/fesm2022/{ngx-histaff-alpha-core-toast-loading.component-D4lPsJ_K.mjs.map → ngx-histaff-alpha-core-toast-loading.component-BLGPX2ov.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-core-workflow-consume.component-Dxy4PssU.mjs → ngx-histaff-alpha-core-workflow-consume.component-DKYtFwki.mjs} +2 -2
- package/fesm2022/{ngx-histaff-alpha-core-workflow-consume.component-Dxy4PssU.mjs.map → ngx-histaff-alpha-core-workflow-consume.component-DKYtFwki.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-db-settings.component-ovw3ShzY.mjs → ngx-histaff-alpha-db-settings.component-CBB_Ahf3.mjs} +5 -5
- package/fesm2022/{ngx-histaff-alpha-db-settings.component-ovw3ShzY.mjs.map → ngx-histaff-alpha-db-settings.component-CBB_Ahf3.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-design-wrapper.component-Dd5UoJX1.mjs → ngx-histaff-alpha-design-wrapper.component-DaSrXARH.mjs} +5 -5
- package/fesm2022/{ngx-histaff-alpha-design-wrapper.component-Dd5UoJX1.mjs.map → ngx-histaff-alpha-design-wrapper.component-DaSrXARH.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-design-wrapper.route-DLdFwwhp.mjs → ngx-histaff-alpha-design-wrapper.route-RgR94c12.mjs} +5 -5
- package/fesm2022/{ngx-histaff-alpha-design-wrapper.route-DLdFwwhp.mjs.map → ngx-histaff-alpha-design-wrapper.route-RgR94c12.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-form-array-props.component-DkAM9Uk9.mjs → ngx-histaff-alpha-form-array-props.component-CCccglL5.mjs} +3 -3
- package/fesm2022/{ngx-histaff-alpha-form-array-props.component-DkAM9Uk9.mjs.map → ngx-histaff-alpha-form-array-props.component-CCccglL5.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-live-form.component-BMCAth2_.mjs → ngx-histaff-alpha-live-form.component-Df56ufkx.mjs} +2 -2
- package/fesm2022/{ngx-histaff-alpha-live-form.component-BMCAth2_.mjs.map → ngx-histaff-alpha-live-form.component-Df56ufkx.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-ngx-histaff-alpha-CkvGEG39.mjs → ngx-histaff-alpha-ngx-histaff-alpha-CYQ3j6IP.mjs} +31 -12
- package/fesm2022/{ngx-histaff-alpha-ngx-histaff-alpha-CkvGEG39.mjs.map → ngx-histaff-alpha-ngx-histaff-alpha-CYQ3j6IP.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-tracker-studio.component-CeB-VuEP.mjs → ngx-histaff-alpha-tracker-studio.component-h4r8nXvw.mjs} +2 -2
- package/fesm2022/{ngx-histaff-alpha-tracker-studio.component-CeB-VuEP.mjs.map → ngx-histaff-alpha-tracker-studio.component-h4r8nXvw.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-wf-form-assign.component-CO09ZkTB.mjs → ngx-histaff-alpha-wf-form-assign.component-Dcwd8mdT.mjs} +2 -2
- package/fesm2022/{ngx-histaff-alpha-wf-form-assign.component-CO09ZkTB.mjs.map → ngx-histaff-alpha-wf-form-assign.component-Dcwd8mdT.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-wf-instance-status.component-DQfVNySE.mjs → ngx-histaff-alpha-wf-instance-status.component-BEucf9x7.mjs} +4 -4
- package/fesm2022/{ngx-histaff-alpha-wf-instance-status.component-DQfVNySE.mjs.map → ngx-histaff-alpha-wf-instance-status.component-BEucf9x7.mjs.map} +1 -1
- package/fesm2022/{ngx-histaff-alpha-wf-instance-step-react.component-DRUYdQY3.mjs → ngx-histaff-alpha-wf-instance-step-react.component-CR-UUVFi.mjs} +3 -3
- package/fesm2022/{ngx-histaff-alpha-wf-instance-step-react.component-DRUYdQY3.mjs.map → ngx-histaff-alpha-wf-instance-step-react.component-CR-UUVFi.mjs.map} +1 -1
- package/fesm2022/ngx-histaff-alpha.mjs +1 -1
- package/lib/app/libraries/core-form-design/core-form-array-layout-editor/core-form-array-layout-editor.component.d.ts +1 -8
- package/lib/app/libraries/core-form-design/core-form-design.component.d.ts +1 -2
- package/lib/app/libraries/core-form-design/core-form-design.service.d.ts +12 -2
- package/lib/app/libraries/core-form-design/core-form-group-editor.component.d.ts +104 -0
- package/lib/app/libraries/core-form-design/field-setting/field-setting.component.d.ts +2 -1
- package/package.json +1 -1
- package/fesm2022/ngx-histaff-alpha-core-form-design.component-KQsI4L2g.mjs.map +0 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, ChangeDetectorRef, Component, signal, effect, HostListener, ChangeDetectionStrategy, Injectable, computed, viewChild, ViewContainerRef, Input, EventEmitter, Output,
|
|
2
|
+
import { inject, ChangeDetectorRef, Component, signal, effect, HostListener, ChangeDetectionStrategy, Injectable, computed, viewChild, ViewContainerRef, Input, EventEmitter, Output, input, Renderer2, isDevMode } from '@angular/core';
|
|
3
3
|
import { trigger, state, transition, style, animate } from '@angular/animations';
|
|
4
|
-
import { n as CoreFormDesignService, b as CoreWorkflowService, B as BaseEditComponent, i as AlertService, L as AppConfigService, O as EnumCorePageEditMode, P as EnumCoreButtonVNSCode, R as READONLY_WORKFLOW_FIELDS, Q as noneAutoClosedAlertOptions, p as DialogService, M as MultiLanguageService, C as CorePageHeaderComponent, U as CoreFormComponent, V as CoreButtonGroupVnsComponent, T as TranslatePipe, E as EnumFormBaseContolType, e as BaseComponent, W as EnumCoreTablePipeType, J as CoreCheckboxComponent, r as CoreDropdownComponent, g as TooltipDirective, G as GptService, l as alertOptions, y as CoreRadioGroupComponent, X as HtmlTooltipDirective, c as EnumCoreFormControlSeekerSourceType, Y as CoreControlNoFormArrayComponent, Z as EnumFormDesignMode, q as DomService, K as JsonService, z as ApplicationHelpService,
|
|
4
|
+
import { n as CoreFormDesignService, b as CoreWorkflowService, B as BaseEditComponent, i as AlertService, L as AppConfigService, O as EnumCorePageEditMode, P as EnumCoreButtonVNSCode, R as READONLY_WORKFLOW_FIELDS, Q as noneAutoClosedAlertOptions, p as DialogService, M as MultiLanguageService, C as CorePageHeaderComponent, U as CoreFormComponent, V as CoreButtonGroupVnsComponent, T as TranslatePipe, E as EnumFormBaseContolType, e as BaseComponent, W as EnumCoreTablePipeType, J as CoreCheckboxComponent, r as CoreDropdownComponent, g as TooltipDirective, G as GptService, l as alertOptions, y as CoreRadioGroupComponent, X as HtmlTooltipDirective, c as EnumCoreFormControlSeekerSourceType, Y as CoreControlNoFormArrayComponent, Z as EnumFormDesignMode, q as DomService, K as JsonService, z as ApplicationHelpService, _ as CoreControlComponent, j as TableCellPipe, H as HotKeysDirective, s as CoreChecklistComponent, u as CoreFormControlSeekerComponent, $ as CoreAttachmentComponent, t as CoreDatePickerComponent, a0 as CoreMonthSelectorComponent, v as CoreCurrencyInputComponent } from './ngx-histaff-alpha-ngx-histaff-alpha-CYQ3j6IP.mjs';
|
|
5
5
|
import * as i1 from '@angular/forms';
|
|
6
6
|
import { FormsModule, FormGroup, FormControl, FormArray, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
7
|
-
import { NgStyle, JsonPipe,
|
|
7
|
+
import { NgStyle, JsonPipe, AsyncPipe, NgTemplateOutlet } from '@angular/common';
|
|
8
8
|
import { BehaviorSubject, catchError, of, filter, distinctUntilChanged, tap, switchMap } from 'rxjs';
|
|
9
9
|
import { Router, ActivatedRoute } from '@angular/router';
|
|
10
|
-
import { CoreStickerCollectionComponent } from './ngx-histaff-alpha-core-sticker-collection.component-
|
|
11
|
-
import { D as DbService, C as CoreToastLoadingComponent } from './ngx-histaff-alpha-core-toast-loading.component-
|
|
10
|
+
import { CoreStickerCollectionComponent } from './ngx-histaff-alpha-core-sticker-collection.component-zkrmzfmx.mjs';
|
|
11
|
+
import { D as DbService, C as CoreToastLoadingComponent } from './ngx-histaff-alpha-core-toast-loading.component-BLGPX2ov.mjs';
|
|
12
12
|
import { EnumTranslateKey } from 'alpha-global-constants';
|
|
13
|
-
import { L as LiveFormComponent } from './ngx-histaff-alpha-live-form.component-
|
|
13
|
+
import { L as LiveFormComponent } from './ngx-histaff-alpha-live-form.component-Df56ufkx.mjs';
|
|
14
14
|
|
|
15
15
|
const slideFromTopFadeIn = trigger('slideFromTopFadeIn', [
|
|
16
16
|
state('in', style({ opacity: 1, transform: 'translateY(0)' })),
|
|
@@ -1081,6 +1081,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
|
|
|
1081
1081
|
class FieldSettingComponent extends BaseComponent {
|
|
1082
1082
|
constructor() {
|
|
1083
1083
|
super(...arguments);
|
|
1084
|
+
this.$isNested = input(false);
|
|
1084
1085
|
this.coreFormDesignService = inject(CoreFormDesignService);
|
|
1085
1086
|
this.enumControlType = EnumFormBaseContolType;
|
|
1086
1087
|
this.renderer = inject(Renderer2);
|
|
@@ -1098,7 +1099,7 @@ class FieldSettingComponent extends BaseComponent {
|
|
|
1098
1099
|
'number-props': () => Promise.resolve().then(function () { return numberProps_component; }).then(m => m.NumberPropsComponent),
|
|
1099
1100
|
'email-props': () => import('./ngx-histaff-alpha-email-props.component-Cf35Pexq.mjs').then(m => m.EmailPropsComponent),
|
|
1100
1101
|
'dropdown-props': () => Promise.resolve().then(function () { return dropdownProps_component; }).then(m => m.DropdownPropsComponent),
|
|
1101
|
-
'form-array-props': () => import('./ngx-histaff-alpha-form-array-props.component-
|
|
1102
|
+
'form-array-props': () => import('./ngx-histaff-alpha-form-array-props.component-CCccglL5.mjs').then(m => m.FormArrayPropsComponent),
|
|
1102
1103
|
// etc...
|
|
1103
1104
|
};
|
|
1104
1105
|
}
|
|
@@ -1147,7 +1148,7 @@ class FieldSettingComponent extends BaseComponent {
|
|
|
1147
1148
|
this.listenerFn();
|
|
1148
1149
|
}
|
|
1149
1150
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: FieldSettingComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
1150
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: FieldSettingComponent, isStandalone: true, selector: "field-setting", usesInheritance: true, ngImport: i0, template: "<div class=\"field-setting-container\">\r\n\r\n @if (!!$control()) {\r\n <div class=\"panel-caption-header\">\r\n <div class=\"panel-caption\">\r\n Editing: {{ $control().type !== 'calculated' ? $control()?.controlType + ' - ' : '' }}{{ $control()?.field ||\r\n 'Unnamed' }}\r\n </div>\r\n <div class=\"close-wrapper pointer\" (click)=\"closeFieldSettingPanel()\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"field-setting-content\">\r\n\r\n\r\n @if ($control().type === 'calculated') {\r\n\r\n <div class=\"group-title mandatory\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-lock\"></i>\r\n </div>\r\n <div class=\"group-name\">Mandatory</div>\r\n </div>\r\n <mandatory-props></mandatory-props>\r\n\r\n <div class=\"group-title calculated\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-lock\"></i>\r\n </div>\r\n <div class=\"group-name\">Calculated Rule<i class=\"feather-help-circle\" [htmlTooltip]=\"aboutCalculatedField\"\r\n [maxWidthUnset]=\"true\"></i></div>\r\n </div>\r\n <calculated-props></calculated-props>\r\n\r\n\r\n } @else {\r\n\r\n <div class=\"group-title mandatory\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-lock\"></i>\r\n </div>\r\n <div class=\"group-name\">Mandatory</div>\r\n </div>\r\n <mandatory-props></mandatory-props>\r\n\r\n <!-- <div class=\"setting-divider\"></div> -->\r\n\r\n @if ($control().controlType !== 'FORM_ARRAY') {\r\n <div class=\"group-title optional\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-sliders\"></i>\r\n </div>\r\n <div class=\"group-name\">Optional</div>\r\n </div>\r\n <optional-props></optional-props>\r\n\r\n <!-- <div class=\"setting-divider\"></div> -->\r\n\r\n <div class=\"group-title validators\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-check-square\"></i>\r\n </div>\r\n <div class=\"group-name\">Validators</div>\r\n </div>\r\n <validator-editor></validator-editor>\r\n }\r\n\r\n @if (!($control().controlType === 'TEXTBOX' && ['string', 'text', 'email'].includes(($control().type ||\r\n '').toLowerCase()))) {\r\n\r\n <div class=\"group-title\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-check-square\"></i>\r\n </div>\r\n <div class=\"group-name\">{{ getFriendlyControlLabel($control()) }} Settings</div>\r\n </div>\r\n\r\n <props-host [loadComponent]=\"componentLoaderMap[coreFormDesignService.$currentPropsComponent()]\"\r\n [props]=\"{ control: $control(), controlChange: onControlParamsChange.bind(this) }\">\r\n </props-host>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n\r\n\r\n</div>\r\n\r\n<ng-template #aboutCalculatedField>\r\n\r\n <div class=\"calculated-field-rule\" style=\"padding: 1rem; border-radius: 8px; background: #000; width: 800px;\">\r\n <h4 style=\"margin-top: 0; color: #fff;\">Calculated Field Rule</h4>\r\n <p><strong>Calculated fields</strong> are invisible boolean fields evaluated based on form inputs and logic. They\r\n help drive dynamic workflow behavior, such as conditional routing or validation triggers.</p>\r\n\r\n <h5 style=\"margin-bottom: 0.5rem; color: #fff;\">Key Properties</h5>\r\n <ul style=\"margin-top: 0;\">\r\n <li><strong>script:</strong> Expression to evaluate (e.g.,\r\n <code>leaveDays > 3 && status == 'Approved'</code>)</li>\r\n <li><strong>evaluationMode:</strong> <code>\"in-memory\"</code> or <code>\"sql-query\"</code></li>\r\n <li><strong>dependsOn[]:</strong> List of field names the script depends on</li>\r\n <li><strong>filterMode:</strong> <code>\"HardBlock\"</code> or <code>\"SoftWarn\"</code></li>\r\n </ul>\r\n\r\n <h5 style=\"margin-bottom: 0.5rem; color: #fff;\">Evaluation Modes</h5>\r\n <ul style=\"margin-top: 0;\">\r\n <li>\r\n <strong>in-memory:</strong> Uses <code>DynamicExpresso</code> to evaluate C#-like logic at runtime<br />\r\n <small>Example: <code>leaveType == \"ANNUAL\" && leaveDays < 5</code></small>\r\n </li>\r\n <li>\r\n <strong>sql-query:</strong> Runs backend SQL to evaluate conditions via\r\n <code>SELECT CASE WHEN ... THEN 1 ELSE 0 END</code><br />\r\n <small>Example:\r\n <code>SELECT CASE WHEN QUOTA > 0 THEN 1 ELSE 0 END FROM LEAVE_QUOTA WHERE EMPLOYEE_ID = {{ '@' }}employeeId</code></small>\r\n </li>\r\n </ul>\r\n\r\n <h5 style=\"margin-bottom: 0.5rem; color: #fff;\">Use Cases</h5>\r\n <ul style=\"margin-top: 0;\">\r\n <li>Validate complex logic without showing the field</li>\r\n <li>Route to a different workflow branch based on hidden logic</li>\r\n <li>Trigger warning or block submission based on business rules</li>\r\n </ul>\r\n\r\n <h5 style=\"margin-bottom: 0.5rem; color: #fff;\">Example</h5>\r\n <pre style=\"color: #eee; padding: 0.5rem 1rem; border-radius: 4px; overflow-x: auto;\">\r\n {{ '{' }}\r\n \"script\": \"leaveDays > 3 && status == 'APPROVED'\",\r\n \"evaluationMode\": \"in-memory\",\r\n \"dependsOn\": [\"leaveDays\", \"status\"],\r\n \"filterMode\": \"HardBlock\"\r\n {{ '}' }}\r\n </pre>\r\n </div>\r\n\r\n\r\n</ng-template>", styles: [".field-setting-container{max-height:100%;overflow-x:hidden;overflow-y:auto}.field-setting-container .field-setting-content{padding:15px}.field-setting-container .panel-caption-header{display:flex;align-items:center;justify-content:space-between;padding:15px;height:60px;background-color:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1f2937}.field-setting-container .panel-caption-header .panel-caption{flex-grow:1}.field-setting-container .panel-caption-header .close-wrapper{display:flex;align-items:center;justify-content:center;background-color:#f1f5f9;width:32px;height:32px;border-radius:50%;cursor:pointer;transition:background-color .2s}.field-setting-container .panel-caption-header .close-wrapper:hover{background-color:#e2e8f0}.field-setting-container .setting-divider{margin:1.5rem 0 .75rem;color:#555;border-top:1px dashed #ccc;padding-top:.5rem}.field-setting-container .group-title{display:flex;height:35px;align-items:center;gap:8px;background-color:#87ceeb;padding:6px 12px;font-weight:600;color:#1f2937;font-size:13px;margin:12px 0 4px;box-shadow:0 1px 2px #0000000d}.field-setting-container .group-title .icon-wrapper{display:flex;align-items:center;justify-content:center;width:18px;height:18px;color:#1f2937}.field-setting-container .group-title .icon-wrapper i{width:16px;height:16px;stroke-width:2}.field-setting-container .group-title.mandatory{background-color:#ffecb3}.field-setting-container .group-title.optional{background-color:#d0f0fd}.field-setting-container .group-title.validators{background-color:#e8f5e9}.field-setting-container .group-title .group-name{flex:1}.field-setting-container .group-title .group-name .feather-help-circle{display:inline-block;margin-left:8px}.field-setting-container .calculated-field-rule{font-family:system-ui,sans-serif;border:1px solid #ccc;padding:1rem;border-radius:8px}.field-setting-container .calculated-field-rule h2{margin-top:0;color:#2b3e50}.field-setting-container .calculated-field-rule pre{background:#eee;padding:.5rem 1rem;border-radius:4px;overflow-x:auto}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: MandatoryPropsComponent, selector: "mandatory-props" }, { kind: "component", type: OptionalPropsComponent, selector: "optional-props" }, { kind: "component", type: ValidatorEditorComponent, selector: "validator-editor" }, { kind: "component", type: PropsHostComponent, selector: "props-host", inputs: ["loadComponent", "props"] }, { kind: "component", type: CalculatedPropsComponent, selector: "calculated-props" }, { kind: "directive", type: HtmlTooltipDirective, selector: "[htmlTooltip]", inputs: ["htmlTooltip", "tooltipContext", "maxWidthUnset", "backgroundColor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1151
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: FieldSettingComponent, isStandalone: true, selector: "field-setting", inputs: { $isNested: { classPropertyName: "$isNested", publicName: "$isNested", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div class=\"field-setting-container\">\r\n\r\n @if (!!$control()) {\r\n <div class=\"panel-caption-header\">\r\n <div class=\"panel-caption\">\r\n Editing: {{ $control().type !== 'calculated' ? $control()?.controlType + ' - ' : '' }}{{ $control()?.field ||\r\n 'Unnamed' }}\r\n </div>\r\n <div class=\"close-wrapper pointer\" (click)=\"closeFieldSettingPanel()\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"field-setting-content\">\r\n\r\n\r\n @if ($control().type === 'calculated') {\r\n\r\n <div class=\"group-title mandatory\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-lock\"></i>\r\n </div>\r\n <div class=\"group-name\">Mandatory</div>\r\n </div>\r\n <mandatory-props></mandatory-props>\r\n\r\n <div class=\"group-title calculated\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-lock\"></i>\r\n </div>\r\n <div class=\"group-name\">Calculated Rule<i class=\"feather-help-circle\" [htmlTooltip]=\"aboutCalculatedField\"\r\n [maxWidthUnset]=\"true\"></i></div>\r\n </div>\r\n <calculated-props></calculated-props>\r\n\r\n\r\n } @else {\r\n\r\n <div class=\"group-title mandatory\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-lock\"></i>\r\n </div>\r\n <div class=\"group-name\">Mandatory</div>\r\n </div>\r\n <mandatory-props></mandatory-props>\r\n\r\n <!-- <div class=\"setting-divider\"></div> -->\r\n\r\n @if ($control().controlType !== 'FORM_ARRAY') {\r\n <div class=\"group-title optional\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-sliders\"></i>\r\n </div>\r\n <div class=\"group-name\">Optional</div>\r\n </div>\r\n <optional-props></optional-props>\r\n\r\n <!-- <div class=\"setting-divider\"></div> -->\r\n\r\n <div class=\"group-title validators\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-check-square\"></i>\r\n </div>\r\n <div class=\"group-name\">Validators</div>\r\n </div>\r\n <validator-editor></validator-editor>\r\n }\r\n\r\n @if (!($control().controlType === 'TEXTBOX' && ['string', 'text', 'email'].includes(($control().type ||\r\n '').toLowerCase()))) {\r\n\r\n <div class=\"group-title\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-check-square\"></i>\r\n </div>\r\n <div class=\"group-name\">{{ getFriendlyControlLabel($control()) }} Settings</div>\r\n </div>\r\n\r\n <props-host [loadComponent]=\"componentLoaderMap[coreFormDesignService.$currentPropsComponent()]\"\r\n [props]=\"{ control: $control(), controlChange: onControlParamsChange.bind(this) }\">\r\n </props-host>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n\r\n\r\n</div>\r\n\r\n<ng-template #aboutCalculatedField>\r\n\r\n <div class=\"calculated-field-rule\" style=\"padding: 1rem; border-radius: 8px; background: #000; width: 800px;\">\r\n <h4 style=\"margin-top: 0; color: #fff;\">Calculated Field Rule</h4>\r\n <p><strong>Calculated fields</strong> are invisible boolean fields evaluated based on form inputs and logic. They\r\n help drive dynamic workflow behavior, such as conditional routing or validation triggers.</p>\r\n\r\n <h5 style=\"margin-bottom: 0.5rem; color: #fff;\">Key Properties</h5>\r\n <ul style=\"margin-top: 0;\">\r\n <li><strong>script:</strong> Expression to evaluate (e.g.,\r\n <code>leaveDays > 3 && status == 'Approved'</code>)</li>\r\n <li><strong>evaluationMode:</strong> <code>\"in-memory\"</code> or <code>\"sql-query\"</code></li>\r\n <li><strong>dependsOn[]:</strong> List of field names the script depends on</li>\r\n <li><strong>filterMode:</strong> <code>\"HardBlock\"</code> or <code>\"SoftWarn\"</code></li>\r\n </ul>\r\n\r\n <h5 style=\"margin-bottom: 0.5rem; color: #fff;\">Evaluation Modes</h5>\r\n <ul style=\"margin-top: 0;\">\r\n <li>\r\n <strong>in-memory:</strong> Uses <code>DynamicExpresso</code> to evaluate C#-like logic at runtime<br />\r\n <small>Example: <code>leaveType == \"ANNUAL\" && leaveDays < 5</code></small>\r\n </li>\r\n <li>\r\n <strong>sql-query:</strong> Runs backend SQL to evaluate conditions via\r\n <code>SELECT CASE WHEN ... THEN 1 ELSE 0 END</code><br />\r\n <small>Example:\r\n <code>SELECT CASE WHEN QUOTA > 0 THEN 1 ELSE 0 END FROM LEAVE_QUOTA WHERE EMPLOYEE_ID = {{ '@' }}employeeId</code></small>\r\n </li>\r\n </ul>\r\n\r\n <h5 style=\"margin-bottom: 0.5rem; color: #fff;\">Use Cases</h5>\r\n <ul style=\"margin-top: 0;\">\r\n <li>Validate complex logic without showing the field</li>\r\n <li>Route to a different workflow branch based on hidden logic</li>\r\n <li>Trigger warning or block submission based on business rules</li>\r\n </ul>\r\n\r\n <h5 style=\"margin-bottom: 0.5rem; color: #fff;\">Example</h5>\r\n <pre style=\"color: #eee; padding: 0.5rem 1rem; border-radius: 4px; overflow-x: auto;\">\r\n {{ '{' }}\r\n \"script\": \"leaveDays > 3 && status == 'APPROVED'\",\r\n \"evaluationMode\": \"in-memory\",\r\n \"dependsOn\": [\"leaveDays\", \"status\"],\r\n \"filterMode\": \"HardBlock\"\r\n {{ '}' }}\r\n </pre>\r\n </div>\r\n\r\n\r\n</ng-template>", styles: [".field-setting-container{max-height:100%;overflow-x:hidden;overflow-y:auto}.field-setting-container .field-setting-content{padding:15px}.field-setting-container .panel-caption-header{display:flex;align-items:center;justify-content:space-between;padding:15px;height:60px;background-color:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1f2937}.field-setting-container .panel-caption-header .panel-caption{flex-grow:1}.field-setting-container .panel-caption-header .close-wrapper{display:flex;align-items:center;justify-content:center;background-color:#f1f5f9;width:32px;height:32px;border-radius:50%;cursor:pointer;transition:background-color .2s}.field-setting-container .panel-caption-header .close-wrapper:hover{background-color:#e2e8f0}.field-setting-container .setting-divider{margin:1.5rem 0 .75rem;color:#555;border-top:1px dashed #ccc;padding-top:.5rem}.field-setting-container .group-title{display:flex;height:35px;align-items:center;gap:8px;background-color:#87ceeb;padding:6px 12px;font-weight:600;color:#1f2937;font-size:13px;margin:12px 0 4px;box-shadow:0 1px 2px #0000000d}.field-setting-container .group-title .icon-wrapper{display:flex;align-items:center;justify-content:center;width:18px;height:18px;color:#1f2937}.field-setting-container .group-title .icon-wrapper i{width:16px;height:16px;stroke-width:2}.field-setting-container .group-title.mandatory{background-color:#ffecb3}.field-setting-container .group-title.optional{background-color:#d0f0fd}.field-setting-container .group-title.validators{background-color:#e8f5e9}.field-setting-container .group-title .group-name{flex:1}.field-setting-container .group-title .group-name .feather-help-circle{display:inline-block;margin-left:8px}.field-setting-container .calculated-field-rule{font-family:system-ui,sans-serif;border:1px solid #ccc;padding:1rem;border-radius:8px}.field-setting-container .calculated-field-rule h2{margin-top:0;color:#2b3e50}.field-setting-container .calculated-field-rule pre{background:#eee;padding:.5rem 1rem;border-radius:4px;overflow-x:auto}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: MandatoryPropsComponent, selector: "mandatory-props" }, { kind: "component", type: OptionalPropsComponent, selector: "optional-props" }, { kind: "component", type: ValidatorEditorComponent, selector: "validator-editor" }, { kind: "component", type: PropsHostComponent, selector: "props-host", inputs: ["loadComponent", "props"] }, { kind: "component", type: CalculatedPropsComponent, selector: "calculated-props" }, { kind: "directive", type: HtmlTooltipDirective, selector: "[htmlTooltip]", inputs: ["htmlTooltip", "tooltipContext", "maxWidthUnset", "backgroundColor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1151
1152
|
}
|
|
1152
1153
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: FieldSettingComponent, decorators: [{
|
|
1153
1154
|
type: Component,
|
|
@@ -1192,7 +1193,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1192
1193
|
field: 'stringBox',
|
|
1193
1194
|
label: '',
|
|
1194
1195
|
value: '',
|
|
1195
|
-
readonly: true,
|
|
1196
|
+
//readonly: true,
|
|
1196
1197
|
placeholder: 'String box',
|
|
1197
1198
|
headless: true,
|
|
1198
1199
|
},
|
|
@@ -1203,7 +1204,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1203
1204
|
field: 'email',
|
|
1204
1205
|
label: '',
|
|
1205
1206
|
value: '',
|
|
1206
|
-
readonly: true,
|
|
1207
|
+
//readonly: true,
|
|
1207
1208
|
placeholder: 'Email',
|
|
1208
1209
|
headless: true,
|
|
1209
1210
|
},
|
|
@@ -1214,7 +1215,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1214
1215
|
field: 'textarea',
|
|
1215
1216
|
label: '',
|
|
1216
1217
|
value: '',
|
|
1217
|
-
readonly: true,
|
|
1218
|
+
//readonly: true,
|
|
1218
1219
|
textareaRows: 2,
|
|
1219
1220
|
placeholder: 'Text area',
|
|
1220
1221
|
headless: true,
|
|
@@ -1226,7 +1227,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1226
1227
|
field: 'number',
|
|
1227
1228
|
label: '',
|
|
1228
1229
|
value: 100,
|
|
1229
|
-
readonly: true,
|
|
1230
|
+
//readonly: true,
|
|
1230
1231
|
placeholder: 'Number',
|
|
1231
1232
|
headless: true,
|
|
1232
1233
|
},
|
|
@@ -1237,7 +1238,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1237
1238
|
field: 'currency',
|
|
1238
1239
|
label: '',
|
|
1239
1240
|
value: '',
|
|
1240
|
-
readonly: true,
|
|
1241
|
+
//readonly: true,
|
|
1241
1242
|
placeholder: 'Currency',
|
|
1242
1243
|
headless: true,
|
|
1243
1244
|
},
|
|
@@ -1248,7 +1249,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1248
1249
|
field: 'dropdown',
|
|
1249
1250
|
label: '',
|
|
1250
1251
|
value: '',
|
|
1251
|
-
readonly: true,
|
|
1252
|
+
//readonly: true,
|
|
1252
1253
|
dropdownOptions$: new BehaviorSubject([]),
|
|
1253
1254
|
shownFrom: 'name',
|
|
1254
1255
|
getByIdObject$: new BehaviorSubject({}),
|
|
@@ -1263,7 +1264,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1263
1264
|
field: 'employeeSeeker',
|
|
1264
1265
|
label: '',
|
|
1265
1266
|
value: ['Nguyễn A'],
|
|
1266
|
-
readonly: true,
|
|
1267
|
+
//readonly: true,
|
|
1267
1268
|
boundFrom: 'id',
|
|
1268
1269
|
shownFrom: 'fullname',
|
|
1269
1270
|
getByIdObject$: new BehaviorSubject({}),
|
|
@@ -1277,7 +1278,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1277
1278
|
field: 'checklist',
|
|
1278
1279
|
label: '',
|
|
1279
1280
|
value: [],
|
|
1280
|
-
readonly: true,
|
|
1281
|
+
//readonly: true,
|
|
1281
1282
|
checklistOptions$: new BehaviorSubject([]),
|
|
1282
1283
|
shownFrom: 'name',
|
|
1283
1284
|
getByIdObject$: new BehaviorSubject({}),
|
|
@@ -1293,7 +1294,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1293
1294
|
field: 'employeeSeekerMultiple',
|
|
1294
1295
|
label: '',
|
|
1295
1296
|
value: [],
|
|
1296
|
-
readonly: true,
|
|
1297
|
+
//readonly: true,
|
|
1297
1298
|
objectList$: new BehaviorSubject([]),
|
|
1298
1299
|
boundFrom: 'id',
|
|
1299
1300
|
shownFrom: 'fullname',
|
|
@@ -1309,7 +1310,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1309
1310
|
field: 'datePicker',
|
|
1310
1311
|
label: '',
|
|
1311
1312
|
value: '',
|
|
1312
|
-
readonly: true,
|
|
1313
|
+
//readonly: true,
|
|
1313
1314
|
placeholder: 'Date picker',
|
|
1314
1315
|
showPlaceholder: true,
|
|
1315
1316
|
headless: true,
|
|
@@ -1321,7 +1322,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1321
1322
|
field: 'timeBox',
|
|
1322
1323
|
label: '',
|
|
1323
1324
|
value: null,
|
|
1324
|
-
readonly: true,
|
|
1325
|
+
//readonly: true,
|
|
1325
1326
|
placeholder: 'Time box',
|
|
1326
1327
|
headless: true,
|
|
1327
1328
|
},
|
|
@@ -1332,7 +1333,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1332
1333
|
field: 'monthSelector',
|
|
1333
1334
|
label: '',
|
|
1334
1335
|
value: '',
|
|
1335
|
-
readonly: true,
|
|
1336
|
+
//readonly: true,
|
|
1336
1337
|
placeholder: 'Month selector',
|
|
1337
1338
|
headless: true,
|
|
1338
1339
|
},
|
|
@@ -1343,7 +1344,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1343
1344
|
field: 'attachment',
|
|
1344
1345
|
label: '',
|
|
1345
1346
|
value: '',
|
|
1346
|
-
readonly: true,
|
|
1347
|
+
//readonly: true,
|
|
1347
1348
|
assignTo: 'unknown',
|
|
1348
1349
|
placeholder: 'Attachment',
|
|
1349
1350
|
headless: true,
|
|
@@ -1355,7 +1356,7 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1355
1356
|
field: 'checkbox',
|
|
1356
1357
|
label: '',
|
|
1357
1358
|
value: '',
|
|
1358
|
-
readonly: true,
|
|
1359
|
+
//readonly: true,
|
|
1359
1360
|
placeholder: 'Checkbox',
|
|
1360
1361
|
headless: true,
|
|
1361
1362
|
}
|
|
@@ -1380,90 +1381,24 @@ class CoreFormArrayControlPaletteComponent {
|
|
|
1380
1381
|
this.checkError$ = new BehaviorSubject(false);
|
|
1381
1382
|
}
|
|
1382
1383
|
onDragStart(event, control) {
|
|
1383
|
-
|
|
1384
|
+
this.coreFormDesignService.beginDragTemplate(control);
|
|
1384
1385
|
}
|
|
1385
1386
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormArrayControlPaletteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1386
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: CoreFormArrayControlPaletteComponent, isStandalone: true, selector: "core-form-array-control-palette", ngImport: i0, template: "<ul>\r\n <!-- <div class=\"palette-debug\">\r\n <div>controlOptions length: {{ controlOptions.length }}</div>\r\n <pre>{{ controlOptions | json }}</pre>\r\n </div> -->\r\n @for (control of controlOptions; track $index) {\r\n <li class=\"palette-item\" draggable=\"true\" (dragstart)=\"onDragStart($event, control)\">\r\n <core-control-no-form-array [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\" />\r\n </li>\r\n }\r\n</ul>", styles: [".palette-debug{font-size:12px;background:#f9f9f9;border:1px solid #ddd;padding:8px;border-radius:4px;color:#333;margin-bottom:8px;white-space:pre-wrap}ul{padding:0}ul li{margin:8px}\n"], dependencies: [{ kind: "component", type: CoreControlNoFormArrayComponent, selector: "core-control-no-form-array", inputs: ["control", "form", "checkError$", "rangeLimit"] }] }); }
|
|
1387
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: CoreFormArrayControlPaletteComponent, isStandalone: true, selector: "core-form-array-control-palette", ngImport: i0, template: "<ul>\r\n <!-- <div class=\"palette-debug\">\r\n <div>controlOptions length: {{ controlOptions.length }}</div>\r\n <pre>{{ controlOptions | json }}</pre>\r\n </div> -->\r\n @for (control of controlOptions; track $index) {\r\n <li class=\"palette-item\" draggable=\"true\" (dragstart)=\"onDragStart($event, control)\">\r\n <core-control-no-form-array [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\" />\r\n </li>\r\n }\r\n</ul>", styles: [".palette-debug{font-size:12px;background:#f9f9f9;border:1px solid #ddd;padding:8px;border-radius:4px;color:#333;margin-bottom:8px;white-space:pre-wrap}ul{padding:0}ul li{margin-top:8px;margin-bottom:8px;margin-right:15px}\n"], dependencies: [{ kind: "component", type: CoreControlNoFormArrayComponent, selector: "core-control-no-form-array", inputs: ["control", "form", "checkError$", "rangeLimit"] }] }); }
|
|
1387
1388
|
}
|
|
1388
1389
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormArrayControlPaletteComponent, decorators: [{
|
|
1389
1390
|
type: Component,
|
|
1390
1391
|
args: [{ selector: 'core-form-array-control-palette', imports: [
|
|
1391
1392
|
JsonPipe,
|
|
1392
1393
|
CoreControlNoFormArrayComponent
|
|
1393
|
-
], template: "<ul>\r\n <!-- <div class=\"palette-debug\">\r\n <div>controlOptions length: {{ controlOptions.length }}</div>\r\n <pre>{{ controlOptions | json }}</pre>\r\n </div> -->\r\n @for (control of controlOptions; track $index) {\r\n <li class=\"palette-item\" draggable=\"true\" (dragstart)=\"onDragStart($event, control)\">\r\n <core-control-no-form-array [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\" />\r\n </li>\r\n }\r\n</ul>", styles: [".palette-debug{font-size:12px;background:#f9f9f9;border:1px solid #ddd;padding:8px;border-radius:4px;color:#333;margin-bottom:8px;white-space:pre-wrap}ul{padding:0}ul li{margin:8px}\n"] }]
|
|
1394
|
-
}] });
|
|
1395
|
-
|
|
1396
|
-
const PLACEHOLDER_CONTROL = {
|
|
1397
|
-
controlType: EnumFormBaseContolType.PLACEHOLDER,
|
|
1398
|
-
field: '',
|
|
1399
|
-
label: '',
|
|
1400
|
-
flexSize: 12,
|
|
1401
|
-
value: ''
|
|
1402
|
-
};
|
|
1403
|
-
class CoreFormArrayLayoutEditorComponent {
|
|
1404
|
-
constructor() {
|
|
1405
|
-
this.checkError$ = new BehaviorSubject(false);
|
|
1406
|
-
this.coreFormDesignService = inject(CoreFormDesignService);
|
|
1407
|
-
this.$sections = this.coreFormDesignService.$nestedDesignSections;
|
|
1408
|
-
this.form = this.coreFormDesignService.formDesign;
|
|
1409
|
-
this.showDebug = false;
|
|
1410
|
-
this.dropIndex = 0;
|
|
1411
|
-
}
|
|
1412
|
-
onClose() {
|
|
1413
|
-
this.coreFormDesignService.$showFormArrayDesign.set(false);
|
|
1414
|
-
}
|
|
1415
|
-
onMiniDrop(event, sectionIndex, rowIndex, colIndex) {
|
|
1416
|
-
const rawData = event?.dataTransfer?.getData('application/json');
|
|
1417
|
-
if (!rawData)
|
|
1418
|
-
return;
|
|
1419
|
-
const control = JSON.parse(rawData);
|
|
1420
|
-
const newControl = structuredClone(control);
|
|
1421
|
-
newControl.field = `control_${++this.dropIndex}`;
|
|
1422
|
-
const current = this.$sections();
|
|
1423
|
-
if (!current)
|
|
1424
|
-
return;
|
|
1425
|
-
current[sectionIndex].rows[rowIndex][colIndex] = newControl;
|
|
1426
|
-
this.$sections.set([...current]);
|
|
1427
|
-
}
|
|
1428
|
-
addSection() {
|
|
1429
|
-
const current = this.$sections() || [];
|
|
1430
|
-
current.push({ caption: '', rows: [[PLACEHOLDER_CONTROL]] });
|
|
1431
|
-
this.$sections.set([...current]);
|
|
1432
|
-
}
|
|
1433
|
-
addRow(sectionIndex) {
|
|
1434
|
-
const current = this.$sections();
|
|
1435
|
-
if (!current?.[sectionIndex])
|
|
1436
|
-
return;
|
|
1437
|
-
current[sectionIndex].rows.push([PLACEHOLDER_CONTROL]);
|
|
1438
|
-
this.$sections.set([...current]);
|
|
1439
|
-
}
|
|
1440
|
-
removeControl(sectionIndex, rowIndex, colIndex) {
|
|
1441
|
-
const current = this.$sections();
|
|
1442
|
-
// Guard: Make sure the section and row exist
|
|
1443
|
-
if (!current?.[sectionIndex]?.rows[rowIndex])
|
|
1444
|
-
return;
|
|
1445
|
-
// Replace the control at given slot with a type-safe placeholder
|
|
1446
|
-
current[sectionIndex].rows[rowIndex][colIndex] = PLACEHOLDER_CONTROL;
|
|
1447
|
-
// Update the signal to trigger re-render
|
|
1448
|
-
this.$sections.set([...current]);
|
|
1449
|
-
}
|
|
1450
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormArrayLayoutEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1451
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: CoreFormArrayLayoutEditorComponent, isStandalone: true, selector: "core-form-array-layout-editor", ngImport: i0, template: "<div class=\"core-form-array-layout-editor-container\">\r\n <div class=\"modal-container\">\r\n <div class=\"modal-content-root\">\r\n\r\n <div class=\"layout-header\">\r\n {{ 'Design Form Array Layout' | uppercase }}\r\n <button class=\"close-button\" (click)=\"onClose()\">\u00D7</button>\r\n </div>\r\n\r\n <div class=\"layout-main-content\">\r\n <!-- Left: Palette -->\r\n <div class=\"layout-left\">\r\n <core-form-array-control-palette />\r\n </div>\r\n\r\n <!-- Right: Grid Layout -->\r\n <div class=\"layout-right\">\r\n <div class=\"layout-toolbar\">\r\n <button class=\"btn btn-sm btn-primary\" (click)=\"addSection()\">+ Section</button>\r\n <button class=\"btn btn-sm btn-secondary\" (click)=\"addRow(0)\">+ Row to First Section</button>\r\n <button class=\"btn btn-sm btn-outline-dark\" (click)=\"showDebug = !showDebug\">\r\n {{ showDebug ? 'Hide' : 'Show' }} Debug\r\n </button>\r\n </div>\r\n\r\n @if (showDebug) {\r\n <pre>{{ $sections() | json }}</pre>\r\n }\r\n\r\n <div class=\"layout-body\">\r\n @for (section of $sections(); track $index; let sectionIndex = $index) {\r\n <div class=\"section-card\">\r\n <div class=\"section-caption\">\r\n {{ section.caption || 'Untitled Section' }}\r\n </div>\r\n\r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n <div class=\"row\">\r\n @for (control of row; track $index; let colIndex = $index) {\r\n <div class=\"form-cell mini-drop-target\" miniDropTarget\r\n (miniDropped)=\"onMiniDrop($event, sectionIndex, rowIndex, colIndex)\">\r\n @if (control) {\r\n <div class=\"form-cell-inner\">\r\n <core-control-no-form-array [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\" />\r\n <button class=\"btn btn-sm btn-link text-danger remove-btn\"\r\n (click)=\"removeControl(sectionIndex, rowIndex, colIndex)\">\r\n \u00D7\r\n </button>\r\n </div>\r\n } @else {\r\n <div class=\"placeholder-slot\">Drop Here</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".layout-header{position:relative;padding:15px;font-size:20px;border-bottom:1px solid #e0e0e0;display:flex;align-items:center;transform:translate(-15px,-15px);width:calc(100% + 30px)}.close-button{position:absolute;top:12px;right:12px;background:none;border:none;font-size:22px;cursor:pointer;color:#666;line-height:1;padding:0;z-index:1}.close-button:hover{color:#000}.layout-main-content{display:flex;gap:24px}.layout-left{width:200px;flex:0 0 240px;border-right:1px solid #eee;padding-right:16px;overflow:auto}.layout-right{flex:1;padding-left:16px;overflow-x:auto}.layout-toolbar{display:flex;gap:12px;margin-bottom:12px}.layout-body{display:flex;flex-direction:column;gap:24px}.section-card{background-color:#fdfdfd;border:1px solid #ddd;border-radius:8px;padding:12px}.section-caption{font-weight:600;margin-bottom:12px}.row{display:flex;gap:12px;margin-bottom:12px}.form-cell{flex:1;min-width:120px;padding:6px;border:1px dashed #ccc;border-radius:4px;background-color:#fff;position:relative}.form-cell-inner{position:relative}.remove-btn{position:absolute;top:0;right:0;font-size:14px;padding:0 4px;border:none}.placeholder-slot{text-align:center;color:#aaa;padding:16px;background:#fafafa;border:1px dashed #bbb;border-radius:4px}\n"], dependencies: [{ kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: UpperCasePipe, name: "uppercase" }, { kind: "component", type: CoreControlNoFormArrayComponent, selector: "core-control-no-form-array", inputs: ["control", "form", "checkError$", "rangeLimit"] }, { kind: "component", type: CoreFormArrayControlPaletteComponent, selector: "core-form-array-control-palette" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1452
|
-
}
|
|
1453
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormArrayLayoutEditorComponent, decorators: [{
|
|
1454
|
-
type: Component,
|
|
1455
|
-
args: [{ selector: 'core-form-array-layout-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
1456
|
-
JsonPipe,
|
|
1457
|
-
UpperCasePipe,
|
|
1458
|
-
CoreControlNoFormArrayComponent,
|
|
1459
|
-
CoreFormArrayControlPaletteComponent
|
|
1460
|
-
], template: "<div class=\"core-form-array-layout-editor-container\">\r\n <div class=\"modal-container\">\r\n <div class=\"modal-content-root\">\r\n\r\n <div class=\"layout-header\">\r\n {{ 'Design Form Array Layout' | uppercase }}\r\n <button class=\"close-button\" (click)=\"onClose()\">\u00D7</button>\r\n </div>\r\n\r\n <div class=\"layout-main-content\">\r\n <!-- Left: Palette -->\r\n <div class=\"layout-left\">\r\n <core-form-array-control-palette />\r\n </div>\r\n\r\n <!-- Right: Grid Layout -->\r\n <div class=\"layout-right\">\r\n <div class=\"layout-toolbar\">\r\n <button class=\"btn btn-sm btn-primary\" (click)=\"addSection()\">+ Section</button>\r\n <button class=\"btn btn-sm btn-secondary\" (click)=\"addRow(0)\">+ Row to First Section</button>\r\n <button class=\"btn btn-sm btn-outline-dark\" (click)=\"showDebug = !showDebug\">\r\n {{ showDebug ? 'Hide' : 'Show' }} Debug\r\n </button>\r\n </div>\r\n\r\n @if (showDebug) {\r\n <pre>{{ $sections() | json }}</pre>\r\n }\r\n\r\n <div class=\"layout-body\">\r\n @for (section of $sections(); track $index; let sectionIndex = $index) {\r\n <div class=\"section-card\">\r\n <div class=\"section-caption\">\r\n {{ section.caption || 'Untitled Section' }}\r\n </div>\r\n\r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n <div class=\"row\">\r\n @for (control of row; track $index; let colIndex = $index) {\r\n <div class=\"form-cell mini-drop-target\" miniDropTarget\r\n (miniDropped)=\"onMiniDrop($event, sectionIndex, rowIndex, colIndex)\">\r\n @if (control) {\r\n <div class=\"form-cell-inner\">\r\n <core-control-no-form-array [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\" />\r\n <button class=\"btn btn-sm btn-link text-danger remove-btn\"\r\n (click)=\"removeControl(sectionIndex, rowIndex, colIndex)\">\r\n \u00D7\r\n </button>\r\n </div>\r\n } @else {\r\n <div class=\"placeholder-slot\">Drop Here</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".layout-header{position:relative;padding:15px;font-size:20px;border-bottom:1px solid #e0e0e0;display:flex;align-items:center;transform:translate(-15px,-15px);width:calc(100% + 30px)}.close-button{position:absolute;top:12px;right:12px;background:none;border:none;font-size:22px;cursor:pointer;color:#666;line-height:1;padding:0;z-index:1}.close-button:hover{color:#000}.layout-main-content{display:flex;gap:24px}.layout-left{width:200px;flex:0 0 240px;border-right:1px solid #eee;padding-right:16px;overflow:auto}.layout-right{flex:1;padding-left:16px;overflow-x:auto}.layout-toolbar{display:flex;gap:12px;margin-bottom:12px}.layout-body{display:flex;flex-direction:column;gap:24px}.section-card{background-color:#fdfdfd;border:1px solid #ddd;border-radius:8px;padding:12px}.section-caption{font-weight:600;margin-bottom:12px}.row{display:flex;gap:12px;margin-bottom:12px}.form-cell{flex:1;min-width:120px;padding:6px;border:1px dashed #ccc;border-radius:4px;background-color:#fff;position:relative}.form-cell-inner{position:relative}.remove-btn{position:absolute;top:0;right:0;font-size:14px;padding:0 4px;border:none}.placeholder-slot{text-align:center;color:#aaa;padding:16px;background:#fafafa;border:1px dashed #bbb;border-radius:4px}\n"] }]
|
|
1394
|
+
], template: "<ul>\r\n <!-- <div class=\"palette-debug\">\r\n <div>controlOptions length: {{ controlOptions.length }}</div>\r\n <pre>{{ controlOptions | json }}</pre>\r\n </div> -->\r\n @for (control of controlOptions; track $index) {\r\n <li class=\"palette-item\" draggable=\"true\" (dragstart)=\"onDragStart($event, control)\">\r\n <core-control-no-form-array [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\" />\r\n </li>\r\n }\r\n</ul>", styles: [".palette-debug{font-size:12px;background:#f9f9f9;border:1px solid #ddd;padding:8px;border-radius:4px;color:#333;margin-bottom:8px;white-space:pre-wrap}ul{padding:0}ul li{margin-top:8px;margin-bottom:8px;margin-right:15px}\n"] }]
|
|
1461
1395
|
}] });
|
|
1462
1396
|
|
|
1463
|
-
class
|
|
1397
|
+
class CoreFormGroupEditorComponent extends BaseComponent {
|
|
1464
1398
|
constructor(mls) {
|
|
1465
1399
|
super(mls);
|
|
1466
1400
|
this.mls = mls;
|
|
1401
|
+
this.$isNested = input(false);
|
|
1467
1402
|
this.$idAsInput = input();
|
|
1468
1403
|
this.$id = input();
|
|
1469
1404
|
this.$settingPanel = viewChild('settingPanel');
|
|
@@ -1851,6 +1786,7 @@ class CoreFormDesignComponent extends BaseComponent {
|
|
|
1851
1786
|
this.generateLabelNameFor = this.coreFormDesignService.generateLabelNameFor.bind(this.coreFormDesignService);
|
|
1852
1787
|
this.getAllControlsFromSections = this.coreFormDesignService.getAllControlsFromSections.bind(this.coreFormDesignService);
|
|
1853
1788
|
this.getControl = this.coreFormDesignService.getControl.bind(this.coreFormDesignService);
|
|
1789
|
+
this.filteredCells = this.coreFormDesignService.filteredCells;
|
|
1854
1790
|
this.coreFormDesignService.resetFormDesignState();
|
|
1855
1791
|
effect(() => {
|
|
1856
1792
|
const _ = this.coreFormDesignService.$placeholderSections();
|
|
@@ -2192,60 +2128,6 @@ class CoreFormDesignComponent extends BaseComponent {
|
|
|
2192
2128
|
this.coreFormDesignService.$selectedCell.set({ ...cell });
|
|
2193
2129
|
this.coreFormDesignService.$fieldSettingPanelOpen.set(true);
|
|
2194
2130
|
}
|
|
2195
|
-
/*
|
|
2196
|
-
deleteField(row: IFormDesignRow | undefined, colIndex: number): void {
|
|
2197
|
-
if (!row || !row.cells[colIndex]) return;
|
|
2198
|
-
const cellToDelete = row.cells[colIndex];
|
|
2199
|
-
if (!cellToDelete.control) return;
|
|
2200
|
-
|
|
2201
|
-
if (confirm('Are you sure to remove the field?')) {
|
|
2202
|
-
|
|
2203
|
-
// 🧠 Check if it's selected
|
|
2204
|
-
const selectedCell = this.coreFormDesignService.$selectedCell();
|
|
2205
|
-
const shouldClearSelection = selectedCell === cellToDelete;
|
|
2206
|
-
let deletedControl: IFormBaseControl | null = null;
|
|
2207
|
-
|
|
2208
|
-
// ✅ Update the reactive state
|
|
2209
|
-
this.coreFormDesignService.$placeholderSections.update(sections => {
|
|
2210
|
-
for (const section of sections) {
|
|
2211
|
-
for (const r of section.rows) {
|
|
2212
|
-
if (r === row) {
|
|
2213
|
-
const control = r.cells[colIndex].control;
|
|
2214
|
-
if (control && control.field && control.flexSize !== undefined) {
|
|
2215
|
-
deletedControl = control as IFormBaseControl; // ✅ Save before removing
|
|
2216
|
-
}
|
|
2217
|
-
r.cells[colIndex].control = { flexSize: r.cells[colIndex].control?.flexSize }; // ❌ Clear after
|
|
2218
|
-
break;
|
|
2219
|
-
}
|
|
2220
|
-
}
|
|
2221
|
-
}
|
|
2222
|
-
return sections;
|
|
2223
|
-
});
|
|
2224
|
-
|
|
2225
|
-
if (deletedControl) {
|
|
2226
|
-
this.coreFormDesignService.$placeholderSections.update(sections => {
|
|
2227
|
-
for (const section of sections) {
|
|
2228
|
-
for (const row of section.rows) {
|
|
2229
|
-
if (!!row) {
|
|
2230
|
-
row.cells = row.cells.filter(cell => cell.control?.field !== deletedControl?.assignTo);
|
|
2231
|
-
}
|
|
2232
|
-
}
|
|
2233
|
-
}
|
|
2234
|
-
return sections;
|
|
2235
|
-
});
|
|
2236
|
-
}
|
|
2237
|
-
|
|
2238
|
-
// ❌ Clear selection if needed
|
|
2239
|
-
if (shouldClearSelection) {
|
|
2240
|
-
this.coreFormDesignService.$selectedCell.set(null);
|
|
2241
|
-
}
|
|
2242
|
-
|
|
2243
|
-
console.log("this.coreFormDesignService.$placeholderSections before triggerUpdateSections", this.coreFormDesignService.$placeholderSections())
|
|
2244
|
-
this.triggerUpdateSections();
|
|
2245
|
-
}
|
|
2246
|
-
}
|
|
2247
|
-
*/
|
|
2248
|
-
// Anti AI version
|
|
2249
2131
|
deleteField(row, sectionIndex, rowIndex, colIndex) {
|
|
2250
2132
|
if (!row)
|
|
2251
2133
|
return;
|
|
@@ -2378,10 +2260,969 @@ class CoreFormDesignComponent extends BaseComponent {
|
|
|
2378
2260
|
return false;
|
|
2379
2261
|
return control.validators.some((v) => v.name === 'required' || v.name === 'requiredTrue');
|
|
2380
2262
|
}
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2263
|
+
onFormDesignCreated(e) {
|
|
2264
|
+
console.log("onFormDesignCreated", e);
|
|
2265
|
+
}
|
|
2266
|
+
onLiveFormCreated(e) {
|
|
2267
|
+
console.log("onLiveFormCreated", e);
|
|
2268
|
+
}
|
|
2269
|
+
showMetadata() {
|
|
2270
|
+
this.coreFormDesignService.$showFormMetadata.set(true);
|
|
2271
|
+
}
|
|
2272
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormGroupEditorComponent, deps: [{ token: MultiLanguageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2273
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: CoreFormGroupEditorComponent, isStandalone: true, selector: "core-form-group-editor", inputs: { $isNested: { classPropertyName: "$isNested", publicName: "$isNested", isSignal: true, isRequired: false, transformFunction: null }, $idAsInput: { classPropertyName: "$idAsInput", publicName: "$idAsInput", isSignal: true, isRequired: false, transformFunction: null }, $id: { classPropertyName: "$id", publicName: "$id", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "$settingPanel", first: true, predicate: ["settingPanel"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"core-form-group-editor-container\">\r\n\r\n <div class=\"form-design-right\">\r\n\r\n @if (coreFormDesignService.$mode() === enumType.Default) {\r\n <div class=\"form-wrapper\">\r\n\r\n @if (!$isNested() && !!coreFormDesignService.$isInWorkflowDesign()) {\r\n <form-metadata></form-metadata>\r\n }\r\n\r\n <form [formGroup]=\"formDesign\" autocomplete=\"off\">\r\n <div class=\"form-cells\"> \r\n\r\n <div class=\"form-tool-bar\">\r\n @if (!$isNested() && !$hasCalculatedSection()) {\r\n <button class=\"core-button-vns-container\" (click)=\"addCalculatedSection()\">+ Calculated fields</button>\r\n }\r\n <button class=\"core-button-vns-container\" (click)=\"addSection()\">+ Add Section</button>\r\n </div>\r\n \r\n @for (section of coreFormDesignService.$placeholderSections(); track $index; let sectionIndex = $index) {\r\n <div class=\"form-section-placeholder\">\r\n\r\n <div class=\"section-header\">\r\n\r\n <div class=\"section-img-wrapper\">\r\n <div class=\"section-img\" [class.calculated]=\"section.forCalculatedFields\"></div>\r\n </div>\r\n\r\n <label [attr.contenteditable]=\"!section.forCalculatedFields\"\r\n [htmlTooltip]=\"!!section.forCalculatedFields ? calculatedFieldsTooltip : null\"\r\n (blur)=\"onCaptionEditEnd(sectionIndex, $event)\"\r\n (keydown.enter)=\"onCaptionEditEnd(sectionIndex, $event); $event.preventDefault()\"\r\n >{{ section.caption }}</label>\r\n\r\n <div class=\"section-tool pointer\" (click)=\"deleteSection(sectionIndex)\" [appTooltip]=\"'Delete section'\" [showAnyway]=\"true\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n \r\n </div>\r\n \r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n\r\n <div class=\"form-row-wrapper\">\r\n <div class=\"form-row\">\r\n @for (cell of filteredCells(row); track $index; let colIndex = $index) {\r\n <div class=\"form-cell drop-target\" \r\n [ngStyle]=\"{ flex: (cell.flexSize ?? 0) + ' 1 0%' }\"\r\n [attr.data-flex]=\"cell.flexSize ?? 0\"\r\n (drop)=\"onDropIntoCell($event, sectionIndex, rowIndex, colIndex)\"\r\n (dragover)=\"onDragOver($event, section, cell.control!)\"\r\n (dragenter)=\"onDragEnter(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n (dragleave)=\"onDragLeave(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n [class.selected]=\"cell?.selected\"\r\n [class.dragging-over]=\"isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]\"\r\n [class.has-control]=\"!!cell && !!cell.control && !!getControl(cell)\"\r\n (click)=\"onCellClicked(sectionIndex, rowIndex, colIndex)\"\r\n >\r\n\r\n\r\n @if (!isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]) {\r\n\r\n @if (!!cell && !!cell.control && !!getControl(cell)) {\r\n <label contenteditable=\"true\"\r\n (blur)=\"onFieldCaptionEditEnd(cell, $event)\"\r\n (keydown.enter)=\"onFieldCaptionEditEnd(cell, $event); $event.preventDefault()\"\r\n [class.d-none]=\"!!getControl(cell)?.hidden\"\r\n [class.required]=\"!!cell && !!cell.control && !!getControl(cell) && isRequired(getControl(cell))\"\r\n >{{ cell.control.label || 'label' }}</label>\r\n\r\n @if (cell.control.controlType==='CALCULATED') {\r\n <div class=\"control-wrapper\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\">\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n </div>\r\n } @else {\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n }\r\n \r\n <div class=\"field-toolbar\">\r\n <ul>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Show settings'\">\r\n <i class=\"feather-settings\"></i>\r\n </div>\r\n </li>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"deleteField(row, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Remove field from cell'\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n \r\n } @else {\r\n <div class=\"calculated-placeholder\" [class.calculated]=\"!!section.forCalculatedFields\">\r\n {{ !!section.forCalculatedFields ? 'Drop calculated field here' : 'Drop here'}}\r\n </div>\r\n }\r\n\r\n @if (cell?.selected && canMergeCells(sectionIndex, rowIndex)) {\r\n <div class=\"merge-toolbar\">\r\n <button (click)=\"mergeCells(sectionIndex, rowIndex)\">\uD83D\uDD17 Merge</button>\r\n </div>\r\n }\r\n \r\n }\r\n\r\n </div>\r\n }\r\n </div>\r\n <div class=\"row-tool-bar\">\r\n <div class=\"icon-wrapper\" (click)=\"deleteRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Delete row'\" [showAnyway]=\"true\"><i class=\"feather-x\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addRow(sectionIndex)\" [appTooltip]=\"'Add row'\" [showAnyway]=\"true\"><i class=\"feather-arrow-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"insertRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Insert row'\" [showAnyway]=\"true\"><i class=\"feather-corner-right-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addColumn(row)\" [appTooltip]=\"'Add column'\" [showAnyway]=\"true\"><i class=\"feather-arrow-right\"></i></div>\r\n </div>\r\n </div>\r\n\r\n }\r\n </div>\r\n }\r\n \r\n \r\n </div>\r\n </form>\r\n </div>\r\n } @else if (!!$sections()) {\r\n\r\n @if(!!(injectedFields$ | async) && !!(injectedFields$ | async)!.length) {\r\n\r\n @if (!!coreFormDesignService.$afInstance().normalMode) {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" />\r\n } @else {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" ($onClose)=\"closePreview()\" />\r\n }\r\n\r\n } @else {\r\n <h2>COULD NOT UPDATE injectedFields$</h2>\r\n }\r\n\r\n } @else {\r\n <h2>$sections() empty / null / undefined</h2>\r\n }\r\n </div>\r\n</div>\r\n\r\n<ng-template #calculatedFieldsTooltip>\r\n <div style=\"max-width: 280px;\">\r\n <strong>Calculated Fields</strong><br />\r\n <p></p>\r\n These fields are hidden from the form and cannot be edited directly.<br /><br />\r\n - They are computed automatically during workflow execution.<br />\r\n - Each field depends on one or more standard input fields.<br />\r\n - The calculation is evaluated using either an SQL query engine (like <strong>Dapper</strong>) or an in-memory expression engine (like <strong>Dynamic Expresso</strong>).<br /><br />\r\n These results can be used to influence workflow logic, rule trees, or approval paths.\r\n </div>\r\n</ng-template>\r\n\r\n\r\n ", styles: ["@charset \"UTF-8\";.core-form-group-editor-container{position:relative;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));width:100%;overflow:hidden;background-color:#eff0f1;font-size:13px}.core-form-group-editor-container .core-button-vns-container{margin-right:8px!important}.core-form-group-editor-container .core-button-vns-container:last-child{background-color:#000;color:#fff;margin-right:0}.core-form-group-editor-container .af-metadata-overlay{position:fixed;top:60px;left:66px;background:#fff;box-shadow:.4rem 0 2rem #0000002e;z-index:1000;width:1214px;height:calc(100vh - 75px);overflow-y:auto;pointer-events:none}.core-form-group-editor-container .af-metadata-overlay.shown{pointer-events:auto}.core-form-group-editor-container *{border-radius:0}.core-form-group-editor-container ul,.core-form-group-editor-container li{padding:0}.core-form-group-editor-container li{max-width:200px}.core-form-group-editor-container ul div.space{display:block;height:15px}.core-form-group-editor-container li.full-width{max-width:100%}.core-form-group-editor-container .field-setting-panel{display:block;position:fixed;width:360px;height:100vh;top:0;right:-360px;background-color:#fff;box-shadow:.4rem 0 2rem #0000002e;transition:right .5s ease-out}.core-form-group-editor-container .field-setting-panel .close-wrapper{width:32px;height:32px;position:absolute;top:15px;right:15px;display:flex;background-color:#848484;border-radius:50%}.core-form-group-editor-container .field-setting-panel .close-wrapper i{width:16px;height:16px;font-size:18px;color:#848484}.core-form-group-editor-container .field-setting-panel .panel-caption{margin-bottom:1rem;padding-bottom:.5rem;border-bottom:1px solid #ddd;width:100%;overflow:hidden;text-wrap:nowrap;text-overflow:ellipsis}.core-form-group-editor-container .field-setting-panel.calculated-type{width:500px;right:-500px}.core-form-group-editor-container .field-setting-panel.calculated-type textarea{border-radius:8px;height:150px}.core-form-group-editor-container .field-setting-panel.open{right:0}.core-form-group-editor-container .form-design-left{position:absolute;top:var(--size-core-page-header-height);bottom:0;left:0;z-index:1;width:360px;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px;padding-right:calc(15px + var(--size-scrollbar-width));background-color:#87ceeb;overflow-y:hidden}.core-form-group-editor-container .form-design-left .category-name{color:#fff}.core-form-group-editor-container .form-design-left .grid-buffer-wrapper{background-color:#fff;padding:15px}.core-form-group-editor-container .form-design-left ul:last-child{padding-bottom:400px}.core-form-group-editor-container .form-design-left .category-name{margin-bottom:15px}.core-form-group-editor-container .form-design-left .json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;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;width:330px;height:calc(100vh - 205px)}.core-form-group-editor-container .form-design-left button{height:35px;border-radius:0;margin-bottom:15px;color:#fff;border:none;font-size:13px;background-color:transparent}.core-form-group-editor-container .form-design-left:hover{overflow-y:auto;padding-right:15px}.core-form-group-editor-container .form-design-right{width:100%;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));overflow-y:auto}.core-form-group-editor-container .form-design-right .form-wrapper{width:100%;overflow-y:visible;background-color:#fff}.core-form-group-editor-container .form-design-right .form-wrapper button{margin-left:12px;padding:4px 10px;border:1px solid #ccc;cursor:pointer;transition:all .2s;width:110px}.core-form-group-editor-container .form-design-right .form-wrapper button:hover{background-color:#e4f0ff;border-color:#007bff;color:#007bff}.core-form-group-editor-container .form-design-right .form-wrapper .form-tool-bar{display:flex;align-items:center;justify-content:flex-end}.core-form-group-editor-container .form-design-right .form-wrapper .form-tool-bar>button{width:150px;margin:0}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells{display:flex;flex-direction:column;gap:32px;padding:20px 15px 15px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder{padding:12px 15px;border:1px dashed #ccc;background-color:#fff;box-shadow:0 2px 6px #0000000a}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header{display:flex;position:relative;align-items:center;justify-content:flex-start;font-weight:600;margin-bottom:12px;color:#333}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img{width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center;margin-right:8px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);background-color:transparent;border-radius:0}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool{position:absolute;right:5px;top:6px;display:none;z-index:2;color:gray}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool i{font-size:24px;color:#848484}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header:hover .section-tool{display:block}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .row-tool-bar{display:flex;align-items:center;justify-content:flex-end;margin-bottom:8px;height:24px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-row{display:flex;gap:15px;margin-bottom:15px;min-height:50px;background-color:#d3d3d3;padding:8px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell{flex:1;min-height:90px;background-color:#fcfcfc;border:1px dashed #ccc;position:relative;padding:20px 10px 10px;transition:border .2s ease-in-out}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell:before{content:attr(data-flex);position:absolute;top:2px;left:4px;font-size:10px;color:#999}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell label.required:after{content:\" *\";color:#ff040b}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar{position:absolute;right:7px;top:6px;display:none;z-index:2;color:gray}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul{display:flex}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div{display:flex;width:24px;height:24px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div i{font-size:18px;width:18px;height:18px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.has-control:hover .field-toolbar{display:flex}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.active-drop{border-color:#007bff;background-color:#eef6ff;transition:.2s}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .calculated-placeholder{display:flex;align-items:center;justify-content:center;background-color:#fff;color:#007bff;padding:15px 0;width:100%;cursor:default}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .calculated-placeholder.calculated{color:#ff4500}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper{width:24px;height:24px;border-radius:50%;padding:0;cursor:pointer;display:none;color:gray;border:1px solid gray;margin-left:8px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper i{font-size:18px;width:18px;height:18px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper:hover .icon-wrapper{display:flex}.core-form-group-editor-container .form-design-right .form-wrapper .form-cell.selected{background-color:#dff6dd}.core-form-group-editor-container .form-design-right .form-wrapper .merge-toolbar{text-align:center;margin-top:4px}.core-form-group-editor-container .form-design-right .form-wrapper.live-form{padding-bottom:15px}.core-form-group-editor-container .form-design-right .form-wrapper.live-form .live-form-header{padding:0 15px}.core-form-group-editor-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon{position:absolute;right:7px;top:6px;z-index:2;color:gray;cursor:pointer}.core-form-group-editor-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon i{font-size:18px}.core-form-group-editor-container .drop-target{min-height:50px;min-width:50px;border:2px dashed transparent;transition:border .2s ease}.core-form-group-editor-container .drop-target.active-drop{border-color:#007bff;background-color:#eaf4ff}.core-form-group-editor-container .no-padding{padding:0!important}.core-form-group-editor-container .modal-content-root{overflow:visible}\n", ".core-form-container{overflow-x:visible}.core-form-container>form .section{margin-top:var(--size-layout-block-cell-spacing)}.core-form-container>form .section:not(:first-child){margin-top:calc(var(--size-layout-block-cell-spacing) * 2)}.core-form-container>form .section .section-header-label{display:block;height:34px;line-height:34px;margin-bottom:15px;margin-left:12px}.core-form-container>form .section .section-header-label .section-img-wrapper{position:relative}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img{position:absolute;width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);border-radius:0;background-color:transparent}.core-form-container>form .section .section-header-label .section-calc-wrapper{width:34px;height:34px;display:flex;align-items:center;justify-content:center;background-color:#d3d3d3;border-radius:50%}.core-form-container>form .section .section-header-label .section-calc-wrapper i{width:24px;height:24px;font-size:24px;color:#1b4332}.core-form-container>form .section .section-header-label .section-caption{padding-left:40px;font-weight:700;color:#696969}.core-form-container .row{margin-left:var(--size-layout-block-cell-spacing) 0px;margin-right:var(--size-layout-block-cell-spacing) 0px}.core-form-container .row .grid-buffer{border:dotted 2px darkgray}.core-form-container .row .button-control{display:flex;align-items:flex-end}.core-form-container .form-row{margin:var(--size-layout-block-cell-spacing) 0px;display:flex;align-items:center;justify-content:center}.core-form-container .form-row>button{cursor:pointer;border-radius:0}.core-form-container .form-row>button:not(:first-child){margin-left:var(--size-layout-block-cell-spacing)}.core-form-container .dev-button{cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;padding:8px;width:120px;border-radius:18px;box-shadow:.4rem 0 2rem #0000002e}.core-form-container .dev-button:not(:last-child){margin-right:15px}.core-form-container .dev-button:first-child{background-color:#dff6dd;border:1px #9fdc9d solid}.core-form-container .dev-button:last-child{background-color:#fff4ce;border:1px #ffda6a solid}.core-form-container .payload-preview{display:block;width:calc(100% - 48px);height:200px;white-space:pre-wrap;overflow-x:hidden;overflow-y:auto;background-color:#dff6dd;padding:24px;margin:24px;text-indent:-58px;color:#333!important;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;line-height:1.5}.core-form-container .payload-preview.validator-preview{background-color:#fff4ce}.core-form-container .bottom-template-wrapper{padding-left:12px;padding-right:12px}.core-form-container .w-100{width:100%}.core-form-container .pr18{padding-right:18px}\n", ".core-button-vns-container{height:30px;display:flex;align-items:center;justify-content:center;min-width:30px}.core-button-vns-container .action-wrapper{height:30px!important;width:30px!important;display:flex;align-items:center;justify-content:center}.core-button-vns-container .action-wrapper:has(i:hover){background-color:#e7e7e7;border-radius:50%}.core-button-vns-container .btn-for-form{border:none;border-radius:0;background-color:transparent;color:#000;min-width:120px}.core-button-vns-container button.last-child{background-color:#000;color:#fff}.core-button-vns-container .action-wrapper.last-child{background-color:var(--color-basic-orange);color:#fff;border-radius:50%}.core-button-vns-container .action-wrapper.last-child:hover{background-color:var(--color-basic-orange);box-shadow:0 1rem 3rem #0000002e}.core-button-vns-container .temporary-unavailable{user-select:none;-moz-user-select:none;-webkit-user-select:none;cursor:not-allowed!important;opacity:.5}.core-button-vns-container .temporary-unavailable:hover{background-color:transparent!important}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: FormMetadataComponent, selector: "form-metadata" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: TooltipDirective, selector: "[appTooltip]", inputs: ["color", "backgroundColor", "appTooltip", "showAnyway", "position"] }, { kind: "component", type: CoreControlComponent, selector: "core-control", inputs: ["control", "form", "checkError$", "rangeLimit"] }, { kind: "component", type: LiveFormComponent, selector: "live-form", inputs: ["$designMode", "$forKickOff", "$workflowReactContext"], outputs: ["$onClose"] }, { kind: "directive", type: HtmlTooltipDirective, selector: "[htmlTooltip]", inputs: ["htmlTooltip", "tooltipContext", "maxWidthUnset", "backgroundColor"] }], animations: [slideFromTopFadeIn], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2274
|
+
}
|
|
2275
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormGroupEditorComponent, decorators: [{
|
|
2276
|
+
type: Component,
|
|
2277
|
+
args: [{ selector: 'core-form-group-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2278
|
+
NgStyle,
|
|
2279
|
+
AsyncPipe,
|
|
2280
|
+
NgTemplateOutlet,
|
|
2281
|
+
CoreFormArrayLayoutEditorComponent,
|
|
2282
|
+
CoreToastLoadingComponent,
|
|
2283
|
+
CorePageHeaderComponent,
|
|
2284
|
+
FormMetadataComponent,
|
|
2285
|
+
ReactiveFormsModule,
|
|
2286
|
+
TranslatePipe,
|
|
2287
|
+
TableCellPipe,
|
|
2288
|
+
TooltipDirective,
|
|
2289
|
+
HotKeysDirective,
|
|
2290
|
+
CoreFormComponent,
|
|
2291
|
+
CoreControlComponent,
|
|
2292
|
+
CoreDropdownComponent,
|
|
2293
|
+
CoreChecklistComponent,
|
|
2294
|
+
CoreFormControlSeekerComponent,
|
|
2295
|
+
CoreCheckboxComponent,
|
|
2296
|
+
CoreAttachmentComponent,
|
|
2297
|
+
CoreDatePickerComponent,
|
|
2298
|
+
CoreRadioGroupComponent,
|
|
2299
|
+
CoreMonthSelectorComponent,
|
|
2300
|
+
TooltipDirective,
|
|
2301
|
+
CoreCurrencyInputComponent,
|
|
2302
|
+
FieldSettingComponent,
|
|
2303
|
+
LiveFormComponent,
|
|
2304
|
+
HtmlTooltipDirective,
|
|
2305
|
+
], animations: [slideFromTopFadeIn], template: "<div class=\"core-form-group-editor-container\">\r\n\r\n <div class=\"form-design-right\">\r\n\r\n @if (coreFormDesignService.$mode() === enumType.Default) {\r\n <div class=\"form-wrapper\">\r\n\r\n @if (!$isNested() && !!coreFormDesignService.$isInWorkflowDesign()) {\r\n <form-metadata></form-metadata>\r\n }\r\n\r\n <form [formGroup]=\"formDesign\" autocomplete=\"off\">\r\n <div class=\"form-cells\"> \r\n\r\n <div class=\"form-tool-bar\">\r\n @if (!$isNested() && !$hasCalculatedSection()) {\r\n <button class=\"core-button-vns-container\" (click)=\"addCalculatedSection()\">+ Calculated fields</button>\r\n }\r\n <button class=\"core-button-vns-container\" (click)=\"addSection()\">+ Add Section</button>\r\n </div>\r\n \r\n @for (section of coreFormDesignService.$placeholderSections(); track $index; let sectionIndex = $index) {\r\n <div class=\"form-section-placeholder\">\r\n\r\n <div class=\"section-header\">\r\n\r\n <div class=\"section-img-wrapper\">\r\n <div class=\"section-img\" [class.calculated]=\"section.forCalculatedFields\"></div>\r\n </div>\r\n\r\n <label [attr.contenteditable]=\"!section.forCalculatedFields\"\r\n [htmlTooltip]=\"!!section.forCalculatedFields ? calculatedFieldsTooltip : null\"\r\n (blur)=\"onCaptionEditEnd(sectionIndex, $event)\"\r\n (keydown.enter)=\"onCaptionEditEnd(sectionIndex, $event); $event.preventDefault()\"\r\n >{{ section.caption }}</label>\r\n\r\n <div class=\"section-tool pointer\" (click)=\"deleteSection(sectionIndex)\" [appTooltip]=\"'Delete section'\" [showAnyway]=\"true\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n \r\n </div>\r\n \r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n\r\n <div class=\"form-row-wrapper\">\r\n <div class=\"form-row\">\r\n @for (cell of filteredCells(row); track $index; let colIndex = $index) {\r\n <div class=\"form-cell drop-target\" \r\n [ngStyle]=\"{ flex: (cell.flexSize ?? 0) + ' 1 0%' }\"\r\n [attr.data-flex]=\"cell.flexSize ?? 0\"\r\n (drop)=\"onDropIntoCell($event, sectionIndex, rowIndex, colIndex)\"\r\n (dragover)=\"onDragOver($event, section, cell.control!)\"\r\n (dragenter)=\"onDragEnter(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n (dragleave)=\"onDragLeave(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n [class.selected]=\"cell?.selected\"\r\n [class.dragging-over]=\"isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]\"\r\n [class.has-control]=\"!!cell && !!cell.control && !!getControl(cell)\"\r\n (click)=\"onCellClicked(sectionIndex, rowIndex, colIndex)\"\r\n >\r\n\r\n\r\n @if (!isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]) {\r\n\r\n @if (!!cell && !!cell.control && !!getControl(cell)) {\r\n <label contenteditable=\"true\"\r\n (blur)=\"onFieldCaptionEditEnd(cell, $event)\"\r\n (keydown.enter)=\"onFieldCaptionEditEnd(cell, $event); $event.preventDefault()\"\r\n [class.d-none]=\"!!getControl(cell)?.hidden\"\r\n [class.required]=\"!!cell && !!cell.control && !!getControl(cell) && isRequired(getControl(cell))\"\r\n >{{ cell.control.label || 'label' }}</label>\r\n\r\n @if (cell.control.controlType==='CALCULATED') {\r\n <div class=\"control-wrapper\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\">\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n </div>\r\n } @else {\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n }\r\n \r\n <div class=\"field-toolbar\">\r\n <ul>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Show settings'\">\r\n <i class=\"feather-settings\"></i>\r\n </div>\r\n </li>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"deleteField(row, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Remove field from cell'\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n \r\n } @else {\r\n <div class=\"calculated-placeholder\" [class.calculated]=\"!!section.forCalculatedFields\">\r\n {{ !!section.forCalculatedFields ? 'Drop calculated field here' : 'Drop here'}}\r\n </div>\r\n }\r\n\r\n @if (cell?.selected && canMergeCells(sectionIndex, rowIndex)) {\r\n <div class=\"merge-toolbar\">\r\n <button (click)=\"mergeCells(sectionIndex, rowIndex)\">\uD83D\uDD17 Merge</button>\r\n </div>\r\n }\r\n \r\n }\r\n\r\n </div>\r\n }\r\n </div>\r\n <div class=\"row-tool-bar\">\r\n <div class=\"icon-wrapper\" (click)=\"deleteRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Delete row'\" [showAnyway]=\"true\"><i class=\"feather-x\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addRow(sectionIndex)\" [appTooltip]=\"'Add row'\" [showAnyway]=\"true\"><i class=\"feather-arrow-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"insertRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Insert row'\" [showAnyway]=\"true\"><i class=\"feather-corner-right-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addColumn(row)\" [appTooltip]=\"'Add column'\" [showAnyway]=\"true\"><i class=\"feather-arrow-right\"></i></div>\r\n </div>\r\n </div>\r\n\r\n }\r\n </div>\r\n }\r\n \r\n \r\n </div>\r\n </form>\r\n </div>\r\n } @else if (!!$sections()) {\r\n\r\n @if(!!(injectedFields$ | async) && !!(injectedFields$ | async)!.length) {\r\n\r\n @if (!!coreFormDesignService.$afInstance().normalMode) {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" />\r\n } @else {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" ($onClose)=\"closePreview()\" />\r\n }\r\n\r\n } @else {\r\n <h2>COULD NOT UPDATE injectedFields$</h2>\r\n }\r\n\r\n } @else {\r\n <h2>$sections() empty / null / undefined</h2>\r\n }\r\n </div>\r\n</div>\r\n\r\n<ng-template #calculatedFieldsTooltip>\r\n <div style=\"max-width: 280px;\">\r\n <strong>Calculated Fields</strong><br />\r\n <p></p>\r\n These fields are hidden from the form and cannot be edited directly.<br /><br />\r\n - They are computed automatically during workflow execution.<br />\r\n - Each field depends on one or more standard input fields.<br />\r\n - The calculation is evaluated using either an SQL query engine (like <strong>Dapper</strong>) or an in-memory expression engine (like <strong>Dynamic Expresso</strong>).<br /><br />\r\n These results can be used to influence workflow logic, rule trees, or approval paths.\r\n </div>\r\n</ng-template>\r\n\r\n\r\n ", styles: ["@charset \"UTF-8\";.core-form-group-editor-container{position:relative;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));width:100%;overflow:hidden;background-color:#eff0f1;font-size:13px}.core-form-group-editor-container .core-button-vns-container{margin-right:8px!important}.core-form-group-editor-container .core-button-vns-container:last-child{background-color:#000;color:#fff;margin-right:0}.core-form-group-editor-container .af-metadata-overlay{position:fixed;top:60px;left:66px;background:#fff;box-shadow:.4rem 0 2rem #0000002e;z-index:1000;width:1214px;height:calc(100vh - 75px);overflow-y:auto;pointer-events:none}.core-form-group-editor-container .af-metadata-overlay.shown{pointer-events:auto}.core-form-group-editor-container *{border-radius:0}.core-form-group-editor-container ul,.core-form-group-editor-container li{padding:0}.core-form-group-editor-container li{max-width:200px}.core-form-group-editor-container ul div.space{display:block;height:15px}.core-form-group-editor-container li.full-width{max-width:100%}.core-form-group-editor-container .field-setting-panel{display:block;position:fixed;width:360px;height:100vh;top:0;right:-360px;background-color:#fff;box-shadow:.4rem 0 2rem #0000002e;transition:right .5s ease-out}.core-form-group-editor-container .field-setting-panel .close-wrapper{width:32px;height:32px;position:absolute;top:15px;right:15px;display:flex;background-color:#848484;border-radius:50%}.core-form-group-editor-container .field-setting-panel .close-wrapper i{width:16px;height:16px;font-size:18px;color:#848484}.core-form-group-editor-container .field-setting-panel .panel-caption{margin-bottom:1rem;padding-bottom:.5rem;border-bottom:1px solid #ddd;width:100%;overflow:hidden;text-wrap:nowrap;text-overflow:ellipsis}.core-form-group-editor-container .field-setting-panel.calculated-type{width:500px;right:-500px}.core-form-group-editor-container .field-setting-panel.calculated-type textarea{border-radius:8px;height:150px}.core-form-group-editor-container .field-setting-panel.open{right:0}.core-form-group-editor-container .form-design-left{position:absolute;top:var(--size-core-page-header-height);bottom:0;left:0;z-index:1;width:360px;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px;padding-right:calc(15px + var(--size-scrollbar-width));background-color:#87ceeb;overflow-y:hidden}.core-form-group-editor-container .form-design-left .category-name{color:#fff}.core-form-group-editor-container .form-design-left .grid-buffer-wrapper{background-color:#fff;padding:15px}.core-form-group-editor-container .form-design-left ul:last-child{padding-bottom:400px}.core-form-group-editor-container .form-design-left .category-name{margin-bottom:15px}.core-form-group-editor-container .form-design-left .json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;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;width:330px;height:calc(100vh - 205px)}.core-form-group-editor-container .form-design-left button{height:35px;border-radius:0;margin-bottom:15px;color:#fff;border:none;font-size:13px;background-color:transparent}.core-form-group-editor-container .form-design-left:hover{overflow-y:auto;padding-right:15px}.core-form-group-editor-container .form-design-right{width:100%;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));overflow-y:auto}.core-form-group-editor-container .form-design-right .form-wrapper{width:100%;overflow-y:visible;background-color:#fff}.core-form-group-editor-container .form-design-right .form-wrapper button{margin-left:12px;padding:4px 10px;border:1px solid #ccc;cursor:pointer;transition:all .2s;width:110px}.core-form-group-editor-container .form-design-right .form-wrapper button:hover{background-color:#e4f0ff;border-color:#007bff;color:#007bff}.core-form-group-editor-container .form-design-right .form-wrapper .form-tool-bar{display:flex;align-items:center;justify-content:flex-end}.core-form-group-editor-container .form-design-right .form-wrapper .form-tool-bar>button{width:150px;margin:0}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells{display:flex;flex-direction:column;gap:32px;padding:20px 15px 15px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder{padding:12px 15px;border:1px dashed #ccc;background-color:#fff;box-shadow:0 2px 6px #0000000a}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header{display:flex;position:relative;align-items:center;justify-content:flex-start;font-weight:600;margin-bottom:12px;color:#333}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img{width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center;margin-right:8px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);background-color:transparent;border-radius:0}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool{position:absolute;right:5px;top:6px;display:none;z-index:2;color:gray}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool i{font-size:24px;color:#848484}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header:hover .section-tool{display:block}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .row-tool-bar{display:flex;align-items:center;justify-content:flex-end;margin-bottom:8px;height:24px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-row{display:flex;gap:15px;margin-bottom:15px;min-height:50px;background-color:#d3d3d3;padding:8px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell{flex:1;min-height:90px;background-color:#fcfcfc;border:1px dashed #ccc;position:relative;padding:20px 10px 10px;transition:border .2s ease-in-out}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell:before{content:attr(data-flex);position:absolute;top:2px;left:4px;font-size:10px;color:#999}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell label.required:after{content:\" *\";color:#ff040b}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar{position:absolute;right:7px;top:6px;display:none;z-index:2;color:gray}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul{display:flex}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div{display:flex;width:24px;height:24px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div i{font-size:18px;width:18px;height:18px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.has-control:hover .field-toolbar{display:flex}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.active-drop{border-color:#007bff;background-color:#eef6ff;transition:.2s}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .calculated-placeholder{display:flex;align-items:center;justify-content:center;background-color:#fff;color:#007bff;padding:15px 0;width:100%;cursor:default}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .calculated-placeholder.calculated{color:#ff4500}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper{width:24px;height:24px;border-radius:50%;padding:0;cursor:pointer;display:none;color:gray;border:1px solid gray;margin-left:8px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper i{font-size:18px;width:18px;height:18px}.core-form-group-editor-container .form-design-right .form-wrapper .form-cells .form-row-wrapper:hover .icon-wrapper{display:flex}.core-form-group-editor-container .form-design-right .form-wrapper .form-cell.selected{background-color:#dff6dd}.core-form-group-editor-container .form-design-right .form-wrapper .merge-toolbar{text-align:center;margin-top:4px}.core-form-group-editor-container .form-design-right .form-wrapper.live-form{padding-bottom:15px}.core-form-group-editor-container .form-design-right .form-wrapper.live-form .live-form-header{padding:0 15px}.core-form-group-editor-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon{position:absolute;right:7px;top:6px;z-index:2;color:gray;cursor:pointer}.core-form-group-editor-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon i{font-size:18px}.core-form-group-editor-container .drop-target{min-height:50px;min-width:50px;border:2px dashed transparent;transition:border .2s ease}.core-form-group-editor-container .drop-target.active-drop{border-color:#007bff;background-color:#eaf4ff}.core-form-group-editor-container .no-padding{padding:0!important}.core-form-group-editor-container .modal-content-root{overflow:visible}\n", ".core-form-container{overflow-x:visible}.core-form-container>form .section{margin-top:var(--size-layout-block-cell-spacing)}.core-form-container>form .section:not(:first-child){margin-top:calc(var(--size-layout-block-cell-spacing) * 2)}.core-form-container>form .section .section-header-label{display:block;height:34px;line-height:34px;margin-bottom:15px;margin-left:12px}.core-form-container>form .section .section-header-label .section-img-wrapper{position:relative}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img{position:absolute;width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);border-radius:0;background-color:transparent}.core-form-container>form .section .section-header-label .section-calc-wrapper{width:34px;height:34px;display:flex;align-items:center;justify-content:center;background-color:#d3d3d3;border-radius:50%}.core-form-container>form .section .section-header-label .section-calc-wrapper i{width:24px;height:24px;font-size:24px;color:#1b4332}.core-form-container>form .section .section-header-label .section-caption{padding-left:40px;font-weight:700;color:#696969}.core-form-container .row{margin-left:var(--size-layout-block-cell-spacing) 0px;margin-right:var(--size-layout-block-cell-spacing) 0px}.core-form-container .row .grid-buffer{border:dotted 2px darkgray}.core-form-container .row .button-control{display:flex;align-items:flex-end}.core-form-container .form-row{margin:var(--size-layout-block-cell-spacing) 0px;display:flex;align-items:center;justify-content:center}.core-form-container .form-row>button{cursor:pointer;border-radius:0}.core-form-container .form-row>button:not(:first-child){margin-left:var(--size-layout-block-cell-spacing)}.core-form-container .dev-button{cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;padding:8px;width:120px;border-radius:18px;box-shadow:.4rem 0 2rem #0000002e}.core-form-container .dev-button:not(:last-child){margin-right:15px}.core-form-container .dev-button:first-child{background-color:#dff6dd;border:1px #9fdc9d solid}.core-form-container .dev-button:last-child{background-color:#fff4ce;border:1px #ffda6a solid}.core-form-container .payload-preview{display:block;width:calc(100% - 48px);height:200px;white-space:pre-wrap;overflow-x:hidden;overflow-y:auto;background-color:#dff6dd;padding:24px;margin:24px;text-indent:-58px;color:#333!important;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;line-height:1.5}.core-form-container .payload-preview.validator-preview{background-color:#fff4ce}.core-form-container .bottom-template-wrapper{padding-left:12px;padding-right:12px}.core-form-container .w-100{width:100%}.core-form-container .pr18{padding-right:18px}\n", ".core-button-vns-container{height:30px;display:flex;align-items:center;justify-content:center;min-width:30px}.core-button-vns-container .action-wrapper{height:30px!important;width:30px!important;display:flex;align-items:center;justify-content:center}.core-button-vns-container .action-wrapper:has(i:hover){background-color:#e7e7e7;border-radius:50%}.core-button-vns-container .btn-for-form{border:none;border-radius:0;background-color:transparent;color:#000;min-width:120px}.core-button-vns-container button.last-child{background-color:#000;color:#fff}.core-button-vns-container .action-wrapper.last-child{background-color:var(--color-basic-orange);color:#fff;border-radius:50%}.core-button-vns-container .action-wrapper.last-child:hover{background-color:var(--color-basic-orange);box-shadow:0 1rem 3rem #0000002e}.core-button-vns-container .temporary-unavailable{user-select:none;-moz-user-select:none;-webkit-user-select:none;cursor:not-allowed!important;opacity:.5}.core-button-vns-container .temporary-unavailable:hover{background-color:transparent!important}\n"] }]
|
|
2306
|
+
}], ctorParameters: () => [{ type: MultiLanguageService }] });
|
|
2307
|
+
|
|
2308
|
+
class CoreFormArrayLayoutEditorComponent {
|
|
2309
|
+
constructor() {
|
|
2310
|
+
this.checkError$ = new BehaviorSubject(false);
|
|
2311
|
+
this.coreFormDesignService = inject(CoreFormDesignService);
|
|
2312
|
+
this.$sections = this.coreFormDesignService.$nestedDesignSections;
|
|
2313
|
+
this.form = this.coreFormDesignService.formDesign;
|
|
2314
|
+
}
|
|
2315
|
+
onClose() {
|
|
2316
|
+
this.coreFormDesignService.$showFormArrayDesign.set(false);
|
|
2317
|
+
}
|
|
2318
|
+
onMiniDrop(event, sectionIndex, rowIndex, colIndex) {
|
|
2319
|
+
const rawData = event?.dataTransfer?.getData('application/json');
|
|
2320
|
+
if (rawData) {
|
|
2321
|
+
const control = JSON.parse(rawData);
|
|
2322
|
+
// clone control để tránh mutate template gốc
|
|
2323
|
+
const newControl = structuredClone(control);
|
|
2324
|
+
// insert vào đúng chỗ
|
|
2325
|
+
const current = this.$sections();
|
|
2326
|
+
if (!current)
|
|
2327
|
+
return;
|
|
2328
|
+
current[sectionIndex].rows[rowIndex][colIndex] = newControl;
|
|
2329
|
+
// trigger signal cập nhật
|
|
2330
|
+
this.$sections.set([...current]);
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormArrayLayoutEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2334
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: CoreFormArrayLayoutEditorComponent, isStandalone: true, selector: "core-form-array-layout-editor", ngImport: i0, template: "<div class=\"core-form-array-layout-editor-container\">\r\n\r\n\r\n <div class=\"modal-container\">\r\n <div class=\"modal-content-root\">\r\n\r\n <div class=\"layout-header\">\r\n DESIGN FORM ARRAY LAYOUT\r\n <button class=\"btn btn-sm btn-outline-secondary\" (click)=\"onClose()\">\u2716</button>\r\n </div>\r\n\r\n <div class=\"layout-body\">\r\n <div class=\"json-holder\">\r\n <pre>{{ coreFormDesignService.$currentControlJson() }}</pre>\r\n </div>\r\n <div class=\"palete\">\r\n <core-form-array-control-palette />\r\n </div>\r\n <div class=\"sections-holder\">\r\n <core-form-group-editor [$idAsInput]=\"true\" [$isNested]=\"true\"/>\r\n </div>\r\n <div class=\"field-setting-holder\">\r\n <field-setting [$isNested]=\"true\"></field-setting>\r\n </div>\r\n \r\n <!-- @for (section of $sections(); track $index; let sectionIndex = $index) {\r\n <div class=\"section-card\">\r\n <div class=\"section-caption\">{{ section.caption || 'Untitled Section' }}</div>\r\n\r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n <div class=\"row\">\r\n @for (control of row; track $index; let colIndex = $index) {\r\n <div\r\n class=\"form-cell mini-drop-target\"\r\n [attr.data-index]=\"$index\"\r\n miniDropTarget\r\n (miniDropped)=\"onMiniDrop($event, sectionIndex, rowIndex, colIndex)\"\r\n >\r\n <core-control-no-form-array\r\n [control]=\"control\"\r\n [form]=\"form\"\r\n [checkError$]=\"checkError$\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n } -->\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n\r\n</div>", styles: [".core-form-array-layout-editor-container{height:100%;width:100vw;display:flex;flex-direction:column}.layout-header{display:flex;justify-content:space-between;align-items:center;padding:15px;height:50px;background:#f7f7f7;border-bottom:1px solid #ddd;transform:translate(-15px,-15px);width:calc(100% + 30px);font-size:20px}.layout-body{display:flex;vertical-align:top}.layout-body .json-holder,.layout-body .palete{width:240px;display:inline-block}.layout-body .sections-holder{width:480px;display:inline-block}.layout-body .field-setting-holder{width:360px;display:inline-block}.layout-footer{padding:1rem;border-top:1px solid #ddd;text-align:right}\n"], dependencies: [{ kind: "component", type: CoreFormArrayControlPaletteComponent, selector: "core-form-array-control-palette" }, { kind: "component", type: CoreFormGroupEditorComponent, selector: "core-form-group-editor", inputs: ["$isNested", "$idAsInput", "$id"] }, { kind: "component", type: FieldSettingComponent, selector: "field-setting", inputs: ["$isNested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2335
|
+
}
|
|
2336
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormArrayLayoutEditorComponent, decorators: [{
|
|
2337
|
+
type: Component,
|
|
2338
|
+
args: [{ selector: 'core-form-array-layout-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2339
|
+
CoreControlNoFormArrayComponent,
|
|
2340
|
+
CoreFormArrayControlPaletteComponent,
|
|
2341
|
+
CoreFormGroupEditorComponent,
|
|
2342
|
+
FieldSettingComponent
|
|
2343
|
+
], template: "<div class=\"core-form-array-layout-editor-container\">\r\n\r\n\r\n <div class=\"modal-container\">\r\n <div class=\"modal-content-root\">\r\n\r\n <div class=\"layout-header\">\r\n DESIGN FORM ARRAY LAYOUT\r\n <button class=\"btn btn-sm btn-outline-secondary\" (click)=\"onClose()\">\u2716</button>\r\n </div>\r\n\r\n <div class=\"layout-body\">\r\n <div class=\"json-holder\">\r\n <pre>{{ coreFormDesignService.$currentControlJson() }}</pre>\r\n </div>\r\n <div class=\"palete\">\r\n <core-form-array-control-palette />\r\n </div>\r\n <div class=\"sections-holder\">\r\n <core-form-group-editor [$idAsInput]=\"true\" [$isNested]=\"true\"/>\r\n </div>\r\n <div class=\"field-setting-holder\">\r\n <field-setting [$isNested]=\"true\"></field-setting>\r\n </div>\r\n \r\n <!-- @for (section of $sections(); track $index; let sectionIndex = $index) {\r\n <div class=\"section-card\">\r\n <div class=\"section-caption\">{{ section.caption || 'Untitled Section' }}</div>\r\n\r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n <div class=\"row\">\r\n @for (control of row; track $index; let colIndex = $index) {\r\n <div\r\n class=\"form-cell mini-drop-target\"\r\n [attr.data-index]=\"$index\"\r\n miniDropTarget\r\n (miniDropped)=\"onMiniDrop($event, sectionIndex, rowIndex, colIndex)\"\r\n >\r\n <core-control-no-form-array\r\n [control]=\"control\"\r\n [form]=\"form\"\r\n [checkError$]=\"checkError$\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n } -->\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n\r\n</div>", styles: [".core-form-array-layout-editor-container{height:100%;width:100vw;display:flex;flex-direction:column}.layout-header{display:flex;justify-content:space-between;align-items:center;padding:15px;height:50px;background:#f7f7f7;border-bottom:1px solid #ddd;transform:translate(-15px,-15px);width:calc(100% + 30px);font-size:20px}.layout-body{display:flex;vertical-align:top}.layout-body .json-holder,.layout-body .palete{width:240px;display:inline-block}.layout-body .sections-holder{width:480px;display:inline-block}.layout-body .field-setting-holder{width:360px;display:inline-block}.layout-footer{padding:1rem;border-top:1px solid #ddd;text-align:right}\n"] }]
|
|
2344
|
+
}] });
|
|
2345
|
+
|
|
2346
|
+
class CoreFormDesignComponent extends BaseComponent {
|
|
2347
|
+
constructor(mls) {
|
|
2348
|
+
super(mls);
|
|
2349
|
+
this.mls = mls;
|
|
2350
|
+
this.$idAsInput = input();
|
|
2351
|
+
this.$id = input();
|
|
2352
|
+
this.$settingPanel = viewChild('settingPanel');
|
|
2353
|
+
this.$jsonMode = signal('selectedField');
|
|
2354
|
+
this.injectedFields$ = new BehaviorSubject([]);
|
|
2355
|
+
this.enumType = EnumFormDesignMode;
|
|
2356
|
+
this.enumLeftPanelMode = EnumLeftPanelMode;
|
|
2357
|
+
this.$leftPanelMode = computed(() => {
|
|
2358
|
+
if (this.coreFormDesignService.$fieldSettingPanelOpen()) {
|
|
2359
|
+
return this.enumLeftPanelMode.Json;
|
|
2360
|
+
}
|
|
2361
|
+
else {
|
|
2362
|
+
return this.enumLeftPanelMode.FieldCollection;
|
|
2363
|
+
}
|
|
2364
|
+
});
|
|
2365
|
+
this.ds = inject(DomService);
|
|
2366
|
+
this.js = inject(JsonService);
|
|
2367
|
+
this.$zIndex = computed(() => {
|
|
2368
|
+
if (this.coreFormDesignService.$fieldSettingPanelOpen()) {
|
|
2369
|
+
return this.ds.getMaxZIndex() + 1;
|
|
2370
|
+
}
|
|
2371
|
+
else {
|
|
2372
|
+
return 0;
|
|
2373
|
+
}
|
|
2374
|
+
});
|
|
2375
|
+
this.previewMode$ = new BehaviorSubject(EnumCorePageEditMode.CREATE);
|
|
2376
|
+
this.$loading = signal(false);
|
|
2377
|
+
this.coreFormDesignService = inject(CoreFormDesignService);
|
|
2378
|
+
this.renderer = inject(Renderer2);
|
|
2379
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
2380
|
+
this.router = inject(Router);
|
|
2381
|
+
this.route = inject(ActivatedRoute);
|
|
2382
|
+
this.alertService = inject(AlertService);
|
|
2383
|
+
this.applicationHelpService = inject(ApplicationHelpService);
|
|
2384
|
+
this.wfs = inject(CoreWorkflowService);
|
|
2385
|
+
this.dbs = inject(DbService);
|
|
2386
|
+
this.appConfigService = inject(AppConfigService);
|
|
2387
|
+
this.$hasCalculatedSection = computed(() => {
|
|
2388
|
+
return this.coreFormDesignService.$placeholderSections().some(s => !!s.forCalculatedFields);
|
|
2389
|
+
});
|
|
2390
|
+
this.formDesign = this.coreFormDesignService.formDesign;
|
|
2391
|
+
this.setControlProp = this.coreFormDesignService.setControlProp.bind(this.coreFormDesignService);
|
|
2392
|
+
this.isDragOverMap = {};
|
|
2393
|
+
this.idStream$ = new BehaviorSubject(undefined);
|
|
2394
|
+
this.getByIdStream$ = this.idStream$.pipe(filter(id => !!id && id !== '0'), distinctUntilChanged(), tap(() => {
|
|
2395
|
+
this.$loading.set(true);
|
|
2396
|
+
this.coreFormDesignService.editMode$.next(EnumCorePageEditMode.UPDATE);
|
|
2397
|
+
this.coreFormDesignService.$submitText.set(EnumTranslateKey.UI_EDIT_FORM_BUTTON_SAVE);
|
|
2398
|
+
}), switchMap(id => {
|
|
2399
|
+
return this.coreFormDesignService.getById(id)
|
|
2400
|
+
.pipe(catchError(err => {
|
|
2401
|
+
this.$loading.set(false);
|
|
2402
|
+
return of(err);
|
|
2403
|
+
}));
|
|
2404
|
+
}));
|
|
2405
|
+
this.form = new FormGroup({
|
|
2406
|
+
stringBox: new FormControl(),
|
|
2407
|
+
timeBox: new FormControl(),
|
|
2408
|
+
email: new FormControl(),
|
|
2409
|
+
textarea: new FormControl(),
|
|
2410
|
+
number: new FormControl(),
|
|
2411
|
+
currency: new FormControl(),
|
|
2412
|
+
dropdown: new FormControl(),
|
|
2413
|
+
employeeSeeker: new FormControl(),
|
|
2414
|
+
checklist: new FormControl(),
|
|
2415
|
+
employeeSeekerMultiple: new FormControl(),
|
|
2416
|
+
datePicker: new FormControl(),
|
|
2417
|
+
monthSelector: new FormControl(),
|
|
2418
|
+
attachment: new FormControl(),
|
|
2419
|
+
attachmentBuffer: new FormControl(),
|
|
2420
|
+
checkbox: new FormControl(),
|
|
2421
|
+
calculated: new FormControl(),
|
|
2422
|
+
formArray: new FormArray([
|
|
2423
|
+
new FormControl('')
|
|
2424
|
+
])
|
|
2425
|
+
});
|
|
2426
|
+
this.$sections = computed(() => {
|
|
2427
|
+
const hydrated = this.coreFormDesignService.rehydrateSections(this.coreFormDesignService.$placeholderSections());
|
|
2428
|
+
let sections = this.coreFormDesignService.toCoreFormSections(hydrated);
|
|
2429
|
+
// ✅ Inject hidden "id" field into the first cell row of the first section
|
|
2430
|
+
sections = this.coreFormDesignService.injectSystemControls(sections, this.coreFormDesignService.$afInstance().hasIdOfStringType ?? false);
|
|
2431
|
+
return sections;
|
|
2432
|
+
});
|
|
2433
|
+
this.checkError$ = new BehaviorSubject(false);
|
|
2434
|
+
this.controlCategories = [
|
|
2435
|
+
{
|
|
2436
|
+
name: 'Calculated fields',
|
|
2437
|
+
controls: [
|
|
2438
|
+
{
|
|
2439
|
+
flexSize: 12,
|
|
2440
|
+
controlType: EnumFormBaseContolType.CALCULATED,
|
|
2441
|
+
type: 'calculated',
|
|
2442
|
+
field: 'calculated',
|
|
2443
|
+
label: '',
|
|
2444
|
+
value: '',
|
|
2445
|
+
placeholder: 'Calculated',
|
|
2446
|
+
headless: true,
|
|
2447
|
+
}
|
|
2448
|
+
]
|
|
2449
|
+
},
|
|
2450
|
+
{
|
|
2451
|
+
name: 'Text',
|
|
2452
|
+
controls: [
|
|
2453
|
+
{
|
|
2454
|
+
flexSize: 12,
|
|
2455
|
+
controlType: EnumFormBaseContolType.TEXTBOX,
|
|
2456
|
+
type: 'string',
|
|
2457
|
+
field: 'stringBox',
|
|
2458
|
+
label: '',
|
|
2459
|
+
value: '',
|
|
2460
|
+
placeholder: 'String box',
|
|
2461
|
+
headless: true,
|
|
2462
|
+
},
|
|
2463
|
+
{
|
|
2464
|
+
flexSize: 12,
|
|
2465
|
+
controlType: EnumFormBaseContolType.TEXTBOX,
|
|
2466
|
+
type: 'email',
|
|
2467
|
+
field: 'email',
|
|
2468
|
+
label: '',
|
|
2469
|
+
value: '',
|
|
2470
|
+
placeholder: 'Email',
|
|
2471
|
+
headless: true,
|
|
2472
|
+
},
|
|
2473
|
+
{
|
|
2474
|
+
flexSize: 12,
|
|
2475
|
+
controlType: EnumFormBaseContolType.TEXTAREA,
|
|
2476
|
+
type: 'string',
|
|
2477
|
+
field: 'textarea',
|
|
2478
|
+
label: '',
|
|
2479
|
+
value: '',
|
|
2480
|
+
textareaRows: 2,
|
|
2481
|
+
placeholder: 'Text area',
|
|
2482
|
+
headless: true,
|
|
2483
|
+
}
|
|
2484
|
+
]
|
|
2485
|
+
},
|
|
2486
|
+
{
|
|
2487
|
+
name: 'Numerical',
|
|
2488
|
+
controls: [
|
|
2489
|
+
{
|
|
2490
|
+
flexSize: 12,
|
|
2491
|
+
controlType: EnumFormBaseContolType.TEXTBOX,
|
|
2492
|
+
type: 'number',
|
|
2493
|
+
field: 'number',
|
|
2494
|
+
label: '',
|
|
2495
|
+
value: 100,
|
|
2496
|
+
placeholder: 'Number',
|
|
2497
|
+
headless: true,
|
|
2498
|
+
},
|
|
2499
|
+
{
|
|
2500
|
+
flexSize: 12,
|
|
2501
|
+
controlType: EnumFormBaseContolType.CURRENCY,
|
|
2502
|
+
type: 'number',
|
|
2503
|
+
field: 'currency',
|
|
2504
|
+
label: '',
|
|
2505
|
+
value: '',
|
|
2506
|
+
placeholder: 'Currency',
|
|
2507
|
+
headless: true,
|
|
2508
|
+
},
|
|
2509
|
+
]
|
|
2510
|
+
},
|
|
2511
|
+
{
|
|
2512
|
+
name: 'Single selection',
|
|
2513
|
+
controls: [
|
|
2514
|
+
{
|
|
2515
|
+
flexSize: 12,
|
|
2516
|
+
controlType: EnumFormBaseContolType.DROPDOWN,
|
|
2517
|
+
type: 'any',
|
|
2518
|
+
field: 'dropdown',
|
|
2519
|
+
label: '',
|
|
2520
|
+
value: '',
|
|
2521
|
+
dropdownOptions$: new BehaviorSubject([]),
|
|
2522
|
+
shownFrom: 'name',
|
|
2523
|
+
getByIdObject$: new BehaviorSubject({}),
|
|
2524
|
+
placeholder: 'Dropdown',
|
|
2525
|
+
headless: true,
|
|
2526
|
+
},
|
|
2527
|
+
{
|
|
2528
|
+
flexSize: 12,
|
|
2529
|
+
controlType: EnumFormBaseContolType.SEEKER,
|
|
2530
|
+
seekerSourceType: EnumCoreFormControlSeekerSourceType.EMPLOYEE_SEEK,
|
|
2531
|
+
type: 'any[]',
|
|
2532
|
+
field: 'employeeSeeker',
|
|
2533
|
+
label: '',
|
|
2534
|
+
value: ['Nguyễn A'],
|
|
2535
|
+
boundFrom: 'id',
|
|
2536
|
+
shownFrom: 'fullname',
|
|
2537
|
+
getByIdObject$: new BehaviorSubject({}),
|
|
2538
|
+
placeholder: 'Employee seeker',
|
|
2539
|
+
headless: true,
|
|
2540
|
+
}
|
|
2541
|
+
]
|
|
2542
|
+
},
|
|
2543
|
+
{
|
|
2544
|
+
name: 'Multiple Selection',
|
|
2545
|
+
controls: [
|
|
2546
|
+
// {
|
|
2547
|
+
// flexSize: 12,
|
|
2548
|
+
// controlType: EnumFormBaseContolType.GRIDBUFFER,
|
|
2549
|
+
// type: 'children',
|
|
2550
|
+
// field: 'gridbuffer',
|
|
2551
|
+
// label: '',
|
|
2552
|
+
// value: [],
|
|
2553
|
+
// placeholder: 'Grid buffer',
|
|
2554
|
+
// gridBufferFormSections: [
|
|
2555
|
+
// {
|
|
2556
|
+
// rows: [
|
|
2557
|
+
// [
|
|
2558
|
+
// {
|
|
2559
|
+
// flexSize: 6,
|
|
2560
|
+
// field: 'field1',
|
|
2561
|
+
// type: 'date',
|
|
2562
|
+
// value: '',
|
|
2563
|
+
// controlType: EnumFormBaseContolType.DATEPICKER,
|
|
2564
|
+
// label: 'field 1'
|
|
2565
|
+
// },
|
|
2566
|
+
// {
|
|
2567
|
+
// flexSize: 6,
|
|
2568
|
+
// field: 'field2',
|
|
2569
|
+
// type: 'number',
|
|
2570
|
+
// value: null,
|
|
2571
|
+
// controlType: EnumFormBaseContolType.TEXTBOX,
|
|
2572
|
+
// label: 'field 2'
|
|
2573
|
+
// },
|
|
2574
|
+
// ]
|
|
2575
|
+
// ]
|
|
2576
|
+
// }
|
|
2577
|
+
// ],
|
|
2578
|
+
// gridBufferTableColumns: [
|
|
2579
|
+
// {
|
|
2580
|
+
// caption: 'id',
|
|
2581
|
+
// field: 'id',
|
|
2582
|
+
// hidden: true,
|
|
2583
|
+
// type: 'string',
|
|
2584
|
+
// align: 'left',
|
|
2585
|
+
// width: 0,
|
|
2586
|
+
// },
|
|
2587
|
+
// {
|
|
2588
|
+
// field: 'field1',
|
|
2589
|
+
// width: 200,
|
|
2590
|
+
// caption: 'field 1',
|
|
2591
|
+
// type: 'date',
|
|
2592
|
+
// pipe: EnumCoreTablePipeType.DATE,
|
|
2593
|
+
// align: 'center'
|
|
2594
|
+
// },
|
|
2595
|
+
// {
|
|
2596
|
+
// field: 'field2',
|
|
2597
|
+
// width: 100,
|
|
2598
|
+
// caption: 'field 2',
|
|
2599
|
+
// type: 'number',
|
|
2600
|
+
// align: 'right'
|
|
2601
|
+
// },
|
|
2602
|
+
// ],
|
|
2603
|
+
// headless: true,
|
|
2604
|
+
// tableHeight: 100,
|
|
2605
|
+
// liteMode: true,
|
|
2606
|
+
// },
|
|
2607
|
+
{
|
|
2608
|
+
flexSize: 12,
|
|
2609
|
+
controlType: EnumFormBaseContolType.CHECKLIST,
|
|
2610
|
+
type: 'any[]',
|
|
2611
|
+
field: 'checklist',
|
|
2612
|
+
label: '',
|
|
2613
|
+
value: [],
|
|
2614
|
+
checklistOptions$: new BehaviorSubject([]),
|
|
2615
|
+
shownFrom: 'name',
|
|
2616
|
+
getByIdObject$: new BehaviorSubject({}),
|
|
2617
|
+
placeholder: 'Check list',
|
|
2618
|
+
headless: true,
|
|
2619
|
+
},
|
|
2620
|
+
{
|
|
2621
|
+
flexSize: 12,
|
|
2622
|
+
controlType: EnumFormBaseContolType.SEEKER,
|
|
2623
|
+
seekerSourceType: EnumCoreFormControlSeekerSourceType.EMPLOYEE_SEEK,
|
|
2624
|
+
multiMode: true,
|
|
2625
|
+
type: 'any[]',
|
|
2626
|
+
field: 'employeeSeekerMultiple',
|
|
2627
|
+
label: '',
|
|
2628
|
+
value: [],
|
|
2629
|
+
objectList$: new BehaviorSubject([]),
|
|
2630
|
+
boundFrom: 'id',
|
|
2631
|
+
shownFrom: 'fullname',
|
|
2632
|
+
getByIdObject$: new BehaviorSubject({}),
|
|
2633
|
+
multiModeTableHeight: 100,
|
|
2634
|
+
placeholder: 'Employee seeker (multi mode)',
|
|
2635
|
+
headless: true,
|
|
2636
|
+
}
|
|
2637
|
+
]
|
|
2638
|
+
},
|
|
2639
|
+
{
|
|
2640
|
+
name: 'Date',
|
|
2641
|
+
controls: [
|
|
2642
|
+
{
|
|
2643
|
+
flexSize: 12,
|
|
2644
|
+
controlType: EnumFormBaseContolType.DATEPICKER,
|
|
2645
|
+
type: 'date',
|
|
2646
|
+
field: 'datePicker',
|
|
2647
|
+
label: '',
|
|
2648
|
+
value: '',
|
|
2649
|
+
placeholder: 'Date picker',
|
|
2650
|
+
showPlaceholder: true,
|
|
2651
|
+
headless: true,
|
|
2652
|
+
},
|
|
2653
|
+
{
|
|
2654
|
+
flexSize: 12,
|
|
2655
|
+
controlType: EnumFormBaseContolType.TEXTBOX,
|
|
2656
|
+
type: 'time',
|
|
2657
|
+
field: 'timeBox',
|
|
2658
|
+
label: '',
|
|
2659
|
+
value: null,
|
|
2660
|
+
placeholder: 'Time box',
|
|
2661
|
+
headless: true,
|
|
2662
|
+
},
|
|
2663
|
+
{
|
|
2664
|
+
flexSize: 12,
|
|
2665
|
+
controlType: EnumFormBaseContolType.MONTHSELECTOR,
|
|
2666
|
+
type: 'string',
|
|
2667
|
+
field: 'monthSelector',
|
|
2668
|
+
label: '',
|
|
2669
|
+
value: '',
|
|
2670
|
+
placeholder: 'Month selector',
|
|
2671
|
+
headless: true,
|
|
2672
|
+
},
|
|
2673
|
+
]
|
|
2674
|
+
},
|
|
2675
|
+
{
|
|
2676
|
+
name: 'Other',
|
|
2677
|
+
controls: [
|
|
2678
|
+
{
|
|
2679
|
+
flexSize: 12,
|
|
2680
|
+
controlType: EnumFormBaseContolType.ATTACHMENT,
|
|
2681
|
+
type: 'string',
|
|
2682
|
+
field: 'attachment',
|
|
2683
|
+
label: '',
|
|
2684
|
+
value: '',
|
|
2685
|
+
assignTo: 'unknown',
|
|
2686
|
+
placeholder: 'Attachment',
|
|
2687
|
+
headless: true,
|
|
2688
|
+
},
|
|
2689
|
+
{
|
|
2690
|
+
flexSize: 12,
|
|
2691
|
+
controlType: EnumFormBaseContolType.CHECKBOX,
|
|
2692
|
+
type: 'boolean',
|
|
2693
|
+
field: 'checkbox',
|
|
2694
|
+
label: '',
|
|
2695
|
+
value: '',
|
|
2696
|
+
placeholder: 'Checkbox',
|
|
2697
|
+
headless: true,
|
|
2698
|
+
},
|
|
2699
|
+
]
|
|
2700
|
+
},
|
|
2701
|
+
{
|
|
2702
|
+
name: 'Form Array',
|
|
2703
|
+
controls: [
|
|
2704
|
+
{
|
|
2705
|
+
flexSize: 12,
|
|
2706
|
+
controlType: EnumFormBaseContolType.FORM_ARRAY,
|
|
2707
|
+
type: 'children',
|
|
2708
|
+
field: 'formArray',
|
|
2709
|
+
label: '',
|
|
2710
|
+
value: '',
|
|
2711
|
+
placeholder: 'FormArray',
|
|
2712
|
+
headless: true,
|
|
2713
|
+
childrenSections: [
|
|
2714
|
+
{
|
|
2715
|
+
rows: [
|
|
2716
|
+
[
|
|
2717
|
+
{
|
|
2718
|
+
field: 'textBox',
|
|
2719
|
+
flexSize: 12,
|
|
2720
|
+
controlType: EnumFormBaseContolType.TEXTBOX,
|
|
2721
|
+
type: 'text',
|
|
2722
|
+
value: '',
|
|
2723
|
+
label: ''
|
|
2724
|
+
}
|
|
2725
|
+
]
|
|
2726
|
+
]
|
|
2727
|
+
}
|
|
2728
|
+
]
|
|
2729
|
+
},
|
|
2730
|
+
]
|
|
2731
|
+
},
|
|
2732
|
+
];
|
|
2733
|
+
/*
|
|
2734
|
+
onDropIntoCell(event: DragEvent, sectionIndex: number, rowIndex: number, colIndex: number): void {
|
|
2735
|
+
event.preventDefault();
|
|
2736
|
+
const template = this.coreFormDesignService.$currentControlTemplate();
|
|
2737
|
+
if (!template) return;
|
|
2738
|
+
|
|
2739
|
+
const section = this.coreFormDesignService.$placeholderSections()[sectionIndex];
|
|
2740
|
+
if (!section.forCalculatedFields && template.type === 'calculated') return;
|
|
2741
|
+
if (!!section.forCalculatedFields && template.type !== 'calculated') return;
|
|
2742
|
+
|
|
2743
|
+
const normalized = this.coreFormDesignService.normalize({
|
|
2744
|
+
...template,
|
|
2745
|
+
field: this.generateFieldNameFor(template),
|
|
2746
|
+
label: this.generateLabelNameFor(template),
|
|
2747
|
+
value: null
|
|
2748
|
+
});
|
|
2749
|
+
|
|
2750
|
+
if (normalized.controlType === EnumFormBaseContolType.CALCULATED) {
|
|
2751
|
+
normalized.returnType = 'number'
|
|
2752
|
+
}
|
|
2753
|
+
|
|
2754
|
+
this.coreFormDesignService.$placeholderSections.update(sections => {
|
|
2755
|
+
const section = sections[sectionIndex];
|
|
2756
|
+
const row = section?.rows[rowIndex];
|
|
2757
|
+
if (!row || row.cells.length <= colIndex) return sections;
|
|
2758
|
+
|
|
2759
|
+
const usedFlex = row.cells.reduce((sum, cell) => sum + (cell?.control?.flexSize ?? 0), 0);
|
|
2760
|
+
const remainingFlex = 12 - usedFlex;
|
|
2761
|
+
const flexSize = Math.max(1, remainingFlex);
|
|
2762
|
+
normalized.flexSize = flexSize;
|
|
2763
|
+
|
|
2764
|
+
const previous = row.cells[colIndex]?.control;
|
|
2765
|
+
|
|
2766
|
+
if (previous && previous.flexSize !== undefined) {
|
|
2767
|
+
|
|
2768
|
+
// AttachmentFieldHelperService.handleAttachmentOverwrite(
|
|
2769
|
+
// previous as IFormBaseControl,
|
|
2770
|
+
// this.coreFormDesignService.getAllControlsFromSections()
|
|
2771
|
+
// );
|
|
2772
|
+
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
const previousField = row.cells[colIndex]?.control?.field ?? null;
|
|
2776
|
+
this.coreFormDesignService.replaceControl(previousField, normalized);
|
|
2777
|
+
|
|
2778
|
+
// 🔹 INSERT FIRST
|
|
2779
|
+
row.cells[colIndex] = { ...row.cells[colIndex], control: normalized };
|
|
2780
|
+
this.coreFormDesignService.$selectedCell.set(row.cells[colIndex]);
|
|
2781
|
+
|
|
2782
|
+
// 🔹 THEN CALL setup
|
|
2783
|
+
if (AttachmentFieldHelperService.isAttachment(normalized)) {
|
|
2784
|
+
const assignToField = AttachmentFieldHelperService.buildHiddenAssignToField(normalized.field);
|
|
2785
|
+
normalized.field = `${normalized.field}Buffer`
|
|
2786
|
+
normalized.assignTo = assignToField.field;
|
|
2787
|
+
AttachmentFieldHelperService.injectAssignToFieldIntoRow(row, assignToField);
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
|
|
2791
|
+
setTimeout(() => {
|
|
2792
|
+
this.coreFormDesignService.setControlPropDirectly(
|
|
2793
|
+
'validators',
|
|
2794
|
+
normalized.validators ?? [],
|
|
2795
|
+
normalized
|
|
2796
|
+
);
|
|
2797
|
+
});
|
|
2798
|
+
|
|
2799
|
+
return sections;
|
|
2800
|
+
});
|
|
2801
|
+
|
|
2802
|
+
this.triggerUpdateSections();
|
|
2803
|
+
this.isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex] = false;
|
|
2804
|
+
this.coreFormDesignService.endDrag();
|
|
2805
|
+
this.openSettingsForCell(this.coreFormDesignService.$selectedCell()!, sectionIndex, rowIndex, colIndex)
|
|
2806
|
+
}
|
|
2807
|
+
*/
|
|
2808
|
+
this.generateFieldNameFor = this.coreFormDesignService.generateFieldNameFor.bind(this.coreFormDesignService);
|
|
2809
|
+
this.generateLabelNameFor = this.coreFormDesignService.generateLabelNameFor.bind(this.coreFormDesignService);
|
|
2810
|
+
this.getAllControlsFromSections = this.coreFormDesignService.getAllControlsFromSections.bind(this.coreFormDesignService);
|
|
2811
|
+
this.getControl = this.coreFormDesignService.getControl.bind(this.coreFormDesignService);
|
|
2812
|
+
this.filteredCells = this.coreFormDesignService.filteredCells;
|
|
2813
|
+
this.coreFormDesignService.resetFormDesignState();
|
|
2814
|
+
effect(() => {
|
|
2815
|
+
const _ = this.coreFormDesignService.$placeholderSections();
|
|
2816
|
+
this.syncFormDesignWithSections();
|
|
2817
|
+
});
|
|
2818
|
+
effect(() => {
|
|
2819
|
+
this.idStream$.next(this.$id());
|
|
2820
|
+
});
|
|
2821
|
+
this.applicationHelpService.activeKey$.pipe(distinctUntilChanged()).subscribe(x => {
|
|
2822
|
+
switch (x) {
|
|
2823
|
+
case 'F3':
|
|
2824
|
+
this.coreFormDesignService.$fieldSettingPanelOpen.set(true);
|
|
2825
|
+
break;
|
|
2826
|
+
case 'F6':
|
|
2827
|
+
this.coreFormDesignService.$mode.set(EnumFormDesignMode.Preview);
|
|
2828
|
+
break;
|
|
2829
|
+
case 'Escape':
|
|
2830
|
+
this.coreFormDesignService.$fieldSettingPanelOpen.set(false);
|
|
2831
|
+
this.coreFormDesignService.$mode.set(EnumFormDesignMode.Default);
|
|
2832
|
+
break;
|
|
2833
|
+
}
|
|
2834
|
+
});
|
|
2835
|
+
}
|
|
2836
|
+
ngOnInit() {
|
|
2837
|
+
this.subscriptions.push(this.mls.lang$.subscribe(x => this.lang = x));
|
|
2838
|
+
if (this.appConfigService.WORKFLOW_ENABLE_DEBUG_MODE) {
|
|
2839
|
+
this.injectedFields$.next([
|
|
2840
|
+
{
|
|
2841
|
+
field: '___submitterEmployeeId',
|
|
2842
|
+
flexSize: 12,
|
|
2843
|
+
type: 'number',
|
|
2844
|
+
controlType: EnumFormBaseContolType.SEEKER,
|
|
2845
|
+
seekerSourceType: EnumCoreFormControlSeekerSourceType.EMPLOYEE_SEEK,
|
|
2846
|
+
getByIdApi: '',
|
|
2847
|
+
getByIdObject$: new BehaviorSubject({}),
|
|
2848
|
+
label: 'Simulated Requester',
|
|
2849
|
+
boundFrom: 'id',
|
|
2850
|
+
shownFrom: 'fullname',
|
|
2851
|
+
value: null,
|
|
2852
|
+
},
|
|
2853
|
+
{
|
|
2854
|
+
field: "___reason",
|
|
2855
|
+
type: "text",
|
|
2856
|
+
value: '',
|
|
2857
|
+
label: "UI_FORM_CONTROL_LABEL.REASON",
|
|
2858
|
+
flexSize: 12,
|
|
2859
|
+
controlType: EnumFormBaseContolType.TEXTAREA,
|
|
2860
|
+
textareaRows: 5,
|
|
2861
|
+
validators: [
|
|
2862
|
+
{
|
|
2863
|
+
name: 'required',
|
|
2864
|
+
validator: Validators.required,
|
|
2865
|
+
errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_REQUIRED
|
|
2866
|
+
}
|
|
2867
|
+
],
|
|
2868
|
+
}
|
|
2869
|
+
]);
|
|
2870
|
+
}
|
|
2871
|
+
else {
|
|
2872
|
+
this.injectedFields$.next([
|
|
2873
|
+
{
|
|
2874
|
+
field: "___reason",
|
|
2875
|
+
type: "text",
|
|
2876
|
+
value: '',
|
|
2877
|
+
label: "UI_FORM_CONTROL_LABEL.REASON",
|
|
2878
|
+
flexSize: 12,
|
|
2879
|
+
controlType: EnumFormBaseContolType.TEXTAREA,
|
|
2880
|
+
textareaRows: 5,
|
|
2881
|
+
validators: [
|
|
2882
|
+
{
|
|
2883
|
+
name: 'required',
|
|
2884
|
+
validator: Validators.required,
|
|
2885
|
+
errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_REQUIRED
|
|
2886
|
+
}
|
|
2887
|
+
],
|
|
2888
|
+
}
|
|
2889
|
+
]);
|
|
2890
|
+
}
|
|
2891
|
+
}
|
|
2892
|
+
switchJson() {
|
|
2893
|
+
if (this.$jsonMode() === 'full') {
|
|
2894
|
+
this.$jsonMode.set('selectedField');
|
|
2895
|
+
}
|
|
2896
|
+
else {
|
|
2897
|
+
this.$jsonMode.set('full');
|
|
2898
|
+
}
|
|
2899
|
+
}
|
|
2900
|
+
onDragStart(event, control) {
|
|
2901
|
+
this.coreFormDesignService.beginDragTemplate(control);
|
|
2902
|
+
}
|
|
2903
|
+
onDragOver(event, section, control) {
|
|
2904
|
+
event.preventDefault(); // necessary to allow drop
|
|
2905
|
+
if ((!!section.forCalculatedFields && this.coreFormDesignService.$draggingControl()?.type === 'calculated') ||
|
|
2906
|
+
(!section.forCalculatedFields && this.coreFormDesignService.$draggingControl()?.type !== 'calculated')) {
|
|
2907
|
+
event.dataTransfer.dropEffect = 'copy';
|
|
2908
|
+
}
|
|
2909
|
+
else {
|
|
2910
|
+
event.dataTransfer.dropEffect = 'none';
|
|
2911
|
+
}
|
|
2912
|
+
}
|
|
2913
|
+
onDragEnter(placeholderId) {
|
|
2914
|
+
this.isDragOverMap[placeholderId] = true;
|
|
2915
|
+
}
|
|
2916
|
+
onDragLeave(placeholderId) {
|
|
2917
|
+
this.isDragOverMap[placeholderId] = false;
|
|
2918
|
+
}
|
|
2919
|
+
addCalculatedSection() {
|
|
2920
|
+
this.coreFormDesignService.$placeholderSections.update(sections => [
|
|
2921
|
+
{
|
|
2922
|
+
caption: `Calculated Section`,
|
|
2923
|
+
forCalculatedFields: true,
|
|
2924
|
+
hidden: true,
|
|
2925
|
+
rows: [{ cells: [{ flexSize: 12 }] }]
|
|
2926
|
+
},
|
|
2927
|
+
...sections,
|
|
2928
|
+
]);
|
|
2929
|
+
}
|
|
2930
|
+
addSection() {
|
|
2931
|
+
this.coreFormDesignService.$placeholderSections.update(sections => [
|
|
2932
|
+
...sections,
|
|
2933
|
+
{
|
|
2934
|
+
caption: `Section ${sections.length + 1}`,
|
|
2935
|
+
rows: [{ cells: [{ flexSize: 12 }] }]
|
|
2936
|
+
}
|
|
2937
|
+
]);
|
|
2938
|
+
}
|
|
2939
|
+
deleteSection(sectionIndex) {
|
|
2940
|
+
const sections = this.coreFormDesignService.$placeholderSections();
|
|
2941
|
+
const section = sections[sectionIndex];
|
|
2942
|
+
const hasControls = section?.rows?.some(row => row?.cells?.some(cell => !!cell?.control));
|
|
2943
|
+
if (hasControls) {
|
|
2944
|
+
const confirmed = confirm('This section contains controls. Are you sure you want to delete it?');
|
|
2945
|
+
if (!confirmed)
|
|
2946
|
+
return;
|
|
2947
|
+
}
|
|
2948
|
+
this.coreFormDesignService.$placeholderSections.update(prev => prev.filter((_, idx) => idx !== sectionIndex));
|
|
2949
|
+
}
|
|
2950
|
+
deleteRow(sectionIndex, rowIndex) {
|
|
2951
|
+
const sections = this.coreFormDesignService.$placeholderSections();
|
|
2952
|
+
const section = sections[sectionIndex];
|
|
2953
|
+
const row = section?.rows?.[rowIndex];
|
|
2954
|
+
if (!row)
|
|
2955
|
+
return; // safety check
|
|
2956
|
+
const hasControls = row.cells?.some(cell => !!cell?.control);
|
|
2957
|
+
if (hasControls) {
|
|
2958
|
+
const confirmed = confirm('This row contains controls. Are you sure you want to delete it?');
|
|
2959
|
+
if (!confirmed)
|
|
2960
|
+
return; // user canceled
|
|
2961
|
+
}
|
|
2962
|
+
this.coreFormDesignService.$placeholderSections.update(sections => {
|
|
2963
|
+
return sections.map((section, sIdx) => {
|
|
2964
|
+
if (sIdx !== sectionIndex)
|
|
2965
|
+
return section;
|
|
2966
|
+
return {
|
|
2967
|
+
...section,
|
|
2968
|
+
rows: (section.rows ?? []).filter((_, rIdx) => rIdx !== rowIndex)
|
|
2969
|
+
};
|
|
2970
|
+
});
|
|
2971
|
+
});
|
|
2972
|
+
}
|
|
2973
|
+
addRow(sectionIndex) {
|
|
2974
|
+
this.coreFormDesignService.$placeholderSections.update(sections => {
|
|
2975
|
+
const section = sections[sectionIndex];
|
|
2976
|
+
if (section) {
|
|
2977
|
+
section.rows.push({ cells: [{ flexSize: 12 }] });
|
|
2978
|
+
}
|
|
2979
|
+
return sections;
|
|
2980
|
+
});
|
|
2981
|
+
}
|
|
2982
|
+
addColumn(row) {
|
|
2983
|
+
if (!row || row.cells.length >= 4)
|
|
2984
|
+
return;
|
|
2985
|
+
const usedFlex = row.cells.reduce((sum, c) => sum + (c.flexSize ?? 0), 0);
|
|
2986
|
+
// ✅ Case 1: Normal case – still space available
|
|
2987
|
+
if (usedFlex < 12) {
|
|
2988
|
+
const remaining = 12 - usedFlex;
|
|
2989
|
+
row.cells.push({ flexSize: Math.min(3, remaining) });
|
|
2990
|
+
return;
|
|
2991
|
+
}
|
|
2992
|
+
// 💥 Case 2: Full row — try to rebalance
|
|
2993
|
+
if (usedFlex === 12) {
|
|
2994
|
+
const count = row.cells.length;
|
|
2995
|
+
if (count === 1) {
|
|
2996
|
+
// 12 → 6 + 6
|
|
2997
|
+
row.cells[0].flexSize = 6;
|
|
2998
|
+
row.cells.push({ flexSize: 6 });
|
|
2999
|
+
return;
|
|
3000
|
+
}
|
|
3001
|
+
if (count === 2) {
|
|
3002
|
+
// 6 + 6 → 4 + 4 + 4
|
|
3003
|
+
row.cells.forEach(c => (c.flexSize = 4));
|
|
3004
|
+
row.cells.push({ flexSize: 4 });
|
|
3005
|
+
return;
|
|
3006
|
+
}
|
|
3007
|
+
if (count === 3) {
|
|
3008
|
+
// 4 + 4 + 4 → 3 + 3 + 3 + 3
|
|
3009
|
+
row.cells.forEach(c => (c.flexSize = 3));
|
|
3010
|
+
row.cells.push({ flexSize: 3 });
|
|
3011
|
+
return;
|
|
3012
|
+
}
|
|
3013
|
+
// ❌ Already 4 cells, each 3 — can’t split further
|
|
3014
|
+
return;
|
|
3015
|
+
}
|
|
3016
|
+
// 🔧 Optional fallback logic for unknown edge cases
|
|
3017
|
+
const maxIndex = row.cells.reduce((maxI, c, i, arr) => (c.flexSize ?? 0) > (arr[maxI]?.flexSize ?? 0) ? i : maxI, 0);
|
|
3018
|
+
const maxCell = row.cells[maxIndex];
|
|
3019
|
+
if ((maxCell?.flexSize ?? 0) <= 3)
|
|
3020
|
+
return; // nothing to shrink
|
|
3021
|
+
maxCell.flexSize -= 3;
|
|
3022
|
+
row.cells.push({ flexSize: 3 });
|
|
3023
|
+
}
|
|
3024
|
+
onCorePageHeaderButtonClicked(e) {
|
|
3025
|
+
if (e.code === EnumCoreButtonVNSCode.HEADER_SWITCH_VIEW) {
|
|
3026
|
+
if (this.coreFormDesignService.$mode() === EnumFormDesignMode.Default) {
|
|
3027
|
+
const sections = this.coreFormDesignService.toCoreFormSections(this.coreFormDesignService.$placeholderSections());
|
|
3028
|
+
this.coreFormDesignService.$liveFormSections.set(sections);
|
|
3029
|
+
}
|
|
3030
|
+
setTimeout(() => this.coreFormDesignService.$mode.set(this.coreFormDesignService.$mode() === EnumFormDesignMode.Preview ? EnumFormDesignMode.Default : EnumFormDesignMode.Preview));
|
|
3031
|
+
}
|
|
3032
|
+
else if (e.code === EnumCoreButtonVNSCode.HEADER_SAVE) {
|
|
3033
|
+
}
|
|
3034
|
+
}
|
|
3035
|
+
closePreview() {
|
|
3036
|
+
this.coreFormDesignService.$mode.set(EnumFormDesignMode.Default);
|
|
3037
|
+
}
|
|
3038
|
+
onPreviewSubmit(e) {
|
|
3039
|
+
alert(JSON.stringify(e, null, 2));
|
|
3040
|
+
}
|
|
3041
|
+
onCellClicked(sectionIndex, rowIndex, colIndex) {
|
|
3042
|
+
const row = this.coreFormDesignService.$placeholderSections()[sectionIndex].rows[rowIndex];
|
|
3043
|
+
if (!!row) {
|
|
3044
|
+
// Toggle selection
|
|
3045
|
+
if (!!row.cells && row.cells.length > colIndex) {
|
|
3046
|
+
row.cells[colIndex].selected = !row.cells[colIndex].selected;
|
|
3047
|
+
}
|
|
3048
|
+
// Only allow max 2 selections
|
|
3049
|
+
const selected = row.cells.filter(c => c?.selected);
|
|
3050
|
+
if (selected.length > 2) {
|
|
3051
|
+
row.cells.forEach(c => c && (c.selected = false));
|
|
3052
|
+
row[colIndex].selected = true;
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
canMergeCells(sectionIndex, rowIndex) {
|
|
3057
|
+
const row = this.coreFormDesignService.$placeholderSections()[sectionIndex].rows[rowIndex];
|
|
3058
|
+
const selected = row?.cells.map((c, i) => ({ c, i })).filter(x => x.c?.selected);
|
|
3059
|
+
if (selected?.length !== 2)
|
|
3060
|
+
return false;
|
|
3061
|
+
const [a, b] = selected;
|
|
3062
|
+
if (a.c.control || b.c.control)
|
|
3063
|
+
return false;
|
|
3064
|
+
return Math.abs(a.i - b.i) === 1; // Must be neighbors
|
|
3065
|
+
}
|
|
3066
|
+
mergeCells(sectionIndex, rowIndex) {
|
|
3067
|
+
const row = this.coreFormDesignService.$placeholderSections()[sectionIndex].rows[rowIndex];
|
|
3068
|
+
if (!row)
|
|
3069
|
+
return;
|
|
3070
|
+
this.coreFormDesignService.$placeholderSections.update(sections => {
|
|
3071
|
+
const selected = row.cells
|
|
3072
|
+
.map((c, i) => ({ c, i }))
|
|
3073
|
+
.filter(x => x.c?.selected);
|
|
3074
|
+
if (selected.length !== 2)
|
|
3075
|
+
return sections;
|
|
3076
|
+
const [a, b] = selected.sort((a, b) => a.i - b.i);
|
|
3077
|
+
const mergedFlex = (typeof a.c.flexSize === 'number' ? a.c.flexSize : 3) +
|
|
3078
|
+
(typeof b.c.flexSize === 'number' ? b.c.flexSize : 3);
|
|
3079
|
+
const mergedCell = {
|
|
3080
|
+
//control: { ...a.c.control, flexSize: mergedFlex }, // keep control data
|
|
3081
|
+
flexSize: mergedFlex,
|
|
3082
|
+
selected: false
|
|
3083
|
+
};
|
|
3084
|
+
row.cells.splice(a.i, 2, mergedCell); // replace both cells with one
|
|
3085
|
+
return sections;
|
|
3086
|
+
});
|
|
3087
|
+
}
|
|
3088
|
+
openSettingsForCell(cell, sectionIndex, rowIndex, colIndex) {
|
|
3089
|
+
this.coreFormDesignService.$sectionIndex.set(sectionIndex);
|
|
3090
|
+
this.coreFormDesignService.$rowIndex.set(rowIndex);
|
|
3091
|
+
this.coreFormDesignService.$colIndex.set(colIndex);
|
|
3092
|
+
this.coreFormDesignService.$selectedCell.set({ ...cell });
|
|
3093
|
+
this.coreFormDesignService.$fieldSettingPanelOpen.set(true);
|
|
3094
|
+
}
|
|
3095
|
+
deleteField(row, sectionIndex, rowIndex, colIndex) {
|
|
3096
|
+
if (!row)
|
|
3097
|
+
return;
|
|
3098
|
+
const dCell = row.cells[colIndex];
|
|
3099
|
+
const currentControl = dCell.control;
|
|
3100
|
+
if (!currentControl)
|
|
3101
|
+
return;
|
|
3102
|
+
const currentPlaceholderSections = this.coreFormDesignService.$placeholderSections();
|
|
3103
|
+
if (!currentPlaceholderSections[sectionIndex].rows[rowIndex])
|
|
3104
|
+
return;
|
|
3105
|
+
currentPlaceholderSections[sectionIndex].rows[rowIndex].cells[colIndex].control = undefined;
|
|
3106
|
+
this.coreFormDesignService.$selectedCell.set(null);
|
|
3107
|
+
this.coreFormDesignService.$placeholderSections.set([...currentPlaceholderSections]);
|
|
3108
|
+
}
|
|
3109
|
+
onCaptionEditEnd(index, event) {
|
|
3110
|
+
const newCaption = event.target.innerText.trim();
|
|
3111
|
+
this.coreFormDesignService.$placeholderSections.update(sections => {
|
|
3112
|
+
sections[index].caption = newCaption;
|
|
3113
|
+
return sections;
|
|
3114
|
+
});
|
|
3115
|
+
}
|
|
3116
|
+
onFieldCaptionEditEnd(cell, event) {
|
|
3117
|
+
const element = event.target;
|
|
3118
|
+
const newLabel = element.innerText.trim();
|
|
3119
|
+
// Fallback if empty
|
|
3120
|
+
cell.control.label = newLabel || 'Unnamed Field';
|
|
3121
|
+
this.triggerUpdateSections();
|
|
3122
|
+
}
|
|
3123
|
+
insertSection() {
|
|
3124
|
+
}
|
|
3125
|
+
insertRow(sectionIndex, rowIndex) {
|
|
3126
|
+
const sections = this.coreFormDesignService.$placeholderSections();
|
|
3127
|
+
const section = sections[sectionIndex];
|
|
3128
|
+
if (!section)
|
|
3129
|
+
return;
|
|
3130
|
+
const newRow = {
|
|
3131
|
+
cells: [
|
|
3132
|
+
{ flexSize: 12 },
|
|
3133
|
+
]
|
|
3134
|
+
};
|
|
3135
|
+
section.rows.splice(rowIndex + 1, 0, newRow);
|
|
3136
|
+
this.coreFormDesignService.$placeholderSections.set([...sections]);
|
|
3137
|
+
}
|
|
3138
|
+
closeFieldSettingPanel() {
|
|
3139
|
+
this.coreFormDesignService.$fieldSettingPanelOpen.set(false);
|
|
3140
|
+
this.coreFormDesignService.$selectedCell.set(null);
|
|
3141
|
+
this.coreFormDesignService.$currentControlTemplate.set(null);
|
|
3142
|
+
this.coreFormDesignService.$currentControl.set(null);
|
|
3143
|
+
}
|
|
3144
|
+
ngAfterViewInit() {
|
|
3145
|
+
setTimeout(() => {
|
|
3146
|
+
this.subscriptions.push(this.getByIdStream$.subscribe(x => {
|
|
3147
|
+
this.$loading.set(false);
|
|
3148
|
+
if (x.ok && x.status === 200 && x.body?.statusCode === 200) {
|
|
3149
|
+
this.coreFormDesignService.$afInstance.set(this.coreFormDesignService.mapFromAfInstanceDTO(x.body.innerBody));
|
|
3150
|
+
this.coreFormDesignService.syncPlaceholderSectionsFromInstance();
|
|
3151
|
+
this.coreFormDesignService.$shouldPatchMetadataForm.set(true);
|
|
3152
|
+
const saveLiveJson = this.coreFormDesignService.$saveLiveJson();
|
|
3153
|
+
setTimeout(() => this.wfs.$initialFormDesignJson.set(saveLiveJson));
|
|
3154
|
+
}
|
|
3155
|
+
}));
|
|
3156
|
+
if (!this.$idAsInput()) {
|
|
3157
|
+
this.subscriptions.push(this.route.params.subscribe(x => {
|
|
3158
|
+
let id = '0';
|
|
3159
|
+
try {
|
|
3160
|
+
id = atob(x['id']);
|
|
3161
|
+
this.coreFormDesignService.$afInstance.update(instance => ({
|
|
3162
|
+
...instance,
|
|
3163
|
+
id
|
|
3164
|
+
}));
|
|
3165
|
+
}
|
|
3166
|
+
catch (err) {
|
|
3167
|
+
if (isDevMode()) {
|
|
3168
|
+
this.alertService.error(err.toString(), noneAutoClosedAlertOptions);
|
|
3169
|
+
}
|
|
3170
|
+
return;
|
|
3171
|
+
}
|
|
3172
|
+
this.idStream$.next(id);
|
|
3173
|
+
}));
|
|
3174
|
+
}
|
|
3175
|
+
console.warn('InitialFormDesignJson on load', this.wfs.$initialFormDesignJson());
|
|
3176
|
+
});
|
|
3177
|
+
}
|
|
3178
|
+
onControlParamsChange(updated) {
|
|
3179
|
+
this.coreFormDesignService.$placeholderSections.update(sections => {
|
|
3180
|
+
const cell = this.coreFormDesignService.$selectedCell();
|
|
3181
|
+
if (!cell)
|
|
3182
|
+
return sections;
|
|
3183
|
+
// Patch the selected cell
|
|
3184
|
+
Object.assign(cell.control, updated);
|
|
3185
|
+
return sections;
|
|
3186
|
+
});
|
|
3187
|
+
}
|
|
3188
|
+
get normalizedSelectedControl() {
|
|
3189
|
+
const cell = this.coreFormDesignService.$selectedCell();
|
|
3190
|
+
if (!cell?.control) {
|
|
3191
|
+
throw new Error('No control is currently selected.');
|
|
3192
|
+
}
|
|
3193
|
+
return this.coreFormDesignService.normalize(cell.control);
|
|
3194
|
+
}
|
|
3195
|
+
triggerUpdateSections() {
|
|
3196
|
+
const newValue = this.coreFormDesignService.$placeholderSections();
|
|
3197
|
+
this.coreFormDesignService.$placeholderSections.set([...newValue]);
|
|
3198
|
+
}
|
|
3199
|
+
syncFormDesignWithSections() {
|
|
3200
|
+
const existingControls = Object.keys(this.formDesign.controls);
|
|
3201
|
+
const expectedControls = [];
|
|
3202
|
+
for (const section of this.coreFormDesignService.$placeholderSections()) {
|
|
3203
|
+
for (const row of section.rows) {
|
|
3204
|
+
for (const cell of row?.cells || []) {
|
|
3205
|
+
const control = cell?.control;
|
|
3206
|
+
if (control?.field) {
|
|
3207
|
+
expectedControls.push(control.field);
|
|
3208
|
+
if (!this.formDesign.contains(control.field)) {
|
|
3209
|
+
this.formDesign.addControl(control.field, new FormControl(control.value ?? null));
|
|
3210
|
+
}
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
// 🧹 Remove controls that no longer exist
|
|
3216
|
+
for (const field of existingControls) {
|
|
3217
|
+
if (!expectedControls.includes(field)) {
|
|
3218
|
+
this.formDesign.removeControl(field);
|
|
3219
|
+
}
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
isRequired(control) {
|
|
3223
|
+
if (!control || !control.validators)
|
|
3224
|
+
return false;
|
|
3225
|
+
return control.validators.some((v) => v.name === 'required' || v.name === 'requiredTrue');
|
|
2385
3226
|
}
|
|
2386
3227
|
onFormDesignCreated(e) {
|
|
2387
3228
|
console.log("onFormDesignCreated", e);
|
|
@@ -2393,7 +3234,7 @@ class CoreFormDesignComponent extends BaseComponent {
|
|
|
2393
3234
|
this.coreFormDesignService.$showFormMetadata.set(true);
|
|
2394
3235
|
}
|
|
2395
3236
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormDesignComponent, deps: [{ token: MultiLanguageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2396
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: CoreFormDesignComponent, isStandalone: true, selector: "core-form-design", inputs: { $idAsInput: { classPropertyName: "$idAsInput", publicName: "$idAsInput", isSignal: true, isRequired: false, transformFunction: null }, $id: { classPropertyName: "$id", publicName: "$id", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "$settingPanel", first: true, predicate: ["settingPanel"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"core-form-design-container fs-13\" [hotKeys]=\"['F3', 'F6', 'Escape']\">\r\n\r\n <core-page-header title=\"UI.COMPONENT_TITLE.WORKFLOW_FORM_DESIGN\" (buttonClick)=\"onCorePageHeaderButtonClicked($event)\"></core-page-header>\r\n\r\n <ng-template #formMetadata>\r\n <form-metadata></form-metadata>\r\n </ng-template>\r\n\r\n @if (coreFormDesignService.$showFormArrayDesign()) {\r\n <core-form-array-layout-editor />\r\n }\r\n\r\n @if (!coreFormDesignService.$isInWorkflowDesign()) {\r\n <aside class=\"af-metadata-overlay\" [@slideFromTopFadeIn]=\"coreFormDesignService.$showFormMetadata() ? 'in' : 'out'\"\r\n [class.shown]=\"coreFormDesignService.$showFormMetadata()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"formMetadata\"></ng-container>\r\n </aside>\r\n }\r\n\r\n <div \r\n class=\"field-setting-panel\" \r\n [class.open]=\"coreFormDesignService.$fieldSettingPanelOpen()\" \r\n [class.calculated-type]=\"coreFormDesignService.$selectedCell()?.control?.type==='calculated'\"\r\n [ngStyle]=\"{ zIndex: $zIndex() }\"\r\n #settingPanel\r\n >\r\n @if (!!(this.coreFormDesignService.$selectedCell())) {\r\n <field-setting></field-setting>\r\n }\r\n </div>\r\n\r\n <div class=\"form-design-left\">\r\n\r\n @switch ($leftPanelMode()) {\r\n @case (enumLeftPanelMode.FieldCollection) {\r\n @for (category of controlCategories; track $index) {\r\n <div class=\"category-name\">\r\n {{ category.name }}\r\n </div>\r\n <ul>\r\n @for (control of category.controls; track $index) {\r\n <li draggable=\"true\" (dragstart)=\"onDragStart($event, control)\" [class.full-width]=\"control.controlType === 'SEEKER' || control.controlType === 'ATTACHMENT' || control.controlType === 'GRIDBUFFER'\">\r\n @if (control.controlType === 'GRIDBUFFER') {\r\n <div class=\"grid-buffer-wrapper\">\r\n <core-control [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\"></core-control>\r\n </div>\r\n } @else {\r\n <core-control [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\"></core-control>\r\n }\r\n </li>\r\n <div class=\"space\"></div>\r\n }\r\n </ul>\r\n }\r\n }\r\n @case (enumLeftPanelMode.Json) {\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"switchJson()\">{{ $jsonMode() }}</button>\r\n @if ($jsonMode()==='selectedField') {\r\n <pre class=\"json-preview\">{{ coreFormDesignService.$currentControlJson() }}</pre>\r\n } @else {\r\n <pre class=\"json-preview\">{{ coreFormDesignService.$saveLiveJson() }}</pre>\r\n }\r\n \r\n }\r\n }\r\n\r\n </div>\r\n\r\n <div class=\"form-design-right\">\r\n <!-- <pre>{{ $injectedFieldsJson() }}</pre> -->\r\n\r\n @if (coreFormDesignService.$mode() === enumType.Default) {\r\n <div class=\"form-wrapper\">\r\n\r\n @if (!!coreFormDesignService.$isInWorkflowDesign()) {\r\n <form-metadata></form-metadata>\r\n }\r\n\r\n <form [formGroup]=\"formDesign\" autocomplete=\"off\">\r\n <div class=\"form-cells\">\r\n\r\n <div class=\"form-tool-bar\">\r\n @if (!$hasCalculatedSection()) {\r\n <button class=\"core-button-vns-container\" (click)=\"addCalculatedSection()\">+ Calculated fields</button>\r\n }\r\n <button class=\"core-button-vns-container\" (click)=\"addSection()\">+ Add Section</button>\r\n </div>\r\n \r\n @for (section of coreFormDesignService.$placeholderSections(); track $index; let sectionIndex = $index) {\r\n <div class=\"form-section-placeholder\">\r\n\r\n <div class=\"section-header\">\r\n\r\n <div class=\"section-img-wrapper\">\r\n <div class=\"section-img\" [class.calculated]=\"section.forCalculatedFields\"></div>\r\n </div>\r\n\r\n <label [attr.contenteditable]=\"!section.forCalculatedFields\"\r\n [htmlTooltip]=\"!!section.forCalculatedFields ? calculatedFieldsTooltip : null\"\r\n (blur)=\"onCaptionEditEnd(sectionIndex, $event)\"\r\n (keydown.enter)=\"onCaptionEditEnd(sectionIndex, $event); $event.preventDefault()\"\r\n >{{ section.caption }}</label>\r\n\r\n <div class=\"section-tool pointer\" (click)=\"deleteSection(sectionIndex)\" [appTooltip]=\"'Delete section'\" [showAnyway]=\"true\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n \r\n </div>\r\n \r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n\r\n <div class=\"form-row-wrapper\">\r\n <div class=\"form-row\">\r\n @for (cell of filteredCells(row); track $index; let colIndex = $index) {\r\n <div class=\"form-cell drop-target\" \r\n [ngStyle]=\"{ flex: (cell.flexSize ?? 0) + ' 1 0%' }\"\r\n [attr.data-flex]=\"cell.flexSize ?? 0\"\r\n (drop)=\"onDropIntoCell($event, sectionIndex, rowIndex, colIndex)\"\r\n (dragover)=\"onDragOver($event, section, cell.control!)\"\r\n (dragenter)=\"onDragEnter(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n (dragleave)=\"onDragLeave(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n [class.selected]=\"cell?.selected\"\r\n [class.dragging-over]=\"isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]\"\r\n [class.has-control]=\"!!cell && !!cell.control && !!getControl(cell)\"\r\n (click)=\"onCellClicked(sectionIndex, rowIndex, colIndex)\"\r\n >\r\n\r\n\r\n @if (!isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]) {\r\n\r\n @if (!!cell && !!cell.control && !!getControl(cell)) {\r\n <label contenteditable=\"true\"\r\n (blur)=\"onFieldCaptionEditEnd(cell, $event)\"\r\n (keydown.enter)=\"onFieldCaptionEditEnd(cell, $event); $event.preventDefault()\"\r\n [class.d-none]=\"!!getControl(cell)?.hidden\"\r\n [class.required]=\"!!cell && !!cell.control && !!getControl(cell) && isRequired(getControl(cell))\"\r\n >{{ cell.control.label || 'label' }}</label>\r\n\r\n @if (cell.control.controlType==='CALCULATED') {\r\n <div class=\"control-wrapper\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\">\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n </div>\r\n } @else {\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n }\r\n \r\n <div class=\"field-toolbar\">\r\n <ul>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Show settings'\">\r\n <i class=\"feather-settings\"></i>\r\n </div>\r\n </li>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"deleteField(row, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Remove field from cell'\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n \r\n } @else {\r\n <div class=\"placeholder\" [class.calculated]=\"!!section.forCalculatedFields\">\r\n {{ !!section.forCalculatedFields ? 'Drop calculated field here' : 'Drop here'}}\r\n </div>\r\n }\r\n\r\n @if (cell?.selected && canMergeCells(sectionIndex, rowIndex)) {\r\n <div class=\"merge-toolbar\">\r\n <button (click)=\"mergeCells(sectionIndex, rowIndex)\">\uD83D\uDD17 Merge</button>\r\n </div>\r\n }\r\n \r\n }\r\n\r\n </div>\r\n }\r\n </div>\r\n <div class=\"row-tool-bar\">\r\n <div class=\"icon-wrapper\" (click)=\"deleteRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Delete row'\" [showAnyway]=\"true\"><i class=\"feather-x\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addRow(sectionIndex)\" [appTooltip]=\"'Add row'\" [showAnyway]=\"true\"><i class=\"feather-arrow-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"insertRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Insert row'\" [showAnyway]=\"true\"><i class=\"feather-corner-right-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addColumn(row)\" [appTooltip]=\"'Add column'\" [showAnyway]=\"true\"><i class=\"feather-arrow-right\"></i></div>\r\n </div>\r\n </div>\r\n\r\n }\r\n </div>\r\n }\r\n \r\n \r\n </div>\r\n </form>\r\n </div>\r\n } @else if (!!$sections()) {\r\n\r\n @if(!!(injectedFields$ | async) && !!(injectedFields$ | async)!.length) {\r\n\r\n @if (!!coreFormDesignService.$afInstance().normalMode) {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" />\r\n } @else {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" ($onClose)=\"closePreview()\" />\r\n }\r\n\r\n } @else {\r\n <h2>COULD NOT UPDATE injectedFields$</h2>\r\n }\r\n\r\n } @else {\r\n <h2>$sections() empty / null / undefined</h2>\r\n }\r\n\r\n\r\n \r\n </div>\r\n @if ($loading()) {\r\n <core-toast-loading></core-toast-loading>\r\n }\r\n\r\n <ng-template #calculatedFieldsTooltip>\r\n <div style=\"max-width: 280px;\">\r\n <strong>Calculated Fields</strong><br />\r\n <p></p>\r\n These fields are hidden from the form and cannot be edited directly.<br /><br />\r\n - They are computed automatically during workflow execution.<br />\r\n - Each field depends on one or more standard input fields.<br />\r\n - The calculation is evaluated using either an SQL query engine (like <strong>Dapper</strong>) or an in-memory expression engine (like <strong>Dynamic Expresso</strong>).<br /><br />\r\n In both cases, the result is a <code>0</code> or <code>1</code>, representing <strong>false</strong> or <strong>true</strong>.<br /><br />\r\n These results can be used to influence workflow logic, rule trees, or approval paths.\r\n </div>\r\n </ng-template>\r\n \r\n</div>", styles: ["@charset \"UTF-8\";.core-form-design-container{position:relative;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));width:100%;overflow:hidden;background-color:#eff0f1;font-size:13px}.core-form-design-container .core-button-vns-container{margin-right:8px!important}.core-form-design-container .core-button-vns-container:last-child{background-color:#000;color:#fff;margin-right:0}.core-form-design-container .af-metadata-overlay{position:fixed;top:60px;left:66px;background:#fff;box-shadow:.4rem 0 2rem #0000002e;z-index:1000;width:1214px;height:calc(100vh - 75px);overflow-y:auto;pointer-events:none}.core-form-design-container .af-metadata-overlay.shown{pointer-events:auto}.core-form-design-container *{border-radius:0}.core-form-design-container ul,.core-form-design-container li{padding:0}.core-form-design-container li{max-width:200px}.core-form-design-container ul div.space{display:block;height:15px}.core-form-design-container li.full-width{max-width:100%}.core-form-design-container .field-setting-panel{display:block;position:fixed;width:360px;height:100vh;top:0;right:-360px;background-color:#fff;box-shadow:.4rem 0 2rem #0000002e;transition:right .5s ease-out}.core-form-design-container .field-setting-panel .close-wrapper{width:32px;height:32px;position:absolute;top:15px;right:15px;display:flex;background-color:#848484;border-radius:50%}.core-form-design-container .field-setting-panel .close-wrapper i{width:16px;height:16px;font-size:18px;color:#848484}.core-form-design-container .field-setting-panel .panel-caption{margin-bottom:1rem;padding-bottom:.5rem;border-bottom:1px solid #ddd;width:100%;overflow:hidden;text-wrap:nowrap;text-overflow:ellipsis}.core-form-design-container .field-setting-panel.calculated-type{width:500px;right:-500px}.core-form-design-container .field-setting-panel.calculated-type textarea{border-radius:8px;height:150px}.core-form-design-container .field-setting-panel.open{right:0}.core-form-design-container .form-design-left{position:absolute;top:var(--size-core-page-header-height);bottom:0;left:0;z-index:1;width:360px;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px;padding-right:calc(15px + var(--size-scrollbar-width));background-color:#87ceeb;overflow-y:hidden}.core-form-design-container .form-design-left .category-name{color:#fff}.core-form-design-container .form-design-left .grid-buffer-wrapper{background-color:#fff;padding:15px}.core-form-design-container .form-design-left ul:last-child{padding-bottom:400px}.core-form-design-container .form-design-left .category-name{margin-bottom:15px}.core-form-design-container .form-design-left .json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;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;width:330px;height:calc(100vh - 205px)}.core-form-design-container .form-design-left button{height:35px;border-radius:0;margin-bottom:15px;color:#fff;border:none;font-size:13px;background-color:transparent}.core-form-design-container .form-design-left:hover{overflow-y:auto;padding-right:15px}.core-form-design-container .form-design-right{width:100%;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px 15px 15px 375px;overflow-y:auto}.core-form-design-container .form-design-right .form-wrapper{width:100%;overflow-y:visible;background-color:#fff}.core-form-design-container .form-design-right .form-wrapper button{margin-left:12px;padding:4px 10px;border:1px solid #ccc;cursor:pointer;transition:all .2s;width:110px}.core-form-design-container .form-design-right .form-wrapper button:hover{background-color:#e4f0ff;border-color:#007bff;color:#007bff}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar{display:flex;align-items:center;justify-content:flex-end}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar>button{width:150px;margin:0}.core-form-design-container .form-design-right .form-wrapper .form-cells{display:flex;flex-direction:column;gap:32px;padding:20px 15px 15px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder{padding:12px 15px;border:1px dashed #ccc;background-color:#fff;box-shadow:0 2px 6px #0000000a}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header{display:flex;position:relative;align-items:center;justify-content:flex-start;font-weight:600;margin-bottom:12px;color:#333}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img{width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center;margin-right:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);background-color:transparent;border-radius:0}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool{position:absolute;right:5px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool i{font-size:24px;color:#848484}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header:hover .section-tool{display:block}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .row-tool-bar{display:flex;align-items:center;justify-content:flex-end;margin-bottom:8px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-row{display:flex;gap:15px;margin-bottom:15px;min-height:50px;background-color:#d3d3d3;padding:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell{flex:1;min-height:90px;background-color:#fcfcfc;border:1px dashed #ccc;position:relative;padding:20px 10px 10px;transition:border .2s ease-in-out}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell:before{content:attr(data-flex);position:absolute;top:2px;left:4px;font-size:10px;color:#999}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell label.required:after{content:\" *\";color:#ff040b}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar{position:absolute;right:7px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div{display:flex;width:24px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.has-control:hover .field-toolbar{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.active-drop{border-color:#007bff;background-color:#eef6ff;transition:.2s}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .placeholder{display:flex;align-items:center;justify-content:center;background-color:#fff;color:#007bff;padding:15px 0;width:100%;cursor:default}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .placeholder.calculated{color:#ff4500}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper{width:24px;height:24px;border-radius:50%;padding:0;cursor:pointer;display:none;color:gray;border:1px solid gray;margin-left:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper:hover .icon-wrapper{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cell.selected{background-color:#dff6dd}.core-form-design-container .form-design-right .form-wrapper .merge-toolbar{text-align:center;margin-top:4px}.core-form-design-container .form-design-right .form-wrapper.live-form{padding-bottom:15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header{padding:0 15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon{position:absolute;right:7px;top:6px;z-index:2;color:gray;cursor:pointer}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon i{font-size:18px}.core-form-design-container .drop-target{min-height:50px;min-width:50px;border:2px dashed transparent;transition:border .2s ease}.core-form-design-container .drop-target.active-drop{border-color:#007bff;background-color:#eaf4ff}.core-form-design-container .no-padding{padding:0!important}.core-form-design-container .modal-content-root{overflow:visible}\n", ".core-form-container{overflow-x:visible}.core-form-container>form .section{margin-top:var(--size-layout-block-cell-spacing)}.core-form-container>form .section:not(:first-child){margin-top:calc(var(--size-layout-block-cell-spacing) * 2)}.core-form-container>form .section .section-header-label{display:block;height:34px;line-height:34px;margin-bottom:15px;margin-left:12px}.core-form-container>form .section .section-header-label .section-img-wrapper{position:relative}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img{position:absolute;width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);border-radius:0;background-color:transparent}.core-form-container>form .section .section-header-label .section-calc-wrapper{width:34px;height:34px;display:flex;align-items:center;justify-content:center;background-color:#d3d3d3;border-radius:50%}.core-form-container>form .section .section-header-label .section-calc-wrapper i{width:24px;height:24px;font-size:24px;color:#1b4332}.core-form-container>form .section .section-header-label .section-caption{padding-left:40px;font-weight:700;color:#696969}.core-form-container .row{margin-left:var(--size-layout-block-cell-spacing) 0px;margin-right:var(--size-layout-block-cell-spacing) 0px}.core-form-container .row .grid-buffer{border:dotted 2px darkgray}.core-form-container .row .button-control{display:flex;align-items:flex-end}.core-form-container .form-row{margin:var(--size-layout-block-cell-spacing) 0px;display:flex;align-items:center;justify-content:center}.core-form-container .form-row>button{cursor:pointer;border-radius:0}.core-form-container .form-row>button:not(:first-child){margin-left:var(--size-layout-block-cell-spacing)}.core-form-container .dev-button{cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;padding:8px;width:120px;border-radius:18px;box-shadow:.4rem 0 2rem #0000002e}.core-form-container .dev-button:not(:last-child){margin-right:15px}.core-form-container .dev-button:first-child{background-color:#dff6dd;border:1px #9fdc9d solid}.core-form-container .dev-button:last-child{background-color:#fff4ce;border:1px #ffda6a solid}.core-form-container .payload-preview{display:block;width:calc(100% - 48px);height:200px;white-space:pre-wrap;overflow-x:hidden;overflow-y:auto;background-color:#dff6dd;padding:24px;margin:24px;text-indent:-58px;color:#333!important;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;line-height:1.5}.core-form-container .payload-preview.validator-preview{background-color:#fff4ce}.core-form-container .bottom-template-wrapper{padding-left:12px;padding-right:12px}.core-form-container .w-100{width:100%}.core-form-container .pr18{padding-right:18px}\n", ".core-button-vns-container{height:30px;display:flex;align-items:center;justify-content:center;min-width:30px}.core-button-vns-container .action-wrapper{height:30px!important;width:30px!important;display:flex;align-items:center;justify-content:center}.core-button-vns-container .action-wrapper:has(i:hover){background-color:#e7e7e7;border-radius:50%}.core-button-vns-container .btn-for-form{border:none;border-radius:0;background-color:transparent;color:#000;min-width:120px}.core-button-vns-container button.last-child{background-color:#000;color:#fff}.core-button-vns-container .action-wrapper.last-child{background-color:var(--color-basic-orange);color:#fff;border-radius:50%}.core-button-vns-container .action-wrapper.last-child:hover{background-color:var(--color-basic-orange);box-shadow:0 1rem 3rem #0000002e}.core-button-vns-container .temporary-unavailable{user-select:none;-moz-user-select:none;-webkit-user-select:none;cursor:not-allowed!important;opacity:.5}.core-button-vns-container .temporary-unavailable:hover{background-color:transparent!important}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CoreFormArrayLayoutEditorComponent, selector: "core-form-array-layout-editor" }, { kind: "component", type: CoreToastLoadingComponent, selector: "core-toast-loading" }, { kind: "component", type: CorePageHeaderComponent, selector: "core-page-header", inputs: ["instanceNumber", "shownItems", "title", "hideButtonGroup", "htmlTooltipRef"], outputs: ["buttonClick"] }, { kind: "component", type: FormMetadataComponent, selector: "form-metadata" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: TooltipDirective, selector: "[appTooltip]", inputs: ["color", "backgroundColor", "appTooltip", "showAnyway", "position"] }, { kind: "directive", type: HotKeysDirective, selector: "[hotKeys]", inputs: ["hotKeys"] }, { kind: "component", type: CoreControlComponent, selector: "core-control", inputs: ["control", "form", "checkError$", "rangeLimit"] }, { kind: "component", type: FieldSettingComponent, selector: "field-setting" }, { kind: "component", type: LiveFormComponent, selector: "live-form", inputs: ["$designMode", "$forKickOff", "$workflowReactContext"], outputs: ["$onClose"] }, { kind: "directive", type: HtmlTooltipDirective, selector: "[htmlTooltip]", inputs: ["htmlTooltip", "tooltipContext", "maxWidthUnset", "backgroundColor"] }], animations: [slideFromTopFadeIn], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3237
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: CoreFormDesignComponent, isStandalone: true, selector: "core-form-design", inputs: { $idAsInput: { classPropertyName: "$idAsInput", publicName: "$idAsInput", isSignal: true, isRequired: false, transformFunction: null }, $id: { classPropertyName: "$id", publicName: "$id", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "$settingPanel", first: true, predicate: ["settingPanel"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"core-form-design-container fs-13\" [hotKeys]=\"['F3', 'F6', 'Escape']\">\r\n\r\n <core-page-header title=\"UI.COMPONENT_TITLE.WORKFLOW_FORM_DESIGN\" (buttonClick)=\"onCorePageHeaderButtonClicked($event)\"></core-page-header>\r\n\r\n <ng-template #formMetadata>\r\n <form-metadata></form-metadata>\r\n </ng-template>\r\n\r\n @if (coreFormDesignService.$showFormArrayDesign()) {\r\n <core-form-array-layout-editor />\r\n }\r\n\r\n @if (!coreFormDesignService.$isInWorkflowDesign()) {\r\n <aside class=\"af-metadata-overlay\" [@slideFromTopFadeIn]=\"coreFormDesignService.$showFormMetadata() ? 'in' : 'out'\"\r\n [class.shown]=\"coreFormDesignService.$showFormMetadata()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"formMetadata\"></ng-container>\r\n </aside>\r\n }\r\n\r\n <div \r\n class=\"field-setting-panel\" \r\n [class.open]=\"coreFormDesignService.$fieldSettingPanelOpen()\" \r\n [class.calculated-type]=\"coreFormDesignService.$selectedCell()?.control?.type==='calculated'\"\r\n [ngStyle]=\"{ zIndex: $zIndex() }\"\r\n #settingPanel\r\n >\r\n @if (!!(this.coreFormDesignService.$selectedCell())) {\r\n <field-setting></field-setting>\r\n }\r\n </div>\r\n\r\n <div class=\"form-design-left\">\r\n\r\n @switch ($leftPanelMode()) {\r\n @case (enumLeftPanelMode.FieldCollection) {\r\n @for (category of controlCategories; track $index) {\r\n <div class=\"category-name\">\r\n {{ category.name }}\r\n </div>\r\n <ul>\r\n @for (control of category.controls; track $index) {\r\n <li draggable=\"true\" (dragstart)=\"onDragStart($event, control)\" [class.full-width]=\"control.controlType === 'SEEKER' || control.controlType === 'ATTACHMENT' || control.controlType === 'GRIDBUFFER'\">\r\n @if (control.controlType === 'GRIDBUFFER') {\r\n <div class=\"grid-buffer-wrapper\">\r\n <core-control [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\"></core-control>\r\n </div>\r\n } @else {\r\n <core-control [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\"></core-control>\r\n }\r\n </li>\r\n <div class=\"space\"></div>\r\n }\r\n </ul>\r\n }\r\n }\r\n @case (enumLeftPanelMode.Json) {\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"switchJson()\">{{ $jsonMode() }}</button>\r\n @if ($jsonMode()==='selectedField') {\r\n <pre class=\"json-preview\">{{ coreFormDesignService.$currentControlJson() }}</pre>\r\n } @else {\r\n <pre class=\"json-preview\">{{ coreFormDesignService.$saveLiveJson() }}</pre>\r\n }\r\n \r\n }\r\n }\r\n\r\n </div>\r\n\r\n <div class=\"form-design-right\">\r\n\r\n <core-form-group-editor [$idAsInput]=\"true\" />\r\n <!-- <pre>{{ $injectedFieldsJson() }}</pre> -->\r\n\r\n \r\n <!-- @if (coreFormDesignService.$mode() === enumType.Default) {\r\n <div class=\"form-wrapper\">\r\n\r\n @if (!!coreFormDesignService.$isInWorkflowDesign()) {\r\n <form-metadata></form-metadata>\r\n }\r\n\r\n <form [formGroup]=\"formDesign\" autocomplete=\"off\">\r\n <div class=\"form-cells\">\r\n\r\n <div class=\"form-tool-bar\">\r\n @if (!$hasCalculatedSection()) {\r\n <button class=\"core-button-vns-container\" (click)=\"addCalculatedSection()\">+ Calculated fields</button>\r\n }\r\n <button class=\"core-button-vns-container\" (click)=\"addSection()\">+ Add Section</button>\r\n </div>\r\n \r\n @for (section of coreFormDesignService.$placeholderSections(); track $index; let sectionIndex = $index) {\r\n <div class=\"form-section-placeholder\">\r\n\r\n <div class=\"section-header\">\r\n\r\n <div class=\"section-img-wrapper\">\r\n <div class=\"section-img\" [class.calculated]=\"section.forCalculatedFields\"></div>\r\n </div>\r\n\r\n <label [attr.contenteditable]=\"!section.forCalculatedFields\"\r\n [htmlTooltip]=\"!!section.forCalculatedFields ? calculatedFieldsTooltip : null\"\r\n (blur)=\"onCaptionEditEnd(sectionIndex, $event)\"\r\n (keydown.enter)=\"onCaptionEditEnd(sectionIndex, $event); $event.preventDefault()\"\r\n >{{ section.caption }}</label>\r\n\r\n <div class=\"section-tool pointer\" (click)=\"deleteSection(sectionIndex)\" [appTooltip]=\"'Delete section'\" [showAnyway]=\"true\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n \r\n </div>\r\n \r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n\r\n <div class=\"form-row-wrapper\">\r\n <div class=\"form-row\">\r\n @for (cell of filteredCells(row); track $index; let colIndex = $index) {\r\n <div class=\"form-cell drop-target\" \r\n [ngStyle]=\"{ flex: (cell.flexSize ?? 0) + ' 1 0%' }\"\r\n [attr.data-flex]=\"cell.flexSize ?? 0\"\r\n (drop)=\"onDropIntoCell($event, sectionIndex, rowIndex, colIndex)\"\r\n (dragover)=\"onDragOver($event, section, cell.control!)\"\r\n (dragenter)=\"onDragEnter(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n (dragleave)=\"onDragLeave(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n [class.selected]=\"cell?.selected\"\r\n [class.dragging-over]=\"isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]\"\r\n [class.has-control]=\"!!cell && !!cell.control && !!getControl(cell)\"\r\n (click)=\"onCellClicked(sectionIndex, rowIndex, colIndex)\"\r\n >\r\n\r\n\r\n @if (!isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]) {\r\n\r\n @if (!!cell && !!cell.control && !!getControl(cell)) {\r\n <label contenteditable=\"true\"\r\n (blur)=\"onFieldCaptionEditEnd(cell, $event)\"\r\n (keydown.enter)=\"onFieldCaptionEditEnd(cell, $event); $event.preventDefault()\"\r\n [class.d-none]=\"!!getControl(cell)?.hidden\"\r\n [class.required]=\"!!cell && !!cell.control && !!getControl(cell) && isRequired(getControl(cell))\"\r\n >{{ cell.control.label || 'label' }}</label>\r\n\r\n @if (cell.control.controlType==='CALCULATED') {\r\n <div class=\"control-wrapper\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\">\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n </div>\r\n } @else {\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n }\r\n \r\n <div class=\"field-toolbar\">\r\n <ul>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Show settings'\">\r\n <i class=\"feather-settings\"></i>\r\n </div>\r\n </li>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"deleteField(row, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Remove field from cell'\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n \r\n } @else {\r\n <div class=\"placeholder\" [class.calculated]=\"!!section.forCalculatedFields\">\r\n {{ !!section.forCalculatedFields ? 'Drop calculated field here' : 'Drop here'}}\r\n </div>\r\n }\r\n\r\n @if (cell?.selected && canMergeCells(sectionIndex, rowIndex)) {\r\n <div class=\"merge-toolbar\">\r\n <button (click)=\"mergeCells(sectionIndex, rowIndex)\">\uD83D\uDD17 Merge</button>\r\n </div>\r\n }\r\n \r\n }\r\n\r\n </div>\r\n }\r\n </div>\r\n <div class=\"row-tool-bar\">\r\n <div class=\"icon-wrapper\" (click)=\"deleteRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Delete row'\" [showAnyway]=\"true\"><i class=\"feather-x\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addRow(sectionIndex)\" [appTooltip]=\"'Add row'\" [showAnyway]=\"true\"><i class=\"feather-arrow-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"insertRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Insert row'\" [showAnyway]=\"true\"><i class=\"feather-corner-right-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addColumn(row)\" [appTooltip]=\"'Add column'\" [showAnyway]=\"true\"><i class=\"feather-arrow-right\"></i></div>\r\n </div>\r\n </div>\r\n\r\n }\r\n </div>\r\n }\r\n \r\n \r\n </div>\r\n </form>\r\n </div>\r\n } @else if (!!$sections()) {\r\n\r\n @if(!!(injectedFields$ | async) && !!(injectedFields$ | async)!.length) {\r\n\r\n @if (!!coreFormDesignService.$afInstance().normalMode) {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" />\r\n } @else {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" ($onClose)=\"closePreview()\" />\r\n }\r\n\r\n } @else {\r\n <h2>COULD NOT UPDATE injectedFields$</h2>\r\n }\r\n\r\n } @else {\r\n <h2>$sections() empty / null / undefined</h2>\r\n } -->\r\n\r\n\r\n \r\n </div>\r\n @if ($loading()) {\r\n <core-toast-loading></core-toast-loading>\r\n }\r\n\r\n <ng-template #calculatedFieldsTooltip>\r\n <div style=\"max-width: 280px;\">\r\n <strong>Calculated Fields</strong><br />\r\n <p></p>\r\n These fields are hidden from the form and cannot be edited directly.<br /><br />\r\n - They are computed automatically during workflow execution.<br />\r\n - Each field depends on one or more standard input fields.<br />\r\n - The calculation is evaluated using either an SQL query engine (like <strong>Dapper</strong>) or an in-memory expression engine (like <strong>Dynamic Expresso</strong>).<br /><br />\r\n In both cases, the result is a <code>0</code> or <code>1</code>, representing <strong>false</strong> or <strong>true</strong>.<br /><br />\r\n These results can be used to influence workflow logic, rule trees, or approval paths.\r\n </div>\r\n </ng-template>\r\n \r\n</div>", styles: ["@charset \"UTF-8\";.core-form-design-container{position:relative;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));width:100%;overflow:hidden;background-color:#eff0f1;font-size:13px}.core-form-design-container .core-button-vns-container{margin-right:8px!important}.core-form-design-container .core-button-vns-container:last-child{background-color:#000;color:#fff;margin-right:0}.core-form-design-container .af-metadata-overlay{position:fixed;top:60px;left:66px;background:#fff;box-shadow:.4rem 0 2rem #0000002e;z-index:1000;width:1214px;height:calc(100vh - 75px);overflow-y:auto;pointer-events:none}.core-form-design-container .af-metadata-overlay.shown{pointer-events:auto}.core-form-design-container *{border-radius:0}.core-form-design-container ul,.core-form-design-container li{padding:0}.core-form-design-container li{max-width:200px}.core-form-design-container ul div.space{display:block;height:15px}.core-form-design-container li.full-width{max-width:100%}.core-form-design-container .field-setting-panel{display:block;position:fixed;width:360px;height:100vh;top:0;right:-360px;background-color:#fff;box-shadow:.4rem 0 2rem #0000002e;transition:right .5s ease-out}.core-form-design-container .field-setting-panel .close-wrapper{width:32px;height:32px;position:absolute;top:15px;right:15px;display:flex;background-color:#848484;border-radius:50%}.core-form-design-container .field-setting-panel .close-wrapper i{width:16px;height:16px;font-size:18px;color:#848484}.core-form-design-container .field-setting-panel .panel-caption{margin-bottom:1rem;padding-bottom:.5rem;border-bottom:1px solid #ddd;width:100%;overflow:hidden;text-wrap:nowrap;text-overflow:ellipsis}.core-form-design-container .field-setting-panel.calculated-type{width:500px;right:-500px}.core-form-design-container .field-setting-panel.calculated-type textarea{border-radius:8px;height:150px}.core-form-design-container .field-setting-panel.open{right:0}.core-form-design-container .form-design-left{position:absolute;top:var(--size-core-page-header-height);bottom:0;left:0;z-index:1;width:360px;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px;padding-right:calc(15px + var(--size-scrollbar-width));background-color:#87ceeb;overflow-y:hidden}.core-form-design-container .form-design-left .category-name{color:#fff}.core-form-design-container .form-design-left .grid-buffer-wrapper{background-color:#fff;padding:15px}.core-form-design-container .form-design-left ul:last-child{padding-bottom:400px}.core-form-design-container .form-design-left .category-name{margin-bottom:15px}.core-form-design-container .form-design-left .json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;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;width:330px;height:calc(100vh - 205px)}.core-form-design-container .form-design-left button{height:35px;border-radius:0;margin-bottom:15px;color:#fff;border:none;font-size:13px;background-color:transparent}.core-form-design-container .form-design-left:hover{overflow-y:auto;padding-right:15px}.core-form-design-container .form-design-right{width:100%;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px 15px 15px 375px;overflow-y:auto}.core-form-design-container .form-design-right .form-wrapper{width:100%;overflow-y:visible;background-color:#fff}.core-form-design-container .form-design-right .form-wrapper button{margin-left:12px;padding:4px 10px;border:1px solid #ccc;cursor:pointer;transition:all .2s;width:110px}.core-form-design-container .form-design-right .form-wrapper button:hover{background-color:#e4f0ff;border-color:#007bff;color:#007bff}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar{display:flex;align-items:center;justify-content:flex-end}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar>button{width:150px;margin:0}.core-form-design-container .form-design-right .form-wrapper .form-cells{display:flex;flex-direction:column;gap:32px;padding:20px 15px 15px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder{padding:12px 15px;border:1px dashed #ccc;background-color:#fff;box-shadow:0 2px 6px #0000000a}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header{display:flex;position:relative;align-items:center;justify-content:flex-start;font-weight:600;margin-bottom:12px;color:#333}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img{width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center;margin-right:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);background-color:transparent;border-radius:0}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool{position:absolute;right:5px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool i{font-size:24px;color:#848484}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header:hover .section-tool{display:block}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .row-tool-bar{display:flex;align-items:center;justify-content:flex-end;margin-bottom:8px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-row{display:flex;gap:15px;margin-bottom:15px;min-height:50px;background-color:#d3d3d3;padding:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell{flex:1;min-height:90px;background-color:#fcfcfc;border:1px dashed #ccc;position:relative;padding:20px 10px 10px;transition:border .2s ease-in-out}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell:before{content:attr(data-flex);position:absolute;top:2px;left:4px;font-size:10px;color:#999}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell label.required:after{content:\" *\";color:#ff040b}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar{position:absolute;right:7px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div{display:flex;width:24px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.has-control:hover .field-toolbar{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.active-drop{border-color:#007bff;background-color:#eef6ff;transition:.2s}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .placeholder{display:flex;align-items:center;justify-content:center;background-color:#fff;color:#007bff;padding:15px 0;width:100%;cursor:default}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .placeholder.calculated{color:#ff4500}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper{width:24px;height:24px;border-radius:50%;padding:0;cursor:pointer;display:none;color:gray;border:1px solid gray;margin-left:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper:hover .icon-wrapper{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cell.selected{background-color:#dff6dd}.core-form-design-container .form-design-right .form-wrapper .merge-toolbar{text-align:center;margin-top:4px}.core-form-design-container .form-design-right .form-wrapper.live-form{padding-bottom:15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header{padding:0 15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon{position:absolute;right:7px;top:6px;z-index:2;color:gray;cursor:pointer}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon i{font-size:18px}.core-form-design-container .drop-target{min-height:50px;min-width:50px;border:2px dashed transparent;transition:border .2s ease}.core-form-design-container .drop-target.active-drop{border-color:#007bff;background-color:#eaf4ff}.core-form-design-container .no-padding{padding:0!important}.core-form-design-container .modal-content-root{overflow:visible}\n", ".core-form-container{overflow-x:visible}.core-form-container>form .section{margin-top:var(--size-layout-block-cell-spacing)}.core-form-container>form .section:not(:first-child){margin-top:calc(var(--size-layout-block-cell-spacing) * 2)}.core-form-container>form .section .section-header-label{display:block;height:34px;line-height:34px;margin-bottom:15px;margin-left:12px}.core-form-container>form .section .section-header-label .section-img-wrapper{position:relative}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img{position:absolute;width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);border-radius:0;background-color:transparent}.core-form-container>form .section .section-header-label .section-calc-wrapper{width:34px;height:34px;display:flex;align-items:center;justify-content:center;background-color:#d3d3d3;border-radius:50%}.core-form-container>form .section .section-header-label .section-calc-wrapper i{width:24px;height:24px;font-size:24px;color:#1b4332}.core-form-container>form .section .section-header-label .section-caption{padding-left:40px;font-weight:700;color:#696969}.core-form-container .row{margin-left:var(--size-layout-block-cell-spacing) 0px;margin-right:var(--size-layout-block-cell-spacing) 0px}.core-form-container .row .grid-buffer{border:dotted 2px darkgray}.core-form-container .row .button-control{display:flex;align-items:flex-end}.core-form-container .form-row{margin:var(--size-layout-block-cell-spacing) 0px;display:flex;align-items:center;justify-content:center}.core-form-container .form-row>button{cursor:pointer;border-radius:0}.core-form-container .form-row>button:not(:first-child){margin-left:var(--size-layout-block-cell-spacing)}.core-form-container .dev-button{cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;padding:8px;width:120px;border-radius:18px;box-shadow:.4rem 0 2rem #0000002e}.core-form-container .dev-button:not(:last-child){margin-right:15px}.core-form-container .dev-button:first-child{background-color:#dff6dd;border:1px #9fdc9d solid}.core-form-container .dev-button:last-child{background-color:#fff4ce;border:1px #ffda6a solid}.core-form-container .payload-preview{display:block;width:calc(100% - 48px);height:200px;white-space:pre-wrap;overflow-x:hidden;overflow-y:auto;background-color:#dff6dd;padding:24px;margin:24px;text-indent:-58px;color:#333!important;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;line-height:1.5}.core-form-container .payload-preview.validator-preview{background-color:#fff4ce}.core-form-container .bottom-template-wrapper{padding-left:12px;padding-right:12px}.core-form-container .w-100{width:100%}.core-form-container .pr18{padding-right:18px}\n", ".core-button-vns-container{height:30px;display:flex;align-items:center;justify-content:center;min-width:30px}.core-button-vns-container .action-wrapper{height:30px!important;width:30px!important;display:flex;align-items:center;justify-content:center}.core-button-vns-container .action-wrapper:has(i:hover){background-color:#e7e7e7;border-radius:50%}.core-button-vns-container .btn-for-form{border:none;border-radius:0;background-color:transparent;color:#000;min-width:120px}.core-button-vns-container button.last-child{background-color:#000;color:#fff}.core-button-vns-container .action-wrapper.last-child{background-color:var(--color-basic-orange);color:#fff;border-radius:50%}.core-button-vns-container .action-wrapper.last-child:hover{background-color:var(--color-basic-orange);box-shadow:0 1rem 3rem #0000002e}.core-button-vns-container .temporary-unavailable{user-select:none;-moz-user-select:none;-webkit-user-select:none;cursor:not-allowed!important;opacity:.5}.core-button-vns-container .temporary-unavailable:hover{background-color:transparent!important}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CoreFormGroupEditorComponent, selector: "core-form-group-editor", inputs: ["$isNested", "$idAsInput", "$id"] }, { kind: "component", type: CoreFormArrayLayoutEditorComponent, selector: "core-form-array-layout-editor" }, { kind: "component", type: CoreToastLoadingComponent, selector: "core-toast-loading" }, { kind: "component", type: CorePageHeaderComponent, selector: "core-page-header", inputs: ["instanceNumber", "shownItems", "title", "hideButtonGroup", "htmlTooltipRef"], outputs: ["buttonClick"] }, { kind: "component", type: FormMetadataComponent, selector: "form-metadata" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: HotKeysDirective, selector: "[hotKeys]", inputs: ["hotKeys"] }, { kind: "component", type: CoreControlComponent, selector: "core-control", inputs: ["control", "form", "checkError$", "rangeLimit"] }, { kind: "component", type: FieldSettingComponent, selector: "field-setting", inputs: ["$isNested"] }], animations: [slideFromTopFadeIn], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2397
3238
|
}
|
|
2398
3239
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormDesignComponent, decorators: [{
|
|
2399
3240
|
type: Component,
|
|
@@ -2401,6 +3242,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
|
|
|
2401
3242
|
NgStyle,
|
|
2402
3243
|
AsyncPipe,
|
|
2403
3244
|
NgTemplateOutlet,
|
|
3245
|
+
CoreFormGroupEditorComponent,
|
|
2404
3246
|
CoreFormArrayLayoutEditorComponent,
|
|
2405
3247
|
CoreToastLoadingComponent,
|
|
2406
3248
|
CorePageHeaderComponent,
|
|
@@ -2425,7 +3267,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
|
|
|
2425
3267
|
FieldSettingComponent,
|
|
2426
3268
|
LiveFormComponent,
|
|
2427
3269
|
HtmlTooltipDirective,
|
|
2428
|
-
], animations: [slideFromTopFadeIn], template: "<div class=\"core-form-design-container fs-13\" [hotKeys]=\"['F3', 'F6', 'Escape']\">\r\n\r\n <core-page-header title=\"UI.COMPONENT_TITLE.WORKFLOW_FORM_DESIGN\" (buttonClick)=\"onCorePageHeaderButtonClicked($event)\"></core-page-header>\r\n\r\n <ng-template #formMetadata>\r\n <form-metadata></form-metadata>\r\n </ng-template>\r\n\r\n @if (coreFormDesignService.$showFormArrayDesign()) {\r\n <core-form-array-layout-editor />\r\n }\r\n\r\n @if (!coreFormDesignService.$isInWorkflowDesign()) {\r\n <aside class=\"af-metadata-overlay\" [@slideFromTopFadeIn]=\"coreFormDesignService.$showFormMetadata() ? 'in' : 'out'\"\r\n [class.shown]=\"coreFormDesignService.$showFormMetadata()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"formMetadata\"></ng-container>\r\n </aside>\r\n }\r\n\r\n <div \r\n class=\"field-setting-panel\" \r\n [class.open]=\"coreFormDesignService.$fieldSettingPanelOpen()\" \r\n [class.calculated-type]=\"coreFormDesignService.$selectedCell()?.control?.type==='calculated'\"\r\n [ngStyle]=\"{ zIndex: $zIndex() }\"\r\n #settingPanel\r\n >\r\n @if (!!(this.coreFormDesignService.$selectedCell())) {\r\n <field-setting></field-setting>\r\n }\r\n </div>\r\n\r\n <div class=\"form-design-left\">\r\n\r\n @switch ($leftPanelMode()) {\r\n @case (enumLeftPanelMode.FieldCollection) {\r\n @for (category of controlCategories; track $index) {\r\n <div class=\"category-name\">\r\n {{ category.name }}\r\n </div>\r\n <ul>\r\n @for (control of category.controls; track $index) {\r\n <li draggable=\"true\" (dragstart)=\"onDragStart($event, control)\" [class.full-width]=\"control.controlType === 'SEEKER' || control.controlType === 'ATTACHMENT' || control.controlType === 'GRIDBUFFER'\">\r\n @if (control.controlType === 'GRIDBUFFER') {\r\n <div class=\"grid-buffer-wrapper\">\r\n <core-control [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\"></core-control>\r\n </div>\r\n } @else {\r\n <core-control [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\"></core-control>\r\n }\r\n </li>\r\n <div class=\"space\"></div>\r\n }\r\n </ul>\r\n }\r\n }\r\n @case (enumLeftPanelMode.Json) {\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"switchJson()\">{{ $jsonMode() }}</button>\r\n @if ($jsonMode()==='selectedField') {\r\n <pre class=\"json-preview\">{{ coreFormDesignService.$currentControlJson() }}</pre>\r\n } @else {\r\n <pre class=\"json-preview\">{{ coreFormDesignService.$saveLiveJson() }}</pre>\r\n }\r\n \r\n }\r\n }\r\n\r\n </div>\r\n\r\n <div class=\"form-design-right\">\r\n <!-- <pre>{{ $injectedFieldsJson() }}</pre> -->\r\n\r\n @if (coreFormDesignService.$mode() === enumType.Default) {\r\n <div class=\"form-wrapper\">\r\n\r\n @if (!!coreFormDesignService.$isInWorkflowDesign()) {\r\n <form-metadata></form-metadata>\r\n }\r\n\r\n <form [formGroup]=\"formDesign\" autocomplete=\"off\">\r\n <div class=\"form-cells\">\r\n\r\n <div class=\"form-tool-bar\">\r\n @if (!$hasCalculatedSection()) {\r\n <button class=\"core-button-vns-container\" (click)=\"addCalculatedSection()\">+ Calculated fields</button>\r\n }\r\n <button class=\"core-button-vns-container\" (click)=\"addSection()\">+ Add Section</button>\r\n </div>\r\n \r\n @for (section of coreFormDesignService.$placeholderSections(); track $index; let sectionIndex = $index) {\r\n <div class=\"form-section-placeholder\">\r\n\r\n <div class=\"section-header\">\r\n\r\n <div class=\"section-img-wrapper\">\r\n <div class=\"section-img\" [class.calculated]=\"section.forCalculatedFields\"></div>\r\n </div>\r\n\r\n <label [attr.contenteditable]=\"!section.forCalculatedFields\"\r\n [htmlTooltip]=\"!!section.forCalculatedFields ? calculatedFieldsTooltip : null\"\r\n (blur)=\"onCaptionEditEnd(sectionIndex, $event)\"\r\n (keydown.enter)=\"onCaptionEditEnd(sectionIndex, $event); $event.preventDefault()\"\r\n >{{ section.caption }}</label>\r\n\r\n <div class=\"section-tool pointer\" (click)=\"deleteSection(sectionIndex)\" [appTooltip]=\"'Delete section'\" [showAnyway]=\"true\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n \r\n </div>\r\n \r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n\r\n <div class=\"form-row-wrapper\">\r\n <div class=\"form-row\">\r\n @for (cell of filteredCells(row); track $index; let colIndex = $index) {\r\n <div class=\"form-cell drop-target\" \r\n [ngStyle]=\"{ flex: (cell.flexSize ?? 0) + ' 1 0%' }\"\r\n [attr.data-flex]=\"cell.flexSize ?? 0\"\r\n (drop)=\"onDropIntoCell($event, sectionIndex, rowIndex, colIndex)\"\r\n (dragover)=\"onDragOver($event, section, cell.control!)\"\r\n (dragenter)=\"onDragEnter(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n (dragleave)=\"onDragLeave(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n [class.selected]=\"cell?.selected\"\r\n [class.dragging-over]=\"isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]\"\r\n [class.has-control]=\"!!cell && !!cell.control && !!getControl(cell)\"\r\n (click)=\"onCellClicked(sectionIndex, rowIndex, colIndex)\"\r\n >\r\n\r\n\r\n @if (!isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]) {\r\n\r\n @if (!!cell && !!cell.control && !!getControl(cell)) {\r\n <label contenteditable=\"true\"\r\n (blur)=\"onFieldCaptionEditEnd(cell, $event)\"\r\n (keydown.enter)=\"onFieldCaptionEditEnd(cell, $event); $event.preventDefault()\"\r\n [class.d-none]=\"!!getControl(cell)?.hidden\"\r\n [class.required]=\"!!cell && !!cell.control && !!getControl(cell) && isRequired(getControl(cell))\"\r\n >{{ cell.control.label || 'label' }}</label>\r\n\r\n @if (cell.control.controlType==='CALCULATED') {\r\n <div class=\"control-wrapper\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\">\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n </div>\r\n } @else {\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n }\r\n \r\n <div class=\"field-toolbar\">\r\n <ul>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Show settings'\">\r\n <i class=\"feather-settings\"></i>\r\n </div>\r\n </li>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"deleteField(row, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Remove field from cell'\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n \r\n } @else {\r\n <div class=\"placeholder\" [class.calculated]=\"!!section.forCalculatedFields\">\r\n {{ !!section.forCalculatedFields ? 'Drop calculated field here' : 'Drop here'}}\r\n </div>\r\n }\r\n\r\n @if (cell?.selected && canMergeCells(sectionIndex, rowIndex)) {\r\n <div class=\"merge-toolbar\">\r\n <button (click)=\"mergeCells(sectionIndex, rowIndex)\">\uD83D\uDD17 Merge</button>\r\n </div>\r\n }\r\n \r\n }\r\n\r\n </div>\r\n }\r\n </div>\r\n <div class=\"row-tool-bar\">\r\n <div class=\"icon-wrapper\" (click)=\"deleteRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Delete row'\" [showAnyway]=\"true\"><i class=\"feather-x\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addRow(sectionIndex)\" [appTooltip]=\"'Add row'\" [showAnyway]=\"true\"><i class=\"feather-arrow-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"insertRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Insert row'\" [showAnyway]=\"true\"><i class=\"feather-corner-right-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addColumn(row)\" [appTooltip]=\"'Add column'\" [showAnyway]=\"true\"><i class=\"feather-arrow-right\"></i></div>\r\n </div>\r\n </div>\r\n\r\n }\r\n </div>\r\n }\r\n \r\n \r\n </div>\r\n </form>\r\n </div>\r\n } @else if (!!$sections()) {\r\n\r\n @if(!!(injectedFields$ | async) && !!(injectedFields$ | async)!.length) {\r\n\r\n @if (!!coreFormDesignService.$afInstance().normalMode) {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" />\r\n } @else {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" ($onClose)=\"closePreview()\" />\r\n }\r\n\r\n } @else {\r\n <h2>COULD NOT UPDATE injectedFields$</h2>\r\n }\r\n\r\n } @else {\r\n <h2>$sections() empty / null / undefined</h2>\r\n }\r\n\r\n\r\n \r\n </div>\r\n @if ($loading()) {\r\n <core-toast-loading></core-toast-loading>\r\n }\r\n\r\n <ng-template #calculatedFieldsTooltip>\r\n <div style=\"max-width: 280px;\">\r\n <strong>Calculated Fields</strong><br />\r\n <p></p>\r\n These fields are hidden from the form and cannot be edited directly.<br /><br />\r\n - They are computed automatically during workflow execution.<br />\r\n - Each field depends on one or more standard input fields.<br />\r\n - The calculation is evaluated using either an SQL query engine (like <strong>Dapper</strong>) or an in-memory expression engine (like <strong>Dynamic Expresso</strong>).<br /><br />\r\n In both cases, the result is a <code>0</code> or <code>1</code>, representing <strong>false</strong> or <strong>true</strong>.<br /><br />\r\n These results can be used to influence workflow logic, rule trees, or approval paths.\r\n </div>\r\n </ng-template>\r\n \r\n</div>", styles: ["@charset \"UTF-8\";.core-form-design-container{position:relative;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));width:100%;overflow:hidden;background-color:#eff0f1;font-size:13px}.core-form-design-container .core-button-vns-container{margin-right:8px!important}.core-form-design-container .core-button-vns-container:last-child{background-color:#000;color:#fff;margin-right:0}.core-form-design-container .af-metadata-overlay{position:fixed;top:60px;left:66px;background:#fff;box-shadow:.4rem 0 2rem #0000002e;z-index:1000;width:1214px;height:calc(100vh - 75px);overflow-y:auto;pointer-events:none}.core-form-design-container .af-metadata-overlay.shown{pointer-events:auto}.core-form-design-container *{border-radius:0}.core-form-design-container ul,.core-form-design-container li{padding:0}.core-form-design-container li{max-width:200px}.core-form-design-container ul div.space{display:block;height:15px}.core-form-design-container li.full-width{max-width:100%}.core-form-design-container .field-setting-panel{display:block;position:fixed;width:360px;height:100vh;top:0;right:-360px;background-color:#fff;box-shadow:.4rem 0 2rem #0000002e;transition:right .5s ease-out}.core-form-design-container .field-setting-panel .close-wrapper{width:32px;height:32px;position:absolute;top:15px;right:15px;display:flex;background-color:#848484;border-radius:50%}.core-form-design-container .field-setting-panel .close-wrapper i{width:16px;height:16px;font-size:18px;color:#848484}.core-form-design-container .field-setting-panel .panel-caption{margin-bottom:1rem;padding-bottom:.5rem;border-bottom:1px solid #ddd;width:100%;overflow:hidden;text-wrap:nowrap;text-overflow:ellipsis}.core-form-design-container .field-setting-panel.calculated-type{width:500px;right:-500px}.core-form-design-container .field-setting-panel.calculated-type textarea{border-radius:8px;height:150px}.core-form-design-container .field-setting-panel.open{right:0}.core-form-design-container .form-design-left{position:absolute;top:var(--size-core-page-header-height);bottom:0;left:0;z-index:1;width:360px;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px;padding-right:calc(15px + var(--size-scrollbar-width));background-color:#87ceeb;overflow-y:hidden}.core-form-design-container .form-design-left .category-name{color:#fff}.core-form-design-container .form-design-left .grid-buffer-wrapper{background-color:#fff;padding:15px}.core-form-design-container .form-design-left ul:last-child{padding-bottom:400px}.core-form-design-container .form-design-left .category-name{margin-bottom:15px}.core-form-design-container .form-design-left .json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;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;width:330px;height:calc(100vh - 205px)}.core-form-design-container .form-design-left button{height:35px;border-radius:0;margin-bottom:15px;color:#fff;border:none;font-size:13px;background-color:transparent}.core-form-design-container .form-design-left:hover{overflow-y:auto;padding-right:15px}.core-form-design-container .form-design-right{width:100%;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px 15px 15px 375px;overflow-y:auto}.core-form-design-container .form-design-right .form-wrapper{width:100%;overflow-y:visible;background-color:#fff}.core-form-design-container .form-design-right .form-wrapper button{margin-left:12px;padding:4px 10px;border:1px solid #ccc;cursor:pointer;transition:all .2s;width:110px}.core-form-design-container .form-design-right .form-wrapper button:hover{background-color:#e4f0ff;border-color:#007bff;color:#007bff}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar{display:flex;align-items:center;justify-content:flex-end}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar>button{width:150px;margin:0}.core-form-design-container .form-design-right .form-wrapper .form-cells{display:flex;flex-direction:column;gap:32px;padding:20px 15px 15px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder{padding:12px 15px;border:1px dashed #ccc;background-color:#fff;box-shadow:0 2px 6px #0000000a}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header{display:flex;position:relative;align-items:center;justify-content:flex-start;font-weight:600;margin-bottom:12px;color:#333}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img{width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center;margin-right:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);background-color:transparent;border-radius:0}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool{position:absolute;right:5px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool i{font-size:24px;color:#848484}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header:hover .section-tool{display:block}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .row-tool-bar{display:flex;align-items:center;justify-content:flex-end;margin-bottom:8px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-row{display:flex;gap:15px;margin-bottom:15px;min-height:50px;background-color:#d3d3d3;padding:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell{flex:1;min-height:90px;background-color:#fcfcfc;border:1px dashed #ccc;position:relative;padding:20px 10px 10px;transition:border .2s ease-in-out}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell:before{content:attr(data-flex);position:absolute;top:2px;left:4px;font-size:10px;color:#999}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell label.required:after{content:\" *\";color:#ff040b}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar{position:absolute;right:7px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div{display:flex;width:24px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.has-control:hover .field-toolbar{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.active-drop{border-color:#007bff;background-color:#eef6ff;transition:.2s}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .placeholder{display:flex;align-items:center;justify-content:center;background-color:#fff;color:#007bff;padding:15px 0;width:100%;cursor:default}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .placeholder.calculated{color:#ff4500}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper{width:24px;height:24px;border-radius:50%;padding:0;cursor:pointer;display:none;color:gray;border:1px solid gray;margin-left:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper:hover .icon-wrapper{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cell.selected{background-color:#dff6dd}.core-form-design-container .form-design-right .form-wrapper .merge-toolbar{text-align:center;margin-top:4px}.core-form-design-container .form-design-right .form-wrapper.live-form{padding-bottom:15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header{padding:0 15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon{position:absolute;right:7px;top:6px;z-index:2;color:gray;cursor:pointer}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon i{font-size:18px}.core-form-design-container .drop-target{min-height:50px;min-width:50px;border:2px dashed transparent;transition:border .2s ease}.core-form-design-container .drop-target.active-drop{border-color:#007bff;background-color:#eaf4ff}.core-form-design-container .no-padding{padding:0!important}.core-form-design-container .modal-content-root{overflow:visible}\n", ".core-form-container{overflow-x:visible}.core-form-container>form .section{margin-top:var(--size-layout-block-cell-spacing)}.core-form-container>form .section:not(:first-child){margin-top:calc(var(--size-layout-block-cell-spacing) * 2)}.core-form-container>form .section .section-header-label{display:block;height:34px;line-height:34px;margin-bottom:15px;margin-left:12px}.core-form-container>form .section .section-header-label .section-img-wrapper{position:relative}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img{position:absolute;width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);border-radius:0;background-color:transparent}.core-form-container>form .section .section-header-label .section-calc-wrapper{width:34px;height:34px;display:flex;align-items:center;justify-content:center;background-color:#d3d3d3;border-radius:50%}.core-form-container>form .section .section-header-label .section-calc-wrapper i{width:24px;height:24px;font-size:24px;color:#1b4332}.core-form-container>form .section .section-header-label .section-caption{padding-left:40px;font-weight:700;color:#696969}.core-form-container .row{margin-left:var(--size-layout-block-cell-spacing) 0px;margin-right:var(--size-layout-block-cell-spacing) 0px}.core-form-container .row .grid-buffer{border:dotted 2px darkgray}.core-form-container .row .button-control{display:flex;align-items:flex-end}.core-form-container .form-row{margin:var(--size-layout-block-cell-spacing) 0px;display:flex;align-items:center;justify-content:center}.core-form-container .form-row>button{cursor:pointer;border-radius:0}.core-form-container .form-row>button:not(:first-child){margin-left:var(--size-layout-block-cell-spacing)}.core-form-container .dev-button{cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;padding:8px;width:120px;border-radius:18px;box-shadow:.4rem 0 2rem #0000002e}.core-form-container .dev-button:not(:last-child){margin-right:15px}.core-form-container .dev-button:first-child{background-color:#dff6dd;border:1px #9fdc9d solid}.core-form-container .dev-button:last-child{background-color:#fff4ce;border:1px #ffda6a solid}.core-form-container .payload-preview{display:block;width:calc(100% - 48px);height:200px;white-space:pre-wrap;overflow-x:hidden;overflow-y:auto;background-color:#dff6dd;padding:24px;margin:24px;text-indent:-58px;color:#333!important;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;line-height:1.5}.core-form-container .payload-preview.validator-preview{background-color:#fff4ce}.core-form-container .bottom-template-wrapper{padding-left:12px;padding-right:12px}.core-form-container .w-100{width:100%}.core-form-container .pr18{padding-right:18px}\n", ".core-button-vns-container{height:30px;display:flex;align-items:center;justify-content:center;min-width:30px}.core-button-vns-container .action-wrapper{height:30px!important;width:30px!important;display:flex;align-items:center;justify-content:center}.core-button-vns-container .action-wrapper:has(i:hover){background-color:#e7e7e7;border-radius:50%}.core-button-vns-container .btn-for-form{border:none;border-radius:0;background-color:transparent;color:#000;min-width:120px}.core-button-vns-container button.last-child{background-color:#000;color:#fff}.core-button-vns-container .action-wrapper.last-child{background-color:var(--color-basic-orange);color:#fff;border-radius:50%}.core-button-vns-container .action-wrapper.last-child:hover{background-color:var(--color-basic-orange);box-shadow:0 1rem 3rem #0000002e}.core-button-vns-container .temporary-unavailable{user-select:none;-moz-user-select:none;-webkit-user-select:none;cursor:not-allowed!important;opacity:.5}.core-button-vns-container .temporary-unavailable:hover{background-color:transparent!important}\n"] }]
|
|
3270
|
+
], animations: [slideFromTopFadeIn], template: "<div class=\"core-form-design-container fs-13\" [hotKeys]=\"['F3', 'F6', 'Escape']\">\r\n\r\n <core-page-header title=\"UI.COMPONENT_TITLE.WORKFLOW_FORM_DESIGN\" (buttonClick)=\"onCorePageHeaderButtonClicked($event)\"></core-page-header>\r\n\r\n <ng-template #formMetadata>\r\n <form-metadata></form-metadata>\r\n </ng-template>\r\n\r\n @if (coreFormDesignService.$showFormArrayDesign()) {\r\n <core-form-array-layout-editor />\r\n }\r\n\r\n @if (!coreFormDesignService.$isInWorkflowDesign()) {\r\n <aside class=\"af-metadata-overlay\" [@slideFromTopFadeIn]=\"coreFormDesignService.$showFormMetadata() ? 'in' : 'out'\"\r\n [class.shown]=\"coreFormDesignService.$showFormMetadata()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"formMetadata\"></ng-container>\r\n </aside>\r\n }\r\n\r\n <div \r\n class=\"field-setting-panel\" \r\n [class.open]=\"coreFormDesignService.$fieldSettingPanelOpen()\" \r\n [class.calculated-type]=\"coreFormDesignService.$selectedCell()?.control?.type==='calculated'\"\r\n [ngStyle]=\"{ zIndex: $zIndex() }\"\r\n #settingPanel\r\n >\r\n @if (!!(this.coreFormDesignService.$selectedCell())) {\r\n <field-setting></field-setting>\r\n }\r\n </div>\r\n\r\n <div class=\"form-design-left\">\r\n\r\n @switch ($leftPanelMode()) {\r\n @case (enumLeftPanelMode.FieldCollection) {\r\n @for (category of controlCategories; track $index) {\r\n <div class=\"category-name\">\r\n {{ category.name }}\r\n </div>\r\n <ul>\r\n @for (control of category.controls; track $index) {\r\n <li draggable=\"true\" (dragstart)=\"onDragStart($event, control)\" [class.full-width]=\"control.controlType === 'SEEKER' || control.controlType === 'ATTACHMENT' || control.controlType === 'GRIDBUFFER'\">\r\n @if (control.controlType === 'GRIDBUFFER') {\r\n <div class=\"grid-buffer-wrapper\">\r\n <core-control [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\"></core-control>\r\n </div>\r\n } @else {\r\n <core-control [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\"></core-control>\r\n }\r\n </li>\r\n <div class=\"space\"></div>\r\n }\r\n </ul>\r\n }\r\n }\r\n @case (enumLeftPanelMode.Json) {\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"switchJson()\">{{ $jsonMode() }}</button>\r\n @if ($jsonMode()==='selectedField') {\r\n <pre class=\"json-preview\">{{ coreFormDesignService.$currentControlJson() }}</pre>\r\n } @else {\r\n <pre class=\"json-preview\">{{ coreFormDesignService.$saveLiveJson() }}</pre>\r\n }\r\n \r\n }\r\n }\r\n\r\n </div>\r\n\r\n <div class=\"form-design-right\">\r\n\r\n <core-form-group-editor [$idAsInput]=\"true\" />\r\n <!-- <pre>{{ $injectedFieldsJson() }}</pre> -->\r\n\r\n \r\n <!-- @if (coreFormDesignService.$mode() === enumType.Default) {\r\n <div class=\"form-wrapper\">\r\n\r\n @if (!!coreFormDesignService.$isInWorkflowDesign()) {\r\n <form-metadata></form-metadata>\r\n }\r\n\r\n <form [formGroup]=\"formDesign\" autocomplete=\"off\">\r\n <div class=\"form-cells\">\r\n\r\n <div class=\"form-tool-bar\">\r\n @if (!$hasCalculatedSection()) {\r\n <button class=\"core-button-vns-container\" (click)=\"addCalculatedSection()\">+ Calculated fields</button>\r\n }\r\n <button class=\"core-button-vns-container\" (click)=\"addSection()\">+ Add Section</button>\r\n </div>\r\n \r\n @for (section of coreFormDesignService.$placeholderSections(); track $index; let sectionIndex = $index) {\r\n <div class=\"form-section-placeholder\">\r\n\r\n <div class=\"section-header\">\r\n\r\n <div class=\"section-img-wrapper\">\r\n <div class=\"section-img\" [class.calculated]=\"section.forCalculatedFields\"></div>\r\n </div>\r\n\r\n <label [attr.contenteditable]=\"!section.forCalculatedFields\"\r\n [htmlTooltip]=\"!!section.forCalculatedFields ? calculatedFieldsTooltip : null\"\r\n (blur)=\"onCaptionEditEnd(sectionIndex, $event)\"\r\n (keydown.enter)=\"onCaptionEditEnd(sectionIndex, $event); $event.preventDefault()\"\r\n >{{ section.caption }}</label>\r\n\r\n <div class=\"section-tool pointer\" (click)=\"deleteSection(sectionIndex)\" [appTooltip]=\"'Delete section'\" [showAnyway]=\"true\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n \r\n </div>\r\n \r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n\r\n <div class=\"form-row-wrapper\">\r\n <div class=\"form-row\">\r\n @for (cell of filteredCells(row); track $index; let colIndex = $index) {\r\n <div class=\"form-cell drop-target\" \r\n [ngStyle]=\"{ flex: (cell.flexSize ?? 0) + ' 1 0%' }\"\r\n [attr.data-flex]=\"cell.flexSize ?? 0\"\r\n (drop)=\"onDropIntoCell($event, sectionIndex, rowIndex, colIndex)\"\r\n (dragover)=\"onDragOver($event, section, cell.control!)\"\r\n (dragenter)=\"onDragEnter(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n (dragleave)=\"onDragLeave(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n [class.selected]=\"cell?.selected\"\r\n [class.dragging-over]=\"isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]\"\r\n [class.has-control]=\"!!cell && !!cell.control && !!getControl(cell)\"\r\n (click)=\"onCellClicked(sectionIndex, rowIndex, colIndex)\"\r\n >\r\n\r\n\r\n @if (!isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]) {\r\n\r\n @if (!!cell && !!cell.control && !!getControl(cell)) {\r\n <label contenteditable=\"true\"\r\n (blur)=\"onFieldCaptionEditEnd(cell, $event)\"\r\n (keydown.enter)=\"onFieldCaptionEditEnd(cell, $event); $event.preventDefault()\"\r\n [class.d-none]=\"!!getControl(cell)?.hidden\"\r\n [class.required]=\"!!cell && !!cell.control && !!getControl(cell) && isRequired(getControl(cell))\"\r\n >{{ cell.control.label || 'label' }}</label>\r\n\r\n @if (cell.control.controlType==='CALCULATED') {\r\n <div class=\"control-wrapper\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\">\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n </div>\r\n } @else {\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n }\r\n \r\n <div class=\"field-toolbar\">\r\n <ul>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"openSettingsForCell(cell, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Show settings'\">\r\n <i class=\"feather-settings\"></i>\r\n </div>\r\n </li>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"deleteField(row, sectionIndex, rowIndex, colIndex)\" [appTooltip]=\"'Remove field from cell'\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n \r\n } @else {\r\n <div class=\"placeholder\" [class.calculated]=\"!!section.forCalculatedFields\">\r\n {{ !!section.forCalculatedFields ? 'Drop calculated field here' : 'Drop here'}}\r\n </div>\r\n }\r\n\r\n @if (cell?.selected && canMergeCells(sectionIndex, rowIndex)) {\r\n <div class=\"merge-toolbar\">\r\n <button (click)=\"mergeCells(sectionIndex, rowIndex)\">\uD83D\uDD17 Merge</button>\r\n </div>\r\n }\r\n \r\n }\r\n\r\n </div>\r\n }\r\n </div>\r\n <div class=\"row-tool-bar\">\r\n <div class=\"icon-wrapper\" (click)=\"deleteRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Delete row'\" [showAnyway]=\"true\"><i class=\"feather-x\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addRow(sectionIndex)\" [appTooltip]=\"'Add row'\" [showAnyway]=\"true\"><i class=\"feather-arrow-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"insertRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Insert row'\" [showAnyway]=\"true\"><i class=\"feather-corner-right-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addColumn(row)\" [appTooltip]=\"'Add column'\" [showAnyway]=\"true\"><i class=\"feather-arrow-right\"></i></div>\r\n </div>\r\n </div>\r\n\r\n }\r\n </div>\r\n }\r\n \r\n \r\n </div>\r\n </form>\r\n </div>\r\n } @else if (!!$sections()) {\r\n\r\n @if(!!(injectedFields$ | async) && !!(injectedFields$ | async)!.length) {\r\n\r\n @if (!!coreFormDesignService.$afInstance().normalMode) {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" />\r\n } @else {\r\n <live-form [$designMode]=\"true\" [$forKickOff]=\"true\" ($onClose)=\"closePreview()\" />\r\n }\r\n\r\n } @else {\r\n <h2>COULD NOT UPDATE injectedFields$</h2>\r\n }\r\n\r\n } @else {\r\n <h2>$sections() empty / null / undefined</h2>\r\n } -->\r\n\r\n\r\n \r\n </div>\r\n @if ($loading()) {\r\n <core-toast-loading></core-toast-loading>\r\n }\r\n\r\n <ng-template #calculatedFieldsTooltip>\r\n <div style=\"max-width: 280px;\">\r\n <strong>Calculated Fields</strong><br />\r\n <p></p>\r\n These fields are hidden from the form and cannot be edited directly.<br /><br />\r\n - They are computed automatically during workflow execution.<br />\r\n - Each field depends on one or more standard input fields.<br />\r\n - The calculation is evaluated using either an SQL query engine (like <strong>Dapper</strong>) or an in-memory expression engine (like <strong>Dynamic Expresso</strong>).<br /><br />\r\n In both cases, the result is a <code>0</code> or <code>1</code>, representing <strong>false</strong> or <strong>true</strong>.<br /><br />\r\n These results can be used to influence workflow logic, rule trees, or approval paths.\r\n </div>\r\n </ng-template>\r\n \r\n</div>", styles: ["@charset \"UTF-8\";.core-form-design-container{position:relative;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));width:100%;overflow:hidden;background-color:#eff0f1;font-size:13px}.core-form-design-container .core-button-vns-container{margin-right:8px!important}.core-form-design-container .core-button-vns-container:last-child{background-color:#000;color:#fff;margin-right:0}.core-form-design-container .af-metadata-overlay{position:fixed;top:60px;left:66px;background:#fff;box-shadow:.4rem 0 2rem #0000002e;z-index:1000;width:1214px;height:calc(100vh - 75px);overflow-y:auto;pointer-events:none}.core-form-design-container .af-metadata-overlay.shown{pointer-events:auto}.core-form-design-container *{border-radius:0}.core-form-design-container ul,.core-form-design-container li{padding:0}.core-form-design-container li{max-width:200px}.core-form-design-container ul div.space{display:block;height:15px}.core-form-design-container li.full-width{max-width:100%}.core-form-design-container .field-setting-panel{display:block;position:fixed;width:360px;height:100vh;top:0;right:-360px;background-color:#fff;box-shadow:.4rem 0 2rem #0000002e;transition:right .5s ease-out}.core-form-design-container .field-setting-panel .close-wrapper{width:32px;height:32px;position:absolute;top:15px;right:15px;display:flex;background-color:#848484;border-radius:50%}.core-form-design-container .field-setting-panel .close-wrapper i{width:16px;height:16px;font-size:18px;color:#848484}.core-form-design-container .field-setting-panel .panel-caption{margin-bottom:1rem;padding-bottom:.5rem;border-bottom:1px solid #ddd;width:100%;overflow:hidden;text-wrap:nowrap;text-overflow:ellipsis}.core-form-design-container .field-setting-panel.calculated-type{width:500px;right:-500px}.core-form-design-container .field-setting-panel.calculated-type textarea{border-radius:8px;height:150px}.core-form-design-container .field-setting-panel.open{right:0}.core-form-design-container .form-design-left{position:absolute;top:var(--size-core-page-header-height);bottom:0;left:0;z-index:1;width:360px;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px;padding-right:calc(15px + var(--size-scrollbar-width));background-color:#87ceeb;overflow-y:hidden}.core-form-design-container .form-design-left .category-name{color:#fff}.core-form-design-container .form-design-left .grid-buffer-wrapper{background-color:#fff;padding:15px}.core-form-design-container .form-design-left ul:last-child{padding-bottom:400px}.core-form-design-container .form-design-left .category-name{margin-bottom:15px}.core-form-design-container .form-design-left .json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;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;width:330px;height:calc(100vh - 205px)}.core-form-design-container .form-design-left button{height:35px;border-radius:0;margin-bottom:15px;color:#fff;border:none;font-size:13px;background-color:transparent}.core-form-design-container .form-design-left:hover{overflow-y:auto;padding-right:15px}.core-form-design-container .form-design-right{width:100%;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px 15px 15px 375px;overflow-y:auto}.core-form-design-container .form-design-right .form-wrapper{width:100%;overflow-y:visible;background-color:#fff}.core-form-design-container .form-design-right .form-wrapper button{margin-left:12px;padding:4px 10px;border:1px solid #ccc;cursor:pointer;transition:all .2s;width:110px}.core-form-design-container .form-design-right .form-wrapper button:hover{background-color:#e4f0ff;border-color:#007bff;color:#007bff}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar{display:flex;align-items:center;justify-content:flex-end}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar>button{width:150px;margin:0}.core-form-design-container .form-design-right .form-wrapper .form-cells{display:flex;flex-direction:column;gap:32px;padding:20px 15px 15px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder{padding:12px 15px;border:1px dashed #ccc;background-color:#fff;box-shadow:0 2px 6px #0000000a}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header{display:flex;position:relative;align-items:center;justify-content:flex-start;font-weight:600;margin-bottom:12px;color:#333}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img{width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center;margin-right:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);background-color:transparent;border-radius:0}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool{position:absolute;right:5px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool i{font-size:24px;color:#848484}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header:hover .section-tool{display:block}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .row-tool-bar{display:flex;align-items:center;justify-content:flex-end;margin-bottom:8px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-row{display:flex;gap:15px;margin-bottom:15px;min-height:50px;background-color:#d3d3d3;padding:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell{flex:1;min-height:90px;background-color:#fcfcfc;border:1px dashed #ccc;position:relative;padding:20px 10px 10px;transition:border .2s ease-in-out}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell:before{content:attr(data-flex);position:absolute;top:2px;left:4px;font-size:10px;color:#999}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell label.required:after{content:\" *\";color:#ff040b}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar{position:absolute;right:7px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div{display:flex;width:24px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.has-control:hover .field-toolbar{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.active-drop{border-color:#007bff;background-color:#eef6ff;transition:.2s}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .placeholder{display:flex;align-items:center;justify-content:center;background-color:#fff;color:#007bff;padding:15px 0;width:100%;cursor:default}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .placeholder.calculated{color:#ff4500}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper{width:24px;height:24px;border-radius:50%;padding:0;cursor:pointer;display:none;color:gray;border:1px solid gray;margin-left:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper:hover .icon-wrapper{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cell.selected{background-color:#dff6dd}.core-form-design-container .form-design-right .form-wrapper .merge-toolbar{text-align:center;margin-top:4px}.core-form-design-container .form-design-right .form-wrapper.live-form{padding-bottom:15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header{padding:0 15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon{position:absolute;right:7px;top:6px;z-index:2;color:gray;cursor:pointer}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon i{font-size:18px}.core-form-design-container .drop-target{min-height:50px;min-width:50px;border:2px dashed transparent;transition:border .2s ease}.core-form-design-container .drop-target.active-drop{border-color:#007bff;background-color:#eaf4ff}.core-form-design-container .no-padding{padding:0!important}.core-form-design-container .modal-content-root{overflow:visible}\n", ".core-form-container{overflow-x:visible}.core-form-container>form .section{margin-top:var(--size-layout-block-cell-spacing)}.core-form-container>form .section:not(:first-child){margin-top:calc(var(--size-layout-block-cell-spacing) * 2)}.core-form-container>form .section .section-header-label{display:block;height:34px;line-height:34px;margin-bottom:15px;margin-left:12px}.core-form-container>form .section .section-header-label .section-img-wrapper{position:relative}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img{position:absolute;width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img.calculated{background-image:url(/assets/images/sql-icon.svg);border-radius:0;background-color:transparent}.core-form-container>form .section .section-header-label .section-calc-wrapper{width:34px;height:34px;display:flex;align-items:center;justify-content:center;background-color:#d3d3d3;border-radius:50%}.core-form-container>form .section .section-header-label .section-calc-wrapper i{width:24px;height:24px;font-size:24px;color:#1b4332}.core-form-container>form .section .section-header-label .section-caption{padding-left:40px;font-weight:700;color:#696969}.core-form-container .row{margin-left:var(--size-layout-block-cell-spacing) 0px;margin-right:var(--size-layout-block-cell-spacing) 0px}.core-form-container .row .grid-buffer{border:dotted 2px darkgray}.core-form-container .row .button-control{display:flex;align-items:flex-end}.core-form-container .form-row{margin:var(--size-layout-block-cell-spacing) 0px;display:flex;align-items:center;justify-content:center}.core-form-container .form-row>button{cursor:pointer;border-radius:0}.core-form-container .form-row>button:not(:first-child){margin-left:var(--size-layout-block-cell-spacing)}.core-form-container .dev-button{cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;padding:8px;width:120px;border-radius:18px;box-shadow:.4rem 0 2rem #0000002e}.core-form-container .dev-button:not(:last-child){margin-right:15px}.core-form-container .dev-button:first-child{background-color:#dff6dd;border:1px #9fdc9d solid}.core-form-container .dev-button:last-child{background-color:#fff4ce;border:1px #ffda6a solid}.core-form-container .payload-preview{display:block;width:calc(100% - 48px);height:200px;white-space:pre-wrap;overflow-x:hidden;overflow-y:auto;background-color:#dff6dd;padding:24px;margin:24px;text-indent:-58px;color:#333!important;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;line-height:1.5}.core-form-container .payload-preview.validator-preview{background-color:#fff4ce}.core-form-container .bottom-template-wrapper{padding-left:12px;padding-right:12px}.core-form-container .w-100{width:100%}.core-form-container .pr18{padding-right:18px}\n", ".core-button-vns-container{height:30px;display:flex;align-items:center;justify-content:center;min-width:30px}.core-button-vns-container .action-wrapper{height:30px!important;width:30px!important;display:flex;align-items:center;justify-content:center}.core-button-vns-container .action-wrapper:has(i:hover){background-color:#e7e7e7;border-radius:50%}.core-button-vns-container .btn-for-form{border:none;border-radius:0;background-color:transparent;color:#000;min-width:120px}.core-button-vns-container button.last-child{background-color:#000;color:#fff}.core-button-vns-container .action-wrapper.last-child{background-color:var(--color-basic-orange);color:#fff;border-radius:50%}.core-button-vns-container .action-wrapper.last-child:hover{background-color:var(--color-basic-orange);box-shadow:0 1rem 3rem #0000002e}.core-button-vns-container .temporary-unavailable{user-select:none;-moz-user-select:none;-webkit-user-select:none;cursor:not-allowed!important;opacity:.5}.core-button-vns-container .temporary-unavailable:hover{background-color:transparent!important}\n"] }]
|
|
2429
3271
|
}], ctorParameters: () => [{ type: MultiLanguageService }] });
|
|
2430
3272
|
|
|
2431
3273
|
var coreFormDesign_component = /*#__PURE__*/Object.freeze({
|
|
@@ -2434,4 +3276,4 @@ var coreFormDesign_component = /*#__PURE__*/Object.freeze({
|
|
|
2434
3276
|
});
|
|
2435
3277
|
|
|
2436
3278
|
export { BasePropsComponent as B, CoreFormDesignComponent as C, coreFormDesign_component as c };
|
|
2437
|
-
//# sourceMappingURL=ngx-histaff-alpha-core-form-design.component-
|
|
3279
|
+
//# sourceMappingURL=ngx-histaff-alpha-core-form-design.component-CGf-jOqR.mjs.map
|