@memberjunction/ng-archive-manager 0.0.1 → 5.30.0

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.
Files changed (30) hide show
  1. package/dist/lib/archive-config/archive-config-admin.component.d.ts +113 -0
  2. package/dist/lib/archive-config/archive-config-admin.component.d.ts.map +1 -0
  3. package/dist/lib/archive-config/archive-config-admin.component.js +735 -0
  4. package/dist/lib/archive-config/archive-config-admin.component.js.map +1 -0
  5. package/dist/lib/archive-manager.module.d.ts +14 -0
  6. package/dist/lib/archive-manager.module.d.ts.map +1 -0
  7. package/dist/lib/archive-manager.module.js +48 -0
  8. package/dist/lib/archive-manager.module.js.map +1 -0
  9. package/dist/lib/archive-restore/archive-restore-dialog.component.d.ts +82 -0
  10. package/dist/lib/archive-restore/archive-restore-dialog.component.d.ts.map +1 -0
  11. package/dist/lib/archive-restore/archive-restore-dialog.component.js +386 -0
  12. package/dist/lib/archive-restore/archive-restore-dialog.component.js.map +1 -0
  13. package/dist/lib/archive-run-viewer/archive-run-viewer.component.d.ts +81 -0
  14. package/dist/lib/archive-run-viewer/archive-run-viewer.component.d.ts.map +1 -0
  15. package/dist/lib/archive-run-viewer/archive-run-viewer.component.js +515 -0
  16. package/dist/lib/archive-run-viewer/archive-run-viewer.component.js.map +1 -0
  17. package/dist/lib/archive-status/archive-status-badge.component.d.ts +65 -0
  18. package/dist/lib/archive-status/archive-status-badge.component.d.ts.map +1 -0
  19. package/dist/lib/archive-status/archive-status-badge.component.js +172 -0
  20. package/dist/lib/archive-status/archive-status-badge.component.js.map +1 -0
  21. package/dist/lib/archive-types.d.ts +81 -0
  22. package/dist/lib/archive-types.d.ts.map +1 -0
  23. package/dist/lib/archive-types.js +8 -0
  24. package/dist/lib/archive-types.js.map +1 -0
  25. package/dist/public-api.d.ts +6 -0
  26. package/dist/public-api.d.ts.map +1 -0
  27. package/dist/public-api.js +11 -0
  28. package/dist/public-api.js.map +1 -0
  29. package/package.json +42 -6
  30. package/README.md +0 -45
@@ -0,0 +1,65 @@
1
+ import { EventEmitter, OnDestroy } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Summary information about an archived version of a record.
5
+ */
6
+ export interface ArchiveVersionInfo {
7
+ /** The archive run detail record ID */
8
+ DetailID: string;
9
+ /** Entity name of the archived record */
10
+ EntityName: string;
11
+ /** Primary key of the archived record */
12
+ RecordID: string;
13
+ /** Number of fields that were archived */
14
+ FieldCount: number;
15
+ /** Date the archive was performed */
16
+ ArchivedAt: Date;
17
+ /** Size of the archived data in bytes */
18
+ Bytes: number;
19
+ }
20
+ export declare class ArchiveStatusBadgeComponent implements OnDestroy {
21
+ private cdr;
22
+ /** Whether the badge is visible (record has archived fields) */
23
+ HasArchivedFields: boolean;
24
+ /** Number of archived fields */
25
+ ArchivedFieldCount: number;
26
+ /** Date of the most recent archive */
27
+ LastArchivedDate: Date | null;
28
+ /** Whether data is currently loading */
29
+ IsLoading: boolean;
30
+ /** Tooltip text shown on hover */
31
+ TooltipText: string;
32
+ /** Latest archive version info for event emission */
33
+ private latestVersion;
34
+ /** Tracks whether the component has been destroyed */
35
+ private destroyed;
36
+ private _entityName;
37
+ set EntityName(value: string);
38
+ get EntityName(): string;
39
+ private _recordID;
40
+ set RecordID(value: string);
41
+ get RecordID(): string;
42
+ /** Emitted when the user clicks the badge to request a restore */
43
+ RestoreRequested: EventEmitter<ArchiveVersionInfo>;
44
+ ngOnDestroy(): void;
45
+ /** Handle badge click — emit the latest archive version info */
46
+ OnBadgeClick(): void;
47
+ /**
48
+ * Load archive status for the current entity/record combination.
49
+ * Queries MJ: Archive Run Details for successful archives.
50
+ */
51
+ private loadArchiveStatus;
52
+ /** Fetch archive run detail records from the server */
53
+ private fetchArchiveDetails;
54
+ /** Process the query results and update component state */
55
+ private processArchiveResults;
56
+ /** Build the tooltip text from current state */
57
+ private buildTooltipText;
58
+ /** Build an ArchiveVersionInfo from a detail record */
59
+ private buildVersionInfo;
60
+ /** Reset all display state to defaults */
61
+ private resetState;
62
+ static ɵfac: i0.ɵɵFactoryDeclaration<ArchiveStatusBadgeComponent, never>;
63
+ static ɵcmp: i0.ɵɵComponentDeclaration<ArchiveStatusBadgeComponent, "mj-archive-status-badge", never, { "EntityName": { "alias": "EntityName"; "required": false; }; "RecordID": { "alias": "RecordID"; "required": false; }; }, { "RestoreRequested": "RestoreRequested"; }, never, never, false, never>;
64
+ }
65
+ //# sourceMappingURL=archive-status-badge.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive-status-badge.component.d.ts","sourceRoot":"","sources":["../../../src/lib/archive-status/archive-status-badge.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,YAAY,EACZ,SAAS,EAEV,MAAM,eAAe,CAAC;;AAGvB;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,UAAU,EAAE,IAAI,CAAC;IACjB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAOa,2BAA4B,YAAW,SAAS;IAC3D,OAAO,CAAC,GAAG,CAA6B;IAExC,gEAAgE;IAChE,iBAAiB,UAAS;IAE1B,gCAAgC;IAChC,kBAAkB,SAAK;IAEvB,sCAAsC;IACtC,gBAAgB,EAAE,IAAI,GAAG,IAAI,CAAQ;IAErC,wCAAwC;IACxC,SAAS,UAAS;IAElB,kCAAkC;IAClC,WAAW,SAAM;IAEjB,qDAAqD;IACrD,OAAO,CAAC,aAAa,CAAmC;IAExD,sDAAsD;IACtD,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,WAAW,CAAM;IAEzB,IACI,UAAU,CAAC,KAAK,EAAE,MAAM,EAM3B;IACD,IAAI,UAAU,IAAI,MAAM,CAEvB;IAGD,OAAO,CAAC,SAAS,CAAM;IAEvB,IACI,QAAQ,CAAC,KAAK,EAAE,MAAM,EAMzB;IACD,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,kEAAkE;IACxD,gBAAgB,mCAA0C;IAEpE,WAAW,IAAI,IAAI;IAInB,gEAAgE;IAChE,YAAY,IAAI,IAAI;IAMpB;;;OAGG;YACW,iBAAiB;IAqB/B,uDAAuD;YACzC,mBAAmB;IAcjC,2DAA2D;IAC3D,OAAO,CAAC,qBAAqB;IAc7B,gDAAgD;IAChD,OAAO,CAAC,gBAAgB;IAQxB,uDAAuD;IACvD,OAAO,CAAC,gBAAgB;IAWxB,0CAA0C;IAC1C,OAAO,CAAC,UAAU;yCAjJP,2BAA2B;2CAA3B,2BAA2B;CAwJvC"}
@@ -0,0 +1,172 @@
1
+ import { Component, ChangeDetectionStrategy, ChangeDetectorRef, Input, Output, EventEmitter, inject, } from '@angular/core';
2
+ import { RunView } from '@memberjunction/core';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@memberjunction/ng-shared-generic";
5
+ function ArchiveStatusBadgeComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
6
+ const _r1 = i0.ɵɵgetCurrentView();
7
+ i0.ɵɵelementStart(0, "span", 2);
8
+ i0.ɵɵlistener("click", function ArchiveStatusBadgeComponent_Conditional_0_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnBadgeClick()); })("keydown.enter", function ArchiveStatusBadgeComponent_Conditional_0_Template_span_keydown_enter_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnBadgeClick()); });
9
+ i0.ɵɵelement(1, "i", 3);
10
+ i0.ɵɵelementStart(2, "span", 4);
11
+ i0.ɵɵtext(3, "Archived");
12
+ i0.ɵɵelementEnd()();
13
+ } if (rf & 2) {
14
+ const ctx_r1 = i0.ɵɵnextContext();
15
+ i0.ɵɵproperty("title", ctx_r1.TooltipText);
16
+ i0.ɵɵattribute("aria-label", "Archived: " + ctx_r1.TooltipText);
17
+ } }
18
+ function ArchiveStatusBadgeComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
19
+ i0.ɵɵelement(0, "mj-loading", 1);
20
+ } if (rf & 2) {
21
+ i0.ɵɵproperty("showText", false);
22
+ } }
23
+ export class ArchiveStatusBadgeComponent {
24
+ cdr = inject(ChangeDetectorRef);
25
+ /** Whether the badge is visible (record has archived fields) */
26
+ HasArchivedFields = false;
27
+ /** Number of archived fields */
28
+ ArchivedFieldCount = 0;
29
+ /** Date of the most recent archive */
30
+ LastArchivedDate = null;
31
+ /** Whether data is currently loading */
32
+ IsLoading = false;
33
+ /** Tooltip text shown on hover */
34
+ TooltipText = '';
35
+ /** Latest archive version info for event emission */
36
+ latestVersion = null;
37
+ /** Tracks whether the component has been destroyed */
38
+ destroyed = false;
39
+ // --- EntityName input with getter/setter ---
40
+ _entityName = '';
41
+ set EntityName(value) {
42
+ const previous = this._entityName;
43
+ this._entityName = value;
44
+ if (value && value !== previous) {
45
+ this.loadArchiveStatus();
46
+ }
47
+ }
48
+ get EntityName() {
49
+ return this._entityName;
50
+ }
51
+ // --- RecordID input with getter/setter ---
52
+ _recordID = '';
53
+ set RecordID(value) {
54
+ const previous = this._recordID;
55
+ this._recordID = value;
56
+ if (value && value !== previous) {
57
+ this.loadArchiveStatus();
58
+ }
59
+ }
60
+ get RecordID() {
61
+ return this._recordID;
62
+ }
63
+ /** Emitted when the user clicks the badge to request a restore */
64
+ RestoreRequested = new EventEmitter();
65
+ ngOnDestroy() {
66
+ this.destroyed = true;
67
+ }
68
+ /** Handle badge click — emit the latest archive version info */
69
+ OnBadgeClick() {
70
+ if (this.latestVersion) {
71
+ this.RestoreRequested.emit(this.latestVersion);
72
+ }
73
+ }
74
+ /**
75
+ * Load archive status for the current entity/record combination.
76
+ * Queries MJ: Archive Run Details for successful archives.
77
+ */
78
+ async loadArchiveStatus() {
79
+ if (!this._entityName || !this._recordID) {
80
+ return;
81
+ }
82
+ this.IsLoading = true;
83
+ this.cdr.markForCheck();
84
+ try {
85
+ const result = await this.fetchArchiveDetails();
86
+ this.processArchiveResults(result);
87
+ }
88
+ catch {
89
+ this.resetState();
90
+ }
91
+ finally {
92
+ this.IsLoading = false;
93
+ if (!this.destroyed) {
94
+ this.cdr.markForCheck();
95
+ }
96
+ }
97
+ }
98
+ /** Fetch archive run detail records from the server */
99
+ async fetchArchiveDetails() {
100
+ const rv = new RunView();
101
+ const escapedEntity = this._entityName.replace(/'/g, "''");
102
+ const escapedRecord = this._recordID.replace(/'/g, "''");
103
+ return rv.RunView({
104
+ EntityName: 'MJ: Archive Run Details',
105
+ ExtraFilter: `Entity='${escapedEntity}' AND RecordID='${escapedRecord}' AND Status='Success'`,
106
+ OrderBy: '__mj_CreatedAt DESC',
107
+ ResultType: 'simple',
108
+ Fields: ['ID', 'Entity', 'RecordID', 'BytesArchived', '__mj_CreatedAt'],
109
+ });
110
+ }
111
+ /** Process the query results and update component state */
112
+ processArchiveResults(result) {
113
+ if (!result.Success || result.Results.length === 0) {
114
+ this.resetState();
115
+ return;
116
+ }
117
+ const latest = result.Results[0];
118
+ this.HasArchivedFields = true;
119
+ this.ArchivedFieldCount = result.Results.length;
120
+ this.LastArchivedDate = latest.__mj_CreatedAt ? new Date(latest.__mj_CreatedAt) : null;
121
+ this.TooltipText = this.buildTooltipText();
122
+ this.latestVersion = this.buildVersionInfo(latest);
123
+ }
124
+ /** Build the tooltip text from current state */
125
+ buildTooltipText() {
126
+ const countText = `${this.ArchivedFieldCount} field${this.ArchivedFieldCount !== 1 ? 's' : ''} archived`;
127
+ if (this.LastArchivedDate) {
128
+ return `${countText} on ${this.LastArchivedDate.toLocaleDateString()}`;
129
+ }
130
+ return countText;
131
+ }
132
+ /** Build an ArchiveVersionInfo from a detail record */
133
+ buildVersionInfo(record) {
134
+ return {
135
+ DetailID: record.ID,
136
+ EntityName: this._entityName,
137
+ RecordID: this._recordID,
138
+ FieldCount: 0,
139
+ ArchivedAt: record.__mj_CreatedAt ? new Date(record.__mj_CreatedAt) : new Date(),
140
+ Bytes: record.BytesArchived ?? 0,
141
+ };
142
+ }
143
+ /** Reset all display state to defaults */
144
+ resetState() {
145
+ this.HasArchivedFields = false;
146
+ this.ArchivedFieldCount = 0;
147
+ this.LastArchivedDate = null;
148
+ this.TooltipText = '';
149
+ this.latestVersion = null;
150
+ }
151
+ static ɵfac = function ArchiveStatusBadgeComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ArchiveStatusBadgeComponent)(); };
152
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ArchiveStatusBadgeComponent, selectors: [["mj-archive-status-badge"]], inputs: { EntityName: "EntityName", RecordID: "RecordID" }, outputs: { RestoreRequested: "RestoreRequested" }, standalone: false, decls: 2, vars: 2, consts: [["tabindex", "0", "role", "button", 1, "badge", "badge-warning", "badge-pill", "badge-icon", "badge-clickable", 3, "title"], ["size", "small", 3, "showText"], ["tabindex", "0", "role", "button", 1, "badge", "badge-warning", "badge-pill", "badge-icon", "badge-clickable", 3, "click", "keydown.enter", "title"], [1, "fa-solid", "fa-box-archive"], [1, "badge-text"]], template: function ArchiveStatusBadgeComponent_Template(rf, ctx) { if (rf & 1) {
153
+ i0.ɵɵconditionalCreate(0, ArchiveStatusBadgeComponent_Conditional_0_Template, 4, 2, "span", 0);
154
+ i0.ɵɵconditionalCreate(1, ArchiveStatusBadgeComponent_Conditional_1_Template, 1, 1, "mj-loading", 1);
155
+ } if (rf & 2) {
156
+ i0.ɵɵconditional(ctx.HasArchivedFields ? 0 : -1);
157
+ i0.ɵɵadvance();
158
+ i0.ɵɵconditional(ctx.IsLoading ? 1 : -1);
159
+ } }, dependencies: [i1.LoadingComponent], styles: ["[_nghost-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 10px;\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1.4;\n border-radius: 12px;\n white-space: nowrap;\n vertical-align: middle;\n transition: background-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.badge-warning[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n\n.badge-pill[_ngcontent-%COMP%] {\n border-radius: 50px;\n}\n\n.badge-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n}\n\n.badge-clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n user-select: none;\n\n &:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-status-warning) 20%, transparent);\n }\n\n &:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n }\n\n &:active {\n background: color-mix(in srgb, var(--mj-status-warning) 35%, var(--mj-bg-surface));\n }\n}\n\n.badge-text[_ngcontent-%COMP%] {\n letter-spacing: 0.02em;\n}"], changeDetection: 0 });
160
+ }
161
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ArchiveStatusBadgeComponent, [{
162
+ type: Component,
163
+ args: [{ standalone: false, selector: 'mj-archive-status-badge', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (HasArchivedFields) {\n <span\n class=\"badge badge-warning badge-pill badge-icon badge-clickable\"\n [title]=\"TooltipText\"\n (click)=\"OnBadgeClick()\"\n (keydown.enter)=\"OnBadgeClick()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Archived: ' + TooltipText\">\n <i class=\"fa-solid fa-box-archive\"></i>\n <span class=\"badge-text\">Archived</span>\n </span>\n}\n\n@if (IsLoading) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n}\n", styles: [":host {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 10px;\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1.4;\n border-radius: 12px;\n white-space: nowrap;\n vertical-align: middle;\n transition: background-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.badge-warning {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n\n.badge-pill {\n border-radius: 50px;\n}\n\n.badge-icon i {\n font-size: 0.7rem;\n}\n\n.badge-clickable {\n cursor: pointer;\n user-select: none;\n\n &:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-status-warning) 20%, transparent);\n }\n\n &:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n }\n\n &:active {\n background: color-mix(in srgb, var(--mj-status-warning) 35%, var(--mj-bg-surface));\n }\n}\n\n.badge-text {\n letter-spacing: 0.02em;\n}\n"] }]
164
+ }], null, { EntityName: [{
165
+ type: Input
166
+ }], RecordID: [{
167
+ type: Input
168
+ }], RestoreRequested: [{
169
+ type: Output
170
+ }] }); })();
171
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArchiveStatusBadgeComponent, { className: "ArchiveStatusBadgeComponent", filePath: "src/lib/archive-status/archive-status-badge.component.ts", lineNumber: 38 }); })();
172
+ //# sourceMappingURL=archive-status-badge.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive-status-badge.component.js","sourceRoot":"","sources":["../../../src/lib/archive-status/archive-status-badge.component.ts","../../../src/lib/archive-status/archive-status-badge.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Input,\n Output,\n EventEmitter,\n OnDestroy,\n inject,\n} from '@angular/core';\nimport { RunView } from '@memberjunction/core';\n\n/**\n * Summary information about an archived version of a record.\n */\nexport interface ArchiveVersionInfo {\n /** The archive run detail record ID */\n DetailID: string;\n /** Entity name of the archived record */\n EntityName: string;\n /** Primary key of the archived record */\n RecordID: string;\n /** Number of fields that were archived */\n FieldCount: number;\n /** Date the archive was performed */\n ArchivedAt: Date;\n /** Size of the archived data in bytes */\n Bytes: number;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-archive-status-badge',\n templateUrl: './archive-status-badge.component.html',\n styleUrls: ['./archive-status-badge.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ArchiveStatusBadgeComponent implements OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n /** Whether the badge is visible (record has archived fields) */\n HasArchivedFields = false;\n\n /** Number of archived fields */\n ArchivedFieldCount = 0;\n\n /** Date of the most recent archive */\n LastArchivedDate: Date | null = null;\n\n /** Whether data is currently loading */\n IsLoading = false;\n\n /** Tooltip text shown on hover */\n TooltipText = '';\n\n /** Latest archive version info for event emission */\n private latestVersion: ArchiveVersionInfo | null = null;\n\n /** Tracks whether the component has been destroyed */\n private destroyed = false;\n\n // --- EntityName input with getter/setter ---\n private _entityName = '';\n\n @Input()\n set EntityName(value: string) {\n const previous = this._entityName;\n this._entityName = value;\n if (value && value !== previous) {\n this.loadArchiveStatus();\n }\n }\n get EntityName(): string {\n return this._entityName;\n }\n\n // --- RecordID input with getter/setter ---\n private _recordID = '';\n\n @Input()\n set RecordID(value: string) {\n const previous = this._recordID;\n this._recordID = value;\n if (value && value !== previous) {\n this.loadArchiveStatus();\n }\n }\n get RecordID(): string {\n return this._recordID;\n }\n\n /** Emitted when the user clicks the badge to request a restore */\n @Output() RestoreRequested = new EventEmitter<ArchiveVersionInfo>();\n\n ngOnDestroy(): void {\n this.destroyed = true;\n }\n\n /** Handle badge click — emit the latest archive version info */\n OnBadgeClick(): void {\n if (this.latestVersion) {\n this.RestoreRequested.emit(this.latestVersion);\n }\n }\n\n /**\n * Load archive status for the current entity/record combination.\n * Queries MJ: Archive Run Details for successful archives.\n */\n private async loadArchiveStatus(): Promise<void> {\n if (!this._entityName || !this._recordID) {\n return;\n }\n\n this.IsLoading = true;\n this.cdr.markForCheck();\n\n try {\n const result = await this.fetchArchiveDetails();\n this.processArchiveResults(result);\n } catch {\n this.resetState();\n } finally {\n this.IsLoading = false;\n if (!this.destroyed) {\n this.cdr.markForCheck();\n }\n }\n }\n\n /** Fetch archive run detail records from the server */\n private async fetchArchiveDetails(): Promise<{ Success: boolean; Results: ArchiveDetailRecord[] }> {\n const rv = new RunView();\n const escapedEntity = this._entityName.replace(/'/g, \"''\");\n const escapedRecord = this._recordID.replace(/'/g, \"''\");\n\n return rv.RunView<ArchiveDetailRecord>({\n EntityName: 'MJ: Archive Run Details',\n ExtraFilter: `Entity='${escapedEntity}' AND RecordID='${escapedRecord}' AND Status='Success'`,\n OrderBy: '__mj_CreatedAt DESC',\n ResultType: 'simple',\n Fields: ['ID', 'Entity', 'RecordID', 'BytesArchived', '__mj_CreatedAt'],\n });\n }\n\n /** Process the query results and update component state */\n private processArchiveResults(result: { Success: boolean; Results: ArchiveDetailRecord[] }): void {\n if (!result.Success || result.Results.length === 0) {\n this.resetState();\n return;\n }\n\n const latest = result.Results[0];\n this.HasArchivedFields = true;\n this.ArchivedFieldCount = result.Results.length;\n this.LastArchivedDate = latest.__mj_CreatedAt ? new Date(latest.__mj_CreatedAt) : null;\n this.TooltipText = this.buildTooltipText();\n this.latestVersion = this.buildVersionInfo(latest);\n }\n\n /** Build the tooltip text from current state */\n private buildTooltipText(): string {\n const countText = `${this.ArchivedFieldCount} field${this.ArchivedFieldCount !== 1 ? 's' : ''} archived`;\n if (this.LastArchivedDate) {\n return `${countText} on ${this.LastArchivedDate.toLocaleDateString()}`;\n }\n return countText;\n }\n\n /** Build an ArchiveVersionInfo from a detail record */\n private buildVersionInfo(record: ArchiveDetailRecord): ArchiveVersionInfo {\n return {\n DetailID: record.ID,\n EntityName: this._entityName,\n RecordID: this._recordID,\n FieldCount: 0,\n ArchivedAt: record.__mj_CreatedAt ? new Date(record.__mj_CreatedAt) : new Date(),\n Bytes: record.BytesArchived ?? 0,\n };\n }\n\n /** Reset all display state to defaults */\n private resetState(): void {\n this.HasArchivedFields = false;\n this.ArchivedFieldCount = 0;\n this.LastArchivedDate = null;\n this.TooltipText = '';\n this.latestVersion = null;\n }\n}\n\n/** Shape of the simple result from the archive run details query */\ninterface ArchiveDetailRecord {\n ID: string;\n Entity: string;\n RecordID: string;\n BytesArchived: number;\n __mj_CreatedAt: string;\n}\n","@if (HasArchivedFields) {\n <span\n class=\"badge badge-warning badge-pill badge-icon badge-clickable\"\n [title]=\"TooltipText\"\n (click)=\"OnBadgeClick()\"\n (keydown.enter)=\"OnBadgeClick()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Archived: ' + TooltipText\">\n <i class=\"fa-solid fa-box-archive\"></i>\n <span class=\"badge-text\">Archived</span>\n </span>\n}\n\n@if (IsLoading) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n}\n"]}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Lightweight interfaces for archive data used by the Angular UI components.
3
+ * These mirror the database schema fields needed for display purposes.
4
+ * Since CodeGen hasn't run yet for the archive entities, we use RunView
5
+ * with ResultType: 'simple' and these interfaces for type safety.
6
+ */
7
+ /** Shape of a row from the MJ: Archive Run Details view */
8
+ export interface ArchiveRunDetailRow {
9
+ ID: string;
10
+ ArchiveRunID: string;
11
+ EntityID: string;
12
+ RecordID: string;
13
+ Status: 'Success' | 'Failed' | 'Skipped';
14
+ StoragePath: string | null;
15
+ BytesArchived: number;
16
+ ErrorMessage: string | null;
17
+ ArchivedAt: string | null;
18
+ VersionStamp: string | null;
19
+ IsRecordChangeArchive: boolean;
20
+ }
21
+ /** Shape of a row from the MJ: Archive Runs view */
22
+ export interface ArchiveRunRow {
23
+ ID: string;
24
+ ArchiveConfigurationID: string;
25
+ StartedAt: string;
26
+ CompletedAt: string | null;
27
+ Status: 'Running' | 'Complete' | 'Failed' | 'Cancelled' | 'PartialSuccess';
28
+ TotalRecords: number;
29
+ ArchivedRecords: number;
30
+ FailedRecords: number;
31
+ SkippedRecords: number;
32
+ TotalBytesArchived: number;
33
+ ErrorLog: string | null;
34
+ UserID: string;
35
+ /** Denormalized from view join */
36
+ ArchiveConfiguration?: string;
37
+ }
38
+ /** Shape of a row from the MJ: Archive Configurations view */
39
+ export interface ArchiveConfigurationRow {
40
+ ID: string;
41
+ Name: string;
42
+ Description: string | null;
43
+ StorageAccountID: string;
44
+ RootPath: string;
45
+ ArchiveFormat: 'JSON' | 'Parquet' | 'CSV';
46
+ IsActive: boolean;
47
+ DefaultRetentionDays: number;
48
+ DefaultMode: 'StripFields' | 'SoftDelete' | 'HardDelete' | 'ArchiveOnly';
49
+ DefaultBatchSize: number;
50
+ ArchiveRelatedRecordChanges: boolean;
51
+ Status: 'Idle' | 'Running' | 'Error' | 'Disabled';
52
+ CreatedByUserID: string;
53
+ /** Denormalized from view join */
54
+ StorageAccount?: string;
55
+ }
56
+ /** Shape of a row from the MJ: Archive Configuration Entities view */
57
+ export interface ArchiveConfigEntityRow {
58
+ ID: string;
59
+ ArchiveConfigurationID: string;
60
+ EntityID: string;
61
+ Mode: 'StripFields' | 'SoftDelete' | 'HardDelete' | 'ArchiveOnly' | null;
62
+ RetentionDays: number | null;
63
+ DateField: string;
64
+ FilterExpression: string | null;
65
+ BatchSize: number | null;
66
+ Priority: number;
67
+ FieldConfiguration: string;
68
+ DriverClass: string | null;
69
+ ArchiveRelatedRecordChanges: boolean | null;
70
+ IsActive: boolean;
71
+ /** Denormalized from view join */
72
+ Entity?: string;
73
+ }
74
+ /** Info passed from status badge to restore dialog */
75
+ export interface ArchiveVersionInfo {
76
+ EntityName: string;
77
+ RecordID: string;
78
+ LatestArchiveDate: Date;
79
+ FieldCount: number;
80
+ }
81
+ //# sourceMappingURL=archive-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive-types.d.ts","sourceRoot":"","sources":["../../src/lib/archive-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Lightweight interfaces for archive data used by the Angular UI components.
3
+ * These mirror the database schema fields needed for display purposes.
4
+ * Since CodeGen hasn't run yet for the archive entities, we use RunView
5
+ * with ResultType: 'simple' and these interfaces for type safety.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=archive-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive-types.js","sourceRoot":"","sources":["../../src/lib/archive-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG","sourcesContent":["/**\n * Lightweight interfaces for archive data used by the Angular UI components.\n * These mirror the database schema fields needed for display purposes.\n * Since CodeGen hasn't run yet for the archive entities, we use RunView\n * with ResultType: 'simple' and these interfaces for type safety.\n */\n\n/** Shape of a row from the MJ: Archive Run Details view */\nexport interface ArchiveRunDetailRow {\n ID: string;\n ArchiveRunID: string;\n EntityID: string;\n RecordID: string;\n Status: 'Success' | 'Failed' | 'Skipped';\n StoragePath: string | null;\n BytesArchived: number;\n ErrorMessage: string | null;\n ArchivedAt: string | null;\n VersionStamp: string | null;\n IsRecordChangeArchive: boolean;\n}\n\n/** Shape of a row from the MJ: Archive Runs view */\nexport interface ArchiveRunRow {\n ID: string;\n ArchiveConfigurationID: string;\n StartedAt: string;\n CompletedAt: string | null;\n Status: 'Running' | 'Complete' | 'Failed' | 'Cancelled' | 'PartialSuccess';\n TotalRecords: number;\n ArchivedRecords: number;\n FailedRecords: number;\n SkippedRecords: number;\n TotalBytesArchived: number;\n ErrorLog: string | null;\n UserID: string;\n /** Denormalized from view join */\n ArchiveConfiguration?: string;\n}\n\n/** Shape of a row from the MJ: Archive Configurations view */\nexport interface ArchiveConfigurationRow {\n ID: string;\n Name: string;\n Description: string | null;\n StorageAccountID: string;\n RootPath: string;\n ArchiveFormat: 'JSON' | 'Parquet' | 'CSV';\n IsActive: boolean;\n DefaultRetentionDays: number;\n DefaultMode: 'StripFields' | 'SoftDelete' | 'HardDelete' | 'ArchiveOnly';\n DefaultBatchSize: number;\n ArchiveRelatedRecordChanges: boolean;\n Status: 'Idle' | 'Running' | 'Error' | 'Disabled';\n CreatedByUserID: string;\n /** Denormalized from view join */\n StorageAccount?: string;\n}\n\n/** Shape of a row from the MJ: Archive Configuration Entities view */\nexport interface ArchiveConfigEntityRow {\n ID: string;\n ArchiveConfigurationID: string;\n EntityID: string;\n Mode: 'StripFields' | 'SoftDelete' | 'HardDelete' | 'ArchiveOnly' | null;\n RetentionDays: number | null;\n DateField: string;\n FilterExpression: string | null;\n BatchSize: number | null;\n Priority: number;\n FieldConfiguration: string;\n DriverClass: string | null;\n ArchiveRelatedRecordChanges: boolean | null;\n IsActive: boolean;\n /** Denormalized from view join */\n Entity?: string;\n}\n\n/** Info passed from status badge to restore dialog */\nexport interface ArchiveVersionInfo {\n EntityName: string;\n RecordID: string;\n LatestArchiveDate: Date;\n FieldCount: number;\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export * from './lib/archive-manager.module';
2
+ export * from './lib/archive-status/archive-status-badge.component';
3
+ export * from './lib/archive-restore/archive-restore-dialog.component';
4
+ export * from './lib/archive-config/archive-config-admin.component';
5
+ export * from './lib/archive-run-viewer/archive-run-viewer.component';
6
+ //# sourceMappingURL=public-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAKA,cAAc,8BAA8B,CAAC;AAG7C,cAAc,qDAAqD,CAAC;AACpE,cAAc,wDAAwD,CAAC;AACvE,cAAc,qDAAqD,CAAC;AACpE,cAAc,uDAAuD,CAAC"}
@@ -0,0 +1,11 @@
1
+ /*
2
+ * Public API Surface for @memberjunction/ng-archive-manager
3
+ */
4
+ // Module
5
+ export * from './lib/archive-manager.module';
6
+ // Components
7
+ export * from './lib/archive-status/archive-status-badge.component';
8
+ export * from './lib/archive-restore/archive-restore-dialog.component';
9
+ export * from './lib/archive-config/archive-config-admin.component';
10
+ export * from './lib/archive-run-viewer/archive-run-viewer.component';
11
+ //# sourceMappingURL=public-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,cAAc,8BAA8B,CAAC;AAE7C,aAAa;AACb,cAAc,qDAAqD,CAAC;AACpE,cAAc,wDAAwD,CAAC;AACvE,cAAc,qDAAqD,CAAC;AACpE,cAAc,uDAAuD,CAAC","sourcesContent":["/*\n * Public API Surface for @memberjunction/ng-archive-manager\n */\n\n// Module\nexport * from './lib/archive-manager.module';\n\n// Components\nexport * from './lib/archive-status/archive-status-badge.component';\nexport * from './lib/archive-restore/archive-restore-dialog.component';\nexport * from './lib/archive-config/archive-config-admin.component';\nexport * from './lib/archive-run-viewer/archive-run-viewer.component';\n"]}
package/package.json CHANGED
@@ -1,10 +1,46 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-archive-manager",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @memberjunction/ng-archive-manager",
3
+ "version": "5.30.0",
4
+ "description": "MemberJunction: Angular Archive Manager - UI components for managing entity field archiving, restoration, and configuration.",
5
+ "main": "./dist/public-api.js",
6
+ "typings": "./dist/public-api.d.ts",
7
+ "files": [
8
+ "/dist"
9
+ ],
10
+ "scripts": {
11
+ "test": "echo \"No tests configured yet\"",
12
+ "build": "npm run clean && ngc",
13
+ "clean": "rimraf dist",
14
+ "test:watch": "vitest"
15
+ },
5
16
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
17
+ "MemberJunction",
18
+ "Angular",
19
+ "Archiving"
20
+ ],
21
+ "author": "",
22
+ "license": "ISC",
23
+ "devDependencies": {
24
+ "@angular/compiler": "21.1.3",
25
+ "@angular/compiler-cli": "21.1.3",
26
+ "vitest": "^4.0.18"
27
+ },
28
+ "peerDependencies": {
29
+ "@angular/common": "21.1.3",
30
+ "@angular/core": "21.1.3",
31
+ "@angular/forms": "21.1.3",
32
+ "rxjs": "^7.8.2"
33
+ },
34
+ "dependencies": {
35
+ "@memberjunction/core": "5.30.0",
36
+ "@memberjunction/core-entities": "5.30.0",
37
+ "@memberjunction/global": "5.30.0",
38
+ "@memberjunction/ng-shared-generic": "5.30.0",
39
+ "tslib": "^2.8.1"
40
+ },
41
+ "sideEffects": false,
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/MemberJunction/MJ"
45
+ }
10
46
  }
package/README.md DELETED
@@ -1,45 +0,0 @@
1
- # @memberjunction/ng-archive-manager
2
-
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
-
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@memberjunction/ng-archive-manager`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**