@a.nemreen/dga-dynamic-form 0.1.7 → 0.1.9

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.
@@ -1,4 +1,160 @@
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:`
1
+ import*as l from"@angular/core";import{InjectionToken as x,inject as c,Injectable as Y,isDevMode as ze,makeEnvironmentProviders as Be,input as u,booleanAttribute as J,signal as m,computed as p,output as g,ChangeDetectionStrategy as V,Component as R,DestroyRef as Q,effect as k,untracked as q}from"@angular/core";import{NgComponentOutlet as X}from"@angular/common";import*as h from"@angular/forms";import{Validators as b,ReactiveFormsModule as O,FormsModule as Z,FormBuilder as _e}from"@angular/forms";import{switchMap as ee,catchError as $e,map as Ue,startWith as Ge}from"rxjs/operators";import{takeUntilDestroyed as T}from"@angular/core/rxjs-interop";import{DgaToastService as je,DgaButton as A,DgaIcon as te,dgaProvideValueAccessor as ae,DgaField as ie,DgaInput as ne,DgaSelect as oe,DgaCheckbox as re,DgaRadio as le,DgaPhoneInput as se,DgaChipInput as de,DgaSwitch as ue,DgaUpload as ce,DgaNumberInput as pe,DgaOtp as fe,DgaStepper as me}from"@a.nemreen/dga-ui";import{of as D,throwError as ge,startWith as Ke,catchError as We}from"rxjs";import{HttpClient as I,HttpHeaders as He}from"@angular/common/http";import{DgaDatePicker as he}from"@a.nemreen/dga-ui/date-picker";const z=new x("DGA_LOOKUP_ADAPTER"),E=new x("DGA_SUBMIT_ADAPTER"),B=new x("DGA_FORM_TOAST_ADAPTER"),_=new x("DGA_CAPTCHA_ADAPTER"),$=new x("DGA_HTTP_SECURITY"),U=new x("DGA_FORM_I18N_ADAPTER"),be=new x("DGA_DYNAMIC_FORM_FIELD_REGISTRY"),ve=[["StartDate","EndDate"],["UseCaseStartDate","UseCaseEndDate"],["startDate","endDate"]];function ye(i){return e=>e.value&&i.value!==e.value?{passwordMismatch:!0}:null}function Ye(i){return e=>{if(!e.value||!i.value)return null;const t=new Date(e.value),a=new Date(i.value),n=new Date(a);return n.setDate(n.getDate()+1),t>=n?null:{endDateAfterStartDate:!0}}}function xe(i){const e=(i.value??"").toString().trim();if(!e)return null;let t=e;return e.startsWith("+966")?t=e.slice(4):e.startsWith("966")&&(t=e.slice(3)),/^\d+$/.test(t)?t.startsWith("0")?t.length===10?null:{invalidLength:!0}:t.startsWith("5")?t.length===9?null:{invalidLength:!0}:{invalidPrefix:!0}:{invalidFormat:!0}}function Je(i){return e=>{if(!e.value)return null;const t=new Date(e.value),a=new Date(i);return t>=a?null:{minDate:!0}}}function Qe(i){return e=>{if(!e.value)return null;const t=new Date(e.value),a=new Date(i);return t<=a?null:{maxDate:!0}}}function Xe(i){const e=i.value;return Array.isArray(e)&&e.some(a=>a&&typeof a=="object"&&a.status==="uploading")?{uploadInProgress:!0}:null}function De(i,e){const t=i.get("password"),a=i.get("confirmPassword");t&&a&&(a.addValidators(ye(t)),a.updateValueAndValidity({emitEvent:!1}));for(const[n,o]of ve){const r=i.get(n),s=i.get(o);if(!r||!s)continue;s.addValidators(Ye(r));const d=e.find(S=>S.name===o),f=S=>{if(d?.validation){if(S){const qe=new Date(S),P=new Date(qe);P.setDate(P.getDate()+1),d.validation.minDate=P.toISOString().split("T")[0]}else delete d.validation.minDate;s.updateValueAndValidity({emitEvent:!1})}};f(r.value),r.valueChanges.subscribe(S=>f(S))}}const we=["checkbox","multiselect","chips","file","multifile","multifilestaged"],Ze=["toggle"];function Se(i){return i.value!==void 0?i.value:we.includes(i.type)?[]:Ze.includes(i.type)?!1:""}function G(i,e){const t=[],a=i.validation;(e||i.required||a?.required)&&(we.includes(i.type)?t.push(et):i.type==="toggle"?t.push(b.requiredTrue):t.push(b.required)),(i.type==="email"||a?.pattern==="email")&&t.push(b.email);const n=a?.minLength;n!=null&&t.push(b.minLength(n));const o=a?.maxLength??i.maxLength;if(o!=null&&t.push(b.maxLength(o)),a?.pattern&&a.pattern!=="email"){const r=a.pattern;if(typeof r=="string"&&r.length>0&&r.length<=200)try{t.push(b.pattern(r))}catch{}}return a?.min!=null&&t.push(b.min(a.min)),a?.max!=null&&t.push(b.max(a.max)),i.maxChips!=null&&i.type==="chips"&&t.push(tt(i.maxChips)),i.type==="phone"&&t.push(xe),i.type==="multifilestaged"&&t.push(Xe),a?.minDate&&t.push(Je(a.minDate)),a?.maxDate&&t.push(Qe(a.maxDate)),t}function et(i){const e=i.value;return Array.isArray(e)&&e.length>0?null:{required:!0}}function tt(i){return e=>{const t=e.value;return Array.isArray(t)&&t.length>i?{maxChips:{max:i,actual:t.length}}:null}}function Ie(i,e,t=!0){const a=!!e.disabled;return i.control({value:Se(e),disabled:a},{validators:G(e,t&&!e.requiredWhen)})}function Ce(i,e){const t={};for(const a of e){if(a.hidden&&a.type==="hidden"){t[a.name]=i.control(a.value??"");continue}t[a.name]=Ie(i,a)}return i.group(t)}function Le(i,e){return e?.length?e.flatMap(t=>t.fields):i}function Fe(i,e,t){i.setValidators(G(e,t)),i.updateValueAndValidity({emitEvent:!1})}function j(i,e){return Array.isArray(i)?i.some(t=>t==e):i==e}function at(i){return i.label?.en??""}function it(i){return i.label?.ar??""}function M(i,e,t,a){return ke(a?.(i)??{name:i,type:"select",label:{en:"",ar:""}},e,t?.(i))}function nt(i,e,t,a,n){if(!i.showOnTitleEn&&!i.showOnTitleAr||t==null||t==="")return!1;const o=M(e,t,a,n);if(!o)return!1;const r=i.showOnTitleEn?at(o)===i.showOnTitleEn:!0,s=i.showOnTitleAr?it(o)===i.showOnTitleAr:!0;return r&&s}function Ne(i,e,t,a){if(!i.extraField)return!0;const n=i.extraFieldTrigger||i.dependsOn;if(!n)return!1;const o=e[n];return M(n,o,t,a)?.requiresTextInput===!0}function ke(i,e,t){return i?[...t??[],...i.options??[],...i.groupedOptions?.flatMap(n=>n.options)??[]].find(n=>n.value==e):void 0}function K(i,e,t,a){if(i.hidden&&i.type!=="hidden"||i.type==="hidden")return!1;if(!i.dependsOn&&!i.extraField)return!0;const n=i.dependsOn??i.extraFieldTrigger;if(!n)return Ne(i,e,t,a);const o=e[n];if(i.showOnValues?.length&&!i.showOnValues.some(r=>j(o,r))||(i.showOnTitleEn||i.showOnTitleAr)&&!nt(i,n,o,t,a))return!1;if(i.showWhenOptionProperty){const r=M(n,o,t,a),s=i.showWhenOptionProperty.property;if(!r||r[s]!==i.showWhenOptionProperty.value)return!1}return!(i.extraField&&!Ne(i,e,t,a)||i.dependsOn&&!i.showOnValues?.length&&!i.showWhenOptionProperty&&!i.showOnTitleEn&&!i.showOnTitleAr&&!i.extraField&&(o==null||o===""||Array.isArray(o)&&o.length===0))}function W(i,e,t,a){const n=i.requiredWhen;if(!n)return!!i.required;const o=e[n.field];if(n.optionProperty!=null){const r=M(n.field,o,t,a);return!!r&&r[n.optionProperty]===n.optionPropertyValue}return n.values?.length?n.values.some(r=>j(o,r)):n.value!==void 0?j(o,n.value):o!=null&&o!==""}const ot=new Set(["otp","file"]),Oe=/password|passwd|secret|token|otp|national.?id|ssn|pin$/i;class C{submitAdapter=c(E,{optional:!0});captcha=c(_,{optional:!0});buildPayload(e,t,a){const n=new Set(a.filter(r=>r.excludeFromPayload).map(r=>r.name));let o={};for(const[r,s]of Object.entries(t)){if(n.has(r))continue;const d=e.fieldMapping?.[r]??r;o[d]=s}return e.payloadTransformer?e.payloadTransformer(o):o}hasFileValues(e){return Object.values(e).some(t=>t instanceof File||Array.isArray(t)&&t.some(a=>a instanceof File||a?.file instanceof File))}toFormData(e){const t=new FormData;for(const[a,n]of Object.entries(e))if(n!=null)if(n instanceof File)t.append(a,n);else if(Array.isArray(n))for(const o of n)o instanceof File?t.append(a,o):o?.file instanceof File?t.append(a,o.file,o.name):t.append(a,typeof o=="string"?o:JSON.stringify(o));else typeof n=="object"?t.append(a,JSON.stringify(n)):t.append(a,String(n));return t}submitForm(e,t,a){if(!e.endpoint||!this.submitAdapter)return D(t);const n=this.buildPayload(e,t,a),o=n instanceof FormData?n:this.hasFileValues(n)?this.toFormData(n):n,r={};return e.idempotencyKey&&(r["Idempotency-Key"]=e.idempotencyKey),(this.captcha?.getToken("submit")??D(null)).pipe(ee(d=>(d&&(r["X-Recaptcha-Token"]=d),D({endpoint:e.endpoint,method:e.method??"POST",body:o,headers:r})))).pipe(ee(d=>this.submitAdapter.submit(d)),$e(d=>{throw d}))}saveDraft(e,t,a=[]){if(typeof localStorage>"u")return;const n=new Map(a.map(r=>[r.name,r])),o={};for(const[r,s]of Object.entries(t)){const d=n.get(r);d&&this.isDraftBlocked(d)||!d&&Oe.test(r)||s instanceof File||(o[r]=s)}localStorage.setItem(this.storageKey(e),JSON.stringify(o))}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||ot.has(e.type)?!0:Oe.test(e.name)}storageKey(e){return`dga-dynamic-form:${e}`}static ɵfac=l.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:C,deps:[],target:l.ɵɵFactoryTarget.Injectable});static ɵprov=l.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:C,providedIn:"root"})}l.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:C,decorators:[{type:Y,args:[{providedIn:"root"}]}]});function v(i,e,t=""){if(!i)return t;const a=i[e];return a||(i.en?i.en:i.ar?i.ar:Object.values(i).find(o=>!!o)||t)}function Te(){return typeof document>"u"?"ar":(document.documentElement.lang||"ar").toLowerCase().split("-")[0]||"ar"}class L{extras=c(be,{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 rt.has(e)}static ɵfac=l.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:L,deps:[],target:l.ɵɵFactoryTarget.Injectable});static ɵprov=l.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:L,providedIn:"root"})}l.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:L,decorators:[{type:Y,args:[{providedIn:"root"}]}],ctorParameters:()=>[]});const rt=new Set(["text","email","textarea","select","multiselect","checkbox","radio","phone","file","multifile","multifilestaged","date","chips","toggle","hidden","number","otp","password"]),Ae={resolveLabel(i,e){return v(i,e)}},Ee={getToken:()=>D(null)},Me={lookup:()=>D([])},lt=new Set(["__proto__","constructor","prototype"]);function F(i,e){const t=i.trim();if(!t)throw new Error("DGA dynamic form: empty HTTP URL");if(t.startsWith("/")&&!t.startsWith("//"))return t.replace(/\/$/,"")||"/";let a;try{a=new URL(t)}catch{throw new Error(`DGA dynamic form: invalid HTTP URL "${i}"`)}if(a.protocol!=="http:"&&a.protocol!=="https:")throw new Error(`DGA dynamic form: blocked URL protocol "${a.protocol}"`);if(e?.length&&!e.some(o=>{try{return new URL(o).origin===a.origin}catch{return o===a.origin}}))throw new Error(`DGA dynamic form: origin not allowlisted "${a.origin}"`);return a.toString().replace(/\/$/,"")}function Pe(i=c(I),e={}){return{lookup(t){try{const n=`${F(t.domain,e.allowedOrigins)}/lookup/${encodeURIComponent(t.name)}`,o={};if(t.parentId!=null&&t.parentId!==""&&(o.parentId=String(t.parentId)),t.search){const r=t.searchParamName||"q";o[r]=t.search}return i.get(n,{params:o}).pipe(Ue(r=>Array.isArray(r)?r.map(st):[]))}catch(a){return ge(()=>a)}}}}function st(i){const e=i??{},t=e.DisplayName??e.UserName??e.Email,a=e.value??e.id??e.Id??e.Code??t??"",n=String(e.labelEn??e.titleEn??e.en??e.TitleEn??e.Name??e.name??t??a),o=String(e.labelAr??e.titleAr??e.ar??e.TitleAr??e.NameAr??e.nameAr??n),r={value:a,label:{en:n,ar:o}};for(const[s,d]of Object.entries(e))lt.has(s)||s==="value"||s==="label"||s==="id"||s==="Id"||s==="labelEn"||s==="titleEn"||s==="en"||s==="TitleEn"||s==="labelAr"||s==="titleAr"||s==="ar"||s==="TitleAr"||(r[s]=d);return e.disabled!=null&&(r.disabled=!!e.disabled),e.requiresTextInput!=null&&(r.requiresTextInput=!!e.requiresTextInput),e.description&&typeof e.description=="object"&&(r.description=e.description),r}function Ve(i=c(I),e={}){return{submit(t){try{const a=F(t.endpoint,e.allowedOrigins),n=new He(t.headers??{}),o=t.method.toUpperCase();return o==="GET"?i.get(a,{headers:n}):o==="DELETE"?i.delete(a,{headers:n,body:t.body}):o==="PUT"?i.put(a,t.body,{headers:n}):o==="PATCH"?i.patch(a,t.body,{headers:n}):i.post(a,t.body,{headers:n})}catch(a){return ge(()=>a)}}}}function Re(i=c(je)){return{show(e){i.show({title:e.title,message:e.message,variant:e.variant??"info"})}}}function dt(i={}){const e=i.httpLookup??!1,t=i.httpSubmit??!0,a=i.dgaToast??!0,n=i.requireAllowedOrigins??!1,o={allowedOrigins:i.allowedOrigins};if(n&&(e||t)&&!i.allowedOrigins?.length)throw new Error("DGA dynamic form: provideDgaDynamicForm({ allowedOrigins: [...] }) is required when requireAllowedOrigins is true. ");return ze()&&(e||t)&&!i.allowedOrigins?.length&&console.warn("[dga-dynamic-form] HTTP adapters enabled without allowedOrigins. Absolute schema URLs can reach any https host — set allowedOrigins (and requireAllowedOrigins: true) for CMS schemas."),Be([{provide:$,useValue:o},{provide:U,useValue:Ae},{provide:_,useValue:Ee},{provide:z,useFactory:()=>e?Pe(c(I),o):Me},{provide:E,useFactory:()=>t?Ve(c(I),o):{submit:()=>D(null)}},{provide:B,useFactory:()=>a?Re():{show:()=>{}}}])}function ut(i,e,t=""){return v(i,e,t)}class y{accept=u("",...ngDevMode?[{debugName:"accept"}]:[]);maxFileSize=u(0,...ngDevMode?[{debugName:"maxFileSize"}]:[]);maxFiles=u(0,...ngDevMode?[{debugName:"maxFiles"}]:[]);uploadEndpoint=u("",...ngDevMode?[{debugName:"uploadEndpoint"}]:[]);deleteEndpoint=u("",...ngDevMode?[{debugName:"deleteEndpoint"}]:[]);deleteMethod=u("DELETE",...ngDevMode?[{debugName:"deleteMethod"}]:[]);hint=u("Drag files here or browse",...ngDevMode?[{debugName:"hint"}]:[]);browseLabel=u("Choose files",...ngDevMode?[{debugName:"browseLabel"}]:[]);removeLabel=u("Remove",...ngDevMode?[{debugName:"removeLabel"}]:[]);downloadLabel=u("Download",...ngDevMode?[{debugName:"downloadLabel"}]:[]);uploadingLabel=u("Uploading…",...ngDevMode?[{debugName:"uploadingLabel"}]:[]);errorLabel=u("Upload failed",...ngDevMode?[{debugName:"errorLabel"}]:[]);disabledInput=u(!1,{...ngDevMode?{debugName:"disabledInput"}:{},alias:"disabled",transform:J});cvaDisabled=m(!1,...ngDevMode?[{debugName:"cvaDisabled"}]:[]);disabled=p(()=>this.disabledInput()||this.cvaDisabled(),...ngDevMode?[{debugName:"disabled"}]:[]);fileDownload=g();http=c(I);httpSecurity=c($,{optional:!0});files=m([],...ngDevMode?[{debugName:"files"}]:[]);dragging=m(!1,...ngDevMode?[{debugName:"dragging"}]:[]);onChange=()=>{};onTouched=()=>{};atLimit=p(()=>{const e=this.maxFiles();return e>0&&this.files().length>=e},...ngDevMode?[{debugName:"atLimit"}]:[]);onDragOver(e){e.preventDefault(),!this.disabled()&&!this.atLimit()&&this.dragging.set(!0)}onDrop(e){if(e.preventDefault(),this.dragging.set(!1),this.disabled()||this.atLimit())return;const t=e.dataTransfer?.files;t?.length&&this.addFiles(Array.from(t))}onPick(e){const t=e.target;t.files?.length&&this.addFiles(Array.from(t.files)),t.value=""}remove(e){if(e.status==="uploading")return;const t=this.isExisting(e),a=this.deleteEndpoint();if(!t&&a&&e.fileId){const n=a.includes(":id")?a.replace(":id",encodeURIComponent(e.fileId)):a.includes(":fileId")?a.replace(":fileId",encodeURIComponent(e.fileId)):a;try{const o=F(n,this.httpSecurity?.allowedOrigins);this.deleteMethod()==="POST"?this.http.post(o,{FileName:e.fileName}).subscribe({complete:()=>this.commit(this.files().filter(r=>r!==e))}):this.http.delete(o).subscribe({complete:()=>this.commit(this.files().filter(r=>r!==e))});return}catch{}}this.commit(this.files().filter(n=>n!==e))}onDownload(e){this.isExisting(e)&&this.fileDownload.emit({Id:Number(e.fileId),FileName:e.fileName,ContentType:""})}isExisting(e){return e.listKey?.startsWith("existing-")??!1}addFiles(e){const t=this.maxFileSize(),a=this.maxFiles();let n=a>0?a-this.files().length:e.length;if(!(n<=0))for(const o of e.slice(0,n))t>0&&o.size>t||this.uploadOne(o)}uploadOne(e){const t=`new-${e.name}-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,a={fileId:"",fileName:e.name,sizeBytes:e.size,status:"uploading",listKey:t},n=[...this.files(),a];this.files.set(n),this.onChange(n);const o=this.uploadEndpoint();if(!o){a.status="success",a.fileId=t,this.commit([...this.files()]);return}try{const r=F(o,this.httpSecurity?.allowedOrigins),s=new FormData;s.append("file",e),this.http.post(r,s).subscribe({next:d=>{a.status="success",a.fileId=d.fileId??t,d.fileName&&(a.fileName=d.fileName),this.commit([...this.files()])},error:d=>{a.status="error",a.errorMessage=d?.message??this.errorLabel(),this.commit([...this.files()])}})}catch(r){a.status="error",a.errorMessage=r?.message??this.errorLabel(),this.commit([...this.files()])}}commit(e){this.files.set(e),this.onChange(e),this.onTouched()}writeValue(e){const a=(Array.isArray(e)?e:[]).map(n=>{if("Id"in n&&"FileName"in n){const o=n;return{fileId:String(o.Id),fileName:o.FileName,status:"success",listKey:`existing-${o.Id}`}}return n});this.files.set(a)}registerOnChange(e){this.onChange=e}registerOnTouched(e){this.onTouched=e}setDisabledState(e){this.cvaDisabled.set(e)}static ɵfac=l.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:y,deps:[],target:l.ɵɵFactoryTarget.Component});static ɵcmp=l.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"22.0.7",type:y,isStandalone:!0,selector:"dga-dynamic-form-staged-upload",inputs:{accept:{classPropertyName:"accept",publicName:"accept",isSignal:!0,isRequired:!1,transformFunction:null},maxFileSize:{classPropertyName:"maxFileSize",publicName:"maxFileSize",isSignal:!0,isRequired:!1,transformFunction:null},maxFiles:{classPropertyName:"maxFiles",publicName:"maxFiles",isSignal:!0,isRequired:!1,transformFunction:null},uploadEndpoint:{classPropertyName:"uploadEndpoint",publicName:"uploadEndpoint",isSignal:!0,isRequired:!1,transformFunction:null},deleteEndpoint:{classPropertyName:"deleteEndpoint",publicName:"deleteEndpoint",isSignal:!0,isRequired:!1,transformFunction:null},deleteMethod:{classPropertyName:"deleteMethod",publicName:"deleteMethod",isSignal:!0,isRequired:!1,transformFunction:null},hint:{classPropertyName:"hint",publicName:"hint",isSignal:!0,isRequired:!1,transformFunction:null},browseLabel:{classPropertyName:"browseLabel",publicName:"browseLabel",isSignal:!0,isRequired:!1,transformFunction:null},removeLabel:{classPropertyName:"removeLabel",publicName:"removeLabel",isSignal:!0,isRequired:!1,transformFunction:null},downloadLabel:{classPropertyName:"downloadLabel",publicName:"downloadLabel",isSignal:!0,isRequired:!1,transformFunction:null},uploadingLabel:{classPropertyName:"uploadingLabel",publicName:"uploadingLabel",isSignal:!0,isRequired:!1,transformFunction:null},errorLabel:{classPropertyName:"errorLabel",publicName:"errorLabel",isSignal:!0,isRequired:!1,transformFunction:null},disabledInput:{classPropertyName:"disabledInput",publicName:"disabled",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{fileDownload:"fileDownload"},host:{classAttribute:"block w-full"},providers:[ae(y)],ngImport:l,template:`
2
+ <div class="flex flex-col gap-md">
3
+ <div
4
+ class="flex flex-col items-center justify-center gap-md rounded-lg border border-dashed border-border
5
+ bg-surface px-xl py-3xl text-center"
6
+ [class.opacity-60]="disabled() || atLimit()"
7
+ [class.pointer-events-none]="disabled() || atLimit()"
8
+ (dragover)="onDragOver($event)"
9
+ (dragleave)="dragging.set(false)"
10
+ (drop)="onDrop($event)"
11
+ >
12
+ <p class="text-body-sm text-muted">{{ hint() }}</p>
13
+ <button
14
+ dgaButton
15
+ type="button"
16
+ variant="secondary"
17
+ [disabled]="disabled() || atLimit()"
18
+ (click)="fileInput.click()"
19
+ >
20
+ {{ browseLabel() }}
21
+ </button>
22
+ <input
23
+ #fileInput
24
+ type="file"
25
+ class="sr-only"
26
+ [attr.accept]="accept() || null"
27
+ multiple
28
+ [disabled]="disabled() || atLimit()"
29
+ (change)="onPick($event)"
30
+ />
31
+ @if (maxFiles() > 0) {
32
+ <p class="text-body-xs text-muted">
33
+ {{ files().length }}/{{ maxFiles() }}
34
+ </p>
35
+ }
36
+ </div>
37
+
38
+ @if (files().length) {
39
+ <ul class="flex flex-col gap-sm" role="list">
40
+ @for (file of files(); track file.listKey || file.fileId) {
41
+ <li
42
+ class="flex items-center justify-between gap-md rounded-md border border-border bg-surface px-md py-sm"
43
+ >
44
+ <div class="min-w-0 flex-1">
45
+ <p class="truncate text-body-sm text-fg">{{ file.fileName }}</p>
46
+ @if (file.status === 'uploading') {
47
+ <p class="text-body-xs text-muted">{{ uploadingLabel() }}</p>
48
+ }
49
+ @if (file.status === 'error') {
50
+ <p class="text-body-xs text-error">{{ file.errorMessage || errorLabel() }}</p>
51
+ }
52
+ </div>
53
+ <div class="flex shrink-0 items-center gap-sm">
54
+ @if (file.status === 'success' && isExisting(file)) {
55
+ <button
56
+ type="button"
57
+ class="inline-flex size-4xl items-center justify-center rounded-sm text-muted hover:text-fg"
58
+ [attr.aria-label]="downloadLabel() + ': ' + file.fileName"
59
+ (click)="onDownload(file)"
60
+ >
61
+ <dga-icon name="download" size="sm" tone="current" />
62
+ </button>
63
+ }
64
+ <button
65
+ type="button"
66
+ class="inline-flex size-4xl items-center justify-center rounded-sm text-muted hover:text-fg"
67
+ [attr.aria-label]="removeLabel() + ': ' + file.fileName"
68
+ [disabled]="disabled() || file.status === 'uploading'"
69
+ (click)="remove(file)"
70
+ >
71
+ <dga-icon name="close" size="sm" tone="current" />
72
+ </button>
73
+ </div>
74
+ </li>
75
+ }
76
+ </ul>
77
+ }
78
+ </div>
79
+ `,isInline:!0,dependencies:[{kind:"directive",type:A,selector:"button[dgaButton], a[dgaButton]",inputs:["variant","size","iconOnly","cooldownMs","loading","dgaButtonClass"]},{kind:"component",type:te,selector:"dga-icon",inputs:["name","glyph","size","tone","label"]}],changeDetection:l.ChangeDetectionStrategy.OnPush})}l.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:y,decorators:[{type:R,args:[{selector:"dga-dynamic-form-staged-upload",standalone:!0,imports:[A,te],template:`
80
+ <div class="flex flex-col gap-md">
81
+ <div
82
+ class="flex flex-col items-center justify-center gap-md rounded-lg border border-dashed border-border
83
+ bg-surface px-xl py-3xl text-center"
84
+ [class.opacity-60]="disabled() || atLimit()"
85
+ [class.pointer-events-none]="disabled() || atLimit()"
86
+ (dragover)="onDragOver($event)"
87
+ (dragleave)="dragging.set(false)"
88
+ (drop)="onDrop($event)"
89
+ >
90
+ <p class="text-body-sm text-muted">{{ hint() }}</p>
91
+ <button
92
+ dgaButton
93
+ type="button"
94
+ variant="secondary"
95
+ [disabled]="disabled() || atLimit()"
96
+ (click)="fileInput.click()"
97
+ >
98
+ {{ browseLabel() }}
99
+ </button>
100
+ <input
101
+ #fileInput
102
+ type="file"
103
+ class="sr-only"
104
+ [attr.accept]="accept() || null"
105
+ multiple
106
+ [disabled]="disabled() || atLimit()"
107
+ (change)="onPick($event)"
108
+ />
109
+ @if (maxFiles() > 0) {
110
+ <p class="text-body-xs text-muted">
111
+ {{ files().length }}/{{ maxFiles() }}
112
+ </p>
113
+ }
114
+ </div>
115
+
116
+ @if (files().length) {
117
+ <ul class="flex flex-col gap-sm" role="list">
118
+ @for (file of files(); track file.listKey || file.fileId) {
119
+ <li
120
+ class="flex items-center justify-between gap-md rounded-md border border-border bg-surface px-md py-sm"
121
+ >
122
+ <div class="min-w-0 flex-1">
123
+ <p class="truncate text-body-sm text-fg">{{ file.fileName }}</p>
124
+ @if (file.status === 'uploading') {
125
+ <p class="text-body-xs text-muted">{{ uploadingLabel() }}</p>
126
+ }
127
+ @if (file.status === 'error') {
128
+ <p class="text-body-xs text-error">{{ file.errorMessage || errorLabel() }}</p>
129
+ }
130
+ </div>
131
+ <div class="flex shrink-0 items-center gap-sm">
132
+ @if (file.status === 'success' && isExisting(file)) {
133
+ <button
134
+ type="button"
135
+ class="inline-flex size-4xl items-center justify-center rounded-sm text-muted hover:text-fg"
136
+ [attr.aria-label]="downloadLabel() + ': ' + file.fileName"
137
+ (click)="onDownload(file)"
138
+ >
139
+ <dga-icon name="download" size="sm" tone="current" />
140
+ </button>
141
+ }
142
+ <button
143
+ type="button"
144
+ class="inline-flex size-4xl items-center justify-center rounded-sm text-muted hover:text-fg"
145
+ [attr.aria-label]="removeLabel() + ': ' + file.fileName"
146
+ [disabled]="disabled() || file.status === 'uploading'"
147
+ (click)="remove(file)"
148
+ >
149
+ <dga-icon name="close" size="sm" tone="current" />
150
+ </button>
151
+ </div>
152
+ </li>
153
+ }
154
+ </ul>
155
+ }
156
+ </div>
157
+ `,changeDetection:V.OnPush,host:{class:"block w-full"},providers:[ae(y)]}]}],propDecorators:{accept:[{type:l.Input,args:[{isSignal:!0,alias:"accept",required:!1}]}],maxFileSize:[{type:l.Input,args:[{isSignal:!0,alias:"maxFileSize",required:!1}]}],maxFiles:[{type:l.Input,args:[{isSignal:!0,alias:"maxFiles",required:!1}]}],uploadEndpoint:[{type:l.Input,args:[{isSignal:!0,alias:"uploadEndpoint",required:!1}]}],deleteEndpoint:[{type:l.Input,args:[{isSignal:!0,alias:"deleteEndpoint",required:!1}]}],deleteMethod:[{type:l.Input,args:[{isSignal:!0,alias:"deleteMethod",required:!1}]}],hint:[{type:l.Input,args:[{isSignal:!0,alias:"hint",required:!1}]}],browseLabel:[{type:l.Input,args:[{isSignal:!0,alias:"browseLabel",required:!1}]}],removeLabel:[{type:l.Input,args:[{isSignal:!0,alias:"removeLabel",required:!1}]}],downloadLabel:[{type:l.Input,args:[{isSignal:!0,alias:"downloadLabel",required:!1}]}],uploadingLabel:[{type:l.Input,args:[{isSignal:!0,alias:"uploadingLabel",required:!1}]}],errorLabel:[{type:l.Input,args:[{isSignal:!0,alias:"errorLabel",required:!1}]}],disabledInput:[{type:l.Input,args:[{isSignal:!0,alias:"disabled",required:!1}]}],fileDownload:[{type:l.Output,args:["fileDownload"]}]}});class w{field=u.required(...ngDevMode?[{debugName:"field"}]:[]);form=u.required(...ngDevMode?[{debugName:"form"}]:[]);locale=u("ar",...ngDevMode?[{debugName:"locale"}]:[]);required=u(!1,{...ngDevMode?{debugName:"required"}:{},transform:J});error=u("",...ngDevMode?[{debugName:"error"}]:[]);runtimeOptions=u([],...ngDevMode?[{debugName:"runtimeOptions"}]:[]);consentBaseUrl=u(...ngDevMode?[void 0,{debugName:"consentBaseUrl"}]:[]);optionsLoaded=g();fileDownload=g();lookup=c(z,{optional:!0});http=c(I,{optional:!0});destroyRef=c(Q);loadedOptions=m([],...ngDevMode?[{debugName:"loadedOptions"}]:[]);controlId=`dga-df-${Math.random().toString(36).slice(2,9)}`;get control(){return this.form().controls[this.field().name]}labelText=p(()=>v(this.field().label,this.locale()),...ngDevMode?[{debugName:"labelText"}]:[]);hintText=p(()=>v(this.field().hint,this.locale()),...ngDevMode?[{debugName:"hintText"}]:[]);placeholderText=p(()=>v(this.field().placeholder,this.locale()),...ngDevMode?[{debugName:"placeholderText"}]:[]);resolvedOptions=p(()=>{const e=this.runtimeOptions();if(e.length)return e;const t=this.loadedOptions();return t.length?t:this.field().options??[]},...ngDevMode?[{debugName:"resolvedOptions"}]:[]);selectOptions=p(()=>this.resolvedOptions().map(e=>({value:String(e.value),label:this.optionLabel(e),disabled:!!e.disabled})),...ngDevMode?[{debugName:"selectOptions"}]:[]);ngOnInit(){const e=this.field();if(this.mapExistingFileValue(),e.consentServiceName&&this.consentBaseUrl()&&this.http&&this.fetchConsent(e),e.lookupDomain&&e.lookupName&&this.lookup){if(e.dependsOn&&e.useParentId!==!1){const t=this.form().get(e.dependsOn);if(t){t.valueChanges.pipe(Ke(t.value),T(this.destroyRef)).subscribe(a=>this.fetchLookup(e,a));return}}e.searchLookup||this.fetchLookup(e)}}mapExistingFileValue(){const e=this.field();if(e.type!=="file"&&e.type!=="multifile")return;const t=this.control.value;if(!Array.isArray(t)||!t.length)return;const a=t[0];if(!a||!("Id"in a)||!("FileName"in a))return;const n=t.map(o=>({id:String(o.Id),name:o.FileName,size:0}));this.control.setValue(n,{emitEvent:!1})}fetchConsent(e){const a=`${this.consentBaseUrl().replace(/\/$/,"")}/consents/${encodeURIComponent(e.consentServiceName)}`;this.http.get(a).pipe(We(()=>D(null)),T(this.destroyRef)).subscribe(n=>{if(!n?.Content)return;const o={en:n.Content.En||n.Content.Ar||"",ar:n.Content.Ar||n.Content.En||""};if(e.type==="checkbox"){const r=e.options?.length?[...e.options]:[{value:!0,label:{en:"",ar:""}}];r[0]={...r[0],label:o},this.loadedOptions.set(r),this.optionsLoaded.emit({name:e.name,options:r})}})}fetchLookup(e,t,a){if(!this.lookup||!e.lookupDomain||!e.lookupName)return;const n=e.minSearchLength??(e.searchLookup?3:0);a!=null&&a.length<n||this.lookup.lookup({domain:e.lookupDomain,name:e.lookupName,parentId:e.useParentId!==!1&&t!=null&&t!==""?t:void 0,search:a||void 0,searchParamName:e.searchParamName}).pipe(T(this.destroyRef)).subscribe(o=>{const r=this.applyLookupFilter(o);this.loadedOptions.set(r),this.optionsLoaded.emit({name:e.name,options:r})})}optionLabel(e){return v(e.label,this.locale())}isPasswordField(){const e=this.field().name;return e==="password"||e==="confirmPassword"}isChecked(e){const t=this.control?.value;return Array.isArray(t)&&t.some(a=>a==e)}toggleCheckbox(e,t){const a=Array.isArray(this.control.value)?[...this.control.value]:[],n=t?a.some(o=>o==e)?a:[...a,e]:a.filter(o=>o!=e);this.control.setValue(n),this.control.markAsDirty()}onSelectSearchQuery(e){const t=this.field();t.searchLookup&&this.fetchLookup(t,this.form().get(t.dependsOn??"")?.value,e)}onStagedFileDownload(e){this.fileDownload.emit(e)}onRestrict(e){const t=this.field().inputRestriction;if(!t)return;const a=e.target;let n=a.value;t==="numbers"&&(n=n.replace(/\D+/g,"")),t==="english"&&(n=n.replace(/[^a-zA-Z0-9\s.,\-_/]/g,"")),t==="arabic"&&(n=n.replace(/[^\u0600-\u06FF0-9\s.,\-_/]/g,"")),n!==a.value&&(a.value=n,this.control.setValue(n))}applyLookupFilter(e){const t=this.field().lookupFilter;return t?e.filter(a=>a[t.property]===t.value):e}static ɵfac=l.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:w,deps:[],target:l.ɵɵFactoryTarget.Component});static ɵcmp=l.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"22.0.7",type:w,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},consentBaseUrl:{classPropertyName:"consentBaseUrl",publicName:"consentBaseUrl",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{optionsLoaded:"optionsLoaded",fileDownload:"fileDownload"},host:{properties:{"class.hidden":'field().type === "hidden"'},classAttribute:"block w-full"},ngImport:l,template:`
2
158
  @if (field().type !== 'hidden') {
3
159
  <dga-field
4
160
  [label]="labelText()"
@@ -51,6 +207,7 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
51
207
  [disabled]="!!field().disabled"
52
208
  [required]="required()"
53
209
  [controlId]="controlId"
210
+ [locale]="locale()"
54
211
  />
55
212
  }
56
213
  @case ('date') {
@@ -72,6 +229,7 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
72
229
  [dgaInvalid]="!!error()"
73
230
  [disabled]="!!field().disabled"
74
231
  [label]="labelText()"
232
+ [allowDuplicates]="field().allowDuplicates ?? false"
75
233
  />
76
234
  }
77
235
  @case ('toggle') {
@@ -91,16 +249,40 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
91
249
  [disabled]="!!field().disabled"
92
250
  />
93
251
  }
252
+ @case ('multifile') {
253
+ <dga-upload
254
+ [formControl]="control"
255
+ [accept]="field().acceptedFileTypes || ''"
256
+ multiple
257
+ [maxFiles]="field().maxFiles || 0"
258
+ [maxSize]="field().maxFileSize || 0"
259
+ [disabled]="!!field().disabled"
260
+ />
261
+ }
262
+ @case ('multifilestaged') {
263
+ <dga-dynamic-form-staged-upload
264
+ [formControl]="control"
265
+ [accept]="field().acceptedFileTypes || ''"
266
+ [maxFileSize]="field().maxFileSize || 0"
267
+ [maxFiles]="field().maxFiles || 0"
268
+ [uploadEndpoint]="field().uploadEndpoint || ''"
269
+ [deleteEndpoint]="field().deleteEndpoint || ''"
270
+ [deleteMethod]="field().deleteMethod || 'DELETE'"
271
+ [disabled]="!!field().disabled"
272
+ (fileDownload)="onStagedFileDownload($event)"
273
+ />
274
+ }
94
275
  @case ('select') {
95
276
  <dga-select
96
277
  [formControl]="control"
97
278
  [options]="selectOptions()"
98
279
  [searchable]="!!field().searchLookup || (selectOptions().length > 8)"
280
+ [openMode]="field().alwaysOpen ? 'always' : 'dropdown'"
99
281
  [placeholder]="placeholderText()"
100
282
  [label]="labelText()"
101
283
  [dgaInvalid]="!!error()"
102
284
  [disabled]="!!field().disabled"
103
- (valueChange)="onSelectSearch($event)"
285
+ (searchChange)="onSelectSearchQuery($event)"
104
286
  />
105
287
  }
106
288
  @case ('multiselect') {
@@ -157,10 +339,23 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
157
339
  }
158
340
  </div>
159
341
  }
342
+ @case ('password') {
343
+ <input
344
+ dgaInput
345
+ type="password"
346
+ [id]="controlId"
347
+ [attr.placeholder]="placeholderText()"
348
+ [attr.maxlength]="field().maxLength || null"
349
+ [readonly]="field().readonly || null"
350
+ [formControl]="control"
351
+ [dgaInvalid]="!!error()"
352
+ autocomplete="new-password"
353
+ />
354
+ }
160
355
  @default {
161
356
  <input
162
357
  dgaInput
163
- type="text"
358
+ [attr.type]="isPasswordField() ? 'password' : 'text'"
164
359
  [id]="controlId"
165
360
  [attr.placeholder]="placeholderText()"
166
361
  [attr.maxlength]="field().maxLength || null"
@@ -173,7 +368,7 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
173
368
  }
174
369
  </dga-field>
175
370
  }
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:`
371
+ `,isInline:!0,dependencies:[{kind:"ngmodule",type:O},{kind:"directive",type:h.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:h.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:h.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:h.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:h.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"ngmodule",type:Z},{kind:"component",type:ie,selector:"dga-field",inputs:["label","labelHint","hint","error","status","statusMessage","controlId","required"]},{kind:"directive",type:ne,selector:"input[dgaInput], textarea[dgaInput]",inputs:["size","dgaInvalid","status"]},{kind:"component",type:oe,selector:"dga-select",inputs:["options","value","multiple","searchable","openMode","clearable","size","status","placeholder","label","removeLabel","clearLabel","emptyLabel","disabled","dgaInvalid"],outputs:["valueChange","searchChange"]},{kind:"directive",type:re,selector:'input[type="checkbox"][dgaCheckbox]',inputs:["size","dgaInvalid"]},{kind:"directive",type:le,selector:'input[type="radio"][dgaRadio]',inputs:["size","dgaInvalid"]},{kind:"component",type:se,selector:"dga-phone-input",inputs:["countries","locale","countryCode","nationalNumber","controlId","name","placeholder","autocomplete","codeLabel","disabled","required","invalid","value"],outputs:["countryCodeChange","nationalNumberChange","valueChange"]},{kind:"component",type:he,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:de,selector:"dga-chip-input",inputs:["value","placeholder","label","removeLabel","disabled","allowDuplicates","dgaInvalid","status"],outputs:["valueChange"]},{kind:"component",type:ue,selector:"dga-switch",inputs:["checked","size","label","disabled"],outputs:["checkedChange","changed"]},{kind:"component",type:ce,selector:"dga-upload",inputs:["files","accept","multiple","appearance","hint","browseLabel","removeLabel","disabled","maxSize","maxFiles","dragging"],outputs:["filesChange","rejected","draggingChange"]},{kind:"component",type:pe,selector:"dga-number-input",inputs:["value","min","max","step","size","label","controlId","name","incrementLabel","decrementLabel","disabled","dgaInvalid","status"],outputs:["valueChange"]},{kind:"component",type:fe,selector:"dga-otp",inputs:["length","value","label","alphanumeric","disabled","dgaInvalid"],outputs:["valueChange","completed"]},{kind:"component",type:y,selector:"dga-dynamic-form-staged-upload",inputs:["accept","maxFileSize","maxFiles","uploadEndpoint","deleteEndpoint","deleteMethod","hint","browseLabel","removeLabel","downloadLabel","uploadingLabel","errorLabel","disabled"],outputs:["fileDownload"]}],changeDetection:l.ChangeDetectionStrategy.OnPush})}l.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:w,decorators:[{type:R,args:[{selector:"dga-dynamic-form-field",standalone:!0,imports:[O,Z,ie,ne,oe,re,le,se,he,de,ue,ce,pe,fe,y],template:`
177
372
  @if (field().type !== 'hidden') {
178
373
  <dga-field
179
374
  [label]="labelText()"
@@ -226,6 +421,7 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
226
421
  [disabled]="!!field().disabled"
227
422
  [required]="required()"
228
423
  [controlId]="controlId"
424
+ [locale]="locale()"
229
425
  />
230
426
  }
231
427
  @case ('date') {
@@ -247,6 +443,7 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
247
443
  [dgaInvalid]="!!error()"
248
444
  [disabled]="!!field().disabled"
249
445
  [label]="labelText()"
446
+ [allowDuplicates]="field().allowDuplicates ?? false"
250
447
  />
251
448
  }
252
449
  @case ('toggle') {
@@ -266,16 +463,40 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
266
463
  [disabled]="!!field().disabled"
267
464
  />
268
465
  }
466
+ @case ('multifile') {
467
+ <dga-upload
468
+ [formControl]="control"
469
+ [accept]="field().acceptedFileTypes || ''"
470
+ multiple
471
+ [maxFiles]="field().maxFiles || 0"
472
+ [maxSize]="field().maxFileSize || 0"
473
+ [disabled]="!!field().disabled"
474
+ />
475
+ }
476
+ @case ('multifilestaged') {
477
+ <dga-dynamic-form-staged-upload
478
+ [formControl]="control"
479
+ [accept]="field().acceptedFileTypes || ''"
480
+ [maxFileSize]="field().maxFileSize || 0"
481
+ [maxFiles]="field().maxFiles || 0"
482
+ [uploadEndpoint]="field().uploadEndpoint || ''"
483
+ [deleteEndpoint]="field().deleteEndpoint || ''"
484
+ [deleteMethod]="field().deleteMethod || 'DELETE'"
485
+ [disabled]="!!field().disabled"
486
+ (fileDownload)="onStagedFileDownload($event)"
487
+ />
488
+ }
269
489
  @case ('select') {
270
490
  <dga-select
271
491
  [formControl]="control"
272
492
  [options]="selectOptions()"
273
493
  [searchable]="!!field().searchLookup || (selectOptions().length > 8)"
494
+ [openMode]="field().alwaysOpen ? 'always' : 'dropdown'"
274
495
  [placeholder]="placeholderText()"
275
496
  [label]="labelText()"
276
497
  [dgaInvalid]="!!error()"
277
498
  [disabled]="!!field().disabled"
278
- (valueChange)="onSelectSearch($event)"
499
+ (searchChange)="onSelectSearchQuery($event)"
279
500
  />
280
501
  }
281
502
  @case ('multiselect') {
@@ -332,10 +553,23 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
332
553
  }
333
554
  </div>
334
555
  }
556
+ @case ('password') {
557
+ <input
558
+ dgaInput
559
+ type="password"
560
+ [id]="controlId"
561
+ [attr.placeholder]="placeholderText()"
562
+ [attr.maxlength]="field().maxLength || null"
563
+ [readonly]="field().readonly || null"
564
+ [formControl]="control"
565
+ [dgaInvalid]="!!error()"
566
+ autocomplete="new-password"
567
+ />
568
+ }
335
569
  @default {
336
570
  <input
337
571
  dgaInput
338
- type="text"
572
+ [attr.type]="isPasswordField() ? 'password' : 'text'"
339
573
  [id]="controlId"
340
574
  [attr.placeholder]="placeholderText()"
341
575
  [attr.maxlength]="field().maxLength || null"
@@ -348,7 +582,7 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
348
582
  }
349
583
  </dga-field>
350
584
  }
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:`
585
+ `,changeDetection:V.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}]}],consentBaseUrl:[{type:l.Input,args:[{isSignal:!0,alias:"consentBaseUrl",required:!1}]}],optionsLoaded:[{type:l.Output,args:["optionsLoaded"]}],fileDownload:[{type:l.Output,args:["fileDownload"]}]}});const ct={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"},pt={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"},ft={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 H(i){return Number.isFinite(i)?Math.min(12,Math.max(1,Math.round(i))):12}class N{config=u.required(...ngDevMode?[{debugName:"config"}]:[]);localeInput=u(null,{...ngDevMode?{debugName:"localeInput"}:{},alias:"locale"});formSubmitted=g();formError=g();clearButtonClick=g();draftSaved=g();fileDownload=g();fb=c(_e);formService=c(C);submitAdapter=c(E,{optional:!0});toast=c(B,{optional:!0});i18n=c(U,{optional:!0});destroyRef=c(Q);registry=c(L);form;formSignature="";valueChangesSub=null;activeStep=m(0,...ngDevMode?[{debugName:"activeStep"}]:[]);submitting=m(!1,...ngDevMode?[{debugName:"submitting"}]:[]);optionsMap=m({},...ngDevMode?[{debugName:"optionsMap"}]:[]);formValues=m({},...ngDevMode?[{debugName:"formValues"}]:[]);locale=p(()=>this.localeInput()??Te(),...ngDevMode?[{debugName:"locale"}]:[]);wizardEnabled=p(()=>!!this.config().wizard?.enabled&&!!this.config().wizard?.steps?.length,...ngDevMode?[{debugName:"wizardEnabled"}]:[]);allFields=p(()=>Le(this.config().fields,this.config().wizard?.steps),...ngDevMode?[{debugName:"allFields"}]:[]);currentStepFields=p(()=>this.wizardEnabled()?this.config().wizard.steps[this.activeStep()]?.fields??[]:this.config().fields,...ngDevMode?[{debugName:"currentStepFields"}]:[]);visibleFields=p(()=>{const e=this.formValues(),t=this.optionsMap(),a=this.allFields(),n=o=>a.find(r=>r.name===o);return this.currentStepFields().filter(o=>K(o,e,r=>t[r],n))},...ngDevMode?[{debugName:"visibleFields"}]:[]);stepperSteps=p(()=>{const e=this.config().wizard?.steps??[],t=this.activeStep(),a=!!this.config().wizard?.allowSkipSteps;return e.map((n,o)=>({label:this.labelOf(n.title),description:n.description?this.labelOf(n.description):void 0,disabled:!a&&o>t}))},...ngDevMode?[{debugName:"stepperSteps"}]:[]);descriptionText=p(()=>this.labelOf(this.config().description),...ngDevMode?[{debugName:"descriptionText"}]:[]);constructor(){this.form=this.fb.group({}),this.destroyRef.onDestroy(()=>this.valueChangesSub?.unsubscribe()),k(()=>{const e=this.allFields(),t=e.map(n=>`${n.name}:${n.type}`).join("|"),a=this.config();q(()=>{if(t===this.formSignature)return;const n=Object.keys(this.form.controls).length?this.form.getRawValue():null,o=this.formSignature==="";this.formSignature=t;const r=Ce(this.fb,e);if(n)r.patchValue(n,{emitEvent:!1});else if(o&&a.formId&&a.enableLocalStorageSave){const f=this.formService.loadDraft(a.formId);f&&r.patchValue(f,{emitEvent:!1})}this.form=r,De(r,e);const s=r.get("password"),d=r.get("confirmPassword");s&&d&&s.valueChanges.pipe(T(this.destroyRef)).subscribe(()=>d.updateValueAndValidity({emitEvent:!1})),o||this.activeStep.set(0),this.formValues.set(r.getRawValue()),this.valueChangesSub?.unsubscribe(),this.valueChangesSub=r.valueChanges.pipe(Ge(r.getRawValue())).subscribe(f=>this.formValues.set(f))})}),k(()=>{const e=this.formValues(),t=this.optionsMap();if(this.form)for(const a of this.allFields()){const n=this.form.get(a.name);if(!n||!a.requiredWhen)continue;const o=this.allFields(),s=W(a,e,d=>t[d],d=>o.find(f=>f.name===d));Fe(n,a,s)}}),k(()=>{const e=this.allFields();q(()=>{if(!this.form)return;const t={};for(const a of e)a.value!==void 0&&(t[a.name]=a.value);Object.keys(t).length&&this.form.patchValue(t,{emitEvent:!1})})}),k(()=>{const e=this.activeStep(),t=this.config().wizard;q(()=>{!t?.steps?.[e]?.initialData||!this.form||this.form.patchValue(t.steps[e].initialData,{emitEvent:!1})})})}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":"إرسال"):this.labelOf(e.submitButtonLabel)||(this.locale()==="en"?"Submit":"إرسال")}nextLabel(){return this.labelOf(this.config().wizard?.nextButtonText)||(this.locale()==="en"?"Next":"التالي")}previousLabel(){return this.labelOf(this.config().wizard?.previousButtonText)||(this.locale()==="en"?"Previous":"السابق")}clearLabel(){return this.labelOf(this.config().clearButtonLabel)}saveLabel(){return this.labelOf(this.config().saveButtonLabel??this.config().wizard?.saveButtonText)||(this.locale()==="en"?"Save":"حفظ")}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){const t=this.allFields(),a=n=>t.find(o=>o.name===n);return W(e,this.formValues(),n=>this.optionsMap()[n],a)}fieldError(e){const t=this.form?.get(e.name);if(!t||!(t.touched||t.dirty)||!t.errors)return"";const a=t.errors,n=e.validation?.errorMessages,o=this.locale(),r=s=>n?.[s]?this.labelOf(n[s]):"";return a.required?r("required")||(o==="en"?"Required":"مطلوب"):a.email?r("email")||(o==="en"?"Invalid email":"بريد غير صالح"):a.minlength?r("minLength")||(o==="en"?"Too short":"قصير جداً"):a.maxlength?r("maxLength")||(o==="en"?"Too long":"طويل جداً"):a.pattern?r("pattern")||(o==="en"?"Invalid format":"صيغة غير صالحة"):a.maxChips?r("maxChips")||(o==="en"?"Too many items":"عدد العناصر كبير"):a.invalidFormat?r("invalidFormat")||(o==="en"?"Invalid format":"صيغة غير صالحة"):a.invalidPrefix?r("invalidPrefix")||(o==="en"?"Invalid prefix":"بادئة غير صالحة"):a.invalidLength?r("invalidLength")||(o==="en"?"Invalid length":"طول غير صالح"):a.passwordMismatch?r("passwordMismatch")||(o==="en"?"Passwords do not match":"كلمات المرور غير متطابقة"):a.endDateAfterStartDate?r("endDateAfterStartDate")||(o==="en"?"End date must be after start date":"تاريخ النهاية يجب أن يكون بعد تاريخ البداية"):a.uploadInProgress?r("uploadInProgress")||(o==="en"?"Upload in progress":"جاري رفع الملفات"):a.maxFiles?r("maxFiles")||(o==="en"?"Too many files":"عدد الملفات كبير"):a.minDate?r("minDate")||(o==="en"?"Date is too early":"التاريخ مبكر جداً"):a.maxDate?r("maxDate")||(o==="en"?"Date is too late":"التاريخ متأخر جداً"):o==="en"?"Invalid":"غير صالح"}columnClass(e){const t=e.columns,a=H(t?.sm??t?.md??12),n=H(t?.md??a),o=H(t?.lg??n);return["w-full",ct[a],pt[n],ft[o]].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 a=this.config().wizard;return!a?.allowSkipSteps&&e>t+1?!1:a?.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),this.skipEmptyStepsForward())}skipEmptyStepsForward(){const e=this.config().wizard;if(e?.steps)for(;this.activeStep()<e.steps.length-1&&this.visibleFields().length===0;)this.activeStep.update(t=>t+1)}onClear(){this.form.reset();for(const t of this.allFields()){const a=this.form.get(t.name);a&&a.setValue(t.value!==void 0?t.value:["checkbox","multiselect","chips","file","multifile","multifilestaged"].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(),a=t.formId;a&&this.formService.saveDraft(a,e,this.allFields());const n=t.wizard;if(n?.autoSave&&n.saveEndpoint&&this.submitAdapter){const o=this.formService.buildPayload(t,e,this.allFields());this.submitAdapter.submit({endpoint:n.saveEndpoint,method:n.saveMethod??"POST",body:o}).subscribe({error:r=>this.formError.emit(r)})}this.draftSaved.emit(e),this.toast?.show({variant:"success",message:this.locale()==="en"?"Draft saved":"تم حفظ المسودة"})}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":"يرجى تصحيح الحقول المحددة"});return}const e=this.config(),t=this.form.getRawValue(),a=new Set(this.collectVisibleFieldNames()),n={};for(const o of this.allFields())!a.has(o.name)&&o.type!=="hidden"||(n[o.name]=t[o.name]);if(e.emitOnly||!e.endpoint){this.formSubmitted.emit(n),this.toast?.show({variant:"success",message:this.labelOf(e.successMessage)||(this.locale()==="en"?"Submitted":"تم الإرسال")});return}this.submitting.set(!0),this.formService.submitForm(e,n,this.allFields()).subscribe({next:o=>{this.submitting.set(!1),this.formSubmitted.emit(o),e.formId&&this.formService.clearDraft(e.formId),this.toast?.show({variant:"success",message:this.labelOf(e.successMessage)||(this.locale()==="en"?"Submitted successfully":"تم الإرسال بنجاح")})},error:o=>{this.submitting.set(!1),this.formError.emit(o),this.toast?.show({variant:"error",message:this.labelOf(e.errorMessage)||(this.locale()==="en"?"Submission failed":"فشل الإرسال")})}})}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.config().wizard?.steps[this.activeStep()]?.optional?!0:this.visibleFields().every(t=>{const a=this.form.get(t.name);return!a||a.disabled||a.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(),a=this.wizardEnabled()?this.allFields():this.config().fields,n=o=>a.find(r=>r.name===o);return a.filter(o=>o.type==="hidden"||K(o,e,r=>t[r],n)).map(o=>o.name)}static ɵfac=l.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:N,deps:[],target:l.ɵɵFactoryTarget.Component});static ɵcmp=l.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"22.0.7",type:N,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",fileDownload:"fileDownload"},host:{classAttribute:"block w-full"},ngImport:l,template:`
352
586
  <form class="flex w-full flex-col gap-3xl" [formGroup]="form" (ngSubmit)="onSubmit()">
353
587
  @if (descriptionText()) {
354
588
  <p class="text-body-md text-paragraph">{{ descriptionText() }}</p>
@@ -359,7 +593,7 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
359
593
  [steps]="stepperSteps()"
360
594
  [(active)]="activeStep"
361
595
  [beforeActiveChange]="canActivateStep"
362
- [label]="locale() === 'en' ? 'Steps' : '\u0627\u0644\u062E\u0637\u0648\u0627\u062A'"
596
+ [label]="locale() === 'en' ? 'Steps' : 'الخطوات'"
363
597
  />
364
598
  }
365
599
 
@@ -376,7 +610,9 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
376
610
  [required]="isRequired(field)"
377
611
  [error]="fieldError(field)"
378
612
  [runtimeOptions]="optionsMap()[field.name] || []"
613
+ [consentBaseUrl]="config().consentBaseUrl"
379
614
  (optionsLoaded)="onOptionsLoaded($event)"
615
+ (fileDownload)="fileDownload.emit($event)"
380
616
  />
381
617
  }
382
618
  </div>
@@ -428,7 +664,7 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
428
664
  }
429
665
  </div>
430
666
  </form>
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:`
667
+ `,isInline:!0,dependencies:[{kind:"ngmodule",type:O},{kind:"directive",type:h.ɵNgNoValidate,selector:"form:not([ngNoForm]):not([ngNativeValidate])"},{kind:"directive",type:h.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:h.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"component",type:w,selector:"dga-dynamic-form-field",inputs:["field","form","locale","required","error","runtimeOptions","consentBaseUrl"],outputs:["optionsLoaded","fileDownload"]},{kind:"directive",type:A,selector:"button[dgaButton], a[dgaButton]",inputs:["variant","size","iconOnly","cooldownMs","loading","dgaButtonClass"]},{kind:"component",type:me,selector:"dga-stepper",inputs:["steps","active","label","beforeActiveChange"],outputs:["activeChange"]},{kind:"directive",type:X,selector:"[ngComponentOutlet]",inputs:["ngComponentOutlet","ngComponentOutletInputs","ngComponentOutletInjector","ngComponentOutletEnvironmentInjector","ngComponentOutletContent","ngComponentOutletNgModule"],exportAs:["ngComponentOutlet"]}],changeDetection:l.ChangeDetectionStrategy.OnPush})}l.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.0.7",ngImport:l,type:N,decorators:[{type:R,args:[{selector:"dga-dynamic-form",standalone:!0,imports:[O,w,A,me,X],template:`
432
668
  <form class="flex w-full flex-col gap-3xl" [formGroup]="form" (ngSubmit)="onSubmit()">
433
669
  @if (descriptionText()) {
434
670
  <p class="text-body-md text-paragraph">{{ descriptionText() }}</p>
@@ -439,7 +675,7 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
439
675
  [steps]="stepperSteps()"
440
676
  [(active)]="activeStep"
441
677
  [beforeActiveChange]="canActivateStep"
442
- [label]="locale() === 'en' ? 'Steps' : '\u0627\u0644\u062E\u0637\u0648\u0627\u062A'"
678
+ [label]="locale() === 'en' ? 'Steps' : 'الخطوات'"
443
679
  />
444
680
  }
445
681
 
@@ -456,7 +692,9 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
456
692
  [required]="isRequired(field)"
457
693
  [error]="fieldError(field)"
458
694
  [runtimeOptions]="optionsMap()[field.name] || []"
695
+ [consentBaseUrl]="config().consentBaseUrl"
459
696
  (optionsLoaded)="onOptionsLoaded($event)"
697
+ (fileDownload)="fileDownload.emit($event)"
460
698
  />
461
699
  }
462
700
  </div>
@@ -508,4 +746,4 @@ import*as l from"@angular/core";import{InjectionToken as h,inject as s,Injectabl
508
746
  }
509
747
  </div>
510
748
  </form>
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};
749
+ `,changeDetection:V.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"]}],fileDownload:[{type:l.Output,args:["fileDownload"]}]}});export{_ as DGA_CAPTCHA_ADAPTER,ve as DGA_DATE_RANGE_PAIRS,be as DGA_DYNAMIC_FORM_FIELD_REGISTRY,U as DGA_FORM_I18N_ADAPTER,B as DGA_FORM_TOAST_ADAPTER,$ as DGA_HTTP_SECURITY,z as DGA_LOOKUP_ADAPTER,E as DGA_SUBMIT_ADAPTER,N as DgaDynamicForm,w as DgaDynamicFormField,L as DgaDynamicFormFieldRegistry,C as DgaDynamicFormService,Re as createDgaToastAdapter,Pe as createHttpLookupAdapter,Ve as createHttpSubmitAdapter,Ae as defaultFormI18nAdapter,De as dgaApplyCrossFieldValidators,F as dgaAssertSafeHttpUrl,Ce as dgaBuildFormGroup,G as dgaBuildValidators,Le as dgaCollectFields,Ie as dgaCreateControl,Se as dgaDefaultValueForField,Te as dgaDetectLocale,ke as dgaFindSelectedOption,K as dgaIsFieldVisible,W as dgaIsRequiredWhen,ye as dgaPasswordMatchValidator,v as dgaResolveLabel,xe as dgaSaudiMobileValidator,Fe as dgaSetControlValidators,Me as emptyLookupAdapter,Ee as noopCaptchaAdapter,dt as provideDgaDynamicForm,ut as resolveFormLabel};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@a.nemreen/dga-dynamic-form",
3
- "version": "0.1.7",
4
- "description": "Schema-driven dynamic forms for Angular, rendered with @a.nemreen/dga-ui controls",
3
+ "version": "0.1.9",
4
+ "description": "Schema-driven Angular dynamic forms 18 field types, wizard, cross-field validators (password, Saudi phone, date range), staged uploads, lookup, reCAPTCHA v3, and conditional visibility. Built on @a.nemreen/dga-ui.",
5
5
  "license": "MIT",
6
6
  "author": {
7
7
  "name": "Ahmed Nemreen",
@@ -22,6 +22,10 @@
22
22
  "dynamic-form",
23
23
  "schema-form",
24
24
  "reactive-forms",
25
+ "wizard",
26
+ "validators",
27
+ "file-upload",
28
+ "recaptcha",
25
29
  "dga",
26
30
  "design-system",
27
31
  "rtl",