@memberjunction/ng-record-changes 3.4.0 → 4.1.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.
- package/dist/lib/ng-record-changes.component.d.ts +38 -14
- package/dist/lib/ng-record-changes.component.d.ts.map +1 -1
- package/dist/lib/ng-record-changes.component.js +452 -260
- package/dist/lib/ng-record-changes.component.js.map +1 -1
- package/dist/lib/ng-record-changes.module.d.ts +4 -10
- package/dist/lib/ng-record-changes.module.d.ts.map +1 -1
- package/dist/lib/ng-record-changes.module.js +9 -37
- package/dist/lib/ng-record-changes.module.js.map +1 -1
- package/package.json +18 -24
- package/README.md +0 -334
|
@@ -1,396 +1,502 @@
|
|
|
1
|
-
import { Component, EventEmitter, Input, Output,
|
|
2
|
-
import { EntityFieldTSType, Metadata } from '@memberjunction/core';
|
|
1
|
+
import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
|
|
2
|
+
import { EntityFieldTSType, Metadata, RunView } from '@memberjunction/core';
|
|
3
3
|
import { diffChars, diffWords } from 'diff';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
import * as i1 from "@memberjunction/ng-notifications";
|
|
6
6
|
import * as i2 from "@angular/platform-browser";
|
|
7
|
-
import * as i3 from "@angular/
|
|
8
|
-
import * as i4 from "@
|
|
9
|
-
import * as i5 from "@
|
|
10
|
-
|
|
11
|
-
const _c0 = ["recordChangesWrapper"];
|
|
7
|
+
import * as i3 from "@angular/forms";
|
|
8
|
+
import * as i4 from "@memberjunction/ng-shared-generic";
|
|
9
|
+
import * as i5 from "@memberjunction/ng-versions";
|
|
10
|
+
const _c0 = a0 => [a0];
|
|
12
11
|
const _forTrack0 = ($index, $item) => $item.ID;
|
|
13
12
|
const _forTrack1 = ($index, $item) => $item.name;
|
|
14
13
|
const _forTrack2 = ($index, $item) => $item.field;
|
|
15
|
-
function
|
|
16
|
-
i0.ɵɵelement(0, "mj-loading",
|
|
14
|
+
function RecordChangesComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
15
|
+
i0.ɵɵelement(0, "mj-loading", 1);
|
|
17
16
|
} }
|
|
18
|
-
function
|
|
19
|
-
i0.ɵɵelementStart(0, "
|
|
17
|
+
function RecordChangesComponent_Conditional_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
18
|
+
i0.ɵɵelementStart(0, "span", 8);
|
|
20
19
|
i0.ɵɵtext(1);
|
|
21
20
|
i0.ɵɵelementEnd();
|
|
22
21
|
} if (rf & 2) {
|
|
23
|
-
const
|
|
22
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
24
23
|
i0.ɵɵadvance();
|
|
25
|
-
i0.ɵɵ
|
|
24
|
+
i0.ɵɵtextInterpolate(ctx_r1.RecordLabels.length);
|
|
26
25
|
} }
|
|
27
|
-
function
|
|
28
|
-
i0.ɵɵ
|
|
29
|
-
i0.ɵɵ
|
|
26
|
+
function RecordChangesComponent_Conditional_2_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
27
|
+
i0.ɵɵelementStart(0, "div", 11);
|
|
28
|
+
i0.ɵɵelement(1, "i", 15);
|
|
29
|
+
i0.ɵɵtext(2, " Loading labels... ");
|
|
30
|
+
i0.ɵɵelementEnd();
|
|
31
|
+
} }
|
|
32
|
+
function RecordChangesComponent_Conditional_2_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
33
|
+
i0.ɵɵelementStart(0, "div", 12);
|
|
34
|
+
i0.ɵɵtext(1, " No version labels for this record yet. ");
|
|
35
|
+
i0.ɵɵelementEnd();
|
|
30
36
|
} }
|
|
31
|
-
function
|
|
32
|
-
i0.ɵɵ
|
|
33
|
-
i0.ɵɵ
|
|
37
|
+
function RecordChangesComponent_Conditional_2_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
38
|
+
i0.ɵɵelementStart(0, "div", 16);
|
|
39
|
+
i0.ɵɵelement(1, "i", 17);
|
|
40
|
+
i0.ɵɵelementStart(2, "span", 18);
|
|
41
|
+
i0.ɵɵtext(3);
|
|
42
|
+
i0.ɵɵelementEnd();
|
|
43
|
+
i0.ɵɵelementStart(4, "span", 19)(5, "span", 20);
|
|
44
|
+
i0.ɵɵtext(6);
|
|
45
|
+
i0.ɵɵelementEnd();
|
|
46
|
+
i0.ɵɵelementStart(7, "span", 21);
|
|
47
|
+
i0.ɵɵtext(8);
|
|
48
|
+
i0.ɵɵelementEnd()()();
|
|
49
|
+
} if (rf & 2) {
|
|
50
|
+
const label_r3 = ctx.$implicit;
|
|
51
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
52
|
+
i0.ɵɵproperty("title", label_r3.Description || label_r3.Name);
|
|
53
|
+
i0.ɵɵadvance(3);
|
|
54
|
+
i0.ɵɵtextInterpolate(label_r3.Name);
|
|
55
|
+
i0.ɵɵadvance(2);
|
|
56
|
+
i0.ɵɵclassMap(ctx_r1.getLabelStatusClass(label_r3.Status));
|
|
57
|
+
i0.ɵɵadvance();
|
|
58
|
+
i0.ɵɵtextInterpolate(label_r3.Status);
|
|
59
|
+
i0.ɵɵadvance(2);
|
|
60
|
+
i0.ɵɵtextInterpolate2("", label_r3.ItemCount, " item", label_r3.ItemCount !== 1 ? "s" : "");
|
|
34
61
|
} }
|
|
35
|
-
function
|
|
36
|
-
i0.ɵɵelementStart(0, "div",
|
|
37
|
-
i0.ɵɵ
|
|
62
|
+
function RecordChangesComponent_Conditional_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
63
|
+
i0.ɵɵelementStart(0, "div", 13);
|
|
64
|
+
i0.ɵɵrepeaterCreate(1, RecordChangesComponent_Conditional_2_Conditional_13_For_2_Template, 9, 7, "div", 16, _forTrack0);
|
|
38
65
|
i0.ɵɵelementEnd();
|
|
39
66
|
} if (rf & 2) {
|
|
40
|
-
const
|
|
67
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
41
68
|
i0.ɵɵadvance();
|
|
42
|
-
i0.ɵɵ
|
|
69
|
+
i0.ɵɵrepeater(ctx_r1.RecordLabels);
|
|
43
70
|
} }
|
|
44
|
-
function
|
|
45
|
-
i0.ɵɵ
|
|
71
|
+
function RecordChangesComponent_Conditional_2_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
72
|
+
i0.ɵɵelementStart(0, "div", 14)(1, "div", 22);
|
|
73
|
+
i0.ɵɵelement(2, "i", 23);
|
|
74
|
+
i0.ɵɵelementEnd();
|
|
75
|
+
i0.ɵɵelementStart(3, "h3", 24);
|
|
76
|
+
i0.ɵɵtext(4, "No Change History");
|
|
77
|
+
i0.ɵɵelementEnd();
|
|
78
|
+
i0.ɵɵelementStart(5, "p", 25);
|
|
79
|
+
i0.ɵɵtext(6, " This record doesn't have any tracked changes yet. Changes will appear here automatically as edits are made. ");
|
|
80
|
+
i0.ɵɵelementEnd();
|
|
81
|
+
i0.ɵɵelementStart(7, "div", 26);
|
|
82
|
+
i0.ɵɵelement(8, "i", 27);
|
|
83
|
+
i0.ɵɵelementStart(9, "span");
|
|
84
|
+
i0.ɵɵtext(10, "Record change tracking is managed at the entity level");
|
|
85
|
+
i0.ɵɵelementEnd()()();
|
|
46
86
|
} }
|
|
47
|
-
function
|
|
48
|
-
i0.ɵɵelementStart(0, "
|
|
87
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
88
|
+
i0.ɵɵelementStart(0, "div", 39);
|
|
49
89
|
i0.ɵɵtext(1);
|
|
50
90
|
i0.ɵɵelementEnd();
|
|
51
91
|
} if (rf & 2) {
|
|
52
|
-
const
|
|
92
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
53
93
|
i0.ɵɵadvance();
|
|
54
|
-
i0.ɵɵ
|
|
94
|
+
i0.ɵɵtextInterpolate2(" Showing ", ctx_r1.filteredData.length, " of ", ctx_r1.viewData.length, " changes ");
|
|
55
95
|
} }
|
|
56
|
-
function
|
|
57
|
-
i0.ɵɵ
|
|
96
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
97
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
98
|
+
i0.ɵɵelementStart(0, "div", 41);
|
|
99
|
+
i0.ɵɵelement(1, "i", 43);
|
|
100
|
+
i0.ɵɵelementStart(2, "p");
|
|
101
|
+
i0.ɵɵtext(3, "No changes match your current filters.");
|
|
102
|
+
i0.ɵɵelementEnd();
|
|
103
|
+
i0.ɵɵelementStart(4, "button", 44);
|
|
104
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_21_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ClearFilters()); });
|
|
105
|
+
i0.ɵɵelement(5, "i", 45);
|
|
106
|
+
i0.ɵɵtext(6, " Clear Filters ");
|
|
107
|
+
i0.ɵɵelementEnd()();
|
|
108
|
+
} }
|
|
109
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
110
|
+
i0.ɵɵelement(0, "div", 50);
|
|
111
|
+
} }
|
|
112
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
113
|
+
i0.ɵɵelementStart(0, "span", 60);
|
|
58
114
|
i0.ɵɵtext(1);
|
|
59
115
|
i0.ɵɵelementEnd();
|
|
60
116
|
} if (rf & 2) {
|
|
61
|
-
const
|
|
62
|
-
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
117
|
+
const change_r7 = i0.ɵɵnextContext().$implicit;
|
|
63
118
|
i0.ɵɵadvance();
|
|
64
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
119
|
+
i0.ɵɵtextInterpolate1(" via ", change_r7.Integration, " ");
|
|
65
120
|
} }
|
|
66
|
-
function
|
|
67
|
-
i0.ɵɵelementStart(0, "div",
|
|
121
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
122
|
+
i0.ɵɵelementStart(0, "div", 61);
|
|
123
|
+
i0.ɵɵtext(1);
|
|
124
|
+
i0.ɵɵelementEnd();
|
|
125
|
+
} if (rf & 2) {
|
|
126
|
+
const change_r7 = i0.ɵɵnextContext().$implicit;
|
|
127
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
128
|
+
i0.ɵɵadvance();
|
|
129
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.getChangeSummary(change_r7), " ");
|
|
130
|
+
} }
|
|
131
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_5_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
132
|
+
i0.ɵɵelementStart(0, "div", 71)(1, "span", 72);
|
|
68
133
|
i0.ɵɵtext(2);
|
|
69
134
|
i0.ɵɵelementEnd();
|
|
70
|
-
i0.ɵɵelementStart(3, "span",
|
|
135
|
+
i0.ɵɵelementStart(3, "span", 73);
|
|
71
136
|
i0.ɵɵtext(4);
|
|
72
137
|
i0.ɵɵelementEnd()();
|
|
73
138
|
} if (rf & 2) {
|
|
74
|
-
const
|
|
139
|
+
const field_r8 = ctx.$implicit;
|
|
75
140
|
i0.ɵɵadvance(2);
|
|
76
|
-
i0.ɵɵtextInterpolate(
|
|
141
|
+
i0.ɵɵtextInterpolate(field_r8.displayName);
|
|
77
142
|
i0.ɵɵadvance(2);
|
|
78
|
-
i0.ɵɵtextInterpolate(
|
|
143
|
+
i0.ɵɵtextInterpolate(field_r8.value);
|
|
79
144
|
} }
|
|
80
|
-
function
|
|
81
|
-
i0.ɵɵelementStart(0, "div",
|
|
82
|
-
i0.ɵɵrepeaterCreate(1,
|
|
145
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
146
|
+
i0.ɵɵelementStart(0, "div", 70);
|
|
147
|
+
i0.ɵɵrepeaterCreate(1, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_5_Conditional_4_For_2_Template, 5, 2, "div", 71, _forTrack1);
|
|
83
148
|
i0.ɵɵelementEnd();
|
|
84
149
|
} if (rf & 2) {
|
|
85
|
-
const
|
|
86
|
-
const
|
|
150
|
+
const change_r7 = i0.ɵɵnextContext(3).$implicit;
|
|
151
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
87
152
|
i0.ɵɵadvance();
|
|
88
|
-
i0.ɵɵrepeater(
|
|
153
|
+
i0.ɵɵrepeater(ctx_r1.getCreatedFields(change_r7));
|
|
89
154
|
} }
|
|
90
|
-
function
|
|
91
|
-
i0.ɵɵelementStart(0, "div",
|
|
92
|
-
i0.ɵɵelement(2, "i",
|
|
155
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
156
|
+
i0.ɵɵelementStart(0, "div", 65)(1, "h4");
|
|
157
|
+
i0.ɵɵelement(2, "i", 10);
|
|
93
158
|
i0.ɵɵtext(3, " Record Created");
|
|
94
159
|
i0.ɵɵelementEnd();
|
|
95
|
-
i0.ɵɵ
|
|
160
|
+
i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_5_Conditional_4_Template, 3, 0, "div", 70);
|
|
96
161
|
i0.ɵɵelementEnd();
|
|
97
162
|
} if (rf & 2) {
|
|
98
|
-
const
|
|
163
|
+
const change_r7 = i0.ɵɵnextContext(2).$implicit;
|
|
99
164
|
i0.ɵɵadvance(4);
|
|
100
|
-
i0.ɵɵconditional(
|
|
165
|
+
i0.ɵɵconditional(change_r7.FullRecordJSON ? 4 : -1);
|
|
101
166
|
} }
|
|
102
|
-
function
|
|
103
|
-
i0.ɵɵelementStart(0, "div",
|
|
104
|
-
i0.ɵɵelement(2, "i",
|
|
167
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
168
|
+
i0.ɵɵelementStart(0, "div", 66)(1, "h4");
|
|
169
|
+
i0.ɵɵelement(2, "i", 74);
|
|
105
170
|
i0.ɵɵtext(3, " Record Deleted");
|
|
106
171
|
i0.ɵɵelementEnd();
|
|
107
|
-
i0.ɵɵelementStart(4, "p",
|
|
172
|
+
i0.ɵɵelementStart(4, "p", 75);
|
|
108
173
|
i0.ɵɵtext(5, "This record was permanently removed from the system.");
|
|
109
174
|
i0.ɵɵelementEnd()();
|
|
110
175
|
} }
|
|
111
|
-
function
|
|
112
|
-
i0.ɵɵelementStart(0, "div",
|
|
176
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_7_For_6_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
177
|
+
i0.ɵɵelementStart(0, "div", 78)(1, "span", 81);
|
|
113
178
|
i0.ɵɵtext(2);
|
|
114
179
|
i0.ɵɵelementEnd()();
|
|
115
180
|
} if (rf & 2) {
|
|
116
|
-
const
|
|
181
|
+
const fieldChange_r9 = i0.ɵɵnextContext().$implicit;
|
|
117
182
|
i0.ɵɵadvance(2);
|
|
118
|
-
i0.ɵɵtextInterpolate(
|
|
183
|
+
i0.ɵɵtextInterpolate(fieldChange_r9.newValue);
|
|
119
184
|
} }
|
|
120
|
-
function
|
|
121
|
-
i0.ɵɵelementStart(0, "div",
|
|
122
|
-
i0.ɵɵelement(1, "div",
|
|
185
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_7_For_6_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
186
|
+
i0.ɵɵelementStart(0, "div", 79);
|
|
187
|
+
i0.ɵɵelement(1, "div", 82);
|
|
123
188
|
i0.ɵɵelementEnd();
|
|
124
189
|
} if (rf & 2) {
|
|
125
|
-
const
|
|
190
|
+
const fieldChange_r9 = i0.ɵɵnextContext().$implicit;
|
|
126
191
|
i0.ɵɵadvance();
|
|
127
|
-
i0.ɵɵproperty("innerHTML",
|
|
192
|
+
i0.ɵɵproperty("innerHTML", fieldChange_r9.diffHtml, i0.ɵɵsanitizeHtml);
|
|
128
193
|
} }
|
|
129
|
-
function
|
|
130
|
-
i0.ɵɵelementStart(0, "div",
|
|
194
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_7_For_6_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
195
|
+
i0.ɵɵelementStart(0, "div", 80)(1, "div", 83)(2, "span", 84);
|
|
131
196
|
i0.ɵɵtext(3, "From:");
|
|
132
197
|
i0.ɵɵelementEnd();
|
|
133
|
-
i0.ɵɵelementStart(4, "span",
|
|
198
|
+
i0.ɵɵelementStart(4, "span", 85);
|
|
134
199
|
i0.ɵɵtext(5);
|
|
135
200
|
i0.ɵɵelementEnd()();
|
|
136
|
-
i0.ɵɵelementStart(6, "div",
|
|
137
|
-
i0.ɵɵelement(7, "i",
|
|
201
|
+
i0.ɵɵelementStart(6, "div", 86);
|
|
202
|
+
i0.ɵɵelement(7, "i", 87);
|
|
138
203
|
i0.ɵɵelementEnd();
|
|
139
|
-
i0.ɵɵelementStart(8, "div",
|
|
204
|
+
i0.ɵɵelementStart(8, "div", 81)(9, "span", 84);
|
|
140
205
|
i0.ɵɵtext(10, "To:");
|
|
141
206
|
i0.ɵɵelementEnd();
|
|
142
|
-
i0.ɵɵelementStart(11, "span",
|
|
207
|
+
i0.ɵɵelementStart(11, "span", 85);
|
|
143
208
|
i0.ɵɵtext(12);
|
|
144
209
|
i0.ɵɵelementEnd()()();
|
|
145
210
|
} if (rf & 2) {
|
|
146
|
-
const
|
|
211
|
+
const fieldChange_r9 = i0.ɵɵnextContext().$implicit;
|
|
147
212
|
i0.ɵɵadvance(5);
|
|
148
|
-
i0.ɵɵtextInterpolate(
|
|
213
|
+
i0.ɵɵtextInterpolate(fieldChange_r9.oldValue || "(empty)");
|
|
149
214
|
i0.ɵɵadvance(7);
|
|
150
|
-
i0.ɵɵtextInterpolate(
|
|
215
|
+
i0.ɵɵtextInterpolate(fieldChange_r9.newValue || "(empty)");
|
|
151
216
|
} }
|
|
152
|
-
function
|
|
153
|
-
i0.ɵɵelementStart(0, "div",
|
|
217
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_7_For_6_Template(rf, ctx) { if (rf & 1) {
|
|
218
|
+
i0.ɵɵelementStart(0, "div", 77)(1, "div", 72);
|
|
154
219
|
i0.ɵɵtext(2);
|
|
155
220
|
i0.ɵɵelementEnd();
|
|
156
|
-
i0.ɵɵ
|
|
221
|
+
i0.ɵɵconditionalCreate(3, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_7_For_6_Conditional_3_Template, 3, 1, "div", 78)(4, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_7_For_6_Conditional_4_Template, 2, 1, "div", 79)(5, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_7_For_6_Conditional_5_Template, 13, 2, "div", 80);
|
|
157
222
|
i0.ɵɵelementEnd();
|
|
158
223
|
} if (rf & 2) {
|
|
159
|
-
const
|
|
224
|
+
const fieldChange_r9 = ctx.$implicit;
|
|
160
225
|
i0.ɵɵadvance(2);
|
|
161
|
-
i0.ɵɵtextInterpolate(
|
|
226
|
+
i0.ɵɵtextInterpolate(fieldChange_r9.displayName);
|
|
162
227
|
i0.ɵɵadvance();
|
|
163
|
-
i0.ɵɵconditional(
|
|
228
|
+
i0.ɵɵconditional(fieldChange_r9.isBooleanField ? 3 : fieldChange_r9.diffHtml ? 4 : 5);
|
|
164
229
|
} }
|
|
165
|
-
function
|
|
166
|
-
i0.ɵɵelementStart(0, "div",
|
|
167
|
-
i0.ɵɵelement(2, "i",
|
|
230
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
231
|
+
i0.ɵɵelementStart(0, "div", 67)(1, "h4");
|
|
232
|
+
i0.ɵɵelement(2, "i", 76);
|
|
168
233
|
i0.ɵɵtext(3, " Fields Changed");
|
|
169
234
|
i0.ɵɵelementEnd();
|
|
170
|
-
i0.ɵɵelementStart(4, "div",
|
|
171
|
-
i0.ɵɵrepeaterCreate(5,
|
|
235
|
+
i0.ɵɵelementStart(4, "div", 70);
|
|
236
|
+
i0.ɵɵrepeaterCreate(5, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_7_For_6_Template, 6, 2, "div", 77, _forTrack2);
|
|
172
237
|
i0.ɵɵelementEnd()();
|
|
173
238
|
} if (rf & 2) {
|
|
174
|
-
const
|
|
175
|
-
const
|
|
239
|
+
const change_r7 = i0.ɵɵnextContext(2).$implicit;
|
|
240
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
176
241
|
i0.ɵɵadvance(5);
|
|
177
|
-
i0.ɵɵrepeater(
|
|
242
|
+
i0.ɵɵrepeater(ctx_r1.getFieldChanges(change_r7));
|
|
178
243
|
} }
|
|
179
|
-
function
|
|
180
|
-
i0.ɵɵelementStart(0, "div",
|
|
181
|
-
i0.ɵɵelement(2, "i",
|
|
244
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
245
|
+
i0.ɵɵelementStart(0, "div", 68)(1, "h5");
|
|
246
|
+
i0.ɵɵelement(2, "i", 88);
|
|
182
247
|
i0.ɵɵtext(3, " Comments");
|
|
183
248
|
i0.ɵɵelementEnd();
|
|
184
249
|
i0.ɵɵelementStart(4, "p");
|
|
185
250
|
i0.ɵɵtext(5);
|
|
186
251
|
i0.ɵɵelementEnd()();
|
|
187
252
|
} if (rf & 2) {
|
|
188
|
-
const
|
|
253
|
+
const change_r7 = i0.ɵɵnextContext(2).$implicit;
|
|
189
254
|
i0.ɵɵadvance(5);
|
|
190
|
-
i0.ɵɵtextInterpolate(
|
|
255
|
+
i0.ɵɵtextInterpolate(change_r7.Comments);
|
|
191
256
|
} }
|
|
192
|
-
function
|
|
193
|
-
i0.ɵɵelementStart(0, "div",
|
|
194
|
-
i0.ɵɵelement(2, "i",
|
|
257
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
258
|
+
i0.ɵɵelementStart(0, "div", 69)(1, "h5");
|
|
259
|
+
i0.ɵɵelement(2, "i", 89);
|
|
195
260
|
i0.ɵɵtext(3, " Errors");
|
|
196
261
|
i0.ɵɵelementEnd();
|
|
197
|
-
i0.ɵɵelementStart(4, "pre",
|
|
262
|
+
i0.ɵɵelementStart(4, "pre", 90);
|
|
198
263
|
i0.ɵɵtext(5);
|
|
199
264
|
i0.ɵɵelementEnd()();
|
|
200
265
|
} if (rf & 2) {
|
|
201
|
-
const
|
|
266
|
+
const change_r7 = i0.ɵɵnextContext(2).$implicit;
|
|
202
267
|
i0.ɵɵadvance(5);
|
|
203
|
-
i0.ɵɵtextInterpolate(
|
|
268
|
+
i0.ɵɵtextInterpolate(change_r7.ErrorLog);
|
|
204
269
|
} }
|
|
205
|
-
function
|
|
206
|
-
i0.ɵɵelementStart(0, "div",
|
|
207
|
-
i0.ɵɵelement(2, "i",
|
|
270
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
271
|
+
i0.ɵɵelementStart(0, "div", 62)(1, "div", 63);
|
|
272
|
+
i0.ɵɵelement(2, "i", 64);
|
|
208
273
|
i0.ɵɵelementStart(3, "strong");
|
|
209
274
|
i0.ɵɵtext(4);
|
|
210
275
|
i0.ɵɵelementEnd()();
|
|
211
|
-
i0.ɵɵ
|
|
276
|
+
i0.ɵɵconditionalCreate(5, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_5_Template, 5, 1, "div", 65)(6, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_6_Template, 6, 0, "div", 66)(7, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_7_Template, 7, 0, "div", 67);
|
|
277
|
+
i0.ɵɵconditionalCreate(8, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_8_Template, 6, 1, "div", 68);
|
|
278
|
+
i0.ɵɵconditionalCreate(9, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Conditional_9_Template, 6, 1, "div", 69);
|
|
212
279
|
i0.ɵɵelementEnd();
|
|
213
280
|
} if (rf & 2) {
|
|
214
|
-
const
|
|
215
|
-
const
|
|
281
|
+
const change_r7 = i0.ɵɵnextContext().$implicit;
|
|
282
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
216
283
|
i0.ɵɵadvance(4);
|
|
217
|
-
i0.ɵɵtextInterpolate(
|
|
284
|
+
i0.ɵɵtextInterpolate(ctx_r1.formatFullDateTime(change_r7.ChangedAt));
|
|
218
285
|
i0.ɵɵadvance();
|
|
219
|
-
i0.ɵɵconditional(
|
|
286
|
+
i0.ɵɵconditional(change_r7.Type === "Create" ? 5 : change_r7.Type === "Delete" ? 6 : 7);
|
|
220
287
|
i0.ɵɵadvance(3);
|
|
221
|
-
i0.ɵɵconditional(
|
|
288
|
+
i0.ɵɵconditional(change_r7.Comments ? 8 : -1);
|
|
222
289
|
i0.ɵɵadvance();
|
|
223
|
-
i0.ɵɵconditional(
|
|
290
|
+
i0.ɵɵconditional(change_r7.ErrorLog ? 9 : -1);
|
|
224
291
|
} }
|
|
225
|
-
function
|
|
226
|
-
const
|
|
227
|
-
i0.ɵɵelementStart(0, "div",
|
|
228
|
-
i0.ɵɵlistener("click", function
|
|
229
|
-
i0.ɵɵelementStart(1, "div",
|
|
292
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
293
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
294
|
+
i0.ɵɵelementStart(0, "div", 47);
|
|
295
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Template_div_click_0_listener() { const change_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.toggleExpansion(change_r7.ID)); })("keydown", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Template_div_keydown_0_listener($event) { const change_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.onTimelineItemKeydown($event, change_r7.ID)); });
|
|
296
|
+
i0.ɵɵelementStart(1, "div", 48)(2, "div", 49);
|
|
230
297
|
i0.ɵɵelement(3, "i");
|
|
231
298
|
i0.ɵɵelementEnd();
|
|
232
|
-
i0.ɵɵ
|
|
299
|
+
i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_4_Template, 1, 0, "div", 50);
|
|
233
300
|
i0.ɵɵelementEnd();
|
|
234
|
-
i0.ɵɵelementStart(5, "div",
|
|
301
|
+
i0.ɵɵelementStart(5, "div", 51)(6, "div", 52)(7, "div", 53)(8, "span", 54);
|
|
235
302
|
i0.ɵɵtext(9);
|
|
236
303
|
i0.ɵɵelementEnd();
|
|
237
|
-
i0.ɵɵelementStart(10, "span",
|
|
304
|
+
i0.ɵɵelementStart(10, "span", 55);
|
|
238
305
|
i0.ɵɵtext(11);
|
|
239
306
|
i0.ɵɵelementEnd();
|
|
240
|
-
i0.ɵɵelementStart(12, "span",
|
|
307
|
+
i0.ɵɵelementStart(12, "span", 56);
|
|
241
308
|
i0.ɵɵtext(13);
|
|
242
309
|
i0.ɵɵelementEnd()();
|
|
243
|
-
i0.ɵɵelementStart(14, "div",
|
|
310
|
+
i0.ɵɵelementStart(14, "div", 57)(15, "span", 58);
|
|
244
311
|
i0.ɵɵtext(16);
|
|
245
312
|
i0.ɵɵelementEnd();
|
|
246
|
-
i0.ɵɵelementStart(17, "span",
|
|
313
|
+
i0.ɵɵelementStart(17, "span", 59);
|
|
247
314
|
i0.ɵɵtext(18);
|
|
248
315
|
i0.ɵɵelementEnd();
|
|
249
|
-
i0.ɵɵ
|
|
316
|
+
i0.ɵɵconditionalCreate(19, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_19_Template, 2, 1, "span", 60);
|
|
250
317
|
i0.ɵɵelementEnd()();
|
|
251
|
-
i0.ɵɵ
|
|
318
|
+
i0.ɵɵconditionalCreate(20, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_20_Template, 2, 1, "div", 61);
|
|
319
|
+
i0.ɵɵconditionalCreate(21, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Conditional_21_Template, 10, 4, "div", 62);
|
|
252
320
|
i0.ɵɵelementEnd()();
|
|
253
321
|
} if (rf & 2) {
|
|
254
|
-
const
|
|
255
|
-
const ɵ$
|
|
256
|
-
const
|
|
257
|
-
i0.ɵɵclassProp("expanded",
|
|
258
|
-
i0.ɵɵattribute("tabindex", 0)("aria-expanded",
|
|
322
|
+
const change_r7 = ctx.$implicit;
|
|
323
|
+
const ɵ$index_132_r10 = ctx.$index;
|
|
324
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
325
|
+
i0.ɵɵclassProp("expanded", ctx_r1.expandedItems.has(change_r7.ID));
|
|
326
|
+
i0.ɵɵattribute("tabindex", 0)("aria-expanded", ctx_r1.expandedItems.has(change_r7.ID))("aria-label", ctx_r1.getTimelineItemLabel(change_r7));
|
|
259
327
|
i0.ɵɵadvance(2);
|
|
260
|
-
i0.ɵɵclassMap(
|
|
328
|
+
i0.ɵɵclassMap(ctx_r1.getChangeTypeClass(change_r7.Type));
|
|
261
329
|
i0.ɵɵadvance();
|
|
262
|
-
i0.ɵɵclassMap(
|
|
330
|
+
i0.ɵɵclassMap(ctx_r1.getChangeTypeIcon(change_r7.Type));
|
|
263
331
|
i0.ɵɵattribute("aria-hidden", true);
|
|
264
332
|
i0.ɵɵadvance();
|
|
265
|
-
i0.ɵɵconditional(ɵ$
|
|
333
|
+
i0.ɵɵconditional(ɵ$index_132_r10 < ctx_r1.filteredData.length - 1 ? 4 : -1);
|
|
266
334
|
i0.ɵɵadvance(4);
|
|
267
|
-
i0.ɵɵclassMap(
|
|
335
|
+
i0.ɵɵclassMap(ctx_r1.getChangeTypeBadgeClass(change_r7.Type));
|
|
268
336
|
i0.ɵɵadvance();
|
|
269
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
337
|
+
i0.ɵɵtextInterpolate1(" ", change_r7.Type, " ");
|
|
270
338
|
i0.ɵɵadvance(2);
|
|
271
|
-
i0.ɵɵtextInterpolate(
|
|
339
|
+
i0.ɵɵtextInterpolate(change_r7.User || "Unknown User");
|
|
272
340
|
i0.ɵɵadvance();
|
|
273
|
-
i0.ɵɵclassMap(
|
|
341
|
+
i0.ɵɵclassMap(ctx_r1.getSourceClass(change_r7.Source));
|
|
274
342
|
i0.ɵɵadvance();
|
|
275
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
343
|
+
i0.ɵɵtextInterpolate1(" ", change_r7.Source, " ");
|
|
276
344
|
i0.ɵɵadvance(2);
|
|
277
|
-
i0.ɵɵproperty("title",
|
|
345
|
+
i0.ɵɵproperty("title", ctx_r1.formatFullDateTime(change_r7.ChangedAt));
|
|
278
346
|
i0.ɵɵadvance();
|
|
279
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
347
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.formatRelativeTime(change_r7.ChangedAt), " ");
|
|
280
348
|
i0.ɵɵadvance();
|
|
281
|
-
i0.ɵɵclassMap(
|
|
349
|
+
i0.ɵɵclassMap(ctx_r1.getStatusClass(change_r7.Status));
|
|
282
350
|
i0.ɵɵadvance();
|
|
283
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
351
|
+
i0.ɵɵtextInterpolate1(" ", change_r7.Status, " ");
|
|
284
352
|
i0.ɵɵadvance();
|
|
285
|
-
i0.ɵɵconditional(
|
|
353
|
+
i0.ɵɵconditional(change_r7.Integration ? 19 : -1);
|
|
286
354
|
i0.ɵɵadvance();
|
|
287
|
-
i0.ɵɵconditional(!
|
|
355
|
+
i0.ɵɵconditional(!ctx_r1.expandedItems.has(change_r7.ID) ? 20 : -1);
|
|
288
356
|
i0.ɵɵadvance();
|
|
289
|
-
i0.ɵɵconditional(
|
|
357
|
+
i0.ɵɵconditional(ctx_r1.expandedItems.has(change_r7.ID) ? 21 : -1);
|
|
290
358
|
} }
|
|
291
|
-
function
|
|
292
|
-
i0.ɵɵelementStart(0, "div",
|
|
293
|
-
i0.ɵɵrepeaterCreate(1,
|
|
359
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
360
|
+
i0.ɵɵelementStart(0, "div", 42);
|
|
361
|
+
i0.ɵɵrepeaterCreate(1, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_For_2_Template, 22, 26, "div", 46, _forTrack0);
|
|
294
362
|
i0.ɵɵelementEnd();
|
|
295
363
|
} if (rf & 2) {
|
|
296
|
-
const
|
|
364
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
297
365
|
i0.ɵɵadvance();
|
|
298
|
-
i0.ɵɵrepeater(
|
|
366
|
+
i0.ɵɵrepeater(ctx_r1.filteredData);
|
|
299
367
|
} }
|
|
300
|
-
function
|
|
301
|
-
const
|
|
302
|
-
i0.ɵɵelementStart(0, "div",
|
|
303
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
304
|
-
i0.ɵɵlistener("input", function
|
|
305
|
-
i0.ɵɵelementEnd();
|
|
306
|
-
i0.ɵɵelementStart(
|
|
307
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
308
|
-
i0.ɵɵlistener("change", function
|
|
309
|
-
i0.ɵɵelementStart(
|
|
310
|
-
i0.ɵɵtext(
|
|
311
|
-
i0.ɵɵelementEnd();
|
|
312
|
-
i0.ɵɵelementStart(
|
|
313
|
-
i0.ɵɵtext(
|
|
314
|
-
i0.ɵɵelementEnd();
|
|
315
|
-
i0.ɵɵelementStart(
|
|
316
|
-
i0.ɵɵtext(
|
|
317
|
-
i0.ɵɵelementEnd();
|
|
318
|
-
i0.ɵɵelementStart(
|
|
319
|
-
i0.ɵɵtext(
|
|
368
|
+
function RecordChangesComponent_Conditional_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
369
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
370
|
+
i0.ɵɵelementStart(0, "div", 28)(1, "div", 29)(2, "input", 30);
|
|
371
|
+
i0.ɵɵtwoWayListener("ngModelChange", function RecordChangesComponent_Conditional_2_Conditional_15_Template_input_ngModelChange_2_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.searchTerm, $event) || (ctx_r1.searchTerm = $event); return i0.ɵɵresetView($event); });
|
|
372
|
+
i0.ɵɵlistener("input", function RecordChangesComponent_Conditional_2_Conditional_15_Template_input_input_2_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onSearchChange()); });
|
|
373
|
+
i0.ɵɵelementEnd();
|
|
374
|
+
i0.ɵɵelementStart(3, "select", 31);
|
|
375
|
+
i0.ɵɵtwoWayListener("ngModelChange", function RecordChangesComponent_Conditional_2_Conditional_15_Template_select_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.selectedType, $event) || (ctx_r1.selectedType = $event); return i0.ɵɵresetView($event); });
|
|
376
|
+
i0.ɵɵlistener("change", function RecordChangesComponent_Conditional_2_Conditional_15_Template_select_change_3_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onFilterChange()); });
|
|
377
|
+
i0.ɵɵelementStart(4, "option", 32);
|
|
378
|
+
i0.ɵɵtext(5, "All Changes");
|
|
379
|
+
i0.ɵɵelementEnd();
|
|
380
|
+
i0.ɵɵelementStart(6, "option", 33);
|
|
381
|
+
i0.ɵɵtext(7, "Created");
|
|
382
|
+
i0.ɵɵelementEnd();
|
|
383
|
+
i0.ɵɵelementStart(8, "option", 34);
|
|
384
|
+
i0.ɵɵtext(9, "Updated");
|
|
385
|
+
i0.ɵɵelementEnd();
|
|
386
|
+
i0.ɵɵelementStart(10, "option", 35);
|
|
387
|
+
i0.ɵɵtext(11, "Deleted");
|
|
320
388
|
i0.ɵɵelementEnd()();
|
|
321
|
-
i0.ɵɵelementStart(
|
|
322
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
323
|
-
i0.ɵɵlistener("change", function
|
|
324
|
-
i0.ɵɵelementStart(
|
|
325
|
-
i0.ɵɵtext(
|
|
389
|
+
i0.ɵɵelementStart(12, "select", 36);
|
|
390
|
+
i0.ɵɵtwoWayListener("ngModelChange", function RecordChangesComponent_Conditional_2_Conditional_15_Template_select_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.selectedSource, $event) || (ctx_r1.selectedSource = $event); return i0.ɵɵresetView($event); });
|
|
391
|
+
i0.ɵɵlistener("change", function RecordChangesComponent_Conditional_2_Conditional_15_Template_select_change_12_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onFilterChange()); });
|
|
392
|
+
i0.ɵɵelementStart(13, "option", 32);
|
|
393
|
+
i0.ɵɵtext(14, "All Sources");
|
|
326
394
|
i0.ɵɵelementEnd();
|
|
327
|
-
i0.ɵɵelementStart(
|
|
328
|
-
i0.ɵɵtext(
|
|
395
|
+
i0.ɵɵelementStart(15, "option", 37);
|
|
396
|
+
i0.ɵɵtext(16, "Internal");
|
|
329
397
|
i0.ɵɵelementEnd();
|
|
330
|
-
i0.ɵɵelementStart(
|
|
331
|
-
i0.ɵɵtext(
|
|
398
|
+
i0.ɵɵelementStart(17, "option", 38);
|
|
399
|
+
i0.ɵɵtext(18, "External");
|
|
332
400
|
i0.ɵɵelementEnd()()();
|
|
333
|
-
i0.ɵɵ
|
|
401
|
+
i0.ɵɵconditionalCreate(19, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Template, 2, 2, "div", 39);
|
|
402
|
+
i0.ɵɵelementEnd();
|
|
403
|
+
i0.ɵɵelementStart(20, "div", 40);
|
|
404
|
+
i0.ɵɵconditionalCreate(21, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_21_Template, 7, 0, "div", 41)(22, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_Template, 3, 0, "div", 42);
|
|
334
405
|
i0.ɵɵelementEnd();
|
|
335
|
-
i0.ɵɵelementStart(22, "div", 19);
|
|
336
|
-
i0.ɵɵtemplate(23, RecordChangesComponent_Conditional_5_Conditional_23_Template, 3, 1, "div", 20)(24, RecordChangesComponent_Conditional_5_Conditional_24_Template, 3, 0, "div", 21);
|
|
337
|
-
i0.ɵɵelementEnd()();
|
|
338
406
|
} if (rf & 2) {
|
|
339
|
-
const
|
|
340
|
-
i0.ɵɵadvance(
|
|
341
|
-
i0.ɵɵtwoWayProperty("ngModel",
|
|
407
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
408
|
+
i0.ɵɵadvance(2);
|
|
409
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.searchTerm);
|
|
342
410
|
i0.ɵɵadvance();
|
|
343
|
-
i0.ɵɵtwoWayProperty("ngModel",
|
|
411
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.selectedType);
|
|
344
412
|
i0.ɵɵadvance(9);
|
|
345
|
-
i0.ɵɵtwoWayProperty("ngModel",
|
|
413
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.selectedSource);
|
|
346
414
|
i0.ɵɵadvance(7);
|
|
347
|
-
i0.ɵɵconditional(
|
|
415
|
+
i0.ɵɵconditional(ctx_r1.filteredData.length !== ctx_r1.viewData.length ? 19 : -1);
|
|
348
416
|
i0.ɵɵadvance();
|
|
349
|
-
i0.ɵɵattribute("aria-label", "Timeline of changes for " +
|
|
417
|
+
i0.ɵɵattribute("aria-label", "Timeline of changes for " + ctx_r1.record.EntityInfo.Name + " record");
|
|
350
418
|
i0.ɵɵadvance();
|
|
351
|
-
i0.ɵɵconditional(
|
|
419
|
+
i0.ɵɵconditional(ctx_r1.filteredData.length === 0 ? 21 : 22);
|
|
420
|
+
} }
|
|
421
|
+
function RecordChangesComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
422
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
423
|
+
i0.ɵɵelementStart(0, "div", 2)(1, "div", 4)(2, "div", 5)(3, "div", 6);
|
|
424
|
+
i0.ɵɵelement(4, "i", 7);
|
|
425
|
+
i0.ɵɵelementStart(5, "span");
|
|
426
|
+
i0.ɵɵtext(6, "Version Labels");
|
|
427
|
+
i0.ɵɵelementEnd();
|
|
428
|
+
i0.ɵɵconditionalCreate(7, RecordChangesComponent_Conditional_2_Conditional_7_Template, 2, 1, "span", 8);
|
|
429
|
+
i0.ɵɵelementEnd();
|
|
430
|
+
i0.ɵɵelementStart(8, "button", 9);
|
|
431
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OpenCreateWizard()); });
|
|
432
|
+
i0.ɵɵelement(9, "i", 10);
|
|
433
|
+
i0.ɵɵtext(10, " Create Label ");
|
|
434
|
+
i0.ɵɵelementEnd()();
|
|
435
|
+
i0.ɵɵconditionalCreate(11, RecordChangesComponent_Conditional_2_Conditional_11_Template, 3, 0, "div", 11)(12, RecordChangesComponent_Conditional_2_Conditional_12_Template, 2, 0, "div", 12)(13, RecordChangesComponent_Conditional_2_Conditional_13_Template, 3, 0, "div", 13);
|
|
436
|
+
i0.ɵɵelementEnd();
|
|
437
|
+
i0.ɵɵconditionalCreate(14, RecordChangesComponent_Conditional_2_Conditional_14_Template, 11, 0, "div", 14)(15, RecordChangesComponent_Conditional_2_Conditional_15_Template, 23, 6);
|
|
438
|
+
i0.ɵɵelementEnd();
|
|
439
|
+
} if (rf & 2) {
|
|
440
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
441
|
+
i0.ɵɵadvance(7);
|
|
442
|
+
i0.ɵɵconditional(ctx_r1.RecordLabels.length > 0 ? 7 : -1);
|
|
443
|
+
i0.ɵɵadvance(4);
|
|
444
|
+
i0.ɵɵconditional(ctx_r1.IsLoadingLabels ? 11 : ctx_r1.RecordLabels.length === 0 ? 12 : 13);
|
|
445
|
+
i0.ɵɵadvance(3);
|
|
446
|
+
i0.ɵɵconditional(ctx_r1.viewData.length === 0 ? 14 : 15);
|
|
447
|
+
} }
|
|
448
|
+
function RecordChangesComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
449
|
+
const _r11 = i0.ɵɵgetCurrentView();
|
|
450
|
+
i0.ɵɵelementStart(0, "div", 91);
|
|
451
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_3_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnLabelCreateCancelled()); });
|
|
452
|
+
i0.ɵɵelementStart(1, "div", 92);
|
|
453
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_3_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
454
|
+
i0.ɵɵelementStart(2, "mj-label-create", 93);
|
|
455
|
+
i0.ɵɵlistener("Created", function RecordChangesComponent_Conditional_3_Template_mj_label_create_Created_2_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnLabelCreated($event)); })("Cancel", function RecordChangesComponent_Conditional_3_Template_mj_label_create_Cancel_2_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnLabelCreateCancelled()); });
|
|
456
|
+
i0.ɵɵelementEnd()()();
|
|
457
|
+
} if (rf & 2) {
|
|
458
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
459
|
+
i0.ɵɵadvance(2);
|
|
460
|
+
i0.ɵɵproperty("PreselectedEntity", ctx_r1.record.EntityInfo)("PreselectedRecordIds", i0.ɵɵpureFunction1(2, _c0, ctx_r1.record.PrimaryKey.KeyValuePairs[0].Value));
|
|
352
461
|
} }
|
|
353
462
|
export class RecordChangesComponent {
|
|
354
|
-
|
|
463
|
+
cdr;
|
|
355
464
|
mjNotificationService;
|
|
356
465
|
sanitizer;
|
|
357
|
-
|
|
466
|
+
IsLoading = false;
|
|
467
|
+
IsVisible = false;
|
|
358
468
|
dialogClosed = new EventEmitter();
|
|
359
469
|
record;
|
|
360
|
-
wrapper;
|
|
361
470
|
viewData = [];
|
|
362
471
|
filteredData = [];
|
|
363
472
|
expandedItems = new Set();
|
|
473
|
+
// Version label state
|
|
474
|
+
RecordLabels = [];
|
|
475
|
+
IsLoadingLabels = false;
|
|
476
|
+
ShowCreateWizard = false;
|
|
364
477
|
// Filter properties
|
|
365
478
|
searchTerm = '';
|
|
366
479
|
selectedType = '';
|
|
367
480
|
selectedSource = '';
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
field: "ChangedAt",
|
|
371
|
-
dir: "desc",
|
|
372
|
-
},
|
|
373
|
-
];
|
|
374
|
-
constructor(renderer, mjNotificationService, sanitizer) {
|
|
375
|
-
this.renderer = renderer;
|
|
481
|
+
constructor(cdr, mjNotificationService, sanitizer) {
|
|
482
|
+
this.cdr = cdr;
|
|
376
483
|
this.mjNotificationService = mjNotificationService;
|
|
377
484
|
this.sanitizer = sanitizer;
|
|
378
485
|
}
|
|
379
486
|
ngOnInit() {
|
|
380
487
|
if (this.record) {
|
|
381
|
-
this.
|
|
488
|
+
this.IsLoading = true;
|
|
489
|
+
this.IsVisible = true;
|
|
490
|
+
this.cdr.markForCheck();
|
|
382
491
|
this.LoadRecordChanges(this.record.PrimaryKey, '', this.record.EntityInfo.Name);
|
|
492
|
+
this.LoadRecordLabels();
|
|
383
493
|
}
|
|
384
494
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
ngOnDestroy() {
|
|
391
|
-
// Remove the wrapper from the body when the component is destroyed
|
|
392
|
-
if (this.renderer && this.wrapper && this.wrapper.nativeElement)
|
|
393
|
-
this.renderer.removeChild(document.body, this.wrapper.nativeElement);
|
|
495
|
+
OnClose() {
|
|
496
|
+
this.IsVisible = false;
|
|
497
|
+
this.cdr.markForCheck();
|
|
498
|
+
// Allow the slide-out animation to complete before emitting
|
|
499
|
+
setTimeout(() => this.dialogClosed.emit(), 300);
|
|
394
500
|
}
|
|
395
501
|
async LoadRecordChanges(pkey, appName, entityName) {
|
|
396
502
|
if (pkey && entityName) {
|
|
@@ -399,17 +505,15 @@ export class RecordChangesComponent {
|
|
|
399
505
|
if (changes) {
|
|
400
506
|
this.viewData = changes.sort((a, b) => new Date(b.ChangedAt).getTime() - new Date(a.ChangedAt).getTime());
|
|
401
507
|
this.filteredData = [...this.viewData];
|
|
402
|
-
this.
|
|
508
|
+
this.IsLoading = false;
|
|
403
509
|
}
|
|
404
510
|
else {
|
|
405
511
|
this.mjNotificationService.CreateSimpleNotification(`Error loading record changes for ${entityName} with primary key ${pkey.ToString()}.`, 'error');
|
|
406
|
-
this.
|
|
512
|
+
this.IsLoading = false;
|
|
407
513
|
}
|
|
514
|
+
this.cdr.markForCheck();
|
|
408
515
|
}
|
|
409
516
|
}
|
|
410
|
-
closePropertiesDialog() {
|
|
411
|
-
this.dialogClosed.emit();
|
|
412
|
-
}
|
|
413
517
|
// Filter and search methods
|
|
414
518
|
onSearchChange() {
|
|
415
519
|
this.applyFilters();
|
|
@@ -417,24 +521,103 @@ export class RecordChangesComponent {
|
|
|
417
521
|
onFilterChange() {
|
|
418
522
|
this.applyFilters();
|
|
419
523
|
}
|
|
524
|
+
ClearFilters() {
|
|
525
|
+
this.searchTerm = '';
|
|
526
|
+
this.selectedType = '';
|
|
527
|
+
this.selectedSource = '';
|
|
528
|
+
this.applyFilters();
|
|
529
|
+
}
|
|
530
|
+
// Version label methods
|
|
531
|
+
async LoadRecordLabels() {
|
|
532
|
+
if (!this.record)
|
|
533
|
+
return;
|
|
534
|
+
this.IsLoadingLabels = true;
|
|
535
|
+
this.cdr.markForCheck();
|
|
536
|
+
try {
|
|
537
|
+
const entityId = this.record.EntityInfo.ID;
|
|
538
|
+
const recordId = this.record.PrimaryKey.ToConcatenatedString();
|
|
539
|
+
const rv = new RunView();
|
|
540
|
+
// Find all label items that reference this specific record
|
|
541
|
+
const itemsResult = await rv.RunView({
|
|
542
|
+
EntityName: 'MJ: Version Label Items',
|
|
543
|
+
Fields: ['VersionLabelID'],
|
|
544
|
+
ExtraFilter: `EntityID='${entityId}' AND RecordID='${recordId}'`,
|
|
545
|
+
ResultType: 'simple'
|
|
546
|
+
});
|
|
547
|
+
if (!itemsResult.Success || itemsResult.Results.length === 0) {
|
|
548
|
+
this.RecordLabels = [];
|
|
549
|
+
this.IsLoadingLabels = false;
|
|
550
|
+
this.cdr.markForCheck();
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
const labelIds = [...new Set(itemsResult.Results.map(i => i.VersionLabelID))];
|
|
554
|
+
const labelIdFilter = labelIds.map(id => `'${id}'`).join(',');
|
|
555
|
+
const labelsResult = await rv.RunView({
|
|
556
|
+
EntityName: 'MJ: Version Labels',
|
|
557
|
+
Fields: ['ID', 'Name', 'Description', 'Scope', 'Status', 'ItemCount', '__mj_CreatedAt'],
|
|
558
|
+
ExtraFilter: `ID IN (${labelIdFilter})`,
|
|
559
|
+
OrderBy: '__mj_CreatedAt DESC',
|
|
560
|
+
ResultType: 'simple'
|
|
561
|
+
});
|
|
562
|
+
if (labelsResult.Success) {
|
|
563
|
+
this.RecordLabels = labelsResult.Results.map(l => ({
|
|
564
|
+
ID: l.ID,
|
|
565
|
+
Name: l.Name,
|
|
566
|
+
Description: l.Description,
|
|
567
|
+
Scope: l.Scope,
|
|
568
|
+
Status: l.Status,
|
|
569
|
+
CreatedAt: l.__mj_CreatedAt,
|
|
570
|
+
ItemCount: l.ItemCount
|
|
571
|
+
}));
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
catch (error) {
|
|
575
|
+
console.error('Error loading version labels for record:', error);
|
|
576
|
+
this.RecordLabels = [];
|
|
577
|
+
}
|
|
578
|
+
finally {
|
|
579
|
+
this.IsLoadingLabels = false;
|
|
580
|
+
this.cdr.markForCheck();
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
OpenCreateWizard() {
|
|
584
|
+
this.ShowCreateWizard = true;
|
|
585
|
+
this.cdr.markForCheck();
|
|
586
|
+
}
|
|
587
|
+
OnLabelCreated(event) {
|
|
588
|
+
this.ShowCreateWizard = false;
|
|
589
|
+
this.cdr.markForCheck();
|
|
590
|
+
this.LoadRecordLabels();
|
|
591
|
+
this.mjNotificationService.CreateSimpleNotification(`Version label created with ${event.ItemCount} snapshot${event.ItemCount !== 1 ? 's' : ''}`, 'info', 2000);
|
|
592
|
+
}
|
|
593
|
+
OnLabelCreateCancelled() {
|
|
594
|
+
this.ShowCreateWizard = false;
|
|
595
|
+
this.cdr.markForCheck();
|
|
596
|
+
}
|
|
597
|
+
getLabelStatusClass(status) {
|
|
598
|
+
switch (status) {
|
|
599
|
+
case 'Active': return 'label-status-active';
|
|
600
|
+
case 'Archived': return 'label-status-archived';
|
|
601
|
+
case 'Restored': return 'label-status-restored';
|
|
602
|
+
default: return '';
|
|
603
|
+
}
|
|
604
|
+
}
|
|
420
605
|
applyFilters() {
|
|
421
606
|
let filtered = [...this.viewData];
|
|
422
|
-
// Apply search filter
|
|
423
607
|
if (this.searchTerm.trim()) {
|
|
424
608
|
const search = this.searchTerm.toLowerCase();
|
|
425
609
|
filtered = filtered.filter(change => change.ChangesDescription?.toLowerCase().includes(search) ||
|
|
426
610
|
change.User?.toLowerCase().includes(search) ||
|
|
427
611
|
change.Comments?.toLowerCase().includes(search));
|
|
428
612
|
}
|
|
429
|
-
// Apply type filter
|
|
430
613
|
if (this.selectedType) {
|
|
431
614
|
filtered = filtered.filter(change => change.Type === this.selectedType);
|
|
432
615
|
}
|
|
433
|
-
// Apply source filter
|
|
434
616
|
if (this.selectedSource) {
|
|
435
617
|
filtered = filtered.filter(change => change.Source === this.selectedSource);
|
|
436
618
|
}
|
|
437
619
|
this.filteredData = filtered;
|
|
620
|
+
this.cdr.markForCheck();
|
|
438
621
|
}
|
|
439
622
|
// Timeline interaction methods
|
|
440
623
|
toggleExpansion(changeId) {
|
|
@@ -444,6 +627,7 @@ export class RecordChangesComponent {
|
|
|
444
627
|
else {
|
|
445
628
|
this.expandedItems.add(changeId);
|
|
446
629
|
}
|
|
630
|
+
this.cdr.markForCheck();
|
|
447
631
|
}
|
|
448
632
|
onTimelineItemKeydown(event, changeId) {
|
|
449
633
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
@@ -533,7 +717,6 @@ export class RecordChangesComponent {
|
|
|
533
717
|
const fields = Object.keys(changesJson);
|
|
534
718
|
if (fields.length === 0)
|
|
535
719
|
return 'No field changes detected';
|
|
536
|
-
// Get field display names
|
|
537
720
|
const fieldNames = fields.map(fieldKey => {
|
|
538
721
|
const changeInfo = changesJson[fieldKey];
|
|
539
722
|
const field = this.record.EntityInfo.Fields.find((f) => f.Name.trim().toLowerCase() === changeInfo.field?.trim().toLowerCase());
|
|
@@ -549,7 +732,6 @@ export class RecordChangesComponent {
|
|
|
549
732
|
const lastField = fieldNames.pop();
|
|
550
733
|
return `${fieldNames.join(', ')}, and ${lastField} changed`;
|
|
551
734
|
}
|
|
552
|
-
// For more than 4 fields, show first 3 and count
|
|
553
735
|
return `${fieldNames.slice(0, 3).join(', ')}, and ${fieldNames.length - 3} other field${fieldNames.length - 3 > 1 ? 's' : ''} changed`;
|
|
554
736
|
}
|
|
555
737
|
catch {
|
|
@@ -564,21 +746,20 @@ export class RecordChangesComponent {
|
|
|
564
746
|
const changeInfo = changesJson[fieldKey];
|
|
565
747
|
const field = this.record.EntityInfo.Fields.find((f) => f.Name.trim().toLowerCase() === changeInfo.field?.trim().toLowerCase());
|
|
566
748
|
const isBooleanField = field?.TSType === EntityFieldTSType.Boolean;
|
|
749
|
+
const isDateField = field?.TSType === EntityFieldTSType.Date;
|
|
567
750
|
let diffHtml;
|
|
568
|
-
|
|
751
|
+
const formattedOld = this.formatChangeValue(changeInfo.oldValue, isDateField);
|
|
752
|
+
const formattedNew = this.formatChangeValue(changeInfo.newValue, isDateField);
|
|
569
753
|
if (!isBooleanField) {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
// Always show diff if values are different, even if one is empty
|
|
573
|
-
if (oldStr !== newStr) {
|
|
574
|
-
diffHtml = this.generateDiffHtml(oldStr, newStr);
|
|
754
|
+
if (formattedOld !== formattedNew) {
|
|
755
|
+
diffHtml = this.generateDiffHtml(formattedOld, formattedNew);
|
|
575
756
|
}
|
|
576
757
|
}
|
|
577
758
|
return {
|
|
578
759
|
field: changeInfo.field,
|
|
579
760
|
displayName: field?.DisplayNameOrName || changeInfo.field,
|
|
580
|
-
oldValue:
|
|
581
|
-
newValue:
|
|
761
|
+
oldValue: formattedOld,
|
|
762
|
+
newValue: formattedNew,
|
|
582
763
|
isBooleanField,
|
|
583
764
|
diffHtml
|
|
584
765
|
};
|
|
@@ -595,19 +776,41 @@ export class RecordChangesComponent {
|
|
|
595
776
|
const record = JSON.parse(change.FullRecordJSON);
|
|
596
777
|
const fields = this.record.EntityInfo.Fields;
|
|
597
778
|
return fields
|
|
598
|
-
.filter((field) => record[field.Name]
|
|
779
|
+
.filter((field) => record[field.Name] != null && record[field.Name] !== '')
|
|
599
780
|
.map((field) => ({
|
|
600
781
|
name: field.Name,
|
|
601
782
|
displayName: field.DisplayNameOrName,
|
|
602
|
-
value: record[field.Name]
|
|
783
|
+
value: this.formatChangeValue(record[field.Name], field.TSType === EntityFieldTSType.Date)
|
|
603
784
|
}));
|
|
604
785
|
}
|
|
605
786
|
catch {
|
|
606
787
|
return [];
|
|
607
788
|
}
|
|
608
789
|
}
|
|
790
|
+
/**
|
|
791
|
+
* Formats a change value for display. Handles corrupted date values (stored as empty objects)
|
|
792
|
+
* and formats ISO date strings into a human-readable format.
|
|
793
|
+
*/
|
|
794
|
+
formatChangeValue(value, isDateField) {
|
|
795
|
+
if (value == null)
|
|
796
|
+
return '';
|
|
797
|
+
// Handle object values (e.g., Date objects that were incorrectly serialized as {})
|
|
798
|
+
if (typeof value === 'object') {
|
|
799
|
+
const keys = Object.keys(value);
|
|
800
|
+
if (keys.length === 0)
|
|
801
|
+
return ''; // Empty object from corrupted date serialization
|
|
802
|
+
return JSON.stringify(value);
|
|
803
|
+
}
|
|
804
|
+
// Format ISO date strings into a readable format
|
|
805
|
+
if (isDateField && typeof value === 'string') {
|
|
806
|
+
const date = new Date(value);
|
|
807
|
+
if (!isNaN(date.getTime())) {
|
|
808
|
+
return date.toLocaleString();
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
return String(value);
|
|
812
|
+
}
|
|
609
813
|
generateDiffHtml(oldValue, newValue) {
|
|
610
|
-
// Handle empty values
|
|
611
814
|
if (!oldValue && !newValue) {
|
|
612
815
|
return this.sanitizer.bypassSecurityTrustHtml('<div class="diff-container"><span class="diff-unchanged">(no change)</span></div>');
|
|
613
816
|
}
|
|
@@ -617,7 +820,6 @@ export class RecordChangesComponent {
|
|
|
617
820
|
if (!newValue) {
|
|
618
821
|
return this.sanitizer.bypassSecurityTrustHtml(`<div class="diff-container"><span class="diff-removed">${this.escapeHtml(oldValue)}</span></div>`);
|
|
619
822
|
}
|
|
620
|
-
// Decide between character and word diff based on content length and type
|
|
621
823
|
const useWordDiff = this.shouldUseWordDiff(oldValue, newValue);
|
|
622
824
|
const diffs = useWordDiff ? diffWords(oldValue, newValue) : diffChars(oldValue, newValue);
|
|
623
825
|
let html = '<div class="diff-container">';
|
|
@@ -637,8 +839,6 @@ export class RecordChangesComponent {
|
|
|
637
839
|
return this.sanitizer.bypassSecurityTrustHtml(html);
|
|
638
840
|
}
|
|
639
841
|
shouldUseWordDiff(oldValue, newValue) {
|
|
640
|
-
// Use word diff for longer text with spaces (sentences/paragraphs)
|
|
641
|
-
// Use character diff for shorter text, codes, IDs, etc.
|
|
642
842
|
const hasMultipleWords = (text) => text.includes(' ') && text.split(' ').length > 3;
|
|
643
843
|
const isLongText = (text) => text.length > 50;
|
|
644
844
|
return (hasMultipleWords(oldValue) || hasMultipleWords(newValue)) &&
|
|
@@ -649,39 +849,31 @@ export class RecordChangesComponent {
|
|
|
649
849
|
div.textContent = text;
|
|
650
850
|
return div.innerHTML;
|
|
651
851
|
}
|
|
652
|
-
static ɵfac = function RecordChangesComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RecordChangesComponent)(i0.ɵɵdirectiveInject(i0.
|
|
653
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RecordChangesComponent, selectors: [["mj-record-changes"]],
|
|
654
|
-
i0.ɵɵ
|
|
852
|
+
static ɵfac = function RecordChangesComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RecordChangesComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.MJNotificationService), i0.ɵɵdirectiveInject(i2.DomSanitizer)); };
|
|
853
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RecordChangesComponent, selectors: [["mj-record-changes"]], inputs: { record: "record" }, outputs: { dialogClosed: "dialogClosed" }, standalone: false, decls: 4, vars: 9, consts: [[3, "Closed", "Mode", "Title", "Visible", "Resizable", "MinWidthPx", "MaxWidthRatio"], ["text", "Loading history...", "size", "medium"], [1, "record-changes-container"], [1, "create-wizard-overlay"], [1, "labels-section"], [1, "labels-header"], [1, "labels-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-tags"], [1, "labels-count"], ["title", "Create a version label for this record", 1, "create-label-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "labels-loading"], [1, "labels-empty"], [1, "labels-list"], [1, "empty-state"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "label-chip", 3, "title"], [1, "fa-solid", "fa-tag", "label-chip-icon"], [1, "label-chip-name"], [1, "label-chip-meta"], [1, "label-chip-status"], [1, "label-chip-items"], [1, "empty-state-icon"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "empty-state-title"], [1, "empty-state-description"], [1, "empty-state-hint"], [1, "fa-solid", "fa-shield-halved"], [1, "filter-panel"], [1, "filter-controls"], ["type", "text", "placeholder", "Search changes...", "aria-label", "Search record changes", 1, "search-input", 3, "ngModelChange", "input", "ngModel"], ["aria-label", "Filter by change type", 1, "filter-select", 3, "ngModelChange", "change", "ngModel"], ["value", ""], ["value", "Create"], ["value", "Update"], ["value", "Delete"], ["aria-label", "Filter by change source", 1, "filter-select", 3, "ngModelChange", "change", "ngModel"], ["value", "Internal"], ["value", "External"], [1, "filter-results"], [1, "timeline-container"], [1, "no-changes-message"], [1, "timeline"], [1, "fa-solid", "fa-filter"], [1, "clear-filters-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "timeline-item", 3, "expanded"], [1, "timeline-item", 3, "click", "keydown"], [1, "timeline-marker"], [1, "timeline-icon"], [1, "timeline-line"], [1, "timeline-content"], [1, "change-header"], [1, "change-title"], [1, "change-type-badge"], [1, "change-user"], [1, "change-source"], [1, "change-meta"], [1, "change-time", 3, "title"], [1, "change-status"], [1, "change-integration"], [1, "change-summary"], [1, "change-details"], [1, "change-timestamp"], ["aria-hidden", "true", 1, "fa-solid", "fa-clock"], [1, "creation-details"], [1, "deletion-details"], [1, "update-details"], [1, "change-comments"], [1, "change-errors"], [1, "field-changes"], [1, "field-change", "created"], [1, "field-name"], [1, "field-value", "new-value"], [1, "fa-solid", "fa-trash"], [1, "deletion-note"], [1, "fa-solid", "fa-edit"], [1, "field-change"], [1, "boolean-change"], [1, "diff-view"], [1, "value-diff"], [1, "new-value"], [1, "diff-content", 3, "innerHTML"], [1, "old-value"], [1, "value-label"], [1, "value"], [1, "diff-arrow"], ["aria-hidden", "true", 1, "fa-solid", "fa-arrow-right"], [1, "fa-solid", "fa-comment"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "error-log"], [1, "create-wizard-overlay", 3, "click"], [1, "create-wizard-container", 3, "click"], [3, "Created", "Cancel", "PreselectedEntity", "PreselectedRecordIds"]], template: function RecordChangesComponent_Template(rf, ctx) { if (rf & 1) {
|
|
854
|
+
i0.ɵɵelementStart(0, "mj-slide-panel", 0);
|
|
855
|
+
i0.ɵɵlistener("Closed", function RecordChangesComponent_Template_mj_slide_panel_Closed_0_listener() { return ctx.OnClose(); });
|
|
856
|
+
i0.ɵɵconditionalCreate(1, RecordChangesComponent_Conditional_1_Template, 1, 0, "mj-loading", 1);
|
|
857
|
+
i0.ɵɵconditionalCreate(2, RecordChangesComponent_Conditional_2_Template, 16, 3, "div", 2);
|
|
858
|
+
i0.ɵɵconditionalCreate(3, RecordChangesComponent_Conditional_3_Template, 3, 4, "div", 3);
|
|
859
|
+
i0.ɵɵelementEnd();
|
|
655
860
|
} if (rf & 2) {
|
|
656
|
-
|
|
657
|
-
i0.ɵɵ
|
|
658
|
-
|
|
659
|
-
const _r1 = i0.ɵɵgetCurrentView();
|
|
660
|
-
i0.ɵɵelementStart(0, "div", null, 0);
|
|
661
|
-
i0.ɵɵelement(2, "div", 2);
|
|
662
|
-
i0.ɵɵelementStart(3, "kendo-window", 3);
|
|
663
|
-
i0.ɵɵlistener("close", function RecordChangesComponent_Template_kendo_window_close_3_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.closePropertiesDialog()); });
|
|
664
|
-
i0.ɵɵtemplate(4, RecordChangesComponent_mj_loading_4_Template, 1, 0, "mj-loading", 4)(5, RecordChangesComponent_Conditional_5_Template, 25, 6, "div", 5);
|
|
665
|
-
i0.ɵɵelementEnd()();
|
|
666
|
-
} if (rf & 2) {
|
|
667
|
-
i0.ɵɵadvance(3);
|
|
668
|
-
i0.ɵɵproperty("width", 800)("height", 650)("minHeight", 400)("minWidth", 600)("resizable", true)("top", 50)("left", 50);
|
|
861
|
+
i0.ɵɵproperty("Mode", "slide")("Title", "Record Changes History")("Visible", ctx.IsVisible)("Resizable", true)("MinWidthPx", 400)("MaxWidthRatio", 0.6);
|
|
862
|
+
i0.ɵɵadvance();
|
|
863
|
+
i0.ɵɵconditional(ctx.IsLoading ? 1 : -1);
|
|
669
864
|
i0.ɵɵadvance();
|
|
670
|
-
i0.ɵɵ
|
|
865
|
+
i0.ɵɵconditional(!ctx.IsLoading ? 2 : -1);
|
|
671
866
|
i0.ɵɵadvance();
|
|
672
|
-
i0.ɵɵconditional(
|
|
673
|
-
} }, dependencies: [i3.NgIf, i4.NgSelectOption, i4.ɵNgSelectMultipleOption, i4.DefaultValueAccessor, i4.SelectControlValueAccessor, i4.NgControlStatus, i4.NgModel, i5.WindowComponent, i6.LoadingComponent], styles: ["/* Record Changes Timeline Styles */\n.record-changes-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 1rem;\n}\n\n/* Filter Panel */\n.filter-panel {\n background: #f8f9fa;\n border-radius: 8px;\n padding: 1rem;\n margin-bottom: 1rem;\n border: 1px solid #e9ecef;\n}\n\n.filter-controls {\n display: flex;\n gap: 1rem;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.search-input {\n flex: 1;\n min-width: 200px;\n padding: 0.5rem 1rem;\n border: 1px solid #ced4da;\n border-radius: 4px;\n font-size: 0.9rem;\n}\n\n.search-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.filter-select {\n padding: 0.5rem;\n border: 1px solid #ced4da;\n border-radius: 4px;\n background: white;\n font-size: 0.9rem;\n min-width: 120px;\n}\n\n.filter-select:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.filter-results {\n margin-top: 0.5rem;\n font-size: 0.85rem;\n color: #6c757d;\n font-style: italic;\n}\n\n/* Timeline Container */\n.timeline-container {\n flex: 1;\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n\n.no-changes-message {\n text-align: center;\n padding: 3rem 1rem;\n color: #6c757d;\n font-size: 1.1rem;\n}\n\n.no-changes-message i {\n display: block;\n font-size: 2rem;\n margin-bottom: 1rem;\n color: #adb5bd;\n}\n\n/* Timeline */\n.timeline {\n position: relative;\n padding-left: 2rem;\n}\n\n.timeline-item {\n position: relative;\n margin-bottom: 1.5rem;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.timeline-item:hover {\n transform: translateX(2px);\n}\n\n.timeline-item:focus {\n outline: 2px solid #007bff;\n outline-offset: 2px;\n border-radius: 4px;\n}\n\n.timeline-item.expanded {\n margin-bottom: 2rem;\n}\n\n/* Timeline Marker */\n.timeline-marker {\n position: absolute;\n left: -2rem;\n top: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.timeline-icon {\n width: 2.5rem;\n height: 2.5rem;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.9rem;\n color: white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n z-index: 2;\n}\n\n.timeline-icon.change-create {\n background: linear-gradient(135deg, #28a745, #20c997);\n}\n\n.timeline-icon.change-update {\n background: linear-gradient(135deg, #007bff, #6f42c1);\n}\n\n.timeline-icon.change-delete {\n background: linear-gradient(135deg, #dc3545, #fd7e14);\n}\n\n.timeline-icon.change-unknown {\n background: linear-gradient(135deg, #6c757d, #adb5bd);\n}\n\n.timeline-line {\n width: 2px;\n height: 2rem;\n background: #e9ecef;\n margin-top: 0.5rem;\n}\n\n/* Timeline Content */\n.timeline-content {\n background: white;\n border: 1px solid #e9ecef;\n border-radius: 8px;\n padding: 1rem;\n box-shadow: 0 2px 4px rgba(0,0,0,0.05);\n transition: box-shadow 0.2s ease;\n}\n\n.timeline-item:hover .timeline-content {\n box-shadow: 0 4px 8px rgba(0,0,0,0.1);\n}\n\n.timeline-item.expanded .timeline-content {\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n}\n\n/* Change Header */\n.change-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.75rem;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.change-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.change-type-badge {\n font-size: 0.75rem;\n font-weight: 600;\n padding: 0.25rem 0.5rem;\n border-radius: 12px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.badge-create {\n background: #d4edda;\n color: #155724;\n}\n\n.badge-update {\n background: #cce7ff;\n color: #004085;\n}\n\n.badge-delete {\n background: #f8d7da;\n color: #721c24;\n}\n\n.badge-unknown {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.change-user {\n font-weight: 600;\n color: #495057;\n}\n\n.change-source {\n font-size: 0.8rem;\n padding: 0.2rem 0.4rem;\n border-radius: 8px;\n font-weight: 500;\n}\n\n.source-internal {\n background: #e7f3ff;\n color: #0056b3;\n}\n\n.source-external {\n background: #fff3cd;\n color: #856404;\n}\n\n.change-meta {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 0.85rem;\n color: #6c757d;\n flex-wrap: wrap;\n}\n\n.change-time {\n font-weight: 500;\n}\n\n.change-status {\n padding: 0.2rem 0.4rem;\n border-radius: 8px;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-complete {\n background: #d4edda;\n color: #155724;\n}\n\n.status-pending {\n background: #fff3cd;\n color: #856404;\n}\n\n.status-error {\n background: #f8d7da;\n color: #721c24;\n}\n\n.status-unknown {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.change-integration {\n font-style: italic;\n color: #495057;\n}\n\n/* Change Summary */\n.change-summary {\n color: #6c757d;\n font-size: 0.9rem;\n line-height: 1.4;\n}\n\n/* Change Details */\n.change-details {\n margin-top: 1rem;\n padding-top: 1rem;\n border-top: 1px solid #e9ecef;\n}\n\n.change-timestamp {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 1rem;\n padding: 0.5rem;\n background: #f8f9fa;\n border-radius: 6px;\n border-left: 4px solid #6c757d;\n font-size: 0.9rem;\n color: #495057;\n}\n\n.change-timestamp i {\n color: #6c757d;\n}\n\n.change-details h4 {\n font-size: 1rem;\n margin-bottom: 1rem;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.change-details h5 {\n font-size: 0.9rem;\n margin-bottom: 0.5rem;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n/* Field Changes */\n.field-changes {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.field-change {\n background: #f8f9fa;\n border-radius: 6px;\n padding: 0.75rem;\n border-left: 4px solid #007bff;\n}\n\n.field-change.created {\n border-left-color: #28a745;\n}\n\n.field-name {\n font-weight: 600;\n color: #495057;\n margin-bottom: 0.5rem;\n display: block;\n}\n\n.field-value {\n font-family: 'Courier New', monospace;\n font-size: 0.85rem;\n padding: 0.25rem 0.5rem;\n border-radius: 4px;\n background: white;\n border: 1px solid #dee2e6;\n}\n\n.value-diff {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 1rem;\n align-items: center;\n}\n\n.old-value, .new-value {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.value-label {\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: #6c757d;\n}\n\n.old-value .value {\n color: #6c757d;\n background: #f8f9fa;\n text-decoration: line-through;\n}\n\n.new-value .value {\n color: #155724;\n background: #d4edda;\n font-weight: 500;\n}\n\n.value {\n font-family: 'Courier New', monospace;\n font-size: 0.85rem;\n padding: 0.25rem 0.5rem;\n border-radius: 4px;\n border: 1px solid #dee2e6;\n word-break: break-all;\n}\n\n.diff-arrow {\n color: #007bff;\n font-size: 1.2rem;\n}\n\n.boolean-change .new-value {\n font-weight: 600;\n color: #007bff;\n font-size: 0.9rem;\n}\n\n/* Creation Details */\n.creation-details .field-change {\n border-left-color: #28a745;\n}\n\n.creation-details .field-value {\n color: #155724;\n background: #d4edda;\n font-weight: 500;\n}\n\n/* Deletion Details */\n.deletion-details {\n text-align: center;\n padding: 1rem;\n}\n\n.deletion-note {\n color: #6c757d;\n font-style: italic;\n margin-bottom: 0;\n}\n\n/* Diff View Styles - Scoped to this component */\nmj-record-changes .diff-view,\n.record-changes-container .diff-view {\n margin-top: 0.5rem !important;\n border: 1px dashed #28a745;\n border-radius: 4px;\n padding: 0.25rem;\n}\n\nmj-record-changes .diff-content,\n.record-changes-container .diff-content {\n background: #ffffff !important;\n border: 2px solid #007bff !important;\n border-radius: 6px;\n padding: 0.75rem !important;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace !important;\n font-size: 0.85rem !important;\n line-height: 1.45 !important;\n overflow-x: auto;\n min-height: 2rem;\n}\n\nmj-record-changes .diff-container,\n.record-changes-container .diff-container {\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\nmj-record-changes .diff-added,\n.record-changes-container .diff-added {\n background-color: #d1f5d3 !important;\n color: #22863a !important;\n text-decoration: none !important;\n border-radius: 3px;\n padding: 2px 4px !important;\n font-weight: 600 !important;\n display: inline;\n border: 1px solid #28a745;\n}\n\nmj-record-changes .diff-removed,\n.record-changes-container .diff-removed {\n background-color: #ffeef0 !important;\n color: #d73a49 !important;\n text-decoration: line-through !important;\n border-radius: 3px;\n padding: 2px 4px !important;\n font-weight: 600 !important;\n display: inline;\n border: 1px solid #dc3545;\n}\n\nmj-record-changes .diff-unchanged,\n.record-changes-container .diff-unchanged {\n color: #24292e !important;\n display: inline;\n}\n\n/* Enhanced diff styling for better readability */\nmj-record-changes .diff-added:not(:empty)::before,\n.record-changes-container .diff-added:not(:empty)::before {\n content: '';\n background: #28a745;\n width: 3px;\n height: 100%;\n position: absolute;\n left: -1px;\n border-radius: 1px;\n}\n\nmj-record-changes .diff-removed:not(:empty)::before,\n.record-changes-container .diff-removed:not(:empty)::before {\n content: '';\n background: #dc3545;\n width: 3px;\n height: 100%;\n position: absolute;\n left: -1px;\n border-radius: 1px;\n}\n\nmj-record-changes .diff-added, \nmj-record-changes .diff-removed,\n.record-changes-container .diff-added, \n.record-changes-container .diff-removed {\n position: relative;\n margin: 0 1px;\n display: inline;\n}\n\n/* Hover effects for diff elements */\nmj-record-changes .diff-added:hover,\n.record-changes-container .diff-added:hover {\n background-color: #c3f0c5 !important;\n box-shadow: 0 0 0 2px rgba(40, 167, 69, 0.15);\n}\n\nmj-record-changes .diff-removed:hover,\n.record-changes-container .diff-removed:hover {\n background-color: #ffd6dd !important;\n box-shadow: 0 0 0 2px rgba(220, 53, 69, 0.15);\n}\n\n/* Multi-line diff styling */\nmj-record-changes .diff-content .diff-added,\nmj-record-changes .diff-content .diff-removed,\n.record-changes-container .diff-content .diff-added,\n.record-changes-container .diff-content .diff-removed {\n padding: 1px 3px;\n border-radius: 3px;\n}\n\nmj-record-changes .diff-content .diff-added + .diff-added,\nmj-record-changes .diff-content .diff-removed + .diff-removed,\n.record-changes-container .diff-content .diff-added + .diff-added,\n.record-changes-container .diff-content .diff-removed + .diff-removed {\n margin-left: 0;\n}\n\n/* Word diff specific styling */\nmj-record-changes .diff-container.word-diff .diff-added,\nmj-record-changes .diff-container.word-diff .diff-removed,\n.record-changes-container .diff-container.word-diff .diff-added,\n.record-changes-container .diff-container.word-diff .diff-removed {\n padding: 2px 4px;\n margin: 0 1px;\n border-radius: 4px;\n}\n\n/* Comments and Errors */\n.change-comments, .change-errors {\n margin-top: 1rem;\n padding: 0.75rem;\n border-radius: 6px;\n}\n\n.change-comments {\n background: #e7f3ff;\n border-left: 4px solid #007bff;\n}\n\n.change-errors {\n background: #f8d7da;\n border-left: 4px solid #dc3545;\n}\n\n.error-log {\n background: #ffffff;\n padding: 0.5rem;\n border-radius: 4px;\n font-family: 'Courier New', monospace;\n font-size: 0.8rem;\n color: #721c24;\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .filter-controls {\n flex-direction: column;\n align-items: stretch;\n }\n \n .search-input, .filter-select {\n width: 100%;\n }\n \n .change-header {\n flex-direction: column;\n align-items: flex-start;\n }\n \n .change-meta {\n flex-direction: column;\n align-items: flex-start;\n gap: 0.25rem;\n }\n \n .value-diff {\n grid-template-columns: 1fr;\n gap: 0.5rem;\n }\n \n .diff-arrow {\n justify-self: center;\n transform: rotate(90deg);\n }\n \n .timeline {\n padding-left: 1.5rem;\n }\n \n .timeline-marker {\n left: -1.5rem;\n }\n \n .timeline-icon {\n width: 2rem;\n height: 2rem;\n font-size: 0.8rem;\n }\n \n /* Responsive diff view */\n .diff-content {\n font-size: 0.8rem;\n padding: 0.5rem;\n }\n \n .diff-added, .diff-removed {\n padding: 1px 2px;\n }\n}\n\n@media (max-width: 480px) {\n .record-changes-container {\n padding: 0.5rem;\n }\n \n .timeline-content {\n padding: 0.75rem;\n }\n \n .field-change {\n padding: 0.5rem;\n }\n}"], encapsulation: 2 });
|
|
867
|
+
i0.ɵɵconditional(ctx.ShowCreateWizard ? 3 : -1);
|
|
868
|
+
} }, dependencies: [i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.DefaultValueAccessor, i3.SelectControlValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent, i5.MjSlidePanelComponent, i5.MjLabelCreateComponent], styles: ["/* Record Changes Timeline Styles */\n.record-changes-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 1rem;\n}\n\n/* Version Labels Section */\n.labels-section {\n background: #f8f9fa;\n border-radius: 8px;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n border: 1px solid #e9ecef;\n}\n\n.labels-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.5rem;\n}\n\n.labels-title {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-weight: 600;\n font-size: 0.9rem;\n color: #495057;\n}\n\n.labels-title i {\n color: #6f42c1;\n}\n\n.labels-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n height: 1.25rem;\n padding: 0 0.35rem;\n border-radius: 10px;\n background: #6f42c1;\n color: white;\n font-size: 0.7rem;\n font-weight: 700;\n}\n\n.create-label-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.35rem 0.75rem;\n border: 1px solid #6f42c1;\n border-radius: 6px;\n background: white;\n color: #6f42c1;\n font-size: 0.8rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.create-label-btn:hover {\n background: #6f42c1;\n color: white;\n}\n\n.labels-loading {\n font-size: 0.8rem;\n color: #6c757d;\n padding: 0.25rem 0;\n}\n\n.labels-loading i {\n margin-right: 0.25rem;\n}\n\n.labels-empty {\n font-size: 0.8rem;\n color: #94a3b8;\n font-style: italic;\n padding: 0.25rem 0;\n}\n\n.labels-list {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.label-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.3rem 0.6rem;\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 16px;\n font-size: 0.8rem;\n color: #495057;\n transition: all 0.15s ease;\n cursor: default;\n}\n\n.label-chip:hover {\n border-color: #6f42c1;\n box-shadow: 0 1px 3px rgba(111, 66, 193, 0.15);\n}\n\n.label-chip-icon {\n color: #6f42c1;\n font-size: 0.7rem;\n}\n\n.label-chip-name {\n font-weight: 600;\n max-width: 180px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.label-chip-meta {\n display: flex;\n align-items: center;\n gap: 0.3rem;\n font-size: 0.7rem;\n color: #6c757d;\n}\n\n.label-chip-status {\n padding: 0.1rem 0.3rem;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 0.6rem;\n letter-spacing: 0.03em;\n}\n\n.label-status-active {\n background: #d4edda;\n color: #155724;\n}\n\n.label-status-archived {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.label-status-restored {\n background: #cce7ff;\n color: #004085;\n}\n\n.label-chip-items {\n white-space: nowrap;\n}\n\n/* Create Wizard Overlay */\n.create-wizard-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: fadeIn 0.15s ease;\n}\n\n.create-wizard-container {\n background: white;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n width: 90%;\n max-width: 600px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 1.5rem;\n animation: slideUp 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes slideUp {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Filter Panel */\n.filter-panel {\n background: #f8f9fa;\n border-radius: 8px;\n padding: 1rem;\n margin-bottom: 1rem;\n border: 1px solid #e9ecef;\n}\n\n.filter-controls {\n display: flex;\n gap: 1rem;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.search-input {\n flex: 1;\n min-width: 200px;\n padding: 0.5rem 1rem;\n border: 1px solid #ced4da;\n border-radius: 4px;\n font-size: 0.9rem;\n}\n\n.search-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.filter-select {\n padding: 0.5rem;\n border: 1px solid #ced4da;\n border-radius: 4px;\n background: white;\n font-size: 0.9rem;\n min-width: 120px;\n}\n\n.filter-select:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.filter-results {\n margin-top: 0.5rem;\n font-size: 0.85rem;\n color: #6c757d;\n font-style: italic;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n text-align: center;\n min-height: 400px;\n}\n\n.empty-state-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: linear-gradient(135deg, #e8edf2, #f0f4f8);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 1.5rem;\n}\n\n.empty-state-icon i {\n font-size: 2rem;\n color: #94a3b8;\n}\n\n.empty-state-title {\n font-size: 1.25rem;\n font-weight: 600;\n color: #334155;\n margin: 0 0 0.75rem 0;\n}\n\n.empty-state-description {\n font-size: 0.95rem;\n color: #64748b;\n line-height: 1.6;\n max-width: 320px;\n margin: 0 0 1.5rem 0;\n}\n\n.empty-state-hint {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n background: #f1f5f9;\n border-radius: 20px;\n font-size: 0.8rem;\n color: #64748b;\n}\n\n.empty-state-hint i {\n color: #94a3b8;\n}\n\n/* No filtered results */\n.no-changes-message {\n text-align: center;\n padding: 3rem 1rem;\n color: #6c757d;\n}\n\n.no-changes-message i {\n display: block;\n font-size: 2rem;\n margin-bottom: 1rem;\n color: #adb5bd;\n}\n\n.no-changes-message p {\n font-size: 1rem;\n margin: 0 0 1rem 0;\n}\n\n.clear-filters-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 1rem;\n border: 1px solid #ced4da;\n border-radius: 6px;\n background: white;\n color: #495057;\n font-size: 0.85rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-filters-btn:hover {\n background: #f8f9fa;\n border-color: #adb5bd;\n}\n\n/* Timeline Container */\n.timeline-container {\n flex: 1;\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n\n/* Timeline */\n.timeline {\n position: relative;\n padding-left: 2rem;\n}\n\n.timeline-item {\n position: relative;\n margin-bottom: 1.5rem;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.timeline-item:hover {\n transform: translateX(2px);\n}\n\n.timeline-item:focus {\n outline: 2px solid #007bff;\n outline-offset: 2px;\n border-radius: 4px;\n}\n\n.timeline-item.expanded {\n margin-bottom: 2rem;\n}\n\n/* Timeline Marker */\n.timeline-marker {\n position: absolute;\n left: -2rem;\n top: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.timeline-icon {\n width: 2.5rem;\n height: 2.5rem;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.9rem;\n color: white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n z-index: 2;\n}\n\n.timeline-icon.change-create {\n background: linear-gradient(135deg, #28a745, #20c997);\n}\n\n.timeline-icon.change-update {\n background: linear-gradient(135deg, #007bff, #6f42c1);\n}\n\n.timeline-icon.change-delete {\n background: linear-gradient(135deg, #dc3545, #fd7e14);\n}\n\n.timeline-icon.change-unknown {\n background: linear-gradient(135deg, #6c757d, #adb5bd);\n}\n\n.timeline-line {\n width: 2px;\n height: 2rem;\n background: #e9ecef;\n margin-top: 0.5rem;\n}\n\n/* Timeline Content */\n.timeline-content {\n background: white;\n border: 1px solid #e9ecef;\n border-radius: 8px;\n padding: 1rem;\n box-shadow: 0 2px 4px rgba(0,0,0,0.05);\n transition: box-shadow 0.2s ease;\n}\n\n.timeline-item:hover .timeline-content {\n box-shadow: 0 4px 8px rgba(0,0,0,0.1);\n}\n\n.timeline-item.expanded .timeline-content {\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n}\n\n/* Change Header */\n.change-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.75rem;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.change-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.change-type-badge {\n font-size: 0.75rem;\n font-weight: 600;\n padding: 0.25rem 0.5rem;\n border-radius: 12px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.badge-create {\n background: #d4edda;\n color: #155724;\n}\n\n.badge-update {\n background: #cce7ff;\n color: #004085;\n}\n\n.badge-delete {\n background: #f8d7da;\n color: #721c24;\n}\n\n.badge-unknown {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.change-user {\n font-weight: 600;\n color: #495057;\n}\n\n.change-source {\n font-size: 0.8rem;\n padding: 0.2rem 0.4rem;\n border-radius: 8px;\n font-weight: 500;\n}\n\n.source-internal {\n background: #e7f3ff;\n color: #0056b3;\n}\n\n.source-external {\n background: #fff3cd;\n color: #856404;\n}\n\n.change-meta {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 0.85rem;\n color: #6c757d;\n flex-wrap: wrap;\n}\n\n.change-time {\n font-weight: 500;\n}\n\n.change-status {\n padding: 0.2rem 0.4rem;\n border-radius: 8px;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-complete {\n background: #d4edda;\n color: #155724;\n}\n\n.status-pending {\n background: #fff3cd;\n color: #856404;\n}\n\n.status-error {\n background: #f8d7da;\n color: #721c24;\n}\n\n.status-unknown {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.change-integration {\n font-style: italic;\n color: #495057;\n}\n\n/* Change Summary */\n.change-summary {\n color: #6c757d;\n font-size: 0.9rem;\n line-height: 1.4;\n}\n\n/* Change Details */\n.change-details {\n margin-top: 1rem;\n padding-top: 1rem;\n border-top: 1px solid #e9ecef;\n}\n\n.change-timestamp {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 1rem;\n padding: 0.5rem;\n background: #f8f9fa;\n border-radius: 6px;\n border-left: 4px solid #6c757d;\n font-size: 0.9rem;\n color: #495057;\n}\n\n.change-timestamp i {\n color: #6c757d;\n}\n\n.change-details h4 {\n font-size: 1rem;\n margin-bottom: 1rem;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.change-details h5 {\n font-size: 0.9rem;\n margin-bottom: 0.5rem;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n/* Field Changes */\n.field-changes {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.field-change {\n background: #f8f9fa;\n border-radius: 6px;\n padding: 0.75rem;\n border-left: 4px solid #007bff;\n}\n\n.field-change.created {\n border-left-color: #28a745;\n}\n\n.field-name {\n font-weight: 600;\n color: #495057;\n margin-bottom: 0.5rem;\n display: block;\n}\n\n.field-value {\n font-family: 'Courier New', monospace;\n font-size: 0.85rem;\n padding: 0.25rem 0.5rem;\n border-radius: 4px;\n background: white;\n border: 1px solid #dee2e6;\n}\n\n.value-diff {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 1rem;\n align-items: center;\n}\n\n.old-value, .new-value {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.value-label {\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: #6c757d;\n}\n\n.old-value .value {\n color: #6c757d;\n background: #f8f9fa;\n text-decoration: line-through;\n}\n\n.new-value .value {\n color: #155724;\n background: #d4edda;\n font-weight: 500;\n}\n\n.value {\n font-family: 'Courier New', monospace;\n font-size: 0.85rem;\n padding: 0.25rem 0.5rem;\n border-radius: 4px;\n border: 1px solid #dee2e6;\n word-break: break-all;\n}\n\n.diff-arrow {\n color: #007bff;\n font-size: 1.2rem;\n}\n\n.boolean-change .new-value {\n font-weight: 600;\n color: #007bff;\n font-size: 0.9rem;\n}\n\n/* Creation Details */\n.creation-details .field-change {\n border-left-color: #28a745;\n}\n\n.creation-details .field-value {\n color: #155724;\n background: #d4edda;\n font-weight: 500;\n}\n\n/* Deletion Details */\n.deletion-details {\n text-align: center;\n padding: 1rem;\n}\n\n.deletion-note {\n color: #6c757d;\n font-style: italic;\n margin-bottom: 0;\n}\n\n/* Diff View Styles */\n.diff-view {\n margin-top: 0.5rem;\n border: 1px dashed #28a745;\n border-radius: 4px;\n padding: 0.25rem;\n}\n\n.diff-content {\n background: #ffffff;\n border: 2px solid #007bff;\n border-radius: 6px;\n padding: 0.75rem;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n font-size: 0.85rem;\n line-height: 1.45;\n overflow-x: auto;\n min-height: 2rem;\n}\n\n.diff-container {\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.diff-added {\n background-color: #d1f5d3;\n color: #22863a;\n text-decoration: none;\n border-radius: 3px;\n padding: 2px 4px;\n font-weight: 600;\n display: inline;\n border: 1px solid #28a745;\n position: relative;\n margin: 0 1px;\n}\n\n.diff-removed {\n background-color: #ffeef0;\n color: #d73a49;\n text-decoration: line-through;\n border-radius: 3px;\n padding: 2px 4px;\n font-weight: 600;\n display: inline;\n border: 1px solid #dc3545;\n position: relative;\n margin: 0 1px;\n}\n\n.diff-unchanged {\n color: #24292e;\n display: inline;\n}\n\n/* Hover effects for diff elements */\n.diff-added:hover {\n background-color: #c3f0c5;\n box-shadow: 0 0 0 2px rgba(40, 167, 69, 0.15);\n}\n\n.diff-removed:hover {\n background-color: #ffd6dd;\n box-shadow: 0 0 0 2px rgba(220, 53, 69, 0.15);\n}\n\n/* Comments and Errors */\n.change-comments, .change-errors {\n margin-top: 1rem;\n padding: 0.75rem;\n border-radius: 6px;\n}\n\n.change-comments {\n background: #e7f3ff;\n border-left: 4px solid #007bff;\n}\n\n.change-errors {\n background: #f8d7da;\n border-left: 4px solid #dc3545;\n}\n\n.error-log {\n background: #ffffff;\n padding: 0.5rem;\n border-radius: 4px;\n font-family: 'Courier New', monospace;\n font-size: 0.8rem;\n color: #721c24;\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .filter-controls {\n flex-direction: column;\n align-items: stretch;\n }\n\n .search-input, .filter-select {\n width: 100%;\n }\n\n .change-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .change-meta {\n flex-direction: column;\n align-items: flex-start;\n gap: 0.25rem;\n }\n\n .value-diff {\n grid-template-columns: 1fr;\n gap: 0.5rem;\n }\n\n .diff-arrow {\n justify-self: center;\n transform: rotate(90deg);\n }\n\n .timeline {\n padding-left: 1.5rem;\n }\n\n .timeline-marker {\n left: -1.5rem;\n }\n\n .timeline-icon {\n width: 2rem;\n height: 2rem;\n font-size: 0.8rem;\n }\n\n .diff-content {\n font-size: 0.8rem;\n padding: 0.5rem;\n }\n\n .diff-added, .diff-removed {\n padding: 1px 2px;\n }\n}\n\n@media (max-width: 480px) {\n .record-changes-container {\n padding: 0.5rem;\n }\n\n .timeline-content {\n padding: 0.75rem;\n }\n\n .field-change {\n padding: 0.5rem;\n }\n}\n"], encapsulation: 2, changeDetection: 0 });
|
|
674
869
|
}
|
|
675
870
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RecordChangesComponent, [{
|
|
676
871
|
type: Component,
|
|
677
|
-
args: [{ selector: 'mj-record-changes', encapsulation: ViewEncapsulation.None, template: "<div #recordChangesWrapper>\n <div class=\"k-overlay\"></div>\n <kendo-window \n class=\"kendo-window-custom\"\n [width]=\"800\"\n [height]=\"650\"\n [minHeight]=\"400\"\n [minWidth]=\"600\"\n [resizable]=\"true\"\n [top]=\"50\"\n [left]=\"50\"\n title=\"Record Changes History\"\n (close)=\"closePropertiesDialog()\"\n >\n <mj-loading *ngIf=\"showloader\" text=\"Loading history...\" size=\"medium\"></mj-loading>\n @if (!showloader) {\n <div class=\"record-changes-container\" #dialogContainer>\n <!-- Filter Panel -->\n <div class=\"filter-panel\">\n <div class=\"filter-controls\">\n <input \n type=\"text\" \n class=\"search-input\"\n placeholder=\"Search changes...\"\n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchChange()\"\n aria-label=\"Search record changes\"\n />\n <select \n class=\"filter-select\"\n [(ngModel)]=\"selectedType\"\n (change)=\"onFilterChange()\"\n aria-label=\"Filter by change type\"\n >\n <option value=\"\">All Changes</option>\n <option value=\"Create\">Created</option>\n <option value=\"Update\">Updated</option>\n <option value=\"Delete\">Deleted</option>\n </select>\n <select \n class=\"filter-select\"\n [(ngModel)]=\"selectedSource\"\n (change)=\"onFilterChange()\"\n aria-label=\"Filter by change source\"\n >\n <option value=\"\">All Sources</option>\n <option value=\"Internal\">Internal</option>\n <option value=\"External\">External</option>\n </select>\n </div>\n @if (filteredData.length !== viewData.length) {\n <div class=\"filter-results\">\n Showing {{ filteredData.length }} of {{ viewData.length }} changes\n </div>\n }\n </div>\n\n <!-- Timeline Container -->\n <div class=\"timeline-container\" [attr.aria-label]=\"'Timeline of changes for ' + record.EntityInfo.Name + ' record'\">\n @if (filteredData.length === 0) {\n <div class=\"no-changes-message\">\n @if (viewData.length === 0) {\n <i class=\"fa-solid fa-info-circle\"></i>\n No changes found for this record.\n } @else {\n <i class=\"fa-solid fa-search\"></i>\n No changes match your current filters.\n }\n </div>\n } @else {\n <div class=\"timeline\">\n @for (change of filteredData; track change.ID; let i = $index) {\n <div \n class=\"timeline-item\"\n [class.expanded]=\"expandedItems.has(change.ID)\"\n [attr.tabindex]=\"0\"\n [attr.aria-expanded]=\"expandedItems.has(change.ID)\"\n [attr.aria-label]=\"getTimelineItemLabel(change)\"\n (click)=\"toggleExpansion(change.ID)\"\n (keydown)=\"onTimelineItemKeydown($event, change.ID)\"\n >\n <div class=\"timeline-marker\">\n <div class=\"timeline-icon\" [class]=\"getChangeTypeClass(change.Type)\">\n <i [class]=\"getChangeTypeIcon(change.Type)\" [attr.aria-hidden]=\"true\"></i>\n </div>\n @if (i < filteredData.length - 1) {\n <div class=\"timeline-line\"></div>\n }\n </div>\n \n <div class=\"timeline-content\">\n <div class=\"change-header\">\n <div class=\"change-title\">\n <span class=\"change-type-badge\" [class]=\"getChangeTypeBadgeClass(change.Type)\">\n {{ change.Type }}\n </span>\n <span class=\"change-user\">{{ change.User || 'Unknown User' }}</span>\n <span class=\"change-source\" [class]=\"getSourceClass(change.Source)\">\n {{ change.Source }}\n </span>\n </div>\n <div class=\"change-meta\">\n <span class=\"change-time\" [title]=\"formatFullDateTime(change.ChangedAt)\">\n {{ formatRelativeTime(change.ChangedAt) }}\n </span>\n <span class=\"change-status\" [class]=\"getStatusClass(change.Status)\">\n {{ change.Status }}\n </span>\n @if (change.Integration) {\n <span class=\"change-integration\">\n via {{ change.Integration }}\n </span>\n }\n </div>\n </div>\n \n @if (!expandedItems.has(change.ID)) {\n <div class=\"change-summary\">\n {{ getChangeSummary(change) }}\n </div>\n }\n \n @if (expandedItems.has(change.ID)) {\n <div class=\"change-details\">\n <div class=\"change-timestamp\">\n <i class=\"fa-solid fa-clock\" aria-hidden=\"true\"></i>\n <strong>{{ formatFullDateTime(change.ChangedAt) }}</strong>\n </div>\n @if (change.Type === 'Create') {\n <div class=\"creation-details\">\n <h4><i class=\"fa-solid fa-plus\"></i> Record Created</h4>\n @if (change.FullRecordJSON) {\n <div class=\"field-changes\">\n @for (field of getCreatedFields(change); track field.name) {\n <div class=\"field-change created\">\n <span class=\"field-name\">{{ field.displayName }}</span>\n <span class=\"field-value new-value\">{{ field.value }}</span>\n </div>\n }\n </div>\n }\n </div>\n } @else if (change.Type === 'Delete') {\n <div class=\"deletion-details\">\n <h4><i class=\"fa-solid fa-trash\"></i> Record Deleted</h4>\n <p class=\"deletion-note\">This record was permanently removed from the system.</p>\n </div>\n } @else {\n <div class=\"update-details\">\n <h4><i class=\"fa-solid fa-edit\"></i> Fields Changed</h4>\n <div class=\"field-changes\">\n @for (fieldChange of getFieldChanges(change); track fieldChange.field) {\n <div class=\"field-change\">\n <div class=\"field-name\">{{ fieldChange.displayName }}</div>\n @if (fieldChange.isBooleanField) {\n <div class=\"boolean-change\">\n <span class=\"new-value\">{{ fieldChange.newValue }}</span>\n </div>\n } @else if (fieldChange.diffHtml) {\n <div class=\"diff-view\">\n <div class=\"diff-content\" [innerHTML]=\"fieldChange.diffHtml\"></div>\n </div>\n } @else {\n <div class=\"value-diff\">\n <div class=\"old-value\">\n <span class=\"value-label\">From:</span>\n <span class=\"value\">{{ fieldChange.oldValue || '(empty)' }}</span>\n </div>\n <div class=\"diff-arrow\">\n <i class=\"fa-solid fa-arrow-right\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"new-value\">\n <span class=\"value-label\">To:</span>\n <span class=\"value\">{{ fieldChange.newValue || '(empty)' }}</span>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n \n @if (change.Comments) {\n <div class=\"change-comments\">\n <h5><i class=\"fa-solid fa-comment\"></i> Comments</h5>\n <p>{{ change.Comments }}</p>\n </div>\n }\n \n @if (change.ErrorLog) {\n <div class=\"change-errors\">\n <h5><i class=\"fa-solid fa-exclamation-triangle\"></i> Errors</h5>\n <pre class=\"error-log\">{{ change.ErrorLog }}</pre>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </kendo-window>\n</div>", styles: ["/* Record Changes Timeline Styles */\n.record-changes-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 1rem;\n}\n\n/* Filter Panel */\n.filter-panel {\n background: #f8f9fa;\n border-radius: 8px;\n padding: 1rem;\n margin-bottom: 1rem;\n border: 1px solid #e9ecef;\n}\n\n.filter-controls {\n display: flex;\n gap: 1rem;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.search-input {\n flex: 1;\n min-width: 200px;\n padding: 0.5rem 1rem;\n border: 1px solid #ced4da;\n border-radius: 4px;\n font-size: 0.9rem;\n}\n\n.search-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.filter-select {\n padding: 0.5rem;\n border: 1px solid #ced4da;\n border-radius: 4px;\n background: white;\n font-size: 0.9rem;\n min-width: 120px;\n}\n\n.filter-select:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.filter-results {\n margin-top: 0.5rem;\n font-size: 0.85rem;\n color: #6c757d;\n font-style: italic;\n}\n\n/* Timeline Container */\n.timeline-container {\n flex: 1;\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n\n.no-changes-message {\n text-align: center;\n padding: 3rem 1rem;\n color: #6c757d;\n font-size: 1.1rem;\n}\n\n.no-changes-message i {\n display: block;\n font-size: 2rem;\n margin-bottom: 1rem;\n color: #adb5bd;\n}\n\n/* Timeline */\n.timeline {\n position: relative;\n padding-left: 2rem;\n}\n\n.timeline-item {\n position: relative;\n margin-bottom: 1.5rem;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.timeline-item:hover {\n transform: translateX(2px);\n}\n\n.timeline-item:focus {\n outline: 2px solid #007bff;\n outline-offset: 2px;\n border-radius: 4px;\n}\n\n.timeline-item.expanded {\n margin-bottom: 2rem;\n}\n\n/* Timeline Marker */\n.timeline-marker {\n position: absolute;\n left: -2rem;\n top: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.timeline-icon {\n width: 2.5rem;\n height: 2.5rem;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.9rem;\n color: white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n z-index: 2;\n}\n\n.timeline-icon.change-create {\n background: linear-gradient(135deg, #28a745, #20c997);\n}\n\n.timeline-icon.change-update {\n background: linear-gradient(135deg, #007bff, #6f42c1);\n}\n\n.timeline-icon.change-delete {\n background: linear-gradient(135deg, #dc3545, #fd7e14);\n}\n\n.timeline-icon.change-unknown {\n background: linear-gradient(135deg, #6c757d, #adb5bd);\n}\n\n.timeline-line {\n width: 2px;\n height: 2rem;\n background: #e9ecef;\n margin-top: 0.5rem;\n}\n\n/* Timeline Content */\n.timeline-content {\n background: white;\n border: 1px solid #e9ecef;\n border-radius: 8px;\n padding: 1rem;\n box-shadow: 0 2px 4px rgba(0,0,0,0.05);\n transition: box-shadow 0.2s ease;\n}\n\n.timeline-item:hover .timeline-content {\n box-shadow: 0 4px 8px rgba(0,0,0,0.1);\n}\n\n.timeline-item.expanded .timeline-content {\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n}\n\n/* Change Header */\n.change-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.75rem;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.change-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.change-type-badge {\n font-size: 0.75rem;\n font-weight: 600;\n padding: 0.25rem 0.5rem;\n border-radius: 12px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.badge-create {\n background: #d4edda;\n color: #155724;\n}\n\n.badge-update {\n background: #cce7ff;\n color: #004085;\n}\n\n.badge-delete {\n background: #f8d7da;\n color: #721c24;\n}\n\n.badge-unknown {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.change-user {\n font-weight: 600;\n color: #495057;\n}\n\n.change-source {\n font-size: 0.8rem;\n padding: 0.2rem 0.4rem;\n border-radius: 8px;\n font-weight: 500;\n}\n\n.source-internal {\n background: #e7f3ff;\n color: #0056b3;\n}\n\n.source-external {\n background: #fff3cd;\n color: #856404;\n}\n\n.change-meta {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 0.85rem;\n color: #6c757d;\n flex-wrap: wrap;\n}\n\n.change-time {\n font-weight: 500;\n}\n\n.change-status {\n padding: 0.2rem 0.4rem;\n border-radius: 8px;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-complete {\n background: #d4edda;\n color: #155724;\n}\n\n.status-pending {\n background: #fff3cd;\n color: #856404;\n}\n\n.status-error {\n background: #f8d7da;\n color: #721c24;\n}\n\n.status-unknown {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.change-integration {\n font-style: italic;\n color: #495057;\n}\n\n/* Change Summary */\n.change-summary {\n color: #6c757d;\n font-size: 0.9rem;\n line-height: 1.4;\n}\n\n/* Change Details */\n.change-details {\n margin-top: 1rem;\n padding-top: 1rem;\n border-top: 1px solid #e9ecef;\n}\n\n.change-timestamp {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 1rem;\n padding: 0.5rem;\n background: #f8f9fa;\n border-radius: 6px;\n border-left: 4px solid #6c757d;\n font-size: 0.9rem;\n color: #495057;\n}\n\n.change-timestamp i {\n color: #6c757d;\n}\n\n.change-details h4 {\n font-size: 1rem;\n margin-bottom: 1rem;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.change-details h5 {\n font-size: 0.9rem;\n margin-bottom: 0.5rem;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n/* Field Changes */\n.field-changes {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.field-change {\n background: #f8f9fa;\n border-radius: 6px;\n padding: 0.75rem;\n border-left: 4px solid #007bff;\n}\n\n.field-change.created {\n border-left-color: #28a745;\n}\n\n.field-name {\n font-weight: 600;\n color: #495057;\n margin-bottom: 0.5rem;\n display: block;\n}\n\n.field-value {\n font-family: 'Courier New', monospace;\n font-size: 0.85rem;\n padding: 0.25rem 0.5rem;\n border-radius: 4px;\n background: white;\n border: 1px solid #dee2e6;\n}\n\n.value-diff {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 1rem;\n align-items: center;\n}\n\n.old-value, .new-value {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.value-label {\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: #6c757d;\n}\n\n.old-value .value {\n color: #6c757d;\n background: #f8f9fa;\n text-decoration: line-through;\n}\n\n.new-value .value {\n color: #155724;\n background: #d4edda;\n font-weight: 500;\n}\n\n.value {\n font-family: 'Courier New', monospace;\n font-size: 0.85rem;\n padding: 0.25rem 0.5rem;\n border-radius: 4px;\n border: 1px solid #dee2e6;\n word-break: break-all;\n}\n\n.diff-arrow {\n color: #007bff;\n font-size: 1.2rem;\n}\n\n.boolean-change .new-value {\n font-weight: 600;\n color: #007bff;\n font-size: 0.9rem;\n}\n\n/* Creation Details */\n.creation-details .field-change {\n border-left-color: #28a745;\n}\n\n.creation-details .field-value {\n color: #155724;\n background: #d4edda;\n font-weight: 500;\n}\n\n/* Deletion Details */\n.deletion-details {\n text-align: center;\n padding: 1rem;\n}\n\n.deletion-note {\n color: #6c757d;\n font-style: italic;\n margin-bottom: 0;\n}\n\n/* Diff View Styles - Scoped to this component */\nmj-record-changes .diff-view,\n.record-changes-container .diff-view {\n margin-top: 0.5rem !important;\n border: 1px dashed #28a745;\n border-radius: 4px;\n padding: 0.25rem;\n}\n\nmj-record-changes .diff-content,\n.record-changes-container .diff-content {\n background: #ffffff !important;\n border: 2px solid #007bff !important;\n border-radius: 6px;\n padding: 0.75rem !important;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace !important;\n font-size: 0.85rem !important;\n line-height: 1.45 !important;\n overflow-x: auto;\n min-height: 2rem;\n}\n\nmj-record-changes .diff-container,\n.record-changes-container .diff-container {\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\nmj-record-changes .diff-added,\n.record-changes-container .diff-added {\n background-color: #d1f5d3 !important;\n color: #22863a !important;\n text-decoration: none !important;\n border-radius: 3px;\n padding: 2px 4px !important;\n font-weight: 600 !important;\n display: inline;\n border: 1px solid #28a745;\n}\n\nmj-record-changes .diff-removed,\n.record-changes-container .diff-removed {\n background-color: #ffeef0 !important;\n color: #d73a49 !important;\n text-decoration: line-through !important;\n border-radius: 3px;\n padding: 2px 4px !important;\n font-weight: 600 !important;\n display: inline;\n border: 1px solid #dc3545;\n}\n\nmj-record-changes .diff-unchanged,\n.record-changes-container .diff-unchanged {\n color: #24292e !important;\n display: inline;\n}\n\n/* Enhanced diff styling for better readability */\nmj-record-changes .diff-added:not(:empty)::before,\n.record-changes-container .diff-added:not(:empty)::before {\n content: '';\n background: #28a745;\n width: 3px;\n height: 100%;\n position: absolute;\n left: -1px;\n border-radius: 1px;\n}\n\nmj-record-changes .diff-removed:not(:empty)::before,\n.record-changes-container .diff-removed:not(:empty)::before {\n content: '';\n background: #dc3545;\n width: 3px;\n height: 100%;\n position: absolute;\n left: -1px;\n border-radius: 1px;\n}\n\nmj-record-changes .diff-added, \nmj-record-changes .diff-removed,\n.record-changes-container .diff-added, \n.record-changes-container .diff-removed {\n position: relative;\n margin: 0 1px;\n display: inline;\n}\n\n/* Hover effects for diff elements */\nmj-record-changes .diff-added:hover,\n.record-changes-container .diff-added:hover {\n background-color: #c3f0c5 !important;\n box-shadow: 0 0 0 2px rgba(40, 167, 69, 0.15);\n}\n\nmj-record-changes .diff-removed:hover,\n.record-changes-container .diff-removed:hover {\n background-color: #ffd6dd !important;\n box-shadow: 0 0 0 2px rgba(220, 53, 69, 0.15);\n}\n\n/* Multi-line diff styling */\nmj-record-changes .diff-content .diff-added,\nmj-record-changes .diff-content .diff-removed,\n.record-changes-container .diff-content .diff-added,\n.record-changes-container .diff-content .diff-removed {\n padding: 1px 3px;\n border-radius: 3px;\n}\n\nmj-record-changes .diff-content .diff-added + .diff-added,\nmj-record-changes .diff-content .diff-removed + .diff-removed,\n.record-changes-container .diff-content .diff-added + .diff-added,\n.record-changes-container .diff-content .diff-removed + .diff-removed {\n margin-left: 0;\n}\n\n/* Word diff specific styling */\nmj-record-changes .diff-container.word-diff .diff-added,\nmj-record-changes .diff-container.word-diff .diff-removed,\n.record-changes-container .diff-container.word-diff .diff-added,\n.record-changes-container .diff-container.word-diff .diff-removed {\n padding: 2px 4px;\n margin: 0 1px;\n border-radius: 4px;\n}\n\n/* Comments and Errors */\n.change-comments, .change-errors {\n margin-top: 1rem;\n padding: 0.75rem;\n border-radius: 6px;\n}\n\n.change-comments {\n background: #e7f3ff;\n border-left: 4px solid #007bff;\n}\n\n.change-errors {\n background: #f8d7da;\n border-left: 4px solid #dc3545;\n}\n\n.error-log {\n background: #ffffff;\n padding: 0.5rem;\n border-radius: 4px;\n font-family: 'Courier New', monospace;\n font-size: 0.8rem;\n color: #721c24;\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .filter-controls {\n flex-direction: column;\n align-items: stretch;\n }\n \n .search-input, .filter-select {\n width: 100%;\n }\n \n .change-header {\n flex-direction: column;\n align-items: flex-start;\n }\n \n .change-meta {\n flex-direction: column;\n align-items: flex-start;\n gap: 0.25rem;\n }\n \n .value-diff {\n grid-template-columns: 1fr;\n gap: 0.5rem;\n }\n \n .diff-arrow {\n justify-self: center;\n transform: rotate(90deg);\n }\n \n .timeline {\n padding-left: 1.5rem;\n }\n \n .timeline-marker {\n left: -1.5rem;\n }\n \n .timeline-icon {\n width: 2rem;\n height: 2rem;\n font-size: 0.8rem;\n }\n \n /* Responsive diff view */\n .diff-content {\n font-size: 0.8rem;\n padding: 0.5rem;\n }\n \n .diff-added, .diff-removed {\n padding: 1px 2px;\n }\n}\n\n@media (max-width: 480px) {\n .record-changes-container {\n padding: 0.5rem;\n }\n \n .timeline-content {\n padding: 0.75rem;\n }\n \n .field-change {\n padding: 0.5rem;\n }\n}"] }]
|
|
678
|
-
}], () => [{ type: i0.
|
|
872
|
+
args: [{ standalone: false, selector: 'mj-record-changes', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mj-slide-panel\n [Mode]=\"'slide'\"\n [Title]=\"'Record Changes History'\"\n [Visible]=\"IsVisible\"\n [Resizable]=\"true\"\n [MinWidthPx]=\"400\"\n [MaxWidthRatio]=\"0.6\"\n (Closed)=\"OnClose()\">\n\n @if (IsLoading) {\n <mj-loading text=\"Loading history...\" size=\"medium\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <div class=\"record-changes-container\">\n <!-- Version Labels Section -->\n <div class=\"labels-section\">\n <div class=\"labels-header\">\n <div class=\"labels-title\">\n <i class=\"fa-solid fa-tags\" aria-hidden=\"true\"></i>\n <span>Version Labels</span>\n @if (RecordLabels.length > 0) {\n <span class=\"labels-count\">{{ RecordLabels.length }}</span>\n }\n </div>\n <button class=\"create-label-btn\" (click)=\"OpenCreateWizard()\" title=\"Create a version label for this record\">\n <i class=\"fa-solid fa-plus\"></i> Create Label\n </button>\n </div>\n @if (IsLoadingLabels) {\n <div class=\"labels-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading labels...\n </div>\n } @else if (RecordLabels.length === 0) {\n <div class=\"labels-empty\">\n No version labels for this record yet.\n </div>\n } @else {\n <div class=\"labels-list\">\n @for (label of RecordLabels; track label.ID) {\n <div class=\"label-chip\" [title]=\"label.Description || label.Name\">\n <i class=\"fa-solid fa-tag label-chip-icon\"></i>\n <span class=\"label-chip-name\">{{ label.Name }}</span>\n <span class=\"label-chip-meta\">\n <span class=\"label-chip-status\" [class]=\"getLabelStatusClass(label.Status)\">{{ label.Status }}</span>\n <span class=\"label-chip-items\">{{ label.ItemCount }} item{{ label.ItemCount !== 1 ? 's' : '' }}</span>\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n @if (viewData.length === 0) {\n <!-- Empty state \u2014 no changes ever recorded -->\n <div class=\"empty-state\">\n <div class=\"empty-state-icon\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n </div>\n <h3 class=\"empty-state-title\">No Change History</h3>\n <p class=\"empty-state-description\">\n This record doesn't have any tracked changes yet.\n Changes will appear here automatically as edits are made.\n </p>\n <div class=\"empty-state-hint\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Record change tracking is managed at the entity level</span>\n </div>\n </div>\n } @else {\n <!-- Filter Panel -->\n <div class=\"filter-panel\">\n <div class=\"filter-controls\">\n <input\n type=\"text\"\n class=\"search-input\"\n placeholder=\"Search changes...\"\n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchChange()\"\n aria-label=\"Search record changes\"\n />\n <select\n class=\"filter-select\"\n [(ngModel)]=\"selectedType\"\n (change)=\"onFilterChange()\"\n aria-label=\"Filter by change type\"\n >\n <option value=\"\">All Changes</option>\n <option value=\"Create\">Created</option>\n <option value=\"Update\">Updated</option>\n <option value=\"Delete\">Deleted</option>\n </select>\n <select\n class=\"filter-select\"\n [(ngModel)]=\"selectedSource\"\n (change)=\"onFilterChange()\"\n aria-label=\"Filter by change source\"\n >\n <option value=\"\">All Sources</option>\n <option value=\"Internal\">Internal</option>\n <option value=\"External\">External</option>\n </select>\n </div>\n @if (filteredData.length !== viewData.length) {\n <div class=\"filter-results\">\n Showing {{ filteredData.length }} of {{ viewData.length }} changes\n </div>\n }\n </div>\n\n <!-- Timeline Container -->\n <div class=\"timeline-container\" [attr.aria-label]=\"'Timeline of changes for ' + record.EntityInfo.Name + ' record'\">\n @if (filteredData.length === 0) {\n <div class=\"no-changes-message\">\n <i class=\"fa-solid fa-filter\"></i>\n <p>No changes match your current filters.</p>\n <button class=\"clear-filters-btn\" (click)=\"ClearFilters()\">\n <i class=\"fa-solid fa-xmark\"></i> Clear Filters\n </button>\n </div>\n } @else {\n <div class=\"timeline\">\n @for (change of filteredData; track change.ID; let i = $index) {\n <div\n class=\"timeline-item\"\n [class.expanded]=\"expandedItems.has(change.ID)\"\n [attr.tabindex]=\"0\"\n [attr.aria-expanded]=\"expandedItems.has(change.ID)\"\n [attr.aria-label]=\"getTimelineItemLabel(change)\"\n (click)=\"toggleExpansion(change.ID)\"\n (keydown)=\"onTimelineItemKeydown($event, change.ID)\"\n >\n <div class=\"timeline-marker\">\n <div class=\"timeline-icon\" [class]=\"getChangeTypeClass(change.Type)\">\n <i [class]=\"getChangeTypeIcon(change.Type)\" [attr.aria-hidden]=\"true\"></i>\n </div>\n @if (i < filteredData.length - 1) {\n <div class=\"timeline-line\"></div>\n }\n </div>\n\n <div class=\"timeline-content\">\n <div class=\"change-header\">\n <div class=\"change-title\">\n <span class=\"change-type-badge\" [class]=\"getChangeTypeBadgeClass(change.Type)\">\n {{ change.Type }}\n </span>\n <span class=\"change-user\">{{ change.User || 'Unknown User' }}</span>\n <span class=\"change-source\" [class]=\"getSourceClass(change.Source)\">\n {{ change.Source }}\n </span>\n </div>\n <div class=\"change-meta\">\n <span class=\"change-time\" [title]=\"formatFullDateTime(change.ChangedAt)\">\n {{ formatRelativeTime(change.ChangedAt) }}\n </span>\n <span class=\"change-status\" [class]=\"getStatusClass(change.Status)\">\n {{ change.Status }}\n </span>\n @if (change.Integration) {\n <span class=\"change-integration\">\n via {{ change.Integration }}\n </span>\n }\n </div>\n </div>\n\n @if (!expandedItems.has(change.ID)) {\n <div class=\"change-summary\">\n {{ getChangeSummary(change) }}\n </div>\n }\n\n @if (expandedItems.has(change.ID)) {\n <div class=\"change-details\">\n <div class=\"change-timestamp\">\n <i class=\"fa-solid fa-clock\" aria-hidden=\"true\"></i>\n <strong>{{ formatFullDateTime(change.ChangedAt) }}</strong>\n </div>\n @if (change.Type === 'Create') {\n <div class=\"creation-details\">\n <h4><i class=\"fa-solid fa-plus\"></i> Record Created</h4>\n @if (change.FullRecordJSON) {\n <div class=\"field-changes\">\n @for (field of getCreatedFields(change); track field.name) {\n <div class=\"field-change created\">\n <span class=\"field-name\">{{ field.displayName }}</span>\n <span class=\"field-value new-value\">{{ field.value }}</span>\n </div>\n }\n </div>\n }\n </div>\n } @else if (change.Type === 'Delete') {\n <div class=\"deletion-details\">\n <h4><i class=\"fa-solid fa-trash\"></i> Record Deleted</h4>\n <p class=\"deletion-note\">This record was permanently removed from the system.</p>\n </div>\n } @else {\n <div class=\"update-details\">\n <h4><i class=\"fa-solid fa-edit\"></i> Fields Changed</h4>\n <div class=\"field-changes\">\n @for (fieldChange of getFieldChanges(change); track fieldChange.field) {\n <div class=\"field-change\">\n <div class=\"field-name\">{{ fieldChange.displayName }}</div>\n @if (fieldChange.isBooleanField) {\n <div class=\"boolean-change\">\n <span class=\"new-value\">{{ fieldChange.newValue }}</span>\n </div>\n } @else if (fieldChange.diffHtml) {\n <div class=\"diff-view\">\n <div class=\"diff-content\" [innerHTML]=\"fieldChange.diffHtml\"></div>\n </div>\n } @else {\n <div class=\"value-diff\">\n <div class=\"old-value\">\n <span class=\"value-label\">From:</span>\n <span class=\"value\">{{ fieldChange.oldValue || '(empty)' }}</span>\n </div>\n <div class=\"diff-arrow\">\n <i class=\"fa-solid fa-arrow-right\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"new-value\">\n <span class=\"value-label\">To:</span>\n <span class=\"value\">{{ fieldChange.newValue || '(empty)' }}</span>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @if (change.Comments) {\n <div class=\"change-comments\">\n <h5><i class=\"fa-solid fa-comment\"></i> Comments</h5>\n <p>{{ change.Comments }}</p>\n </div>\n }\n\n @if (change.ErrorLog) {\n <div class=\"change-errors\">\n <h5><i class=\"fa-solid fa-exclamation-triangle\"></i> Errors</h5>\n <pre class=\"error-log\">{{ change.ErrorLog }}</pre>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (ShowCreateWizard) {\n <div class=\"create-wizard-overlay\" (click)=\"OnLabelCreateCancelled()\">\n <div class=\"create-wizard-container\" (click)=\"$event.stopPropagation()\">\n <mj-label-create\n [PreselectedEntity]=\"record.EntityInfo\"\n [PreselectedRecordIds]=\"[record.PrimaryKey.KeyValuePairs[0].Value]\"\n (Created)=\"OnLabelCreated($event)\"\n (Cancel)=\"OnLabelCreateCancelled()\">\n </mj-label-create>\n </div>\n </div>\n }\n</mj-slide-panel>\n", styles: ["/* Record Changes Timeline Styles */\n.record-changes-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 1rem;\n}\n\n/* Version Labels Section */\n.labels-section {\n background: #f8f9fa;\n border-radius: 8px;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n border: 1px solid #e9ecef;\n}\n\n.labels-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.5rem;\n}\n\n.labels-title {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-weight: 600;\n font-size: 0.9rem;\n color: #495057;\n}\n\n.labels-title i {\n color: #6f42c1;\n}\n\n.labels-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n height: 1.25rem;\n padding: 0 0.35rem;\n border-radius: 10px;\n background: #6f42c1;\n color: white;\n font-size: 0.7rem;\n font-weight: 700;\n}\n\n.create-label-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.35rem 0.75rem;\n border: 1px solid #6f42c1;\n border-radius: 6px;\n background: white;\n color: #6f42c1;\n font-size: 0.8rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.create-label-btn:hover {\n background: #6f42c1;\n color: white;\n}\n\n.labels-loading {\n font-size: 0.8rem;\n color: #6c757d;\n padding: 0.25rem 0;\n}\n\n.labels-loading i {\n margin-right: 0.25rem;\n}\n\n.labels-empty {\n font-size: 0.8rem;\n color: #94a3b8;\n font-style: italic;\n padding: 0.25rem 0;\n}\n\n.labels-list {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.label-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.3rem 0.6rem;\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 16px;\n font-size: 0.8rem;\n color: #495057;\n transition: all 0.15s ease;\n cursor: default;\n}\n\n.label-chip:hover {\n border-color: #6f42c1;\n box-shadow: 0 1px 3px rgba(111, 66, 193, 0.15);\n}\n\n.label-chip-icon {\n color: #6f42c1;\n font-size: 0.7rem;\n}\n\n.label-chip-name {\n font-weight: 600;\n max-width: 180px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.label-chip-meta {\n display: flex;\n align-items: center;\n gap: 0.3rem;\n font-size: 0.7rem;\n color: #6c757d;\n}\n\n.label-chip-status {\n padding: 0.1rem 0.3rem;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 0.6rem;\n letter-spacing: 0.03em;\n}\n\n.label-status-active {\n background: #d4edda;\n color: #155724;\n}\n\n.label-status-archived {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.label-status-restored {\n background: #cce7ff;\n color: #004085;\n}\n\n.label-chip-items {\n white-space: nowrap;\n}\n\n/* Create Wizard Overlay */\n.create-wizard-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: fadeIn 0.15s ease;\n}\n\n.create-wizard-container {\n background: white;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n width: 90%;\n max-width: 600px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 1.5rem;\n animation: slideUp 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes slideUp {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Filter Panel */\n.filter-panel {\n background: #f8f9fa;\n border-radius: 8px;\n padding: 1rem;\n margin-bottom: 1rem;\n border: 1px solid #e9ecef;\n}\n\n.filter-controls {\n display: flex;\n gap: 1rem;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.search-input {\n flex: 1;\n min-width: 200px;\n padding: 0.5rem 1rem;\n border: 1px solid #ced4da;\n border-radius: 4px;\n font-size: 0.9rem;\n}\n\n.search-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.filter-select {\n padding: 0.5rem;\n border: 1px solid #ced4da;\n border-radius: 4px;\n background: white;\n font-size: 0.9rem;\n min-width: 120px;\n}\n\n.filter-select:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.filter-results {\n margin-top: 0.5rem;\n font-size: 0.85rem;\n color: #6c757d;\n font-style: italic;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n text-align: center;\n min-height: 400px;\n}\n\n.empty-state-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: linear-gradient(135deg, #e8edf2, #f0f4f8);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 1.5rem;\n}\n\n.empty-state-icon i {\n font-size: 2rem;\n color: #94a3b8;\n}\n\n.empty-state-title {\n font-size: 1.25rem;\n font-weight: 600;\n color: #334155;\n margin: 0 0 0.75rem 0;\n}\n\n.empty-state-description {\n font-size: 0.95rem;\n color: #64748b;\n line-height: 1.6;\n max-width: 320px;\n margin: 0 0 1.5rem 0;\n}\n\n.empty-state-hint {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n background: #f1f5f9;\n border-radius: 20px;\n font-size: 0.8rem;\n color: #64748b;\n}\n\n.empty-state-hint i {\n color: #94a3b8;\n}\n\n/* No filtered results */\n.no-changes-message {\n text-align: center;\n padding: 3rem 1rem;\n color: #6c757d;\n}\n\n.no-changes-message i {\n display: block;\n font-size: 2rem;\n margin-bottom: 1rem;\n color: #adb5bd;\n}\n\n.no-changes-message p {\n font-size: 1rem;\n margin: 0 0 1rem 0;\n}\n\n.clear-filters-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 1rem;\n border: 1px solid #ced4da;\n border-radius: 6px;\n background: white;\n color: #495057;\n font-size: 0.85rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-filters-btn:hover {\n background: #f8f9fa;\n border-color: #adb5bd;\n}\n\n/* Timeline Container */\n.timeline-container {\n flex: 1;\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n\n/* Timeline */\n.timeline {\n position: relative;\n padding-left: 2rem;\n}\n\n.timeline-item {\n position: relative;\n margin-bottom: 1.5rem;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.timeline-item:hover {\n transform: translateX(2px);\n}\n\n.timeline-item:focus {\n outline: 2px solid #007bff;\n outline-offset: 2px;\n border-radius: 4px;\n}\n\n.timeline-item.expanded {\n margin-bottom: 2rem;\n}\n\n/* Timeline Marker */\n.timeline-marker {\n position: absolute;\n left: -2rem;\n top: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.timeline-icon {\n width: 2.5rem;\n height: 2.5rem;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.9rem;\n color: white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n z-index: 2;\n}\n\n.timeline-icon.change-create {\n background: linear-gradient(135deg, #28a745, #20c997);\n}\n\n.timeline-icon.change-update {\n background: linear-gradient(135deg, #007bff, #6f42c1);\n}\n\n.timeline-icon.change-delete {\n background: linear-gradient(135deg, #dc3545, #fd7e14);\n}\n\n.timeline-icon.change-unknown {\n background: linear-gradient(135deg, #6c757d, #adb5bd);\n}\n\n.timeline-line {\n width: 2px;\n height: 2rem;\n background: #e9ecef;\n margin-top: 0.5rem;\n}\n\n/* Timeline Content */\n.timeline-content {\n background: white;\n border: 1px solid #e9ecef;\n border-radius: 8px;\n padding: 1rem;\n box-shadow: 0 2px 4px rgba(0,0,0,0.05);\n transition: box-shadow 0.2s ease;\n}\n\n.timeline-item:hover .timeline-content {\n box-shadow: 0 4px 8px rgba(0,0,0,0.1);\n}\n\n.timeline-item.expanded .timeline-content {\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n}\n\n/* Change Header */\n.change-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.75rem;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.change-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.change-type-badge {\n font-size: 0.75rem;\n font-weight: 600;\n padding: 0.25rem 0.5rem;\n border-radius: 12px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.badge-create {\n background: #d4edda;\n color: #155724;\n}\n\n.badge-update {\n background: #cce7ff;\n color: #004085;\n}\n\n.badge-delete {\n background: #f8d7da;\n color: #721c24;\n}\n\n.badge-unknown {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.change-user {\n font-weight: 600;\n color: #495057;\n}\n\n.change-source {\n font-size: 0.8rem;\n padding: 0.2rem 0.4rem;\n border-radius: 8px;\n font-weight: 500;\n}\n\n.source-internal {\n background: #e7f3ff;\n color: #0056b3;\n}\n\n.source-external {\n background: #fff3cd;\n color: #856404;\n}\n\n.change-meta {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 0.85rem;\n color: #6c757d;\n flex-wrap: wrap;\n}\n\n.change-time {\n font-weight: 500;\n}\n\n.change-status {\n padding: 0.2rem 0.4rem;\n border-radius: 8px;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-complete {\n background: #d4edda;\n color: #155724;\n}\n\n.status-pending {\n background: #fff3cd;\n color: #856404;\n}\n\n.status-error {\n background: #f8d7da;\n color: #721c24;\n}\n\n.status-unknown {\n background: #e2e3e5;\n color: #383d41;\n}\n\n.change-integration {\n font-style: italic;\n color: #495057;\n}\n\n/* Change Summary */\n.change-summary {\n color: #6c757d;\n font-size: 0.9rem;\n line-height: 1.4;\n}\n\n/* Change Details */\n.change-details {\n margin-top: 1rem;\n padding-top: 1rem;\n border-top: 1px solid #e9ecef;\n}\n\n.change-timestamp {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 1rem;\n padding: 0.5rem;\n background: #f8f9fa;\n border-radius: 6px;\n border-left: 4px solid #6c757d;\n font-size: 0.9rem;\n color: #495057;\n}\n\n.change-timestamp i {\n color: #6c757d;\n}\n\n.change-details h4 {\n font-size: 1rem;\n margin-bottom: 1rem;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.change-details h5 {\n font-size: 0.9rem;\n margin-bottom: 0.5rem;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n/* Field Changes */\n.field-changes {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.field-change {\n background: #f8f9fa;\n border-radius: 6px;\n padding: 0.75rem;\n border-left: 4px solid #007bff;\n}\n\n.field-change.created {\n border-left-color: #28a745;\n}\n\n.field-name {\n font-weight: 600;\n color: #495057;\n margin-bottom: 0.5rem;\n display: block;\n}\n\n.field-value {\n font-family: 'Courier New', monospace;\n font-size: 0.85rem;\n padding: 0.25rem 0.5rem;\n border-radius: 4px;\n background: white;\n border: 1px solid #dee2e6;\n}\n\n.value-diff {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 1rem;\n align-items: center;\n}\n\n.old-value, .new-value {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.value-label {\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: #6c757d;\n}\n\n.old-value .value {\n color: #6c757d;\n background: #f8f9fa;\n text-decoration: line-through;\n}\n\n.new-value .value {\n color: #155724;\n background: #d4edda;\n font-weight: 500;\n}\n\n.value {\n font-family: 'Courier New', monospace;\n font-size: 0.85rem;\n padding: 0.25rem 0.5rem;\n border-radius: 4px;\n border: 1px solid #dee2e6;\n word-break: break-all;\n}\n\n.diff-arrow {\n color: #007bff;\n font-size: 1.2rem;\n}\n\n.boolean-change .new-value {\n font-weight: 600;\n color: #007bff;\n font-size: 0.9rem;\n}\n\n/* Creation Details */\n.creation-details .field-change {\n border-left-color: #28a745;\n}\n\n.creation-details .field-value {\n color: #155724;\n background: #d4edda;\n font-weight: 500;\n}\n\n/* Deletion Details */\n.deletion-details {\n text-align: center;\n padding: 1rem;\n}\n\n.deletion-note {\n color: #6c757d;\n font-style: italic;\n margin-bottom: 0;\n}\n\n/* Diff View Styles */\n.diff-view {\n margin-top: 0.5rem;\n border: 1px dashed #28a745;\n border-radius: 4px;\n padding: 0.25rem;\n}\n\n.diff-content {\n background: #ffffff;\n border: 2px solid #007bff;\n border-radius: 6px;\n padding: 0.75rem;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n font-size: 0.85rem;\n line-height: 1.45;\n overflow-x: auto;\n min-height: 2rem;\n}\n\n.diff-container {\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.diff-added {\n background-color: #d1f5d3;\n color: #22863a;\n text-decoration: none;\n border-radius: 3px;\n padding: 2px 4px;\n font-weight: 600;\n display: inline;\n border: 1px solid #28a745;\n position: relative;\n margin: 0 1px;\n}\n\n.diff-removed {\n background-color: #ffeef0;\n color: #d73a49;\n text-decoration: line-through;\n border-radius: 3px;\n padding: 2px 4px;\n font-weight: 600;\n display: inline;\n border: 1px solid #dc3545;\n position: relative;\n margin: 0 1px;\n}\n\n.diff-unchanged {\n color: #24292e;\n display: inline;\n}\n\n/* Hover effects for diff elements */\n.diff-added:hover {\n background-color: #c3f0c5;\n box-shadow: 0 0 0 2px rgba(40, 167, 69, 0.15);\n}\n\n.diff-removed:hover {\n background-color: #ffd6dd;\n box-shadow: 0 0 0 2px rgba(220, 53, 69, 0.15);\n}\n\n/* Comments and Errors */\n.change-comments, .change-errors {\n margin-top: 1rem;\n padding: 0.75rem;\n border-radius: 6px;\n}\n\n.change-comments {\n background: #e7f3ff;\n border-left: 4px solid #007bff;\n}\n\n.change-errors {\n background: #f8d7da;\n border-left: 4px solid #dc3545;\n}\n\n.error-log {\n background: #ffffff;\n padding: 0.5rem;\n border-radius: 4px;\n font-family: 'Courier New', monospace;\n font-size: 0.8rem;\n color: #721c24;\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .filter-controls {\n flex-direction: column;\n align-items: stretch;\n }\n\n .search-input, .filter-select {\n width: 100%;\n }\n\n .change-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .change-meta {\n flex-direction: column;\n align-items: flex-start;\n gap: 0.25rem;\n }\n\n .value-diff {\n grid-template-columns: 1fr;\n gap: 0.5rem;\n }\n\n .diff-arrow {\n justify-self: center;\n transform: rotate(90deg);\n }\n\n .timeline {\n padding-left: 1.5rem;\n }\n\n .timeline-marker {\n left: -1.5rem;\n }\n\n .timeline-icon {\n width: 2rem;\n height: 2rem;\n font-size: 0.8rem;\n }\n\n .diff-content {\n font-size: 0.8rem;\n padding: 0.5rem;\n }\n\n .diff-added, .diff-removed {\n padding: 1px 2px;\n }\n}\n\n@media (max-width: 480px) {\n .record-changes-container {\n padding: 0.5rem;\n }\n\n .timeline-content {\n padding: 0.75rem;\n }\n\n .field-change {\n padding: 0.5rem;\n }\n}\n"] }]
|
|
873
|
+
}], () => [{ type: i0.ChangeDetectorRef }, { type: i1.MJNotificationService }, { type: i2.DomSanitizer }], { dialogClosed: [{
|
|
679
874
|
type: Output
|
|
680
875
|
}], record: [{
|
|
681
876
|
type: Input
|
|
682
|
-
}], wrapper: [{
|
|
683
|
-
type: ViewChild,
|
|
684
|
-
args: ['recordChangesWrapper', { static: true }]
|
|
685
877
|
}] }); })();
|
|
686
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RecordChangesComponent, { className: "RecordChangesComponent", filePath: "src/lib/ng-record-changes.component.ts", lineNumber:
|
|
878
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RecordChangesComponent, { className: "RecordChangesComponent", filePath: "src/lib/ng-record-changes.component.ts", lineNumber: 27 }); })();
|
|
687
879
|
//# sourceMappingURL=ng-record-changes.component.js.map
|