ngx-form-draft 2.2.11 → 2.2.13
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/LICENSE +21 -21
- package/README.md +206 -206
- package/esm2020/form-draft-banner.component.mjs +84 -84
- package/esm2020/form-draft.directive.mjs +267 -267
- package/esm2020/form-draft.service.mjs +92 -92
- package/esm2020/index.mjs +4 -4
- package/esm2020/ngx-form-draft.mjs +4 -4
- package/esm2020/ngx-form-draft.module.mjs +19 -19
- package/fesm2015/ngx-form-draft.mjs +446 -446
- package/fesm2015/ngx-form-draft.mjs.map +1 -1
- package/fesm2020/ngx-form-draft.mjs +439 -439
- package/fesm2020/ngx-form-draft.mjs.map +1 -1
- package/form-draft-banner.component.d.ts +14 -14
- package/form-draft.directive.d.ts +56 -56
- package/form-draft.service.d.ts +35 -35
- package/index.d.ts +4 -4
- package/ngx-form-draft.module.d.ts +9 -9
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngx-form-draft.mjs","sources":["../../src/form-draft-banner.component.ts","../../src/form-draft.service.ts","../../src/form-draft.directive.ts","../../src/ngx-form-draft.module.ts","../../src/ngx-form-draft.ts"],"sourcesContent":["import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'ngx-form-draft-banner',\r\n template: `\r\n <div class=\"form-draft-banner\" *ngIf=\"visible\">\r\n <div class=\"form-draft-banner__icon\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12 8V12L14.5 14.5\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" stroke-width=\"2\"/>\r\n </svg>\r\n </div>\r\n <div class=\"form-draft-banner__content\">\r\n <span class=\"form-draft-banner__text\">\r\n <span *ngIf=\"isRestored\">{{ restoredText }}</span>\r\n <span *ngIf=\"!isRestored\">{{ savedText }}</span>\r\n <span class=\"form-draft-banner__time\" *ngIf=\"timeLabel && isRestored\">\r\n · {{ savedLabel }} {{ timeLabel }}\r\n </span>\r\n </span>\r\n </div>\r\n <div class=\"form-draft-banner__actions\">\r\n <button class=\"form-draft-banner__btn form-draft-banner__btn--discard\" (click)=\"discard.emit()\" type=\"button\">\r\n ✕ {{ discardText }}\r\n </button>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host { display: block; width: 100%; }\r\n .form-draft-banner {\r\n display: flex; align-items: center; gap: 10px; padding: 10px 14px; margin-bottom: 12px;\r\n border-radius: 8px; background: linear-gradient(135deg, #eef6ff 0%, #f0f4ff 100%);\r\n border: 1px solid #c5ddf8; box-shadow: 0 2px 8px rgba(18, 138, 214, 0.08);\r\n animation: slideDown 250ms cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n @keyframes slideDown {\r\n from { opacity: 0; transform: translateY(-8px); }\r\n to { opacity: 1; transform: translateY(0); }\r\n }\r\n .form-draft-banner__icon {\r\n display: flex; align-items: center; justify-content: center; width: 32px; height: 32px;\r\n border-radius: 6px; background: linear-gradient(135deg, #128ad6, #22b9ff); color: #fff; flex-shrink: 0;\r\n }\r\n .form-draft-banner__content { flex: 1; min-width: 0; }\r\n .form-draft-banner__text { font-size: 13px; font-weight: 600; color: #1a3a5c; }\r\n .form-draft-banner__time { font-weight: 400; color: #6b8aaa; font-size: 12px; }\r\n .form-draft-banner__actions { flex-shrink: 0; }\r\n .form-draft-banner__btn {\r\n border: none; padding: 5px 12px; border-radius: 6px; font-size: 12px;\r\n font-weight: 600; cursor: pointer; transition: all 0.2s ease;\r\n }\r\n .form-draft-banner__btn--discard { background: transparent; color: #8899a6; border: 1px solid #d0dce6; }\r\n .form-draft-banner__btn--discard:hover { background: #fef2f2; color: #e62e43; border-color: #e62e43; }\r\n `],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class FormDraftBannerComponent {\r\n @Input() visible = false;\r\n @Input() timeLabel = '';\r\n @Input() isRestored = false;\r\n @Input() restoredText = 'Draft restored';\r\n @Input() savedText = 'Draft saved';\r\n @Input() savedLabel = 'saved';\r\n @Input() discardText = 'Discard';\r\n @Output() discard = new EventEmitter<void>();\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\nexport interface FormDraftData {\r\n values: Record<string, any>;\r\n savedAt: number;\r\n formId: string;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class FormDraftService {\r\n private readonly STORAGE_PREFIX = 'form_draft_';\r\n private readonly MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;\r\n\r\n /** Registry of formId -> reset callback (used by directive to reset form + banner) */\r\n private resetRegistry = new Map<string, () => void>();\r\n\r\n /**\r\n * Register a callback to reset the form and draft UI for the given formId.\r\n * Called by the directive; apps should use clearAndReset(formId) instead.\r\n */\r\n registerReset(formId: string, resetFn: () => void): void {\r\n this.resetRegistry.set(formId, resetFn);\r\n }\r\n\r\n /**\r\n * Unregister the reset callback for the given formId.\r\n * Called by the directive on destroy.\r\n */\r\n unregisterReset(formId: string): void {\r\n this.resetRegistry.delete(formId);\r\n }\r\n\r\n /**\r\n * Clear the draft from storage and, if a directive is registered for this formId,\r\n * reset the form and dismiss the draft banner in one call.\r\n * Use this on form submit to clear local storage and reset the form in one line.\r\n */\r\n clearAndReset(formId: string): void {\r\n this.clear(formId);\r\n this.resetRegistry.get(formId)?.();\r\n }\r\n\r\n private buildKey(formId: string): string {\r\n return `${this.STORAGE_PREFIX}${formId}`;\r\n }\r\n\r\n save(formId: string, values: Record<string, any>): void {\r\n try {\r\n const draft: FormDraftData = { values, savedAt: Date.now(), formId };\r\n localStorage.setItem(this.buildKey(formId), JSON.stringify(draft));\r\n } catch (e) {\r\n console.warn('[FormDraft] Could not save draft:', e);\r\n }\r\n }\r\n\r\n load(formId: string): FormDraftData | null {\r\n try {\r\n const raw = localStorage.getItem(this.buildKey(formId));\r\n if (!raw) return null;\r\n\r\n const draft: FormDraftData = JSON.parse(raw);\r\n if (Date.now() - draft.savedAt > this.MAX_AGE_MS) {\r\n this.clear(formId);\r\n return null;\r\n }\r\n return draft;\r\n } catch (e) {\r\n console.warn('[FormDraft] Could not load draft:', e);\r\n return null;\r\n }\r\n }\r\n\r\n clear(formId: string): void {\r\n try {\r\n localStorage.removeItem(this.buildKey(formId));\r\n } catch (e) {\r\n console.warn('[FormDraft] Could not clear draft:', e);\r\n }\r\n }\r\n\r\n formatTimestamp(timestamp: number): string {\r\n const seconds = Math.floor((Date.now() - timestamp) / 1000);\r\n if (seconds < 60) return 'just now';\r\n const minutes = Math.floor(seconds / 60);\r\n if (minutes < 60) return `${minutes}m ago`;\r\n const hours = Math.floor(minutes / 60);\r\n if (hours < 24) return `${hours}h ago`;\r\n const days = Math.floor(hours / 24);\r\n return `${days}d ago`;\r\n }\r\n}\r\n","import {\n Directive, Input, OnInit, AfterViewInit, OnDestroy, Optional, ComponentRef,\n ViewContainerRef, ChangeDetectorRef, ElementRef, Renderer2,\n} from '@angular/core';\nimport { NgForm, FormGroupDirective, AbstractControl, FormArray, FormGroup, FormControl } from '@angular/forms';\nimport { Subject } from 'rxjs';\nimport { debounceTime, takeUntil, skip, filter } from 'rxjs/operators';\nimport { FormDraftService } from './form-draft.service';\nimport { FormDraftBannerComponent } from './form-draft-banner.component';\n\n/**\n * Auto-saves and restores form drafts\n * \n * @example\n * <form [formGroup]=\"myForm\" ngxFormDraft=\"myFormId\">\n * \n * @example\n * <form [formGroup]=\"myForm\" [ngxFormDraft]=\"'edit_' + entityId\" [draftExcludeFields]=\"['password']\">\n */\n@Directive({\n selector: '[ngxFormDraft]',\n})\nexport class FormDraftDirective implements OnInit, AfterViewInit, OnDestroy {\n @Input('ngxFormDraft') formId!: string;\n @Input() draftDebounce = 800;\n @Input() draftExcludeFields: string[] = [];\n @Input() draftShowOnChange = false;\n @Input() draftRestoredText = 'Draft restored';\n @Input() draftSavedText = 'Draft saved';\n @Input() draftSavedLabel = 'saved';\n @Input() draftDiscardText = 'Discard';\n\n private destroy$ = new Subject<void>();\n private bannerRef: ComponentRef<FormDraftBannerComponent> | null = null;\n private formControl: AbstractControl | null = null;\n private initialValues: Record<string, any> = {};\n private isRestoring = false;\n\n constructor(\n @Optional() private formGroupDir: FormGroupDirective,\n @Optional() private ngForm: NgForm,\n private draftService: FormDraftService,\n private viewContainerRef: ViewContainerRef,\n private cdRef: ChangeDetectorRef,\n private elRef: ElementRef,\n private renderer: Renderer2,\n ) {}\n\n ngOnInit(): void {\n this.formControl = this.formGroupDir?.form || this.ngForm?.form || null;\n if (!this.formControl || !this.formId) return;\n\n this.draftService.registerReset(this.formId, () => this.performResetAndDestroyBanner());\n\n // For reactive forms, capture initial values and restore draft immediately\n if (this.formGroupDir) {\n this.initialValues = JSON.parse(JSON.stringify(this.formControl.value));\n \n const draft = this.draftService.load(this.formId);\n if (draft) {\n this.restoreDraft(draft.values);\n this.showBanner(draft.savedAt, true);\n }\n }\n\n let hasUserInteraction = false;\n \n this.formControl.valueChanges\n .pipe(\n filter(() => {\n if (this.isRestoring) return false;\n if (this.ngForm && !hasUserInteraction) {\n const currentValues = this.formControl?.value || {};\n const isDifferent = JSON.stringify(currentValues) !== JSON.stringify(this.initialValues);\n if (isDifferent) {\n hasUserInteraction = true;\n return true;\n }\n return false;\n }\n return true;\n }),\n debounceTime(this.draftDebounce),\n takeUntil(this.destroy$)\n )\n .subscribe((values) => {\n this.saveDraft(values);\n });\n }\n\n ngAfterViewInit(): void {\n if (this.ngForm && this.formControl) {\n const draft = this.draftService.load(this.formId);\n \n if (draft) {\n this.isRestoring = true;\n }\n \n setTimeout(() => {\n if (draft) {\n this.restoreDraft(draft.values);\n this.showBanner(draft.savedAt, true);\n this.initialValues = {};\n } else {\n this.initialValues = JSON.parse(JSON.stringify(this.formControl!.value));\n }\n }, 0);\n }\n }\n\n ngOnDestroy(): void {\n this.draftService.unregisterReset(this.formId);\n this.destroy$.next();\n this.destroy$.complete();\n this.destroyBanner();\n }\n\n private saveDraft(values: Record<string, any>): void {\n const filtered = this.filterFields(values);\n \n // Don't save if empty\n if (this.isAllEmpty(filtered)) {\n return;\n }\n\n // Don't save if matches initial values (even if initial is empty)\n if (this.matchesInitialValues(filtered)) {\n return;\n }\n\n this.draftService.save(this.formId, filtered);\n if (this.draftShowOnChange && !this.bannerRef) {\n this.showBanner(Date.now(), false);\n }\n }\n\n private filterFields(values: Record<string, any>): Record<string, any> {\n if (!this.draftExcludeFields.length) return values;\n const result = { ...values };\n this.draftExcludeFields.forEach(field => delete result[field]);\n return result;\n }\n\n private isAllEmpty(values: Record<string, any>): boolean {\n return Object.values(values).every(\n v => v === null || v === undefined || v === '' || (Array.isArray(v) && v.length === 0)\n );\n }\n\n private matchesInitialValues(values: Record<string, any>): boolean {\n return JSON.stringify(values) === JSON.stringify(this.initialValues);\n }\n\n private restoreDraft(values: Record<string, any>): void {\n if (!this.formControl) return;\n this.isRestoring = true;\n\n const form = this.formGroupDir?.form || this.ngForm?.form;\n if (form) {\n this.prepareFormArrays(form, values);\n form.patchValue(values);\n }\n\n setTimeout(() => this.isRestoring = false, 100);\n }\n\n private prepareFormArrays(control: AbstractControl, value: any): void {\n if (!control || value == null) return;\n\n if (control instanceof FormGroup && value && typeof value === 'object' && !Array.isArray(value)) {\n Object.keys(value).forEach(key => {\n const childControl = control.get(key);\n if (childControl) this.prepareFormArrays(childControl, value[key]);\n });\n return;\n }\n\n if (control instanceof FormArray && Array.isArray(value)) {\n const formArray = control as FormArray;\n\n while (formArray.length < value.length) {\n const template = formArray.at(0);\n if (template instanceof FormGroup) {\n const newGroup = new FormGroup({});\n Object.keys(template.controls).forEach(ctrlName => {\n const existing = template.get(ctrlName) as AbstractControl;\n if (existing instanceof FormArray) {\n newGroup.addControl(ctrlName, new FormArray([]));\n } else if (existing instanceof FormGroup) {\n newGroup.addControl(ctrlName, new FormGroup({}));\n } else {\n newGroup.addControl(ctrlName, new FormControl(null));\n }\n });\n formArray.push(newGroup);\n } else if (template) {\n formArray.push(new FormControl(null));\n } else {\n const firstValue = value[0];\n if (firstValue && typeof firstValue === 'object' && !Array.isArray(firstValue)) {\n const group = new FormGroup({});\n Object.keys(firstValue).forEach(key => group.addControl(key, new FormControl(null)));\n formArray.push(group);\n } else {\n formArray.push(new FormControl(null));\n }\n }\n }\n\n while (formArray.length > value.length) {\n formArray.removeAt(formArray.length - 1);\n }\n\n value.forEach((childValue, index) => {\n this.prepareFormArrays(formArray.at(index), childValue);\n });\n }\n }\n\n private discardDraft(): void {\n this.draftService.clear(this.formId);\n this.performResetAndDestroyBanner();\n }\n\n /**\n * Resets the form to initial values and destroys the draft banner.\n * Used by the service when clearAndReset(formId) is called (e.g. on submit).\n */\n public performResetAndDestroyBanner(): void {\n if (this.formControl) {\n this.isRestoring = true;\n const form = this.formGroupDir?.form || this.ngForm?.form;\n if (form) {\n this.prepareFormArrays(form, this.initialValues);\n form.reset(this.initialValues);\n }\n setTimeout(() => {\n this.isRestoring = false;\n }, this.draftDebounce + 200);\n }\n this.destroyBanner();\n }\n\n private showBanner(savedAt: number, isRestored = false): void {\n this.bannerRef = this.viewContainerRef.createComponent(FormDraftBannerComponent);\n this.bannerRef.setInput('visible', true);\n this.bannerRef.setInput('isRestored', isRestored);\n this.bannerRef.setInput('timeLabel', isRestored ? this.draftService.formatTimestamp(savedAt) : '');\n this.bannerRef.setInput('restoredText', this.draftRestoredText);\n this.bannerRef.setInput('savedText', this.draftSavedText);\n this.bannerRef.setInput('savedLabel', this.draftSavedLabel);\n this.bannerRef.setInput('discardText', this.draftDiscardText);\n\n this.bannerRef.instance.discard.subscribe(() => this.discardDraft());\n\n const bannerEl = this.bannerRef.location.nativeElement;\n const formEl = this.elRef.nativeElement;\n this.renderer.insertBefore(formEl, bannerEl, formEl.firstChild);\n\n this.cdRef.detectChanges();\n }\n\n private destroyBanner(): void {\n if (this.bannerRef) {\n this.bannerRef.destroy();\n this.bannerRef = null;\n }\n }\n\n public clearDraft(): void {\n this.draftService.clear(this.formId);\n this.destroyBanner();\n }\n}\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormDraftDirective } from './form-draft.directive';\r\nimport { FormDraftBannerComponent } from './form-draft-banner.component';\r\n\r\n@NgModule({\r\n declarations: [FormDraftDirective, FormDraftBannerComponent],\r\n imports: [CommonModule],\r\n exports: [FormDraftDirective, FormDraftBannerComponent],\r\n})\r\nexport class NgxFormDraftModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2.FormDraftService"],"mappings":";;;;;;;;;MAyDa,wBAAwB,CAAA;AAvDrC,IAAA,WAAA,GAAA;QAwDW,IAAO,CAAA,OAAA,GAAG,KAAK,CAAC;QAChB,IAAS,CAAA,SAAA,GAAG,EAAE,CAAC;QACf,IAAU,CAAA,UAAA,GAAG,KAAK,CAAC;QACnB,IAAY,CAAA,YAAA,GAAG,gBAAgB,CAAC;QAChC,IAAS,CAAA,SAAA,GAAG,aAAa,CAAC;QAC1B,IAAU,CAAA,UAAA,GAAG,OAAO,CAAC;QACrB,IAAW,CAAA,WAAA,GAAG,SAAS,CAAC;AACvB,QAAA,IAAA,CAAA,OAAO,GAAG,IAAI,YAAY,EAAQ,CAAC;AAC9C,KAAA;;qHATY,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAxB,wBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,wBAAwB,EArDzB,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,SAAA,EAAA,WAAA,EAAA,UAAA,EAAA,YAAA,EAAA,YAAA,EAAA,cAAA,EAAA,SAAA,EAAA,WAAA,EAAA,UAAA,EAAA,YAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,OAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;AAuBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,gpCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;2FA8BU,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBAvDpC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,uBAAuB,EACvB,QAAA,EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBT,EA4BgB,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,MAAA,EAAA,CAAA,gpCAAA,CAAA,EAAA,CAAA;8BAGtC,OAAO,EAAA,CAAA;sBAAf,KAAK;gBACG,SAAS,EAAA,CAAA;sBAAjB,KAAK;gBACG,UAAU,EAAA,CAAA;sBAAlB,KAAK;gBACG,YAAY,EAAA,CAAA;sBAApB,KAAK;gBACG,SAAS,EAAA,CAAA;sBAAjB,KAAK;gBACG,UAAU,EAAA,CAAA;sBAAlB,KAAK;gBACG,WAAW,EAAA,CAAA;sBAAnB,KAAK;gBACI,OAAO,EAAA,CAAA;sBAAhB,MAAM;;;MCtDI,gBAAgB,CAAA;AAH7B,IAAA,WAAA,GAAA;QAImB,IAAc,CAAA,cAAA,GAAG,aAAa,CAAC;QAC/B,IAAU,CAAA,UAAA,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;;AAG9C,QAAA,IAAA,CAAA,aAAa,GAAG,IAAI,GAAG,EAAsB,CAAC;AA4EvD,KAAA;AA1EC;;;AAGG;IACH,aAAa,CAAC,MAAc,EAAE,OAAmB,EAAA;QAC/C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACzC;AAED;;;AAGG;AACH,IAAA,eAAe,CAAC,MAAc,EAAA;AAC5B,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;KACnC;AAED;;;;AAIG;AACH,IAAA,aAAa,CAAC,MAAc,EAAA;AAC1B,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACnB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;KACpC;AAEO,IAAA,QAAQ,CAAC,MAAc,EAAA;AAC7B,QAAA,OAAO,GAAG,IAAI,CAAC,cAAc,CAAG,EAAA,MAAM,EAAE,CAAC;KAC1C;IAED,IAAI,CAAC,MAAc,EAAE,MAA2B,EAAA;QAC9C,IAAI;AACF,YAAA,MAAM,KAAK,GAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC;AACrE,YAAA,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACpE,SAAA;AAAC,QAAA,OAAO,CAAC,EAAE;AACV,YAAA,OAAO,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC,CAAC;AACtD,SAAA;KACF;AAED,IAAA,IAAI,CAAC,MAAc,EAAA;QACjB,IAAI;AACF,YAAA,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACxD,YAAA,IAAI,CAAC,GAAG;AAAE,gBAAA,OAAO,IAAI,CAAC;YAEtB,MAAM,KAAK,GAAkB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAC7C,YAAA,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;AAChD,gBAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACnB,gBAAA,OAAO,IAAI,CAAC;AACb,aAAA;AACD,YAAA,OAAO,KAAK,CAAC;AACd,SAAA;AAAC,QAAA,OAAO,CAAC,EAAE;AACV,YAAA,OAAO,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC,CAAC;AACrD,YAAA,OAAO,IAAI,CAAC;AACb,SAAA;KACF;AAED,IAAA,KAAK,CAAC,MAAc,EAAA;QAClB,IAAI;YACF,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAChD,SAAA;AAAC,QAAA,OAAO,CAAC,EAAE;AACV,YAAA,OAAO,CAAC,IAAI,CAAC,oCAAoC,EAAE,CAAC,CAAC,CAAC;AACvD,SAAA;KACF;AAED,IAAA,eAAe,CAAC,SAAiB,EAAA;AAC/B,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,IAAI,CAAC,CAAC;QAC5D,IAAI,OAAO,GAAG,EAAE;AAAE,YAAA,OAAO,UAAU,CAAC;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACzC,IAAI,OAAO,GAAG,EAAE;YAAE,OAAO,CAAA,EAAG,OAAO,CAAA,KAAA,CAAO,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACvC,IAAI,KAAK,GAAG,EAAE;YAAE,OAAO,CAAA,EAAG,KAAK,CAAA,KAAA,CAAO,CAAC;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;QACpC,OAAO,CAAA,EAAG,IAAI,CAAA,KAAA,CAAO,CAAC;KACvB;;6GAhFU,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAhB,gBAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cAFf,MAAM,EAAA,CAAA,CAAA;2FAEP,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAH5B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA,CAAA;;;ACAD;;;;;;;;AAQG;MAIU,kBAAkB,CAAA;AAgB7B,IAAA,WAAA,CACsB,YAAgC,EAChC,MAAc,EAC1B,YAA8B,EAC9B,gBAAkC,EAClC,KAAwB,EACxB,KAAiB,EACjB,QAAmB,EAAA;QANP,IAAY,CAAA,YAAA,GAAZ,YAAY,CAAoB;QAChC,IAAM,CAAA,MAAA,GAAN,MAAM,CAAQ;QAC1B,IAAY,CAAA,YAAA,GAAZ,YAAY,CAAkB;QAC9B,IAAgB,CAAA,gBAAA,GAAhB,gBAAgB,CAAkB;QAClC,IAAK,CAAA,KAAA,GAAL,KAAK,CAAmB;QACxB,IAAK,CAAA,KAAA,GAAL,KAAK,CAAY;QACjB,IAAQ,CAAA,QAAA,GAAR,QAAQ,CAAW;QArBpB,IAAa,CAAA,aAAA,GAAG,GAAG,CAAC;QACpB,IAAkB,CAAA,kBAAA,GAAa,EAAE,CAAC;QAClC,IAAiB,CAAA,iBAAA,GAAG,KAAK,CAAC;QAC1B,IAAiB,CAAA,iBAAA,GAAG,gBAAgB,CAAC;QACrC,IAAc,CAAA,cAAA,GAAG,aAAa,CAAC;QAC/B,IAAe,CAAA,eAAA,GAAG,OAAO,CAAC;QAC1B,IAAgB,CAAA,gBAAA,GAAG,SAAS,CAAC;AAE9B,QAAA,IAAA,CAAA,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;QAC/B,IAAS,CAAA,SAAA,GAAkD,IAAI,CAAC;QAChE,IAAW,CAAA,WAAA,GAA2B,IAAI,CAAC;QAC3C,IAAa,CAAA,aAAA,GAAwB,EAAE,CAAC;QACxC,IAAW,CAAA,WAAA,GAAG,KAAK,CAAC;KAUxB;IAEJ,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;QACxE,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;AAE9C,QAAA,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,4BAA4B,EAAE,CAAC,CAAC;;QAGxF,IAAI,IAAI,CAAC,YAAY,EAAE;AACrB,YAAA,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;AAExE,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClD,YAAA,IAAI,KAAK,EAAE;AACT,gBAAA,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAChC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACtC,aAAA;AACF,SAAA;QAED,IAAI,kBAAkB,GAAG,KAAK,CAAC;QAE/B,IAAI,CAAC,WAAW,CAAC,YAAY;AAC1B,aAAA,IAAI,CACH,MAAM,CAAC,MAAK;YACV,IAAI,IAAI,CAAC,WAAW;AAAE,gBAAA,OAAO,KAAK,CAAC;AACnC,YAAA,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,kBAAkB,EAAE;gBACtC,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC;AACpD,gBAAA,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACzF,gBAAA,IAAI,WAAW,EAAE;oBACf,kBAAkB,GAAG,IAAI,CAAC;AAC1B,oBAAA,OAAO,IAAI,CAAC;AACb,iBAAA;AACD,gBAAA,OAAO,KAAK,CAAC;AACd,aAAA;AACD,YAAA,OAAO,IAAI,CAAC;AACd,SAAC,CAAC,EACF,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,EAChC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB;AACA,aAAA,SAAS,CAAC,CAAC,MAAM,KAAI;AACpB,YAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AACzB,SAAC,CAAC,CAAC;KACN;IAED,eAAe,GAAA;AACb,QAAA,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE;AACnC,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAElD,YAAA,IAAI,KAAK,EAAE;AACT,gBAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;AACzB,aAAA;YAED,UAAU,CAAC,MAAK;AACd,gBAAA,IAAI,KAAK,EAAE;AACT,oBAAA,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBAChC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACrC,oBAAA,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;AACzB,iBAAA;AAAM,qBAAA;AACL,oBAAA,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAY,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1E,iBAAA;aACF,EAAE,CAAC,CAAC,CAAC;AACP,SAAA;KACF;IAED,WAAW,GAAA;QACT,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC/C,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;AACrB,QAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;KACtB;AAEO,IAAA,SAAS,CAAC,MAA2B,EAAA;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;;AAG3C,QAAA,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;YAC7B,OAAO;AACR,SAAA;;AAGD,QAAA,IAAI,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE;YACvC,OAAO;AACR,SAAA;QAED,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC9C,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAC7C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;AACpC,SAAA;KACF;AAEO,IAAA,YAAY,CAAC,MAA2B,EAAA;AAC9C,QAAA,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM;AAAE,YAAA,OAAO,MAAM,CAAC;AACnD,QAAA,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;AAC7B,QAAA,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/D,QAAA,OAAO,MAAM,CAAC;KACf;AAEO,IAAA,UAAU,CAAC,MAA2B,EAAA;AAC5C,QAAA,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAChC,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CACvF,CAAC;KACH;AAEO,IAAA,oBAAoB,CAAC,MAA2B,EAAA;AACtD,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;KACtE;AAEO,IAAA,YAAY,CAAC,MAA2B,EAAA;QAC9C,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO;AAC9B,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;AAExB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC1D,QAAA,IAAI,IAAI,EAAE;AACR,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACrC,YAAA,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AACzB,SAAA;AAED,QAAA,UAAU,CAAC,MAAM,IAAI,CAAC,WAAW,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC;KACjD;IAEO,iBAAiB,CAAC,OAAwB,EAAE,KAAU,EAAA;AAC5D,QAAA,IAAI,CAAC,OAAO,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO;AAEtC,QAAA,IAAI,OAAO,YAAY,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC/F,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,IAAG;gBAC/B,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACtC,gBAAA,IAAI,YAAY;oBAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AACrE,aAAC,CAAC,CAAC;YACH,OAAO;AACR,SAAA;QAED,IAAI,OAAO,YAAY,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACxD,MAAM,SAAS,GAAG,OAAoB,CAAC;AAEvC,YAAA,OAAO,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE;gBACtC,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACjC,IAAI,QAAQ,YAAY,SAAS,EAAE;AACjC,oBAAA,MAAM,QAAQ,GAAG,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC;AACnC,oBAAA,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAG;wBAChD,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAoB,CAAC;wBAC3D,IAAI,QAAQ,YAAY,SAAS,EAAE;4BACjC,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;AAClD,yBAAA;6BAAM,IAAI,QAAQ,YAAY,SAAS,EAAE;4BACxC,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;AAClD,yBAAA;AAAM,6BAAA;4BACL,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AACtD,yBAAA;AACH,qBAAC,CAAC,CAAC;AACH,oBAAA,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC1B,iBAAA;AAAM,qBAAA,IAAI,QAAQ,EAAE;oBACnB,SAAS,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AACvC,iBAAA;AAAM,qBAAA;AACL,oBAAA,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AAC5B,oBAAA,IAAI,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;AAC9E,wBAAA,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC;wBAChC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACrF,wBAAA,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACvB,qBAAA;AAAM,yBAAA;wBACL,SAAS,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AACvC,qBAAA;AACF,iBAAA;AACF,aAAA;AAED,YAAA,OAAO,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE;gBACtC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC1C,aAAA;YAED,KAAK,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,KAAK,KAAI;AAClC,gBAAA,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC;AAC1D,aAAC,CAAC,CAAC;AACJ,SAAA;KACF;IAEO,YAAY,GAAA;QAClB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,4BAA4B,EAAE,CAAC;KACrC;AAED;;;AAGG;IACI,4BAA4B,GAAA;QACjC,IAAI,IAAI,CAAC,WAAW,EAAE;AACpB,YAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;AACxB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC1D,YAAA,IAAI,IAAI,EAAE;gBACR,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;AACjD,gBAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AAChC,aAAA;YACD,UAAU,CAAC,MAAK;AACd,gBAAA,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;AAC3B,aAAC,EAAE,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC;AAC9B,SAAA;QACD,IAAI,CAAC,aAAa,EAAE,CAAC;KACtB;AAEO,IAAA,UAAU,CAAC,OAAe,EAAE,UAAU,GAAG,KAAK,EAAA;QACpD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,wBAAwB,CAAC,CAAC;QACjF,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAClD,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACnG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAChE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1D,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5D,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;AAE9D,QAAA,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QAErE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC;AACvD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;AACxC,QAAA,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;AAEhE,QAAA,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;KAC5B;IAEO,aAAa,GAAA;QACnB,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,YAAA,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;AACzB,YAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;AACvB,SAAA;KACF;IAEM,UAAU,GAAA;QACf,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,aAAa,EAAE,CAAC;KACtB;;+GA1PU,kBAAkB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,IAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,KAAA,EAAAA,IAAA,CAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,gBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,SAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;mGAAlB,kBAAkB,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,CAAA,cAAA,EAAA,QAAA,CAAA,EAAA,aAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;2FAAlB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAH9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,gBAAgB;AAC3B,iBAAA,CAAA;;0BAkBI,QAAQ;;0BACR,QAAQ;wLAjBY,MAAM,EAAA,CAAA;sBAA5B,KAAK;uBAAC,cAAc,CAAA;gBACZ,aAAa,EAAA,CAAA;sBAArB,KAAK;gBACG,kBAAkB,EAAA,CAAA;sBAA1B,KAAK;gBACG,iBAAiB,EAAA,CAAA;sBAAzB,KAAK;gBACG,iBAAiB,EAAA,CAAA;sBAAzB,KAAK;gBACG,cAAc,EAAA,CAAA;sBAAtB,KAAK;gBACG,eAAe,EAAA,CAAA;sBAAvB,KAAK;gBACG,gBAAgB,EAAA,CAAA;sBAAxB,KAAK;;;MCpBK,kBAAkB,CAAA;;+GAAlB,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;gHAAlB,kBAAkB,EAAA,YAAA,EAAA,CAJd,kBAAkB,EAAE,wBAAwB,aACjD,YAAY,CAAA,EAAA,OAAA,EAAA,CACZ,kBAAkB,EAAE,wBAAwB,CAAA,EAAA,CAAA,CAAA;AAE3C,kBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,YAHnB,YAAY,CAAA,EAAA,CAAA,CAAA;2FAGX,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAL9B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,YAAY,EAAE,CAAC,kBAAkB,EAAE,wBAAwB,CAAC;oBAC5D,OAAO,EAAE,CAAC,YAAY,CAAC;AACvB,oBAAA,OAAO,EAAE,CAAC,kBAAkB,EAAE,wBAAwB,CAAC;AACxD,iBAAA,CAAA;;;ACTD;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"ngx-form-draft.mjs","sources":["../../src/form-draft-banner.component.ts","../../src/form-draft.service.ts","../../src/form-draft.directive.ts","../../src/ngx-form-draft.module.ts","../../src/ngx-form-draft.ts"],"sourcesContent":["import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';\n\n@Component({\n selector: 'ngx-form-draft-banner',\n template: `\n <div class=\"form-draft-banner\" *ngIf=\"visible\">\n <div class=\"form-draft-banner__icon\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 8V12L14.5 14.5\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" stroke-width=\"2\"/>\n </svg>\n </div>\n <div class=\"form-draft-banner__content\">\n <span class=\"form-draft-banner__text\">\n <span *ngIf=\"isRestored\">{{ restoredText }}</span>\n <span *ngIf=\"!isRestored\">{{ savedText }}</span>\n <span class=\"form-draft-banner__time\" *ngIf=\"timeLabel && isRestored\">\n · {{ savedLabel }} {{ timeLabel }}\n </span>\n </span>\n </div>\n <div class=\"form-draft-banner__actions\">\n <button class=\"form-draft-banner__btn form-draft-banner__btn--discard\" (click)=\"discard.emit()\" type=\"button\">\n ✕ {{ discardText }}\n </button>\n </div>\n </div>\n `,\n styles: [`\n :host { display: block; width: 100%; }\n .form-draft-banner {\n display: flex; align-items: center; gap: 10px; padding: 10px 14px; margin-bottom: 12px;\n border-radius: 8px; background: linear-gradient(135deg, #eef6ff 0%, #f0f4ff 100%);\n border: 1px solid #c5ddf8; box-shadow: 0 2px 8px rgba(18, 138, 214, 0.08);\n animation: slideDown 250ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n @keyframes slideDown {\n from { opacity: 0; transform: translateY(-8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .form-draft-banner__icon {\n display: flex; align-items: center; justify-content: center; width: 32px; height: 32px;\n border-radius: 6px; background: linear-gradient(135deg, #128ad6, #22b9ff); color: #fff; flex-shrink: 0;\n }\n .form-draft-banner__content { flex: 1; min-width: 0; }\n .form-draft-banner__text { font-size: 13px; font-weight: 600; color: #1a3a5c; }\n .form-draft-banner__time { font-weight: 400; color: #6b8aaa; font-size: 12px; }\n .form-draft-banner__actions { flex-shrink: 0; }\n .form-draft-banner__btn {\n border: none; padding: 5px 12px; border-radius: 6px; font-size: 12px;\n font-weight: 600; cursor: pointer; transition: all 0.2s ease;\n }\n .form-draft-banner__btn--discard { background: transparent; color: #8899a6; border: 1px solid #d0dce6; }\n .form-draft-banner__btn--discard:hover { background: #fef2f2; color: #e62e43; border-color: #e62e43; }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FormDraftBannerComponent {\n @Input() visible = false;\n @Input() timeLabel = '';\n @Input() isRestored = false;\n @Input() restoredText = 'Draft restored';\n @Input() savedText = 'Draft saved';\n @Input() savedLabel = 'saved';\n @Input() discardText = 'Discard';\n @Output() discard = new EventEmitter<void>();\n}\n","import { Injectable } from '@angular/core';\n\nexport interface FormDraftData {\n values: Record<string, any>;\n savedAt: number;\n formId: string;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class FormDraftService {\n private readonly STORAGE_PREFIX = 'form_draft_';\n private readonly MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;\n\n /** Registry of formId -> reset callback (used by directive to reset form + banner) */\n private resetRegistry = new Map<string, () => void>();\n\n /**\n * Register a callback to reset the form and draft UI for the given formId.\n * Called by the directive; apps should use clearAndReset(formId) instead.\n */\n registerReset(formId: string, resetFn: () => void): void {\n this.resetRegistry.set(formId, resetFn);\n }\n\n /**\n * Unregister the reset callback for the given formId.\n * Called by the directive on destroy.\n */\n unregisterReset(formId: string): void {\n this.resetRegistry.delete(formId);\n }\n\n /**\n * Clear the draft from storage and, if a directive is registered for this formId,\n * reset the form and dismiss the draft banner in one call.\n * Use this on form submit to clear local storage and reset the form in one line.\n */\n clearAndReset(formId: string): void {\n this.clear(formId);\n this.resetRegistry.get(formId)?.();\n }\n\n private buildKey(formId: string): string {\n return `${this.STORAGE_PREFIX}${formId}`;\n }\n\n save(formId: string, values: Record<string, any>): void {\n try {\n const draft: FormDraftData = { values, savedAt: Date.now(), formId };\n localStorage.setItem(this.buildKey(formId), JSON.stringify(draft));\n } catch (e) {\n console.warn('[FormDraft] Could not save draft:', e);\n }\n }\n\n load(formId: string): FormDraftData | null {\n try {\n const raw = localStorage.getItem(this.buildKey(formId));\n if (!raw) return null;\n\n const draft: FormDraftData = JSON.parse(raw);\n if (Date.now() - draft.savedAt > this.MAX_AGE_MS) {\n this.clear(formId);\n return null;\n }\n return draft;\n } catch (e) {\n console.warn('[FormDraft] Could not load draft:', e);\n return null;\n }\n }\n\n clear(formId: string): void {\n try {\n localStorage.removeItem(this.buildKey(formId));\n } catch (e) {\n console.warn('[FormDraft] Could not clear draft:', e);\n }\n }\n\n formatTimestamp(timestamp: number): string {\n const seconds = Math.floor((Date.now() - timestamp) / 1000);\n if (seconds < 60) return 'just now';\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n }\n}\n","import {\n Directive, Input, OnInit, AfterViewInit, OnDestroy, Optional, ComponentRef,\n ViewContainerRef, ChangeDetectorRef, ElementRef, Renderer2,\n} from '@angular/core';\nimport { NgForm, FormGroupDirective, AbstractControl, FormArray, FormGroup, FormControl } from '@angular/forms';\nimport { Subject } from 'rxjs';\nimport { debounceTime, takeUntil, skip, filter } from 'rxjs/operators';\nimport { FormDraftService } from './form-draft.service';\nimport { FormDraftBannerComponent } from './form-draft-banner.component';\n\n/**\n * Auto-saves and restores form drafts\n * \n * @example\n * <form [formGroup]=\"myForm\" ngxFormDraft=\"myFormId\">\n * \n * @example\n * <form [formGroup]=\"myForm\" [ngxFormDraft]=\"'edit_' + entityId\" [draftExcludeFields]=\"['password']\">\n */\n@Directive({\n selector: '[ngxFormDraft]',\n})\nexport class FormDraftDirective implements OnInit, AfterViewInit, OnDestroy {\n @Input('ngxFormDraft') formId!: string;\n @Input() draftDebounce = 800;\n @Input() draftExcludeFields: string[] = [];\n @Input() draftShowOnChange = false;\n @Input() draftRestoredText = 'Draft restored';\n @Input() draftSavedText = 'Draft saved';\n @Input() draftSavedLabel = 'saved';\n @Input() draftDiscardText = 'Discard';\n\n private destroy$ = new Subject<void>();\n private bannerRef: ComponentRef<FormDraftBannerComponent> | null = null;\n private formControl: AbstractControl | null = null;\n private initialValues: Record<string, any> = {};\n private isRestoring = false;\n\n constructor(\n @Optional() private formGroupDir: FormGroupDirective,\n @Optional() private ngForm: NgForm,\n private draftService: FormDraftService,\n private viewContainerRef: ViewContainerRef,\n private cdRef: ChangeDetectorRef,\n private elRef: ElementRef,\n private renderer: Renderer2,\n ) {}\n\n ngOnInit(): void {\n this.formControl = this.formGroupDir?.form || this.ngForm?.form || null;\n if (!this.formControl || !this.formId) return;\n\n this.draftService.registerReset(this.formId, () => this.performResetAndDestroyBanner());\n\n // For reactive forms, capture initial values and restore draft immediately\n if (this.formGroupDir) {\n this.initialValues = JSON.parse(JSON.stringify(this.formControl.value));\n \n const draft = this.draftService.load(this.formId);\n if (draft) {\n this.restoreDraft(draft.values);\n this.showBanner(draft.savedAt, true);\n }\n }\n\n let hasUserInteraction = false;\n \n this.formControl.valueChanges\n .pipe(\n filter(() => {\n if (this.isRestoring) return false;\n if (this.ngForm && !hasUserInteraction) {\n const currentValues = this.formControl?.value || {};\n const isDifferent = JSON.stringify(currentValues) !== JSON.stringify(this.initialValues);\n if (isDifferent) {\n hasUserInteraction = true;\n return true;\n }\n return false;\n }\n return true;\n }),\n debounceTime(this.draftDebounce),\n takeUntil(this.destroy$)\n )\n .subscribe((values) => {\n this.saveDraft(values);\n });\n }\n\n ngAfterViewInit(): void {\n if (this.ngForm && this.formControl) {\n const draft = this.draftService.load(this.formId);\n \n if (draft) {\n this.isRestoring = true;\n }\n \n setTimeout(() => {\n if (draft) {\n this.restoreDraft(draft.values);\n this.showBanner(draft.savedAt, true);\n this.initialValues = {};\n } else {\n this.initialValues = JSON.parse(JSON.stringify(this.formControl!.value));\n }\n }, 0);\n }\n }\n\n ngOnDestroy(): void {\n this.draftService.unregisterReset(this.formId);\n this.destroy$.next();\n this.destroy$.complete();\n this.destroyBanner();\n }\n\n private saveDraft(values: Record<string, any>): void {\n const filtered = this.filterFields(values);\n \n // Don't save if empty\n if (this.isAllEmpty(filtered)) {\n return;\n }\n\n // Don't save if matches initial values (even if initial is empty)\n if (this.matchesInitialValues(filtered)) {\n return;\n }\n\n this.draftService.save(this.formId, filtered);\n if (this.draftShowOnChange && !this.bannerRef) {\n this.showBanner(Date.now(), false);\n }\n }\n\n private filterFields(values: Record<string, any>): Record<string, any> {\n if (!this.draftExcludeFields.length) return values;\n const result = { ...values };\n this.draftExcludeFields.forEach(field => delete result[field]);\n return result;\n }\n\n private isAllEmpty(values: Record<string, any>): boolean {\n return Object.values(values).every(\n v => v === null || v === undefined || v === '' || (Array.isArray(v) && v.length === 0)\n );\n }\n\n private matchesInitialValues(values: Record<string, any>): boolean {\n return JSON.stringify(values) === JSON.stringify(this.initialValues);\n }\n\n private restoreDraft(values: Record<string, any>): void {\n if (!this.formControl) return;\n this.isRestoring = true;\n\n const form = this.formGroupDir?.form || this.ngForm?.form;\n if (form) {\n this.prepareFormArrays(form, values);\n form.patchValue(values);\n }\n\n setTimeout(() => this.isRestoring = false, 100);\n }\n\n private prepareFormArrays(control: AbstractControl, value: any): void {\n if (!control || value == null) return;\n\n if (control instanceof FormGroup && value && typeof value === 'object' && !Array.isArray(value)) {\n Object.keys(value).forEach(key => {\n const childControl = control.get(key);\n if (childControl) this.prepareFormArrays(childControl, value[key]);\n });\n return;\n }\n\n if (control instanceof FormArray && Array.isArray(value)) {\n const formArray = control as FormArray;\n\n while (formArray.length < value.length) {\n const template = formArray.at(0);\n if (template instanceof FormGroup) {\n const newGroup = new FormGroup({});\n Object.keys(template.controls).forEach(ctrlName => {\n const existing = template.get(ctrlName) as AbstractControl;\n if (existing instanceof FormArray) {\n newGroup.addControl(ctrlName, new FormArray([]));\n } else if (existing instanceof FormGroup) {\n newGroup.addControl(ctrlName, new FormGroup({}));\n } else {\n newGroup.addControl(ctrlName, new FormControl(null));\n }\n });\n formArray.push(newGroup);\n } else if (template) {\n formArray.push(new FormControl(null));\n } else {\n const firstValue = value[0];\n if (firstValue && typeof firstValue === 'object' && !Array.isArray(firstValue)) {\n const group = new FormGroup({});\n Object.keys(firstValue).forEach(key => group.addControl(key, new FormControl(null)));\n formArray.push(group);\n } else {\n formArray.push(new FormControl(null));\n }\n }\n }\n\n while (formArray.length > value.length) {\n formArray.removeAt(formArray.length - 1);\n }\n\n value.forEach((childValue, index) => {\n this.prepareFormArrays(formArray.at(index), childValue);\n });\n }\n }\n\n private discardDraft(): void {\n this.draftService.clear(this.formId);\n this.performResetAndDestroyBanner();\n }\n\n /**\n * Resets the form to initial values and destroys the draft banner.\n * Used by the service when clearAndReset(formId) is called (e.g. on submit).\n */\n public performResetAndDestroyBanner(): void {\n if (this.formControl) {\n this.isRestoring = true;\n const form = this.formGroupDir?.form || this.ngForm?.form;\n if (form) {\n this.prepareFormArrays(form, this.initialValues);\n form.reset(this.initialValues);\n }\n setTimeout(() => {\n this.isRestoring = false;\n }, this.draftDebounce + 200);\n }\n this.destroyBanner();\n }\n\n private showBanner(savedAt: number, isRestored = false): void {\n this.bannerRef = this.viewContainerRef.createComponent(FormDraftBannerComponent);\n this.bannerRef.setInput('visible', true);\n this.bannerRef.setInput('isRestored', isRestored);\n this.bannerRef.setInput('timeLabel', isRestored ? this.draftService.formatTimestamp(savedAt) : '');\n this.bannerRef.setInput('restoredText', this.draftRestoredText);\n this.bannerRef.setInput('savedText', this.draftSavedText);\n this.bannerRef.setInput('savedLabel', this.draftSavedLabel);\n this.bannerRef.setInput('discardText', this.draftDiscardText);\n\n this.bannerRef.instance.discard.subscribe(() => this.discardDraft());\n\n const bannerEl = this.bannerRef.location.nativeElement;\n const formEl = this.elRef.nativeElement;\n this.renderer.insertBefore(formEl, bannerEl, formEl.firstChild);\n\n this.cdRef.detectChanges();\n }\n\n private destroyBanner(): void {\n if (this.bannerRef) {\n this.bannerRef.destroy();\n this.bannerRef = null;\n }\n }\n\n public clearDraft(): void {\n this.draftService.clear(this.formId);\n this.destroyBanner();\n }\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormDraftDirective } from './form-draft.directive';\nimport { FormDraftBannerComponent } from './form-draft-banner.component';\n\n@NgModule({\n declarations: [FormDraftDirective, FormDraftBannerComponent],\n imports: [CommonModule],\n exports: [FormDraftDirective, FormDraftBannerComponent],\n})\nexport class NgxFormDraftModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2.FormDraftService"],"mappings":"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"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { EventEmitter } from '@angular/core';
|
|
2
|
-
import * as i0 from "@angular/core";
|
|
3
|
-
export declare class FormDraftBannerComponent {
|
|
4
|
-
visible: boolean;
|
|
5
|
-
timeLabel: string;
|
|
6
|
-
isRestored: boolean;
|
|
7
|
-
restoredText: string;
|
|
8
|
-
savedText: string;
|
|
9
|
-
savedLabel: string;
|
|
10
|
-
discardText: string;
|
|
11
|
-
discard: EventEmitter<void>;
|
|
12
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<FormDraftBannerComponent, never>;
|
|
13
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<FormDraftBannerComponent, "ngx-form-draft-banner", never, { "visible": "visible"; "timeLabel": "timeLabel"; "isRestored": "isRestored"; "restoredText": "restoredText"; "savedText": "savedText"; "savedLabel": "savedLabel"; "discardText": "discardText"; }, { "discard": "discard"; }, never, never, false>;
|
|
14
|
-
}
|
|
1
|
+
import { EventEmitter } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class FormDraftBannerComponent {
|
|
4
|
+
visible: boolean;
|
|
5
|
+
timeLabel: string;
|
|
6
|
+
isRestored: boolean;
|
|
7
|
+
restoredText: string;
|
|
8
|
+
savedText: string;
|
|
9
|
+
savedLabel: string;
|
|
10
|
+
discardText: string;
|
|
11
|
+
discard: EventEmitter<void>;
|
|
12
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FormDraftBannerComponent, never>;
|
|
13
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FormDraftBannerComponent, "ngx-form-draft-banner", never, { "visible": "visible"; "timeLabel": "timeLabel"; "isRestored": "isRestored"; "restoredText": "restoredText"; "savedText": "savedText"; "savedLabel": "savedLabel"; "discardText": "discardText"; }, { "discard": "discard"; }, never, never, false>;
|
|
14
|
+
}
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
import { OnInit, AfterViewInit, OnDestroy, ViewContainerRef, ChangeDetectorRef, ElementRef, Renderer2 } from '@angular/core';
|
|
2
|
-
import { NgForm, FormGroupDirective } from '@angular/forms';
|
|
3
|
-
import { FormDraftService } from './form-draft.service';
|
|
4
|
-
import * as i0 from "@angular/core";
|
|
5
|
-
/**
|
|
6
|
-
* Auto-saves and restores form drafts
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* <form [formGroup]="myForm" ngxFormDraft="myFormId">
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* <form [formGroup]="myForm" [ngxFormDraft]="'edit_' + entityId" [draftExcludeFields]="['password']">
|
|
13
|
-
*/
|
|
14
|
-
export declare class FormDraftDirective implements OnInit, AfterViewInit, OnDestroy {
|
|
15
|
-
private formGroupDir;
|
|
16
|
-
private ngForm;
|
|
17
|
-
private draftService;
|
|
18
|
-
private viewContainerRef;
|
|
19
|
-
private cdRef;
|
|
20
|
-
private elRef;
|
|
21
|
-
private renderer;
|
|
22
|
-
formId: string;
|
|
23
|
-
draftDebounce: number;
|
|
24
|
-
draftExcludeFields: string[];
|
|
25
|
-
draftShowOnChange: boolean;
|
|
26
|
-
draftRestoredText: string;
|
|
27
|
-
draftSavedText: string;
|
|
28
|
-
draftSavedLabel: string;
|
|
29
|
-
draftDiscardText: string;
|
|
30
|
-
private destroy$;
|
|
31
|
-
private bannerRef;
|
|
32
|
-
private formControl;
|
|
33
|
-
private initialValues;
|
|
34
|
-
private isRestoring;
|
|
35
|
-
constructor(formGroupDir: FormGroupDirective, ngForm: NgForm, draftService: FormDraftService, viewContainerRef: ViewContainerRef, cdRef: ChangeDetectorRef, elRef: ElementRef, renderer: Renderer2);
|
|
36
|
-
ngOnInit(): void;
|
|
37
|
-
ngAfterViewInit(): void;
|
|
38
|
-
ngOnDestroy(): void;
|
|
39
|
-
private saveDraft;
|
|
40
|
-
private filterFields;
|
|
41
|
-
private isAllEmpty;
|
|
42
|
-
private matchesInitialValues;
|
|
43
|
-
private restoreDraft;
|
|
44
|
-
private prepareFormArrays;
|
|
45
|
-
private discardDraft;
|
|
46
|
-
/**
|
|
47
|
-
* Resets the form to initial values and destroys the draft banner.
|
|
48
|
-
* Used by the service when clearAndReset(formId) is called (e.g. on submit).
|
|
49
|
-
*/
|
|
50
|
-
performResetAndDestroyBanner(): void;
|
|
51
|
-
private showBanner;
|
|
52
|
-
private destroyBanner;
|
|
53
|
-
clearDraft(): void;
|
|
54
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<FormDraftDirective, [{ optional: true; }, { optional: true; }, null, null, null, null, null]>;
|
|
55
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<FormDraftDirective, "[ngxFormDraft]", never, { "formId": "ngxFormDraft"; "draftDebounce": "draftDebounce"; "draftExcludeFields": "draftExcludeFields"; "draftShowOnChange": "draftShowOnChange"; "draftRestoredText": "draftRestoredText"; "draftSavedText": "draftSavedText"; "draftSavedLabel": "draftSavedLabel"; "draftDiscardText": "draftDiscardText"; }, {}, never, never, false>;
|
|
56
|
-
}
|
|
1
|
+
import { OnInit, AfterViewInit, OnDestroy, ViewContainerRef, ChangeDetectorRef, ElementRef, Renderer2 } from '@angular/core';
|
|
2
|
+
import { NgForm, FormGroupDirective } from '@angular/forms';
|
|
3
|
+
import { FormDraftService } from './form-draft.service';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* Auto-saves and restores form drafts
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* <form [formGroup]="myForm" ngxFormDraft="myFormId">
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* <form [formGroup]="myForm" [ngxFormDraft]="'edit_' + entityId" [draftExcludeFields]="['password']">
|
|
13
|
+
*/
|
|
14
|
+
export declare class FormDraftDirective implements OnInit, AfterViewInit, OnDestroy {
|
|
15
|
+
private formGroupDir;
|
|
16
|
+
private ngForm;
|
|
17
|
+
private draftService;
|
|
18
|
+
private viewContainerRef;
|
|
19
|
+
private cdRef;
|
|
20
|
+
private elRef;
|
|
21
|
+
private renderer;
|
|
22
|
+
formId: string;
|
|
23
|
+
draftDebounce: number;
|
|
24
|
+
draftExcludeFields: string[];
|
|
25
|
+
draftShowOnChange: boolean;
|
|
26
|
+
draftRestoredText: string;
|
|
27
|
+
draftSavedText: string;
|
|
28
|
+
draftSavedLabel: string;
|
|
29
|
+
draftDiscardText: string;
|
|
30
|
+
private destroy$;
|
|
31
|
+
private bannerRef;
|
|
32
|
+
private formControl;
|
|
33
|
+
private initialValues;
|
|
34
|
+
private isRestoring;
|
|
35
|
+
constructor(formGroupDir: FormGroupDirective, ngForm: NgForm, draftService: FormDraftService, viewContainerRef: ViewContainerRef, cdRef: ChangeDetectorRef, elRef: ElementRef, renderer: Renderer2);
|
|
36
|
+
ngOnInit(): void;
|
|
37
|
+
ngAfterViewInit(): void;
|
|
38
|
+
ngOnDestroy(): void;
|
|
39
|
+
private saveDraft;
|
|
40
|
+
private filterFields;
|
|
41
|
+
private isAllEmpty;
|
|
42
|
+
private matchesInitialValues;
|
|
43
|
+
private restoreDraft;
|
|
44
|
+
private prepareFormArrays;
|
|
45
|
+
private discardDraft;
|
|
46
|
+
/**
|
|
47
|
+
* Resets the form to initial values and destroys the draft banner.
|
|
48
|
+
* Used by the service when clearAndReset(formId) is called (e.g. on submit).
|
|
49
|
+
*/
|
|
50
|
+
performResetAndDestroyBanner(): void;
|
|
51
|
+
private showBanner;
|
|
52
|
+
private destroyBanner;
|
|
53
|
+
clearDraft(): void;
|
|
54
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FormDraftDirective, [{ optional: true; }, { optional: true; }, null, null, null, null, null]>;
|
|
55
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<FormDraftDirective, "[ngxFormDraft]", never, { "formId": "ngxFormDraft"; "draftDebounce": "draftDebounce"; "draftExcludeFields": "draftExcludeFields"; "draftShowOnChange": "draftShowOnChange"; "draftRestoredText": "draftRestoredText"; "draftSavedText": "draftSavedText"; "draftSavedLabel": "draftSavedLabel"; "draftDiscardText": "draftDiscardText"; }, {}, never, never, false>;
|
|
56
|
+
}
|
package/form-draft.service.d.ts
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import * as i0 from "@angular/core";
|
|
2
|
-
export interface FormDraftData {
|
|
3
|
-
values: Record<string, any>;
|
|
4
|
-
savedAt: number;
|
|
5
|
-
formId: string;
|
|
6
|
-
}
|
|
7
|
-
export declare class FormDraftService {
|
|
8
|
-
private readonly STORAGE_PREFIX;
|
|
9
|
-
private readonly MAX_AGE_MS;
|
|
10
|
-
/** Registry of formId -> reset callback (used by directive to reset form + banner) */
|
|
11
|
-
private resetRegistry;
|
|
12
|
-
/**
|
|
13
|
-
* Register a callback to reset the form and draft UI for the given formId.
|
|
14
|
-
* Called by the directive; apps should use clearAndReset(formId) instead.
|
|
15
|
-
*/
|
|
16
|
-
registerReset(formId: string, resetFn: () => void): void;
|
|
17
|
-
/**
|
|
18
|
-
* Unregister the reset callback for the given formId.
|
|
19
|
-
* Called by the directive on destroy.
|
|
20
|
-
*/
|
|
21
|
-
unregisterReset(formId: string): void;
|
|
22
|
-
/**
|
|
23
|
-
* Clear the draft from storage and, if a directive is registered for this formId,
|
|
24
|
-
* reset the form and dismiss the draft banner in one call.
|
|
25
|
-
* Use this on form submit to clear local storage and reset the form in one line.
|
|
26
|
-
*/
|
|
27
|
-
clearAndReset(formId: string): void;
|
|
28
|
-
private buildKey;
|
|
29
|
-
save(formId: string, values: Record<string, any>): void;
|
|
30
|
-
load(formId: string): FormDraftData | null;
|
|
31
|
-
clear(formId: string): void;
|
|
32
|
-
formatTimestamp(timestamp: number): string;
|
|
33
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<FormDraftService, never>;
|
|
34
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<FormDraftService>;
|
|
35
|
-
}
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
export interface FormDraftData {
|
|
3
|
+
values: Record<string, any>;
|
|
4
|
+
savedAt: number;
|
|
5
|
+
formId: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class FormDraftService {
|
|
8
|
+
private readonly STORAGE_PREFIX;
|
|
9
|
+
private readonly MAX_AGE_MS;
|
|
10
|
+
/** Registry of formId -> reset callback (used by directive to reset form + banner) */
|
|
11
|
+
private resetRegistry;
|
|
12
|
+
/**
|
|
13
|
+
* Register a callback to reset the form and draft UI for the given formId.
|
|
14
|
+
* Called by the directive; apps should use clearAndReset(formId) instead.
|
|
15
|
+
*/
|
|
16
|
+
registerReset(formId: string, resetFn: () => void): void;
|
|
17
|
+
/**
|
|
18
|
+
* Unregister the reset callback for the given formId.
|
|
19
|
+
* Called by the directive on destroy.
|
|
20
|
+
*/
|
|
21
|
+
unregisterReset(formId: string): void;
|
|
22
|
+
/**
|
|
23
|
+
* Clear the draft from storage and, if a directive is registered for this formId,
|
|
24
|
+
* reset the form and dismiss the draft banner in one call.
|
|
25
|
+
* Use this on form submit to clear local storage and reset the form in one line.
|
|
26
|
+
*/
|
|
27
|
+
clearAndReset(formId: string): void;
|
|
28
|
+
private buildKey;
|
|
29
|
+
save(formId: string, values: Record<string, any>): void;
|
|
30
|
+
load(formId: string): FormDraftData | null;
|
|
31
|
+
clear(formId: string): void;
|
|
32
|
+
formatTimestamp(timestamp: number): string;
|
|
33
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FormDraftService, never>;
|
|
34
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<FormDraftService>;
|
|
35
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './form-draft.directive';
|
|
2
|
-
export * from './form-draft-banner.component';
|
|
3
|
-
export * from './form-draft.service';
|
|
4
|
-
export * from './ngx-form-draft.module';
|
|
1
|
+
export * from './form-draft.directive';
|
|
2
|
+
export * from './form-draft-banner.component';
|
|
3
|
+
export * from './form-draft.service';
|
|
4
|
+
export * from './ngx-form-draft.module';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import * as i0 from "@angular/core";
|
|
2
|
-
import * as i1 from "./form-draft.directive";
|
|
3
|
-
import * as i2 from "./form-draft-banner.component";
|
|
4
|
-
import * as i3 from "@angular/common";
|
|
5
|
-
export declare class NgxFormDraftModule {
|
|
6
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<NgxFormDraftModule, never>;
|
|
7
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<NgxFormDraftModule, [typeof i1.FormDraftDirective, typeof i2.FormDraftBannerComponent], [typeof i3.CommonModule], [typeof i1.FormDraftDirective, typeof i2.FormDraftBannerComponent]>;
|
|
8
|
-
static ɵinj: i0.ɵɵInjectorDeclaration<NgxFormDraftModule>;
|
|
9
|
-
}
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import * as i1 from "./form-draft.directive";
|
|
3
|
+
import * as i2 from "./form-draft-banner.component";
|
|
4
|
+
import * as i3 from "@angular/common";
|
|
5
|
+
export declare class NgxFormDraftModule {
|
|
6
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgxFormDraftModule, never>;
|
|
7
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<NgxFormDraftModule, [typeof i1.FormDraftDirective, typeof i2.FormDraftBannerComponent], [typeof i3.CommonModule], [typeof i1.FormDraftDirective, typeof i2.FormDraftBannerComponent]>;
|
|
8
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<NgxFormDraftModule>;
|
|
9
|
+
}
|