@a.nemreen/dga-dynamic-form 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -241,7 +241,7 @@ Fields named `password` or `confirmPassword` with `type: 'text'` are rendered as
|
|
|
241
241
|
| `searchParamName` | Query param (default `q`). |
|
|
242
242
|
| `minSearchLength` | Min chars before search (default `3` when `searchLookup`). |
|
|
243
243
|
|
|
244
|
-
HTTP adapter maps `Id/Title`, `Code/Name`, and `{UserName,Email,DisplayName}` shapes.
|
|
244
|
+
HTTP adapter maps `Id/Title`, `Code/Name`, and `{UserName,Email,DisplayName}` shapes. Nested titles keep **every** locale key (`{ En, Ar, Fr }` → `{ en, ar, fr }`). Radio, checkbox, select, and multiselect all use that map. The form then resolves the active locale (`provideDgaLocales` / `[locale]`) → `en` → `ar` → first non-empty value. Select/multiselect show only that locale in the dropdown (`dga-select` renders `keywords` as visible secondary text, so other languages are not copied there).
|
|
245
245
|
|
|
246
246
|
### Files
|
|
247
247
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import*as l from"@angular/core";import{InjectionToken as x,inject as p,Injectable as X,isDevMode as je,makeEnvironmentProviders as We,input as c,booleanAttribute as Z,signal as f,computed as u,output as h,ChangeDetectionStrategy as R,Component as V,DestroyRef as ee,effect as N,untracked as q}from"@angular/core";import{NgComponentOutlet as te,NgTemplateOutlet as ae}from"@angular/common";import*as b from"@angular/forms";import{Validators as v,ReactiveFormsModule as O,FormsModule as ie,FormBuilder as Ke}from"@angular/forms";import{switchMap as ne,catchError as He,map as Ye,startWith as Je}from"rxjs/operators";import{takeUntilDestroyed as A}from"@angular/core/rxjs-interop";import{DgaToastService as Qe,DgaButton as E,DgaIcon as C,dgaProvideValueAccessor as oe,DgaField as re,DgaInput as le,DgaSelect as se,DgaCheckbox as de,DgaRadio as ce,DgaPhoneInput as ue,DgaChipInput as pe,DgaSwitch as fe,DgaUpload as me,DgaNumberInput as ge,DgaOtp as he,DgaAlert as be,DgaBadge as ve,DgaCard as ye,DgaProgress as xe,DgaStepper as De}from"@a.nemreen/dga-ui";import{of as D,throwError as we,startWith as Xe,catchError as Ze}from"rxjs";import{HttpClient as L,HttpHeaders as et}from"@angular/common/http";import{DgaDatePicker as Se}from"@a.nemreen/dga-ui/date-picker";const B=new x("DGA_LOOKUP_ADAPTER"),M=new x("DGA_SUBMIT_ADAPTER"),$=new x("DGA_FORM_TOAST_ADAPTER"),_=new x("DGA_CAPTCHA_ADAPTER"),U=new x("DGA_HTTP_SECURITY"),G=new x("DGA_FORM_I18N_ADAPTER"),Ce=new x("DGA_DYNAMIC_FORM_FIELD_REGISTRY"),Le=[["StartDate","EndDate"],["UseCaseStartDate","UseCaseEndDate"],["startDate","endDate"]];function Ie(i){return e=>e.value&&i.value!==e.value?{passwordMismatch:!0}:null}function tt(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 at(i){const e=(i??"").trim();if(e)return e.startsWith("+")?e:`+${e}`}function ke(i){const e=[...new Set((i??[]).map(t=>at(t?.code)).filter(t=>!!t&&t!=="+966"))].sort((t,a)=>a.length-t.length);return t=>{const a=(t.value??"").toString().trim();if(!a||!e.length)return j(t);const n=e.find(r=>a.startsWith(r));if(!n)return j(t);const o=a.slice(n.length).replace(/\s+/g,"");return o?/^\d+$/.test(o)?null:{invalidFormat:!0}:null}}function j(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 it(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 nt(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 ot(i){const e=i.value;return Array.isArray(e)&&e.some(a=>a&&typeof a=="object"&&a.status==="uploading")?{uploadInProgress:!0}:null}function Te(i,e){const t=i.get("password"),a=i.get("confirmPassword");t&&a&&(a.addValidators(Ie(t)),a.updateValueAndValidity({emitEvent:!1}));for(const[n,o]of Le){const r=i.get(n),s=i.get(o);if(!r||!s)continue;s.addValidators(tt(r));const d=e.find(S=>S.name===o),g=S=>{if(d?.validation){if(S){const Ge=new Date(S),z=new Date(Ge);z.setDate(z.getDate()+1),d.validation.minDate=z.toISOString().split("T")[0]}else delete d.validation.minDate;s.updateValueAndValidity({emitEvent:!1})}};g(r.value),r.valueChanges.subscribe(S=>g(S))}}const Fe=["checkbox","multiselect","chips","file","multifile","multifilestaged"],rt=["toggle"];function Ne(i){return i.value!==void 0?i.value:Fe.includes(i.type)?[]:rt.includes(i.type)?!1:""}function W(i,e){const t=[],a=i.validation;(e||i.required||a?.required)&&(Fe.includes(i.type)?t.push(lt):i.type==="toggle"?t.push(v.requiredTrue):t.push(v.required)),(i.type==="email"||a?.pattern==="email")&&t.push(v.email);const n=a?.minLength;n!=null&&t.push(v.minLength(n));const o=a?.maxLength??i.maxLength;if(o!=null&&t.push(v.maxLength(o)),a?.pattern&&a.pattern!=="email"){const r=a.pattern;if(typeof r=="string"&&r.length>0&&r.length<=200)try{t.push(v.pattern(r))}catch{}}return a?.min!=null&&t.push(v.min(a.min)),a?.max!=null&&t.push(v.max(a.max)),i.maxChips!=null&&i.type==="chips"&&t.push(st(i.maxChips)),i.type==="phone"&&t.push(ke(i.countries)),i.type==="multifilestaged"&&t.push(ot),a?.minDate&&t.push(it(a.minDate)),a?.maxDate&&t.push(nt(a.maxDate)),t}function lt(i){const e=i.value;return Array.isArray(e)&&e.length>0?null:{required:!0}}function st(i){return e=>{const t=e.value;return Array.isArray(t)&&t.length>i?{maxChips:{max:i,actual:t.length}}:null}}function Oe(i,e,t=!0){const a=!!e.disabled;return i.control({value:Ne(e),disabled:a},{validators:W(e,t&&!e.requiredWhen)})}function Ae(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]=Oe(i,a)}return i.group(t)}function Ee(i,e){return e?.length?e.flatMap(t=>t.fields):i}function K(i,e,t){i.setValidators(W(e,t)),i.updateValueAndValidity({emitEvent:!1})}function H(i,e){return Array.isArray(i)?i.some(t=>t==e):i==e}function dt(i){return i.label?.en??""}function ct(i){return i.label?.ar??""}function P(i,e,t,a){return Pe(a?.(i)??{name:i,type:"select",label:{en:"",ar:""}},e,t?.(i))}function ut(i,e,t,a,n){if(!i.showOnTitleEn&&!i.showOnTitleAr||t==null||t==="")return!1;const o=P(e,t,a,n);if(!o)return!1;const r=i.showOnTitleEn?dt(o)===i.showOnTitleEn:!0,s=i.showOnTitleAr?ct(o)===i.showOnTitleAr:!0;return r&&s}function Me(i,e,t,a){if(!i.extraField)return!0;const n=i.extraFieldTrigger||i.dependsOn;if(!n)return!1;const o=e[n];return P(n,o,t,a)?.requiresTextInput===!0}function Pe(i,e,t){return i?[...t??[],...i.options??[],...i.groupedOptions?.flatMap(n=>n.options)??[]].find(n=>n.value==e):void 0}function Y(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 Me(i,e,t,a);const o=e[n];if(i.showOnValues?.length&&!i.showOnValues.some(r=>H(o,r))||(i.showOnTitleEn||i.showOnTitleAr)&&!ut(i,n,o,t,a))return!1;if(i.showWhenOptionProperty){const r=P(n,o,t,a),s=i.showWhenOptionProperty.property;if(!r||r[s]!==i.showWhenOptionProperty.value)return!1}return!(i.extraField&&!Me(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 J(i,e,t,a){const n=i.requiredWhen;if(!n)return!!i.required;const o=e[n.field];if(n.optionProperty!=null){const r=P(n.field,o,t,a);return!!r&&r[n.optionProperty]===n.optionPropertyValue}return n.values?.length?n.values.some(r=>H(o,r)):n.value!==void 0?H(o,n.value):o!=null&&o!==""}const pt=new Set(["otp","file"]),ze=/password|passwd|secret|token|otp|national.?id|ssn|pin$/i;class I{submitAdapter=p(M,{optional:!0});captcha=p(_,{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(ne(d=>(d&&(r["X-Recaptcha-Token"]=d),D({endpoint:e.endpoint,method:e.method??"POST",body:o,headers:r})))).pipe(ne(d=>this.submitAdapter.submit(d)),He(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&&ze.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||pt.has(e.type)?!0:ze.test(e.name)}storageKey(e){return`dga-dynamic-form:${e}`}static ɵfac=l.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:I,deps:[],target:l.ɵɵFactoryTarget.Injectable});static ɵprov=l.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:I,providedIn:"root"})}l.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:I,decorators:[{type:X,args:[{providedIn:"root"}]}]});function m(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 Re(){return typeof document>"u"?"ar":(document.documentElement.lang||"ar").toLowerCase().split("-")[0]||"ar"}class k{extras=p(Ce,{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 ft.has(e)}static ɵfac=l.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:k,deps:[],target:l.ɵɵFactoryTarget.Injectable});static ɵprov=l.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:k,providedIn:"root"})}l.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:k,decorators:[{type:X,args:[{providedIn:"root"}]}],ctorParameters:()=>[]});const ft=new Set(["text","email","textarea","select","multiselect","checkbox","radio","phone","file","multifile","multifilestaged","date","chips","toggle","hidden","number","otp","password"]),Ve={resolveLabel(i,e){return m(i,e)}},qe={getToken:()=>D(null)},Be={lookup:()=>D([])},mt=new Set(["__proto__","constructor","prototype"]);function T(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 $e(i=p(L),e={}){return{lookup(t){try{const n=`${T(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(Ye(r=>Array.isArray(r)?r.map(gt):[]))}catch(a){return we(()=>a)}}}}function gt(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))mt.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 _e(i=p(L),e={}){return{submit(t){try{const a=T(t.endpoint,e.allowedOrigins),n=new et(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 we(()=>a)}}}}function Ue(i=p(Qe)){return{show(e){i.show({title:e.title,message:e.message,variant:e.variant??"info"})}}}function ht(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 je()&&(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."),We([{provide:U,useValue:o},{provide:G,useValue:Ve},{provide:_,useValue:qe},{provide:B,useFactory:()=>e?$e(p(L),o):Be},{provide:M,useFactory:()=>t?_e(p(L),o):{submit:()=>D(null)}},{provide:$,useFactory:()=>a?Ue():{show:()=>{}}}])}function bt(i,e,t=""){return m(i,e,t)}class y{accept=c("",...ngDevMode?[{debugName:"accept"}]:[]);maxFileSize=c(0,...ngDevMode?[{debugName:"maxFileSize"}]:[]);maxFiles=c(0,...ngDevMode?[{debugName:"maxFiles"}]:[]);uploadEndpoint=c("",...ngDevMode?[{debugName:"uploadEndpoint"}]:[]);deleteEndpoint=c("",...ngDevMode?[{debugName:"deleteEndpoint"}]:[]);deleteMethod=c("DELETE",...ngDevMode?[{debugName:"deleteMethod"}]:[]);hint=c("Drag files here or browse",...ngDevMode?[{debugName:"hint"}]:[]);browseLabel=c("Choose files",...ngDevMode?[{debugName:"browseLabel"}]:[]);removeLabel=c("Remove",...ngDevMode?[{debugName:"removeLabel"}]:[]);downloadLabel=c("Download",...ngDevMode?[{debugName:"downloadLabel"}]:[]);uploadingLabel=c("Uploading…",...ngDevMode?[{debugName:"uploadingLabel"}]:[]);errorLabel=c("Upload failed",...ngDevMode?[{debugName:"errorLabel"}]:[]);disabledInput=c(!1,{...ngDevMode?{debugName:"disabledInput"}:{},alias:"disabled",transform:Z});cvaDisabled=f(!1,...ngDevMode?[{debugName:"cvaDisabled"}]:[]);disabled=u(()=>this.disabledInput()||this.cvaDisabled(),...ngDevMode?[{debugName:"disabled"}]:[]);fileDownload=h();http=p(L);httpSecurity=p(U,{optional:!0});files=f([],...ngDevMode?[{debugName:"files"}]:[]);dragging=f(!1,...ngDevMode?[{debugName:"dragging"}]:[]);onChange=()=>{};onTouched=()=>{};atLimit=u(()=>{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=T(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=T(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.1.5",ngImport:l,type:y,deps:[],target:l.ɵɵFactoryTarget.Component});static ɵcmp=l.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"22.1.5",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:[oe(y)],ngImport:l,template:`
|
|
1
|
+
import*as l from"@angular/core";import{InjectionToken as C,inject as p,Injectable as ae,isDevMode as Qe,makeEnvironmentProviders as Xe,input as c,booleanAttribute as ie,signal as h,computed as u,output as y,ChangeDetectionStrategy as $,Component as _,DestroyRef as ne,effect as E,untracked as j}from"@angular/core";import{NgComponentOutlet as oe,NgTemplateOutlet as re}from"@angular/common";import*as x from"@angular/forms";import{Validators as D,ReactiveFormsModule as M,FormsModule as le,FormBuilder as Ze}from"@angular/forms";import{switchMap as se,catchError as et,map as tt,startWith as at}from"rxjs/operators";import{takeUntilDestroyed as P}from"@angular/core/rxjs-interop";import{DgaToastService as it,DgaButton as z,DgaIcon as k,dgaProvideValueAccessor as de,DgaField as ce,DgaInput as ue,DgaSelect as pe,DgaCheckbox as fe,DgaRadio as me,DgaPhoneInput as ge,DgaChipInput as he,DgaSwitch as be,DgaUpload as ve,DgaNumberInput as ye,DgaOtp as xe,DgaAlert as De,DgaBadge as Se,DgaCard as we,DgaProgress as Ce,DgaStepper as Le}from"@a.nemreen/dga-ui";import{of as L,throwError as Ie,startWith as nt,catchError as ot}from"rxjs";import{HttpClient as T,HttpHeaders as rt}from"@angular/common/http";import{DgaDatePicker as ke}from"@a.nemreen/dga-ui/date-picker";const U=new C("DGA_LOOKUP_ADAPTER"),R=new C("DGA_SUBMIT_ADAPTER"),G=new C("DGA_FORM_TOAST_ADAPTER"),K=new C("DGA_CAPTCHA_ADAPTER"),W=new C("DGA_HTTP_SECURITY"),H=new C("DGA_FORM_I18N_ADAPTER"),Te=new C("DGA_DYNAMIC_FORM_FIELD_REGISTRY"),Fe=[["StartDate","EndDate"],["UseCaseStartDate","UseCaseEndDate"],["startDate","endDate"]];function Oe(i){return e=>e.value&&i.value!==e.value?{passwordMismatch:!0}:null}function lt(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 st(i){const e=(i??"").trim();if(e)return e.startsWith("+")?e:`+${e}`}function Ne(i){const e=[...new Set((i??[]).map(t=>st(t?.code)).filter(t=>!!t&&t!=="+966"))].sort((t,a)=>a.length-t.length);return t=>{const a=(t.value??"").toString().trim();if(!a||!e.length)return Y(t);const n=e.find(r=>a.startsWith(r));if(!n)return Y(t);const o=a.slice(n.length).replace(/\s+/g,"");return o?/^\d+$/.test(o)?null:{invalidFormat:!0}:null}}function Y(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 dt(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 ct(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 ut(i){const e=i.value;return Array.isArray(e)&&e.some(a=>a&&typeof a=="object"&&a.status==="uploading")?{uploadInProgress:!0}:null}function Ae(i,e){const t=i.get("password"),a=i.get("confirmPassword");t&&a&&(a.addValidators(Oe(t)),a.updateValueAndValidity({emitEvent:!1}));for(const[n,o]of Fe){const r=i.get(n),d=i.get(o);if(!r||!d)continue;d.addValidators(lt(r));const s=e.find(b=>b.name===o),f=b=>{if(s?.validation){if(b){const v=new Date(b),m=new Date(v);m.setDate(m.getDate()+1),s.validation.minDate=m.toISOString().split("T")[0]}else delete s.validation.minDate;d.updateValueAndValidity({emitEvent:!1})}};f(r.value),r.valueChanges.subscribe(b=>f(b))}}const Ee=["checkbox","multiselect","chips","file","multifile","multifilestaged"],pt=["toggle"];function Me(i){return i.value!==void 0?i.value:Ee.includes(i.type)?[]:pt.includes(i.type)?!1:""}function J(i,e){const t=[],a=i.validation;(e||i.required||a?.required)&&(Ee.includes(i.type)?t.push(ft):i.type==="toggle"?t.push(D.requiredTrue):t.push(D.required)),(i.type==="email"||a?.pattern==="email")&&t.push(D.email);const n=a?.minLength;n!=null&&t.push(D.minLength(n));const o=a?.maxLength??i.maxLength;if(o!=null&&t.push(D.maxLength(o)),a?.pattern&&a.pattern!=="email"){const r=a.pattern;if(typeof r=="string"&&r.length>0&&r.length<=200)try{t.push(D.pattern(r))}catch{}}return a?.min!=null&&t.push(D.min(a.min)),a?.max!=null&&t.push(D.max(a.max)),i.maxChips!=null&&i.type==="chips"&&t.push(mt(i.maxChips)),i.type==="phone"&&t.push(Ne(i.countries)),i.type==="multifilestaged"&&t.push(ut),a?.minDate&&t.push(dt(a.minDate)),a?.maxDate&&t.push(ct(a.maxDate)),t}function ft(i){const e=i.value;return Array.isArray(e)&&e.length>0?null:{required:!0}}function mt(i){return e=>{const t=e.value;return Array.isArray(t)&&t.length>i?{maxChips:{max:i,actual:t.length}}:null}}function Pe(i,e,t=!0){const a=!!e.disabled;return i.control({value:Me(e),disabled:a},{validators:J(e,t&&!e.requiredWhen)})}function ze(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]=Pe(i,a)}return i.group(t)}function Re(i,e){return e?.length?e.flatMap(t=>t.fields):i}function Q(i,e,t){i.setValidators(J(e,t)),i.updateValueAndValidity({emitEvent:!1})}function X(i,e){return Array.isArray(i)?i.some(t=>t==e):i==e}function gt(i){return i.label?.en??""}function ht(i){return i.label?.ar??""}function V(i,e,t,a){return qe(a?.(i)??{name:i,type:"select",label:{en:"",ar:""}},e,t?.(i))}function bt(i,e,t,a,n){if(!i.showOnTitleEn&&!i.showOnTitleAr||t==null||t==="")return!1;const o=V(e,t,a,n);if(!o)return!1;const r=i.showOnTitleEn?gt(o)===i.showOnTitleEn:!0,d=i.showOnTitleAr?ht(o)===i.showOnTitleAr:!0;return r&&d}function Ve(i,e,t,a){if(!i.extraField)return!0;const n=i.extraFieldTrigger||i.dependsOn;if(!n)return!1;const o=e[n];return V(n,o,t,a)?.requiresTextInput===!0}function qe(i,e,t){return i?[...t??[],...i.options??[],...i.groupedOptions?.flatMap(n=>n.options)??[]].find(n=>n.value==e):void 0}function Z(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 Ve(i,e,t,a);const o=e[n];if(i.showOnValues?.length&&!i.showOnValues.some(r=>X(o,r))||(i.showOnTitleEn||i.showOnTitleAr)&&!bt(i,n,o,t,a))return!1;if(i.showWhenOptionProperty){const r=V(n,o,t,a),d=i.showWhenOptionProperty.property;if(!r||r[d]!==i.showWhenOptionProperty.value)return!1}return!(i.extraField&&!Ve(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 ee(i,e,t,a){const n=i.requiredWhen;if(!n)return!!i.required;const o=e[n.field];if(n.optionProperty!=null){const r=V(n.field,o,t,a);return!!r&&r[n.optionProperty]===n.optionPropertyValue}return n.values?.length?n.values.some(r=>X(o,r)):n.value!==void 0?X(o,n.value):o!=null&&o!==""}const vt=new Set(["otp","file"]),Be=/password|passwd|secret|token|otp|national.?id|ssn|pin$/i;class F{submitAdapter=p(R,{optional:!0});captcha=p(K,{optional:!0});buildPayload(e,t,a){const n=new Set(a.filter(r=>r.excludeFromPayload).map(r=>r.name));let o={};for(const[r,d]of Object.entries(t)){if(n.has(r))continue;const s=e.fieldMapping?.[r]??r;o[s]=d}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 L(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")??L(null)).pipe(se(s=>(s&&(r["X-Recaptcha-Token"]=s),L({endpoint:e.endpoint,method:e.method??"POST",body:o,headers:r})))).pipe(se(s=>this.submitAdapter.submit(s)),et(s=>{throw s}))}saveDraft(e,t,a=[]){if(typeof localStorage>"u")return;const n=new Map(a.map(r=>[r.name,r])),o={};for(const[r,d]of Object.entries(t)){const s=n.get(r);s&&this.isDraftBlocked(s)||!s&&Be.test(r)||d instanceof File||(o[r]=d)}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||vt.has(e.type)?!0:Be.test(e.name)}storageKey(e){return`dga-dynamic-form:${e}`}static ɵfac=l.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:F,deps:[],target:l.ɵɵFactoryTarget.Injectable});static ɵprov=l.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:F,providedIn:"root"})}l.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:F,decorators:[{type:ae,args:[{providedIn:"root"}]}]});const yt=/^[a-z]{2,3}(?:-[a-z0-9]{2,8})*$/;function g(i,e,t=""){if(!i)return t;const a=e.toLowerCase(),n=i[e]||i[a];if(n)return n;const o=a.split("-")[0];return o&&i[o]?i[o]:i.en?i.en:i.ar?i.ar:Object.values(i).find(d=>!!d)||t}function S(i){if(i==null)return null;if(typeof i=="string"||typeof i=="number"){const t=String(i).trim();return t?{en:t,ar:t}:null}if(typeof i!="object"||Array.isArray(i))return null;const e={};for(const[t,a]of Object.entries(i)){if(a==null||typeof a=="object")continue;const n=String(a).trim();if(!n)continue;const o=t.trim().toLowerCase();if(!yt.test(o))continue;e[o]=n;const r=o.split("-")[0];r&&e[r]==null&&(e[r]=n)}return Object.keys(e).length?e:null}function $e(){return typeof document>"u"?"ar":(document.documentElement.lang||"ar").toLowerCase().split("-")[0]||"ar"}class O{extras=p(Te,{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 xt.has(e)}static ɵfac=l.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:O,deps:[],target:l.ɵɵFactoryTarget.Injectable});static ɵprov=l.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:O,providedIn:"root"})}l.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:O,decorators:[{type:ae,args:[{providedIn:"root"}]}],ctorParameters:()=>[]});const xt=new Set(["text","email","textarea","select","multiselect","checkbox","radio","phone","file","multifile","multifilestaged","date","chips","toggle","hidden","number","otp","password"]);function Dt(i){if(!i)return[];const e=new Set,t=[];for(const a of Object.values(i))!a||e.has(a)||(e.add(a),t.push(a));return t}function _e(i,e){return i.map(t=>{const a=g(t.label,e),n=t.description?g(t.description,e):"";return{value:String(t.value),label:a,disabled:!!t.disabled,keywords:n&&n!==a?n:void 0}})}const je={resolveLabel(i,e){return g(i,e)}},Ue={getToken:()=>L(null)},Ge={lookup:()=>L([])},St=new Set(["__proto__","constructor","prototype"]),wt=new Set(["value","label","id","Id","Code","labelEn","titleEn","en","TitleEn","labelAr","titleAr","ar","TitleAr","Title","title","Label","Name","name","NameAr","nameAr","DisplayName","UserName","Email","Description","description","disabled","requiresTextInput","RequiresTextInput"]);function N(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 Ke(i=p(T),e={}){return{lookup(t){try{const n=`${N(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(tt(r=>Array.isArray(r)?r.map(He):[]))}catch(a){return Ie(()=>a)}}}}function q(...i){for(const e of i){if(e==null||typeof e=="object")continue;const t=String(e).trim();if(t)return t}}const Ct=/^(?:label|title|name)([A-Za-z]{2,3})$/i;function Lt(i){const e={};for(const[t,a]of Object.entries(i)){const n=q(a);if(!n)continue;const o=t.match(Ct);o&&(e[o[1].toLowerCase()]=n)}return e}function We(i,e,t){const a={en:e,ar:t};if(!i)return a;for(const[n,o]of Object.entries(i))o&&(a[n]=o);return a.en=e,a.ar=t,a}function He(i){const e=i??{},t=q(e.DisplayName,e.UserName,e.Email),a=e.value??e.id??e.Id??e.Code??t??"",o={...S(e.Title)??S(e.title)??S(e.Label)??S(e.label)??S(e.Name)??S(e.name),...Lt(e)},r=Object.values(o).find(m=>!!m),d=q(e.labelEn,e.titleEn,e.en,e.TitleEn,o.en,r,t,a)??"",s=q(e.labelAr,e.titleAr,e.ar,e.TitleAr,e.NameAr,e.nameAr,o.ar,d)??"",f={value:a,label:We(o,d,s)};for(const[m,B]of Object.entries(e))St.has(m)||wt.has(m)||(f[m]=B);e.disabled!=null&&(f.disabled=!!e.disabled);const b=e.requiresTextInput??e.RequiresTextInput;b!=null&&(f.requiresTextInput=!!b);const v=S(e.Description??e.description);if(v){const m=v.en||v.ar||Object.values(v).find(B=>!!B)||"";f.description=We(v,m,v.ar||m)}return f}function Ye(i=p(T),e={}){return{submit(t){try{const a=N(t.endpoint,e.allowedOrigins),n=new rt(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 Ie(()=>a)}}}}function Je(i=p(it)){return{show(e){i.show({title:e.title,message:e.message,variant:e.variant??"info"})}}}function It(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 Qe()&&(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."),Xe([{provide:W,useValue:o},{provide:H,useValue:je},{provide:K,useValue:Ue},{provide:U,useFactory:()=>e?Ke(p(T),o):Ge},{provide:R,useFactory:()=>t?Ye(p(T),o):{submit:()=>L(null)}},{provide:G,useFactory:()=>a?Je():{show:()=>{}}}])}function kt(i,e,t=""){return g(i,e,t)}class w{accept=c("",...ngDevMode?[{debugName:"accept"}]:[]);maxFileSize=c(0,...ngDevMode?[{debugName:"maxFileSize"}]:[]);maxFiles=c(0,...ngDevMode?[{debugName:"maxFiles"}]:[]);uploadEndpoint=c("",...ngDevMode?[{debugName:"uploadEndpoint"}]:[]);deleteEndpoint=c("",...ngDevMode?[{debugName:"deleteEndpoint"}]:[]);deleteMethod=c("DELETE",...ngDevMode?[{debugName:"deleteMethod"}]:[]);hint=c("Drag files here or browse",...ngDevMode?[{debugName:"hint"}]:[]);browseLabel=c("Choose files",...ngDevMode?[{debugName:"browseLabel"}]:[]);removeLabel=c("Remove",...ngDevMode?[{debugName:"removeLabel"}]:[]);downloadLabel=c("Download",...ngDevMode?[{debugName:"downloadLabel"}]:[]);uploadingLabel=c("Uploading…",...ngDevMode?[{debugName:"uploadingLabel"}]:[]);errorLabel=c("Upload failed",...ngDevMode?[{debugName:"errorLabel"}]:[]);disabledInput=c(!1,{...ngDevMode?{debugName:"disabledInput"}:{},alias:"disabled",transform:ie});cvaDisabled=h(!1,...ngDevMode?[{debugName:"cvaDisabled"}]:[]);disabled=u(()=>this.disabledInput()||this.cvaDisabled(),...ngDevMode?[{debugName:"disabled"}]:[]);fileDownload=y();http=p(T);httpSecurity=p(W,{optional:!0});files=h([],...ngDevMode?[{debugName:"files"}]:[]);dragging=h(!1,...ngDevMode?[{debugName:"dragging"}]:[]);onChange=()=>{};onTouched=()=>{};atLimit=u(()=>{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=N(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=N(o,this.httpSecurity?.allowedOrigins),d=new FormData;d.append("file",e),this.http.post(r,d).subscribe({next:s=>{a.status="success",a.fileId=s.fileId??t,s.fileName&&(a.fileName=s.fileName),this.commit([...this.files()])},error:s=>{a.status="error",a.errorMessage=s?.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.1.5",ngImport:l,type:w,deps:[],target:l.ɵɵFactoryTarget.Component});static ɵcmp=l.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"22.1.5",type:w,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:[de(w)],ngImport:l,template:`
|
|
2
2
|
<div class="flex flex-col gap-md">
|
|
3
3
|
<div
|
|
4
4
|
class="flex flex-col items-center justify-center gap-md rounded-lg border border-dashed border-border
|
|
@@ -76,7 +76,7 @@ import*as l from"@angular/core";import{InjectionToken as x,inject as p,Injectabl
|
|
|
76
76
|
</ul>
|
|
77
77
|
}
|
|
78
78
|
</div>
|
|
79
|
-
`,isInline:!0,dependencies:[{kind:"directive",type:
|
|
79
|
+
`,isInline:!0,dependencies:[{kind:"directive",type:z,selector:"button[dgaButton], a[dgaButton]",inputs:["variant","size","iconOnly","cooldownMs","loading","dgaButtonClass"]},{kind:"component",type:k,selector:"dga-icon",inputs:["name","glyph","size","tone","label"]}],changeDetection:l.ChangeDetectionStrategy.OnPush})}l.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:w,decorators:[{type:_,args:[{selector:"dga-dynamic-form-staged-upload",standalone:!0,imports:[z,k],template:`
|
|
80
80
|
<div class="flex flex-col gap-md">
|
|
81
81
|
<div
|
|
82
82
|
class="flex flex-col items-center justify-center gap-md rounded-lg border border-dashed border-border
|
|
@@ -154,7 +154,7 @@ import*as l from"@angular/core";import{InjectionToken as x,inject as p,Injectabl
|
|
|
154
154
|
</ul>
|
|
155
155
|
}
|
|
156
156
|
</div>
|
|
157
|
-
`,changeDetection
|
|
157
|
+
`,changeDetection:$.OnPush,host:{class:"block w-full"},providers:[de(w)]}]}],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 I{field=c.required(...ngDevMode?[{debugName:"field"}]:[]);form=c.required(...ngDevMode?[{debugName:"form"}]:[]);locale=c("ar",...ngDevMode?[{debugName:"locale"}]:[]);required=c(!1,{...ngDevMode?{debugName:"required"}:{},transform:ie});error=c("",...ngDevMode?[{debugName:"error"}]:[]);runtimeOptions=c([],...ngDevMode?[{debugName:"runtimeOptions"}]:[]);consentBaseUrl=c(...ngDevMode?[void 0,{debugName:"consentBaseUrl"}]:[]);optionsLoaded=y();fileDownload=y();lookup=p(U,{optional:!0});http=p(T,{optional:!0});destroyRef=p(ne);loadedOptions=h([],...ngDevMode?[{debugName:"loadedOptions"}]:[]);controlId=`dga-df-${Math.random().toString(36).slice(2,9)}`;get control(){return this.form().controls[this.field().name]}labelText=u(()=>g(this.field().label,this.locale()),...ngDevMode?[{debugName:"labelText"}]:[]);hintText=u(()=>g(this.field().hint,this.locale()),...ngDevMode?[{debugName:"hintText"}]:[]);placeholderText=u(()=>g(this.field().placeholder,this.locale()),...ngDevMode?[{debugName:"placeholderText"}]:[]);phoneCountries=u(()=>(this.field().countries??[]).flatMap(e=>{const t=(e.code??"").trim();if(!t)return[];const a=t.startsWith("+")?t:`+${t}`;return[{code:a,label:(e.label??"").trim()||a,name:e.name}]}),...ngDevMode?[{debugName:"phoneCountries"}]:[]);resolvedOptions=u(()=>{const e=this.runtimeOptions();if(e.length)return e;const t=this.loadedOptions();if(t.length)return t;const a=this.field();return a.options?.length?a.options:a.groupedOptions?.flatMap(n=>n.options)??[]},...ngDevMode?[{debugName:"resolvedOptions"}]:[]);optionGroups=u(()=>{const e=this.runtimeOptions();if(e.length)return[{label:"",options:e}];const t=this.loadedOptions();if(t.length)return[{label:"",options:t}];const a=this.field();return a.groupedOptions?.length&&!a.options?.length?a.groupedOptions.map(n=>({label:g(n.groupLabel,this.locale()),options:n.options})):[{label:"",options:a.options??[]}]},...ngDevMode?[{debugName:"optionGroups"}]:[]);selectOptions=u(()=>_e(this.resolvedOptions(),this.locale()),...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(nt(t.value),P(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(ot(()=>L(null)),P(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(P(this.destroyRef)).subscribe(o=>{const r=this.applyLookupFilter(o);this.loadedOptions.set(r),this.optionsLoaded.emit({name:e.name,options:r})})}optionLabel(e){return g(e.label,this.locale())}optionDescription(e){return e.description?g(e.description,this.locale()):""}isCardsLayout(){return this.field().optionsLayout==="cards"}optionsContainerClass(){const e=this.field().optionsLayout;return e==="cards"?"grid grid-cols-1 gap-md sm:grid-cols-2":e==="grid"?"flex flex-wrap gap-lg":"flex flex-col gap-md"}choiceLabelClass(e){return this.isCardsLayout()?["flex min-h-7xl cursor-pointer items-start gap-lg rounded-lg border border-border bg-elevated p-xl text-start shadow-xs","transition-[border-color,box-shadow,background-color] hover:border-border-primary-light hover:shadow-sm","has-[:checked]:border-border-primary has-[:checked]:bg-primary-faint has-[:checked]:shadow-sm has-[:checked]:ring-2 has-[:checked]:ring-primary/20","has-[:focus-visible]:outline has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-focus",e.disabled||this.field().disabled?"pointer-events-none opacity-50":""].filter(Boolean).join(" "):"inline-flex max-w-full items-start gap-sm text-body-sm text-fg"}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.1.5",ngImport:l,type:I,deps:[],target:l.ɵɵFactoryTarget.Component});static ɵcmp=l.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"22.1.5",type:I,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:`
|
|
158
158
|
@if (field().type !== 'hidden') {
|
|
159
159
|
<dga-field
|
|
160
160
|
[label]="labelText()"
|
|
@@ -402,7 +402,7 @@ import*as l from"@angular/core";import{InjectionToken as x,inject as p,Injectabl
|
|
|
402
402
|
}
|
|
403
403
|
</dga-field>
|
|
404
404
|
}
|
|
405
|
-
`,isInline:!0,dependencies:[{kind:"ngmodule",type:
|
|
405
|
+
`,isInline:!0,dependencies:[{kind:"ngmodule",type:M},{kind:"directive",type:x.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:x.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:x.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:x.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:x.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"ngmodule",type:le},{kind:"component",type:ce,selector:"dga-field",inputs:["label","labelHint","hint","error","status","statusMessage","controlId","required"]},{kind:"directive",type:ue,selector:"input[dgaInput], textarea[dgaInput]",inputs:["size","dgaInvalid","status"]},{kind:"component",type:pe,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:fe,selector:'input[type="checkbox"][dgaCheckbox]',inputs:["size","dgaInvalid"]},{kind:"directive",type:me,selector:'input[type="radio"][dgaRadio]',inputs:["size","dgaInvalid"]},{kind:"component",type:ge,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:ke,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:he,selector:"dga-chip-input",inputs:["value","placeholder","label","removeLabel","disabled","allowDuplicates","dgaInvalid","status"],outputs:["valueChange"]},{kind:"component",type:be,selector:"dga-switch",inputs:["checked","size","label","disabled"],outputs:["checkedChange","changed"]},{kind:"component",type:ve,selector:"dga-upload",inputs:["files","accept","multiple","appearance","hint","browseLabel","removeLabel","disabled","maxSize","maxFiles","dragging"],outputs:["filesChange","rejected","draggingChange"]},{kind:"component",type:ye,selector:"dga-number-input",inputs:["value","min","max","step","size","label","controlId","name","incrementLabel","decrementLabel","disabled","dgaInvalid","status"],outputs:["valueChange"]},{kind:"component",type:xe,selector:"dga-otp",inputs:["length","value","label","alphanumeric","disabled","dgaInvalid"],outputs:["valueChange","completed"]},{kind:"component",type:k,selector:"dga-icon",inputs:["name","glyph","size","tone","label"]},{kind:"component",type:w,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.1.5",ngImport:l,type:I,decorators:[{type:_,args:[{selector:"dga-dynamic-form-field",standalone:!0,imports:[M,le,ce,ue,pe,fe,me,ge,ke,he,be,ve,ye,xe,k,w],template:`
|
|
406
406
|
@if (field().type !== 'hidden') {
|
|
407
407
|
<dga-field
|
|
408
408
|
[label]="labelText()"
|
|
@@ -650,7 +650,7 @@ import*as l from"@angular/core";import{InjectionToken as x,inject as p,Injectabl
|
|
|
650
650
|
}
|
|
651
651
|
</dga-field>
|
|
652
652
|
}
|
|
653
|
-
`,changeDetection:R.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 vt={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"},yt={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"},xt={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 Q(i){return Number.isFinite(i)?Math.min(12,Math.max(1,Math.round(i))):12}class F{config=c.required(...ngDevMode?[{debugName:"config"}]:[]);localeInput=c(null,{...ngDevMode?{debugName:"localeInput"}:{},alias:"locale"});formSubmitted=h();formError=h();clearButtonClick=h();draftSaved=h();fileDownload=h();fb=p(Ke);formService=p(I);submitAdapter=p(M,{optional:!0});toast=p($,{optional:!0});i18n=p(G,{optional:!0});destroyRef=p(ee);registry=p(k);form;formSignature="";valueChangesSub=null;activeStep=f(0,...ngDevMode?[{debugName:"activeStep"}]:[]);submitting=f(!1,...ngDevMode?[{debugName:"submitting"}]:[]);draftRestored=f(!1,...ngDevMode?[{debugName:"draftRestored"}]:[]);draftJustSaved=f(!1,...ngDevMode?[{debugName:"draftJustSaved"}]:[]);optionsMap=f({},...ngDevMode?[{debugName:"optionsMap"}]:[]);formValues=f({},...ngDevMode?[{debugName:"formValues"}]:[]);draftSavedTimer=null;locale=u(()=>this.localeInput()??Re(),...ngDevMode?[{debugName:"locale"}]:[]);wizardEnabled=u(()=>!!this.config().wizard?.enabled&&!!this.config().wizard?.steps?.length,...ngDevMode?[{debugName:"wizardEnabled"}]:[]);allFields=u(()=>Ee(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(),a=this.allFields(),n=o=>a.find(r=>r.name===o);return this.currentStepFields().filter(o=>Y(o,e,r=>t[r],n))},...ngDevMode?[{debugName:"visibleFields"}]:[]);stepperSteps=u(()=>{const e=this.config().wizard?.steps??[],t=this.activeStep(),a=!!this.config().wizard?.allowSkipSteps;return e.map((n,o)=>({label:this.labelOf(n.title),disabled:!a&&o>t}))},...ngDevMode?[{debugName:"stepperSteps"}]:[]);descriptionText=u(()=>this.labelOf(this.config().description),...ngDevMode?[{debugName:"descriptionText"}]:[]);currentStep=u(()=>this.wizardEnabled()?this.config().wizard?.steps[this.activeStep()]:void 0,...ngDevMode?[{debugName:"currentStep"}]:[]);currentStepTitle=u(()=>this.labelOf(this.currentStep()?.title),...ngDevMode?[{debugName:"currentStepTitle"}]:[]);currentStepDescription=u(()=>this.labelOf(this.currentStep()?.description),...ngDevMode?[{debugName:"currentStepDescription"}]:[]);currentStepOptional=u(()=>!!this.currentStep()?.optional,...ngDevMode?[{debugName:"currentStepOptional"}]:[]);stepCount=u(()=>this.config().wizard?.steps.length??0,...ngDevMode?[{debugName:"stepCount"}]:[]);stepPercent=u(()=>{const e=this.stepCount();return e?Math.round((this.activeStep()+1)/e*100):0},...ngDevMode?[{debugName:"stepPercent"}]:[]);stepFraction(){return`${this.activeStep()+1}/${this.stepCount()}`}constructor(){this.form=this.fb.group({}),this.destroyRef.onDestroy(()=>{this.valueChangesSub?.unsubscribe(),this.draftSavedTimer&&clearTimeout(this.draftSavedTimer)}),N(()=>{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=Ae(this.fb,e);if(n)r.patchValue(n,{emitEvent:!1});else if(o&&a.formId&&a.enableLocalStorageSave){const g=this.formService.loadDraft(a.formId);g&&(r.patchValue(g,{emitEvent:!1}),this.draftRestored.set(!0))}this.form=r,Te(r,e);const s=r.get("password"),d=r.get("confirmPassword");s&&d&&s.valueChanges.pipe(A(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(Je(r.getRawValue())).subscribe(g=>this.formValues.set(g))})}),N(()=>{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)if(a.requiredWhen){const o=this.allFields(),s=J(a,e,d=>t[d],d=>o.find(g=>g.name===d));K(n,a,s)}else a.type==="phone"&&K(n,a,!!(a.required||a.validation?.required))}}),N(()=>{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})})}),N(()=>{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()):m(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"?"Back":"رجوع")}clearLabel(){return this.labelOf(this.config().clearButtonLabel)}saveLabel(){return this.labelOf(this.config().saveButtonLabel??this.config().wizard?.saveButtonText)||(this.locale()==="en"?"Save as draft":"حفظ كمسودة")}draftSavedLabel(){return this.locale()==="en"?"Draft saved":"تم حفظ المسودة"}draftRestoredTitle(){return this.locale()==="en"?"Draft restored":"تم استعادة المسودة"}draftRestoredBody(){return this.locale()==="en"?"Your previous answers were loaded. You can continue or discard the draft.":"تم تحميل إجاباتك السابقة. يمكنك المتابعة أو حذف المسودة."}discardDraftLabel(){return this.locale()==="en"?"Discard draft":"حذف المسودة"}optionalBadgeLabel(){return this.locale()==="en"?"Optional":"اختياري"}stepProgressLabel(){const e=this.stepCount(),t=this.activeStep()+1;return this.locale()==="en"?`Step ${t} of ${e}`:`الخطوة ${t} من ${e}`}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 J(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=Q(t?.sm??t?.md??12),n=Q(t?.md??a),o=Q(t?.lg??n);return["w-full",vt[a],yt[n],xt[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),this.draftRestored.set(!1),this.draftJustSaved.set(!1);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.draftRestored.set(!1),this.draftJustSaved.set(!0),this.draftSavedTimer&&clearTimeout(this.draftSavedTimer),this.draftSavedTimer=setTimeout(()=>this.draftJustSaved.set(!1),2500),this.toast?.show({variant:"success",message:this.locale()==="en"?"Draft saved":"تم حفظ المسودة"})}dismissDraftBanner(){this.draftRestored.set(!1)}onDiscardDraft(){this.draftRestored.set(!1),this.onClear()}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"||Y(o,e,r=>t[r],n)).map(o=>o.name)}static ɵfac=l.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:F,deps:[],target:l.ɵɵFactoryTarget.Component});static ɵcmp=l.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"22.1.5",type:F,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:`
|
|
653
|
+
`,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}]}],consentBaseUrl:[{type:l.Input,args:[{isSignal:!0,alias:"consentBaseUrl",required:!1}]}],optionsLoaded:[{type:l.Output,args:["optionsLoaded"]}],fileDownload:[{type:l.Output,args:["fileDownload"]}]}});const Tt={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"},Ft={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"},Ot={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 te(i){return Number.isFinite(i)?Math.min(12,Math.max(1,Math.round(i))):12}class A{config=c.required(...ngDevMode?[{debugName:"config"}]:[]);localeInput=c(null,{...ngDevMode?{debugName:"localeInput"}:{},alias:"locale"});formSubmitted=y();formError=y();clearButtonClick=y();draftSaved=y();fileDownload=y();fb=p(Ze);formService=p(F);submitAdapter=p(R,{optional:!0});toast=p(G,{optional:!0});i18n=p(H,{optional:!0});destroyRef=p(ne);registry=p(O);form;formSignature="";valueChangesSub=null;activeStep=h(0,...ngDevMode?[{debugName:"activeStep"}]:[]);submitting=h(!1,...ngDevMode?[{debugName:"submitting"}]:[]);draftRestored=h(!1,...ngDevMode?[{debugName:"draftRestored"}]:[]);draftJustSaved=h(!1,...ngDevMode?[{debugName:"draftJustSaved"}]:[]);optionsMap=h({},...ngDevMode?[{debugName:"optionsMap"}]:[]);formValues=h({},...ngDevMode?[{debugName:"formValues"}]:[]);draftSavedTimer=null;locale=u(()=>this.localeInput()??$e(),...ngDevMode?[{debugName:"locale"}]:[]);wizardEnabled=u(()=>!!this.config().wizard?.enabled&&!!this.config().wizard?.steps?.length,...ngDevMode?[{debugName:"wizardEnabled"}]:[]);allFields=u(()=>Re(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(),a=this.allFields(),n=o=>a.find(r=>r.name===o);return this.currentStepFields().filter(o=>Z(o,e,r=>t[r],n))},...ngDevMode?[{debugName:"visibleFields"}]:[]);stepperSteps=u(()=>{const e=this.config().wizard?.steps??[],t=this.activeStep(),a=!!this.config().wizard?.allowSkipSteps;return e.map((n,o)=>({label:this.labelOf(n.title),disabled:!a&&o>t}))},...ngDevMode?[{debugName:"stepperSteps"}]:[]);descriptionText=u(()=>this.labelOf(this.config().description),...ngDevMode?[{debugName:"descriptionText"}]:[]);currentStep=u(()=>this.wizardEnabled()?this.config().wizard?.steps[this.activeStep()]:void 0,...ngDevMode?[{debugName:"currentStep"}]:[]);currentStepTitle=u(()=>this.labelOf(this.currentStep()?.title),...ngDevMode?[{debugName:"currentStepTitle"}]:[]);currentStepDescription=u(()=>this.labelOf(this.currentStep()?.description),...ngDevMode?[{debugName:"currentStepDescription"}]:[]);currentStepOptional=u(()=>!!this.currentStep()?.optional,...ngDevMode?[{debugName:"currentStepOptional"}]:[]);stepCount=u(()=>this.config().wizard?.steps.length??0,...ngDevMode?[{debugName:"stepCount"}]:[]);stepPercent=u(()=>{const e=this.stepCount();return e?Math.round((this.activeStep()+1)/e*100):0},...ngDevMode?[{debugName:"stepPercent"}]:[]);stepFraction(){return`${this.activeStep()+1}/${this.stepCount()}`}constructor(){this.form=this.fb.group({}),this.destroyRef.onDestroy(()=>{this.valueChangesSub?.unsubscribe(),this.draftSavedTimer&&clearTimeout(this.draftSavedTimer)}),E(()=>{const e=this.allFields(),t=e.map(n=>`${n.name}:${n.type}`).join("|"),a=this.config();j(()=>{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=ze(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.draftRestored.set(!0))}this.form=r,Ae(r,e);const d=r.get("password"),s=r.get("confirmPassword");d&&s&&d.valueChanges.pipe(P(this.destroyRef)).subscribe(()=>s.updateValueAndValidity({emitEvent:!1})),o||this.activeStep.set(0),this.formValues.set(r.getRawValue()),this.valueChangesSub?.unsubscribe(),this.valueChangesSub=r.valueChanges.pipe(at(r.getRawValue())).subscribe(f=>this.formValues.set(f))})}),E(()=>{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)if(a.requiredWhen){const o=this.allFields(),d=ee(a,e,s=>t[s],s=>o.find(f=>f.name===s));Q(n,a,d)}else a.type==="phone"&&Q(n,a,!!(a.required||a.validation?.required))}}),E(()=>{const e=this.allFields();j(()=>{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})})}),E(()=>{const e=this.activeStep(),t=this.config().wizard;j(()=>{!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()):g(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"?"Back":"رجوع")}clearLabel(){return this.labelOf(this.config().clearButtonLabel)}saveLabel(){return this.labelOf(this.config().saveButtonLabel??this.config().wizard?.saveButtonText)||(this.locale()==="en"?"Save as draft":"حفظ كمسودة")}draftSavedLabel(){return this.locale()==="en"?"Draft saved":"تم حفظ المسودة"}draftRestoredTitle(){return this.locale()==="en"?"Draft restored":"تم استعادة المسودة"}draftRestoredBody(){return this.locale()==="en"?"Your previous answers were loaded. You can continue or discard the draft.":"تم تحميل إجاباتك السابقة. يمكنك المتابعة أو حذف المسودة."}discardDraftLabel(){return this.locale()==="en"?"Discard draft":"حذف المسودة"}optionalBadgeLabel(){return this.locale()==="en"?"Optional":"اختياري"}stepProgressLabel(){const e=this.stepCount(),t=this.activeStep()+1;return this.locale()==="en"?`Step ${t} of ${e}`:`الخطوة ${t} من ${e}`}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 ee(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=d=>n?.[d]?this.labelOf(n[d]):"";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=te(t?.sm??t?.md??12),n=te(t?.md??a),o=te(t?.lg??n);return["w-full",Tt[a],Ft[n],Ot[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),this.draftRestored.set(!1),this.draftJustSaved.set(!1);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.draftRestored.set(!1),this.draftJustSaved.set(!0),this.draftSavedTimer&&clearTimeout(this.draftSavedTimer),this.draftSavedTimer=setTimeout(()=>this.draftJustSaved.set(!1),2500),this.toast?.show({variant:"success",message:this.locale()==="en"?"Draft saved":"تم حفظ المسودة"})}dismissDraftBanner(){this.draftRestored.set(!1)}onDiscardDraft(){this.draftRestored.set(!1),this.onClear()}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"||Z(o,e,r=>t[r],n)).map(o=>o.name)}static ɵfac=l.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:A,deps:[],target:l.ɵɵFactoryTarget.Component});static ɵcmp=l.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"22.1.5",type:A,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:`
|
|
654
654
|
<form
|
|
655
655
|
class="flex w-full flex-col"
|
|
656
656
|
[class.gap-2xl]="wizardEnabled()"
|
|
@@ -824,7 +824,7 @@ import*as l from"@angular/core";import{InjectionToken as x,inject as p,Injectabl
|
|
|
824
824
|
}
|
|
825
825
|
</div>
|
|
826
826
|
</ng-template>
|
|
827
|
-
`,isInline:!0,dependencies:[{kind:"ngmodule",type:
|
|
827
|
+
`,isInline:!0,dependencies:[{kind:"ngmodule",type:M},{kind:"directive",type:x.ɵNgNoValidate,selector:"form:not([ngNoForm]):not([ngNativeValidate])"},{kind:"directive",type:x.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:x.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"component",type:I,selector:"dga-dynamic-form-field",inputs:["field","form","locale","required","error","runtimeOptions","consentBaseUrl"],outputs:["optionsLoaded","fileDownload"]},{kind:"component",type:De,selector:"dga-alert",inputs:["variant","title","shadow","color","display","dismissible","closeLabel"],outputs:["dismissed"]},{kind:"component",type:Se,selector:"dga-badge",inputs:["variant","size"]},{kind:"directive",type:z,selector:"button[dgaButton], a[dgaButton]",inputs:["variant","size","iconOnly","cooldownMs","loading","dgaButtonClass"]},{kind:"component",type:we,selector:"dga-card",inputs:["appearance","padding","border","shadow","title","description","titleTruncate","descriptionClamp","icon","iconSize","iconAppearance","badges","badgeSize","primaryLabel","primaryHref","primaryVariant","secondaryLabel","secondaryHref","secondaryVariant","actionSize","actionsAlign","interactive"],outputs:["primaryClick","secondaryClick"]},{kind:"component",type:k,selector:"dga-icon",inputs:["name","glyph","size","tone","label"]},{kind:"component",type:Ce,selector:"dga-progress",inputs:["value","size","tone","appearance","showValue","valueText","label"]},{kind:"component",type:Le,selector:"dga-stepper",inputs:["steps","active","label","beforeActiveChange"],outputs:["activeChange"]},{kind:"directive",type:oe,selector:"[ngComponentOutlet]",inputs:["ngComponentOutlet","ngComponentOutletInputs","ngComponentOutletInjector","ngComponentOutletEnvironmentInjector","ngComponentOutletContent","ngComponentOutletNgModule"],exportAs:["ngComponentOutlet"]},{kind:"directive",type:re,selector:"[ngTemplateOutlet]",inputs:["ngTemplateOutletContext","ngTemplateOutlet","ngTemplateOutletInjector"]}],changeDetection:l.ChangeDetectionStrategy.OnPush})}l.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.1.5",ngImport:l,type:A,decorators:[{type:_,args:[{selector:"dga-dynamic-form",standalone:!0,imports:[M,I,De,Se,z,we,k,Ce,Le,oe,re],template:`
|
|
828
828
|
<form
|
|
829
829
|
class="flex w-full flex-col"
|
|
830
830
|
[class.gap-2xl]="wizardEnabled()"
|
|
@@ -998,4 +998,4 @@ import*as l from"@angular/core";import{InjectionToken as x,inject as p,Injectabl
|
|
|
998
998
|
}
|
|
999
999
|
</div>
|
|
1000
1000
|
</ng-template>
|
|
1001
|
-
`,changeDetection
|
|
1001
|
+
`,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"]}],fileDownload:[{type:l.Output,args:["fileDownload"]}]}});export{K as DGA_CAPTCHA_ADAPTER,Fe as DGA_DATE_RANGE_PAIRS,Te as DGA_DYNAMIC_FORM_FIELD_REGISTRY,H as DGA_FORM_I18N_ADAPTER,G as DGA_FORM_TOAST_ADAPTER,W as DGA_HTTP_SECURITY,U as DGA_LOOKUP_ADAPTER,R as DGA_SUBMIT_ADAPTER,A as DgaDynamicForm,I as DgaDynamicFormField,O as DgaDynamicFormFieldRegistry,F as DgaDynamicFormService,Je as createDgaToastAdapter,Ke as createHttpLookupAdapter,Ye as createHttpSubmitAdapter,je as defaultFormI18nAdapter,Ae as dgaApplyCrossFieldValidators,N as dgaAssertSafeHttpUrl,ze as dgaBuildFormGroup,J as dgaBuildValidators,Re as dgaCollectFields,Pe as dgaCreateControl,Me as dgaDefaultValueForField,$e as dgaDetectLocale,qe as dgaFindSelectedOption,Z as dgaIsFieldVisible,ee as dgaIsRequiredWhen,Dt as dgaLocalizedValues,Oe as dgaPasswordMatchValidator,Ne as dgaPhoneFieldValidator,S as dgaReadLocalizedMap,g as dgaResolveLabel,Y as dgaSaudiMobileValidator,Q as dgaSetControlValidators,_e as dgaToSelectOptions,Ge as emptyLookupAdapter,Ue as noopCaptchaAdapter,He as normalizeLookupOption,It as provideDgaDynamicForm,kt as resolveFormLabel};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a.nemreen/dga-dynamic-form",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
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": {
|
|
@@ -457,6 +457,15 @@ declare function dgaFindSelectedOption(field: DgaFormField | undefined, value: u
|
|
|
457
457
|
declare function dgaIsFieldVisible(field: DgaFormField, values: Record<string, unknown>, getOptions?: (name: string) => DgaFormFieldOption[] | undefined, getField?: (name: string) => DgaFormField | undefined): boolean;
|
|
458
458
|
declare function dgaIsRequiredWhen(field: DgaFormField, values: Record<string, unknown>, getOptions?: (name: string) => DgaFormFieldOption[] | undefined, getField?: (name: string) => DgaFormField | undefined): boolean;
|
|
459
459
|
|
|
460
|
+
/** Unique non-empty strings from a locale map. */
|
|
461
|
+
declare function dgaLocalizedValues(label: Partial<DgaFormLabel> | DgaFormLabel | undefined): string[];
|
|
462
|
+
/**
|
|
463
|
+
* Maps lookup/schema options to `dga-select` / multiselect options.
|
|
464
|
+
* Label is the active locale only. `dga-select` renders `keywords` as visible
|
|
465
|
+
* secondary text, so we never dump other languages there.
|
|
466
|
+
*/
|
|
467
|
+
declare function dgaToSelectOptions(options: DgaFormFieldOption[], locale: DgaFormLocale): DgaSelectOption[];
|
|
468
|
+
|
|
460
469
|
/** Known start/end date field pairs used by cross-field validators. */
|
|
461
470
|
declare const DGA_DATE_RANGE_PAIRS: ReadonlyArray<[string, string]>;
|
|
462
471
|
declare function dgaPasswordMatchValidator(passwordControl: AbstractControl): ValidatorFn;
|
|
@@ -490,9 +499,17 @@ interface DgaHttpAdapterSecurityOptions extends DgaHttpSecurityOptions {
|
|
|
490
499
|
declare function dgaAssertSafeHttpUrl(raw: string, allowedOrigins?: string[]): string;
|
|
491
500
|
/**
|
|
492
501
|
* HTTP lookup that expects `{domain}/lookup/{name}` JSON arrays.
|
|
493
|
-
* Maps
|
|
502
|
+
* Maps `{ Id, Title: { En, Ar } }`, `{ Code, Name: { En, Ar } }`,
|
|
503
|
+
* and flat `{ id|value, titleEn|labelEn|en, titleAr|labelAr|ar }` shapes.
|
|
494
504
|
*/
|
|
495
505
|
declare function createHttpLookupAdapter(http?: HttpClient, security?: DgaHttpAdapterSecurityOptions): DgaLookupAdapter;
|
|
506
|
+
/**
|
|
507
|
+
* Maps lookup rows to form options.
|
|
508
|
+
* Nested `{ Title: { En, Ar, Fr } }` keeps every locale key (lowercased).
|
|
509
|
+
* Also reads `{ Code, Name }`, flat `titleEn` / `titleFr`, and falls back to
|
|
510
|
+
* the option value only when no title is present.
|
|
511
|
+
*/
|
|
512
|
+
declare function normalizeLookupOption(row: unknown): DgaFormFieldOption;
|
|
496
513
|
declare function createHttpSubmitAdapter(http?: HttpClient, security?: DgaHttpAdapterSecurityOptions): DgaSubmitAdapter;
|
|
497
514
|
declare function createDgaToastAdapter(toasts?: DgaToastService): DgaFormToastAdapter;
|
|
498
515
|
interface ProvideDgaDynamicFormOptions {
|
|
@@ -520,7 +537,13 @@ declare function resolveFormLabel(label: DgaFormLabel | undefined, locale: DgaFo
|
|
|
520
537
|
|
|
521
538
|
type LocalizedMap = Partial<Record<string, string>>;
|
|
522
539
|
declare function dgaResolveLabel(label: LocalizedMap | DgaFormLabel | undefined, locale: DgaFormLocale, fallback?: string): string;
|
|
540
|
+
/**
|
|
541
|
+
* Reads a lookup title/name/description into a locale → string map.
|
|
542
|
+
* Nested `{ En, Ar, Fr }` / `{ en, ar, ur }` objects keep every locale key
|
|
543
|
+
* (lowercased). A plain string is stored as both `en` and `ar`.
|
|
544
|
+
*/
|
|
545
|
+
declare function dgaReadLocalizedMap(raw: unknown): LocalizedMap | null;
|
|
523
546
|
declare function dgaDetectLocale(): DgaFormLocale;
|
|
524
547
|
|
|
525
|
-
export { DGA_CAPTCHA_ADAPTER, DGA_DATE_RANGE_PAIRS, DGA_DYNAMIC_FORM_FIELD_REGISTRY, DGA_FORM_I18N_ADAPTER, DGA_FORM_TOAST_ADAPTER, DGA_HTTP_SECURITY, DGA_LOOKUP_ADAPTER, DGA_SUBMIT_ADAPTER, DgaDynamicForm, DgaDynamicFormField, DgaDynamicFormFieldRegistry, DgaDynamicFormService, createDgaToastAdapter, createHttpLookupAdapter, createHttpSubmitAdapter, defaultFormI18nAdapter, dgaApplyCrossFieldValidators, dgaAssertSafeHttpUrl, dgaBuildFormGroup, dgaBuildValidators, dgaCollectFields, dgaCreateControl, dgaDefaultValueForField, dgaDetectLocale, dgaFindSelectedOption, dgaIsFieldVisible, dgaIsRequiredWhen, dgaPasswordMatchValidator, dgaPhoneFieldValidator, dgaResolveLabel, dgaSaudiMobileValidator, dgaSetControlValidators, emptyLookupAdapter, noopCaptchaAdapter, provideDgaDynamicForm, resolveFormLabel };
|
|
548
|
+
export { DGA_CAPTCHA_ADAPTER, DGA_DATE_RANGE_PAIRS, DGA_DYNAMIC_FORM_FIELD_REGISTRY, DGA_FORM_I18N_ADAPTER, DGA_FORM_TOAST_ADAPTER, DGA_HTTP_SECURITY, DGA_LOOKUP_ADAPTER, DGA_SUBMIT_ADAPTER, DgaDynamicForm, DgaDynamicFormField, DgaDynamicFormFieldRegistry, DgaDynamicFormService, createDgaToastAdapter, createHttpLookupAdapter, createHttpSubmitAdapter, defaultFormI18nAdapter, dgaApplyCrossFieldValidators, dgaAssertSafeHttpUrl, dgaBuildFormGroup, dgaBuildValidators, dgaCollectFields, dgaCreateControl, dgaDefaultValueForField, dgaDetectLocale, dgaFindSelectedOption, dgaIsFieldVisible, dgaIsRequiredWhen, dgaLocalizedValues, dgaPasswordMatchValidator, dgaPhoneFieldValidator, dgaReadLocalizedMap, dgaResolveLabel, dgaSaudiMobileValidator, dgaSetControlValidators, dgaToSelectOptions, emptyLookupAdapter, noopCaptchaAdapter, normalizeLookupOption, provideDgaDynamicForm, resolveFormLabel };
|
|
526
549
|
export type { DgaCaptchaAdapter, DgaDynamicFieldHostContext, DgaDynamicFieldRenderer, DgaDynamicFormConfig, DgaDynamicFormPayloadTransformer, DgaExistingAttachment, DgaFormField, DgaFormFieldColumns, DgaFormFieldOption, DgaFormFieldType, DgaFormI18nAdapter, DgaFormLabel, DgaFormLocale, DgaFormPhoneCountry, DgaFormStep, DgaFormToastAdapter, DgaHttpAdapterSecurityOptions, DgaHttpMethod, DgaHttpSecurityOptions, DgaInputRestriction, DgaLookupAdapter, DgaLookupRequest, DgaStagedFileRef, DgaSubmitAdapter, DgaSubmitRequest, DgaToastVariant, DgaWizardConfig, ProvideDgaDynamicFormOptions };
|