@a.nemreen/dga-dynamic-form 0.1.5 → 0.1.7
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/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Version **0.1.1** — API may move until freeze.
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install @a.nemreen/dga-dynamic-form @a.nemreen/dga-ui @a.nemreen/dga-tokens
|
|
10
|
+
npm install @a.nemreen/dga-dynamic-form @a.nemreen/dga-ui @a.nemreen/dga-tokens
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
**Peers:** `@angular/core` / `common` / `forms` ^19–22, `@a.nemreen/dga-ui` ^0.2, `@a.nemreen/dga-tokens` ^0.2.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectable as q,input as p,booleanAttribute as Se,output as S,DestroyRef as B,signal as C,computed as c,ChangeDetectionStrategy as _,Component as z,effect as G,untracked as Ce,makeEnvironmentProviders as Ie}from"@angular/core";import{NgComponentOutlet as $}from"@angular/common";import*as m from"@angular/forms";import{Validators as f,ReactiveFormsModule as k,FormsModule as j,FormBuilder as ke}from"@angular/forms";import{switchMap as U,catchError as De,startWith as Oe,map as Le}from"rxjs/operators";import{DgaField as H,DgaInput as W,DgaSelect as K,DgaCheckbox as Y,DgaRadio as J,DgaPhoneInput as X,DgaDatePicker as Z,DgaChipInput as Q,DgaSwitch as ee,DgaUpload as te,DgaNumberInput as oe,DgaOtp as re,DgaButton as ae,DgaStepper as ne,DgaToastService as Te}from"@a.nemreen/dga-ui";import{of as b,throwError as ie}from"rxjs";import{takeUntilDestroyed as we}from"@angular/core/rxjs-interop";import{HttpClient as D,HttpHeaders as Ae}from"@angular/common/http";const O=new h("DGA_LOOKUP_ADAPTER"),L=new h("DGA_SUBMIT_ADAPTER"),T=new h("DGA_FORM_TOAST_ADAPTER"),w=new h("DGA_CAPTCHA_ADAPTER"),A=new h("DGA_FORM_I18N_ADAPTER"),le=new h("DGA_DYNAMIC_FORM_FIELD_REGISTRY"),se=["checkbox","multiselect","chips","file"],Fe=["toggle"];function de(r){return r.value!==void 0?r.value:se.includes(r.type)?[]:Fe.includes(r.type)?!1:""}function F(r,e){const t=[],o=r.validation;(e||r.required||o?.required)&&(se.includes(r.type)?t.push(Ne):r.type==="toggle"?t.push(f.requiredTrue):t.push(f.required)),(r.type==="email"||o?.pattern==="email")&&t.push(f.email);const a=o?.minLength;a!=null&&t.push(f.minLength(a));const n=o?.maxLength??r.maxLength;if(n!=null&&t.push(f.maxLength(n)),o?.pattern&&o.pattern!=="email")try{t.push(f.pattern(o.pattern))}catch{}return o?.min!=null&&t.push(f.min(o.min)),o?.max!=null&&t.push(f.max(o.max)),r.maxChips!=null&&r.type==="chips"&&t.push(Me(r.maxChips)),t}function Ne(r){const e=r.value;return Array.isArray(e)&&e.length>0?null:{required:!0}}function Me(r){return e=>{const t=e.value;return Array.isArray(t)&&t.length>r?{maxChips:{max:r,actual:t.length}}:null}}function ce(r,e,t=!0){const o=!!e.disabled;return r.control({value:de(e),disabled:o},{validators:F(e,t&&!e.requiredWhen)})}function ue(r,e){const t={};for(const o of e){if(o.hidden&&o.type==="hidden"){t[o.name]=r.control(o.value??"");continue}t[o.name]=ce(r,o)}return r.group(t)}function pe(r,e){return e?.length?e.flatMap(t=>t.fields):r}function me(r,e,t){r.setValidators(F(e,t)),r.updateValueAndValidity({emitEvent:!1})}function N(r,e){return Array.isArray(r)?r.some(t=>t==e):r==e}function M(r,e,t){return r?[...t??[],...r.options??[],...r.groupedOptions?.flatMap(a=>a.options)??[]].find(a=>a.value==e):void 0}function V(r,e,t){if(r.hidden&&r.type!=="hidden"||r.type==="hidden")return!1;if(!r.dependsOn)return!0;const o=e[r.dependsOn];if(r.showOnValues?.length&&!r.showOnValues.some(a=>N(o,a)))return!1;if(r.showWhenOptionProperty){const a=t?.(r.dependsOn),n=M({name:r.dependsOn,type:"select",label:{en:"",ar:""}},o,a),i=r.showWhenOptionProperty.property;if(!n||n[i]!==r.showWhenOptionProperty.value)return!1}return!(!r.showOnValues?.length&&!r.showWhenOptionProperty&&(o==null||o===""||Array.isArray(o)&&o.length===0))}function R(r,e,t){const o=r.requiredWhen;if(!o)return!!r.required;const a=e[o.field];if(o.optionProperty!=null){const n=t?.(o.field),i=M({name:o.field,type:"select",label:{en:"",ar:""}},a,n);return!!i&&i[o.optionProperty]===o.optionPropertyValue}return o.values?.length?o.values.some(n=>N(a,n)):o.value!==void 0?N(a,o.value):a!=null&&a!==""}class y{submitAdapter=s(L,{optional:!0});captcha=s(w,{optional:!0});buildPayload(e,t,o){const a=new Set(o.filter(i=>i.excludeFromPayload).map(i=>i.name));let n={};for(const[i,d]of Object.entries(t)){if(a.has(i))continue;const u=e.fieldMapping?.[i]??i;n[u]=d}return e.payloadTransformer?e.payloadTransformer(n):n}hasFileValues(e){return Object.values(e).some(t=>t instanceof File||Array.isArray(t)&&t.some(o=>o instanceof File||o?.file instanceof File))}toFormData(e){const t=new FormData;for(const[o,a]of Object.entries(e))if(a!=null)if(a instanceof File)t.append(o,a);else if(Array.isArray(a))for(const n of a)n instanceof File?t.append(o,n):n?.file instanceof File?t.append(o,n.file,n.name):t.append(o,typeof n=="string"?n:JSON.stringify(n));else typeof a=="object"?t.append(o,JSON.stringify(a)):t.append(o,String(a));return t}submitForm(e,t,o){if(!e.endpoint||!this.submitAdapter)return b(t);const a=this.buildPayload(e,t,o),n=a instanceof FormData?a:this.hasFileValues(a)?this.toFormData(a):a,i={};return e.idempotencyKey&&(i["Idempotency-Key"]=e.idempotencyKey),(this.captcha?.getToken("submit")??b(null)).pipe(U(u=>(u&&(i["X-Recaptcha-Token"]=u),b({endpoint:e.endpoint,method:e.method??"POST",body:n,headers:i})))).pipe(U(u=>this.submitAdapter.submit(u)),De(u=>{throw u}))}saveDraft(e,t){typeof localStorage>"u"||localStorage.setItem(this.storageKey(e),JSON.stringify(t))}loadDraft(e){if(typeof localStorage>"u")return null;const t=localStorage.getItem(this.storageKey(e));if(!t)return null;try{return JSON.parse(t)}catch{return null}}clearDraft(e){typeof localStorage>"u"||localStorage.removeItem(this.storageKey(e))}storageKey(e){return`dga-dynamic-form:${e}`}static \u0275fac=l.\u0275\u0275ngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:y,deps:[],target:l.\u0275\u0275FactoryTarget.Injectable});static \u0275prov=l.\u0275\u0275ngDeclareInjectable({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:y,providedIn:"root"})}l.\u0275\u0275ngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:y,decorators:[{type:q,args:[{providedIn:"root"}]}]});function v(r,e,t=""){return r?e==="en"?r.en||r.ar:r.ar||r.en:t}function fe(){return typeof document>"u"?"ar":(document.documentElement.lang||"ar").toLowerCase().startsWith("en")?"en":"ar"}class x{extras=s(le,{optional:!0});map=new Map;constructor(){for(const e of this.extras??[])this.register(e)}register(e){this.map.set(e.type,e.component)}get(e){return this.map.get(e)??null}hasCustom(e){return this.map.has(e)}isBuiltIn(e){return Ve.has(e)}static \u0275fac=l.\u0275\u0275ngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:x,deps:[],target:l.\u0275\u0275FactoryTarget.Injectable});static \u0275prov=l.\u0275\u0275ngDeclareInjectable({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:x,providedIn:"root"})}l.\u0275\u0275ngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:x,decorators:[{type:q,args:[{providedIn:"root"}]}],ctorParameters:()=>[]});const Ve=new Set(["text","email","textarea","select","multiselect","checkbox","radio","phone","file","date","chips","toggle","hidden","number","otp"]);class g{field=p.required(...ngDevMode?[{debugName:"field"}]:[]);form=p.required(...ngDevMode?[{debugName:"form"}]:[]);locale=p("ar",...ngDevMode?[{debugName:"locale"}]:[]);required=p(!1,{...ngDevMode?{debugName:"required"}:{},transform:Se});error=p("",...ngDevMode?[{debugName:"error"}]:[]);runtimeOptions=p([],...ngDevMode?[{debugName:"runtimeOptions"}]:[]);optionsLoaded=S();lookup=s(O,{optional:!0});destroyRef=s(B);loadedOptions=C([],...ngDevMode?[{debugName:"loadedOptions"}]:[]);controlId=`dga-df-${Math.random().toString(36).slice(2,9)}`;get control(){return this.form().controls[this.field().name]}labelText=c(()=>v(this.field().label,this.locale()),...ngDevMode?[{debugName:"labelText"}]:[]);hintText=c(()=>v(this.field().hint,this.locale()),...ngDevMode?[{debugName:"hintText"}]:[]);placeholderText=c(()=>v(this.field().placeholder,this.locale()),...ngDevMode?[{debugName:"placeholderText"}]:[]);resolvedOptions=c(()=>{const e=this.runtimeOptions();if(e.length)return e;const t=this.loadedOptions();return t.length?t:this.field().options??[]},...ngDevMode?[{debugName:"resolvedOptions"}]:[]);selectOptions=c(()=>this.resolvedOptions().map(e=>({value:String(e.value),label:this.optionLabel(e),disabled:!!e.disabled})),...ngDevMode?[{debugName:"selectOptions"}]:[]);ngOnInit(){const e=this.field();if(e.lookupDomain&&e.lookupName&&this.lookup&&!e.searchLookup){const t=e.useParentId&&e.dependsOn?this.form().get(e.dependsOn)?.value:void 0;this.lookup.lookup({domain:e.lookupDomain,name:e.lookupName,parentId:t??void 0}).pipe(we(this.destroyRef)).subscribe(o=>{const a=this.applyLookupFilter(o);this.loadedOptions.set(a),this.optionsLoaded.emit({name:e.name,options:a})})}}optionLabel(e){return v(e.label,this.locale())}isChecked(e){const t=this.control?.value;return Array.isArray(t)&&t.some(o=>o==e)}toggleCheckbox(e,t){const o=Array.isArray(this.control.value)?[...this.control.value]:[],a=t?o.some(n=>n==e)?o:[...o,e]:o.filter(n=>n!=e);this.control.setValue(a),this.control.markAsDirty()}onSelectSearch(e){const t=this.field();!t.searchLookup||!this.lookup||!t.lookupDomain||t.lookupName}onRestrict(e){const t=this.field().inputRestriction;if(!t)return;const o=e.target;let a=o.value;t==="numbers"&&(a=a.replace(/\D+/g,"")),t==="english"&&(a=a.replace(/[^a-zA-Z0-9\s.,\-_/]/g,"")),t==="arabic"&&(a=a.replace(/[^\u0600-\u06FF0-9\s.,\-_/]/g,"")),a!==o.value&&(o.value=a,this.control.setValue(a))}applyLookupFilter(e){const t=this.field().lookupFilter;return t?e.filter(o=>o[t.property]===t.value):e}static \u0275fac=l.\u0275\u0275ngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:g,deps:[],target:l.\u0275\u0275FactoryTarget.Component});static \u0275cmp=l.\u0275\u0275ngDeclareComponent({minVersion:"17.0.0",version:"22.0.7",type:g,isStandalone:!0,selector:"dga-dynamic-form-field",inputs:{field:{classPropertyName:"field",publicName:"field",isSignal:!0,isRequired:!0,transformFunction:null},form:{classPropertyName:"form",publicName:"form",isSignal:!0,isRequired:!0,transformFunction:null},locale:{classPropertyName:"locale",publicName:"locale",isSignal:!0,isRequired:!1,transformFunction:null},required:{classPropertyName:"required",publicName:"required",isSignal:!0,isRequired:!1,transformFunction:null},error:{classPropertyName:"error",publicName:"error",isSignal:!0,isRequired:!1,transformFunction:null},runtimeOptions:{classPropertyName:"runtimeOptions",publicName:"runtimeOptions",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{optionsLoaded:"optionsLoaded"},host:{properties:{"class.hidden":'field().type === "hidden"'},classAttribute:"block w-full"},ngImport:l,template:`
|
|
1
|
+
import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectable as P,input as p,booleanAttribute as Ce,output as S,DestroyRef as B,signal as C,computed as u,ChangeDetectionStrategy as _,Component as z,effect as G,untracked as Ie,isDevMode as ke,makeEnvironmentProviders as De}from"@angular/core";import{NgComponentOutlet as $}from"@angular/common";import*as m from"@angular/forms";import{Validators as f,ReactiveFormsModule as k,FormsModule as j,FormBuilder as Oe}from"@angular/forms";import{switchMap as U,catchError as we,startWith as Te,map as Le}from"rxjs/operators";import{DgaField as H,DgaInput as K,DgaSelect as W,DgaCheckbox as Y,DgaRadio as J,DgaPhoneInput as X,DgaChipInput as Z,DgaSwitch as Q,DgaUpload as ee,DgaNumberInput as te,DgaOtp as oe,DgaButton as re,DgaStepper as ae,DgaToastService as Ae}from"@a.nemreen/dga-ui";import{of as b,throwError as ne}from"rxjs";import{takeUntilDestroyed as Fe}from"@angular/core/rxjs-interop";import{DgaDatePicker as ie}from"@a.nemreen/dga-ui/date-picker";import{HttpClient as D,HttpHeaders as Ne}from"@angular/common/http";const O=new h("DGA_LOOKUP_ADAPTER"),w=new h("DGA_SUBMIT_ADAPTER"),T=new h("DGA_FORM_TOAST_ADAPTER"),L=new h("DGA_CAPTCHA_ADAPTER"),A=new h("DGA_FORM_I18N_ADAPTER"),le=new h("DGA_DYNAMIC_FORM_FIELD_REGISTRY"),se=["checkbox","multiselect","chips","file"],Me=["toggle"];function de(r){return r.value!==void 0?r.value:se.includes(r.type)?[]:Me.includes(r.type)?!1:""}function F(r,e){const t=[],o=r.validation;(e||r.required||o?.required)&&(se.includes(r.type)?t.push(Ve):r.type==="toggle"?t.push(f.requiredTrue):t.push(f.required)),(r.type==="email"||o?.pattern==="email")&&t.push(f.email);const a=o?.minLength;a!=null&&t.push(f.minLength(a));const n=o?.maxLength??r.maxLength;if(n!=null&&t.push(f.maxLength(n)),o?.pattern&&o.pattern!=="email"){const i=o.pattern;if(typeof i=="string"&&i.length>0&&i.length<=200)try{t.push(f.pattern(i))}catch{}}return o?.min!=null&&t.push(f.min(o.min)),o?.max!=null&&t.push(f.max(o.max)),r.maxChips!=null&&r.type==="chips"&&t.push(Re(r.maxChips)),t}function Ve(r){const e=r.value;return Array.isArray(e)&&e.length>0?null:{required:!0}}function Re(r){return e=>{const t=e.value;return Array.isArray(t)&&t.length>r?{maxChips:{max:r,actual:t.length}}:null}}function ce(r,e,t=!0){const o=!!e.disabled;return r.control({value:de(e),disabled:o},{validators:F(e,t&&!e.requiredWhen)})}function ue(r,e){const t={};for(const o of e){if(o.hidden&&o.type==="hidden"){t[o.name]=r.control(o.value??"");continue}t[o.name]=ce(r,o)}return r.group(t)}function pe(r,e){return e?.length?e.flatMap(t=>t.fields):r}function me(r,e,t){r.setValidators(F(e,t)),r.updateValueAndValidity({emitEvent:!1})}function N(r,e){return Array.isArray(r)?r.some(t=>t==e):r==e}function M(r,e,t){return r?[...t??[],...r.options??[],...r.groupedOptions?.flatMap(a=>a.options)??[]].find(a=>a.value==e):void 0}function V(r,e,t){if(r.hidden&&r.type!=="hidden"||r.type==="hidden")return!1;if(!r.dependsOn)return!0;const o=e[r.dependsOn];if(r.showOnValues?.length&&!r.showOnValues.some(a=>N(o,a)))return!1;if(r.showWhenOptionProperty){const a=t?.(r.dependsOn),n=M({name:r.dependsOn,type:"select",label:{en:"",ar:""}},o,a),i=r.showWhenOptionProperty.property;if(!n||n[i]!==r.showWhenOptionProperty.value)return!1}return!(!r.showOnValues?.length&&!r.showWhenOptionProperty&&(o==null||o===""||Array.isArray(o)&&o.length===0))}function R(r,e,t){const o=r.requiredWhen;if(!o)return!!r.required;const a=e[o.field];if(o.optionProperty!=null){const n=t?.(o.field),i=M({name:o.field,type:"select",label:{en:"",ar:""}},a,n);return!!i&&i[o.optionProperty]===o.optionPropertyValue}return o.values?.length?o.values.some(n=>N(a,n)):o.value!==void 0?N(a,o.value):a!=null&&a!==""}const Ee=new Set(["otp","file"]),fe=/password|passwd|secret|token|otp|national.?id|ssn|pin$/i;class y{submitAdapter=s(w,{optional:!0});captcha=s(L,{optional:!0});buildPayload(e,t,o){const a=new Set(o.filter(i=>i.excludeFromPayload).map(i=>i.name));let n={};for(const[i,d]of Object.entries(t)){if(a.has(i))continue;const c=e.fieldMapping?.[i]??i;n[c]=d}return e.payloadTransformer?e.payloadTransformer(n):n}hasFileValues(e){return Object.values(e).some(t=>t instanceof File||Array.isArray(t)&&t.some(o=>o instanceof File||o?.file instanceof File))}toFormData(e){const t=new FormData;for(const[o,a]of Object.entries(e))if(a!=null)if(a instanceof File)t.append(o,a);else if(Array.isArray(a))for(const n of a)n instanceof File?t.append(o,n):n?.file instanceof File?t.append(o,n.file,n.name):t.append(o,typeof n=="string"?n:JSON.stringify(n));else typeof a=="object"?t.append(o,JSON.stringify(a)):t.append(o,String(a));return t}submitForm(e,t,o){if(!e.endpoint||!this.submitAdapter)return b(t);const a=this.buildPayload(e,t,o),n=a instanceof FormData?a:this.hasFileValues(a)?this.toFormData(a):a,i={};return e.idempotencyKey&&(i["Idempotency-Key"]=e.idempotencyKey),(this.captcha?.getToken("submit")??b(null)).pipe(U(c=>(c&&(i["X-Recaptcha-Token"]=c),b({endpoint:e.endpoint,method:e.method??"POST",body:n,headers:i})))).pipe(U(c=>this.submitAdapter.submit(c)),we(c=>{throw c}))}saveDraft(e,t,o=[]){if(typeof localStorage>"u")return;const a=new Map(o.map(i=>[i.name,i])),n={};for(const[i,d]of Object.entries(t)){const c=a.get(i);c&&this.isDraftBlocked(c)||!c&&fe.test(i)||d instanceof File||(n[i]=d)}localStorage.setItem(this.storageKey(e),JSON.stringify(n))}loadDraft(e){if(typeof localStorage>"u")return null;const t=localStorage.getItem(this.storageKey(e));if(!t)return null;try{return JSON.parse(t)}catch{return null}}clearDraft(e){typeof localStorage>"u"||localStorage.removeItem(this.storageKey(e))}isDraftBlocked(e){return e.excludeFromDraft||e.sensitive||e.excludeFromPayload||Ee.has(e.type)?!0:fe.test(e.name)}storageKey(e){return`dga-dynamic-form:${e}`}static \u0275fac=l.\u0275\u0275ngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:y,deps:[],target:l.\u0275\u0275FactoryTarget.Injectable});static \u0275prov=l.\u0275\u0275ngDeclareInjectable({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:y,providedIn:"root"})}l.\u0275\u0275ngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:y,decorators:[{type:P,args:[{providedIn:"root"}]}]});function v(r,e,t=""){return r?e==="en"?r.en||r.ar:r.ar||r.en:t}function ge(){return typeof document>"u"?"ar":(document.documentElement.lang||"ar").toLowerCase().startsWith("en")?"en":"ar"}class x{extras=s(le,{optional:!0});map=new Map;constructor(){for(const e of this.extras??[])this.register(e)}register(e){this.map.set(e.type,e.component)}get(e){return this.map.get(e)??null}hasCustom(e){return this.map.has(e)}isBuiltIn(e){return qe.has(e)}static \u0275fac=l.\u0275\u0275ngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:x,deps:[],target:l.\u0275\u0275FactoryTarget.Injectable});static \u0275prov=l.\u0275\u0275ngDeclareInjectable({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:x,providedIn:"root"})}l.\u0275\u0275ngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:x,decorators:[{type:P,args:[{providedIn:"root"}]}],ctorParameters:()=>[]});const qe=new Set(["text","email","textarea","select","multiselect","checkbox","radio","phone","file","date","chips","toggle","hidden","number","otp"]);class g{field=p.required(...ngDevMode?[{debugName:"field"}]:[]);form=p.required(...ngDevMode?[{debugName:"form"}]:[]);locale=p("ar",...ngDevMode?[{debugName:"locale"}]:[]);required=p(!1,{...ngDevMode?{debugName:"required"}:{},transform:Ce});error=p("",...ngDevMode?[{debugName:"error"}]:[]);runtimeOptions=p([],...ngDevMode?[{debugName:"runtimeOptions"}]:[]);optionsLoaded=S();lookup=s(O,{optional:!0});destroyRef=s(B);loadedOptions=C([],...ngDevMode?[{debugName:"loadedOptions"}]:[]);controlId=`dga-df-${Math.random().toString(36).slice(2,9)}`;get control(){return this.form().controls[this.field().name]}labelText=u(()=>v(this.field().label,this.locale()),...ngDevMode?[{debugName:"labelText"}]:[]);hintText=u(()=>v(this.field().hint,this.locale()),...ngDevMode?[{debugName:"hintText"}]:[]);placeholderText=u(()=>v(this.field().placeholder,this.locale()),...ngDevMode?[{debugName:"placeholderText"}]:[]);resolvedOptions=u(()=>{const e=this.runtimeOptions();if(e.length)return e;const t=this.loadedOptions();return t.length?t:this.field().options??[]},...ngDevMode?[{debugName:"resolvedOptions"}]:[]);selectOptions=u(()=>this.resolvedOptions().map(e=>({value:String(e.value),label:this.optionLabel(e),disabled:!!e.disabled})),...ngDevMode?[{debugName:"selectOptions"}]:[]);ngOnInit(){const e=this.field();if(e.lookupDomain&&e.lookupName&&this.lookup&&!e.searchLookup){const t=e.useParentId&&e.dependsOn?this.form().get(e.dependsOn)?.value:void 0;this.lookup.lookup({domain:e.lookupDomain,name:e.lookupName,parentId:t??void 0}).pipe(Fe(this.destroyRef)).subscribe(o=>{const a=this.applyLookupFilter(o);this.loadedOptions.set(a),this.optionsLoaded.emit({name:e.name,options:a})})}}optionLabel(e){return v(e.label,this.locale())}isChecked(e){const t=this.control?.value;return Array.isArray(t)&&t.some(o=>o==e)}toggleCheckbox(e,t){const o=Array.isArray(this.control.value)?[...this.control.value]:[],a=t?o.some(n=>n==e)?o:[...o,e]:o.filter(n=>n!=e);this.control.setValue(a),this.control.markAsDirty()}onSelectSearch(e){const t=this.field();!t.searchLookup||!this.lookup||!t.lookupDomain||t.lookupName}onRestrict(e){const t=this.field().inputRestriction;if(!t)return;const o=e.target;let a=o.value;t==="numbers"&&(a=a.replace(/\D+/g,"")),t==="english"&&(a=a.replace(/[^a-zA-Z0-9\s.,\-_/]/g,"")),t==="arabic"&&(a=a.replace(/[^\u0600-\u06FF0-9\s.,\-_/]/g,"")),a!==o.value&&(o.value=a,this.control.setValue(a))}applyLookupFilter(e){const t=this.field().lookupFilter;return t?e.filter(o=>o[t.property]===t.value):e}static \u0275fac=l.\u0275\u0275ngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:g,deps:[],target:l.\u0275\u0275FactoryTarget.Component});static \u0275cmp=l.\u0275\u0275ngDeclareComponent({minVersion:"17.0.0",version:"22.0.7",type:g,isStandalone:!0,selector:"dga-dynamic-form-field",inputs:{field:{classPropertyName:"field",publicName:"field",isSignal:!0,isRequired:!0,transformFunction:null},form:{classPropertyName:"form",publicName:"form",isSignal:!0,isRequired:!0,transformFunction:null},locale:{classPropertyName:"locale",publicName:"locale",isSignal:!0,isRequired:!1,transformFunction:null},required:{classPropertyName:"required",publicName:"required",isSignal:!0,isRequired:!1,transformFunction:null},error:{classPropertyName:"error",publicName:"error",isSignal:!0,isRequired:!1,transformFunction:null},runtimeOptions:{classPropertyName:"runtimeOptions",publicName:"runtimeOptions",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{optionsLoaded:"optionsLoaded"},host:{properties:{"class.hidden":'field().type === "hidden"'},classAttribute:"block w-full"},ngImport:l,template:`
|
|
2
2
|
@if (field().type !== 'hidden') {
|
|
3
3
|
<dga-field
|
|
4
4
|
[label]="labelText()"
|
|
@@ -173,7 +173,7 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
|
|
|
173
173
|
}
|
|
174
174
|
</dga-field>
|
|
175
175
|
}
|
|
176
|
-
`,isInline:!0,dependencies:[{kind:"ngmodule",type:k},{kind:"directive",type:m.DefaultValueAccessor,selector:"input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]"},{kind:"directive",type:m.RadioControlValueAccessor,selector:"input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]",inputs:["name","formControlName","value"]},{kind:"directive",type:m.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:m.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:m.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"ngmodule",type:j},{kind:"component",type:H,selector:"dga-field",inputs:["label","labelHint","hint","error","status","statusMessage","controlId","required"]},{kind:"directive",type:
|
|
176
|
+
`,isInline:!0,dependencies:[{kind:"ngmodule",type:k},{kind:"directive",type:m.DefaultValueAccessor,selector:"input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]"},{kind:"directive",type:m.RadioControlValueAccessor,selector:"input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]",inputs:["name","formControlName","value"]},{kind:"directive",type:m.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:m.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:m.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"ngmodule",type:j},{kind:"component",type:H,selector:"dga-field",inputs:["label","labelHint","hint","error","status","statusMessage","controlId","required"]},{kind:"directive",type:K,selector:"input[dgaInput], textarea[dgaInput]",inputs:["size","dgaInvalid","status"]},{kind:"component",type:W,selector:"dga-select",inputs:["options","value","multiple","searchable","openMode","clearable","size","status","placeholder","label","removeLabel","clearLabel","emptyLabel","disabled","dgaInvalid"],outputs:["valueChange"]},{kind:"directive",type:Y,selector:'input[type="checkbox"][dgaCheckbox]',inputs:["size","dgaInvalid"]},{kind:"directive",type:J,selector:'input[type="radio"][dgaRadio]',inputs:["size","dgaInvalid"]},{kind:"component",type:X,selector:"dga-phone-input",inputs:["countries","countryCode","nationalNumber","controlId","name","placeholder","autocomplete","codeLabel","disabled","required","invalid","value"],outputs:["countryCodeChange","nationalNumberChange","valueChange"]},{kind:"component",type:ie,selector:"dga-date-picker",inputs:["value","startValue","endValue","calendar","range","format","mode","locale","minDate","maxDate","yearBefore","yearAfter","placeholder","controlId","name","size","disabled","required","clearable","editable","dgaInvalid","status","rangeSeparator","todayLabel","clearLabel","closeLabel","saveLabel","ariaLabel"],outputs:["startValueChange","endValueChange","valueChange","rangeChange"]},{kind:"component",type:Z,selector:"dga-chip-input",inputs:["value","placeholder","label","removeLabel","disabled","dgaInvalid","status"],outputs:["valueChange"]},{kind:"component",type:Q,selector:"dga-switch",inputs:["checked","size","label","disabled"],outputs:["checkedChange","changed"]},{kind:"component",type:ee,selector:"dga-upload",inputs:["files","accept","multiple","appearance","hint","browseLabel","removeLabel","disabled","maxSize","maxFiles","dragging"],outputs:["filesChange","rejected","draggingChange"]},{kind:"component",type:te,selector:"dga-number-input",inputs:["value","min","max","step","size","label","controlId","name","incrementLabel","decrementLabel","disabled","dgaInvalid","status"],outputs:["valueChange"]},{kind:"component",type:oe,selector:"dga-otp",inputs:["length","value","label","alphanumeric","disabled","dgaInvalid"],outputs:["valueChange","completed"]}],changeDetection:l.ChangeDetectionStrategy.OnPush})}l.\u0275\u0275ngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:g,decorators:[{type:z,args:[{selector:"dga-dynamic-form-field",standalone:!0,imports:[k,j,H,K,W,Y,J,X,ie,Z,Q,ee,te,oe],template:`
|
|
177
177
|
@if (field().type !== 'hidden') {
|
|
178
178
|
<dga-field
|
|
179
179
|
[label]="labelText()"
|
|
@@ -348,23 +348,19 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
|
|
|
348
348
|
}
|
|
349
349
|
</dga-field>
|
|
350
350
|
}
|
|
351
|
-
`,changeDetection:_.OnPush,host:{class:"block w-full","[class.hidden]":'field().type === "hidden"'}}]}],propDecorators:{field:[{type:l.Input,args:[{isSignal:!0,alias:"field",required:!0}]}],form:[{type:l.Input,args:[{isSignal:!0,alias:"form",required:!0}]}],locale:[{type:l.Input,args:[{isSignal:!0,alias:"locale",required:!1}]}],required:[{type:l.Input,args:[{isSignal:!0,alias:"required",required:!1}]}],error:[{type:l.Input,args:[{isSignal:!0,alias:"error",required:!1}]}],runtimeOptions:[{type:l.Input,args:[{isSignal:!0,alias:"runtimeOptions",required:!1}]}],optionsLoaded:[{type:l.Output,args:["optionsLoaded"]}]}});const Re={1:"col-span-1",2:"col-span-2",3:"col-span-3",4:"col-span-4",5:"col-span-5",6:"col-span-6",7:"col-span-7",8:"col-span-8",9:"col-span-9",10:"col-span-10",11:"col-span-11",12:"col-span-12"},Ee={1:"md:col-span-1",2:"md:col-span-2",3:"md:col-span-3",4:"md:col-span-4",5:"md:col-span-5",6:"md:col-span-6",7:"md:col-span-7",8:"md:col-span-8",9:"md:col-span-9",10:"md:col-span-10",11:"md:col-span-11",12:"md:col-span-12"},Pe={1:"lg:col-span-1",2:"lg:col-span-2",3:"lg:col-span-3",4:"lg:col-span-4",5:"lg:col-span-5",6:"lg:col-span-6",7:"lg:col-span-7",8:"lg:col-span-8",9:"lg:col-span-9",10:"lg:col-span-10",11:"lg:col-span-11",12:"lg:col-span-12"};function E(r){return Number.isFinite(r)?Math.min(12,Math.max(1,Math.round(r))):12}class I{config=p.required(...ngDevMode?[{debugName:"config"}]:[]);localeInput=p(null,{...ngDevMode?{debugName:"localeInput"}:{},alias:"locale"});formSubmitted=S();formError=S();clearButtonClick=S();draftSaved=S();fb=s(ke);formService=s(y);toast=s(T,{optional:!0});i18n=s(A,{optional:!0});destroyRef=s(B);registry=s(x);form;formSignature="";valueChangesSub=null;activeStep=C(0,...ngDevMode?[{debugName:"activeStep"}]:[]);submitting=C(!1,...ngDevMode?[{debugName:"submitting"}]:[]);optionsMap=C({},...ngDevMode?[{debugName:"optionsMap"}]:[]);formValues=C({},...ngDevMode?[{debugName:"formValues"}]:[]);locale=c(()=>this.localeInput()??fe(),...ngDevMode?[{debugName:"locale"}]:[]);wizardEnabled=c(()=>!!this.config().wizard?.enabled&&!!this.config().wizard?.steps?.length,...ngDevMode?[{debugName:"wizardEnabled"}]:[]);allFields=c(()=>pe(this.config().fields,this.config().wizard?.steps),...ngDevMode?[{debugName:"allFields"}]:[]);currentStepFields=c(()=>this.wizardEnabled()?this.config().wizard.steps[this.activeStep()]?.fields??[]:this.config().fields,...ngDevMode?[{debugName:"currentStepFields"}]:[]);visibleFields=c(()=>{const e=this.formValues(),t=this.optionsMap();return this.currentStepFields().filter(o=>V(o,e,a=>t[a]))},...ngDevMode?[{debugName:"visibleFields"}]:[]);stepperSteps=c(()=>{const e=this.config().wizard?.steps??[],t=this.activeStep(),o=!!this.config().wizard?.allowSkipSteps;return e.map((a,n)=>({label:this.labelOf(a.title),description:a.description?this.labelOf(a.description):void 0,disabled:!o&&n>t}))},...ngDevMode?[{debugName:"stepperSteps"}]:[]);descriptionText=c(()=>this.labelOf(this.config().description),...ngDevMode?[{debugName:"descriptionText"}]:[]);constructor(){this.form=this.fb.group({}),this.destroyRef.onDestroy(()=>this.valueChangesSub?.unsubscribe()),G(()=>{const e=this.allFields(),t=e.map(a=>`${a.name}:${a.type}`).join("|"),o=this.config();Ce(()=>{if(t===this.formSignature)return;const a=Object.keys(this.form.controls).length?this.form.getRawValue():null,n=this.formSignature==="";this.formSignature=t;const i=ue(this.fb,e);if(a)i.patchValue(a,{emitEvent:!1});else if(n&&o.formId&&o.enableLocalStorageSave){const d=this.formService.loadDraft(o.formId);d&&i.patchValue(d,{emitEvent:!1})}this.form=i,n||this.activeStep.set(0),this.formValues.set(i.getRawValue()),this.valueChangesSub?.unsubscribe(),this.valueChangesSub=i.valueChanges.pipe(Oe(i.getRawValue())).subscribe(d=>this.formValues.set(d))})}),G(()=>{const e=this.formValues(),t=this.optionsMap();if(this.form)for(const o of this.allFields()){const a=this.form.get(o.name);if(!a||!o.requiredWhen)continue;const n=R(o,e,i=>t[i]);me(a,o,n)}})}labelOf(e){return e?this.i18n?this.i18n.resolveLabel(e,this.locale()):v(e,this.locale()):""}submitLabel(){const e=this.config();return this.wizardEnabled()?this.labelOf(e.wizard?.submitButtonText??e.submitButtonLabel)||(this.locale()==="en"?"Submit":"\u0625\u0631\u0633\u0627\u0644"):this.labelOf(e.submitButtonLabel)||(this.locale()==="en"?"Submit":"\u0625\u0631\u0633\u0627\u0644")}nextLabel(){return this.labelOf(this.config().wizard?.nextButtonText)||(this.locale()==="en"?"Next":"\u0627\u0644\u062A\u0627\u0644\u064A")}previousLabel(){return this.labelOf(this.config().wizard?.previousButtonText)||(this.locale()==="en"?"Previous":"\u0627\u0644\u0633\u0627\u0628\u0642")}clearLabel(){return this.labelOf(this.config().clearButtonLabel)}saveLabel(){return this.labelOf(this.config().saveButtonLabel??this.config().wizard?.saveButtonText)||(this.locale()==="en"?"Save":"\u062D\u0641\u0638")}showSave(){const e=this.config();return!!(e.enableLocalStorageSave||e.wizard?.showSaveButton)}isLastStep(){return this.wizardEnabled()?this.activeStep()>=this.config().wizard.steps.length-1:!0}isRequired(e){return R(e,this.formValues(),t=>this.optionsMap()[t])}fieldError(e){const t=this.form?.get(e.name);if(!t||!(t.touched||t.dirty)||!t.errors)return"";const o=t.errors,a=e.validation?.errorMessages,n=this.locale(),i=d=>a?.[d]?this.labelOf(a[d]):"";return o.required?i("required")||(n==="en"?"Required":"\u0645\u0637\u0644\u0648\u0628"):o.email?i("email")||(n==="en"?"Invalid email":"\u0628\u0631\u064A\u062F \u063A\u064A\u0631 \u0635\u0627\u0644\u062D"):o.minlength?i("minLength")||(n==="en"?"Too short":"\u0642\u0635\u064A\u0631 \u062C\u062F\u0627\u064B"):o.maxlength?i("maxLength")||(n==="en"?"Too long":"\u0637\u0648\u064A\u0644 \u062C\u062F\u0627\u064B"):o.pattern?i("pattern")||(n==="en"?"Invalid format":"\u0635\u064A\u063A\u0629 \u063A\u064A\u0631 \u0635\u0627\u0644\u062D\u0629"):o.maxChips?i("maxChips")||(n==="en"?"Too many items":"\u0639\u062F\u062F \u0627\u0644\u0639\u0646\u0627\u0635\u0631 \u0643\u0628\u064A\u0631"):n==="en"?"Invalid":"\u063A\u064A\u0631 \u0635\u0627\u0644\u062D"}columnClass(e){const t=e.columns,o=E(t?.sm??t?.md??12),a=E(t?.md??o),n=E(t?.lg??a);return["w-full",Re[o],Ee[a],Pe[n]].join(" ")}customComponent(e){return this.registry.hasCustom(e.type)?this.registry.get(e.type):null}customInputs(e){return{field:e,form:this.form,locale:this.locale(),required:this.isRequired(e),error:this.fieldError(e)}}onOptionsLoaded(e){this.optionsMap.update(t=>({...t,[e.name]:e.options}))}previousStep(){this.activeStep()>0&&this.activeStep.update(e=>e-1)}nextStep(){this.config().wizard?.validateOnStepChange!==!1&&(this.markStepTouched(),!this.stepValid())||this.isLastStep()||this.activeStep.update(t=>t+1)}onClear(){this.form.reset();for(const t of this.allFields()){const o=this.form.get(t.name);o&&o.setValue(t.value!==void 0?t.value:["checkbox","multiselect","chips","file"].includes(t.type)?[]:t.type==="toggle"?!1:"")}this.activeStep.set(0);const e=this.config().formId;e&&this.formService.clearDraft(e),this.clearButtonClick.emit()}onSaveDraft(){const e=this.form.getRawValue(),t=this.config().formId;t&&this.formService.saveDraft(t,e),this.draftSaved.emit(e),this.toast?.show({variant:"success",message:this.locale()==="en"?"Draft saved":"\u062A\u0645 \u062D\u0641\u0638 \u0627\u0644\u0645\u0633\u0648\u062F\u0629"})}onSubmit(){if(this.wizardEnabled()&&!this.isLastStep()){this.nextStep();return}if(this.markVisibleTouched(),!this.visibleValid()){this.toast?.show({variant:"error",message:this.locale()==="en"?"Please fix the highlighted fields":"\u064A\u0631\u062C\u0649 \u062A\u0635\u062D\u064A\u062D \u0627\u0644\u062D\u0642\u0648\u0644 \u0627\u0644\u0645\u062D\u062F\u062F\u0629"});return}const e=this.config(),t=this.form.getRawValue(),o=new Set(this.collectVisibleFieldNames()),a={};for(const n of this.allFields())!o.has(n.name)&&n.type!=="hidden"||(a[n.name]=t[n.name]);if(e.emitOnly||!e.endpoint){this.formSubmitted.emit(a),this.toast?.show({variant:"success",message:this.labelOf(e.successMessage)||(this.locale()==="en"?"Submitted":"\u062A\u0645 \u0627\u0644\u0625\u0631\u0633\u0627\u0644")});return}this.submitting.set(!0),this.formService.submitForm(e,a,this.allFields()).subscribe({next:n=>{this.submitting.set(!1),this.formSubmitted.emit(n),e.formId&&this.formService.clearDraft(e.formId),this.toast?.show({variant:"success",message:this.labelOf(e.successMessage)||(this.locale()==="en"?"Submitted successfully":"\u062A\u0645 \u0627\u0644\u0625\u0631\u0633\u0627\u0644 \u0628\u0646\u062C\u0627\u062D")})},error:n=>{this.submitting.set(!1),this.formError.emit(n),this.toast?.show({variant:"error",message:this.labelOf(e.errorMessage)||(this.locale()==="en"?"Submission failed":"\u0641\u0634\u0644 \u0627\u0644\u0625\u0631\u0633\u0627\u0644")})}})}patchFormValues(e){this.form.patchValue(e)}getForm(){return this.form}markStepTouched(){for(const e of this.visibleFields())this.form.get(e.name)?.markAsTouched()}markVisibleTouched(){for(const e of this.collectVisibleFieldNames())this.form.get(e)?.markAsTouched()}stepValid(){return this.visibleFields().every(e=>{const t=this.form.get(e.name);return!t||t.disabled||t.valid})}visibleValid(){return this.collectVisibleFieldNames().every(e=>{const t=this.form.get(e);return!t||t.disabled||t.valid})}collectVisibleFieldNames(){const e=this.formValues(),t=this.optionsMap();return(this.wizardEnabled()?this.allFields():this.config().fields).filter(a=>a.type==="hidden"||V(a,e,n=>t[n])).map(a=>a.name)}static \u0275fac=l.\u0275\u0275ngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:I,deps:[],target:l.\u0275\u0275FactoryTarget.Component});static \u0275cmp=l.\u0275\u0275ngDeclareComponent({minVersion:"17.0.0",version:"22.0.7",type:I,isStandalone:!0,selector:"dga-dynamic-form",inputs:{config:{classPropertyName:"config",publicName:"config",isSignal:!0,isRequired:!0,transformFunction:null},localeInput:{classPropertyName:"localeInput",publicName:"locale",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{formSubmitted:"formSubmitted",formError:"formError",clearButtonClick:"clearButtonClick",draftSaved:"draftSaved"},host:{classAttribute:"block w-full"},ngImport:l,template:`
|
|
351
|
+
`,changeDetection:_.OnPush,host:{class:"block w-full","[class.hidden]":'field().type === "hidden"'}}]}],propDecorators:{field:[{type:l.Input,args:[{isSignal:!0,alias:"field",required:!0}]}],form:[{type:l.Input,args:[{isSignal:!0,alias:"form",required:!0}]}],locale:[{type:l.Input,args:[{isSignal:!0,alias:"locale",required:!1}]}],required:[{type:l.Input,args:[{isSignal:!0,alias:"required",required:!1}]}],error:[{type:l.Input,args:[{isSignal:!0,alias:"error",required:!1}]}],runtimeOptions:[{type:l.Input,args:[{isSignal:!0,alias:"runtimeOptions",required:!1}]}],optionsLoaded:[{type:l.Output,args:["optionsLoaded"]}]}});const Pe={1:"col-span-1",2:"col-span-2",3:"col-span-3",4:"col-span-4",5:"col-span-5",6:"col-span-6",7:"col-span-7",8:"col-span-8",9:"col-span-9",10:"col-span-10",11:"col-span-11",12:"col-span-12"},Be={1:"md:col-span-1",2:"md:col-span-2",3:"md:col-span-3",4:"md:col-span-4",5:"md:col-span-5",6:"md:col-span-6",7:"md:col-span-7",8:"md:col-span-8",9:"md:col-span-9",10:"md:col-span-10",11:"md:col-span-11",12:"md:col-span-12"},_e={1:"lg:col-span-1",2:"lg:col-span-2",3:"lg:col-span-3",4:"lg:col-span-4",5:"lg:col-span-5",6:"lg:col-span-6",7:"lg:col-span-7",8:"lg:col-span-8",9:"lg:col-span-9",10:"lg:col-span-10",11:"lg:col-span-11",12:"lg:col-span-12"};function E(r){return Number.isFinite(r)?Math.min(12,Math.max(1,Math.round(r))):12}class I{config=p.required(...ngDevMode?[{debugName:"config"}]:[]);localeInput=p(null,{...ngDevMode?{debugName:"localeInput"}:{},alias:"locale"});formSubmitted=S();formError=S();clearButtonClick=S();draftSaved=S();fb=s(Oe);formService=s(y);toast=s(T,{optional:!0});i18n=s(A,{optional:!0});destroyRef=s(B);registry=s(x);form;formSignature="";valueChangesSub=null;activeStep=C(0,...ngDevMode?[{debugName:"activeStep"}]:[]);submitting=C(!1,...ngDevMode?[{debugName:"submitting"}]:[]);optionsMap=C({},...ngDevMode?[{debugName:"optionsMap"}]:[]);formValues=C({},...ngDevMode?[{debugName:"formValues"}]:[]);locale=u(()=>this.localeInput()??ge(),...ngDevMode?[{debugName:"locale"}]:[]);wizardEnabled=u(()=>!!this.config().wizard?.enabled&&!!this.config().wizard?.steps?.length,...ngDevMode?[{debugName:"wizardEnabled"}]:[]);allFields=u(()=>pe(this.config().fields,this.config().wizard?.steps),...ngDevMode?[{debugName:"allFields"}]:[]);currentStepFields=u(()=>this.wizardEnabled()?this.config().wizard.steps[this.activeStep()]?.fields??[]:this.config().fields,...ngDevMode?[{debugName:"currentStepFields"}]:[]);visibleFields=u(()=>{const e=this.formValues(),t=this.optionsMap();return this.currentStepFields().filter(o=>V(o,e,a=>t[a]))},...ngDevMode?[{debugName:"visibleFields"}]:[]);stepperSteps=u(()=>{const e=this.config().wizard?.steps??[],t=this.activeStep(),o=!!this.config().wizard?.allowSkipSteps;return e.map((a,n)=>({label:this.labelOf(a.title),description:a.description?this.labelOf(a.description):void 0,disabled:!o&&n>t}))},...ngDevMode?[{debugName:"stepperSteps"}]:[]);descriptionText=u(()=>this.labelOf(this.config().description),...ngDevMode?[{debugName:"descriptionText"}]:[]);constructor(){this.form=this.fb.group({}),this.destroyRef.onDestroy(()=>this.valueChangesSub?.unsubscribe()),G(()=>{const e=this.allFields(),t=e.map(a=>`${a.name}:${a.type}`).join("|"),o=this.config();Ie(()=>{if(t===this.formSignature)return;const a=Object.keys(this.form.controls).length?this.form.getRawValue():null,n=this.formSignature==="";this.formSignature=t;const i=ue(this.fb,e);if(a)i.patchValue(a,{emitEvent:!1});else if(n&&o.formId&&o.enableLocalStorageSave){const d=this.formService.loadDraft(o.formId);d&&i.patchValue(d,{emitEvent:!1})}this.form=i,n||this.activeStep.set(0),this.formValues.set(i.getRawValue()),this.valueChangesSub?.unsubscribe(),this.valueChangesSub=i.valueChanges.pipe(Te(i.getRawValue())).subscribe(d=>this.formValues.set(d))})}),G(()=>{const e=this.formValues(),t=this.optionsMap();if(this.form)for(const o of this.allFields()){const a=this.form.get(o.name);if(!a||!o.requiredWhen)continue;const n=R(o,e,i=>t[i]);me(a,o,n)}})}labelOf(e){return e?this.i18n?this.i18n.resolveLabel(e,this.locale()):v(e,this.locale()):""}submitLabel(){const e=this.config();return this.wizardEnabled()?this.labelOf(e.wizard?.submitButtonText??e.submitButtonLabel)||(this.locale()==="en"?"Submit":"\u0625\u0631\u0633\u0627\u0644"):this.labelOf(e.submitButtonLabel)||(this.locale()==="en"?"Submit":"\u0625\u0631\u0633\u0627\u0644")}nextLabel(){return this.labelOf(this.config().wizard?.nextButtonText)||(this.locale()==="en"?"Next":"\u0627\u0644\u062A\u0627\u0644\u064A")}previousLabel(){return this.labelOf(this.config().wizard?.previousButtonText)||(this.locale()==="en"?"Previous":"\u0627\u0644\u0633\u0627\u0628\u0642")}clearLabel(){return this.labelOf(this.config().clearButtonLabel)}saveLabel(){return this.labelOf(this.config().saveButtonLabel??this.config().wizard?.saveButtonText)||(this.locale()==="en"?"Save":"\u062D\u0641\u0638")}showSave(){const e=this.config();return!!(e.enableLocalStorageSave||e.wizard?.showSaveButton)}isLastStep(){return this.wizardEnabled()?this.activeStep()>=this.config().wizard.steps.length-1:!0}isRequired(e){return R(e,this.formValues(),t=>this.optionsMap()[t])}fieldError(e){const t=this.form?.get(e.name);if(!t||!(t.touched||t.dirty)||!t.errors)return"";const o=t.errors,a=e.validation?.errorMessages,n=this.locale(),i=d=>a?.[d]?this.labelOf(a[d]):"";return o.required?i("required")||(n==="en"?"Required":"\u0645\u0637\u0644\u0648\u0628"):o.email?i("email")||(n==="en"?"Invalid email":"\u0628\u0631\u064A\u062F \u063A\u064A\u0631 \u0635\u0627\u0644\u062D"):o.minlength?i("minLength")||(n==="en"?"Too short":"\u0642\u0635\u064A\u0631 \u062C\u062F\u0627\u064B"):o.maxlength?i("maxLength")||(n==="en"?"Too long":"\u0637\u0648\u064A\u0644 \u062C\u062F\u0627\u064B"):o.pattern?i("pattern")||(n==="en"?"Invalid format":"\u0635\u064A\u063A\u0629 \u063A\u064A\u0631 \u0635\u0627\u0644\u062D\u0629"):o.maxChips?i("maxChips")||(n==="en"?"Too many items":"\u0639\u062F\u062F \u0627\u0644\u0639\u0646\u0627\u0635\u0631 \u0643\u0628\u064A\u0631"):n==="en"?"Invalid":"\u063A\u064A\u0631 \u0635\u0627\u0644\u062D"}columnClass(e){const t=e.columns,o=E(t?.sm??t?.md??12),a=E(t?.md??o),n=E(t?.lg??a);return["w-full",Pe[o],Be[a],_e[n]].join(" ")}customComponent(e){return this.registry.hasCustom(e.type)?this.registry.get(e.type):null}customInputs(e){return{field:e,form:this.form,locale:this.locale(),required:this.isRequired(e),error:this.fieldError(e)}}onOptionsLoaded(e){this.optionsMap.update(t=>({...t,[e.name]:e.options}))}previousStep(){this.activeStep()>0&&this.activeStep.update(e=>e-1)}canActivateStep=(e,t)=>{if(e<=t)return!0;const o=this.config().wizard;return!o?.allowSkipSteps&&e>t+1?!1:o?.validateOnStepChange===!1?!0:(this.markStepTouched(),this.stepValid())};nextStep(){this.config().wizard?.validateOnStepChange!==!1&&(this.markStepTouched(),!this.stepValid())||this.isLastStep()||this.activeStep.update(t=>t+1)}onClear(){this.form.reset();for(const t of this.allFields()){const o=this.form.get(t.name);o&&o.setValue(t.value!==void 0?t.value:["checkbox","multiselect","chips","file"].includes(t.type)?[]:t.type==="toggle"?!1:"")}this.activeStep.set(0);const e=this.config().formId;e&&this.formService.clearDraft(e),this.clearButtonClick.emit()}onSaveDraft(){const e=this.form.getRawValue(),t=this.config().formId;t&&this.formService.saveDraft(t,e,this.allFields()),this.draftSaved.emit(e),this.toast?.show({variant:"success",message:this.locale()==="en"?"Draft saved":"\u062A\u0645 \u062D\u0641\u0638 \u0627\u0644\u0645\u0633\u0648\u062F\u0629"})}onSubmit(){if(this.wizardEnabled()&&!this.isLastStep()){this.nextStep();return}if(this.markVisibleTouched(),!this.visibleValid()){this.toast?.show({variant:"error",message:this.locale()==="en"?"Please fix the highlighted fields":"\u064A\u0631\u062C\u0649 \u062A\u0635\u062D\u064A\u062D \u0627\u0644\u062D\u0642\u0648\u0644 \u0627\u0644\u0645\u062D\u062F\u062F\u0629"});return}const e=this.config(),t=this.form.getRawValue(),o=new Set(this.collectVisibleFieldNames()),a={};for(const n of this.allFields())!o.has(n.name)&&n.type!=="hidden"||(a[n.name]=t[n.name]);if(e.emitOnly||!e.endpoint){this.formSubmitted.emit(a),this.toast?.show({variant:"success",message:this.labelOf(e.successMessage)||(this.locale()==="en"?"Submitted":"\u062A\u0645 \u0627\u0644\u0625\u0631\u0633\u0627\u0644")});return}this.submitting.set(!0),this.formService.submitForm(e,a,this.allFields()).subscribe({next:n=>{this.submitting.set(!1),this.formSubmitted.emit(n),e.formId&&this.formService.clearDraft(e.formId),this.toast?.show({variant:"success",message:this.labelOf(e.successMessage)||(this.locale()==="en"?"Submitted successfully":"\u062A\u0645 \u0627\u0644\u0625\u0631\u0633\u0627\u0644 \u0628\u0646\u062C\u0627\u062D")})},error:n=>{this.submitting.set(!1),this.formError.emit(n),this.toast?.show({variant:"error",message:this.labelOf(e.errorMessage)||(this.locale()==="en"?"Submission failed":"\u0641\u0634\u0644 \u0627\u0644\u0625\u0631\u0633\u0627\u0644")})}})}patchFormValues(e){this.form.patchValue(e)}getForm(){return this.form}markStepTouched(){for(const e of this.visibleFields())this.form.get(e.name)?.markAsTouched()}markVisibleTouched(){for(const e of this.collectVisibleFieldNames())this.form.get(e)?.markAsTouched()}stepValid(){return this.visibleFields().every(e=>{const t=this.form.get(e.name);return!t||t.disabled||t.valid})}visibleValid(){return this.collectVisibleFieldNames().every(e=>{const t=this.form.get(e);return!t||t.disabled||t.valid})}collectVisibleFieldNames(){const e=this.formValues(),t=this.optionsMap();return(this.wizardEnabled()?this.allFields():this.config().fields).filter(a=>a.type==="hidden"||V(a,e,n=>t[n])).map(a=>a.name)}static \u0275fac=l.\u0275\u0275ngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:I,deps:[],target:l.\u0275\u0275FactoryTarget.Component});static \u0275cmp=l.\u0275\u0275ngDeclareComponent({minVersion:"17.0.0",version:"22.0.7",type:I,isStandalone:!0,selector:"dga-dynamic-form",inputs:{config:{classPropertyName:"config",publicName:"config",isSignal:!0,isRequired:!0,transformFunction:null},localeInput:{classPropertyName:"localeInput",publicName:"locale",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{formSubmitted:"formSubmitted",formError:"formError",clearButtonClick:"clearButtonClick",draftSaved:"draftSaved"},host:{classAttribute:"block w-full"},ngImport:l,template:`
|
|
352
352
|
<form class="flex w-full flex-col gap-3xl" [formGroup]="form" (ngSubmit)="onSubmit()">
|
|
353
353
|
@if (descriptionText()) {
|
|
354
354
|
<p class="text-body-md text-paragraph">{{ descriptionText() }}</p>
|
|
355
355
|
}
|
|
356
356
|
|
|
357
357
|
@if (wizardEnabled()) {
|
|
358
|
-
<
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
[(active)]="activeStep"
|
|
365
|
-
[label]="locale() === 'en' ? 'Steps' : '\u0627\u0644\u062E\u0637\u0648\u0627\u062A'"
|
|
366
|
-
/>
|
|
367
|
-
</div>
|
|
358
|
+
<dga-stepper
|
|
359
|
+
[steps]="stepperSteps()"
|
|
360
|
+
[(active)]="activeStep"
|
|
361
|
+
[beforeActiveChange]="canActivateStep"
|
|
362
|
+
[label]="locale() === 'en' ? 'Steps' : '\u0627\u0644\u062E\u0637\u0648\u0627\u062A'"
|
|
363
|
+
/>
|
|
368
364
|
}
|
|
369
365
|
|
|
370
366
|
<div class="grid grid-cols-12 gap-xl">
|
|
@@ -432,23 +428,19 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
|
|
|
432
428
|
}
|
|
433
429
|
</div>
|
|
434
430
|
</form>
|
|
435
|
-
`,isInline:!0,dependencies:[{kind:"ngmodule",type:k},{kind:"directive",type:m.\u0275NgNoValidate,selector:"form:not([ngNoForm]):not([ngNativeValidate])"},{kind:"directive",type:m.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:m.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"component",type:g,selector:"dga-dynamic-form-field",inputs:["field","form","locale","required","error","runtimeOptions"],outputs:["optionsLoaded"]},{kind:"directive",type:
|
|
431
|
+
`,isInline:!0,dependencies:[{kind:"ngmodule",type:k},{kind:"directive",type:m.\u0275NgNoValidate,selector:"form:not([ngNoForm]):not([ngNativeValidate])"},{kind:"directive",type:m.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:m.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"component",type:g,selector:"dga-dynamic-form-field",inputs:["field","form","locale","required","error","runtimeOptions"],outputs:["optionsLoaded"]},{kind:"directive",type:re,selector:"button[dgaButton], a[dgaButton]",inputs:["variant","size","iconOnly","cooldownMs","loading","dgaButtonClass"]},{kind:"component",type:ae,selector:"dga-stepper",inputs:["steps","active","label","beforeActiveChange"],outputs:["activeChange"]},{kind:"directive",type:$,selector:"[ngComponentOutlet]",inputs:["ngComponentOutlet","ngComponentOutletInputs","ngComponentOutletInjector","ngComponentOutletEnvironmentInjector","ngComponentOutletContent","ngComponentOutletNgModule"],exportAs:["ngComponentOutlet"]}],changeDetection:l.ChangeDetectionStrategy.OnPush})}l.\u0275\u0275ngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:I,decorators:[{type:z,args:[{selector:"dga-dynamic-form",standalone:!0,imports:[k,g,re,ae,$],template:`
|
|
436
432
|
<form class="flex w-full flex-col gap-3xl" [formGroup]="form" (ngSubmit)="onSubmit()">
|
|
437
433
|
@if (descriptionText()) {
|
|
438
434
|
<p class="text-body-md text-paragraph">{{ descriptionText() }}</p>
|
|
439
435
|
}
|
|
440
436
|
|
|
441
437
|
@if (wizardEnabled()) {
|
|
442
|
-
<
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
[(active)]="activeStep"
|
|
449
|
-
[label]="locale() === 'en' ? 'Steps' : '\u0627\u0644\u062E\u0637\u0648\u0627\u062A'"
|
|
450
|
-
/>
|
|
451
|
-
</div>
|
|
438
|
+
<dga-stepper
|
|
439
|
+
[steps]="stepperSteps()"
|
|
440
|
+
[(active)]="activeStep"
|
|
441
|
+
[beforeActiveChange]="canActivateStep"
|
|
442
|
+
[label]="locale() === 'en' ? 'Steps' : '\u0627\u0644\u062E\u0637\u0648\u0627\u062A'"
|
|
443
|
+
/>
|
|
452
444
|
}
|
|
453
445
|
|
|
454
446
|
<div class="grid grid-cols-12 gap-xl">
|
|
@@ -516,4 +508,4 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
|
|
|
516
508
|
}
|
|
517
509
|
</div>
|
|
518
510
|
</form>
|
|
519
|
-
`,changeDetection:_.OnPush,host:{class:"block w-full"}}]}],ctorParameters:()=>[],propDecorators:{config:[{type:l.Input,args:[{isSignal:!0,alias:"config",required:!0}]}],localeInput:[{type:l.Input,args:[{isSignal:!0,alias:"locale",required:!1}]}],formSubmitted:[{type:l.Output,args:["formSubmitted"]}],formError:[{type:l.Output,args:["formError"]}],clearButtonClick:[{type:l.Output,args:["clearButtonClick"]}],draftSaved:[{type:l.Output,args:["draftSaved"]}]}});const
|
|
511
|
+
`,changeDetection:_.OnPush,host:{class:"block w-full"}}]}],ctorParameters:()=>[],propDecorators:{config:[{type:l.Input,args:[{isSignal:!0,alias:"config",required:!0}]}],localeInput:[{type:l.Input,args:[{isSignal:!0,alias:"locale",required:!1}]}],formSubmitted:[{type:l.Output,args:["formSubmitted"]}],formError:[{type:l.Output,args:["formError"]}],clearButtonClick:[{type:l.Output,args:["clearButtonClick"]}],draftSaved:[{type:l.Output,args:["draftSaved"]}]}});const he={resolveLabel(r,e){return e==="en"?r.en:r.ar}},be={getToken:()=>b(null)},ve={lookup:()=>b([])},ze=new Set(["__proto__","constructor","prototype"]);function q(r,e){const t=r.trim();if(!t)throw new Error("DGA dynamic form: empty HTTP URL");if(t.startsWith("/")&&!t.startsWith("//"))return t.replace(/\/$/,"")||"/";let o;try{o=new URL(t)}catch{throw new Error(`DGA dynamic form: invalid HTTP URL "${r}"`)}if(o.protocol!=="http:"&&o.protocol!=="https:")throw new Error(`DGA dynamic form: blocked URL protocol "${o.protocol}"`);if(e?.length&&!e.some(n=>{try{return new URL(n).origin===o.origin}catch{return n===o.origin}}))throw new Error(`DGA dynamic form: origin not allowlisted "${o.origin}"`);return o.toString().replace(/\/$/,"")}function ye(r=s(D),e={}){return{lookup(t){try{const a=`${q(t.domain,e.allowedOrigins)}/lookup/${encodeURIComponent(t.name)}`,n={};if(t.parentId!=null&&t.parentId!==""&&(n.parentId=String(t.parentId)),t.search){const i=t.searchParamName||"q";n[i]=t.search}return r.get(a,{params:n}).pipe(Le(i=>Array.isArray(i)?i.map(Ge):[]))}catch(o){return ne(()=>o)}}}}function Ge(r){const e=r??{},t=e.value??e.id??e.Id??"",o=String(e.labelEn??e.titleEn??e.en??e.TitleEn??t),a=String(e.labelAr??e.titleAr??e.ar??e.TitleAr??o),n={value:t,label:{en:o,ar:a}};for(const[i,d]of Object.entries(e))ze.has(i)||i==="value"||i==="label"||i==="id"||i==="Id"||i==="labelEn"||i==="titleEn"||i==="en"||i==="TitleEn"||i==="labelAr"||i==="titleAr"||i==="ar"||i==="TitleAr"||(n[i]=d);return e.disabled!=null&&(n.disabled=!!e.disabled),e.requiresTextInput!=null&&(n.requiresTextInput=!!e.requiresTextInput),e.description&&typeof e.description=="object"&&(n.description=e.description),n}function xe(r=s(D),e={}){return{submit(t){try{const o=q(t.endpoint,e.allowedOrigins),a=new Ne(t.headers??{}),n=t.method.toUpperCase();return n==="GET"?r.get(o,{headers:a}):n==="DELETE"?r.delete(o,{headers:a,body:t.body}):n==="PUT"?r.put(o,t.body,{headers:a}):n==="PATCH"?r.patch(o,t.body,{headers:a}):r.post(o,t.body,{headers:a})}catch(o){return ne(()=>o)}}}}function Se(r=s(Ae)){return{show(e){r.show({title:e.title,message:e.message,variant:e.variant??"info"})}}}function $e(r={}){const e=r.httpLookup??!1,t=r.httpSubmit??!0,o=r.dgaToast??!0,a=r.requireAllowedOrigins??!1,n={allowedOrigins:r.allowedOrigins};if(a&&(e||t)&&!r.allowedOrigins?.length)throw new Error("DGA dynamic form: provideDgaDynamicForm({ allowedOrigins: [...] }) is required when requireAllowedOrigins is true. ");return ke()&&(e||t)&&!r.allowedOrigins?.length&&console.warn("[dga-dynamic-form] HTTP adapters enabled without allowedOrigins. Absolute schema URLs can reach any https host \u2014 set allowedOrigins (and requireAllowedOrigins: true) for CMS schemas."),De([{provide:A,useValue:he},{provide:L,useValue:be},{provide:O,useFactory:()=>e?ye(s(D),n):ve},{provide:w,useFactory:()=>t?xe(s(D),n):{submit:()=>b(null)}},{provide:T,useFactory:()=>o?Se():{show:()=>{}}}])}function je(r,e,t=""){return r?e==="en"?r.en:r.ar:t}export{L as DGA_CAPTCHA_ADAPTER,le as DGA_DYNAMIC_FORM_FIELD_REGISTRY,A as DGA_FORM_I18N_ADAPTER,T as DGA_FORM_TOAST_ADAPTER,O as DGA_LOOKUP_ADAPTER,w as DGA_SUBMIT_ADAPTER,I as DgaDynamicForm,g as DgaDynamicFormField,x as DgaDynamicFormFieldRegistry,y as DgaDynamicFormService,Se as createDgaToastAdapter,ye as createHttpLookupAdapter,xe as createHttpSubmitAdapter,he as defaultFormI18nAdapter,q as dgaAssertSafeHttpUrl,ue as dgaBuildFormGroup,F as dgaBuildValidators,pe as dgaCollectFields,ce as dgaCreateControl,de as dgaDefaultValueForField,ge as dgaDetectLocale,M as dgaFindSelectedOption,V as dgaIsFieldVisible,R as dgaIsRequiredWhen,v as dgaResolveLabel,me as dgaSetControlValidators,ve as emptyLookupAdapter,be as noopCaptchaAdapter,$e as provideDgaDynamicForm,je as resolveFormLabel};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a.nemreen/dga-dynamic-form",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Schema-driven dynamic forms for Angular, rendered with @a.nemreen/dga-ui controls",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -33,6 +33,12 @@
|
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
|
+
"files": [
|
|
37
|
+
"fesm2022",
|
|
38
|
+
"types",
|
|
39
|
+
"LICENSE",
|
|
40
|
+
"README.md"
|
|
41
|
+
],
|
|
36
42
|
"engines": {
|
|
37
43
|
"node": ">=18"
|
|
38
44
|
},
|
|
@@ -40,8 +46,8 @@
|
|
|
40
46
|
"@angular/common": "^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
|
|
41
47
|
"@angular/core": "^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
|
|
42
48
|
"@angular/forms": "^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
|
|
43
|
-
"@a.nemreen/dga-tokens": "^0.2.0",
|
|
44
|
-
"@a.nemreen/dga-ui": "^0.2.0"
|
|
49
|
+
"@a.nemreen/dga-tokens": "^0.2.0 || ^0.3.0",
|
|
50
|
+
"@a.nemreen/dga-ui": "^0.2.0 || ^0.3.0"
|
|
45
51
|
},
|
|
46
52
|
"dependencies": {
|
|
47
53
|
"tslib": "^2.3.0"
|
|
@@ -72,6 +72,13 @@ interface DgaFormField {
|
|
|
72
72
|
columns?: DgaFormFieldColumns;
|
|
73
73
|
optionsLayout?: 'stack' | 'grid';
|
|
74
74
|
excludeFromPayload?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* When true, the field value is never written to draft storage.
|
|
77
|
+
* OTP / file fields are always excluded even without this flag.
|
|
78
|
+
*/
|
|
79
|
+
excludeFromDraft?: boolean;
|
|
80
|
+
/** Treat as sensitive in drafts (same effect as excludeFromDraft). */
|
|
81
|
+
sensitive?: boolean;
|
|
75
82
|
inputRestriction?: DgaInputRestriction;
|
|
76
83
|
requiredWhen?: {
|
|
77
84
|
field: string;
|
|
@@ -261,6 +268,8 @@ declare class DgaDynamicForm {
|
|
|
261
268
|
options: DgaFormFieldOption[];
|
|
262
269
|
}): void;
|
|
263
270
|
previousStep(): void;
|
|
271
|
+
/** Keep stepper clicks aligned with Next validation / allowSkip rules. */
|
|
272
|
+
readonly canActivateStep: (next: number, current: number) => boolean;
|
|
264
273
|
nextStep(): void;
|
|
265
274
|
onClear(): void;
|
|
266
275
|
onSaveDraft(): void;
|
|
@@ -319,9 +328,14 @@ declare class DgaDynamicFormService {
|
|
|
319
328
|
hasFileValues(data: Record<string, unknown>): boolean;
|
|
320
329
|
toFormData(data: Record<string, unknown>): FormData;
|
|
321
330
|
submitForm(config: DgaDynamicFormConfig, values: Record<string, unknown>, fields: DgaFormField[]): Observable<unknown>;
|
|
322
|
-
|
|
331
|
+
/**
|
|
332
|
+
* Persist a draft. Sensitive fields (otp, file, password-like names,
|
|
333
|
+
* `excludeFromDraft` / `sensitive`) are stripped before writing.
|
|
334
|
+
*/
|
|
335
|
+
saveDraft(formId: string, values: Record<string, unknown>, fields?: DgaFormField[]): void;
|
|
323
336
|
loadDraft(formId: string): Record<string, unknown> | null;
|
|
324
337
|
clearDraft(formId: string): void;
|
|
338
|
+
private isDraftBlocked;
|
|
325
339
|
private storageKey;
|
|
326
340
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DgaDynamicFormService, never>;
|
|
327
341
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<DgaDynamicFormService>;
|
|
@@ -352,8 +366,11 @@ declare const emptyLookupAdapter: DgaLookupAdapter;
|
|
|
352
366
|
interface DgaHttpAdapterSecurityOptions {
|
|
353
367
|
/**
|
|
354
368
|
* Allowed URL origins for schema-driven HTTP (e.g. `https://api.example.com`).
|
|
355
|
-
*
|
|
356
|
-
*
|
|
369
|
+
* Absolute URLs outside the list are rejected.
|
|
370
|
+
* Same-origin paths (`/api/...`) are always allowed.
|
|
371
|
+
*
|
|
372
|
+
* Strongly recommended for CMS / untrusted schemas. When `requireAllowedOrigins`
|
|
373
|
+
* is true (see `provideDgaDynamicForm`), omitting this throws at bootstrap.
|
|
357
374
|
*/
|
|
358
375
|
allowedOrigins?: string[];
|
|
359
376
|
}
|
|
@@ -378,6 +395,11 @@ interface ProvideDgaDynamicFormOptions {
|
|
|
378
395
|
dgaToast?: boolean;
|
|
379
396
|
/** Optional origin allowlist for HTTP adapters (recommended for CMS schemas). */
|
|
380
397
|
allowedOrigins?: string[];
|
|
398
|
+
/**
|
|
399
|
+
* When true, `allowedOrigins` is required if httpLookup or httpSubmit is enabled.
|
|
400
|
+
* Defaults to false (warn in dev). Set true for CMS / untrusted schemas.
|
|
401
|
+
*/
|
|
402
|
+
requireAllowedOrigins?: boolean;
|
|
381
403
|
}
|
|
382
404
|
/**
|
|
383
405
|
* Registers default adapters for lookup, submit, toast, captcha, and i18n.
|