ngx-form-draft 2.0.2 → 2.0.4
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/package.json +27 -24
- package/dist/LICENSE +0 -21
- package/dist/README.md +0 -144
- package/dist/esm2020/form-draft-banner.component.mjs +0 -105
- package/dist/esm2020/form-draft.directive.mjs +0 -221
- package/dist/esm2020/form-draft.service.mjs +0 -67
- package/dist/esm2020/index.mjs +0 -5
- package/dist/esm2020/ngx-form-draft.mjs +0 -5
- package/dist/esm2020/ngx-form-draft.module.mjs +0 -19
- package/dist/fesm2015/ngx-form-draft.mjs +0 -414
- package/dist/fesm2015/ngx-form-draft.mjs.map +0 -1
- package/dist/fesm2020/ngx-form-draft.mjs +0 -409
- package/dist/fesm2020/ngx-form-draft.mjs.map +0 -1
- package/dist/form-draft-banner.component.d.ts +0 -14
- package/dist/form-draft.directive.d.ts +0 -50
- package/dist/form-draft.service.d.ts +0 -17
- package/dist/index.d.ts +0 -4
- package/dist/ngx-form-draft.module.d.ts +0 -9
- package/dist/package.json +0 -64
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@angular/core';
|
|
2
|
-
import * as i0 from "@angular/core";
|
|
3
|
-
export class FormDraftService {
|
|
4
|
-
constructor() {
|
|
5
|
-
this.STORAGE_PREFIX = 'form_draft_';
|
|
6
|
-
this.MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
7
|
-
}
|
|
8
|
-
buildKey(formId) {
|
|
9
|
-
return `${this.STORAGE_PREFIX}${formId}`;
|
|
10
|
-
}
|
|
11
|
-
save(formId, values) {
|
|
12
|
-
try {
|
|
13
|
-
const draft = { values, savedAt: Date.now(), formId };
|
|
14
|
-
localStorage.setItem(this.buildKey(formId), JSON.stringify(draft));
|
|
15
|
-
}
|
|
16
|
-
catch (e) {
|
|
17
|
-
console.warn('[FormDraft] Could not save draft:', e);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
load(formId) {
|
|
21
|
-
try {
|
|
22
|
-
const raw = localStorage.getItem(this.buildKey(formId));
|
|
23
|
-
if (!raw)
|
|
24
|
-
return null;
|
|
25
|
-
const draft = JSON.parse(raw);
|
|
26
|
-
if (Date.now() - draft.savedAt > this.MAX_AGE_MS) {
|
|
27
|
-
this.clear(formId);
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
return draft;
|
|
31
|
-
}
|
|
32
|
-
catch (e) {
|
|
33
|
-
console.warn('[FormDraft] Could not load draft:', e);
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
clear(formId) {
|
|
38
|
-
try {
|
|
39
|
-
localStorage.removeItem(this.buildKey(formId));
|
|
40
|
-
}
|
|
41
|
-
catch (e) {
|
|
42
|
-
console.warn('[FormDraft] Could not clear draft:', e);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
formatTimestamp(timestamp) {
|
|
46
|
-
const seconds = Math.floor((Date.now() - timestamp) / 1000);
|
|
47
|
-
if (seconds < 60)
|
|
48
|
-
return 'just now';
|
|
49
|
-
const minutes = Math.floor(seconds / 60);
|
|
50
|
-
if (minutes < 60)
|
|
51
|
-
return `${minutes}m ago`;
|
|
52
|
-
const hours = Math.floor(minutes / 60);
|
|
53
|
-
if (hours < 24)
|
|
54
|
-
return `${hours}h ago`;
|
|
55
|
-
const days = Math.floor(hours / 24);
|
|
56
|
-
return `${days}d ago`;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
FormDraftService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormDraftService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
60
|
-
FormDraftService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormDraftService, providedIn: 'root' });
|
|
61
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormDraftService, decorators: [{
|
|
62
|
-
type: Injectable,
|
|
63
|
-
args: [{
|
|
64
|
-
providedIn: 'root'
|
|
65
|
-
}]
|
|
66
|
-
}] });
|
|
67
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1kcmFmdC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Zvcm0tZHJhZnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQVczQyxNQUFNLE9BQU8sZ0JBQWdCO0lBSDdCO1FBSW1CLG1CQUFjLEdBQUcsYUFBYSxDQUFDO1FBQy9CLGVBQVUsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0tBa0R2RDtJQWhEUyxRQUFRLENBQUMsTUFBYztRQUM3QixPQUFPLEdBQUcsSUFBSSxDQUFDLGNBQWMsR0FBRyxNQUFNLEVBQUUsQ0FBQztJQUMzQyxDQUFDO0lBRUQsSUFBSSxDQUFDLE1BQWMsRUFBRSxNQUEyQjtRQUM5QyxJQUFJO1lBQ0YsTUFBTSxLQUFLLEdBQWtCLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUM7WUFDckUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztTQUNwRTtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsT0FBTyxDQUFDLElBQUksQ0FBQyxtQ0FBbUMsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUN0RDtJQUNILENBQUM7SUFFRCxJQUFJLENBQUMsTUFBYztRQUNqQixJQUFJO1lBQ0YsTUFBTSxHQUFHLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDeEQsSUFBSSxDQUFDLEdBQUc7Z0JBQUUsT0FBTyxJQUFJLENBQUM7WUFFdEIsTUFBTSxLQUFLLEdBQWtCLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDN0MsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFO2dCQUNoRCxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNuQixPQUFPLElBQUksQ0FBQzthQUNiO1lBQ0QsT0FBTyxLQUFLLENBQUM7U0FDZDtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsT0FBTyxDQUFDLElBQUksQ0FBQyxtQ0FBbUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNyRCxPQUFPLElBQUksQ0FBQztTQUNiO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxNQUFjO1FBQ2xCLElBQUk7WUFDRixZQUFZLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztTQUNoRDtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsT0FBTyxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUN2RDtJQUNILENBQUM7SUFFRCxlQUFlLENBQUMsU0FBaUI7UUFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztRQUM1RCxJQUFJLE9BQU8sR0FBRyxFQUFFO1lBQUUsT0FBTyxVQUFVLENBQUM7UUFDcEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDekMsSUFBSSxPQUFPLEdBQUcsRUFBRTtZQUFFLE9BQU8sR0FBRyxPQUFPLE9BQU8sQ0FBQztRQUMzQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUMsQ0FBQztRQUN2QyxJQUFJLEtBQUssR0FBRyxFQUFFO1lBQUUsT0FBTyxHQUFHLEtBQUssT0FBTyxDQUFDO1FBQ3ZDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQztJQUN4QixDQUFDOzs2R0FuRFUsZ0JBQWdCO2lIQUFoQixnQkFBZ0IsY0FGZixNQUFNOzJGQUVQLGdCQUFnQjtrQkFINUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRm9ybURyYWZ0RGF0YSB7XG4gIHZhbHVlczogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgc2F2ZWRBdDogbnVtYmVyO1xuICBmb3JtSWQ6IHN0cmluZztcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgRm9ybURyYWZ0U2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgU1RPUkFHRV9QUkVGSVggPSAnZm9ybV9kcmFmdF8nO1xuICBwcml2YXRlIHJlYWRvbmx5IE1BWF9BR0VfTVMgPSA3ICogMjQgKiA2MCAqIDYwICogMTAwMDtcblxuICBwcml2YXRlIGJ1aWxkS2V5KGZvcm1JZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7dGhpcy5TVE9SQUdFX1BSRUZJWH0ke2Zvcm1JZH1gO1xuICB9XG5cbiAgc2F2ZShmb3JtSWQ6IHN0cmluZywgdmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGRyYWZ0OiBGb3JtRHJhZnREYXRhID0geyB2YWx1ZXMsIHNhdmVkQXQ6IERhdGUubm93KCksIGZvcm1JZCB9O1xuICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0odGhpcy5idWlsZEtleShmb3JtSWQpLCBKU09OLnN0cmluZ2lmeShkcmFmdCkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUud2FybignW0Zvcm1EcmFmdF0gQ291bGQgbm90IHNhdmUgZHJhZnQ6JywgZSk7XG4gICAgfVxuICB9XG5cbiAgbG9hZChmb3JtSWQ6IHN0cmluZyk6IEZvcm1EcmFmdERhdGEgfCBudWxsIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmF3ID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5idWlsZEtleShmb3JtSWQpKTtcbiAgICAgIGlmICghcmF3KSByZXR1cm4gbnVsbDtcblxuICAgICAgY29uc3QgZHJhZnQ6IEZvcm1EcmFmdERhdGEgPSBKU09OLnBhcnNlKHJhdyk7XG4gICAgICBpZiAoRGF0ZS5ub3coKSAtIGRyYWZ0LnNhdmVkQXQgPiB0aGlzLk1BWF9BR0VfTVMpIHtcbiAgICAgICAgdGhpcy5jbGVhcihmb3JtSWQpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkcmFmdDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tGb3JtRHJhZnRdIENvdWxkIG5vdCBsb2FkIGRyYWZ0OicsIGUpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgY2xlYXIoZm9ybUlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5idWlsZEtleShmb3JtSWQpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tGb3JtRHJhZnRdIENvdWxkIG5vdCBjbGVhciBkcmFmdDonLCBlKTtcbiAgICB9XG4gIH1cblxuICBmb3JtYXRUaW1lc3RhbXAodGltZXN0YW1wOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IHNlY29uZHMgPSBNYXRoLmZsb29yKChEYXRlLm5vdygpIC0gdGltZXN0YW1wKSAvIDEwMDApO1xuICAgIGlmIChzZWNvbmRzIDwgNjApIHJldHVybiAnanVzdCBub3cnO1xuICAgIGNvbnN0IG1pbnV0ZXMgPSBNYXRoLmZsb29yKHNlY29uZHMgLyA2MCk7XG4gICAgaWYgKG1pbnV0ZXMgPCA2MCkgcmV0dXJuIGAke21pbnV0ZXN9bSBhZ29gO1xuICAgIGNvbnN0IGhvdXJzID0gTWF0aC5mbG9vcihtaW51dGVzIC8gNjApO1xuICAgIGlmIChob3VycyA8IDI0KSByZXR1cm4gYCR7aG91cnN9aCBhZ29gO1xuICAgIGNvbnN0IGRheXMgPSBNYXRoLmZsb29yKGhvdXJzIC8gMjQpO1xuICAgIHJldHVybiBgJHtkYXlzfWQgYWdvYDtcbiAgfVxufVxuIl19
|
package/dist/esm2020/index.mjs
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
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';
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLCtCQUErQixDQUFDO0FBQzlDLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyx5QkFBeUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vZm9ybS1kcmFmdC5kaXJlY3RpdmUnO1xuZXhwb3J0ICogZnJvbSAnLi9mb3JtLWRyYWZ0LWJhbm5lci5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9mb3JtLWRyYWZ0LnNlcnZpY2UnO1xuZXhwb3J0ICogZnJvbSAnLi9uZ3gtZm9ybS1kcmFmdC5tb2R1bGUnO1xuIl19
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generated bundle index. Do not edit.
|
|
3
|
-
*/
|
|
4
|
-
export * from './index';
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWZvcm0tZHJhZnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbmd4LWZvcm0tZHJhZnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLFNBQVMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9pbmRleCc7XG4iXX0=
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { NgModule } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { FormDraftDirective } from './form-draft.directive';
|
|
4
|
-
import { FormDraftBannerComponent } from './form-draft-banner.component';
|
|
5
|
-
import * as i0 from "@angular/core";
|
|
6
|
-
export class NgxFormDraftModule {
|
|
7
|
-
}
|
|
8
|
-
NgxFormDraftModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxFormDraftModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
9
|
-
NgxFormDraftModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: NgxFormDraftModule, declarations: [FormDraftDirective, FormDraftBannerComponent], imports: [CommonModule], exports: [FormDraftDirective, FormDraftBannerComponent] });
|
|
10
|
-
NgxFormDraftModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxFormDraftModule, imports: [CommonModule] });
|
|
11
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxFormDraftModule, decorators: [{
|
|
12
|
-
type: NgModule,
|
|
13
|
-
args: [{
|
|
14
|
-
declarations: [FormDraftDirective, FormDraftBannerComponent],
|
|
15
|
-
imports: [CommonModule],
|
|
16
|
-
exports: [FormDraftDirective, FormDraftBannerComponent],
|
|
17
|
-
}]
|
|
18
|
-
}] });
|
|
19
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWZvcm0tZHJhZnQubW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL25neC1mb3JtLWRyYWZ0Lm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQzs7QUFPekUsTUFBTSxPQUFPLGtCQUFrQjs7K0dBQWxCLGtCQUFrQjtnSEFBbEIsa0JBQWtCLGlCQUpkLGtCQUFrQixFQUFFLHdCQUF3QixhQUNqRCxZQUFZLGFBQ1osa0JBQWtCLEVBQUUsd0JBQXdCO2dIQUUzQyxrQkFBa0IsWUFIbkIsWUFBWTsyRkFHWCxrQkFBa0I7a0JBTDlCLFFBQVE7bUJBQUM7b0JBQ1IsWUFBWSxFQUFFLENBQUMsa0JBQWtCLEVBQUUsd0JBQXdCLENBQUM7b0JBQzVELE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQztvQkFDdkIsT0FBTyxFQUFFLENBQUMsa0JBQWtCLEVBQUUsd0JBQXdCLENBQUM7aUJBQ3hEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3JtRHJhZnREaXJlY3RpdmUgfSBmcm9tICcuL2Zvcm0tZHJhZnQuZGlyZWN0aXZlJztcbmltcG9ydCB7IEZvcm1EcmFmdEJhbm5lckNvbXBvbmVudCB9IGZyb20gJy4vZm9ybS1kcmFmdC1iYW5uZXIuY29tcG9uZW50JztcblxuQE5nTW9kdWxlKHtcbiAgZGVjbGFyYXRpb25zOiBbRm9ybURyYWZ0RGlyZWN0aXZlLCBGb3JtRHJhZnRCYW5uZXJDb21wb25lbnRdLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgZXhwb3J0czogW0Zvcm1EcmFmdERpcmVjdGl2ZSwgRm9ybURyYWZ0QmFubmVyQ29tcG9uZW50XSxcbn0pXG5leHBvcnQgY2xhc3MgTmd4Rm9ybURyYWZ0TW9kdWxlIHt9XG4iXX0=
|
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { EventEmitter, Component, ChangeDetectionStrategy, Input, Output, Injectable, Directive, Optional, NgModule } from '@angular/core';
|
|
3
|
-
import * as i1$1 from '@angular/forms';
|
|
4
|
-
import { FormGroup, FormArray, FormControl } from '@angular/forms';
|
|
5
|
-
import { Subject } from 'rxjs';
|
|
6
|
-
import { debounceTime, takeUntil } from 'rxjs/operators';
|
|
7
|
-
import { trigger, transition, style, animate } from '@angular/animations';
|
|
8
|
-
import * as i1 from '@angular/common';
|
|
9
|
-
import { CommonModule } from '@angular/common';
|
|
10
|
-
|
|
11
|
-
class FormDraftBannerComponent {
|
|
12
|
-
constructor() {
|
|
13
|
-
this.visible = false;
|
|
14
|
-
this.timeLabel = '';
|
|
15
|
-
this.isRestored = false;
|
|
16
|
-
this.restoredText = 'Draft restored';
|
|
17
|
-
this.savedText = 'Draft saved';
|
|
18
|
-
this.savedLabel = 'saved';
|
|
19
|
-
this.discardText = 'Discard';
|
|
20
|
-
this.discard = new EventEmitter();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
FormDraftBannerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormDraftBannerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
24
|
-
FormDraftBannerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: FormDraftBannerComponent, selector: "ngx-form-draft-banner", inputs: { visible: "visible", timeLabel: "timeLabel", isRestored: "isRestored", restoredText: "restoredText", savedText: "savedText", savedLabel: "savedLabel", discardText: "discardText" }, outputs: { discard: "discard" }, ngImport: i0, template: `
|
|
25
|
-
<div class="form-draft-banner" *ngIf="visible" [@slideDown]>
|
|
26
|
-
<div class="form-draft-banner__icon">
|
|
27
|
-
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
28
|
-
<path d="M12 8V12L14.5 14.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
29
|
-
<circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2"/>
|
|
30
|
-
</svg>
|
|
31
|
-
</div>
|
|
32
|
-
<div class="form-draft-banner__content">
|
|
33
|
-
<span class="form-draft-banner__text">
|
|
34
|
-
<span *ngIf="isRestored">{{ restoredText }}</span>
|
|
35
|
-
<span *ngIf="!isRestored">{{ savedText }}</span>
|
|
36
|
-
<span class="form-draft-banner__time" *ngIf="timeLabel && isRestored">
|
|
37
|
-
· {{ savedLabel }} {{ timeLabel }}
|
|
38
|
-
</span>
|
|
39
|
-
</span>
|
|
40
|
-
</div>
|
|
41
|
-
<div class="form-draft-banner__actions">
|
|
42
|
-
<button class="form-draft-banner__btn form-draft-banner__btn--discard" (click)="discard.emit()" type="button">
|
|
43
|
-
✕ {{ discardText }}
|
|
44
|
-
</button>
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
47
|
-
`, isInline: true, styles: [":host{display:block;width:100%}.form-draft-banner{display:flex;align-items:center;gap:10px;padding:10px 14px;margin-bottom:12px;border-radius:8px;background:linear-gradient(135deg,#eef6ff 0%,#f0f4ff 100%);border:1px solid #c5ddf8;box-shadow:0 2px 8px #128ad614}.form-draft-banner__icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:6px;background:linear-gradient(135deg,#128ad6,#22b9ff);color:#fff;flex-shrink:0}.form-draft-banner__content{flex:1;min-width:0}.form-draft-banner__text{font-size:13px;font-weight:600;color:#1a3a5c}.form-draft-banner__time{font-weight:400;color:#6b8aaa;font-size:12px}.form-draft-banner__actions{flex-shrink:0}.form-draft-banner__btn{border:none;padding:5px 12px;border-radius:6px;font-size:12px;font-weight:600;cursor:pointer;transition:all .2s ease}.form-draft-banner__btn--discard{background:transparent;color:#8899a6;border:1px solid #d0dce6}.form-draft-banner__btn--discard:hover{background:#fef2f2;color:#e62e43;border-color:#e62e43}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], animations: [
|
|
48
|
-
trigger('slideDown', [
|
|
49
|
-
transition(':enter', [
|
|
50
|
-
style({ opacity: 0, transform: 'translateY(-8px)' }),
|
|
51
|
-
animate('250ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 1, transform: 'translateY(0)' }))
|
|
52
|
-
]),
|
|
53
|
-
transition(':leave', [
|
|
54
|
-
animate('200ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 0, transform: 'translateY(-8px)' }))
|
|
55
|
-
])
|
|
56
|
-
])
|
|
57
|
-
], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
58
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormDraftBannerComponent, decorators: [{
|
|
59
|
-
type: Component,
|
|
60
|
-
args: [{ selector: 'ngx-form-draft-banner', template: `
|
|
61
|
-
<div class="form-draft-banner" *ngIf="visible" [@slideDown]>
|
|
62
|
-
<div class="form-draft-banner__icon">
|
|
63
|
-
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
64
|
-
<path d="M12 8V12L14.5 14.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
65
|
-
<circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2"/>
|
|
66
|
-
</svg>
|
|
67
|
-
</div>
|
|
68
|
-
<div class="form-draft-banner__content">
|
|
69
|
-
<span class="form-draft-banner__text">
|
|
70
|
-
<span *ngIf="isRestored">{{ restoredText }}</span>
|
|
71
|
-
<span *ngIf="!isRestored">{{ savedText }}</span>
|
|
72
|
-
<span class="form-draft-banner__time" *ngIf="timeLabel && isRestored">
|
|
73
|
-
· {{ savedLabel }} {{ timeLabel }}
|
|
74
|
-
</span>
|
|
75
|
-
</span>
|
|
76
|
-
</div>
|
|
77
|
-
<div class="form-draft-banner__actions">
|
|
78
|
-
<button class="form-draft-banner__btn form-draft-banner__btn--discard" (click)="discard.emit()" type="button">
|
|
79
|
-
✕ {{ discardText }}
|
|
80
|
-
</button>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
`, animations: [
|
|
84
|
-
trigger('slideDown', [
|
|
85
|
-
transition(':enter', [
|
|
86
|
-
style({ opacity: 0, transform: 'translateY(-8px)' }),
|
|
87
|
-
animate('250ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 1, transform: 'translateY(0)' }))
|
|
88
|
-
]),
|
|
89
|
-
transition(':leave', [
|
|
90
|
-
animate('200ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 0, transform: 'translateY(-8px)' }))
|
|
91
|
-
])
|
|
92
|
-
])
|
|
93
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%}.form-draft-banner{display:flex;align-items:center;gap:10px;padding:10px 14px;margin-bottom:12px;border-radius:8px;background:linear-gradient(135deg,#eef6ff 0%,#f0f4ff 100%);border:1px solid #c5ddf8;box-shadow:0 2px 8px #128ad614}.form-draft-banner__icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:6px;background:linear-gradient(135deg,#128ad6,#22b9ff);color:#fff;flex-shrink:0}.form-draft-banner__content{flex:1;min-width:0}.form-draft-banner__text{font-size:13px;font-weight:600;color:#1a3a5c}.form-draft-banner__time{font-weight:400;color:#6b8aaa;font-size:12px}.form-draft-banner__actions{flex-shrink:0}.form-draft-banner__btn{border:none;padding:5px 12px;border-radius:6px;font-size:12px;font-weight:600;cursor:pointer;transition:all .2s ease}.form-draft-banner__btn--discard{background:transparent;color:#8899a6;border:1px solid #d0dce6}.form-draft-banner__btn--discard:hover{background:#fef2f2;color:#e62e43;border-color:#e62e43}\n"] }]
|
|
94
|
-
}], propDecorators: { visible: [{
|
|
95
|
-
type: Input
|
|
96
|
-
}], timeLabel: [{
|
|
97
|
-
type: Input
|
|
98
|
-
}], isRestored: [{
|
|
99
|
-
type: Input
|
|
100
|
-
}], restoredText: [{
|
|
101
|
-
type: Input
|
|
102
|
-
}], savedText: [{
|
|
103
|
-
type: Input
|
|
104
|
-
}], savedLabel: [{
|
|
105
|
-
type: Input
|
|
106
|
-
}], discardText: [{
|
|
107
|
-
type: Input
|
|
108
|
-
}], discard: [{
|
|
109
|
-
type: Output
|
|
110
|
-
}] } });
|
|
111
|
-
|
|
112
|
-
class FormDraftService {
|
|
113
|
-
constructor() {
|
|
114
|
-
this.STORAGE_PREFIX = 'form_draft_';
|
|
115
|
-
this.MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
116
|
-
}
|
|
117
|
-
buildKey(formId) {
|
|
118
|
-
return `${this.STORAGE_PREFIX}${formId}`;
|
|
119
|
-
}
|
|
120
|
-
save(formId, values) {
|
|
121
|
-
try {
|
|
122
|
-
const draft = { values, savedAt: Date.now(), formId };
|
|
123
|
-
localStorage.setItem(this.buildKey(formId), JSON.stringify(draft));
|
|
124
|
-
}
|
|
125
|
-
catch (e) {
|
|
126
|
-
console.warn('[FormDraft] Could not save draft:', e);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
load(formId) {
|
|
130
|
-
try {
|
|
131
|
-
const raw = localStorage.getItem(this.buildKey(formId));
|
|
132
|
-
if (!raw)
|
|
133
|
-
return null;
|
|
134
|
-
const draft = JSON.parse(raw);
|
|
135
|
-
if (Date.now() - draft.savedAt > this.MAX_AGE_MS) {
|
|
136
|
-
this.clear(formId);
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
return draft;
|
|
140
|
-
}
|
|
141
|
-
catch (e) {
|
|
142
|
-
console.warn('[FormDraft] Could not load draft:', e);
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
clear(formId) {
|
|
147
|
-
try {
|
|
148
|
-
localStorage.removeItem(this.buildKey(formId));
|
|
149
|
-
}
|
|
150
|
-
catch (e) {
|
|
151
|
-
console.warn('[FormDraft] Could not clear draft:', e);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
formatTimestamp(timestamp) {
|
|
155
|
-
const seconds = Math.floor((Date.now() - timestamp) / 1000);
|
|
156
|
-
if (seconds < 60)
|
|
157
|
-
return 'just now';
|
|
158
|
-
const minutes = Math.floor(seconds / 60);
|
|
159
|
-
if (minutes < 60)
|
|
160
|
-
return `${minutes}m ago`;
|
|
161
|
-
const hours = Math.floor(minutes / 60);
|
|
162
|
-
if (hours < 24)
|
|
163
|
-
return `${hours}h ago`;
|
|
164
|
-
const days = Math.floor(hours / 24);
|
|
165
|
-
return `${days}d ago`;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
FormDraftService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormDraftService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
169
|
-
FormDraftService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormDraftService, providedIn: 'root' });
|
|
170
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormDraftService, decorators: [{
|
|
171
|
-
type: Injectable,
|
|
172
|
-
args: [{
|
|
173
|
-
providedIn: 'root'
|
|
174
|
-
}]
|
|
175
|
-
}] });
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Auto-saves and restores form drafts
|
|
179
|
-
*
|
|
180
|
-
* @example
|
|
181
|
-
* <form [formGroup]="myForm" ngxFormDraft="myFormId">
|
|
182
|
-
*
|
|
183
|
-
* @example
|
|
184
|
-
* <form [formGroup]="myForm" [ngxFormDraft]="'edit_' + entityId" [draftExcludeFields]="['password']">
|
|
185
|
-
*/
|
|
186
|
-
class FormDraftDirective {
|
|
187
|
-
constructor(formGroupDir, ngForm, draftService, viewContainerRef, cdRef, elRef, renderer) {
|
|
188
|
-
this.formGroupDir = formGroupDir;
|
|
189
|
-
this.ngForm = ngForm;
|
|
190
|
-
this.draftService = draftService;
|
|
191
|
-
this.viewContainerRef = viewContainerRef;
|
|
192
|
-
this.cdRef = cdRef;
|
|
193
|
-
this.elRef = elRef;
|
|
194
|
-
this.renderer = renderer;
|
|
195
|
-
this.draftDebounce = 800;
|
|
196
|
-
this.draftExcludeFields = [];
|
|
197
|
-
this.draftShowOnChange = false;
|
|
198
|
-
this.draftRestoredText = 'Draft restored';
|
|
199
|
-
this.draftSavedText = 'Draft saved';
|
|
200
|
-
this.draftSavedLabel = 'saved';
|
|
201
|
-
this.draftDiscardText = 'Discard';
|
|
202
|
-
this.destroy$ = new Subject();
|
|
203
|
-
this.bannerRef = null;
|
|
204
|
-
this.formControl = null;
|
|
205
|
-
this.initialValues = {};
|
|
206
|
-
this.isRestoring = false;
|
|
207
|
-
}
|
|
208
|
-
ngOnInit() {
|
|
209
|
-
var _a, _b;
|
|
210
|
-
this.formControl = ((_a = this.formGroupDir) === null || _a === void 0 ? void 0 : _a.form) || ((_b = this.ngForm) === null || _b === void 0 ? void 0 : _b.form) || null;
|
|
211
|
-
if (!this.formControl || !this.formId)
|
|
212
|
-
return;
|
|
213
|
-
this.initialValues = JSON.parse(JSON.stringify(this.formControl.value));
|
|
214
|
-
const draft = this.draftService.load(this.formId);
|
|
215
|
-
if (draft) {
|
|
216
|
-
this.restoreDraft(draft.values);
|
|
217
|
-
this.showBanner(draft.savedAt, true);
|
|
218
|
-
}
|
|
219
|
-
this.formControl.valueChanges
|
|
220
|
-
.pipe(debounceTime(this.draftDebounce), takeUntil(this.destroy$))
|
|
221
|
-
.subscribe((values) => {
|
|
222
|
-
if (this.isRestoring)
|
|
223
|
-
return;
|
|
224
|
-
this.saveDraft(values);
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
ngOnDestroy() {
|
|
228
|
-
this.destroy$.next();
|
|
229
|
-
this.destroy$.complete();
|
|
230
|
-
this.destroyBanner();
|
|
231
|
-
}
|
|
232
|
-
saveDraft(values) {
|
|
233
|
-
const filtered = this.filterFields(values);
|
|
234
|
-
if (this.isAllEmpty(filtered) || this.matchesInitialValues(filtered)) {
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
this.draftService.save(this.formId, filtered);
|
|
238
|
-
if (this.draftShowOnChange && !this.bannerRef) {
|
|
239
|
-
this.showBanner(Date.now(), false);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
filterFields(values) {
|
|
243
|
-
if (!this.draftExcludeFields.length)
|
|
244
|
-
return values;
|
|
245
|
-
const result = Object.assign({}, values);
|
|
246
|
-
this.draftExcludeFields.forEach(field => delete result[field]);
|
|
247
|
-
return result;
|
|
248
|
-
}
|
|
249
|
-
isAllEmpty(values) {
|
|
250
|
-
return Object.values(values).every(v => v === null || v === undefined || v === '' || (Array.isArray(v) && v.length === 0));
|
|
251
|
-
}
|
|
252
|
-
matchesInitialValues(values) {
|
|
253
|
-
return JSON.stringify(values) === JSON.stringify(this.initialValues);
|
|
254
|
-
}
|
|
255
|
-
restoreDraft(values) {
|
|
256
|
-
var _a, _b;
|
|
257
|
-
if (!this.formControl)
|
|
258
|
-
return;
|
|
259
|
-
this.isRestoring = true;
|
|
260
|
-
const form = ((_a = this.formGroupDir) === null || _a === void 0 ? void 0 : _a.form) || ((_b = this.ngForm) === null || _b === void 0 ? void 0 : _b.form);
|
|
261
|
-
if (form) {
|
|
262
|
-
this.prepareFormArrays(form, values);
|
|
263
|
-
form.patchValue(values);
|
|
264
|
-
}
|
|
265
|
-
setTimeout(() => this.isRestoring = false, 100);
|
|
266
|
-
}
|
|
267
|
-
prepareFormArrays(control, value) {
|
|
268
|
-
if (!control || value == null)
|
|
269
|
-
return;
|
|
270
|
-
if (control instanceof FormGroup && value && typeof value === 'object' && !Array.isArray(value)) {
|
|
271
|
-
Object.keys(value).forEach(key => {
|
|
272
|
-
const childControl = control.get(key);
|
|
273
|
-
if (childControl)
|
|
274
|
-
this.prepareFormArrays(childControl, value[key]);
|
|
275
|
-
});
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
if (control instanceof FormArray && Array.isArray(value)) {
|
|
279
|
-
const formArray = control;
|
|
280
|
-
while (formArray.length < value.length) {
|
|
281
|
-
const template = formArray.at(0);
|
|
282
|
-
if (template instanceof FormGroup) {
|
|
283
|
-
const newGroup = new FormGroup({});
|
|
284
|
-
Object.keys(template.controls).forEach(ctrlName => {
|
|
285
|
-
const existing = template.get(ctrlName);
|
|
286
|
-
if (existing instanceof FormArray) {
|
|
287
|
-
newGroup.addControl(ctrlName, new FormArray([]));
|
|
288
|
-
}
|
|
289
|
-
else if (existing instanceof FormGroup) {
|
|
290
|
-
newGroup.addControl(ctrlName, new FormGroup({}));
|
|
291
|
-
}
|
|
292
|
-
else {
|
|
293
|
-
newGroup.addControl(ctrlName, new FormControl(null));
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
formArray.push(newGroup);
|
|
297
|
-
}
|
|
298
|
-
else if (template) {
|
|
299
|
-
formArray.push(new FormControl(null));
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
const firstValue = value[0];
|
|
303
|
-
if (firstValue && typeof firstValue === 'object' && !Array.isArray(firstValue)) {
|
|
304
|
-
const group = new FormGroup({});
|
|
305
|
-
Object.keys(firstValue).forEach(key => group.addControl(key, new FormControl(null)));
|
|
306
|
-
formArray.push(group);
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
309
|
-
formArray.push(new FormControl(null));
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
while (formArray.length > value.length) {
|
|
314
|
-
formArray.removeAt(formArray.length - 1);
|
|
315
|
-
}
|
|
316
|
-
value.forEach((childValue, index) => {
|
|
317
|
-
this.prepareFormArrays(formArray.at(index), childValue);
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
discardDraft() {
|
|
322
|
-
var _a, _b;
|
|
323
|
-
this.draftService.clear(this.formId);
|
|
324
|
-
if (this.formControl) {
|
|
325
|
-
this.isRestoring = true;
|
|
326
|
-
const form = ((_a = this.formGroupDir) === null || _a === void 0 ? void 0 : _a.form) || ((_b = this.ngForm) === null || _b === void 0 ? void 0 : _b.form);
|
|
327
|
-
if (form) {
|
|
328
|
-
this.prepareFormArrays(form, this.initialValues);
|
|
329
|
-
form.reset(this.initialValues);
|
|
330
|
-
}
|
|
331
|
-
setTimeout(() => {
|
|
332
|
-
this.isRestoring = false;
|
|
333
|
-
}, this.draftDebounce + 200);
|
|
334
|
-
}
|
|
335
|
-
this.destroyBanner();
|
|
336
|
-
}
|
|
337
|
-
showBanner(savedAt, isRestored = false) {
|
|
338
|
-
this.bannerRef = this.viewContainerRef.createComponent(FormDraftBannerComponent);
|
|
339
|
-
this.bannerRef.setInput('visible', true);
|
|
340
|
-
this.bannerRef.setInput('isRestored', isRestored);
|
|
341
|
-
this.bannerRef.setInput('timeLabel', isRestored ? this.draftService.formatTimestamp(savedAt) : '');
|
|
342
|
-
this.bannerRef.setInput('restoredText', this.draftRestoredText);
|
|
343
|
-
this.bannerRef.setInput('savedText', this.draftSavedText);
|
|
344
|
-
this.bannerRef.setInput('savedLabel', this.draftSavedLabel);
|
|
345
|
-
this.bannerRef.setInput('discardText', this.draftDiscardText);
|
|
346
|
-
this.bannerRef.instance.discard.subscribe(() => this.discardDraft());
|
|
347
|
-
const bannerEl = this.bannerRef.location.nativeElement;
|
|
348
|
-
const formEl = this.elRef.nativeElement;
|
|
349
|
-
this.renderer.insertBefore(formEl, bannerEl, formEl.firstChild);
|
|
350
|
-
this.cdRef.detectChanges();
|
|
351
|
-
}
|
|
352
|
-
destroyBanner() {
|
|
353
|
-
if (this.bannerRef) {
|
|
354
|
-
this.bannerRef.destroy();
|
|
355
|
-
this.bannerRef = null;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
clearDraft() {
|
|
359
|
-
this.draftService.clear(this.formId);
|
|
360
|
-
this.destroyBanner();
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
FormDraftDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormDraftDirective, deps: [{ token: i1$1.FormGroupDirective, optional: true }, { token: i1$1.NgForm, optional: true }, { token: FormDraftService }, { token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
|
|
364
|
-
FormDraftDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: FormDraftDirective, selector: "[ngxFormDraft]", inputs: { formId: ["ngxFormDraft", "formId"], draftDebounce: "draftDebounce", draftExcludeFields: "draftExcludeFields", draftShowOnChange: "draftShowOnChange", draftRestoredText: "draftRestoredText", draftSavedText: "draftSavedText", draftSavedLabel: "draftSavedLabel", draftDiscardText: "draftDiscardText" }, ngImport: i0 });
|
|
365
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormDraftDirective, decorators: [{
|
|
366
|
-
type: Directive,
|
|
367
|
-
args: [{
|
|
368
|
-
selector: '[ngxFormDraft]',
|
|
369
|
-
}]
|
|
370
|
-
}], ctorParameters: function () {
|
|
371
|
-
return [{ type: i1$1.FormGroupDirective, decorators: [{
|
|
372
|
-
type: Optional
|
|
373
|
-
}] }, { type: i1$1.NgForm, decorators: [{
|
|
374
|
-
type: Optional
|
|
375
|
-
}] }, { type: FormDraftService }, { type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Renderer2 }];
|
|
376
|
-
}, propDecorators: { formId: [{
|
|
377
|
-
type: Input,
|
|
378
|
-
args: ['ngxFormDraft']
|
|
379
|
-
}], draftDebounce: [{
|
|
380
|
-
type: Input
|
|
381
|
-
}], draftExcludeFields: [{
|
|
382
|
-
type: Input
|
|
383
|
-
}], draftShowOnChange: [{
|
|
384
|
-
type: Input
|
|
385
|
-
}], draftRestoredText: [{
|
|
386
|
-
type: Input
|
|
387
|
-
}], draftSavedText: [{
|
|
388
|
-
type: Input
|
|
389
|
-
}], draftSavedLabel: [{
|
|
390
|
-
type: Input
|
|
391
|
-
}], draftDiscardText: [{
|
|
392
|
-
type: Input
|
|
393
|
-
}] } });
|
|
394
|
-
|
|
395
|
-
class NgxFormDraftModule {
|
|
396
|
-
}
|
|
397
|
-
NgxFormDraftModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxFormDraftModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
398
|
-
NgxFormDraftModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: NgxFormDraftModule, declarations: [FormDraftDirective, FormDraftBannerComponent], imports: [CommonModule], exports: [FormDraftDirective, FormDraftBannerComponent] });
|
|
399
|
-
NgxFormDraftModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxFormDraftModule, imports: [CommonModule] });
|
|
400
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxFormDraftModule, decorators: [{
|
|
401
|
-
type: NgModule,
|
|
402
|
-
args: [{
|
|
403
|
-
declarations: [FormDraftDirective, FormDraftBannerComponent],
|
|
404
|
-
imports: [CommonModule],
|
|
405
|
-
exports: [FormDraftDirective, FormDraftBannerComponent],
|
|
406
|
-
}]
|
|
407
|
-
}] });
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* Generated bundle index. Do not edit.
|
|
411
|
-
*/
|
|
412
|
-
|
|
413
|
-
export { FormDraftBannerComponent, FormDraftDirective, FormDraftService, NgxFormDraftModule };
|
|
414
|
-
//# sourceMappingURL=ngx-form-draft.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
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';\nimport { trigger, transition, style, animate } from '@angular/animations';\n\n@Component({\n selector: 'ngx-form-draft-banner',\n template: `\n <div class=\"form-draft-banner\" *ngIf=\"visible\" [@slideDown]>\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 }\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 animations: [\n trigger('slideDown', [\n transition(':enter', [\n style({ opacity: 0, transform: 'translateY(-8px)' }),\n animate('250ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 1, transform: 'translateY(0)' }))\n ]),\n transition(':leave', [\n animate('200ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 0, transform: 'translateY(-8px)' }))\n ])\n ])\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 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, 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 } 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, 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.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 this.formControl.valueChanges\n .pipe(debounceTime(this.draftDebounce), takeUntil(this.destroy$))\n .subscribe((values) => {\n if (this.isRestoring) return;\n this.saveDraft(values);\n });\n }\n\n ngOnDestroy(): void {\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 if (this.isAllEmpty(filtered) || 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\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\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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"}
|