@memberjunction/ng-record-changes 6.2.0-edge.5 → 6.2.0-edge.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/dist/lib/ng-record-changes.component.d.ts +166 -1
- package/dist/lib/ng-record-changes.component.d.ts.map +1 -1
- package/dist/lib/ng-record-changes.component.js +1347 -349
- package/dist/lib/ng-record-changes.component.js.map +1 -1
- package/dist/lib/ng-record-changes.module.d.ts +1 -1
- package/dist/lib/ng-record-changes.module.d.ts.map +1 -1
- package/dist/lib/ng-record-changes.module.js +7 -4
- package/dist/lib/ng-record-changes.module.js.map +1 -1
- package/package.json +10 -10
|
@@ -14,592 +14,936 @@ import * as i6 from "@memberjunction/ng-ui-components";
|
|
|
14
14
|
import * as i7 from "./restore-preview-panel/restore-preview-panel.component";
|
|
15
15
|
import * as i8 from "@angular/common";
|
|
16
16
|
const _c0 = a0 => [a0];
|
|
17
|
-
const _forTrack0 = ($index, $item) => $item.
|
|
18
|
-
const _forTrack1 = ($index, $item) => $item.
|
|
19
|
-
const _forTrack2 = ($index, $item) => $item.
|
|
20
|
-
const _forTrack3 = ($index, $item) => $item.
|
|
21
|
-
const _forTrack4 = ($index, $item) => $item.
|
|
17
|
+
const _forTrack0 = ($index, $item) => $item.Name;
|
|
18
|
+
const _forTrack1 = ($index, $item) => $item.ID;
|
|
19
|
+
const _forTrack2 = ($index, $item) => $item.field;
|
|
20
|
+
const _forTrack3 = ($index, $item) => $item.Key;
|
|
21
|
+
const _forTrack4 = ($index, $item) => $item.label;
|
|
22
|
+
const _forTrack5 = ($index, $item) => $item.name;
|
|
22
23
|
function RecordChangesComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
23
24
|
i0.ɵɵelement(0, "mj-loading", 1);
|
|
24
25
|
} }
|
|
25
|
-
function
|
|
26
|
-
i0.ɵɵelementStart(0, "span",
|
|
26
|
+
function RecordChangesComponent_Conditional_2_Conditional_9_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
27
|
+
i0.ɵɵelementStart(0, "span", 23);
|
|
27
28
|
i0.ɵɵtext(1);
|
|
28
29
|
i0.ɵɵelementEnd();
|
|
29
30
|
} if (rf & 2) {
|
|
30
|
-
const
|
|
31
|
+
const contributor_r2 = ctx.$implicit;
|
|
32
|
+
i0.ɵɵproperty("title", contributor_r2.Name);
|
|
33
|
+
i0.ɵɵattribute("aria-label", contributor_r2.Name);
|
|
31
34
|
i0.ɵɵadvance();
|
|
32
|
-
i0.ɵɵ
|
|
35
|
+
i0.ɵɵtextInterpolate1(" ", contributor_r2.Initials, " ");
|
|
33
36
|
} }
|
|
34
|
-
function
|
|
35
|
-
i0.ɵɵelementStart(0, "div",
|
|
36
|
-
i0.ɵɵ
|
|
37
|
-
i0.ɵɵ
|
|
37
|
+
function RecordChangesComponent_Conditional_2_Conditional_9_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
38
|
+
i0.ɵɵelementStart(0, "div", 21);
|
|
39
|
+
i0.ɵɵrepeaterCreate(1, RecordChangesComponent_Conditional_2_Conditional_9_Conditional_3_For_2_Template, 2, 3, "span", 23, _forTrack0);
|
|
40
|
+
i0.ɵɵelementEnd();
|
|
41
|
+
} if (rf & 2) {
|
|
42
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
43
|
+
i0.ɵɵadvance();
|
|
44
|
+
i0.ɵɵrepeater(ctx_r2.TopContributors);
|
|
45
|
+
} }
|
|
46
|
+
function RecordChangesComponent_Conditional_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
47
|
+
i0.ɵɵelementStart(0, "div", 11)(1, "span", 20);
|
|
48
|
+
i0.ɵɵtext(2);
|
|
38
49
|
i0.ɵɵelementEnd();
|
|
50
|
+
i0.ɵɵconditionalCreate(3, RecordChangesComponent_Conditional_2_Conditional_9_Conditional_3_Template, 3, 0, "div", 21);
|
|
51
|
+
i0.ɵɵelementStart(4, "span", 22);
|
|
52
|
+
i0.ɵɵtext(5);
|
|
53
|
+
i0.ɵɵelementEnd()();
|
|
54
|
+
} if (rf & 2) {
|
|
55
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
56
|
+
i0.ɵɵadvance(2);
|
|
57
|
+
i0.ɵɵtextInterpolate4(" ", ctx_r2.viewData.length, " change", ctx_r2.viewData.length !== 1 ? "s" : "", " \u00B7 ", ctx_r2.getUniqueContributorCount(), " contributor", ctx_r2.getUniqueContributorCount() !== 1 ? "s" : "", " ");
|
|
58
|
+
i0.ɵɵadvance();
|
|
59
|
+
i0.ɵɵconditional(ctx_r2.TopContributors.length > 0 ? 3 : -1);
|
|
60
|
+
i0.ɵɵadvance(2);
|
|
61
|
+
i0.ɵɵtextInterpolate1("\u00B7 Latest ", ctx_r2.formatRelativeTime(ctx_r2.viewData[0].ChangedAt));
|
|
62
|
+
} }
|
|
63
|
+
function RecordChangesComponent_Conditional_2_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
64
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
65
|
+
i0.ɵɵelementStart(0, "button", 24);
|
|
66
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.ToggleCompareMode()); });
|
|
67
|
+
i0.ɵɵelement(1, "i", 25);
|
|
68
|
+
i0.ɵɵelementStart(2, "span");
|
|
69
|
+
i0.ɵɵtext(3, "Compare");
|
|
70
|
+
i0.ɵɵelementEnd()();
|
|
71
|
+
} if (rf & 2) {
|
|
72
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
73
|
+
i0.ɵɵclassProp("active", ctx_r2.CompareMode);
|
|
74
|
+
i0.ɵɵattribute("aria-pressed", ctx_r2.CompareMode);
|
|
39
75
|
} }
|
|
40
76
|
function RecordChangesComponent_Conditional_2_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
41
|
-
i0.ɵɵ
|
|
77
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
78
|
+
i0.ɵɵelementStart(0, "button", 26);
|
|
79
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.ToggleLabelsTray()); });
|
|
80
|
+
i0.ɵɵelement(1, "i", 27);
|
|
81
|
+
i0.ɵɵelementStart(2, "span");
|
|
82
|
+
i0.ɵɵtext(3);
|
|
83
|
+
i0.ɵɵelementEnd();
|
|
84
|
+
i0.ɵɵelement(4, "i", 28);
|
|
85
|
+
i0.ɵɵelementEnd();
|
|
86
|
+
} if (rf & 2) {
|
|
87
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
88
|
+
i0.ɵɵclassProp("active", ctx_r2.ShowLabelsTray);
|
|
89
|
+
i0.ɵɵattribute("aria-expanded", ctx_r2.ShowLabelsTray);
|
|
90
|
+
i0.ɵɵadvance(3);
|
|
91
|
+
i0.ɵɵtextInterpolate2("", ctx_r2.RecordLabels.length, " Label", ctx_r2.RecordLabels.length !== 1 ? "s" : "");
|
|
92
|
+
i0.ɵɵadvance();
|
|
93
|
+
i0.ɵɵclassProp("fa-chevron-up", ctx_r2.ShowLabelsTray)("fa-chevron-down", !ctx_r2.ShowLabelsTray);
|
|
94
|
+
} }
|
|
95
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_For_9_Template(rf, ctx) { if (rf & 1) {
|
|
96
|
+
i0.ɵɵelementStart(0, "option", 34);
|
|
97
|
+
i0.ɵɵtext(1);
|
|
98
|
+
i0.ɵɵelementEnd();
|
|
99
|
+
} if (rf & 2) {
|
|
100
|
+
const ver_r7 = ctx.$implicit;
|
|
101
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
102
|
+
i0.ɵɵproperty("value", ver_r7.ID)("selected", ctx_r2.IsChangeSelectedAsCompareBase(ver_r7));
|
|
103
|
+
i0.ɵɵadvance();
|
|
104
|
+
i0.ɵɵtextInterpolate2(" ", ctx_r2.formatFullDateTime(ver_r7.ChangedAt), " \u2014 ", ctx_r2.getUserDisplayName(ver_r7.User), " ");
|
|
105
|
+
} }
|
|
106
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_10_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
107
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
108
|
+
i0.ɵɵelementStart(0, "button", 42);
|
|
109
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_10_Conditional_2_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r10); const baseChange_r9 = i0.ɵɵnextContext(); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnRestoreVersion(baseChange_r9, $event)); });
|
|
110
|
+
i0.ɵɵelement(1, "i", 43);
|
|
111
|
+
i0.ɵɵelementEnd();
|
|
112
|
+
} }
|
|
113
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
114
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
115
|
+
i0.ɵɵelementStart(0, "button", 39);
|
|
116
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_10_Template_button_click_0_listener($event) { const baseChange_r9 = i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnToggleFormPreview(baseChange_r9, $event)); });
|
|
117
|
+
i0.ɵɵelement(1, "i", 40);
|
|
118
|
+
i0.ɵɵelementEnd();
|
|
119
|
+
i0.ɵɵconditionalCreate(2, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_10_Conditional_2_Template, 2, 0, "button", 41);
|
|
120
|
+
} if (rf & 2) {
|
|
121
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
122
|
+
i0.ɵɵclassProp("active", ctx_r2.IsChangePreviewedInForm(ctx));
|
|
123
|
+
i0.ɵɵadvance(2);
|
|
124
|
+
i0.ɵɵconditional(ctx_r2.AllowRestore ? 2 : -1);
|
|
125
|
+
} }
|
|
126
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_For_20_Template(rf, ctx) { if (rf & 1) {
|
|
127
|
+
i0.ɵɵelementStart(0, "option", 34);
|
|
128
|
+
i0.ɵɵtext(1);
|
|
129
|
+
i0.ɵɵelementEnd();
|
|
130
|
+
} if (rf & 2) {
|
|
131
|
+
const ver_r11 = ctx.$implicit;
|
|
132
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
133
|
+
i0.ɵɵproperty("value", ver_r11.ID)("selected", ctx_r2.IsChangeSelectedAsCompareTarget(ver_r11));
|
|
134
|
+
i0.ɵɵadvance();
|
|
135
|
+
i0.ɵɵtextInterpolate2(" ", ctx_r2.formatFullDateTime(ver_r11.ChangedAt), " \u2014 ", ctx_r2.getUserDisplayName(ver_r11.User), " ");
|
|
136
|
+
} }
|
|
137
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_21_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
138
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
139
|
+
i0.ɵɵelementStart(0, "button", 46);
|
|
140
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_21_Conditional_2_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r14); const targetChange_r13 = i0.ɵɵnextContext(); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnRestoreVersion(targetChange_r13, $event)); });
|
|
141
|
+
i0.ɵɵelement(1, "i", 43);
|
|
142
|
+
i0.ɵɵelementEnd();
|
|
42
143
|
} }
|
|
43
|
-
function
|
|
44
|
-
i0.ɵɵ
|
|
45
|
-
i0.ɵɵ
|
|
46
|
-
i0.ɵɵ
|
|
144
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
145
|
+
const _r12 = i0.ɵɵgetCurrentView();
|
|
146
|
+
i0.ɵɵelementStart(0, "button", 44);
|
|
147
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_21_Template_button_click_0_listener($event) { const targetChange_r13 = i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnToggleFormPreview(targetChange_r13, $event)); });
|
|
148
|
+
i0.ɵɵelement(1, "i", 40);
|
|
149
|
+
i0.ɵɵelementEnd();
|
|
150
|
+
i0.ɵɵconditionalCreate(2, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_21_Conditional_2_Template, 2, 0, "button", 45);
|
|
151
|
+
} if (rf & 2) {
|
|
152
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
153
|
+
i0.ɵɵclassProp("active", ctx_r2.IsChangePreviewedInForm(ctx));
|
|
154
|
+
i0.ɵɵadvance(2);
|
|
155
|
+
i0.ɵɵconditional(ctx_r2.AllowRestore ? 2 : -1);
|
|
156
|
+
} }
|
|
157
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
158
|
+
i0.ɵɵelementStart(0, "div", 47);
|
|
159
|
+
i0.ɵɵelement(1, "i", 48);
|
|
160
|
+
i0.ɵɵelementStart(2, "span");
|
|
47
161
|
i0.ɵɵtext(3);
|
|
162
|
+
i0.ɵɵelementEnd()();
|
|
163
|
+
} if (rf & 2) {
|
|
164
|
+
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
165
|
+
i0.ɵɵadvance(3);
|
|
166
|
+
i0.ɵɵtextInterpolate2("No field differences between ", ctx_r2.GetComparisonSlotLabel("base"), " and ", ctx_r2.GetComparisonSlotLabel("target"), ".");
|
|
167
|
+
} }
|
|
168
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_For_10_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
169
|
+
i0.ɵɵelementStart(0, "div", 54);
|
|
170
|
+
i0.ɵɵelement(1, "span", 57);
|
|
171
|
+
i0.ɵɵelementStart(2, "span", 58);
|
|
172
|
+
i0.ɵɵtext(3);
|
|
173
|
+
i0.ɵɵelementEnd();
|
|
174
|
+
i0.ɵɵelement(4, "i", 59)(5, "span", 57);
|
|
175
|
+
i0.ɵɵelementStart(6, "span", 60);
|
|
176
|
+
i0.ɵɵtext(7);
|
|
177
|
+
i0.ɵɵelementEnd()();
|
|
178
|
+
} if (rf & 2) {
|
|
179
|
+
const fc_r15 = i0.ɵɵnextContext().$implicit;
|
|
180
|
+
i0.ɵɵadvance();
|
|
181
|
+
i0.ɵɵclassProp("on", fc_r15.oldValue === "true" || fc_r15.oldValue === "1")("off", fc_r15.oldValue !== "true" && fc_r15.oldValue !== "1");
|
|
182
|
+
i0.ɵɵadvance(2);
|
|
183
|
+
i0.ɵɵtextInterpolate(fc_r15.oldValue === "true" || fc_r15.oldValue === "1" ? "Yes" : "No");
|
|
184
|
+
i0.ɵɵadvance(2);
|
|
185
|
+
i0.ɵɵclassProp("on", fc_r15.newValue === "true" || fc_r15.newValue === "1")("off", fc_r15.newValue !== "true" && fc_r15.newValue !== "1");
|
|
186
|
+
i0.ɵɵadvance();
|
|
187
|
+
i0.ɵɵclassProp("active", fc_r15.newValue === "true" || fc_r15.newValue === "1")("inactive", fc_r15.newValue !== "true" && fc_r15.newValue !== "1");
|
|
188
|
+
i0.ɵɵadvance();
|
|
189
|
+
i0.ɵɵtextInterpolate(fc_r15.newValue === "true" || fc_r15.newValue === "1" ? "Yes" : "No");
|
|
190
|
+
} }
|
|
191
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_For_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
192
|
+
i0.ɵɵelementStart(0, "div", 55)(1, "span", 61);
|
|
193
|
+
i0.ɵɵtext(2);
|
|
194
|
+
i0.ɵɵelementEnd();
|
|
195
|
+
i0.ɵɵelement(3, "i", 59);
|
|
196
|
+
i0.ɵɵelementStart(4, "span", 62);
|
|
197
|
+
i0.ɵɵtext(5);
|
|
198
|
+
i0.ɵɵelementEnd()();
|
|
199
|
+
} if (rf & 2) {
|
|
200
|
+
const fc_r15 = i0.ɵɵnextContext().$implicit;
|
|
201
|
+
i0.ɵɵadvance(2);
|
|
202
|
+
i0.ɵɵtextInterpolate(fc_r15.oldValue || "(empty)");
|
|
203
|
+
i0.ɵɵadvance(3);
|
|
204
|
+
i0.ɵɵtextInterpolate(fc_r15.newValue || "(empty)");
|
|
205
|
+
} }
|
|
206
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_For_10_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
207
|
+
i0.ɵɵelement(0, "div", 56);
|
|
208
|
+
} if (rf & 2) {
|
|
209
|
+
const fc_r15 = i0.ɵɵnextContext().$implicit;
|
|
210
|
+
i0.ɵɵproperty("innerHTML", fc_r15.diffHtml, i0.ɵɵsanitizeHtml);
|
|
211
|
+
} }
|
|
212
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_For_10_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
213
|
+
i0.ɵɵelementStart(0, "div", 55)(1, "span", 61);
|
|
214
|
+
i0.ɵɵtext(2);
|
|
215
|
+
i0.ɵɵelementEnd();
|
|
216
|
+
i0.ɵɵelement(3, "i", 59);
|
|
217
|
+
i0.ɵɵelementStart(4, "span", 62);
|
|
218
|
+
i0.ɵɵtext(5);
|
|
219
|
+
i0.ɵɵelementEnd()();
|
|
220
|
+
} if (rf & 2) {
|
|
221
|
+
const fc_r15 = i0.ɵɵnextContext().$implicit;
|
|
222
|
+
i0.ɵɵadvance(2);
|
|
223
|
+
i0.ɵɵtextInterpolate(fc_r15.oldValue || "(empty)");
|
|
224
|
+
i0.ɵɵadvance(3);
|
|
225
|
+
i0.ɵɵtextInterpolate(fc_r15.newValue || "(empty)");
|
|
226
|
+
} }
|
|
227
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_For_10_Template(rf, ctx) { if (rf & 1) {
|
|
228
|
+
i0.ɵɵelementStart(0, "div", 51)(1, "div", 52);
|
|
229
|
+
i0.ɵɵtext(2);
|
|
48
230
|
i0.ɵɵelementEnd();
|
|
49
|
-
i0.ɵɵelementStart(
|
|
231
|
+
i0.ɵɵelementStart(3, "div", 53);
|
|
232
|
+
i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_For_10_Conditional_4_Template, 8, 14, "div", 54)(5, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_For_10_Conditional_5_Template, 6, 2, "div", 55)(6, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_For_10_Conditional_6_Template, 1, 1, "div", 56)(7, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_For_10_Conditional_7_Template, 6, 2, "div", 55);
|
|
233
|
+
i0.ɵɵelementEnd()();
|
|
234
|
+
} if (rf & 2) {
|
|
235
|
+
const fc_r15 = ctx.$implicit;
|
|
236
|
+
i0.ɵɵadvance(2);
|
|
237
|
+
i0.ɵɵtextInterpolate(fc_r15.displayName);
|
|
238
|
+
i0.ɵɵadvance(2);
|
|
239
|
+
i0.ɵɵconditional(fc_r15.fieldType === "boolean" ? 4 : fc_r15.fieldType === "date" || fc_r15.fieldType === "number" ? 5 : fc_r15.diffHtml ? 6 : 7);
|
|
240
|
+
} }
|
|
241
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
242
|
+
i0.ɵɵelementStart(0, "div", 49)(1, "span");
|
|
243
|
+
i0.ɵɵtext(2);
|
|
244
|
+
i0.ɵɵelementStart(3, "strong");
|
|
245
|
+
i0.ɵɵtext(4, "vA");
|
|
246
|
+
i0.ɵɵelementEnd();
|
|
247
|
+
i0.ɵɵtext(5, " and ");
|
|
248
|
+
i0.ɵɵelementStart(6, "strong");
|
|
249
|
+
i0.ɵɵtext(7, "vB");
|
|
250
|
+
i0.ɵɵelementEnd()()();
|
|
251
|
+
i0.ɵɵelementStart(8, "div", 50);
|
|
252
|
+
i0.ɵɵrepeaterCreate(9, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_For_10_Template, 8, 2, "div", 51, _forTrack2);
|
|
253
|
+
i0.ɵɵelementEnd();
|
|
254
|
+
} if (rf & 2) {
|
|
255
|
+
const compDiffs_r16 = i0.ɵɵnextContext();
|
|
256
|
+
i0.ɵɵadvance(2);
|
|
257
|
+
i0.ɵɵtextInterpolate2("", compDiffs_r16.length, " field", compDiffs_r16.length !== 1 ? "s" : "", " differ between ");
|
|
258
|
+
i0.ɵɵadvance(7);
|
|
259
|
+
i0.ɵɵrepeater(compDiffs_r16);
|
|
260
|
+
} }
|
|
261
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
262
|
+
i0.ɵɵconditionalCreate(0, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_0_Template, 4, 2, "div", 47)(1, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Conditional_1_Template, 11, 2);
|
|
263
|
+
} if (rf & 2) {
|
|
264
|
+
i0.ɵɵconditional(ctx.length === 0 ? 0 : 1);
|
|
265
|
+
} }
|
|
266
|
+
function RecordChangesComponent_Conditional_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
267
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
268
|
+
i0.ɵɵelementStart(0, "div", 17)(1, "div", 29)(2, "div", 30)(3, "span", 31);
|
|
269
|
+
i0.ɵɵtext(4, "vA \u00B7 Base");
|
|
270
|
+
i0.ɵɵelementEnd();
|
|
271
|
+
i0.ɵɵelementStart(5, "select", 32);
|
|
272
|
+
i0.ɵɵlistener("change", function RecordChangesComponent_Conditional_2_Conditional_17_Template_select_change_5_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnComparisonSelectChange("base", $event)); });
|
|
273
|
+
i0.ɵɵelementStart(6, "option", 33);
|
|
274
|
+
i0.ɵɵtext(7, "Current Live Record");
|
|
275
|
+
i0.ɵɵelementEnd();
|
|
276
|
+
i0.ɵɵrepeaterCreate(8, RecordChangesComponent_Conditional_2_Conditional_17_For_9_Template, 2, 4, "option", 34, _forTrack1);
|
|
277
|
+
i0.ɵɵelementEnd();
|
|
278
|
+
i0.ɵɵconditionalCreate(10, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_10_Template, 3, 3);
|
|
279
|
+
i0.ɵɵelementEnd();
|
|
280
|
+
i0.ɵɵelementStart(11, "button", 35);
|
|
281
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_17_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SwapComparisonVersions()); });
|
|
282
|
+
i0.ɵɵelement(12, "i", 36);
|
|
283
|
+
i0.ɵɵelementEnd();
|
|
284
|
+
i0.ɵɵelementStart(13, "div", 30)(14, "span", 37);
|
|
285
|
+
i0.ɵɵtext(15, "vB \u00B7 Target");
|
|
286
|
+
i0.ɵɵelementEnd();
|
|
287
|
+
i0.ɵɵelementStart(16, "select", 38);
|
|
288
|
+
i0.ɵɵlistener("change", function RecordChangesComponent_Conditional_2_Conditional_17_Template_select_change_16_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnComparisonSelectChange("target", $event)); });
|
|
289
|
+
i0.ɵɵelementStart(17, "option", 33);
|
|
290
|
+
i0.ɵɵtext(18, "Current Live Record");
|
|
291
|
+
i0.ɵɵelementEnd();
|
|
292
|
+
i0.ɵɵrepeaterCreate(19, RecordChangesComponent_Conditional_2_Conditional_17_For_20_Template, 2, 4, "option", 34, _forTrack1);
|
|
293
|
+
i0.ɵɵelementEnd();
|
|
294
|
+
i0.ɵɵconditionalCreate(21, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_21_Template, 3, 3);
|
|
295
|
+
i0.ɵɵelementEnd()();
|
|
296
|
+
i0.ɵɵconditionalCreate(22, RecordChangesComponent_Conditional_2_Conditional_17_Conditional_22_Template, 2, 1);
|
|
297
|
+
i0.ɵɵelementEnd();
|
|
298
|
+
} if (rf & 2) {
|
|
299
|
+
let tmp_5_0;
|
|
300
|
+
let tmp_9_0;
|
|
301
|
+
let tmp_10_0;
|
|
302
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
303
|
+
i0.ɵɵadvance(5);
|
|
304
|
+
i0.ɵɵproperty("value", ctx_r2.CompareBaseChangeID ?? "");
|
|
305
|
+
i0.ɵɵadvance();
|
|
306
|
+
i0.ɵɵproperty("selected", ctx_r2.CompareBaseChangeID === "__CURRENT__");
|
|
307
|
+
i0.ɵɵadvance(2);
|
|
308
|
+
i0.ɵɵrepeater(ctx_r2.GetPreviewableChanges());
|
|
309
|
+
i0.ɵɵadvance(2);
|
|
310
|
+
i0.ɵɵconditional((tmp_5_0 = ctx_r2.CompareBaseChange) ? 10 : -1, tmp_5_0);
|
|
311
|
+
i0.ɵɵadvance(6);
|
|
312
|
+
i0.ɵɵproperty("value", ctx_r2.CompareTargetChangeID ?? "");
|
|
313
|
+
i0.ɵɵadvance();
|
|
314
|
+
i0.ɵɵproperty("selected", ctx_r2.CompareTargetChangeID === "__CURRENT__");
|
|
315
|
+
i0.ɵɵadvance(2);
|
|
316
|
+
i0.ɵɵrepeater(ctx_r2.GetPreviewableChanges());
|
|
317
|
+
i0.ɵɵadvance(2);
|
|
318
|
+
i0.ɵɵconditional((tmp_9_0 = ctx_r2.CompareTargetChange) ? 21 : -1, tmp_9_0);
|
|
319
|
+
i0.ɵɵadvance();
|
|
320
|
+
i0.ɵɵconditional((tmp_10_0 = ctx_r2.GetComparisonDiffs()) ? 22 : -1, tmp_10_0);
|
|
321
|
+
} }
|
|
322
|
+
function RecordChangesComponent_Conditional_2_Conditional_18_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
323
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
324
|
+
i0.ɵɵelement(1, "i", 65);
|
|
325
|
+
i0.ɵɵelementStart(2, "span", 66);
|
|
326
|
+
i0.ɵɵtext(3);
|
|
327
|
+
i0.ɵɵelementEnd();
|
|
328
|
+
i0.ɵɵelementStart(4, "span", 67)(5, "span", 68);
|
|
50
329
|
i0.ɵɵtext(6);
|
|
51
330
|
i0.ɵɵelementEnd();
|
|
52
|
-
i0.ɵɵelementStart(7, "span",
|
|
331
|
+
i0.ɵɵelementStart(7, "span", 69);
|
|
53
332
|
i0.ɵɵtext(8);
|
|
54
333
|
i0.ɵɵelementEnd()()();
|
|
55
334
|
} if (rf & 2) {
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
i0.ɵɵproperty("title",
|
|
335
|
+
const label_r17 = ctx.$implicit;
|
|
336
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
337
|
+
i0.ɵɵproperty("title", label_r17.Description || label_r17.Name);
|
|
59
338
|
i0.ɵɵadvance(3);
|
|
60
|
-
i0.ɵɵtextInterpolate(
|
|
339
|
+
i0.ɵɵtextInterpolate(label_r17.Name);
|
|
61
340
|
i0.ɵɵadvance(2);
|
|
62
|
-
i0.ɵɵclassMap(
|
|
341
|
+
i0.ɵɵclassMap(ctx_r2.getLabelStatusClass(label_r17.Status));
|
|
63
342
|
i0.ɵɵadvance();
|
|
64
|
-
i0.ɵɵtextInterpolate(
|
|
343
|
+
i0.ɵɵtextInterpolate(label_r17.Status);
|
|
65
344
|
i0.ɵɵadvance(2);
|
|
66
|
-
i0.ɵɵtextInterpolate2("",
|
|
345
|
+
i0.ɵɵtextInterpolate2("", label_r17.ItemCount, " item", label_r17.ItemCount !== 1 ? "s" : "");
|
|
67
346
|
} }
|
|
68
|
-
function
|
|
69
|
-
i0.ɵɵelementStart(0, "div",
|
|
70
|
-
i0.ɵɵrepeaterCreate(
|
|
71
|
-
i0.ɵɵelementEnd();
|
|
347
|
+
function RecordChangesComponent_Conditional_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
348
|
+
i0.ɵɵelementStart(0, "div", 18)(1, "div", 63);
|
|
349
|
+
i0.ɵɵrepeaterCreate(2, RecordChangesComponent_Conditional_2_Conditional_18_For_3_Template, 9, 7, "div", 64, _forTrack1);
|
|
350
|
+
i0.ɵɵelementEnd()();
|
|
72
351
|
} if (rf & 2) {
|
|
73
|
-
const
|
|
74
|
-
i0.ɵɵadvance();
|
|
75
|
-
i0.ɵɵrepeater(
|
|
352
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
353
|
+
i0.ɵɵadvance(2);
|
|
354
|
+
i0.ɵɵrepeater(ctx_r2.RecordLabels);
|
|
76
355
|
} }
|
|
77
|
-
function
|
|
78
|
-
i0.ɵɵelementStart(0, "mj-empty-state",
|
|
79
|
-
i0.ɵɵelement(2, "i",
|
|
356
|
+
function RecordChangesComponent_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
357
|
+
i0.ɵɵelementStart(0, "mj-empty-state", 19)(1, "div", 70);
|
|
358
|
+
i0.ɵɵelement(2, "i", 71);
|
|
80
359
|
i0.ɵɵelementStart(3, "span");
|
|
81
360
|
i0.ɵɵtext(4, "Record change tracking is managed at the entity level");
|
|
82
361
|
i0.ɵɵelementEnd()()();
|
|
83
362
|
} }
|
|
84
|
-
function
|
|
85
|
-
const
|
|
86
|
-
i0.ɵɵelementStart(0, "button",
|
|
87
|
-
i0.ɵɵlistener("click", function
|
|
88
|
-
i0.ɵɵelement(1, "i",
|
|
363
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_0_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
364
|
+
const _r19 = i0.ɵɵgetCurrentView();
|
|
365
|
+
i0.ɵɵelementStart(0, "button", 77);
|
|
366
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_0_For_1_Template_button_click_0_listener() { const pill_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.TogglePill(pill_r20.Key)); });
|
|
367
|
+
i0.ɵɵelement(1, "i", 9);
|
|
89
368
|
i0.ɵɵtext(2);
|
|
90
|
-
i0.ɵɵelementStart(3, "span",
|
|
369
|
+
i0.ɵɵelementStart(3, "span", 84);
|
|
91
370
|
i0.ɵɵtext(4);
|
|
92
371
|
i0.ɵɵelementEnd()();
|
|
93
372
|
} if (rf & 2) {
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
i0.ɵɵclassProp("active",
|
|
373
|
+
const pill_r20 = ctx.$implicit;
|
|
374
|
+
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
375
|
+
i0.ɵɵclassProp("active", ctx_r2.ChipSelections[pill_r20.Key])("rc-filter-pill-restore", pill_r20.Variant === "restore");
|
|
97
376
|
i0.ɵɵadvance();
|
|
98
|
-
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fa-solid ",
|
|
377
|
+
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fa-solid ", pill_r20.Icon));
|
|
99
378
|
i0.ɵɵadvance();
|
|
100
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
379
|
+
i0.ɵɵtextInterpolate1(" ", pill_r20.Label, " ");
|
|
101
380
|
i0.ɵɵadvance(2);
|
|
102
|
-
i0.ɵɵtextInterpolate(
|
|
381
|
+
i0.ɵɵtextInterpolate(pill_r20.Count);
|
|
103
382
|
} }
|
|
104
|
-
function
|
|
105
|
-
i0.ɵɵrepeaterCreate(0,
|
|
383
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
384
|
+
i0.ɵɵrepeaterCreate(0, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_0_For_1_Template, 5, 9, "button", 83, _forTrack3);
|
|
106
385
|
} if (rf & 2) {
|
|
107
|
-
const
|
|
108
|
-
i0.ɵɵrepeater(
|
|
386
|
+
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
387
|
+
i0.ɵɵrepeater(ctx_r2.ConditionalPills);
|
|
109
388
|
} }
|
|
110
|
-
function
|
|
111
|
-
i0.ɵɵelementStart(0, "span",
|
|
389
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
390
|
+
i0.ɵɵelementStart(0, "span", 84);
|
|
112
391
|
i0.ɵɵtext(1);
|
|
113
392
|
i0.ɵɵelementEnd();
|
|
114
393
|
} if (rf & 2) {
|
|
115
|
-
const
|
|
394
|
+
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
116
395
|
i0.ɵɵadvance();
|
|
117
|
-
i0.ɵɵtextInterpolate(
|
|
396
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedConditionalCount);
|
|
118
397
|
} }
|
|
119
|
-
function
|
|
120
|
-
const
|
|
121
|
-
i0.ɵɵelementStart(0, "label",
|
|
122
|
-
i0.ɵɵlistener("change", function
|
|
398
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Conditional_6_For_5_Template(rf, ctx) { if (rf & 1) {
|
|
399
|
+
const _r23 = i0.ɵɵgetCurrentView();
|
|
400
|
+
i0.ɵɵelementStart(0, "label", 95)(1, "input", 96);
|
|
401
|
+
i0.ɵɵlistener("change", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Conditional_6_For_5_Template_input_change_1_listener() { const pill_r24 = i0.ɵɵrestoreView(_r23).$implicit; const ctx_r2 = i0.ɵɵnextContext(6); return i0.ɵɵresetView(ctx_r2.TogglePill(pill_r24.Key)); });
|
|
123
402
|
i0.ɵɵelementEnd();
|
|
124
|
-
i0.ɵɵelement(2, "i",
|
|
125
|
-
i0.ɵɵelementStart(3, "span",
|
|
403
|
+
i0.ɵɵelement(2, "i", 9);
|
|
404
|
+
i0.ɵɵelementStart(3, "span", 97);
|
|
126
405
|
i0.ɵɵtext(4);
|
|
127
406
|
i0.ɵɵelementEnd();
|
|
128
|
-
i0.ɵɵelementStart(5, "span",
|
|
407
|
+
i0.ɵɵelementStart(5, "span", 98);
|
|
129
408
|
i0.ɵɵtext(6);
|
|
130
409
|
i0.ɵɵelementEnd()();
|
|
131
410
|
} if (rf & 2) {
|
|
132
|
-
const
|
|
133
|
-
const
|
|
134
|
-
i0.ɵɵclassProp("rc-filter-overflow-row-restore",
|
|
411
|
+
const pill_r24 = ctx.$implicit;
|
|
412
|
+
const ctx_r2 = i0.ɵɵnextContext(6);
|
|
413
|
+
i0.ɵɵclassProp("rc-filter-overflow-row-restore", pill_r24.Variant === "restore");
|
|
135
414
|
i0.ɵɵadvance();
|
|
136
|
-
i0.ɵɵproperty("checked",
|
|
415
|
+
i0.ɵɵproperty("checked", ctx_r2.ChipSelections[pill_r24.Key]);
|
|
137
416
|
i0.ɵɵadvance();
|
|
138
|
-
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fa-solid ",
|
|
417
|
+
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fa-solid ", pill_r24.Icon));
|
|
139
418
|
i0.ɵɵadvance(2);
|
|
140
|
-
i0.ɵɵtextInterpolate(
|
|
419
|
+
i0.ɵɵtextInterpolate(pill_r24.Label);
|
|
141
420
|
i0.ɵɵadvance(2);
|
|
142
|
-
i0.ɵɵtextInterpolate(
|
|
421
|
+
i0.ɵɵtextInterpolate(pill_r24.Count);
|
|
143
422
|
} }
|
|
144
|
-
function
|
|
145
|
-
const
|
|
146
|
-
i0.ɵɵelementStart(0, "div",
|
|
147
|
-
i0.ɵɵlistener("click", function
|
|
423
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
424
|
+
const _r22 = i0.ɵɵgetCurrentView();
|
|
425
|
+
i0.ɵɵelementStart(0, "div", 88);
|
|
426
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Conditional_6_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.CloseFilterOverflow()); });
|
|
148
427
|
i0.ɵɵelementEnd();
|
|
149
|
-
i0.ɵɵelementStart(1, "div",
|
|
428
|
+
i0.ɵɵelementStart(1, "div", 89)(2, "div", 90);
|
|
150
429
|
i0.ɵɵtext(3, "Filter by");
|
|
151
430
|
i0.ɵɵelementEnd();
|
|
152
|
-
i0.ɵɵrepeaterCreate(4,
|
|
153
|
-
i0.ɵɵelementStart(6, "div",
|
|
154
|
-
i0.ɵɵlistener("click", function
|
|
431
|
+
i0.ɵɵrepeaterCreate(4, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Conditional_6_For_5_Template, 7, 8, "label", 91, _forTrack3);
|
|
432
|
+
i0.ɵɵelementStart(6, "div", 92)(7, "button", 93);
|
|
433
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Conditional_6_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(5); ctx_r2.SelectAllPill(); return i0.ɵɵresetView(ctx_r2.CloseFilterOverflow()); });
|
|
155
434
|
i0.ɵɵtext(8, " Clear all ");
|
|
156
435
|
i0.ɵɵelementEnd();
|
|
157
|
-
i0.ɵɵelementStart(9, "button",
|
|
158
|
-
i0.ɵɵlistener("click", function
|
|
436
|
+
i0.ɵɵelementStart(9, "button", 94);
|
|
437
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Conditional_6_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.CloseFilterOverflow()); });
|
|
159
438
|
i0.ɵɵtext(10, " Done ");
|
|
160
439
|
i0.ɵɵelementEnd()()();
|
|
161
440
|
} if (rf & 2) {
|
|
162
|
-
const
|
|
441
|
+
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
163
442
|
i0.ɵɵadvance(4);
|
|
164
|
-
i0.ɵɵrepeater(
|
|
443
|
+
i0.ɵɵrepeater(ctx_r2.ConditionalPills);
|
|
165
444
|
} }
|
|
166
|
-
function
|
|
167
|
-
const
|
|
168
|
-
i0.ɵɵelementStart(0, "div",
|
|
169
|
-
i0.ɵɵlistener("click", function
|
|
170
|
-
i0.ɵɵelement(2, "i",
|
|
445
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
446
|
+
const _r21 = i0.ɵɵgetCurrentView();
|
|
447
|
+
i0.ɵɵelementStart(0, "div", 82)(1, "button", 85);
|
|
448
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r21); const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.ToggleFilterOverflow()); });
|
|
449
|
+
i0.ɵɵelement(2, "i", 86);
|
|
171
450
|
i0.ɵɵtext(3, " More filters ");
|
|
172
|
-
i0.ɵɵconditionalCreate(4,
|
|
173
|
-
i0.ɵɵelement(5, "i",
|
|
451
|
+
i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Conditional_4_Template, 2, 1, "span", 84);
|
|
452
|
+
i0.ɵɵelement(5, "i", 87);
|
|
174
453
|
i0.ɵɵelementEnd();
|
|
175
|
-
i0.ɵɵconditionalCreate(6,
|
|
454
|
+
i0.ɵɵconditionalCreate(6, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Conditional_6_Template, 11, 0);
|
|
176
455
|
i0.ɵɵelementEnd();
|
|
177
456
|
} if (rf & 2) {
|
|
178
|
-
const
|
|
457
|
+
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
179
458
|
i0.ɵɵadvance();
|
|
180
|
-
i0.ɵɵclassProp("active",
|
|
459
|
+
i0.ɵɵclassProp("active", ctx_r2.SelectedConditionalCount > 0);
|
|
181
460
|
i0.ɵɵadvance(3);
|
|
182
|
-
i0.ɵɵconditional(
|
|
461
|
+
i0.ɵɵconditional(ctx_r2.SelectedConditionalCount > 0 ? 4 : -1);
|
|
183
462
|
i0.ɵɵadvance(2);
|
|
184
|
-
i0.ɵɵconditional(
|
|
463
|
+
i0.ɵɵconditional(ctx_r2.ShowFilterOverflow ? 6 : -1);
|
|
185
464
|
} }
|
|
186
|
-
function
|
|
187
|
-
i0.ɵɵconditionalCreate(0,
|
|
465
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
466
|
+
i0.ɵɵconditionalCreate(0, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_0_Template, 2, 0)(1, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Conditional_1_Template, 7, 4, "div", 82);
|
|
188
467
|
} if (rf & 2) {
|
|
189
|
-
const
|
|
190
|
-
i0.ɵɵconditional(!
|
|
468
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
469
|
+
i0.ɵɵconditional(!ctx_r2.UseOverflowPopover ? 0 : 1);
|
|
191
470
|
} }
|
|
192
|
-
function
|
|
193
|
-
const
|
|
194
|
-
i0.ɵɵelementStart(0, "div",
|
|
471
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
472
|
+
const _r25 = i0.ɵɵgetCurrentView();
|
|
473
|
+
i0.ɵɵelementStart(0, "div", 79);
|
|
195
474
|
i0.ɵɵtext(1);
|
|
196
|
-
i0.ɵɵelementStart(2, "button",
|
|
197
|
-
i0.ɵɵlistener("click", function
|
|
475
|
+
i0.ɵɵelementStart(2, "button", 99);
|
|
476
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_9_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r25); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.ClearFilters()); });
|
|
198
477
|
i0.ɵɵtext(3, "Clear filters");
|
|
199
478
|
i0.ɵɵelementEnd()();
|
|
200
479
|
} if (rf & 2) {
|
|
201
|
-
const
|
|
480
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
202
481
|
i0.ɵɵadvance();
|
|
203
|
-
i0.ɵɵtextInterpolate2(" Showing ",
|
|
482
|
+
i0.ɵɵtextInterpolate2(" Showing ", ctx_r2.filteredData.length, " of ", ctx_r2.viewData.length, " changes ");
|
|
204
483
|
} }
|
|
205
|
-
function
|
|
206
|
-
const
|
|
207
|
-
i0.ɵɵelementStart(0, "mj-empty-state",
|
|
208
|
-
i0.ɵɵlistener("Action", function
|
|
484
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
485
|
+
const _r26 = i0.ɵɵgetCurrentView();
|
|
486
|
+
i0.ɵɵelementStart(0, "mj-empty-state", 100);
|
|
487
|
+
i0.ɵɵlistener("Action", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_11_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.ClearFilters()); });
|
|
488
|
+
i0.ɵɵelementEnd();
|
|
489
|
+
} }
|
|
490
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
491
|
+
i0.ɵɵelementStart(0, "span", 109);
|
|
492
|
+
i0.ɵɵelement(1, "i", 40);
|
|
493
|
+
i0.ɵɵtext(2, " Previewing in form ");
|
|
209
494
|
i0.ɵɵelementEnd();
|
|
210
495
|
} }
|
|
211
|
-
function
|
|
496
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_8_Conditional_0_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
212
497
|
i0.ɵɵtext(0);
|
|
213
498
|
} if (rf & 2) {
|
|
214
|
-
const
|
|
215
|
-
const
|
|
216
|
-
i0.ɵɵtextInterpolate1(" by ",
|
|
499
|
+
const srcChange_r30 = i0.ɵɵnextContext();
|
|
500
|
+
const ctx_r2 = i0.ɵɵnextContext(7);
|
|
501
|
+
i0.ɵɵtextInterpolate1(" by ", ctx_r2.getUserDisplayName(srcChange_r30.User), " ");
|
|
217
502
|
} }
|
|
218
|
-
function
|
|
219
|
-
const
|
|
220
|
-
i0.ɵɵelementStart(0, "a",
|
|
221
|
-
i0.ɵɵlistener("click", function
|
|
222
|
-
i0.ɵɵelement(1, "i",
|
|
503
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_8_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
504
|
+
const _r29 = i0.ɵɵgetCurrentView();
|
|
505
|
+
i0.ɵɵelementStart(0, "a", 121);
|
|
506
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_8_Conditional_0_Template_a_click_0_listener($event) { const srcChange_r30 = i0.ɵɵrestoreView(_r29); const ctx_r2 = i0.ɵɵnextContext(7); return i0.ɵɵresetView(ctx_r2.JumpToSourceChange(srcChange_r30, $event)); });
|
|
507
|
+
i0.ɵɵelement(1, "i", 122);
|
|
223
508
|
i0.ɵɵtext(2);
|
|
224
509
|
i0.ɵɵpipe(3, "date");
|
|
225
|
-
i0.ɵɵconditionalCreate(4,
|
|
510
|
+
i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_8_Conditional_0_Conditional_4_Template, 1, 1);
|
|
226
511
|
i0.ɵɵelementEnd();
|
|
227
512
|
} if (rf & 2) {
|
|
228
|
-
const
|
|
229
|
-
const
|
|
230
|
-
i0.ɵɵproperty("title", "Jump to source version (" +
|
|
513
|
+
const srcChange_r30 = ctx;
|
|
514
|
+
const ctx_r2 = i0.ɵɵnextContext(7);
|
|
515
|
+
i0.ɵɵproperty("title", "Jump to source version (" + ctx_r2.formatFullDateTime(srcChange_r30.ChangedAt) + ")");
|
|
231
516
|
i0.ɵɵadvance(2);
|
|
232
|
-
i0.ɵɵtextInterpolate2(" Restored from ",
|
|
517
|
+
i0.ɵɵtextInterpolate2(" Restored from ", ctx_r2.formatTime(srcChange_r30.ChangedAt), " ", srcChange_r30.ChangedAt ? "on " + i0.ɵɵpipeBind2(3, 4, srcChange_r30.ChangedAt, "mediumDate") : "", " ");
|
|
233
518
|
i0.ɵɵadvance(2);
|
|
234
|
-
i0.ɵɵconditional(
|
|
519
|
+
i0.ɵɵconditional(srcChange_r30.User ? 4 : -1);
|
|
235
520
|
} }
|
|
236
|
-
function
|
|
237
|
-
i0.ɵɵelementStart(0, "span",
|
|
238
|
-
i0.ɵɵelement(1, "i",
|
|
521
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_8_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
522
|
+
i0.ɵɵelementStart(0, "span", 120);
|
|
523
|
+
i0.ɵɵelement(1, "i", 43);
|
|
239
524
|
i0.ɵɵtext(2, " Restored from earlier version ");
|
|
240
525
|
i0.ɵɵelementEnd();
|
|
241
526
|
} }
|
|
242
|
-
function
|
|
243
|
-
i0.ɵɵconditionalCreate(0,
|
|
527
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
528
|
+
i0.ɵɵconditionalCreate(0, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_8_Conditional_0_Template, 5, 7, "a", 119)(1, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_8_Conditional_1_Template, 3, 0, "span", 120);
|
|
244
529
|
} if (rf & 2) {
|
|
245
530
|
let tmp_24_0;
|
|
246
|
-
const
|
|
247
|
-
const
|
|
248
|
-
i0.ɵɵconditional((tmp_24_0 =
|
|
531
|
+
const change_r28 = i0.ɵɵnextContext().$implicit;
|
|
532
|
+
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
533
|
+
i0.ɵɵconditional((tmp_24_0 = ctx_r2.getRestoredFromSourceChange(change_r28)) ? 0 : 1, tmp_24_0);
|
|
249
534
|
} }
|
|
250
|
-
function
|
|
251
|
-
i0.ɵɵ
|
|
535
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
536
|
+
const _r31 = i0.ɵɵgetCurrentView();
|
|
537
|
+
i0.ɵɵelementStart(0, "div", 111)(1, "button", 123);
|
|
538
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_10_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r31); const change_r28 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.SelectForComparison("base", change_r28.ID, $event)); });
|
|
539
|
+
i0.ɵɵtext(2, " A ");
|
|
540
|
+
i0.ɵɵelementEnd();
|
|
541
|
+
i0.ɵɵelementStart(3, "button", 124);
|
|
542
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_10_Template_button_click_3_listener($event) { i0.ɵɵrestoreView(_r31); const change_r28 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.SelectForComparison("target", change_r28.ID, $event)); });
|
|
543
|
+
i0.ɵɵtext(4, " B ");
|
|
544
|
+
i0.ɵɵelementEnd()();
|
|
545
|
+
} if (rf & 2) {
|
|
546
|
+
const change_r28 = i0.ɵɵnextContext().$implicit;
|
|
547
|
+
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
548
|
+
i0.ɵɵadvance();
|
|
549
|
+
i0.ɵɵclassProp("active", ctx_r2.IsChangeSelectedAsCompareBase(change_r28));
|
|
550
|
+
i0.ɵɵadvance(2);
|
|
551
|
+
i0.ɵɵclassProp("active", ctx_r2.IsChangeSelectedAsCompareTarget(change_r28));
|
|
552
|
+
} }
|
|
553
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
554
|
+
i0.ɵɵelementStart(0, "blockquote", 125)(1, "span", 130);
|
|
252
555
|
i0.ɵɵtext(2, "Reason");
|
|
253
556
|
i0.ɵɵelementEnd();
|
|
254
|
-
i0.ɵɵelementStart(3, "span",
|
|
557
|
+
i0.ɵɵelementStart(3, "span", 131);
|
|
255
558
|
i0.ɵɵtext(4);
|
|
256
559
|
i0.ɵɵelementEnd()();
|
|
257
560
|
} if (rf & 2) {
|
|
258
561
|
i0.ɵɵadvance(4);
|
|
259
562
|
i0.ɵɵtextInterpolate(ctx);
|
|
260
563
|
} }
|
|
261
|
-
function
|
|
262
|
-
i0.ɵɵelementStart(0, "div",
|
|
564
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_2_Conditional_0_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
565
|
+
i0.ɵɵelementStart(0, "div", 51)(1, "div", 52);
|
|
263
566
|
i0.ɵɵtext(2);
|
|
264
567
|
i0.ɵɵelementEnd();
|
|
265
|
-
i0.ɵɵelementStart(3, "div",
|
|
568
|
+
i0.ɵɵelementStart(3, "div", 53)(4, "span", 62);
|
|
266
569
|
i0.ɵɵtext(5);
|
|
267
570
|
i0.ɵɵelementEnd()()();
|
|
268
571
|
} if (rf & 2) {
|
|
269
|
-
const
|
|
572
|
+
const field_r32 = ctx.$implicit;
|
|
270
573
|
i0.ɵɵadvance(2);
|
|
271
|
-
i0.ɵɵtextInterpolate(
|
|
574
|
+
i0.ɵɵtextInterpolate(field_r32.displayName);
|
|
272
575
|
i0.ɵɵadvance(3);
|
|
273
|
-
i0.ɵɵtextInterpolate(
|
|
576
|
+
i0.ɵɵtextInterpolate(field_r32.value);
|
|
274
577
|
} }
|
|
275
|
-
function
|
|
276
|
-
i0.ɵɵrepeaterCreate(0,
|
|
578
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
579
|
+
i0.ɵɵrepeaterCreate(0, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_2_Conditional_0_For_1_Template, 6, 2, "div", 51, _forTrack5);
|
|
277
580
|
} if (rf & 2) {
|
|
278
|
-
const
|
|
279
|
-
const
|
|
280
|
-
i0.ɵɵrepeater(
|
|
581
|
+
const change_r28 = i0.ɵɵnextContext(3).$implicit;
|
|
582
|
+
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
583
|
+
i0.ɵɵrepeater(ctx_r2.getCreatedFields(change_r28));
|
|
281
584
|
} }
|
|
282
|
-
function
|
|
283
|
-
i0.ɵɵconditionalCreate(0,
|
|
585
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
586
|
+
i0.ɵɵconditionalCreate(0, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_2_Conditional_0_Template, 2, 0);
|
|
284
587
|
} if (rf & 2) {
|
|
285
|
-
const
|
|
286
|
-
i0.ɵɵconditional(
|
|
588
|
+
const change_r28 = i0.ɵɵnextContext(2).$implicit;
|
|
589
|
+
i0.ɵɵconditional(change_r28.FullRecordJSON ? 0 : -1);
|
|
287
590
|
} }
|
|
288
|
-
function
|
|
289
|
-
i0.ɵɵelementStart(0, "div",
|
|
290
|
-
i0.ɵɵelement(1, "i",
|
|
591
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
592
|
+
i0.ɵɵelementStart(0, "div", 126);
|
|
593
|
+
i0.ɵɵelement(1, "i", 132);
|
|
291
594
|
i0.ɵɵtext(2, " This record was permanently removed from the system. ");
|
|
292
595
|
i0.ɵɵelementEnd();
|
|
293
596
|
} }
|
|
294
|
-
function
|
|
295
|
-
i0.ɵɵelementStart(0, "div",
|
|
296
|
-
i0.ɵɵelement(1, "span",
|
|
297
|
-
i0.ɵɵelementStart(2, "span",
|
|
597
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_For_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
598
|
+
i0.ɵɵelementStart(0, "div", 54);
|
|
599
|
+
i0.ɵɵelement(1, "span", 57);
|
|
600
|
+
i0.ɵɵelementStart(2, "span", 58);
|
|
298
601
|
i0.ɵɵtext(3);
|
|
299
602
|
i0.ɵɵelementEnd();
|
|
300
|
-
i0.ɵɵelement(4, "i",
|
|
301
|
-
i0.ɵɵelementStart(6, "span",
|
|
603
|
+
i0.ɵɵelement(4, "i", 59)(5, "span", 57);
|
|
604
|
+
i0.ɵɵelementStart(6, "span", 60);
|
|
302
605
|
i0.ɵɵtext(7);
|
|
303
606
|
i0.ɵɵelementEnd()();
|
|
304
607
|
} if (rf & 2) {
|
|
305
|
-
const
|
|
608
|
+
const fc_r33 = i0.ɵɵnextContext().$implicit;
|
|
306
609
|
i0.ɵɵadvance();
|
|
307
|
-
i0.ɵɵclassProp("on",
|
|
610
|
+
i0.ɵɵclassProp("on", fc_r33.oldValue === "true" || fc_r33.oldValue === "1")("off", fc_r33.oldValue !== "true" && fc_r33.oldValue !== "1");
|
|
308
611
|
i0.ɵɵadvance(2);
|
|
309
|
-
i0.ɵɵtextInterpolate(
|
|
612
|
+
i0.ɵɵtextInterpolate(fc_r33.oldValue === "true" || fc_r33.oldValue === "1" ? "Yes" : "No");
|
|
310
613
|
i0.ɵɵadvance(2);
|
|
311
|
-
i0.ɵɵclassProp("on",
|
|
614
|
+
i0.ɵɵclassProp("on", fc_r33.newValue === "true" || fc_r33.newValue === "1")("off", fc_r33.newValue !== "true" && fc_r33.newValue !== "1");
|
|
312
615
|
i0.ɵɵadvance();
|
|
313
|
-
i0.ɵɵclassProp("active",
|
|
616
|
+
i0.ɵɵclassProp("active", fc_r33.newValue === "true" || fc_r33.newValue === "1")("inactive", fc_r33.newValue !== "true" && fc_r33.newValue !== "1");
|
|
314
617
|
i0.ɵɵadvance();
|
|
315
|
-
i0.ɵɵtextInterpolate(
|
|
618
|
+
i0.ɵɵtextInterpolate(fc_r33.newValue === "true" || fc_r33.newValue === "1" ? "Yes" : "No");
|
|
316
619
|
} }
|
|
317
|
-
function
|
|
318
|
-
i0.ɵɵelementStart(0, "div",
|
|
620
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_For_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
621
|
+
i0.ɵɵelementStart(0, "div", 55)(1, "span", 61);
|
|
319
622
|
i0.ɵɵtext(2);
|
|
320
623
|
i0.ɵɵelementEnd();
|
|
321
|
-
i0.ɵɵelement(3, "i",
|
|
322
|
-
i0.ɵɵelementStart(4, "span",
|
|
624
|
+
i0.ɵɵelement(3, "i", 59);
|
|
625
|
+
i0.ɵɵelementStart(4, "span", 62);
|
|
323
626
|
i0.ɵɵtext(5);
|
|
324
627
|
i0.ɵɵelementEnd()();
|
|
325
628
|
} if (rf & 2) {
|
|
326
|
-
const
|
|
629
|
+
const fc_r33 = i0.ɵɵnextContext().$implicit;
|
|
327
630
|
i0.ɵɵadvance(2);
|
|
328
|
-
i0.ɵɵtextInterpolate(
|
|
631
|
+
i0.ɵɵtextInterpolate(fc_r33.oldValue || "(empty)");
|
|
329
632
|
i0.ɵɵadvance(3);
|
|
330
|
-
i0.ɵɵtextInterpolate(
|
|
633
|
+
i0.ɵɵtextInterpolate(fc_r33.newValue || "(empty)");
|
|
331
634
|
} }
|
|
332
|
-
function
|
|
333
|
-
i0.ɵɵelement(0, "div",
|
|
635
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_For_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
636
|
+
i0.ɵɵelement(0, "div", 56);
|
|
334
637
|
} if (rf & 2) {
|
|
335
|
-
const
|
|
336
|
-
i0.ɵɵproperty("innerHTML",
|
|
638
|
+
const fc_r33 = i0.ɵɵnextContext().$implicit;
|
|
639
|
+
i0.ɵɵproperty("innerHTML", fc_r33.diffHtml, i0.ɵɵsanitizeHtml);
|
|
337
640
|
} }
|
|
338
|
-
function
|
|
339
|
-
i0.ɵɵelementStart(0, "div",
|
|
641
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_For_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
642
|
+
i0.ɵɵelementStart(0, "div", 55)(1, "span", 61);
|
|
340
643
|
i0.ɵɵtext(2);
|
|
341
644
|
i0.ɵɵelementEnd();
|
|
342
|
-
i0.ɵɵelement(3, "i",
|
|
343
|
-
i0.ɵɵelementStart(4, "span",
|
|
645
|
+
i0.ɵɵelement(3, "i", 59);
|
|
646
|
+
i0.ɵɵelementStart(4, "span", 62);
|
|
344
647
|
i0.ɵɵtext(5);
|
|
345
648
|
i0.ɵɵelementEnd()();
|
|
346
649
|
} if (rf & 2) {
|
|
347
|
-
const
|
|
650
|
+
const fc_r33 = i0.ɵɵnextContext().$implicit;
|
|
348
651
|
i0.ɵɵadvance(2);
|
|
349
|
-
i0.ɵɵtextInterpolate(
|
|
652
|
+
i0.ɵɵtextInterpolate(fc_r33.oldValue || "(empty)");
|
|
350
653
|
i0.ɵɵadvance(3);
|
|
351
|
-
i0.ɵɵtextInterpolate(
|
|
654
|
+
i0.ɵɵtextInterpolate(fc_r33.newValue || "(empty)");
|
|
352
655
|
} }
|
|
353
|
-
function
|
|
354
|
-
i0.ɵɵelementStart(0, "div",
|
|
656
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
657
|
+
i0.ɵɵelementStart(0, "div", 51)(1, "div", 52);
|
|
355
658
|
i0.ɵɵtext(2);
|
|
356
659
|
i0.ɵɵelementEnd();
|
|
357
|
-
i0.ɵɵelementStart(3, "div",
|
|
358
|
-
i0.ɵɵconditionalCreate(4,
|
|
660
|
+
i0.ɵɵelementStart(3, "div", 53);
|
|
661
|
+
i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_For_1_Conditional_4_Template, 8, 14, "div", 54)(5, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_For_1_Conditional_5_Template, 6, 2, "div", 55)(6, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_For_1_Conditional_6_Template, 1, 1, "div", 56)(7, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_For_1_Conditional_7_Template, 6, 2, "div", 55);
|
|
359
662
|
i0.ɵɵelementEnd()();
|
|
360
663
|
} if (rf & 2) {
|
|
361
|
-
const
|
|
664
|
+
const fc_r33 = ctx.$implicit;
|
|
362
665
|
i0.ɵɵadvance(2);
|
|
363
|
-
i0.ɵɵtextInterpolate(
|
|
666
|
+
i0.ɵɵtextInterpolate(fc_r33.displayName);
|
|
364
667
|
i0.ɵɵadvance(2);
|
|
365
|
-
i0.ɵɵconditional(
|
|
668
|
+
i0.ɵɵconditional(fc_r33.fieldType === "boolean" ? 4 : fc_r33.fieldType === "date" || fc_r33.fieldType === "number" ? 5 : fc_r33.diffHtml ? 6 : 7);
|
|
366
669
|
} }
|
|
367
|
-
function
|
|
368
|
-
i0.ɵɵrepeaterCreate(0,
|
|
670
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
671
|
+
i0.ɵɵrepeaterCreate(0, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_For_1_Template, 8, 2, "div", 51, _forTrack2);
|
|
369
672
|
} if (rf & 2) {
|
|
370
|
-
const
|
|
371
|
-
const
|
|
372
|
-
i0.ɵɵrepeater(
|
|
673
|
+
const change_r28 = i0.ɵɵnextContext(2).$implicit;
|
|
674
|
+
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
675
|
+
i0.ɵɵrepeater(ctx_r2.getFieldChanges(change_r28));
|
|
373
676
|
} }
|
|
374
|
-
function
|
|
375
|
-
i0.ɵɵelementStart(0, "div",
|
|
376
|
-
i0.ɵɵelement(1, "i",
|
|
677
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
678
|
+
i0.ɵɵelementStart(0, "div", 127);
|
|
679
|
+
i0.ɵɵelement(1, "i", 133);
|
|
377
680
|
i0.ɵɵtext(2);
|
|
378
681
|
i0.ɵɵelementEnd();
|
|
379
682
|
} if (rf & 2) {
|
|
380
|
-
const
|
|
683
|
+
const change_r28 = i0.ɵɵnextContext(2).$implicit;
|
|
381
684
|
i0.ɵɵadvance(2);
|
|
382
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
685
|
+
i0.ɵɵtextInterpolate1(" ", change_r28.Comments, " ");
|
|
383
686
|
} }
|
|
384
|
-
function
|
|
385
|
-
i0.ɵɵelementStart(0, "div",
|
|
386
|
-
i0.ɵɵelement(1, "i",
|
|
387
|
-
i0.ɵɵelementStart(2, "pre",
|
|
687
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
688
|
+
i0.ɵɵelementStart(0, "div", 128);
|
|
689
|
+
i0.ɵɵelement(1, "i", 134);
|
|
690
|
+
i0.ɵɵelementStart(2, "pre", 135);
|
|
388
691
|
i0.ɵɵtext(3);
|
|
389
692
|
i0.ɵɵelementEnd()();
|
|
390
693
|
} if (rf & 2) {
|
|
391
|
-
const
|
|
694
|
+
const change_r28 = i0.ɵɵnextContext(2).$implicit;
|
|
392
695
|
i0.ɵɵadvance(3);
|
|
393
|
-
i0.ɵɵtextInterpolate(
|
|
696
|
+
i0.ɵɵtextInterpolate(change_r28.ErrorLog);
|
|
394
697
|
} }
|
|
395
|
-
function
|
|
396
|
-
const
|
|
397
|
-
i0.ɵɵelementStart(0, "
|
|
398
|
-
i0.ɵɵlistener("click", function
|
|
399
|
-
i0.ɵɵelement(
|
|
400
|
-
i0.ɵɵtext(
|
|
401
|
-
i0.ɵɵelementEnd()
|
|
698
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
699
|
+
const _r34 = i0.ɵɵgetCurrentView();
|
|
700
|
+
i0.ɵɵelementStart(0, "button", 138);
|
|
701
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_7_Conditional_1_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r34); const change_r28 = i0.ɵɵnextContext(3).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.OnToggleFormPreview(change_r28, $event)); });
|
|
702
|
+
i0.ɵɵelement(1, "i", 28);
|
|
703
|
+
i0.ɵɵtext(2);
|
|
704
|
+
i0.ɵɵelementEnd();
|
|
705
|
+
} if (rf & 2) {
|
|
706
|
+
const change_r28 = i0.ɵɵnextContext(3).$implicit;
|
|
707
|
+
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
708
|
+
i0.ɵɵclassProp("rc-preview-form-btn--active", ctx_r2.IsChangePreviewedInForm(change_r28));
|
|
709
|
+
i0.ɵɵadvance();
|
|
710
|
+
i0.ɵɵclassProp("fa-eye", !ctx_r2.IsChangePreviewedInForm(change_r28))("fa-eye-slash", ctx_r2.IsChangePreviewedInForm(change_r28));
|
|
711
|
+
i0.ɵɵadvance();
|
|
712
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r2.IsChangePreviewedInForm(change_r28) ? "Exit Form Preview" : "Preview in Form", " ");
|
|
713
|
+
} }
|
|
714
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
715
|
+
const _r35 = i0.ɵɵgetCurrentView();
|
|
716
|
+
i0.ɵɵelementStart(0, "button", 139);
|
|
717
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_7_Conditional_2_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r35); const change_r28 = i0.ɵɵnextContext(3).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.OnRestoreVersion(change_r28, $event)); });
|
|
718
|
+
i0.ɵɵelement(1, "i", 43);
|
|
719
|
+
i0.ɵɵtext(2, " Restore record to this version ");
|
|
720
|
+
i0.ɵɵelementEnd();
|
|
721
|
+
} }
|
|
722
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
723
|
+
i0.ɵɵelementStart(0, "div", 129);
|
|
724
|
+
i0.ɵɵconditionalCreate(1, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_7_Conditional_1_Template, 3, 7, "button", 136);
|
|
725
|
+
i0.ɵɵconditionalCreate(2, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_7_Conditional_2_Template, 3, 0, "button", 137);
|
|
726
|
+
i0.ɵɵelementEnd();
|
|
727
|
+
} if (rf & 2) {
|
|
728
|
+
const change_r28 = i0.ɵɵnextContext(2).$implicit;
|
|
729
|
+
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
730
|
+
i0.ɵɵadvance();
|
|
731
|
+
i0.ɵɵconditional(change_r28.FullRecordJSON ? 1 : -1);
|
|
732
|
+
i0.ɵɵadvance();
|
|
733
|
+
i0.ɵɵconditional(ctx_r2.AllowRestore ? 2 : -1);
|
|
402
734
|
} }
|
|
403
|
-
function
|
|
404
|
-
i0.ɵɵelementStart(0, "div",
|
|
405
|
-
i0.ɵɵconditionalCreate(1,
|
|
406
|
-
i0.ɵɵconditionalCreate(2,
|
|
407
|
-
i0.ɵɵconditionalCreate(5,
|
|
408
|
-
i0.ɵɵconditionalCreate(6,
|
|
409
|
-
i0.ɵɵconditionalCreate(7,
|
|
735
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
736
|
+
i0.ɵɵelementStart(0, "div", 118);
|
|
737
|
+
i0.ɵɵconditionalCreate(1, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_1_Template, 5, 1, "blockquote", 125);
|
|
738
|
+
i0.ɵɵconditionalCreate(2, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_2_Template, 1, 1)(3, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_3_Template, 3, 0, "div", 126)(4, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_4_Template, 2, 0);
|
|
739
|
+
i0.ɵɵconditionalCreate(5, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_5_Template, 3, 1, "div", 127);
|
|
740
|
+
i0.ɵɵconditionalCreate(6, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_6_Template, 4, 1, "div", 128);
|
|
741
|
+
i0.ɵɵconditionalCreate(7, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Conditional_7_Template, 3, 2, "div", 129);
|
|
410
742
|
i0.ɵɵelementEnd();
|
|
411
743
|
} if (rf & 2) {
|
|
412
744
|
let tmp_24_0;
|
|
413
|
-
const
|
|
414
|
-
const
|
|
745
|
+
const change_r28 = i0.ɵɵnextContext().$implicit;
|
|
746
|
+
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
415
747
|
i0.ɵɵadvance();
|
|
416
|
-
i0.ɵɵconditional((tmp_24_0 =
|
|
748
|
+
i0.ɵɵconditional((tmp_24_0 = ctx_r2.getRestoreReason(change_r28)) ? 1 : -1, tmp_24_0);
|
|
417
749
|
i0.ɵɵadvance();
|
|
418
|
-
i0.ɵɵconditional(
|
|
750
|
+
i0.ɵɵconditional(change_r28.Type === "Create" ? 2 : change_r28.Type === "Delete" ? 3 : 4);
|
|
419
751
|
i0.ɵɵadvance(3);
|
|
420
|
-
i0.ɵɵconditional(
|
|
752
|
+
i0.ɵɵconditional(change_r28.Comments ? 5 : -1);
|
|
421
753
|
i0.ɵɵadvance();
|
|
422
|
-
i0.ɵɵconditional(
|
|
754
|
+
i0.ɵɵconditional(change_r28.ErrorLog ? 6 : -1);
|
|
423
755
|
i0.ɵɵadvance();
|
|
424
|
-
i0.ɵɵconditional(
|
|
756
|
+
i0.ɵɵconditional(change_r28.Type !== "Delete" && !ctx_r2.isMostRecentChange(change_r28) && (ctx_r2.AllowRestore || change_r28.FullRecordJSON) ? 7 : -1);
|
|
425
757
|
} }
|
|
426
|
-
function
|
|
427
|
-
const
|
|
428
|
-
i0.ɵɵelementStart(0, "div",
|
|
429
|
-
i0.ɵɵlistener("keydown", function
|
|
430
|
-
i0.ɵɵelementStart(1, "div",
|
|
431
|
-
i0.ɵɵlistener("click", function
|
|
432
|
-
i0.ɵɵelementStart(2, "div",
|
|
758
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
759
|
+
const _r27 = i0.ɵɵgetCurrentView();
|
|
760
|
+
i0.ɵɵelementStart(0, "div", 104);
|
|
761
|
+
i0.ɵɵlistener("keydown", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Template_div_keydown_0_listener($event) { const change_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.onTimelineItemKeydown($event, change_r28.ID)); });
|
|
762
|
+
i0.ɵɵelementStart(1, "div", 105);
|
|
763
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Template_div_click_1_listener() { const change_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r2 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r2.toggleExpansion(change_r28.ID)); });
|
|
764
|
+
i0.ɵɵelementStart(2, "div", 106)(3, "span", 107);
|
|
433
765
|
i0.ɵɵtext(4);
|
|
434
766
|
i0.ɵɵelementEnd();
|
|
435
|
-
i0.ɵɵelementStart(5, "span",
|
|
767
|
+
i0.ɵɵelementStart(5, "span", 108);
|
|
436
768
|
i0.ɵɵtext(6);
|
|
437
769
|
i0.ɵɵelementEnd();
|
|
438
|
-
i0.ɵɵconditionalCreate(7,
|
|
439
|
-
i0.ɵɵ
|
|
440
|
-
i0.ɵɵelementStart(8, "div", 69)(9, "div", 70)(10, "div", 71);
|
|
441
|
-
i0.ɵɵtext(11);
|
|
770
|
+
i0.ɵɵconditionalCreate(7, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_7_Template, 3, 0, "span", 109);
|
|
771
|
+
i0.ɵɵconditionalCreate(8, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_8_Template, 2, 1);
|
|
442
772
|
i0.ɵɵelementEnd();
|
|
443
|
-
i0.ɵɵ
|
|
773
|
+
i0.ɵɵelementStart(9, "div", 110);
|
|
774
|
+
i0.ɵɵconditionalCreate(10, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_10_Template, 5, 4, "div", 111);
|
|
775
|
+
i0.ɵɵelementStart(11, "div", 112)(12, "div", 113);
|
|
776
|
+
i0.ɵɵtext(13);
|
|
444
777
|
i0.ɵɵelementEnd();
|
|
445
|
-
i0.ɵɵelementStart(13, "span", 72);
|
|
446
778
|
i0.ɵɵtext(14);
|
|
447
779
|
i0.ɵɵelementEnd();
|
|
448
|
-
i0.ɵɵelementStart(15, "span",
|
|
780
|
+
i0.ɵɵelementStart(15, "span", 114);
|
|
449
781
|
i0.ɵɵtext(16);
|
|
450
782
|
i0.ɵɵelementEnd();
|
|
451
|
-
i0.ɵɵelementStart(17, "span",
|
|
783
|
+
i0.ɵɵelementStart(17, "span", 115);
|
|
452
784
|
i0.ɵɵtext(18);
|
|
453
785
|
i0.ɵɵelementEnd();
|
|
454
|
-
i0.ɵɵ
|
|
786
|
+
i0.ɵɵelementStart(19, "span", 116);
|
|
787
|
+
i0.ɵɵtext(20);
|
|
788
|
+
i0.ɵɵelementEnd();
|
|
789
|
+
i0.ɵɵelement(21, "i", 117);
|
|
455
790
|
i0.ɵɵelementEnd()();
|
|
456
|
-
i0.ɵɵconditionalCreate(
|
|
791
|
+
i0.ɵɵconditionalCreate(22, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Conditional_22_Template, 8, 5, "div", 118);
|
|
457
792
|
i0.ɵɵelementEnd();
|
|
458
793
|
} if (rf & 2) {
|
|
459
|
-
const
|
|
460
|
-
const
|
|
461
|
-
i0.ɵɵclassMap(
|
|
462
|
-
i0.ɵɵclassProp("expanded",
|
|
463
|
-
i0.ɵɵattribute("data-change-id",
|
|
794
|
+
const change_r28 = ctx.$implicit;
|
|
795
|
+
const ctx_r2 = i0.ɵɵnextContext(5);
|
|
796
|
+
i0.ɵɵclassMap(ctx_r2.getChangeTypeCardClass(change_r28.Type));
|
|
797
|
+
i0.ɵɵclassProp("expanded", ctx_r2.expandedItems.has(change_r28.ID))("rc-card-restore", ctx_r2.isRestoreRow(change_r28))("rc-card-highlight", ctx_r2.HighlightedChangeID === change_r28.ID)("rc-card-previewing", ctx_r2.IsChangePreviewedInForm(change_r28));
|
|
798
|
+
i0.ɵɵattribute("data-change-id", change_r28.ID)("tabindex", 0)("aria-expanded", ctx_r2.expandedItems.has(change_r28.ID))("aria-label", ctx_r2.getTimelineItemLabel(change_r28));
|
|
464
799
|
i0.ɵɵadvance(3);
|
|
465
|
-
i0.ɵɵclassProp("rc-card-type-badge-restore",
|
|
800
|
+
i0.ɵɵclassProp("rc-card-type-badge-restore", ctx_r2.isRestoreRow(change_r28));
|
|
466
801
|
i0.ɵɵadvance();
|
|
467
|
-
i0.ɵɵtextInterpolate(
|
|
802
|
+
i0.ɵɵtextInterpolate(ctx_r2.getEffectiveBadgeText(change_r28));
|
|
468
803
|
i0.ɵɵadvance(2);
|
|
469
|
-
i0.ɵɵtextInterpolate(
|
|
804
|
+
i0.ɵɵtextInterpolate(ctx_r2.getChangeSummary(change_r28));
|
|
470
805
|
i0.ɵɵadvance();
|
|
471
|
-
i0.ɵɵconditional(
|
|
472
|
-
i0.ɵɵadvance(4);
|
|
473
|
-
i0.ɵɵtextInterpolate(ctx_r1.getUserInitials(change_r14.User));
|
|
806
|
+
i0.ɵɵconditional(ctx_r2.IsChangePreviewedInForm(change_r28) ? 7 : -1);
|
|
474
807
|
i0.ɵɵadvance();
|
|
475
|
-
i0.ɵɵ
|
|
808
|
+
i0.ɵɵconditional(ctx_r2.isRestoreRow(change_r28) ? 8 : -1);
|
|
809
|
+
i0.ɵɵadvance(2);
|
|
810
|
+
i0.ɵɵconditional(ctx_r2.CompareMode && change_r28.FullRecordJSON && change_r28.Type !== "Delete" ? 10 : -1);
|
|
811
|
+
i0.ɵɵadvance(3);
|
|
812
|
+
i0.ɵɵtextInterpolate(ctx_r2.getUserInitials(change_r28.User));
|
|
813
|
+
i0.ɵɵadvance();
|
|
814
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r2.getUserDisplayName(change_r28.User), " ");
|
|
476
815
|
i0.ɵɵadvance();
|
|
477
|
-
i0.ɵɵproperty("title",
|
|
816
|
+
i0.ɵɵproperty("title", ctx_r2.formatFullDateTime(change_r28.ChangedAt));
|
|
478
817
|
i0.ɵɵadvance();
|
|
479
|
-
i0.ɵɵtextInterpolate(
|
|
818
|
+
i0.ɵɵtextInterpolate(ctx_r2.formatTime(change_r28.ChangedAt));
|
|
480
819
|
i0.ɵɵadvance();
|
|
481
|
-
i0.ɵɵclassMap(
|
|
820
|
+
i0.ɵɵclassMap(ctx_r2.getSourceClass(change_r28.Source));
|
|
482
821
|
i0.ɵɵadvance();
|
|
483
|
-
i0.ɵɵtextInterpolate(
|
|
822
|
+
i0.ɵɵtextInterpolate(change_r28.Source);
|
|
484
823
|
i0.ɵɵadvance();
|
|
485
|
-
i0.ɵɵclassMap(
|
|
824
|
+
i0.ɵɵclassMap(ctx_r2.getStatusClass(change_r28.Status));
|
|
486
825
|
i0.ɵɵadvance();
|
|
487
|
-
i0.ɵɵtextInterpolate(
|
|
826
|
+
i0.ɵɵtextInterpolate(change_r28.Status);
|
|
488
827
|
i0.ɵɵadvance(2);
|
|
489
|
-
i0.ɵɵconditional(
|
|
828
|
+
i0.ɵɵconditional(ctx_r2.expandedItems.has(change_r28.ID) ? 22 : -1);
|
|
490
829
|
} }
|
|
491
|
-
function
|
|
492
|
-
i0.ɵɵelementStart(0, "div",
|
|
830
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
831
|
+
i0.ɵɵelementStart(0, "div", 101)(1, "div", 102);
|
|
493
832
|
i0.ɵɵtext(2);
|
|
494
833
|
i0.ɵɵelementEnd();
|
|
495
|
-
i0.ɵɵrepeaterCreate(3,
|
|
834
|
+
i0.ɵɵrepeaterCreate(3, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_For_4_Template, 23, 32, "div", 103, _forTrack1);
|
|
496
835
|
i0.ɵɵelementEnd();
|
|
497
836
|
} if (rf & 2) {
|
|
498
|
-
const
|
|
837
|
+
const group_r36 = ctx.$implicit;
|
|
499
838
|
i0.ɵɵadvance(2);
|
|
500
|
-
i0.ɵɵtextInterpolate(
|
|
839
|
+
i0.ɵɵtextInterpolate(group_r36.label);
|
|
501
840
|
i0.ɵɵadvance();
|
|
502
|
-
i0.ɵɵrepeater(
|
|
841
|
+
i0.ɵɵrepeater(group_r36.changes);
|
|
503
842
|
} }
|
|
504
|
-
function
|
|
505
|
-
i0.ɵɵrepeaterCreate(0,
|
|
843
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
844
|
+
i0.ɵɵrepeaterCreate(0, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_For_1_Template, 5, 1, "div", 101, _forTrack4);
|
|
506
845
|
} if (rf & 2) {
|
|
507
|
-
const
|
|
508
|
-
i0.ɵɵrepeater(
|
|
846
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
847
|
+
i0.ɵɵrepeater(ctx_r2.dateGroups);
|
|
509
848
|
} }
|
|
510
|
-
function
|
|
511
|
-
const
|
|
512
|
-
i0.ɵɵelementStart(0, "
|
|
513
|
-
i0.ɵɵ
|
|
514
|
-
i0.ɵɵ
|
|
515
|
-
i0.ɵɵelementStart(4, "div", 27);
|
|
516
|
-
i0.ɵɵtext(5);
|
|
517
|
-
i0.ɵɵelementEnd()();
|
|
518
|
-
i0.ɵɵelementStart(6, "div", 28)(7, "div", 29);
|
|
519
|
-
i0.ɵɵelement(8, "i", 30);
|
|
520
|
-
i0.ɵɵtext(9);
|
|
849
|
+
function RecordChangesComponent_Conditional_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
850
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
851
|
+
i0.ɵɵelementStart(0, "mj-burst-cluster-strip", 72);
|
|
852
|
+
i0.ɵɵtwoWayListener("SelectedClusterKeyChange", function RecordChangesComponent_Conditional_2_Conditional_20_Template_mj_burst_cluster_strip_SelectedClusterKeyChange_0_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.SelectedBucketKey, $event) || (ctx_r2.SelectedBucketKey = $event); return i0.ɵɵresetView($event); });
|
|
853
|
+
i0.ɵɵlistener("AfterClustersRebuild", function RecordChangesComponent_Conditional_2_Conditional_20_Template_mj_burst_cluster_strip_AfterClustersRebuild_0_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnBurstClustersRebuilt($event)); })("FilterChanged", function RecordChangesComponent_Conditional_2_Conditional_20_Template_mj_burst_cluster_strip_FilterChanged_0_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnBurstFilterChanged($event)); });
|
|
521
854
|
i0.ɵɵelementEnd();
|
|
522
|
-
i0.ɵɵelementStart(
|
|
523
|
-
i0.ɵɵ
|
|
524
|
-
i0.ɵɵ
|
|
525
|
-
i0.ɵɵ
|
|
526
|
-
i0.ɵɵ
|
|
527
|
-
i0.ɵɵelementStart(15, "input", 35);
|
|
528
|
-
i0.ɵɵtwoWayListener("ngModelChange", function RecordChangesComponent_Conditional_2_Conditional_15_Template_input_ngModelChange_15_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); });
|
|
529
|
-
i0.ɵɵlistener("input", function RecordChangesComponent_Conditional_2_Conditional_15_Template_input_input_15_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onSearchChange()); });
|
|
855
|
+
i0.ɵɵelementStart(1, "div", 73)(2, "div", 74);
|
|
856
|
+
i0.ɵɵelement(3, "i", 75);
|
|
857
|
+
i0.ɵɵelementStart(4, "input", 76);
|
|
858
|
+
i0.ɵɵtwoWayListener("ngModelChange", function RecordChangesComponent_Conditional_2_Conditional_20_Template_input_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.searchTerm, $event) || (ctx_r2.searchTerm = $event); return i0.ɵɵresetView($event); });
|
|
859
|
+
i0.ɵɵlistener("input", function RecordChangesComponent_Conditional_2_Conditional_20_Template_input_input_4_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onSearchChange()); });
|
|
530
860
|
i0.ɵɵelementEnd()();
|
|
531
|
-
i0.ɵɵelementStart(
|
|
532
|
-
i0.ɵɵlistener("click", function
|
|
533
|
-
i0.ɵɵelement(
|
|
534
|
-
i0.ɵɵtext(
|
|
861
|
+
i0.ɵɵelementStart(5, "button", 77);
|
|
862
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_20_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SelectAllPill()); });
|
|
863
|
+
i0.ɵɵelement(6, "i", 78);
|
|
864
|
+
i0.ɵɵtext(7, " All ");
|
|
535
865
|
i0.ɵɵelementEnd();
|
|
536
|
-
i0.ɵɵconditionalCreate(
|
|
866
|
+
i0.ɵɵconditionalCreate(8, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_8_Template, 2, 1);
|
|
537
867
|
i0.ɵɵelementEnd();
|
|
538
|
-
i0.ɵɵconditionalCreate(
|
|
539
|
-
i0.ɵɵelementStart(
|
|
540
|
-
i0.ɵɵconditionalCreate(
|
|
868
|
+
i0.ɵɵconditionalCreate(9, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_9_Template, 4, 2, "div", 79);
|
|
869
|
+
i0.ɵɵelementStart(10, "div", 80);
|
|
870
|
+
i0.ɵɵconditionalCreate(11, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_11_Template, 1, 0, "mj-empty-state", 81)(12, RecordChangesComponent_Conditional_2_Conditional_20_Conditional_12_Template, 2, 0);
|
|
541
871
|
i0.ɵɵelementEnd();
|
|
542
872
|
} if (rf & 2) {
|
|
543
|
-
const
|
|
544
|
-
i0.ɵɵ
|
|
545
|
-
i0.ɵɵ
|
|
873
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
874
|
+
i0.ɵɵproperty("Items", ctx_r2.BurstClusterItems)("Categories", ctx_r2.BurstClusterCategories)("Resolution", ctx_r2.BurstResolution)("CoalesceStrategy", ctx_r2.BurstCoalesceStrategy)("SessionGapHours", ctx_r2.BurstSessionGapHours)("MaxClusters", ctx_r2.BurstMaxClusters)("EraZoomThreshold", ctx_r2.BurstEraZoomThreshold)("AllowZoom", ctx_r2.AllowBurstZoom);
|
|
875
|
+
i0.ɵɵtwoWayProperty("SelectedClusterKey", ctx_r2.SelectedBucketKey);
|
|
546
876
|
i0.ɵɵadvance(4);
|
|
547
|
-
i0.ɵɵ
|
|
548
|
-
i0.ɵɵadvance(2);
|
|
549
|
-
i0.ɵɵtextInterpolate4("", ctx_r1.viewData.length, " change", ctx_r1.viewData.length !== 1 ? "s" : "", " \u00B7 ", ctx_r1.getUniqueContributorCount(), " contributor", ctx_r1.getUniqueContributorCount() !== 1 ? "s" : "");
|
|
550
|
-
i0.ɵɵadvance(4);
|
|
551
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.searchTerm);
|
|
877
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.searchTerm);
|
|
552
878
|
i0.ɵɵadvance();
|
|
553
|
-
i0.ɵɵclassProp("active",
|
|
879
|
+
i0.ɵɵclassProp("active", ctx_r2.IsAllSelected);
|
|
554
880
|
i0.ɵɵadvance(3);
|
|
555
|
-
i0.ɵɵconditional(
|
|
881
|
+
i0.ɵɵconditional(ctx_r2.HasConditionalPills ? 8 : -1);
|
|
556
882
|
i0.ɵɵadvance();
|
|
557
|
-
i0.ɵɵconditional(
|
|
883
|
+
i0.ɵɵconditional(ctx_r2.filteredData.length !== ctx_r2.viewData.length ? 9 : -1);
|
|
558
884
|
i0.ɵɵadvance();
|
|
559
|
-
i0.ɵɵattribute("aria-label", "Timeline of changes for " +
|
|
885
|
+
i0.ɵɵattribute("aria-label", "Timeline of changes for " + ctx_r2.record.EntityInfo.Name + " record");
|
|
560
886
|
i0.ɵɵadvance();
|
|
561
|
-
i0.ɵɵconditional(
|
|
887
|
+
i0.ɵɵconditional(ctx_r2.filteredData.length === 0 ? 11 : 12);
|
|
562
888
|
} }
|
|
563
889
|
function RecordChangesComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
564
890
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
565
|
-
i0.ɵɵelementStart(0, "div", 2)(1, "div", 5)(2, "div", 6)(3, "div", 7);
|
|
566
|
-
i0.ɵɵelement(
|
|
567
|
-
i0.ɵɵ
|
|
568
|
-
i0.ɵɵtext(6, "Version Labels");
|
|
569
|
-
i0.ɵɵelementEnd();
|
|
570
|
-
i0.ɵɵconditionalCreate(7, RecordChangesComponent_Conditional_2_Conditional_7_Template, 2, 1, "span", 9);
|
|
891
|
+
i0.ɵɵelementStart(0, "div", 2)(1, "div", 5)(2, "div", 6)(3, "div", 7)(4, "span", 8);
|
|
892
|
+
i0.ɵɵelement(5, "i", 9);
|
|
893
|
+
i0.ɵɵtext(6);
|
|
571
894
|
i0.ɵɵelementEnd();
|
|
572
|
-
i0.ɵɵelementStart(
|
|
573
|
-
i0.ɵɵ
|
|
574
|
-
i0.ɵɵelement(9, "i", 11);
|
|
575
|
-
i0.ɵɵtext(10, " Create Label ");
|
|
895
|
+
i0.ɵɵelementStart(7, "h2", 10);
|
|
896
|
+
i0.ɵɵtext(8);
|
|
576
897
|
i0.ɵɵelementEnd()();
|
|
577
|
-
i0.ɵɵconditionalCreate(
|
|
898
|
+
i0.ɵɵconditionalCreate(9, RecordChangesComponent_Conditional_2_Conditional_9_Template, 6, 6, "div", 11);
|
|
578
899
|
i0.ɵɵelementEnd();
|
|
579
|
-
i0.ɵɵ
|
|
900
|
+
i0.ɵɵelementStart(10, "div", 12);
|
|
901
|
+
i0.ɵɵconditionalCreate(11, RecordChangesComponent_Conditional_2_Conditional_11_Template, 4, 3, "button", 13);
|
|
902
|
+
i0.ɵɵconditionalCreate(12, RecordChangesComponent_Conditional_2_Conditional_12_Template, 5, 9, "button", 14);
|
|
903
|
+
i0.ɵɵelementStart(13, "button", 15);
|
|
904
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OpenCreateWizard()); });
|
|
905
|
+
i0.ɵɵelement(14, "i", 16);
|
|
906
|
+
i0.ɵɵelementStart(15, "span");
|
|
907
|
+
i0.ɵɵtext(16, "+ Label");
|
|
908
|
+
i0.ɵɵelementEnd()()()();
|
|
909
|
+
i0.ɵɵconditionalCreate(17, RecordChangesComponent_Conditional_2_Conditional_17_Template, 23, 7, "div", 17);
|
|
910
|
+
i0.ɵɵconditionalCreate(18, RecordChangesComponent_Conditional_2_Conditional_18_Template, 4, 0, "div", 18);
|
|
911
|
+
i0.ɵɵconditionalCreate(19, RecordChangesComponent_Conditional_2_Conditional_19_Template, 5, 0, "mj-empty-state", 19)(20, RecordChangesComponent_Conditional_2_Conditional_20_Template, 13, 16);
|
|
580
912
|
i0.ɵɵelementEnd();
|
|
581
913
|
} if (rf & 2) {
|
|
582
|
-
const
|
|
583
|
-
i0.ɵɵadvance(
|
|
584
|
-
i0.ɵɵ
|
|
585
|
-
i0.ɵɵadvance(
|
|
586
|
-
i0.ɵɵ
|
|
587
|
-
i0.ɵɵadvance(
|
|
588
|
-
i0.ɵɵ
|
|
914
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
915
|
+
i0.ɵɵadvance(5);
|
|
916
|
+
i0.ɵɵclassMap(ctx_r2.EntityIcon);
|
|
917
|
+
i0.ɵɵadvance();
|
|
918
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r2.EntityDisplayName, " ");
|
|
919
|
+
i0.ɵɵadvance(2);
|
|
920
|
+
i0.ɵɵtextInterpolate(ctx_r2.RecordDisplayName || "Change History");
|
|
921
|
+
i0.ɵɵadvance();
|
|
922
|
+
i0.ɵɵconditional(ctx_r2.viewData.length > 0 ? 9 : -1);
|
|
923
|
+
i0.ɵɵadvance(2);
|
|
924
|
+
i0.ɵɵconditional(ctx_r2.GetPreviewableChanges().length > 0 ? 11 : -1);
|
|
925
|
+
i0.ɵɵadvance();
|
|
926
|
+
i0.ɵɵconditional(ctx_r2.RecordLabels.length > 0 ? 12 : -1);
|
|
927
|
+
i0.ɵɵadvance(5);
|
|
928
|
+
i0.ɵɵconditional(ctx_r2.CompareMode ? 17 : -1);
|
|
929
|
+
i0.ɵɵadvance();
|
|
930
|
+
i0.ɵɵconditional(ctx_r2.ShowLabelsTray && ctx_r2.RecordLabels.length > 0 ? 18 : -1);
|
|
931
|
+
i0.ɵɵadvance();
|
|
932
|
+
i0.ɵɵconditional(ctx_r2.viewData.length === 0 ? 19 : 20);
|
|
589
933
|
} }
|
|
590
934
|
function RecordChangesComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
591
|
-
const
|
|
592
|
-
i0.ɵɵelementStart(0, "div",
|
|
593
|
-
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_4_Template_div_click_0_listener() { i0.ɵɵrestoreView(
|
|
594
|
-
i0.ɵɵelementStart(1, "div",
|
|
935
|
+
const _r37 = i0.ɵɵgetCurrentView();
|
|
936
|
+
i0.ɵɵelementStart(0, "div", 140);
|
|
937
|
+
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_4_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r37); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnLabelCreateCancelled()); });
|
|
938
|
+
i0.ɵɵelementStart(1, "div", 141);
|
|
595
939
|
i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_4_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
596
|
-
i0.ɵɵelementStart(2, "mj-label-create",
|
|
597
|
-
i0.ɵɵlistener("Created", function RecordChangesComponent_Conditional_4_Template_mj_label_create_Created_2_listener($event) { i0.ɵɵrestoreView(
|
|
940
|
+
i0.ɵɵelementStart(2, "mj-label-create", 142);
|
|
941
|
+
i0.ɵɵlistener("Created", function RecordChangesComponent_Conditional_4_Template_mj_label_create_Created_2_listener($event) { i0.ɵɵrestoreView(_r37); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnLabelCreated($event)); })("Cancel", function RecordChangesComponent_Conditional_4_Template_mj_label_create_Cancel_2_listener() { i0.ɵɵrestoreView(_r37); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnLabelCreateCancelled()); });
|
|
598
942
|
i0.ɵɵelementEnd()()();
|
|
599
943
|
} if (rf & 2) {
|
|
600
|
-
const
|
|
944
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
601
945
|
i0.ɵɵadvance(2);
|
|
602
|
-
i0.ɵɵproperty("PreselectedEntity",
|
|
946
|
+
i0.ɵɵproperty("PreselectedEntity", ctx_r2.record.EntityInfo)("PreselectedRecordIds", i0.ɵɵpureFunction1(2, _c0, ctx_r2.record.PrimaryKey.KeyValuePairs[0].Value));
|
|
603
947
|
} }
|
|
604
948
|
/**
|
|
605
949
|
* Slide-out timeline of all changes to a single record. Hosts the reusable
|
|
@@ -634,6 +978,17 @@ export class RecordChangesComponent extends BaseAngularComponent {
|
|
|
634
978
|
record;
|
|
635
979
|
/** Whether to show a "Restore" button on each historical version row. Default false. */
|
|
636
980
|
AllowRestore = false;
|
|
981
|
+
/**
|
|
982
|
+
* Optional ID of the historical change currently being previewed directly
|
|
983
|
+
* inside the host entity form ("Time Travel" mode).
|
|
984
|
+
*/
|
|
985
|
+
PreviewedChangeID = null;
|
|
986
|
+
/**
|
|
987
|
+
* Emitted when the user toggles "Preview in Form" on a historical change card
|
|
988
|
+
* (or clears the preview). Emits the selected {@link MJRecordChangeEntity} or
|
|
989
|
+
* `null` when exiting preview.
|
|
990
|
+
*/
|
|
991
|
+
PreviewVersionSelected = new EventEmitter();
|
|
637
992
|
/**
|
|
638
993
|
* Emitted when the user confirms a restore in the preview panel.
|
|
639
994
|
* The host is responsible for applying the snapshot to the record and
|
|
@@ -694,6 +1049,29 @@ export class RecordChangesComponent extends BaseAngularComponent {
|
|
|
694
1049
|
RecordLabels = [];
|
|
695
1050
|
IsLoadingLabels = false;
|
|
696
1051
|
ShowCreateWizard = false;
|
|
1052
|
+
/** Controls whether the compact version labels tray is expanded in the header. */
|
|
1053
|
+
ShowLabelsTray = false;
|
|
1054
|
+
// Activity spark-bar chart state (powered by <mj-burst-cluster-strip> from @memberjunction/ng-ui-components)
|
|
1055
|
+
BurstResolution = 'auto';
|
|
1056
|
+
BurstCoalesceStrategy = 'adaptive-era';
|
|
1057
|
+
BurstSessionGapHours = 6;
|
|
1058
|
+
BurstMaxClusters = 5;
|
|
1059
|
+
BurstEraZoomThreshold = 10;
|
|
1060
|
+
AllowBurstZoom = true;
|
|
1061
|
+
BurstClusterItems = [];
|
|
1062
|
+
BurstClusterCategories = [
|
|
1063
|
+
{ Key: 'update', Label: 'Update', SingularLabel: 'edit', PluralLabel: 'edits', Color: 'var(--mj-brand-primary)', CssModifier: 'update' },
|
|
1064
|
+
{ Key: 'create', Label: 'Create', SingularLabel: 'create', PluralLabel: 'creates', Color: 'var(--mj-status-success)', CssModifier: 'create' },
|
|
1065
|
+
{ Key: 'restore', Label: 'Restore', SingularLabel: 'restore', PluralLabel: 'restores', Color: '#8b5cf6', CssModifier: 'restore' },
|
|
1066
|
+
];
|
|
1067
|
+
ActiveBurstFilteredIDs = null;
|
|
1068
|
+
ActivityBuckets = [];
|
|
1069
|
+
SelectedBucketKey = null;
|
|
1070
|
+
ActivityChartGranularityLabel = '';
|
|
1071
|
+
// Cross-version comparison (vA <-> vB) state
|
|
1072
|
+
CompareMode = false;
|
|
1073
|
+
CompareBaseChangeID = null;
|
|
1074
|
+
CompareTargetChangeID = null;
|
|
697
1075
|
// Filter properties
|
|
698
1076
|
SearchTerm = '';
|
|
699
1077
|
/** @deprecated Use {@link SearchTerm}. */
|
|
@@ -819,6 +1197,7 @@ export class RecordChangesComponent extends BaseAngularComponent {
|
|
|
819
1197
|
this.ViewData = changes.sort((a, b) => new Date(b.ChangedAt).getTime() - new Date(a.ChangedAt).getTime());
|
|
820
1198
|
this.rebuildViewDataIndex();
|
|
821
1199
|
this.rebuildConditionalPills();
|
|
1200
|
+
this.rebuildActivityChart();
|
|
822
1201
|
this.applyFilters();
|
|
823
1202
|
this.IsLoading = false;
|
|
824
1203
|
}
|
|
@@ -889,10 +1268,148 @@ export class RecordChangesComponent extends BaseAngularComponent {
|
|
|
889
1268
|
}
|
|
890
1269
|
ClearFilters() {
|
|
891
1270
|
this.SearchTerm = '';
|
|
1271
|
+
this.SelectedBucketKey = null;
|
|
1272
|
+
this.ActiveBurstFilteredIDs = null;
|
|
892
1273
|
for (const k of Object.keys(this.ChipSelections))
|
|
893
1274
|
this.ChipSelections[k] = false;
|
|
894
1275
|
this.applyFilters();
|
|
895
1276
|
}
|
|
1277
|
+
ToggleLabelsTray() {
|
|
1278
|
+
this.ShowLabelsTray = !this.ShowLabelsTray;
|
|
1279
|
+
this.cdr.markForCheck();
|
|
1280
|
+
}
|
|
1281
|
+
ToggleBucketFilter(bucketKey) {
|
|
1282
|
+
const bucket = this.ActivityBuckets.find(b => b.Key === bucketKey);
|
|
1283
|
+
if (!bucket || bucket.TotalCount === 0)
|
|
1284
|
+
return;
|
|
1285
|
+
this.SelectedBucketKey = this.SelectedBucketKey === bucketKey ? null : bucketKey;
|
|
1286
|
+
this.ActiveBurstFilteredIDs = this.SelectedBucketKey ? new Set(bucket.ChangeIDs) : null;
|
|
1287
|
+
this.applyFilters();
|
|
1288
|
+
}
|
|
1289
|
+
ClearBucketFilter() {
|
|
1290
|
+
if (!this.SelectedBucketKey && !this.ActiveBurstFilteredIDs)
|
|
1291
|
+
return;
|
|
1292
|
+
this.SelectedBucketKey = null;
|
|
1293
|
+
this.ActiveBurstFilteredIDs = null;
|
|
1294
|
+
this.applyFilters();
|
|
1295
|
+
}
|
|
1296
|
+
OnBurstClustersRebuilt(event) {
|
|
1297
|
+
this.ActivityChartGranularityLabel = event.GranularityLabel;
|
|
1298
|
+
this.ActivityBuckets = event.Clusters.map(c => {
|
|
1299
|
+
const updateCount = c.CategoryCounts['update'] ?? 0;
|
|
1300
|
+
const createCount = c.CategoryCounts['create'] ?? 0;
|
|
1301
|
+
const restoreCount = c.CategoryCounts['restore'] ?? 0;
|
|
1302
|
+
const otherCount = Math.max(0, c.TotalCount - updateCount - createCount - restoreCount);
|
|
1303
|
+
return {
|
|
1304
|
+
Key: c.Key,
|
|
1305
|
+
Label: c.Label,
|
|
1306
|
+
Subtitle: c.Subtitle,
|
|
1307
|
+
GapAfterLabel: c.GapAfterLabel,
|
|
1308
|
+
Pips: c.Pips.map(p => ({
|
|
1309
|
+
ID: p.ID,
|
|
1310
|
+
Type: (p.Category === 'create' || p.Category === 'restore' ? p.Category : 'update'),
|
|
1311
|
+
Tooltip: p.Tooltip,
|
|
1312
|
+
})),
|
|
1313
|
+
OverflowPipCount: c.OverflowPipCount,
|
|
1314
|
+
Tooltip: c.Tooltip,
|
|
1315
|
+
StartTime: c.StartTime,
|
|
1316
|
+
EndTime: c.EndTime,
|
|
1317
|
+
TotalCount: c.TotalCount,
|
|
1318
|
+
UpdateCount: updateCount,
|
|
1319
|
+
CreateCount: createCount,
|
|
1320
|
+
RestoreCount: restoreCount,
|
|
1321
|
+
OtherCount: otherCount,
|
|
1322
|
+
HeightPercent: c.HeightPercent,
|
|
1323
|
+
UpdateSharePercent: c.CategoryShares.find(s => s.Key === 'update')?.SharePercent ?? 0,
|
|
1324
|
+
CreateSharePercent: c.CategoryShares.find(s => s.Key === 'create')?.SharePercent ?? 0,
|
|
1325
|
+
RestoreSharePercent: c.CategoryShares.find(s => s.Key === 'restore')?.SharePercent ?? 0,
|
|
1326
|
+
ChangeIDs: new Set(c.ItemIDs),
|
|
1327
|
+
};
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
OnBurstFilterChanged(event) {
|
|
1331
|
+
this.SelectedBucketKey = event.ActiveCluster?.Key ?? null;
|
|
1332
|
+
this.ActiveBurstFilteredIDs = event.FilteredIDs ? new Set(event.FilteredIDs) : null;
|
|
1333
|
+
this.applyFilters();
|
|
1334
|
+
}
|
|
1335
|
+
get SelectedBucketLabel() {
|
|
1336
|
+
if (!this.SelectedBucketKey)
|
|
1337
|
+
return null;
|
|
1338
|
+
return this.ActivityBuckets.find(b => b.Key === this.SelectedBucketKey)?.Label ?? null;
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* Human-friendly display name for the current entity (uses `EntityInfo.DisplayNameOrName`,
|
|
1342
|
+
* stripping technical schema prefixes like `MJ_BizApps_Common: ` when falling back to `Name`).
|
|
1343
|
+
*/
|
|
1344
|
+
get EntityDisplayName() {
|
|
1345
|
+
const info = this.record?.EntityInfo;
|
|
1346
|
+
if (!info)
|
|
1347
|
+
return '';
|
|
1348
|
+
if (info.DisplayNameOrName && info.DisplayNameOrName.trim().length > 0) {
|
|
1349
|
+
return info.DisplayNameOrName.trim();
|
|
1350
|
+
}
|
|
1351
|
+
if (info.DisplayName && info.DisplayName.trim().length > 0) {
|
|
1352
|
+
return info.DisplayName.trim();
|
|
1353
|
+
}
|
|
1354
|
+
const rawName = info.Name || '';
|
|
1355
|
+
const colonIdx = rawName.indexOf(':');
|
|
1356
|
+
return colonIdx >= 0 ? rawName.slice(colonIdx + 1).trim() : rawName.trim();
|
|
1357
|
+
}
|
|
1358
|
+
/**
|
|
1359
|
+
* Icon class for the current entity, falling back to `fa-solid fa-layer-group`.
|
|
1360
|
+
*/
|
|
1361
|
+
get EntityIcon() {
|
|
1362
|
+
const icon = this.record?.EntityInfo?.Icon;
|
|
1363
|
+
return icon && icon.trim().length > 0 ? icon.trim() : 'fa-solid fa-layer-group';
|
|
1364
|
+
}
|
|
1365
|
+
/**
|
|
1366
|
+
* Display name of the current record (e.g. 'Henry Grantham'), or null if unavailable.
|
|
1367
|
+
*/
|
|
1368
|
+
get RecordDisplayName() {
|
|
1369
|
+
const rec = this.record;
|
|
1370
|
+
if (!rec)
|
|
1371
|
+
return null;
|
|
1372
|
+
const entityInfo = rec.EntityInfo;
|
|
1373
|
+
const nameFieldName = entityInfo?.NameField?.Name;
|
|
1374
|
+
if (nameFieldName && Array.isArray(rec.Fields)) {
|
|
1375
|
+
const f = rec.Fields.find(item => item.Name === nameFieldName);
|
|
1376
|
+
if (f?.Value != null && String(f.Value).trim().length > 0) {
|
|
1377
|
+
return String(f.Value).trim();
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
if (Array.isArray(rec.Fields)) {
|
|
1381
|
+
for (const candidate of ['DisplayName', 'Name', 'Title', 'FullName']) {
|
|
1382
|
+
const f = rec.Fields.find(item => item.Name.toLowerCase() === candidate.toLowerCase());
|
|
1383
|
+
if (f?.Value != null && String(f.Value).trim().length > 0) {
|
|
1384
|
+
return String(f.Value).trim();
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
return null;
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* Up to 4 unique contributors for the compact avatar stack in the header.
|
|
1392
|
+
*/
|
|
1393
|
+
get TopContributors() {
|
|
1394
|
+
const seen = new Set();
|
|
1395
|
+
const out = [];
|
|
1396
|
+
for (const c of this.ViewData) {
|
|
1397
|
+
const rawUser = (c.User || '').trim();
|
|
1398
|
+
if (!rawUser)
|
|
1399
|
+
continue;
|
|
1400
|
+
const key = rawUser.toLowerCase();
|
|
1401
|
+
if (seen.has(key))
|
|
1402
|
+
continue;
|
|
1403
|
+
seen.add(key);
|
|
1404
|
+
out.push({
|
|
1405
|
+
Name: this.GetUserDisplayName(rawUser),
|
|
1406
|
+
Initials: this.GetUserInitials(rawUser),
|
|
1407
|
+
});
|
|
1408
|
+
if (out.length >= 4)
|
|
1409
|
+
break;
|
|
1410
|
+
}
|
|
1411
|
+
return out;
|
|
1412
|
+
}
|
|
896
1413
|
/**
|
|
897
1414
|
* Builds the list of conditional pills from currently loaded data —
|
|
898
1415
|
* a pill only appears for change types/sources that actually exist.
|
|
@@ -935,10 +1452,272 @@ export class RecordChangesComponent extends BaseAngularComponent {
|
|
|
935
1452
|
this.ConditionalPills = pills;
|
|
936
1453
|
}
|
|
937
1454
|
isRestoreChange(c) {
|
|
938
|
-
|
|
1455
|
+
const withLineage = c;
|
|
1456
|
+
return c.Source === 'Restore' || withLineage.RestoredFromID != null;
|
|
1457
|
+
}
|
|
1458
|
+
/**
|
|
1459
|
+
* Builds the Burst-Aware Cluster Strip (Option A) with non-linear time-gap compression.
|
|
1460
|
+
* Instead of dividing wall-clock time into 12 fixed equal buckets (which leaves mostly empty
|
|
1461
|
+
* columns when a record has irregular bursts separated by weeks or months), changes are grouped
|
|
1462
|
+
* into active editing sessions separated by compact quiet-gap connectors (`⋯ 11 mos quiet ⋯`).
|
|
1463
|
+
*/
|
|
1464
|
+
rebuildActivityChart() {
|
|
1465
|
+
if (!this.ViewData || this.ViewData.length === 0) {
|
|
1466
|
+
this.BurstClusterItems = [];
|
|
1467
|
+
this.ActivityBuckets = [];
|
|
1468
|
+
this.ActivityChartGranularityLabel = '';
|
|
1469
|
+
this.SelectedBucketKey = null;
|
|
1470
|
+
this.ActiveBurstFilteredIDs = null;
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
const datedChanges = this.ViewData
|
|
1474
|
+
.map(c => ({ change: c, time: new Date(c.ChangedAt).getTime() }))
|
|
1475
|
+
.filter(item => Number.isFinite(item.time))
|
|
1476
|
+
.sort((a, b) => a.time - b.time);
|
|
1477
|
+
if (datedChanges.length === 0) {
|
|
1478
|
+
this.BurstClusterItems = [];
|
|
1479
|
+
this.ActivityBuckets = [];
|
|
1480
|
+
this.ActivityChartGranularityLabel = '';
|
|
1481
|
+
this.ActiveBurstFilteredIDs = null;
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1484
|
+
this.BurstClusterItems = datedChanges.map(({ change, time }) => {
|
|
1485
|
+
const normId = NormalizeUUID(change.ID);
|
|
1486
|
+
let category = 'update';
|
|
1487
|
+
if (this.isRestoreChange(change)) {
|
|
1488
|
+
category = 'restore';
|
|
1489
|
+
}
|
|
1490
|
+
else if (change.Type === 'Create') {
|
|
1491
|
+
category = 'create';
|
|
1492
|
+
}
|
|
1493
|
+
const userLabel = this.getUserDisplayName(change.User);
|
|
1494
|
+
const dateLabel = new Intl.DateTimeFormat('en-US', {
|
|
1495
|
+
month: 'short',
|
|
1496
|
+
day: 'numeric',
|
|
1497
|
+
hour: 'numeric',
|
|
1498
|
+
minute: '2-digit',
|
|
1499
|
+
}).format(new Date(time));
|
|
1500
|
+
return {
|
|
1501
|
+
ID: normId,
|
|
1502
|
+
Timestamp: time,
|
|
1503
|
+
Category: category,
|
|
1504
|
+
Tooltip: `${category === 'create' ? 'Created' : category === 'restore' ? 'Restored' : 'Updated'} by ${userLabel} · ${dateLabel}`,
|
|
1505
|
+
Data: change,
|
|
1506
|
+
};
|
|
1507
|
+
});
|
|
1508
|
+
const hourMs = 3600 * 1000;
|
|
1509
|
+
const sessionGapThresholdMs = this.BurstSessionGapHours * hourMs;
|
|
1510
|
+
const maxClusters = this.BurstMaxClusters;
|
|
1511
|
+
// 1. Group chronologically adjacent changes into initial session clusters (same calendar day or <= 6h apart)
|
|
1512
|
+
const clusters = [];
|
|
1513
|
+
for (const entry of datedChanges) {
|
|
1514
|
+
const prev = clusters[clusters.length - 1];
|
|
1515
|
+
if (!prev) {
|
|
1516
|
+
clusters.push({ items: [entry], startTime: entry.time, endTime: entry.time });
|
|
1517
|
+
continue;
|
|
1518
|
+
}
|
|
1519
|
+
const prevDate = new Date(prev.endTime);
|
|
1520
|
+
const currDate = new Date(entry.time);
|
|
1521
|
+
const sameDay = prevDate.getUTCFullYear() === currDate.getUTCFullYear() &&
|
|
1522
|
+
prevDate.getUTCMonth() === currDate.getUTCMonth() &&
|
|
1523
|
+
prevDate.getUTCDate() === currDate.getUTCDate();
|
|
1524
|
+
const withinSessionGap = (entry.time - prev.endTime) <= sessionGapThresholdMs;
|
|
1525
|
+
if (sameDay || withinSessionGap) {
|
|
1526
|
+
prev.items.push(entry);
|
|
1527
|
+
prev.endTime = entry.time;
|
|
1528
|
+
}
|
|
1529
|
+
else {
|
|
1530
|
+
clusters.push({ items: [entry], startTime: entry.time, endTime: entry.time });
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
// 2. If more than maxClusters exist, iteratively merge the closest adjacent pair so the strip stays compact
|
|
1534
|
+
while (clusters.length > maxClusters) {
|
|
1535
|
+
let minGap = Infinity;
|
|
1536
|
+
let mergeIdx = 0;
|
|
1537
|
+
for (let i = 0; i < clusters.length - 1; i++) {
|
|
1538
|
+
const gap = clusters[i + 1].startTime - clusters[i].endTime;
|
|
1539
|
+
if (gap < minGap) {
|
|
1540
|
+
minGap = gap;
|
|
1541
|
+
mergeIdx = i;
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
const left = clusters[mergeIdx];
|
|
1545
|
+
const right = clusters[mergeIdx + 1];
|
|
1546
|
+
clusters.splice(mergeIdx, 2, {
|
|
1547
|
+
items: [...left.items, ...right.items],
|
|
1548
|
+
startTime: left.startTime,
|
|
1549
|
+
endTime: right.endTime,
|
|
1550
|
+
});
|
|
1551
|
+
}
|
|
1552
|
+
const minTime = datedChanges[0].time;
|
|
1553
|
+
const maxTime = datedChanges[datedChanges.length - 1].time;
|
|
1554
|
+
const totalSpanMs = Math.max(0, maxTime - minTime);
|
|
1555
|
+
const maxCount = Math.max(1, ...clusters.map(c => c.items.length));
|
|
1556
|
+
const buckets = clusters.map((cluster, idx) => {
|
|
1557
|
+
let updateCount = 0;
|
|
1558
|
+
let createCount = 0;
|
|
1559
|
+
let restoreCount = 0;
|
|
1560
|
+
let otherCount = 0;
|
|
1561
|
+
const changeIds = new Set();
|
|
1562
|
+
const pips = [];
|
|
1563
|
+
for (const { change, time } of cluster.items) {
|
|
1564
|
+
const normId = NormalizeUUID(change.ID);
|
|
1565
|
+
changeIds.add(normId);
|
|
1566
|
+
let pipType = 'update';
|
|
1567
|
+
if (this.isRestoreChange(change)) {
|
|
1568
|
+
restoreCount++;
|
|
1569
|
+
pipType = 'restore';
|
|
1570
|
+
}
|
|
1571
|
+
else if (change.Type === 'Create') {
|
|
1572
|
+
createCount++;
|
|
1573
|
+
pipType = 'create';
|
|
1574
|
+
}
|
|
1575
|
+
else if (change.Type === 'Update' || !change.Type) {
|
|
1576
|
+
updateCount++;
|
|
1577
|
+
pipType = 'update';
|
|
1578
|
+
}
|
|
1579
|
+
else {
|
|
1580
|
+
otherCount++;
|
|
1581
|
+
pipType = 'update';
|
|
1582
|
+
}
|
|
1583
|
+
if (pips.length < 12) {
|
|
1584
|
+
const userLabel = this.getUserDisplayName(change.User);
|
|
1585
|
+
const dateLabel = new Intl.DateTimeFormat('en-US', {
|
|
1586
|
+
month: 'short',
|
|
1587
|
+
day: 'numeric',
|
|
1588
|
+
hour: 'numeric',
|
|
1589
|
+
minute: '2-digit',
|
|
1590
|
+
}).format(new Date(time));
|
|
1591
|
+
pips.push({
|
|
1592
|
+
ID: normId,
|
|
1593
|
+
Type: pipType,
|
|
1594
|
+
Tooltip: `${pipType === 'create' ? 'Created' : pipType === 'restore' ? 'Restored' : 'Updated'} by ${userLabel} · ${dateLabel}`,
|
|
1595
|
+
});
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
const totalCount = cluster.items.length;
|
|
1599
|
+
const label = this.formatBurstClusterLabel(cluster.startTime, cluster.endTime, maxTime, totalSpanMs);
|
|
1600
|
+
const subtitle = this.formatBurstSubtitle(totalCount, createCount, updateCount + otherCount, restoreCount);
|
|
1601
|
+
const nextCluster = idx < clusters.length - 1 ? clusters[idx + 1] : null;
|
|
1602
|
+
const gapAfterLabel = nextCluster
|
|
1603
|
+
? this.formatQuietGapLabel(Math.max(0, nextCluster.startTime - cluster.endTime))
|
|
1604
|
+
: null;
|
|
1605
|
+
const updateShare = Math.round(((updateCount + otherCount) / totalCount) * 100);
|
|
1606
|
+
const createShare = Math.round((createCount / totalCount) * 100);
|
|
1607
|
+
const restoreShare = Math.max(0, 100 - updateShare - createShare);
|
|
1608
|
+
const parts = [];
|
|
1609
|
+
if (updateCount > 0)
|
|
1610
|
+
parts.push(`${updateCount} update${updateCount !== 1 ? 's' : ''}`);
|
|
1611
|
+
if (createCount > 0)
|
|
1612
|
+
parts.push(`${createCount} create`);
|
|
1613
|
+
if (restoreCount > 0)
|
|
1614
|
+
parts.push(`${restoreCount} restore${restoreCount !== 1 ? 's' : ''}`);
|
|
1615
|
+
if (otherCount > 0)
|
|
1616
|
+
parts.push(`${otherCount} other`);
|
|
1617
|
+
return {
|
|
1618
|
+
Key: `burst-${idx}-${cluster.startTime}`,
|
|
1619
|
+
Label: label,
|
|
1620
|
+
Subtitle: subtitle,
|
|
1621
|
+
GapAfterLabel: gapAfterLabel,
|
|
1622
|
+
Pips: pips,
|
|
1623
|
+
OverflowPipCount: Math.max(0, totalCount - pips.length),
|
|
1624
|
+
Tooltip: `${label} · ${totalCount} change${totalCount !== 1 ? 's' : ''} (${parts.join(', ')})`,
|
|
1625
|
+
StartTime: cluster.startTime,
|
|
1626
|
+
EndTime: cluster.endTime + 1,
|
|
1627
|
+
TotalCount: totalCount,
|
|
1628
|
+
UpdateCount: updateCount,
|
|
1629
|
+
CreateCount: createCount,
|
|
1630
|
+
RestoreCount: restoreCount,
|
|
1631
|
+
OtherCount: otherCount,
|
|
1632
|
+
HeightPercent: Math.max(22, Math.round((totalCount / maxCount) * 100)),
|
|
1633
|
+
UpdateSharePercent: updateShare,
|
|
1634
|
+
CreateSharePercent: createShare,
|
|
1635
|
+
RestoreSharePercent: restoreShare,
|
|
1636
|
+
ChangeIDs: changeIds,
|
|
1637
|
+
};
|
|
1638
|
+
});
|
|
1639
|
+
this.ActivityChartGranularityLabel =
|
|
1640
|
+
buckets.length === 1
|
|
1641
|
+
? '1 active editing session'
|
|
1642
|
+
: `Editing sessions (${buckets.length} active bursts · quiet gaps compressed)`;
|
|
1643
|
+
this.ActivityBuckets = buckets;
|
|
1644
|
+
if (this.SelectedBucketKey && !buckets.some(b => b.Key === this.SelectedBucketKey)) {
|
|
1645
|
+
this.SelectedBucketKey = null;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
formatBurstClusterLabel(startMs, endMs, maxTimeMs, totalSpanMs) {
|
|
1649
|
+
const start = new Date(startMs);
|
|
1650
|
+
const end = new Date(endMs);
|
|
1651
|
+
const now = new Date();
|
|
1652
|
+
const dayMs = 24 * 3600 * 1000;
|
|
1653
|
+
const includeYear = start.getFullYear() !== new Date(maxTimeMs).getFullYear() || totalSpanMs > 240 * dayMs;
|
|
1654
|
+
const sameDay = start.getFullYear() === end.getFullYear() &&
|
|
1655
|
+
start.getMonth() === end.getMonth() &&
|
|
1656
|
+
start.getDate() === end.getDate();
|
|
1657
|
+
if (sameDay) {
|
|
1658
|
+
const isToday = start.getFullYear() === now.getFullYear() &&
|
|
1659
|
+
start.getMonth() === now.getMonth() &&
|
|
1660
|
+
start.getDate() === now.getDate();
|
|
1661
|
+
if (isToday) {
|
|
1662
|
+
return 'Today';
|
|
1663
|
+
}
|
|
1664
|
+
return new Intl.DateTimeFormat('en-US', includeYear
|
|
1665
|
+
? { month: 'short', day: 'numeric', year: '2-digit' }
|
|
1666
|
+
: { month: 'short', day: 'numeric' }).format(start);
|
|
1667
|
+
}
|
|
1668
|
+
if (start.getFullYear() === end.getFullYear() && start.getMonth() === end.getMonth()) {
|
|
1669
|
+
const monthStr = new Intl.DateTimeFormat('en-US', { month: 'short' }).format(start);
|
|
1670
|
+
const yrSuffix = includeYear ? ` '${String(start.getFullYear()).slice(-2)}` : '';
|
|
1671
|
+
return `${monthStr} ${start.getDate()}–${end.getDate()}${yrSuffix}`;
|
|
1672
|
+
}
|
|
1673
|
+
const fmt = new Intl.DateTimeFormat('en-US', includeYear
|
|
1674
|
+
? { month: 'short', day: 'numeric', year: '2-digit' }
|
|
1675
|
+
: { month: 'short', day: 'numeric' });
|
|
1676
|
+
return `${fmt.format(start)} – ${fmt.format(end)}`;
|
|
1677
|
+
}
|
|
1678
|
+
formatBurstSubtitle(total, creates, updates, restores) {
|
|
1679
|
+
if (creates > 0 && total === 1) {
|
|
1680
|
+
return 'Initial creation';
|
|
1681
|
+
}
|
|
1682
|
+
if (restores > 0 && updates > 0) {
|
|
1683
|
+
return `${restores} restore${restores !== 1 ? 's' : ''}, ${updates} edit${updates !== 1 ? 's' : ''}`;
|
|
1684
|
+
}
|
|
1685
|
+
if (restores > 0) {
|
|
1686
|
+
return `${restores} restore${restores !== 1 ? 's' : ''}`;
|
|
1687
|
+
}
|
|
1688
|
+
if (creates > 0 && updates > 0) {
|
|
1689
|
+
return `Created + ${updates} edit${updates !== 1 ? 's' : ''}`;
|
|
1690
|
+
}
|
|
1691
|
+
return `${total} edit${total !== 1 ? 's' : ''}`;
|
|
1692
|
+
}
|
|
1693
|
+
formatQuietGapLabel(gapMs) {
|
|
1694
|
+
const hourMs = 3600 * 1000;
|
|
1695
|
+
const dayMs = 24 * hourMs;
|
|
1696
|
+
const gapDays = gapMs / dayMs;
|
|
1697
|
+
if (gapDays >= 540) {
|
|
1698
|
+
const yrs = (gapDays / 365).toFixed(1).replace(/\.0$/, '');
|
|
1699
|
+
return `${yrs} yrs quiet`;
|
|
1700
|
+
}
|
|
1701
|
+
if (gapDays >= 45) {
|
|
1702
|
+
return `${Math.round(gapDays / 30)} mos quiet`;
|
|
1703
|
+
}
|
|
1704
|
+
if (gapDays >= 1) {
|
|
1705
|
+
return `${Math.max(1, Math.round(gapDays))}d quiet`;
|
|
1706
|
+
}
|
|
1707
|
+
const gapHours = Math.max(1, Math.round(gapMs / hourMs));
|
|
1708
|
+
return `${gapHours}h quiet`;
|
|
939
1709
|
}
|
|
940
1710
|
applyFilters() {
|
|
941
1711
|
let filtered = [...this.ViewData];
|
|
1712
|
+
if (this.ActiveBurstFilteredIDs && this.ActiveBurstFilteredIDs.size > 0) {
|
|
1713
|
+
filtered = filtered.filter(change => this.ActiveBurstFilteredIDs.has(NormalizeUUID(change.ID)));
|
|
1714
|
+
}
|
|
1715
|
+
else if (this.SelectedBucketKey) {
|
|
1716
|
+
const activeBucket = this.ActivityBuckets.find(b => b.Key === this.SelectedBucketKey);
|
|
1717
|
+
if (activeBucket) {
|
|
1718
|
+
filtered = filtered.filter(change => activeBucket.ChangeIDs.has(NormalizeUUID(change.ID)));
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
942
1721
|
if (this.SearchTerm.trim()) {
|
|
943
1722
|
const search = this.SearchTerm.toLowerCase();
|
|
944
1723
|
filtered = filtered.filter(change => change.ChangesDescription?.toLowerCase().includes(search) ||
|
|
@@ -1081,10 +1860,212 @@ export class RecordChangesComponent extends BaseAngularComponent {
|
|
|
1081
1860
|
*/
|
|
1082
1861
|
OnRestoreVersion(change, event) {
|
|
1083
1862
|
event.stopPropagation();
|
|
1863
|
+
this.OpenRestoreForChange(change);
|
|
1864
|
+
}
|
|
1865
|
+
/**
|
|
1866
|
+
* Programmatically opens the restore confirmation panel for a specific
|
|
1867
|
+
* historical change (e.g., when triggered from the host form's Time-Travel
|
|
1868
|
+
* Preview banner).
|
|
1869
|
+
*/
|
|
1870
|
+
OpenRestoreForChange(change) {
|
|
1084
1871
|
this.RestorePreviewChange = change;
|
|
1085
1872
|
this.RestorePreviewVisible = true;
|
|
1086
1873
|
this.cdr.markForCheck();
|
|
1087
1874
|
}
|
|
1875
|
+
/**
|
|
1876
|
+
* Returns true when `change` is the historical version currently being
|
|
1877
|
+
* previewed in the host form.
|
|
1878
|
+
*/
|
|
1879
|
+
IsChangePreviewedInForm(change) {
|
|
1880
|
+
return this.PreviewedChangeID != null && UUIDsEqual(this.PreviewedChangeID, change.ID);
|
|
1881
|
+
}
|
|
1882
|
+
/**
|
|
1883
|
+
* Toggles in-form Time-Travel preview for the given historical change.
|
|
1884
|
+
*/
|
|
1885
|
+
OnToggleFormPreview(change, event) {
|
|
1886
|
+
event.stopPropagation();
|
|
1887
|
+
if (this.IsChangePreviewedInForm(change)) {
|
|
1888
|
+
this.PreviewedChangeID = null;
|
|
1889
|
+
this.PreviewVersionSelected.emit(null);
|
|
1890
|
+
}
|
|
1891
|
+
else {
|
|
1892
|
+
this.PreviewedChangeID = change.ID;
|
|
1893
|
+
this.PreviewVersionSelected.emit(change);
|
|
1894
|
+
}
|
|
1895
|
+
this.cdr.markForCheck();
|
|
1896
|
+
}
|
|
1897
|
+
/**
|
|
1898
|
+
* Returns all loaded changes that carry a `FullRecordJSON` snapshot and can
|
|
1899
|
+
* be previewed in the form, ordered newest-first.
|
|
1900
|
+
*/
|
|
1901
|
+
GetPreviewableChanges() {
|
|
1902
|
+
return this.ViewData.filter(c => c.Type !== 'Delete' && !!c.FullRecordJSON);
|
|
1903
|
+
}
|
|
1904
|
+
/**
|
|
1905
|
+
* Toggles Cross-Version Diff Comparison (`vA ↔ vB`) mode.
|
|
1906
|
+
* When entering Compare Mode with no versions selected, defaults `vB` to the
|
|
1907
|
+
* latest version and `vA` to the immediately preceding snapshot (or live state).
|
|
1908
|
+
*/
|
|
1909
|
+
ToggleCompareMode() {
|
|
1910
|
+
this.CompareMode = !this.CompareMode;
|
|
1911
|
+
if (this.CompareMode && !this.CompareBaseChangeID && !this.CompareTargetChangeID) {
|
|
1912
|
+
const previewable = this.GetPreviewableChanges();
|
|
1913
|
+
if (previewable.length >= 2) {
|
|
1914
|
+
this.CompareTargetChangeID = previewable[0].ID;
|
|
1915
|
+
this.CompareBaseChangeID = previewable[1].ID;
|
|
1916
|
+
}
|
|
1917
|
+
else if (previewable.length === 1) {
|
|
1918
|
+
this.CompareBaseChangeID = previewable[0].ID;
|
|
1919
|
+
this.CompareTargetChangeID = '__CURRENT__';
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
this.cdr.markForCheck();
|
|
1923
|
+
}
|
|
1924
|
+
/**
|
|
1925
|
+
* Assigns a historical change ID (or `'__CURRENT__'`) to either the `base` (`vA`)
|
|
1926
|
+
* or `target` (`vB`) comparison slot.
|
|
1927
|
+
*/
|
|
1928
|
+
SelectForComparison(slot, changeId, event) {
|
|
1929
|
+
event?.stopPropagation();
|
|
1930
|
+
if (slot === 'base') {
|
|
1931
|
+
this.CompareBaseChangeID = changeId;
|
|
1932
|
+
}
|
|
1933
|
+
else {
|
|
1934
|
+
this.CompareTargetChangeID = changeId;
|
|
1935
|
+
}
|
|
1936
|
+
if (!this.CompareMode) {
|
|
1937
|
+
this.CompareMode = true;
|
|
1938
|
+
}
|
|
1939
|
+
this.cdr.markForCheck();
|
|
1940
|
+
}
|
|
1941
|
+
/**
|
|
1942
|
+
* Handles `<select>` change events for the `vA` and `vB` version selectors.
|
|
1943
|
+
*/
|
|
1944
|
+
OnComparisonSelectChange(slot, event) {
|
|
1945
|
+
const selectEl = event.target;
|
|
1946
|
+
if (!selectEl)
|
|
1947
|
+
return;
|
|
1948
|
+
this.SelectForComparison(slot, selectEl.value || null);
|
|
1949
|
+
}
|
|
1950
|
+
/**
|
|
1951
|
+
* Swaps the selected `vA` (base) and `vB` (target) comparison versions.
|
|
1952
|
+
*/
|
|
1953
|
+
SwapComparisonVersions() {
|
|
1954
|
+
const prevBase = this.CompareBaseChangeID;
|
|
1955
|
+
this.CompareBaseChangeID = this.CompareTargetChangeID;
|
|
1956
|
+
this.CompareTargetChangeID = prevBase;
|
|
1957
|
+
this.cdr.markForCheck();
|
|
1958
|
+
}
|
|
1959
|
+
IsChangeSelectedAsCompareBase(change) {
|
|
1960
|
+
return (this.CompareBaseChangeID != null &&
|
|
1961
|
+
this.CompareBaseChangeID !== '__CURRENT__' &&
|
|
1962
|
+
UUIDsEqual(this.CompareBaseChangeID, change.ID));
|
|
1963
|
+
}
|
|
1964
|
+
IsChangeSelectedAsCompareTarget(change) {
|
|
1965
|
+
return (this.CompareTargetChangeID != null &&
|
|
1966
|
+
this.CompareTargetChangeID !== '__CURRENT__' &&
|
|
1967
|
+
UUIDsEqual(this.CompareTargetChangeID, change.ID));
|
|
1968
|
+
}
|
|
1969
|
+
get CompareBaseChange() {
|
|
1970
|
+
if (!this.CompareBaseChangeID || this.CompareBaseChangeID === '__CURRENT__') {
|
|
1971
|
+
return null;
|
|
1972
|
+
}
|
|
1973
|
+
return this.viewDataById.get(NormalizeUUID(this.CompareBaseChangeID)) ?? null;
|
|
1974
|
+
}
|
|
1975
|
+
get CompareTargetChange() {
|
|
1976
|
+
if (!this.CompareTargetChangeID || this.CompareTargetChangeID === '__CURRENT__') {
|
|
1977
|
+
return null;
|
|
1978
|
+
}
|
|
1979
|
+
return this.viewDataById.get(NormalizeUUID(this.CompareTargetChangeID)) ?? null;
|
|
1980
|
+
}
|
|
1981
|
+
GetComparisonSlotLabel(slot) {
|
|
1982
|
+
const id = slot === 'base' ? this.CompareBaseChangeID : this.CompareTargetChangeID;
|
|
1983
|
+
if (!id)
|
|
1984
|
+
return 'Select version…';
|
|
1985
|
+
if (id === '__CURRENT__')
|
|
1986
|
+
return 'Current Live Record';
|
|
1987
|
+
const change = this.viewDataById.get(NormalizeUUID(id));
|
|
1988
|
+
if (!change)
|
|
1989
|
+
return 'Selected version';
|
|
1990
|
+
return `${this.FormatRelativeTime(change.ChangedAt)} (${this.GetUserDisplayName(change.User)})`;
|
|
1991
|
+
}
|
|
1992
|
+
extractSnapshotObject(changeId) {
|
|
1993
|
+
if (!changeId)
|
|
1994
|
+
return null;
|
|
1995
|
+
if (changeId === '__CURRENT__') {
|
|
1996
|
+
const rec = this.record;
|
|
1997
|
+
if (!rec)
|
|
1998
|
+
return null;
|
|
1999
|
+
if (typeof rec.GetAll === 'function') {
|
|
2000
|
+
return rec.GetAll();
|
|
2001
|
+
}
|
|
2002
|
+
if (Array.isArray(rec.Fields)) {
|
|
2003
|
+
const snapshot = {};
|
|
2004
|
+
for (const f of rec.Fields) {
|
|
2005
|
+
snapshot[f.Name] = f.Value;
|
|
2006
|
+
}
|
|
2007
|
+
return snapshot;
|
|
2008
|
+
}
|
|
2009
|
+
return null;
|
|
2010
|
+
}
|
|
2011
|
+
const change = this.viewDataById.get(NormalizeUUID(changeId));
|
|
2012
|
+
if (!change?.FullRecordJSON)
|
|
2013
|
+
return null;
|
|
2014
|
+
try {
|
|
2015
|
+
return JSON.parse(change.FullRecordJSON);
|
|
2016
|
+
}
|
|
2017
|
+
catch {
|
|
2018
|
+
return null;
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
/**
|
|
2022
|
+
* Computes the field-by-field diff between the selected `vA` (`CompareBaseChangeID`)
|
|
2023
|
+
* and `vB` (`CompareTargetChangeID`) snapshots.
|
|
2024
|
+
*/
|
|
2025
|
+
GetComparisonDiffs() {
|
|
2026
|
+
const baseSnap = this.extractSnapshotObject(this.CompareBaseChangeID);
|
|
2027
|
+
const targetSnap = this.extractSnapshotObject(this.CompareTargetChangeID);
|
|
2028
|
+
if (!baseSnap || !targetSnap) {
|
|
2029
|
+
return [];
|
|
2030
|
+
}
|
|
2031
|
+
const entityFields = this.record?.EntityInfo?.Fields ?? [];
|
|
2032
|
+
const candidateNames = new Set();
|
|
2033
|
+
for (const f of entityFields) {
|
|
2034
|
+
if (!f.IsPrimaryKey && !f.Name.startsWith('__mj_')) {
|
|
2035
|
+
candidateNames.add(f.Name);
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
for (const key of Object.keys(baseSnap)) {
|
|
2039
|
+
if (!key.startsWith('__mj_') && key.toLowerCase() !== 'id') {
|
|
2040
|
+
candidateNames.add(key);
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
for (const key of Object.keys(targetSnap)) {
|
|
2044
|
+
if (!key.startsWith('__mj_') && key.toLowerCase() !== 'id') {
|
|
2045
|
+
candidateNames.add(key);
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
const diffs = [];
|
|
2049
|
+
for (const fieldName of candidateNames) {
|
|
2050
|
+
const fieldInfo = entityFields.find((f) => f.Name.trim().toLowerCase() === fieldName.trim().toLowerCase());
|
|
2051
|
+
if (fieldInfo?.IsPrimaryKey || fieldName.startsWith('__mj_')) {
|
|
2052
|
+
continue;
|
|
2053
|
+
}
|
|
2054
|
+
const oldVal = baseSnap[fieldName];
|
|
2055
|
+
const newVal = targetSnap[fieldName];
|
|
2056
|
+
const formattedOld = FormatChangeValue(oldVal, fieldInfo);
|
|
2057
|
+
const formattedNew = FormatChangeValue(newVal, fieldInfo);
|
|
2058
|
+
if (formattedOld === formattedNew) {
|
|
2059
|
+
continue;
|
|
2060
|
+
}
|
|
2061
|
+
diffs.push(this.buildFieldChangeInfo({
|
|
2062
|
+
field: fieldInfo?.Name || fieldName,
|
|
2063
|
+
oldValue: oldVal,
|
|
2064
|
+
newValue: newVal,
|
|
2065
|
+
}));
|
|
2066
|
+
}
|
|
2067
|
+
return diffs;
|
|
2068
|
+
}
|
|
1088
2069
|
/**
|
|
1089
2070
|
* Called when the user confirms the restore in the embedded panel.
|
|
1090
2071
|
* Translates the panel's RestoreCommitEvent into the broader-shape
|
|
@@ -1126,7 +2107,8 @@ export class RecordChangesComponent extends BaseAngularComponent {
|
|
|
1126
2107
|
* (e.g., it's been pruned from history) or when this row isn't a restore.
|
|
1127
2108
|
*/
|
|
1128
2109
|
GetRestoredFromSourceChange(change) {
|
|
1129
|
-
const
|
|
2110
|
+
const withLineage = change;
|
|
2111
|
+
const sourceId = withLineage.RestoredFromID;
|
|
1130
2112
|
if (!sourceId)
|
|
1131
2113
|
return null;
|
|
1132
2114
|
return this.viewDataById.get(NormalizeUUID(sourceId)) ?? null;
|
|
@@ -1556,11 +2538,11 @@ export class RecordChangesComponent extends BaseAngularComponent {
|
|
|
1556
2538
|
return div.innerHTML;
|
|
1557
2539
|
}
|
|
1558
2540
|
static ɵfac = function RecordChangesComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RecordChangesComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i1.MJNotificationService), i0.ɵɵdirectiveInject(i2.DomSanitizer)); };
|
|
1559
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RecordChangesComponent, selectors: [["mj-record-changes"]], inputs: { record: "record", AllowRestore: "AllowRestore" }, outputs: { DialogClosed: "DialogClosed", dialogClosed: "dialogClosed", RestoreRequested: "RestoreRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 13, consts: [[3, "Closed", "Mode", "Title", "Visible", "Resizable", "MinWidthPx", "MaxWidthRatio"], ["text", "Loading history...", "size", "medium"], [1, "rc-container"], [3, "RestoreConfirmed", "RestoreCancelled", "Visible", "Mode", "RecordChange", "LiveRecord"], [1, "rc-wizard-overlay"], [1, "rc-
|
|
2541
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RecordChangesComponent, selectors: [["mj-record-changes"]], inputs: { record: "record", AllowRestore: "AllowRestore", PreviewedChangeID: "PreviewedChangeID", BurstResolution: "BurstResolution", BurstCoalesceStrategy: "BurstCoalesceStrategy", BurstSessionGapHours: "BurstSessionGapHours", BurstMaxClusters: "BurstMaxClusters", BurstEraZoomThreshold: "BurstEraZoomThreshold", AllowBurstZoom: "AllowBurstZoom" }, outputs: { DialogClosed: "DialogClosed", dialogClosed: "dialogClosed", PreviewVersionSelected: "PreviewVersionSelected", RestoreRequested: "RestoreRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 13, consts: [[3, "Closed", "Mode", "Title", "Visible", "Resizable", "MinWidthPx", "MaxWidthRatio"], ["text", "Loading history...", "size", "medium"], [1, "rc-container"], [3, "RestoreConfirmed", "RestoreCancelled", "Visible", "Mode", "RecordChange", "LiveRecord"], [1, "rc-wizard-overlay"], [1, "rc-page-header"], [1, "rc-header-main"], [1, "rc-header-title-row"], [1, "rc-entity-badge", "rc-page-subtitle"], ["aria-hidden", "true"], [1, "rc-page-title"], [1, "rc-header-stats-row"], [1, "rc-header-actions"], ["type", "button", "aria-label", "Compare any two versions", 1, "rc-compare-toggle-btn", 3, "active"], ["type", "button", 1, "rc-labels-toggle-btn", 3, "active"], ["type", "button", "title", "Create a version label snapshot for this record", 1, "rc-create-label-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-tag"], ["role", "region", "aria-label", "Cross-version diff comparison", 1, "rc-compare-panel"], [1, "rc-labels-tray"], ["Icon", "fa-solid fa-clock-rotate-left", "Title", "No Change History", "Message", "This record doesn't have any tracked changes yet. Changes will appear here automatically as edits are made.", "Size", "large"], [1, "rc-change-count"], ["aria-label", "Contributors", 1, "rc-contributor-stack"], [1, "rc-latest-time"], [1, "rc-contributor-avatar", 3, "title"], ["type", "button", "aria-label", "Compare any two versions", 1, "rc-compare-toggle-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-code-compare"], ["type", "button", 1, "rc-labels-toggle-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-tags"], ["aria-hidden", "true", 1, "fa-solid"], [1, "rc-compare-toolbar"], [1, "rc-compare-slot"], [1, "rc-compare-badge", "rc-compare-badge--base"], ["aria-label", "Base version vA", 1, "rc-compare-select", 3, "change", "value"], ["value", "__CURRENT__", 3, "selected"], [3, "value", "selected"], ["type", "button", "aria-label", "Swap comparison versions", 1, "rc-compare-swap-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-right-left"], [1, "rc-compare-badge", "rc-compare-badge--target"], ["aria-label", "Target version vB", 1, "rc-compare-select", 3, "change", "value"], ["type", "button", "aria-label", "Preview base version in form", 1, "rc-compare-action-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-eye"], ["type", "button", "aria-label", "Restore base version", 1, "rc-compare-action-btn"], ["type", "button", "aria-label", "Restore base version", 1, "rc-compare-action-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-clock-rotate-left"], ["type", "button", "aria-label", "Preview target version in form", 1, "rc-compare-action-btn", 3, "click"], ["type", "button", "aria-label", "Restore target version", 1, "rc-compare-action-btn"], ["type", "button", "aria-label", "Restore target version", 1, "rc-compare-action-btn", 3, "click"], [1, "rc-compare-empty"], ["aria-hidden", "true", 1, "fa-solid", "fa-circle-check"], [1, "rc-compare-summary"], [1, "rc-compare-diff-list"], [1, "rc-field-row"], [1, "rc-field-label"], [1, "rc-field-values"], [1, "rc-bool-change"], [1, "rc-atomic-change"], [1, "rc-text-diff", 3, "innerHTML"], [1, "rc-bool-dot"], [1, "rc-bool-label", "old"], ["aria-hidden", "true", 1, "fa-solid", "fa-arrow-right", "rc-val-arrow"], [1, "rc-bool-label", "new"], [1, "rc-val-old"], [1, "rc-val-new"], [1, "rc-labels-list"], [1, "rc-label-chip", 3, "title"], [1, "fa-solid", "fa-tag", "rc-label-chip-icon"], [1, "rc-label-chip-name"], [1, "rc-label-chip-meta"], [1, "rc-label-chip-status"], [1, "rc-label-chip-items"], [1, "rc-empty-state-hint"], [1, "fa-solid", "fa-shield-halved"], ["Title", "Editing sessions", "TitleIcon", "fa-solid fa-wave-square", "AriaLabel", "Change activity bursts over time", "ItemSingularNoun", "change", "ItemPluralNoun", "changes", 3, "SelectedClusterKeyChange", "AfterClustersRebuild", "FilterChanged", "Items", "Categories", "Resolution", "CoalesceStrategy", "SessionGapHours", "MaxClusters", "EraZoomThreshold", "AllowZoom", "SelectedClusterKey"], [1, "rc-filter-bar"], [1, "rc-search-wrap"], ["aria-hidden", "true", 1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search changes...", "aria-label", "Search record changes", 1, "rc-search-box", 3, "ngModelChange", "input", "ngModel"], ["type", "button", 1, "rc-filter-pill", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-layer-group"], [1, "rc-filter-results"], [1, "rc-timeline"], ["Variant", "no-results", "Icon", "fa-solid fa-filter", "Title", "No changes match your current filters", "ActionText", "Clear filters", "ActionIcon", "fa-solid fa-rotate-left"], [1, "rc-filter-overflow-wrap"], ["type", "button", 1, "rc-filter-pill", 3, "active", "rc-filter-pill-restore"], [1, "rc-filter-pill-count"], ["type", "button", 1, "rc-filter-pill", "rc-filter-pill-overflow", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-sliders"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down", "rc-filter-overflow-caret"], [1, "rc-filter-overflow-backdrop", 3, "click"], ["role", "menu", 1, "rc-filter-overflow-popover"], [1, "rc-filter-overflow-header"], [1, "rc-filter-overflow-row", 3, "rc-filter-overflow-row-restore"], [1, "rc-filter-overflow-actions"], ["type", "button", 1, "rc-filter-overflow-clear", 3, "click"], ["type", "button", 1, "rc-filter-overflow-done", 3, "click"], [1, "rc-filter-overflow-row"], ["type", "checkbox", 3, "change", "checked"], [1, "rc-filter-overflow-label"], [1, "rc-filter-overflow-count"], [1, "rc-clear-filters-link", 3, "click"], ["Variant", "no-results", "Icon", "fa-solid fa-filter", "Title", "No changes match your current filters", "ActionText", "Clear filters", "ActionIcon", "fa-solid fa-rotate-left", 3, "Action"], [1, "rc-date-group"], [1, "rc-date-label"], [1, "rc-card", 3, "class", "expanded", "rc-card-restore", "rc-card-highlight", "rc-card-previewing"], [1, "rc-card", 3, "keydown"], [1, "rc-card-header", 3, "click"], [1, "rc-card-header-left"], [1, "rc-card-type-badge"], [1, "rc-card-summary"], ["title", "This version is currently rendered inside the form", 1, "rc-previewing-chip"], [1, "rc-card-meta"], [1, "rc-card-compare-pills"], [1, "rc-card-user"], [1, "rc-avatar"], [1, "rc-card-time", 3, "title"], [1, "rc-card-source"], [1, "rc-card-status"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down", "rc-card-chevron"], [1, "rc-card-body"], [1, "rc-restored-chip", 3, "title"], ["title", "Source version was not loaded into this view", 1, "rc-restored-chip", "rc-restored-chip-orphan"], [1, "rc-restored-chip", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-link"], ["type", "button", "aria-label", "Set as Base Version A", 1, "rc-card-compare-pill", 3, "click"], ["type", "button", "aria-label", "Set as Target Version B", 1, "rc-card-compare-pill", "rc-card-compare-pill--target", 3, "click"], [1, "rc-restore-reason"], [1, "rc-deletion-note"], [1, "rc-comments"], [1, "rc-errors"], [1, "rc-restore-action"], [1, "rc-restore-reason-label"], [1, "rc-restore-reason-text"], ["aria-hidden", "true", 1, "fa-solid", "fa-trash"], ["aria-hidden", "true", 1, "fa-solid", "fa-comment"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle"], [1, "rc-error-log"], ["type", "button", "title", "Render this historical version's field values directly inside the form", 1, "rc-preview-form-btn", 3, "rc-preview-form-btn--active"], ["type", "button", "title", "Restore the entire record to its state at this version", 1, "rc-restore-btn"], ["type", "button", "title", "Render this historical version's field values directly inside the form", 1, "rc-preview-form-btn", 3, "click"], ["type", "button", "title", "Restore the entire record to its state at this version", 1, "rc-restore-btn", 3, "click"], [1, "rc-wizard-overlay", 3, "click"], [1, "rc-wizard-container", 3, "click"], [3, "Created", "Cancel", "PreselectedEntity", "PreselectedRecordIds"]], template: function RecordChangesComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1560
2542
|
i0.ɵɵelementStart(0, "mj-slide-panel", 0);
|
|
1561
2543
|
i0.ɵɵlistener("Closed", function RecordChangesComponent_Template_mj_slide_panel_Closed_0_listener() { return ctx.OnClose(); });
|
|
1562
2544
|
i0.ɵɵconditionalCreate(1, RecordChangesComponent_Conditional_1_Template, 1, 0, "mj-loading", 1);
|
|
1563
|
-
i0.ɵɵconditionalCreate(2, RecordChangesComponent_Conditional_2_Template,
|
|
2545
|
+
i0.ɵɵconditionalCreate(2, RecordChangesComponent_Conditional_2_Template, 21, 10, "div", 2);
|
|
1564
2546
|
i0.ɵɵelementStart(3, "mj-restore-preview-panel", 3);
|
|
1565
2547
|
i0.ɵɵlistener("RestoreConfirmed", function RecordChangesComponent_Template_mj_restore_preview_panel_RestoreConfirmed_3_listener($event) { return ctx.OnRestorePanelConfirmed($event); })("RestoreCancelled", function RecordChangesComponent_Template_mj_restore_preview_panel_RestoreCancelled_3_listener() { return ctx.OnRestorePanelCancelled(); });
|
|
1566
2548
|
i0.ɵɵelementEnd();
|
|
@@ -1576,11 +2558,11 @@ export class RecordChangesComponent extends BaseAngularComponent {
|
|
|
1576
2558
|
i0.ɵɵproperty("Visible", ctx.RestorePreviewVisible)("Mode", "live")("RecordChange", ctx.RestorePreviewChange)("LiveRecord", ctx.record);
|
|
1577
2559
|
i0.ɵɵadvance();
|
|
1578
2560
|
i0.ɵɵconditional(ctx.ShowCreateWizard ? 4 : -1);
|
|
1579
|
-
} }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent, i5.MjLabelCreateComponent, i6.MjSlidePanelComponent, i6.MJEmptyStateComponent, i7.RestorePreviewPanelComponent, i8.DatePipe], styles: ["/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Record Changes \u2014 Option A \"Clean Timeline\"\n Linear / Notion-inspired minimal timeline design\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* \u2500\u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Version Labels Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-labels-section {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 12px 16px;\n margin-bottom: 20px;\n border: 1px solid var(--mj-border-default);\n}\n\n.rc-labels-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.rc-labels-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.rc-labels-title i { color: var(--mj-brand-primary); }\n\n.rc-labels-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-create-label-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-create-label-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.rc-labels-loading {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding: 4px 0;\n}\n\n.rc-labels-loading i { margin-right: 4px; }\n\n.rc-labels-empty {\n font-size: 12px;\n color: var(--mj-text-disabled);\n font-style: italic;\n padding: 4px 0;\n}\n\n.rc-labels-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.rc-label-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n cursor: default;\n}\n\n.rc-label-chip:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-label-chip-icon { color: var(--mj-brand-primary); font-size: 10px; }\n\n.rc-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.rc-label-chip-meta {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.rc-label-chip-status {\n padding: 1px 5px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 9px;\n letter-spacing: 0.03em;\n}\n\n.label-status-active { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.label-status-archived { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.label-status-restored { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n\n.rc-label-chip-items { white-space: nowrap; }\n\n/* \u2500\u2500\u2500 Empty State (hint projected into <mj-empty-state> default slot) \u2500\u2500\u2500 */\n.rc-empty-state-hint {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: var(--mj-space-4);\n padding: 8px 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 20px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.rc-empty-state-hint i { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Page Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n padding-bottom: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-page-title {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.rc-page-subtitle {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n.rc-header-meta { text-align: right; }\n\n.rc-entity-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.rc-change-count {\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n/* \u2500\u2500\u2500 Filter Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-filter-bar {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n align-items: center;\n}\n\n.rc-search-wrap {\n position: relative;\n flex: 1;\n min-width: 180px;\n}\n\n.rc-search-wrap i {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-disabled);\n font-size: 13px;\n pointer-events: none;\n}\n\n.rc-search-box {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n outline: none;\n color: var(--mj-text-primary);\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.rc-search-box:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-search-box::placeholder { color: var(--mj-text-disabled); }\n\n.rc-filter-pill {\n padding: 7px 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n\n.rc-filter-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.rc-filter-pill.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.rc-filter-results {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-clear-filters-link {\n background: none;\n border: none;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 0;\n text-decoration: underline;\n}\n\n.rc-clear-filters-link:hover { color: var(--mj-brand-primary-hover); }\n\n/* \u2500\u2500\u2500 Timeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-timeline {\n position: relative;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Vertical line running through the timeline */\n.rc-timeline::before {\n content: '';\n position: absolute;\n left: 15px;\n top: 24px;\n bottom: 0;\n width: 2px;\n background: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Date Group \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-date-group { margin-bottom: 8px; }\n\n.rc-date-label {\n position: relative;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: var(--mj-text-disabled);\n padding: 16px 0 12px 44px;\n}\n\n/* Date dot on the timeline line */\n.rc-date-label::before {\n content: '';\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--mj-border-default);\n border: 2px solid var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Change Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card {\n position: relative;\n margin-left: 44px;\n margin-bottom: 12px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s;\n overflow: hidden;\n}\n\n.rc-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-card:focus {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* Colored dot on the timeline line for each card */\n.rc-card::before {\n content: '';\n position: absolute;\n left: -23px;\n top: 20px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n z-index: 1;\n}\n\n.rc-card.type-update::before {\n background: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-card.type-create::before {\n background: var(--mj-status-success);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-success) 15%, transparent);\n}\n\n.rc-card.type-delete::before {\n background: var(--mj-status-error);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n}\n\n/* \u2500\u2500\u2500 Card Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-header {\n padding: 14px 18px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n user-select: none;\n gap: 12px;\n}\n\n.rc-card-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n flex: 1;\n /* Allow the lineage chip to wrap to a second line on narrow panel widths\n instead of squeezing the title text into a \"Name and Description c...\"\n truncation. The badge stays on the first line; chip wraps gracefully. */\n flex-wrap: wrap;\n row-gap: 6px;\n}\n\n.rc-card-type-badge {\n padding: 3px 10px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.3px;\n text-transform: uppercase;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.type-update .rc-card-type-badge { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.type-create .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.type-delete .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n.rc-card-summary {\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-card-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.rc-card-user {\n display: flex;\n align-items: center;\n gap: 5px;\n white-space: nowrap;\n}\n\n.rc-avatar {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 8px;\n font-weight: 700;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.rc-card-time { white-space: nowrap; }\n\n.rc-card-source {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.source-internal { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.source-external { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n.rc-card-status {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n white-space: nowrap;\n}\n\n.status-complete { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-pending { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.status-unknown { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n.rc-card-chevron {\n color: var(--mj-text-disabled);\n transition: transform 0.2s;\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.rc-card.expanded .rc-card-chevron { transform: rotate(180deg); }\n\n/* \u2500\u2500\u2500 Card Body \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-body {\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Field Row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-field-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-field-row:last-child { border-bottom: none; }\n\n.rc-field-label {\n width: 140px;\n min-width: 140px;\n padding: 12px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.rc-field-values {\n flex: 1;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* \u2500\u2500\u2500 Atomic Change (numbers, dates) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-atomic-change {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.rc-val-old {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n font-weight: 400;\n}\n\n.rc-val-arrow {\n color: var(--mj-border-strong);\n font-size: 11px;\n flex-shrink: 0;\n}\n\n.rc-val-new {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n/* \u2500\u2500\u2500 Boolean Change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-bool-change {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-bool-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.rc-bool-dot.on { background: var(--mj-status-success); }\n.rc-bool-dot.off { background: var(--mj-border-strong); }\n\n.rc-bool-label {\n font-size: 13px;\n font-weight: 500;\n}\n\n.rc-bool-label.old {\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n}\n\n.rc-bool-label.new.active { color: var(--mj-status-success); }\n.rc-bool-label.new.inactive { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Text Diff (strings only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-text-diff {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n line-height: 1.6;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.rc-diff-added {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n padding: 1px 3px;\n border-radius: 3px;\n}\n\n.rc-diff-removed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n padding: 1px 3px;\n border-radius: 3px;\n text-decoration: line-through;\n}\n\n.rc-diff-unchanged {\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Deletion Note \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-deletion-note {\n padding: 16px 18px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-style: italic;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-deletion-note i {\n color: var(--mj-status-error);\n font-size: 14px;\n}\n\n/* \u2500\u2500\u2500 Comments & Errors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-comments {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-comments i {\n color: var(--mj-brand-primary);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-errors {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-errors i {\n color: var(--mj-status-error);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-error-log {\n background: var(--mj-bg-surface);\n padding: 8px;\n border-radius: 4px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n font-size: 12px;\n color: var(--mj-status-error);\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n flex: 1;\n}\n\n/* \u2500\u2500\u2500 Create Wizard Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-wizard-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-wizard-container {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 600px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 24px;\n animation: rc-slideUp 0.2s ease;\n}\n\n@keyframes rc-fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes rc-slideUp {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* \u2500\u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 768px) {\n .rc-card-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .rc-card-meta {\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .rc-field-row {\n flex-direction: column;\n }\n\n .rc-field-label {\n width: 100%;\n min-width: unset;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n }\n\n .rc-field-values {\n padding: 8px 16px;\n }\n\n .rc-atomic-change {\n flex-wrap: wrap;\n }\n\n .rc-filter-bar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .rc-search-wrap { min-width: unset; }\n\n .rc-filter-pill { justify-content: center; }\n\n .rc-page-header {\n flex-direction: column;\n gap: 12px;\n }\n\n .rc-header-meta { text-align: left; }\n}\n\n@media (max-width: 480px) {\n .rc-container { padding: 12px 16px; }\n\n .rc-card { margin-left: 36px; }\n\n .rc-date-label { padding-left: 36px; }\n\n .rc-card::before { left: -19px; }\n\n .rc-timeline::before { left: 12px; }\n\n .rc-date-label::before { left: 7px; }\n}\n\n/* \u2500\u2500\u2500 Restore Action \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-action {\n display: flex;\n justify-content: flex-end;\n padding-top: 10px;\n margin-top: 10px;\n /* Breathing room from the card's bottom and right edges so the button\n doesn't sit flush against the border. */\n padding-right: 10px;\n padding-bottom: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.rc-restore-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1;\n}\n\n.rc-restore-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-restore-btn:active {\n transform: translateY(1px);\n box-shadow: none;\n}\n\n.rc-restore-btn i {\n font-size: 13px;\n}\n\n/* \u2500\u2500\u2500 Restore Preview Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-preview-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-restore-preview-panel {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 700px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 0;\n animation: rc-slideUp 0.2s ease;\n}\n\n.rc-restore-preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.rc-restore-preview-title i {\n color: var(--mj-brand-primary);\n}\n\n.rc-restore-preview-close {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 16px;\n transition: color 0.15s, background 0.15s;\n}\n\n.rc-restore-preview-close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-restore-preview-meta {\n display: flex;\n gap: 20px;\n padding: 12px 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-empty {\n padding: 24px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.rc-restore-preview-empty i {\n color: var(--mj-text-disabled);\n}\n\n/* Restore Preview Table */\n.rc-restore-preview-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.rc-restore-preview-table th {\n text-align: left;\n padding: 10px 16px;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-table td {\n padding: 10px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n vertical-align: top;\n}\n\n.rc-restore-preview-table tr:last-child td {\n border-bottom: none;\n}\n\n.rc-restore-preview-table tr.rc-diff-changed {\n background: color-mix(in srgb, var(--mj-status-warning) 5%, var(--mj-bg-surface));\n}\n\n.rc-restore-preview-table tr.rc-diff-unchanged {\n opacity: 0.6;\n}\n\n.rc-restore-field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n}\n\n.rc-restore-current {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-secondary);\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-version {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-indicator {\n text-align: center;\n width: 30px;\n}\n\n.rc-diff-changed .rc-restore-indicator i {\n color: var(--mj-status-warning);\n}\n\n.rc-diff-unchanged .rc-restore-indicator i {\n color: var(--mj-status-success);\n font-size: 12px;\n}\n\n/* Restore Preview Actions */\n.rc-restore-preview-actions {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-confirm-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-confirm-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.rc-restore-confirm-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.rc-restore-cancel-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-cancel-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.rc-restore-cancel-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore lineage + conditional filter chips + overflow popover\n * (added with the Restore Prior Version feature)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* \u2500\u2500\u2500 Filter pill enhancements \u2500\u2500\u2500 */\n\n.rc-filter-pill-count {\n margin-left: 4px;\n background: color-mix(in srgb, currentColor 12%, transparent);\n padding: 1px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-filter-pill.active .rc-filter-pill-count {\n background: color-mix(in srgb, var(--mj-text-inverse, #fff) 22%, transparent);\n}\n\n/* Restore-variant pill: violet treatment to set it apart from type pills */\n.rc-filter-pill-restore {\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n color: color-mix(in srgb, var(--mj-status-info) 80%, var(--mj-text-secondary));\n border-color: color-mix(in srgb, var(--mj-status-info) 30%, var(--mj-border-default));\n}\n.rc-filter-pill-restore:hover {\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n.rc-filter-pill-restore.active {\n background: var(--mj-status-info);\n color: var(--mj-text-inverse, #fff);\n border-color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Overflow filter popover \u2500\u2500\u2500 */\n\n.rc-filter-overflow-wrap {\n position: relative;\n display: inline-block;\n}\n\n.rc-filter-pill-overflow {\n /* Overflow trigger inherits the standard filter pill look */\n}\n\n.rc-filter-overflow-caret {\n font-size: 9px;\n margin-left: 2px;\n}\n\n.rc-filter-overflow-backdrop {\n position: fixed;\n inset: 0;\n z-index: 10;\n}\n\n.rc-filter-overflow-popover {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: 11;\n min-width: 240px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 14px 40px rgba(0, 0, 0, 0.18);\n padding: 8px;\n}\n\n.rc-filter-overflow-header {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n font-weight: 600;\n padding: 6px 8px 8px;\n}\n\n.rc-filter-overflow-row {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 7px 8px;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n\n.rc-filter-overflow-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-filter-overflow-row input[type=\"checkbox\"] {\n margin: 0;\n accent-color: var(--mj-brand-primary);\n}\n\n.rc-filter-overflow-row i {\n color: var(--mj-text-muted);\n font-size: 12px;\n width: 14px;\n text-align: center;\n}\n\n.rc-filter-overflow-row-restore i {\n color: var(--mj-status-info);\n}\n\n.rc-filter-overflow-label {\n flex: 1;\n}\n\n.rc-filter-overflow-count {\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 500;\n}\n\n.rc-filter-overflow-actions {\n display: flex;\n justify-content: space-between;\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 8px;\n margin-top: 6px;\n}\n\n.rc-filter-overflow-clear,\n.rc-filter-overflow-done {\n background: none;\n border: none;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 4px 10px;\n border-radius: 5px;\n}\n\n.rc-filter-overflow-clear {\n color: var(--mj-text-muted);\n}\n.rc-filter-overflow-clear:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.rc-filter-overflow-done {\n color: var(--mj-brand-primary);\n}\n.rc-filter-overflow-done:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n/* \u2500\u2500\u2500 Snapshot type badge + card accent \u2500\u2500\u2500 */\n\n.type-snapshot .rc-card-type-badge {\n background: color-mix(in srgb, var(--mj-text-muted) 15%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Restore Source pill (in card meta) \u2500\u2500\u2500 */\n\n.source-restore {\n background: color-mix(in srgb, var(--mj-status-info) 12%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Restore card variant: violet left accent \u2500\u2500\u2500 */\n\n.rc-card.rc-card-restore {\n border-left: 3px solid var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Lineage chip \u2500\u2500\u2500 */\n\n/* Lineage chip \u2014 outline-only \"interactive link\" treatment so it reads as\n distinct from the filled RESTORE badge sitting next to it. The badge says\n \"this row IS a restore\" (filled, static); the chip says \"click here to\n see the source version\" (outline, hoverable). */\n.rc-restored-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n margin-left: 8px;\n padding: 2px 9px;\n border-radius: 11px;\n font-size: 11px;\n font-weight: 500;\n background: transparent;\n color: color-mix(in srgb, var(--mj-status-info) 90%, var(--mj-text-primary));\n border: 1px solid color-mix(in srgb, var(--mj-status-info) 40%, var(--mj-border-default));\n cursor: pointer;\n text-decoration: none;\n white-space: nowrap;\n transition: background-color 0.12s, border-color 0.12s, color 0.12s;\n}\n\n.rc-restored-chip:hover {\n background: color-mix(in srgb, var(--mj-status-info) 12%, transparent);\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n\n.rc-restored-chip i {\n font-size: 10px;\n}\n\n.rc-restored-chip-orphan {\n cursor: default;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n border-color: var(--mj-border-default);\n}\n\n.rc-restored-chip-orphan:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Card highlight (when jumped-to via lineage chip) \u2500\u2500\u2500 */\n\n.rc-card.rc-card-highlight {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n animation: rc-card-pulse 1.4s ease-in-out;\n}\n\n@keyframes rc-card-pulse {\n 0%, 100% { background: var(--mj-bg-surface); }\n 50% { background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface)); }\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore-row badge override + Restore Reason block\n * (mockup-aligned treatment for restore rows in the timeline)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* The base type-update badge styling would otherwise paint a restore row's\n badge blue with \"Update\" text. Override to violet + \"Restore\" text so it\n matches the source pill, lineage chip, and card border. */\n.rc-card-type-badge.rc-card-type-badge-restore {\n background: color-mix(in srgb, var(--mj-status-info) 14%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* Restore reason \u2014 minimal blockquote treatment.\n A thin violet left bar + italic text reads like a margin note rather than\n a heavy callout. Visually connected to the restore family (left bar uses\n the same violet as the badge / source pill / card border) without\n competing with the field-diff rows that follow. */\n.rc-restore-reason {\n /* Indented in from the card body edge so it visually nests one level\n deeper than the field-diff rows that follow, and given generous\n vertical breathing room so it doesn't crowd the lineage chip above\n or the first field row below. */\n margin: 14px 8px 18px 18px;\n padding: 0 0 0 12px;\n border-left: 2px solid color-mix(in srgb, var(--mj-status-info) 55%, var(--mj-border-default));\n display: flex;\n align-items: baseline;\n gap: 8px;\n font-size: 13px;\n line-height: 1.5;\n}\n\n.rc-restore-reason-label {\n flex-shrink: 0;\n font-size: 11px;\n font-weight: 600;\n color: color-mix(in srgb, var(--mj-status-info) 75%, var(--mj-text-muted));\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n.rc-restore-reason-text {\n color: var(--mj-text-secondary);\n font-style: italic;\n}\n"], encapsulation: 2, changeDetection: 0 });
|
|
2561
|
+
} }, dependencies: [i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent, i5.MjLabelCreateComponent, i6.MjSlidePanelComponent, i6.MJEmptyStateComponent, i6.MJBurstClusterStripComponent, i7.RestorePreviewPanelComponent, i8.DatePipe], styles: ["/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Record Changes \u2014 Option A \"Clean Timeline\"\n Linear / Notion-inspired minimal timeline design\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* \u2500\u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Unified Header & Compact Labels Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 16px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-header-main {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n flex: 1;\n}\n\n.rc-header-title-row {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.rc-entity-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 24%, var(--mj-bg-surface));\n margin: 0;\n}\n\n.rc-header-sep {\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.rc-page-title {\n font-size: 17px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.rc-header-stats-row {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.rc-change-count {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.rc-change-count strong {\n color: var(--mj-text-primary);\n font-weight: 700;\n}\n\n.rc-stat-dot {\n color: var(--mj-text-disabled);\n}\n\n.rc-stat-latest {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n color: var(--mj-text-muted);\n}\n\n.rc-contributor-stack {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.rc-contributor-avatar {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 16%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1.5px solid var(--mj-bg-surface-card);\n font-size: 9px;\n font-weight: 700;\n margin-left: -5px;\n}\n\n.rc-contributor-avatar:first-child {\n margin-left: 0;\n}\n\n.rc-contributor-label {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-left: 2px;\n}\n\n.rc-header-actions {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.rc-labels-toggle-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-labels-toggle-btn:hover,\n.rc-labels-toggle-btn.active {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.rc-labels-toggle-btn i:first-child {\n color: var(--mj-brand-primary);\n font-size: 11px;\n}\n\n.rc-labels-caret {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.rc-labels-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: 9px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-create-label-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 11px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-create-label-btn:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n/* \u2500\u2500\u2500 Collapsible Version Labels Tray \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-labels-tray {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n padding: 10px 14px;\n margin-bottom: 14px;\n border: 1px solid var(--mj-border-default);\n}\n\n.rc-labels-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.rc-label-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n cursor: default;\n}\n\n.rc-label-chip:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-label-chip-icon { color: var(--mj-brand-primary); font-size: 10px; }\n\n.rc-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.rc-label-chip-meta {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.rc-label-chip-status {\n padding: 1px 5px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 9px;\n letter-spacing: 0.03em;\n}\n\n.label-status-active { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.label-status-archived { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.label-status-restored { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n\n.rc-label-chip-items { white-space: nowrap; }\n\n/* \u2500\u2500\u2500 Activity Over Time Burst-Aware Cluster Strip \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-activity-chart {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 12px 14px 10px;\n margin-bottom: 16px;\n}\n\n.rc-activity-chart-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n margin-bottom: 10px;\n flex-wrap: wrap;\n}\n\n.rc-activity-chart-title {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-secondary);\n}\n\n.rc-activity-chart-title i {\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n.rc-activity-chart-meta {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.rc-activity-bucket-pill {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 2px 8px;\n border-radius: 999px;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 35%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s ease, color 0.15s ease;\n}\n\n.rc-activity-bucket-pill:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.rc-activity-legend {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.rc-legend-item {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.rc-legend-dot {\n width: 7px;\n height: 7px;\n border-radius: 2px;\n}\n\n.rc-legend-dot--update { background: var(--mj-brand-primary); }\n.rc-legend-dot--create { background: var(--mj-status-success); }\n.rc-legend-dot--restore { background: var(--mj-status-warning); }\n\n.rc-burst-track {\n display: flex;\n align-items: stretch;\n gap: 0;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 8px 10px;\n overflow-x: auto;\n}\n\n.rc-burst-node {\n flex: 1 1 0;\n min-width: 78px;\n border-radius: 8px;\n border: 1px solid transparent;\n background: var(--mj-bg-surface);\n padding: 7px 8px 6px;\n cursor: pointer;\n transition: border-color 0.14s ease, box-shadow 0.14s ease, transform 0.14s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n box-shadow: var(--mj-shadow-sm);\n font-family: inherit;\n}\n\n.rc-burst-node:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-border-default));\n transform: translateY(-1px);\n}\n\n.rc-burst-node--selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 22%, transparent);\n}\n\n.rc-burst-pips {\n display: flex;\n align-items: flex-end;\n justify-content: center;\n gap: 3px;\n height: 28px;\n width: 100%;\n padding: 0 2px;\n}\n\n.rc-burst-pip {\n width: 6px;\n height: 18px;\n border-radius: 2px 2px 1px 1px;\n transition: transform 0.12s ease;\n flex-shrink: 0;\n}\n\n.rc-burst-pip--create { background: var(--mj-status-success); height: 22px; }\n.rc-burst-pip--update { background: var(--mj-brand-primary); height: 18px; }\n.rc-burst-pip--restore { background: var(--mj-status-warning); height: 24px; }\n.rc-burst-pip--delete { background: var(--mj-status-error); height: 20px; }\n\n.rc-burst-pip-overflow {\n font-size: 9px;\n font-weight: 700;\n color: var(--mj-text-muted);\n margin-left: 2px;\n align-self: center;\n}\n\n.rc-burst-count {\n font-size: 10px;\n font-weight: 700;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken);\n padding: 1px 6px;\n border-radius: 999px;\n line-height: 1.3;\n white-space: nowrap;\n}\n\n.rc-burst-node--selected .rc-burst-count {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.rc-burst-date {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n line-height: 1.2;\n}\n\n.rc-burst-sub {\n font-size: 9px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n line-height: 1.1;\n}\n\n.rc-gap-connector {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 0 5px;\n min-width: 44px;\n position: relative;\n flex-shrink: 0;\n}\n\n.rc-gap-line {\n width: 100%;\n border-top: 1.5px dashed var(--mj-border-default);\n position: relative;\n}\n\n.rc-gap-pill {\n margin-top: -8px;\n background: var(--mj-bg-surface-sunken);\n padding: 1px 4px;\n font-size: 9px;\n font-weight: 600;\n color: var(--mj-text-muted);\n border-radius: 4px;\n white-space: nowrap;\n}\n\n/* \u2500\u2500\u2500 Empty State (hint projected into <mj-empty-state> default slot) \u2500\u2500\u2500 */\n.rc-empty-state-hint {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: var(--mj-space-4);\n padding: 8px 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 20px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.rc-empty-state-hint i { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Filter Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-filter-bar {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n align-items: center;\n}\n\n.rc-search-wrap {\n position: relative;\n flex: 1;\n min-width: 180px;\n}\n\n.rc-search-wrap i {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-disabled);\n font-size: 13px;\n pointer-events: none;\n}\n\n.rc-search-box {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n outline: none;\n color: var(--mj-text-primary);\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.rc-search-box:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-search-box::placeholder { color: var(--mj-text-disabled); }\n\n.rc-filter-pill {\n padding: 7px 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n\n.rc-filter-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.rc-filter-pill.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.rc-filter-results {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-clear-filters-link {\n background: none;\n border: none;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 0;\n text-decoration: underline;\n}\n\n.rc-clear-filters-link:hover { color: var(--mj-brand-primary-hover); }\n\n/* \u2500\u2500\u2500 Timeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-timeline {\n position: relative;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Vertical line running through the timeline */\n.rc-timeline::before {\n content: '';\n position: absolute;\n left: 15px;\n top: 24px;\n bottom: 0;\n width: 2px;\n background: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Date Group \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-date-group { margin-bottom: 8px; }\n\n.rc-date-label {\n position: relative;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: var(--mj-text-disabled);\n padding: 16px 0 12px 44px;\n}\n\n/* Date dot on the timeline line */\n.rc-date-label::before {\n content: '';\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--mj-border-default);\n border: 2px solid var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Change Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card {\n position: relative;\n margin-left: 44px;\n margin-bottom: 12px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s;\n overflow: hidden;\n}\n\n.rc-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-card:focus {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* Colored dot on the timeline line for each card */\n.rc-card::before {\n content: '';\n position: absolute;\n left: -23px;\n top: 20px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n z-index: 1;\n}\n\n.rc-card.type-update::before {\n background: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-card.type-create::before {\n background: var(--mj-status-success);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-success) 15%, transparent);\n}\n\n.rc-card.type-delete::before {\n background: var(--mj-status-error);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n}\n\n/* \u2500\u2500\u2500 Card Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-header {\n padding: 14px 18px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n user-select: none;\n gap: 12px;\n}\n\n.rc-card-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n flex: 1;\n /* Allow the lineage chip to wrap to a second line on narrow panel widths\n instead of squeezing the title text into a \"Name and Description c...\"\n truncation. The badge stays on the first line; chip wraps gracefully. */\n flex-wrap: wrap;\n row-gap: 6px;\n}\n\n.rc-card-type-badge {\n padding: 3px 10px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.3px;\n text-transform: uppercase;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.type-update .rc-card-type-badge { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.type-create .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.type-delete .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n.rc-card-summary {\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-card-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.rc-card-user {\n display: flex;\n align-items: center;\n gap: 5px;\n white-space: nowrap;\n}\n\n.rc-avatar {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 8px;\n font-weight: 700;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.rc-card-time { white-space: nowrap; }\n\n.rc-card-source {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.source-internal { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.source-external { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n.rc-card-status {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n white-space: nowrap;\n}\n\n.status-complete { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-pending { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.status-unknown { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n.rc-card-chevron {\n color: var(--mj-text-disabled);\n transition: transform 0.2s;\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.rc-card.expanded .rc-card-chevron { transform: rotate(180deg); }\n\n/* \u2500\u2500\u2500 Card Body \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-body {\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Field Row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-field-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-field-row:last-child { border-bottom: none; }\n\n.rc-field-label {\n width: 140px;\n min-width: 140px;\n padding: 12px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.rc-field-values {\n flex: 1;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* \u2500\u2500\u2500 Atomic Change (numbers, dates) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-atomic-change {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.rc-val-old {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n font-weight: 400;\n}\n\n.rc-val-arrow {\n color: var(--mj-border-strong);\n font-size: 11px;\n flex-shrink: 0;\n}\n\n.rc-val-new {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n/* \u2500\u2500\u2500 Boolean Change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-bool-change {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-bool-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.rc-bool-dot.on { background: var(--mj-status-success); }\n.rc-bool-dot.off { background: var(--mj-border-strong); }\n\n.rc-bool-label {\n font-size: 13px;\n font-weight: 500;\n}\n\n.rc-bool-label.old {\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n}\n\n.rc-bool-label.new.active { color: var(--mj-status-success); }\n.rc-bool-label.new.inactive { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Text Diff (strings only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-text-diff {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n line-height: 1.6;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.rc-diff-added {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n padding: 1px 3px;\n border-radius: 3px;\n}\n\n.rc-diff-removed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n padding: 1px 3px;\n border-radius: 3px;\n text-decoration: line-through;\n}\n\n.rc-diff-unchanged {\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Deletion Note \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-deletion-note {\n padding: 16px 18px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-style: italic;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-deletion-note i {\n color: var(--mj-status-error);\n font-size: 14px;\n}\n\n/* \u2500\u2500\u2500 Comments & Errors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-comments {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-comments i {\n color: var(--mj-brand-primary);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-errors {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-errors i {\n color: var(--mj-status-error);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-error-log {\n background: var(--mj-bg-surface);\n padding: 8px;\n border-radius: 4px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n font-size: 12px;\n color: var(--mj-status-error);\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n flex: 1;\n}\n\n/* \u2500\u2500\u2500 Create Wizard Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-wizard-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-wizard-container {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 600px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 24px;\n animation: rc-slideUp 0.2s ease;\n}\n\n@keyframes rc-fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes rc-slideUp {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* \u2500\u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 768px) {\n .rc-card-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .rc-card-meta {\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .rc-field-row {\n flex-direction: column;\n }\n\n .rc-field-label {\n width: 100%;\n min-width: unset;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n }\n\n .rc-field-values {\n padding: 8px 16px;\n }\n\n .rc-atomic-change {\n flex-wrap: wrap;\n }\n\n .rc-filter-bar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .rc-search-wrap { min-width: unset; }\n\n .rc-filter-pill { justify-content: center; }\n\n .rc-page-header {\n flex-direction: column;\n gap: 12px;\n }\n\n .rc-header-meta { text-align: left; }\n}\n\n@media (max-width: 480px) {\n .rc-container { padding: 12px 16px; }\n\n .rc-card { margin-left: 36px; }\n\n .rc-date-label { padding-left: 36px; }\n\n .rc-card::before { left: -19px; }\n\n .rc-timeline::before { left: 12px; }\n\n .rc-date-label::before { left: 7px; }\n}\n\n/* \u2500\u2500\u2500 Restore & Form Preview Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card.rc-card-previewing {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.rc-previewing-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 2px 8px;\n font-size: 11px;\n font-weight: 600;\n border-radius: 999px;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.rc-card-preview-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1.1;\n}\n\n.rc-card-preview-btn:hover {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.rc-card-preview-btn--active {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n}\n\n.rc-restore-action {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n padding-top: 10px;\n margin-top: 10px;\n /* Breathing room from the card's bottom and right edges so the button\n doesn't sit flush against the border. */\n padding-right: 10px;\n padding-bottom: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.rc-preview-form-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1;\n}\n\n.rc-preview-form-btn:hover {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.rc-preview-form-btn--active {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.rc-restore-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1;\n}\n\n.rc-restore-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-restore-btn:active {\n transform: translateY(1px);\n box-shadow: none;\n}\n\n.rc-restore-btn i {\n font-size: 13px;\n}\n\n/* \u2500\u2500\u2500 Restore Preview Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-preview-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-restore-preview-panel {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 700px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 0;\n animation: rc-slideUp 0.2s ease;\n}\n\n.rc-restore-preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.rc-restore-preview-title i {\n color: var(--mj-brand-primary);\n}\n\n.rc-restore-preview-close {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 16px;\n transition: color 0.15s, background 0.15s;\n}\n\n.rc-restore-preview-close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-restore-preview-meta {\n display: flex;\n gap: 20px;\n padding: 12px 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-empty {\n padding: 24px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.rc-restore-preview-empty i {\n color: var(--mj-text-disabled);\n}\n\n/* Restore Preview Table */\n.rc-restore-preview-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.rc-restore-preview-table th {\n text-align: left;\n padding: 10px 16px;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-table td {\n padding: 10px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n vertical-align: top;\n}\n\n.rc-restore-preview-table tr:last-child td {\n border-bottom: none;\n}\n\n.rc-restore-preview-table tr.rc-diff-changed {\n background: color-mix(in srgb, var(--mj-status-warning) 5%, var(--mj-bg-surface));\n}\n\n.rc-restore-preview-table tr.rc-diff-unchanged {\n opacity: 0.6;\n}\n\n.rc-restore-field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n}\n\n.rc-restore-current {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-secondary);\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-version {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-indicator {\n text-align: center;\n width: 30px;\n}\n\n.rc-diff-changed .rc-restore-indicator i {\n color: var(--mj-status-warning);\n}\n\n.rc-diff-unchanged .rc-restore-indicator i {\n color: var(--mj-status-success);\n font-size: 12px;\n}\n\n/* Restore Preview Actions */\n.rc-restore-preview-actions {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-confirm-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-confirm-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.rc-restore-confirm-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.rc-restore-cancel-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-cancel-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.rc-restore-cancel-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore lineage + conditional filter chips + overflow popover\n * (added with the Restore Prior Version feature)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* \u2500\u2500\u2500 Filter pill enhancements \u2500\u2500\u2500 */\n\n.rc-filter-pill-count {\n margin-left: 4px;\n background: color-mix(in srgb, currentColor 12%, transparent);\n padding: 1px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-filter-pill.active .rc-filter-pill-count {\n background: color-mix(in srgb, var(--mj-text-inverse, #fff) 22%, transparent);\n}\n\n/* Restore-variant pill: violet treatment to set it apart from type pills */\n.rc-filter-pill-restore {\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n color: color-mix(in srgb, var(--mj-status-info) 80%, var(--mj-text-secondary));\n border-color: color-mix(in srgb, var(--mj-status-info) 30%, var(--mj-border-default));\n}\n.rc-filter-pill-restore:hover {\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n.rc-filter-pill-restore.active {\n background: var(--mj-status-info);\n color: var(--mj-text-inverse, #fff);\n border-color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Overflow filter popover \u2500\u2500\u2500 */\n\n.rc-filter-overflow-wrap {\n position: relative;\n display: inline-block;\n}\n\n.rc-filter-pill-overflow {\n /* Overflow trigger inherits the standard filter pill look */\n}\n\n.rc-filter-overflow-caret {\n font-size: 9px;\n margin-left: 2px;\n}\n\n.rc-filter-overflow-backdrop {\n position: fixed;\n inset: 0;\n z-index: 10;\n}\n\n.rc-filter-overflow-popover {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: 11;\n min-width: 240px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 14px 40px rgba(0, 0, 0, 0.18);\n padding: 8px;\n}\n\n.rc-filter-overflow-header {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n font-weight: 600;\n padding: 6px 8px 8px;\n}\n\n.rc-filter-overflow-row {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 7px 8px;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n\n.rc-filter-overflow-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-filter-overflow-row input[type=\"checkbox\"] {\n margin: 0;\n accent-color: var(--mj-brand-primary);\n}\n\n.rc-filter-overflow-row i {\n color: var(--mj-text-muted);\n font-size: 12px;\n width: 14px;\n text-align: center;\n}\n\n.rc-filter-overflow-row-restore i {\n color: var(--mj-status-info);\n}\n\n.rc-filter-overflow-label {\n flex: 1;\n}\n\n.rc-filter-overflow-count {\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 500;\n}\n\n.rc-filter-overflow-actions {\n display: flex;\n justify-content: space-between;\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 8px;\n margin-top: 6px;\n}\n\n.rc-filter-overflow-clear,\n.rc-filter-overflow-done {\n background: none;\n border: none;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 4px 10px;\n border-radius: 5px;\n}\n\n.rc-filter-overflow-clear {\n color: var(--mj-text-muted);\n}\n.rc-filter-overflow-clear:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.rc-filter-overflow-done {\n color: var(--mj-brand-primary);\n}\n.rc-filter-overflow-done:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n/* \u2500\u2500\u2500 Snapshot type badge + card accent \u2500\u2500\u2500 */\n\n.type-snapshot .rc-card-type-badge {\n background: color-mix(in srgb, var(--mj-text-muted) 15%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Restore Source pill (in card meta) \u2500\u2500\u2500 */\n\n.source-restore {\n background: color-mix(in srgb, var(--mj-status-info) 12%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Restore card variant: violet left accent \u2500\u2500\u2500 */\n\n.rc-card.rc-card-restore {\n border-left: 3px solid var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Lineage chip \u2500\u2500\u2500 */\n\n/* Lineage chip \u2014 outline-only \"interactive link\" treatment so it reads as\n distinct from the filled RESTORE badge sitting next to it. The badge says\n \"this row IS a restore\" (filled, static); the chip says \"click here to\n see the source version\" (outline, hoverable). */\n.rc-restored-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n margin-left: 8px;\n padding: 2px 9px;\n border-radius: 11px;\n font-size: 11px;\n font-weight: 500;\n background: transparent;\n color: color-mix(in srgb, var(--mj-status-info) 90%, var(--mj-text-primary));\n border: 1px solid color-mix(in srgb, var(--mj-status-info) 40%, var(--mj-border-default));\n cursor: pointer;\n text-decoration: none;\n white-space: nowrap;\n transition: background-color 0.12s, border-color 0.12s, color 0.12s;\n}\n\n.rc-restored-chip:hover {\n background: color-mix(in srgb, var(--mj-status-info) 12%, transparent);\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n\n.rc-restored-chip i {\n font-size: 10px;\n}\n\n.rc-restored-chip-orphan {\n cursor: default;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n border-color: var(--mj-border-default);\n}\n\n.rc-restored-chip-orphan:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Card highlight (when jumped-to via lineage chip) \u2500\u2500\u2500 */\n\n.rc-card.rc-card-highlight {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n animation: rc-card-pulse 1.4s ease-in-out;\n}\n\n@keyframes rc-card-pulse {\n 0%, 100% { background: var(--mj-bg-surface); }\n 50% { background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface)); }\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore-row badge override + Restore Reason block\n * (mockup-aligned treatment for restore rows in the timeline)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* The base type-update badge styling would otherwise paint a restore row's\n badge blue with \"Update\" text. Override to violet + \"Restore\" text so it\n matches the source pill, lineage chip, and card border. */\n.rc-card-type-badge.rc-card-type-badge-restore {\n background: color-mix(in srgb, var(--mj-status-info) 14%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* Restore reason \u2014 minimal blockquote treatment.\n A thin violet left bar + italic text reads like a margin note rather than\n a heavy callout. Visually connected to the restore family (left bar uses\n the same violet as the badge / source pill / card border) without\n competing with the field-diff rows that follow. */\n.rc-restore-reason {\n /* Indented in from the card body edge so it visually nests one level\n deeper than the field-diff rows that follow, and given generous\n vertical breathing room so it doesn't crowd the lineage chip above\n or the first field row below. */\n margin: 14px 8px 18px 18px;\n padding: 0 0 0 12px;\n border-left: 2px solid color-mix(in srgb, var(--mj-status-info) 55%, var(--mj-border-default));\n display: flex;\n align-items: baseline;\n gap: 8px;\n font-size: 13px;\n line-height: 1.5;\n}\n\n.rc-restore-reason-label {\n flex-shrink: 0;\n font-size: 11px;\n font-weight: 600;\n color: color-mix(in srgb, var(--mj-status-info) 75%, var(--mj-text-muted));\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n.rc-restore-reason-text {\n color: var(--mj-text-secondary);\n font-style: italic;\n}\n\n/* \u2500\u2500\u2500 Cross-Version Diff Comparison Workbench (vA <-> vB) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-compare-toggle-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-compare-toggle-btn:hover,\n.rc-compare-toggle-btn.active {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.rc-compare-panel {\n background: var(--mj-bg-surface);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n border-radius: 10px;\n margin-bottom: 16px;\n overflow: hidden;\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-compare-toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface-sunken));\n border-bottom: 1px solid var(--mj-border-default);\n flex-wrap: wrap;\n}\n\n.rc-compare-slot {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: 1;\n min-width: 190px;\n}\n\n.rc-compare-badge {\n padding: 2px 7px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n white-space: nowrap;\n}\n\n.rc-compare-badge--base {\n background: color-mix(in srgb, var(--mj-status-warning) 16%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.rc-compare-badge--target {\n background: color-mix(in srgb, var(--mj-status-success) 16%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.rc-compare-select {\n flex: 1;\n min-width: 0;\n padding: 5px 8px;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12px;\n font-family: inherit;\n outline: none;\n}\n\n.rc-compare-select:focus {\n border-color: var(--mj-brand-primary);\n}\n\n.rc-compare-swap-btn,\n.rc-compare-action-btn {\n width: 28px;\n height: 28px;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n flex-shrink: 0;\n transition: all 0.15s ease;\n}\n\n.rc-compare-swap-btn:hover,\n.rc-compare-action-btn:hover,\n.rc-compare-action-btn.active {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.rc-compare-summary {\n padding: 8px 14px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-compare-diff-list {\n max-height: 280px;\n overflow-y: auto;\n}\n\n.rc-compare-empty {\n padding: 14px 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.rc-compare-empty i {\n color: var(--mj-status-success);\n}\n\n.rc-card-compare-pills {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.rc-card-compare-pill {\n min-width: 22px;\n height: 20px;\n padding: 0 6px;\n border-radius: 5px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 10px;\n font-weight: 700;\n cursor: pointer;\n transition: all 0.12s ease;\n}\n\n.rc-card-compare-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-primary);\n}\n\n.rc-card-compare-pill.active {\n background: var(--mj-status-warning);\n border-color: var(--mj-status-warning);\n color: var(--mj-text-inverse);\n}\n\n.rc-card-compare-pill--target.active {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n"], encapsulation: 2, changeDetection: 0 });
|
|
1580
2562
|
}
|
|
1581
2563
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RecordChangesComponent, [{
|
|
1582
2564
|
type: Component,
|
|
1583
|
-
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=\"rc-container\">\n <!-- Version Labels Section -->\n <div class=\"rc-labels-section\">\n <div class=\"rc-labels-header\">\n <div class=\"rc-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=\"rc-labels-count\">{{ RecordLabels.length }}</span>\n }\n </div>\n <button class=\"rc-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=\"rc-labels-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading labels...\n </div>\n } @else if (RecordLabels.length === 0) {\n <mj-empty-state class=\"rc-labels-empty\" Size=\"compact\"\n Icon=\"\" Title=\"No version labels for this record yet.\" />\n } @else {\n <div class=\"rc-labels-list\">\n @for (label of RecordLabels; track label.ID) {\n <div class=\"rc-label-chip\" [title]=\"label.Description || label.Name\">\n <i class=\"fa-solid fa-tag rc-label-chip-icon\"></i>\n <span class=\"rc-label-chip-name\">{{ label.Name }}</span>\n <span class=\"rc-label-chip-meta\">\n <span class=\"rc-label-chip-status\" [class]=\"getLabelStatusClass(label.Status)\">{{ label.Status }}</span>\n <span class=\"rc-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 -->\n <mj-empty-state\n Icon=\"fa-solid fa-clock-rotate-left\"\n Title=\"No Change History\"\n Message=\"This record doesn't have any tracked changes yet. Changes will appear here automatically as edits are made.\"\n Size=\"large\">\n <div class=\"rc-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 </mj-empty-state>\n } @else {\n <!-- Page Header -->\n <div class=\"rc-page-header\">\n <div>\n <h2 class=\"rc-page-title\">Change History</h2>\n <div class=\"rc-page-subtitle\">{{ record.EntityInfo.Name }}</div>\n </div>\n <div class=\"rc-header-meta\">\n <div class=\"rc-entity-badge\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n {{ record.EntityInfo.Name }}\n </div>\n <div class=\"rc-change-count\">{{ viewData.length }} change{{ viewData.length !== 1 ? 's' : '' }} · {{ getUniqueContributorCount() }} contributor{{ getUniqueContributorCount() !== 1 ? 's' : '' }}</div>\n </div>\n </div>\n\n <!-- Filter Bar \u2014 chips render only for change types/sources actually present in loaded data.\n When more than 2 conditional chips would render, they collapse into a \"More filters\" popover. -->\n <div class=\"rc-filter-bar\">\n <div class=\"rc-search-wrap\">\n <i class=\"fa-solid fa-search\" aria-hidden=\"true\"></i>\n <input\n class=\"rc-search-box\"\n type=\"text\"\n placeholder=\"Search changes...\"\n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchChange()\"\n aria-label=\"Search record changes\"\n />\n </div>\n\n <button class=\"rc-filter-pill\" [class.active]=\"IsAllSelected\" (click)=\"SelectAllPill()\" type=\"button\">\n <i class=\"fa-solid fa-layer-group\" aria-hidden=\"true\"></i> All\n </button>\n\n @if (HasConditionalPills) {\n @if (!UseOverflowPopover) {\n <!-- 1-2 conditional pills: render inline -->\n @for (pill of ConditionalPills; track pill.Key) {\n <button class=\"rc-filter-pill\"\n [class.active]=\"ChipSelections[pill.Key]\"\n [class.rc-filter-pill-restore]=\"pill.Variant === 'restore'\"\n (click)=\"TogglePill(pill.Key)\"\n type=\"button\">\n <i class=\"fa-solid {{ pill.Icon }}\" aria-hidden=\"true\"></i>\n {{ pill.Label }}\n <span class=\"rc-filter-pill-count\">{{ pill.Count }}</span>\n </button>\n }\n } @else {\n <!-- 3+ conditional pills: overflow popover -->\n <div class=\"rc-filter-overflow-wrap\">\n <button class=\"rc-filter-pill rc-filter-pill-overflow\"\n [class.active]=\"SelectedConditionalCount > 0\"\n (click)=\"ToggleFilterOverflow()\"\n type=\"button\">\n <i class=\"fa-solid fa-sliders\" aria-hidden=\"true\"></i>\n More filters\n @if (SelectedConditionalCount > 0) {\n <span class=\"rc-filter-pill-count\">{{ SelectedConditionalCount }}</span>\n }\n <i class=\"fa-solid fa-chevron-down rc-filter-overflow-caret\" aria-hidden=\"true\"></i>\n </button>\n\n @if (ShowFilterOverflow) {\n <!-- Backdrop: clicks close the popover -->\n <div class=\"rc-filter-overflow-backdrop\" (click)=\"CloseFilterOverflow()\"></div>\n <div class=\"rc-filter-overflow-popover\" role=\"menu\">\n <div class=\"rc-filter-overflow-header\">Filter by</div>\n @for (pill of ConditionalPills; track pill.Key) {\n <label class=\"rc-filter-overflow-row\" [class.rc-filter-overflow-row-restore]=\"pill.Variant === 'restore'\">\n <input type=\"checkbox\"\n [checked]=\"ChipSelections[pill.Key]\"\n (change)=\"TogglePill(pill.Key)\" />\n <i class=\"fa-solid {{ pill.Icon }}\" aria-hidden=\"true\"></i>\n <span class=\"rc-filter-overflow-label\">{{ pill.Label }}</span>\n <span class=\"rc-filter-overflow-count\">{{ pill.Count }}</span>\n </label>\n }\n <div class=\"rc-filter-overflow-actions\">\n <button class=\"rc-filter-overflow-clear\" (click)=\"SelectAllPill(); CloseFilterOverflow()\" type=\"button\">\n Clear all\n </button>\n <button class=\"rc-filter-overflow-done\" (click)=\"CloseFilterOverflow()\" type=\"button\">\n Done\n </button>\n </div>\n </div>\n }\n </div>\n }\n }\n </div>\n\n @if (filteredData.length !== viewData.length) {\n <div class=\"rc-filter-results\">\n Showing {{ filteredData.length }} of {{ viewData.length }} changes\n <button class=\"rc-clear-filters-link\" (click)=\"ClearFilters()\">Clear filters</button>\n </div>\n }\n\n <!-- Timeline -->\n <div class=\"rc-timeline\" [attr.aria-label]=\"'Timeline of changes for ' + record.EntityInfo.Name + ' record'\">\n @if (filteredData.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-filter\"\n Title=\"No changes match your current filters\"\n ActionText=\"Clear filters\"\n ActionIcon=\"fa-solid fa-rotate-left\"\n (Action)=\"ClearFilters()\" />\n } @else {\n @for (group of dateGroups; track group.label) {\n <div class=\"rc-date-group\">\n <div class=\"rc-date-label\">{{ group.label }}</div>\n\n @for (change of group.changes; track change.ID) {\n <div\n class=\"rc-card\"\n [attr.data-change-id]=\"change.ID\"\n [class]=\"getChangeTypeCardClass(change.Type)\"\n [class.expanded]=\"expandedItems.has(change.ID)\"\n [class.rc-card-restore]=\"isRestoreRow(change)\"\n [class.rc-card-highlight]=\"HighlightedChangeID === change.ID\"\n [attr.tabindex]=\"0\"\n [attr.aria-expanded]=\"expandedItems.has(change.ID)\"\n [attr.aria-label]=\"getTimelineItemLabel(change)\"\n (keydown)=\"onTimelineItemKeydown($event, change.ID)\"\n >\n <!-- Card Header -->\n <div class=\"rc-card-header\" (click)=\"toggleExpansion(change.ID)\">\n <div class=\"rc-card-header-left\">\n <span class=\"rc-card-type-badge\"\n [class.rc-card-type-badge-restore]=\"isRestoreRow(change)\">{{ getEffectiveBadgeText(change) }}</span>\n <span class=\"rc-card-summary\">{{ getChangeSummary(change) }}</span>\n\n <!-- Lineage chip \u2014 visible when this row was produced by a restore -->\n @if (isRestoreRow(change)) {\n @if (getRestoredFromSourceChange(change); as srcChange) {\n <a class=\"rc-restored-chip\"\n (click)=\"JumpToSourceChange(srcChange, $event)\"\n [title]=\"'Jump to source version (' + formatFullDateTime(srcChange.ChangedAt) + ')'\">\n <i class=\"fa-solid fa-link\" aria-hidden=\"true\"></i>\n Restored from {{ formatTime(srcChange.ChangedAt) }} {{ srcChange.ChangedAt ? 'on ' + (srcChange.ChangedAt | date:'mediumDate') : '' }}\n @if (srcChange.User) {\n by {{ getUserDisplayName(srcChange.User) }}\n }\n </a>\n } @else {\n <span class=\"rc-restored-chip rc-restored-chip-orphan\"\n title=\"Source version was not loaded into this view\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restored from earlier version\n </span>\n }\n }\n </div>\n <div class=\"rc-card-meta\">\n <div class=\"rc-card-user\">\n <div class=\"rc-avatar\">{{ getUserInitials(change.User) }}</div>\n {{ getUserDisplayName(change.User) }}\n </div>\n <span class=\"rc-card-time\" [title]=\"formatFullDateTime(change.ChangedAt)\">{{ formatTime(change.ChangedAt) }}</span>\n <span class=\"rc-card-source\" [class]=\"getSourceClass(change.Source)\">{{ change.Source }}</span>\n <span class=\"rc-card-status\" [class]=\"getStatusClass(change.Status)\">{{ change.Status }}</span>\n <i class=\"fa-solid fa-chevron-down rc-card-chevron\" aria-hidden=\"true\"></i>\n </div>\n </div>\n\n <!-- Card Body (expanded) -->\n @if (expandedItems.has(change.ID)) {\n <div class=\"rc-card-body\">\n <!-- Restore reason (when present) \u2014 Notion/Linear-style\n blockquote: a thin violet left bar + italic text,\n with a tiny \"Reason\" prefix. No box, no header,\n no large vertical footprint. Reads as a\n justification note rather than a callout. -->\n @if (getRestoreReason(change); as reason) {\n <blockquote class=\"rc-restore-reason\">\n <span class=\"rc-restore-reason-label\">Reason</span>\n <span class=\"rc-restore-reason-text\">{{ reason }}</span>\n </blockquote>\n }\n\n @if (change.Type === 'Create') {\n @if (change.FullRecordJSON) {\n @for (field of getCreatedFields(change); track field.name) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ field.displayName }}</div>\n <div class=\"rc-field-values\">\n <span class=\"rc-val-new\">{{ field.value }}</span>\n </div>\n </div>\n }\n }\n } @else if (change.Type === 'Delete') {\n <div class=\"rc-deletion-note\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n This record was permanently removed from the system.\n </div>\n } @else {\n <!-- Update / Snapshot / Restore: type-aware field changes -->\n @for (fc of getFieldChanges(change); track fc.field) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ fc.displayName }}</div>\n <div class=\"rc-field-values\">\n @if (fc.fieldType === 'boolean') {\n <div class=\"rc-bool-change\">\n <span class=\"rc-bool-dot\" [class.on]=\"fc.oldValue === 'true' || fc.oldValue === '1'\" [class.off]=\"fc.oldValue !== 'true' && fc.oldValue !== '1'\"></span>\n <span class=\"rc-bool-label old\">{{ fc.oldValue === 'true' || fc.oldValue === '1' ? 'Yes' : 'No' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-bool-dot\" [class.on]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.off]=\"fc.newValue !== 'true' && fc.newValue !== '1'\"></span>\n <span class=\"rc-bool-label new\" [class.active]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.inactive]=\"fc.newValue !== 'true' && fc.newValue !== '1'\">{{ fc.newValue === 'true' || fc.newValue === '1' ? 'Yes' : 'No' }}</span>\n </div>\n } @else if (fc.fieldType === 'date' || fc.fieldType === 'number') {\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n } @else if (fc.diffHtml) {\n <div class=\"rc-text-diff\" [innerHTML]=\"fc.diffHtml\"></div>\n } @else {\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n }\n </div>\n </div>\n }\n }\n\n @if (change.Comments) {\n <div class=\"rc-comments\">\n <i class=\"fa-solid fa-comment\" aria-hidden=\"true\"></i>\n {{ change.Comments }}\n </div>\n }\n\n @if (change.ErrorLog) {\n <div class=\"rc-errors\">\n <i class=\"fa-solid fa-exclamation-triangle\" aria-hidden=\"true\"></i>\n <pre class=\"rc-error-log\">{{ change.ErrorLog }}</pre>\n </div>\n }\n\n <!-- Restore action: shown for Update, Create, and Snapshot rows.\n Hidden on Delete rows (handled via the Recycle Bin path)\n and on the most recent change (restoring to current state is a no-op). -->\n @if (AllowRestore && change.Type !== 'Delete' && !isMostRecentChange(change)) {\n <div class=\"rc-restore-action\">\n <button class=\"rc-restore-btn\"\n (click)=\"OnRestoreVersion(change, $event)\"\n title=\"Restore the entire record to its state at this version\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restore record to this version\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n\n <!-- Restore preview slide-in (reusable component) -->\n <mj-restore-preview-panel\n [Visible]=\"RestorePreviewVisible\"\n [Mode]=\"'live'\"\n [RecordChange]=\"RestorePreviewChange\"\n [LiveRecord]=\"record\"\n (RestoreConfirmed)=\"OnRestorePanelConfirmed($event)\"\n (RestoreCancelled)=\"OnRestorePanelCancelled()\">\n </mj-restore-preview-panel>\n\n @if (ShowCreateWizard) {\n <div class=\"rc-wizard-overlay\" (click)=\"OnLabelCreateCancelled()\">\n <div class=\"rc-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: ["/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Record Changes \u2014 Option A \"Clean Timeline\"\n Linear / Notion-inspired minimal timeline design\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* \u2500\u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Version Labels Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-labels-section {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 12px 16px;\n margin-bottom: 20px;\n border: 1px solid var(--mj-border-default);\n}\n\n.rc-labels-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.rc-labels-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.rc-labels-title i { color: var(--mj-brand-primary); }\n\n.rc-labels-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-create-label-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-create-label-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.rc-labels-loading {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding: 4px 0;\n}\n\n.rc-labels-loading i { margin-right: 4px; }\n\n.rc-labels-empty {\n font-size: 12px;\n color: var(--mj-text-disabled);\n font-style: italic;\n padding: 4px 0;\n}\n\n.rc-labels-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.rc-label-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n cursor: default;\n}\n\n.rc-label-chip:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-label-chip-icon { color: var(--mj-brand-primary); font-size: 10px; }\n\n.rc-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.rc-label-chip-meta {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.rc-label-chip-status {\n padding: 1px 5px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 9px;\n letter-spacing: 0.03em;\n}\n\n.label-status-active { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.label-status-archived { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.label-status-restored { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n\n.rc-label-chip-items { white-space: nowrap; }\n\n/* \u2500\u2500\u2500 Empty State (hint projected into <mj-empty-state> default slot) \u2500\u2500\u2500 */\n.rc-empty-state-hint {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: var(--mj-space-4);\n padding: 8px 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 20px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.rc-empty-state-hint i { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Page Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n padding-bottom: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-page-title {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.rc-page-subtitle {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n.rc-header-meta { text-align: right; }\n\n.rc-entity-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.rc-change-count {\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n/* \u2500\u2500\u2500 Filter Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-filter-bar {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n align-items: center;\n}\n\n.rc-search-wrap {\n position: relative;\n flex: 1;\n min-width: 180px;\n}\n\n.rc-search-wrap i {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-disabled);\n font-size: 13px;\n pointer-events: none;\n}\n\n.rc-search-box {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n outline: none;\n color: var(--mj-text-primary);\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.rc-search-box:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-search-box::placeholder { color: var(--mj-text-disabled); }\n\n.rc-filter-pill {\n padding: 7px 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n\n.rc-filter-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.rc-filter-pill.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.rc-filter-results {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-clear-filters-link {\n background: none;\n border: none;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 0;\n text-decoration: underline;\n}\n\n.rc-clear-filters-link:hover { color: var(--mj-brand-primary-hover); }\n\n/* \u2500\u2500\u2500 Timeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-timeline {\n position: relative;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Vertical line running through the timeline */\n.rc-timeline::before {\n content: '';\n position: absolute;\n left: 15px;\n top: 24px;\n bottom: 0;\n width: 2px;\n background: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Date Group \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-date-group { margin-bottom: 8px; }\n\n.rc-date-label {\n position: relative;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: var(--mj-text-disabled);\n padding: 16px 0 12px 44px;\n}\n\n/* Date dot on the timeline line */\n.rc-date-label::before {\n content: '';\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--mj-border-default);\n border: 2px solid var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Change Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card {\n position: relative;\n margin-left: 44px;\n margin-bottom: 12px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s;\n overflow: hidden;\n}\n\n.rc-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-card:focus {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* Colored dot on the timeline line for each card */\n.rc-card::before {\n content: '';\n position: absolute;\n left: -23px;\n top: 20px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n z-index: 1;\n}\n\n.rc-card.type-update::before {\n background: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-card.type-create::before {\n background: var(--mj-status-success);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-success) 15%, transparent);\n}\n\n.rc-card.type-delete::before {\n background: var(--mj-status-error);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n}\n\n/* \u2500\u2500\u2500 Card Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-header {\n padding: 14px 18px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n user-select: none;\n gap: 12px;\n}\n\n.rc-card-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n flex: 1;\n /* Allow the lineage chip to wrap to a second line on narrow panel widths\n instead of squeezing the title text into a \"Name and Description c...\"\n truncation. The badge stays on the first line; chip wraps gracefully. */\n flex-wrap: wrap;\n row-gap: 6px;\n}\n\n.rc-card-type-badge {\n padding: 3px 10px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.3px;\n text-transform: uppercase;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.type-update .rc-card-type-badge { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.type-create .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.type-delete .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n.rc-card-summary {\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-card-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.rc-card-user {\n display: flex;\n align-items: center;\n gap: 5px;\n white-space: nowrap;\n}\n\n.rc-avatar {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 8px;\n font-weight: 700;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.rc-card-time { white-space: nowrap; }\n\n.rc-card-source {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.source-internal { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.source-external { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n.rc-card-status {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n white-space: nowrap;\n}\n\n.status-complete { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-pending { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.status-unknown { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n.rc-card-chevron {\n color: var(--mj-text-disabled);\n transition: transform 0.2s;\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.rc-card.expanded .rc-card-chevron { transform: rotate(180deg); }\n\n/* \u2500\u2500\u2500 Card Body \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-body {\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Field Row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-field-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-field-row:last-child { border-bottom: none; }\n\n.rc-field-label {\n width: 140px;\n min-width: 140px;\n padding: 12px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.rc-field-values {\n flex: 1;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* \u2500\u2500\u2500 Atomic Change (numbers, dates) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-atomic-change {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.rc-val-old {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n font-weight: 400;\n}\n\n.rc-val-arrow {\n color: var(--mj-border-strong);\n font-size: 11px;\n flex-shrink: 0;\n}\n\n.rc-val-new {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n/* \u2500\u2500\u2500 Boolean Change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-bool-change {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-bool-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.rc-bool-dot.on { background: var(--mj-status-success); }\n.rc-bool-dot.off { background: var(--mj-border-strong); }\n\n.rc-bool-label {\n font-size: 13px;\n font-weight: 500;\n}\n\n.rc-bool-label.old {\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n}\n\n.rc-bool-label.new.active { color: var(--mj-status-success); }\n.rc-bool-label.new.inactive { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Text Diff (strings only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-text-diff {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n line-height: 1.6;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.rc-diff-added {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n padding: 1px 3px;\n border-radius: 3px;\n}\n\n.rc-diff-removed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n padding: 1px 3px;\n border-radius: 3px;\n text-decoration: line-through;\n}\n\n.rc-diff-unchanged {\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Deletion Note \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-deletion-note {\n padding: 16px 18px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-style: italic;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-deletion-note i {\n color: var(--mj-status-error);\n font-size: 14px;\n}\n\n/* \u2500\u2500\u2500 Comments & Errors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-comments {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-comments i {\n color: var(--mj-brand-primary);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-errors {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-errors i {\n color: var(--mj-status-error);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-error-log {\n background: var(--mj-bg-surface);\n padding: 8px;\n border-radius: 4px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n font-size: 12px;\n color: var(--mj-status-error);\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n flex: 1;\n}\n\n/* \u2500\u2500\u2500 Create Wizard Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-wizard-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-wizard-container {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 600px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 24px;\n animation: rc-slideUp 0.2s ease;\n}\n\n@keyframes rc-fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes rc-slideUp {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* \u2500\u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 768px) {\n .rc-card-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .rc-card-meta {\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .rc-field-row {\n flex-direction: column;\n }\n\n .rc-field-label {\n width: 100%;\n min-width: unset;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n }\n\n .rc-field-values {\n padding: 8px 16px;\n }\n\n .rc-atomic-change {\n flex-wrap: wrap;\n }\n\n .rc-filter-bar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .rc-search-wrap { min-width: unset; }\n\n .rc-filter-pill { justify-content: center; }\n\n .rc-page-header {\n flex-direction: column;\n gap: 12px;\n }\n\n .rc-header-meta { text-align: left; }\n}\n\n@media (max-width: 480px) {\n .rc-container { padding: 12px 16px; }\n\n .rc-card { margin-left: 36px; }\n\n .rc-date-label { padding-left: 36px; }\n\n .rc-card::before { left: -19px; }\n\n .rc-timeline::before { left: 12px; }\n\n .rc-date-label::before { left: 7px; }\n}\n\n/* \u2500\u2500\u2500 Restore Action \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-action {\n display: flex;\n justify-content: flex-end;\n padding-top: 10px;\n margin-top: 10px;\n /* Breathing room from the card's bottom and right edges so the button\n doesn't sit flush against the border. */\n padding-right: 10px;\n padding-bottom: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.rc-restore-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1;\n}\n\n.rc-restore-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-restore-btn:active {\n transform: translateY(1px);\n box-shadow: none;\n}\n\n.rc-restore-btn i {\n font-size: 13px;\n}\n\n/* \u2500\u2500\u2500 Restore Preview Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-preview-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-restore-preview-panel {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 700px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 0;\n animation: rc-slideUp 0.2s ease;\n}\n\n.rc-restore-preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.rc-restore-preview-title i {\n color: var(--mj-brand-primary);\n}\n\n.rc-restore-preview-close {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 16px;\n transition: color 0.15s, background 0.15s;\n}\n\n.rc-restore-preview-close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-restore-preview-meta {\n display: flex;\n gap: 20px;\n padding: 12px 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-empty {\n padding: 24px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.rc-restore-preview-empty i {\n color: var(--mj-text-disabled);\n}\n\n/* Restore Preview Table */\n.rc-restore-preview-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.rc-restore-preview-table th {\n text-align: left;\n padding: 10px 16px;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-table td {\n padding: 10px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n vertical-align: top;\n}\n\n.rc-restore-preview-table tr:last-child td {\n border-bottom: none;\n}\n\n.rc-restore-preview-table tr.rc-diff-changed {\n background: color-mix(in srgb, var(--mj-status-warning) 5%, var(--mj-bg-surface));\n}\n\n.rc-restore-preview-table tr.rc-diff-unchanged {\n opacity: 0.6;\n}\n\n.rc-restore-field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n}\n\n.rc-restore-current {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-secondary);\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-version {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-indicator {\n text-align: center;\n width: 30px;\n}\n\n.rc-diff-changed .rc-restore-indicator i {\n color: var(--mj-status-warning);\n}\n\n.rc-diff-unchanged .rc-restore-indicator i {\n color: var(--mj-status-success);\n font-size: 12px;\n}\n\n/* Restore Preview Actions */\n.rc-restore-preview-actions {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-confirm-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-confirm-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.rc-restore-confirm-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.rc-restore-cancel-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-cancel-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.rc-restore-cancel-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore lineage + conditional filter chips + overflow popover\n * (added with the Restore Prior Version feature)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* \u2500\u2500\u2500 Filter pill enhancements \u2500\u2500\u2500 */\n\n.rc-filter-pill-count {\n margin-left: 4px;\n background: color-mix(in srgb, currentColor 12%, transparent);\n padding: 1px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-filter-pill.active .rc-filter-pill-count {\n background: color-mix(in srgb, var(--mj-text-inverse, #fff) 22%, transparent);\n}\n\n/* Restore-variant pill: violet treatment to set it apart from type pills */\n.rc-filter-pill-restore {\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n color: color-mix(in srgb, var(--mj-status-info) 80%, var(--mj-text-secondary));\n border-color: color-mix(in srgb, var(--mj-status-info) 30%, var(--mj-border-default));\n}\n.rc-filter-pill-restore:hover {\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n.rc-filter-pill-restore.active {\n background: var(--mj-status-info);\n color: var(--mj-text-inverse, #fff);\n border-color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Overflow filter popover \u2500\u2500\u2500 */\n\n.rc-filter-overflow-wrap {\n position: relative;\n display: inline-block;\n}\n\n.rc-filter-pill-overflow {\n /* Overflow trigger inherits the standard filter pill look */\n}\n\n.rc-filter-overflow-caret {\n font-size: 9px;\n margin-left: 2px;\n}\n\n.rc-filter-overflow-backdrop {\n position: fixed;\n inset: 0;\n z-index: 10;\n}\n\n.rc-filter-overflow-popover {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: 11;\n min-width: 240px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 14px 40px rgba(0, 0, 0, 0.18);\n padding: 8px;\n}\n\n.rc-filter-overflow-header {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n font-weight: 600;\n padding: 6px 8px 8px;\n}\n\n.rc-filter-overflow-row {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 7px 8px;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n\n.rc-filter-overflow-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-filter-overflow-row input[type=\"checkbox\"] {\n margin: 0;\n accent-color: var(--mj-brand-primary);\n}\n\n.rc-filter-overflow-row i {\n color: var(--mj-text-muted);\n font-size: 12px;\n width: 14px;\n text-align: center;\n}\n\n.rc-filter-overflow-row-restore i {\n color: var(--mj-status-info);\n}\n\n.rc-filter-overflow-label {\n flex: 1;\n}\n\n.rc-filter-overflow-count {\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 500;\n}\n\n.rc-filter-overflow-actions {\n display: flex;\n justify-content: space-between;\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 8px;\n margin-top: 6px;\n}\n\n.rc-filter-overflow-clear,\n.rc-filter-overflow-done {\n background: none;\n border: none;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 4px 10px;\n border-radius: 5px;\n}\n\n.rc-filter-overflow-clear {\n color: var(--mj-text-muted);\n}\n.rc-filter-overflow-clear:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.rc-filter-overflow-done {\n color: var(--mj-brand-primary);\n}\n.rc-filter-overflow-done:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n/* \u2500\u2500\u2500 Snapshot type badge + card accent \u2500\u2500\u2500 */\n\n.type-snapshot .rc-card-type-badge {\n background: color-mix(in srgb, var(--mj-text-muted) 15%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Restore Source pill (in card meta) \u2500\u2500\u2500 */\n\n.source-restore {\n background: color-mix(in srgb, var(--mj-status-info) 12%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Restore card variant: violet left accent \u2500\u2500\u2500 */\n\n.rc-card.rc-card-restore {\n border-left: 3px solid var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Lineage chip \u2500\u2500\u2500 */\n\n/* Lineage chip \u2014 outline-only \"interactive link\" treatment so it reads as\n distinct from the filled RESTORE badge sitting next to it. The badge says\n \"this row IS a restore\" (filled, static); the chip says \"click here to\n see the source version\" (outline, hoverable). */\n.rc-restored-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n margin-left: 8px;\n padding: 2px 9px;\n border-radius: 11px;\n font-size: 11px;\n font-weight: 500;\n background: transparent;\n color: color-mix(in srgb, var(--mj-status-info) 90%, var(--mj-text-primary));\n border: 1px solid color-mix(in srgb, var(--mj-status-info) 40%, var(--mj-border-default));\n cursor: pointer;\n text-decoration: none;\n white-space: nowrap;\n transition: background-color 0.12s, border-color 0.12s, color 0.12s;\n}\n\n.rc-restored-chip:hover {\n background: color-mix(in srgb, var(--mj-status-info) 12%, transparent);\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n\n.rc-restored-chip i {\n font-size: 10px;\n}\n\n.rc-restored-chip-orphan {\n cursor: default;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n border-color: var(--mj-border-default);\n}\n\n.rc-restored-chip-orphan:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Card highlight (when jumped-to via lineage chip) \u2500\u2500\u2500 */\n\n.rc-card.rc-card-highlight {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n animation: rc-card-pulse 1.4s ease-in-out;\n}\n\n@keyframes rc-card-pulse {\n 0%, 100% { background: var(--mj-bg-surface); }\n 50% { background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface)); }\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore-row badge override + Restore Reason block\n * (mockup-aligned treatment for restore rows in the timeline)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* The base type-update badge styling would otherwise paint a restore row's\n badge blue with \"Update\" text. Override to violet + \"Restore\" text so it\n matches the source pill, lineage chip, and card border. */\n.rc-card-type-badge.rc-card-type-badge-restore {\n background: color-mix(in srgb, var(--mj-status-info) 14%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* Restore reason \u2014 minimal blockquote treatment.\n A thin violet left bar + italic text reads like a margin note rather than\n a heavy callout. Visually connected to the restore family (left bar uses\n the same violet as the badge / source pill / card border) without\n competing with the field-diff rows that follow. */\n.rc-restore-reason {\n /* Indented in from the card body edge so it visually nests one level\n deeper than the field-diff rows that follow, and given generous\n vertical breathing room so it doesn't crowd the lineage chip above\n or the first field row below. */\n margin: 14px 8px 18px 18px;\n padding: 0 0 0 12px;\n border-left: 2px solid color-mix(in srgb, var(--mj-status-info) 55%, var(--mj-border-default));\n display: flex;\n align-items: baseline;\n gap: 8px;\n font-size: 13px;\n line-height: 1.5;\n}\n\n.rc-restore-reason-label {\n flex-shrink: 0;\n font-size: 11px;\n font-weight: 600;\n color: color-mix(in srgb, var(--mj-status-info) 75%, var(--mj-text-muted));\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n.rc-restore-reason-text {\n color: var(--mj-text-secondary);\n font-style: italic;\n}\n"] }]
|
|
2565
|
+
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=\"rc-container\">\n <!-- Compact Context Header (Entity Display Name + Record Name + Stats + Compact Version Labels Action) -->\n <div class=\"rc-page-header\">\n <div class=\"rc-header-main\">\n <div class=\"rc-header-title-row\">\n <span class=\"rc-entity-badge rc-page-subtitle\">\n <i [class]=\"EntityIcon\" aria-hidden=\"true\"></i>\n {{ EntityDisplayName }}\n </span>\n <h2 class=\"rc-page-title\">{{ RecordDisplayName || 'Change History' }}</h2>\n </div>\n @if (viewData.length > 0) {\n <div class=\"rc-header-stats-row\">\n <span class=\"rc-change-count\">\n {{ viewData.length }} change{{ viewData.length !== 1 ? 's' : '' }} ·\n {{ getUniqueContributorCount() }} contributor{{ getUniqueContributorCount() !== 1 ? 's' : '' }}\n </span>\n @if (TopContributors.length > 0) {\n <div class=\"rc-contributor-stack\" aria-label=\"Contributors\">\n @for (contributor of TopContributors; track contributor.Name) {\n <span class=\"rc-contributor-avatar\" [attr.aria-label]=\"contributor.Name\" [title]=\"contributor.Name\">\n {{ contributor.Initials }}\n </span>\n }\n </div>\n }\n <span class=\"rc-latest-time\">· Latest {{ formatRelativeTime(viewData[0].ChangedAt) }}</span>\n </div>\n }\n </div>\n\n <div class=\"rc-header-actions\">\n @if (GetPreviewableChanges().length > 0) {\n <button\n type=\"button\"\n class=\"rc-compare-toggle-btn\"\n [class.active]=\"CompareMode\"\n (click)=\"ToggleCompareMode()\"\n [attr.aria-pressed]=\"CompareMode\"\n aria-label=\"Compare any two versions\">\n <i class=\"fa-solid fa-code-compare\" aria-hidden=\"true\"></i>\n <span>Compare</span>\n </button>\n }\n @if (RecordLabels.length > 0) {\n <button\n type=\"button\"\n class=\"rc-labels-toggle-btn\"\n [class.active]=\"ShowLabelsTray\"\n (click)=\"ToggleLabelsTray()\"\n [attr.aria-expanded]=\"ShowLabelsTray\">\n <i class=\"fa-solid fa-tags\" aria-hidden=\"true\"></i>\n <span>{{ RecordLabels.length }} Label{{ RecordLabels.length !== 1 ? 's' : '' }}</span>\n <i class=\"fa-solid\" [class.fa-chevron-up]=\"ShowLabelsTray\" [class.fa-chevron-down]=\"!ShowLabelsTray\" aria-hidden=\"true\"></i>\n </button>\n }\n <button\n type=\"button\"\n class=\"rc-create-label-btn\"\n (click)=\"OpenCreateWizard()\"\n title=\"Create a version label snapshot for this record\">\n <i class=\"fa-solid fa-tag\" aria-hidden=\"true\"></i>\n <span>+ Label</span>\n </button>\n </div>\n </div>\n\n <!-- Cross-Version Diff Comparison Workbench (vA <-> vB) -->\n @if (CompareMode) {\n <div class=\"rc-compare-panel\" role=\"region\" aria-label=\"Cross-version diff comparison\">\n <div class=\"rc-compare-toolbar\">\n <div class=\"rc-compare-slot\">\n <span class=\"rc-compare-badge rc-compare-badge--base\">vA \u00B7 Base</span>\n <select\n class=\"rc-compare-select\"\n aria-label=\"Base version vA\"\n [value]=\"CompareBaseChangeID ?? ''\"\n (change)=\"OnComparisonSelectChange('base', $event)\">\n <option value=\"__CURRENT__\" [selected]=\"CompareBaseChangeID === '__CURRENT__'\">Current Live Record</option>\n @for (ver of GetPreviewableChanges(); track ver.ID) {\n <option [value]=\"ver.ID\" [selected]=\"IsChangeSelectedAsCompareBase(ver)\">\n {{ formatFullDateTime(ver.ChangedAt) }} \u2014 {{ getUserDisplayName(ver.User) }}\n </option>\n }\n </select>\n @if (CompareBaseChange; as baseChange) {\n <button\n type=\"button\"\n class=\"rc-compare-action-btn\"\n [class.active]=\"IsChangePreviewedInForm(baseChange)\"\n (click)=\"OnToggleFormPreview(baseChange, $event)\"\n aria-label=\"Preview base version in form\">\n <i class=\"fa-solid fa-eye\" aria-hidden=\"true\"></i>\n </button>\n @if (AllowRestore) {\n <button\n type=\"button\"\n class=\"rc-compare-action-btn\"\n (click)=\"OnRestoreVersion(baseChange, $event)\"\n aria-label=\"Restore base version\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n </button>\n }\n }\n </div>\n\n <button\n type=\"button\"\n class=\"rc-compare-swap-btn\"\n (click)=\"SwapComparisonVersions()\"\n aria-label=\"Swap comparison versions\">\n <i class=\"fa-solid fa-right-left\" aria-hidden=\"true\"></i>\n </button>\n\n <div class=\"rc-compare-slot\">\n <span class=\"rc-compare-badge rc-compare-badge--target\">vB \u00B7 Target</span>\n <select\n class=\"rc-compare-select\"\n aria-label=\"Target version vB\"\n [value]=\"CompareTargetChangeID ?? ''\"\n (change)=\"OnComparisonSelectChange('target', $event)\">\n <option value=\"__CURRENT__\" [selected]=\"CompareTargetChangeID === '__CURRENT__'\">Current Live Record</option>\n @for (ver of GetPreviewableChanges(); track ver.ID) {\n <option [value]=\"ver.ID\" [selected]=\"IsChangeSelectedAsCompareTarget(ver)\">\n {{ formatFullDateTime(ver.ChangedAt) }} \u2014 {{ getUserDisplayName(ver.User) }}\n </option>\n }\n </select>\n @if (CompareTargetChange; as targetChange) {\n <button\n type=\"button\"\n class=\"rc-compare-action-btn\"\n [class.active]=\"IsChangePreviewedInForm(targetChange)\"\n (click)=\"OnToggleFormPreview(targetChange, $event)\"\n aria-label=\"Preview target version in form\">\n <i class=\"fa-solid fa-eye\" aria-hidden=\"true\"></i>\n </button>\n @if (AllowRestore) {\n <button\n type=\"button\"\n class=\"rc-compare-action-btn\"\n (click)=\"OnRestoreVersion(targetChange, $event)\"\n aria-label=\"Restore target version\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n </button>\n }\n }\n </div>\n </div>\n\n @if (GetComparisonDiffs(); as compDiffs) {\n @if (compDiffs.length === 0) {\n <div class=\"rc-compare-empty\">\n <i class=\"fa-solid fa-circle-check\" aria-hidden=\"true\"></i>\n <span>No field differences between {{ GetComparisonSlotLabel('base') }} and {{ GetComparisonSlotLabel('target') }}.</span>\n </div>\n } @else {\n <div class=\"rc-compare-summary\">\n <span>{{ compDiffs.length }} field{{ compDiffs.length !== 1 ? 's' : '' }} differ between <strong>vA</strong> and <strong>vB</strong></span>\n </div>\n <div class=\"rc-compare-diff-list\">\n @for (fc of compDiffs; track fc.field) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ fc.displayName }}</div>\n <div class=\"rc-field-values\">\n @if (fc.fieldType === 'boolean') {\n <div class=\"rc-bool-change\">\n <span class=\"rc-bool-dot\" [class.on]=\"fc.oldValue === 'true' || fc.oldValue === '1'\" [class.off]=\"fc.oldValue !== 'true' && fc.oldValue !== '1'\"></span>\n <span class=\"rc-bool-label old\">{{ fc.oldValue === 'true' || fc.oldValue === '1' ? 'Yes' : 'No' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-bool-dot\" [class.on]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.off]=\"fc.newValue !== 'true' && fc.newValue !== '1'\"></span>\n <span class=\"rc-bool-label new\" [class.active]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.inactive]=\"fc.newValue !== 'true' && fc.newValue !== '1'\">{{ fc.newValue === 'true' || fc.newValue === '1' ? 'Yes' : 'No' }}</span>\n </div>\n } @else if (fc.fieldType === 'date' || fc.fieldType === 'number') {\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n } @else if (fc.diffHtml) {\n <div class=\"rc-text-diff\" [innerHTML]=\"fc.diffHtml\"></div>\n } @else {\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n </div>\n }\n\n <!-- Collapsible Version Labels Tray (only takes vertical space when user opens it and labels exist) -->\n @if (ShowLabelsTray && RecordLabels.length > 0) {\n <div class=\"rc-labels-tray\">\n <div class=\"rc-labels-list\">\n @for (label of RecordLabels; track label.ID) {\n <div class=\"rc-label-chip\" [title]=\"label.Description || label.Name\">\n <i class=\"fa-solid fa-tag rc-label-chip-icon\"></i>\n <span class=\"rc-label-chip-name\">{{ label.Name }}</span>\n <span class=\"rc-label-chip-meta\">\n <span class=\"rc-label-chip-status\" [class]=\"getLabelStatusClass(label.Status)\">{{ label.Status }}</span>\n <span class=\"rc-label-chip-items\">{{ label.ItemCount }} item{{ label.ItemCount !== 1 ? 's' : '' }}</span>\n </span>\n </div>\n }\n </div>\n </div>\n }\n\n @if (viewData.length === 0) {\n <!-- Empty state -->\n <mj-empty-state\n Icon=\"fa-solid fa-clock-rotate-left\"\n Title=\"No Change History\"\n Message=\"This record doesn't have any tracked changes yet. Changes will appear here automatically as edits are made.\"\n Size=\"large\">\n <div class=\"rc-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 </mj-empty-state>\n } @else {\n <!-- Activity Over Time Burst-Aware Cluster Strip (Powered by @memberjunction/ng-ui-components) -->\n <mj-burst-cluster-strip\n Title=\"Editing sessions\"\n TitleIcon=\"fa-solid fa-wave-square\"\n AriaLabel=\"Change activity bursts over time\"\n ItemSingularNoun=\"change\"\n ItemPluralNoun=\"changes\"\n [Items]=\"BurstClusterItems\"\n [Categories]=\"BurstClusterCategories\"\n [Resolution]=\"BurstResolution\"\n [CoalesceStrategy]=\"BurstCoalesceStrategy\"\n [SessionGapHours]=\"BurstSessionGapHours\"\n [MaxClusters]=\"BurstMaxClusters\"\n [EraZoomThreshold]=\"BurstEraZoomThreshold\"\n [AllowZoom]=\"AllowBurstZoom\"\n [(SelectedClusterKey)]=\"SelectedBucketKey\"\n (AfterClustersRebuild)=\"OnBurstClustersRebuilt($event)\"\n (FilterChanged)=\"OnBurstFilterChanged($event)\">\n </mj-burst-cluster-strip>\n\n <!-- Filter Bar \u2014 chips render only for change types/sources actually present in loaded data.\n When more than 2 conditional chips would render, they collapse into a \"More filters\" popover. -->\n <div class=\"rc-filter-bar\">\n <div class=\"rc-search-wrap\">\n <i class=\"fa-solid fa-search\" aria-hidden=\"true\"></i>\n <input\n class=\"rc-search-box\"\n type=\"text\"\n placeholder=\"Search changes...\"\n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchChange()\"\n aria-label=\"Search record changes\"\n />\n </div>\n\n <button class=\"rc-filter-pill\" [class.active]=\"IsAllSelected\" (click)=\"SelectAllPill()\" type=\"button\">\n <i class=\"fa-solid fa-layer-group\" aria-hidden=\"true\"></i> All\n </button>\n\n @if (HasConditionalPills) {\n @if (!UseOverflowPopover) {\n <!-- 1-2 conditional pills: render inline -->\n @for (pill of ConditionalPills; track pill.Key) {\n <button class=\"rc-filter-pill\"\n [class.active]=\"ChipSelections[pill.Key]\"\n [class.rc-filter-pill-restore]=\"pill.Variant === 'restore'\"\n (click)=\"TogglePill(pill.Key)\"\n type=\"button\">\n <i class=\"fa-solid {{ pill.Icon }}\" aria-hidden=\"true\"></i>\n {{ pill.Label }}\n <span class=\"rc-filter-pill-count\">{{ pill.Count }}</span>\n </button>\n }\n } @else {\n <!-- 3+ conditional pills: overflow popover -->\n <div class=\"rc-filter-overflow-wrap\">\n <button class=\"rc-filter-pill rc-filter-pill-overflow\"\n [class.active]=\"SelectedConditionalCount > 0\"\n (click)=\"ToggleFilterOverflow()\"\n type=\"button\">\n <i class=\"fa-solid fa-sliders\" aria-hidden=\"true\"></i>\n More filters\n @if (SelectedConditionalCount > 0) {\n <span class=\"rc-filter-pill-count\">{{ SelectedConditionalCount }}</span>\n }\n <i class=\"fa-solid fa-chevron-down rc-filter-overflow-caret\" aria-hidden=\"true\"></i>\n </button>\n\n @if (ShowFilterOverflow) {\n <!-- Backdrop: clicks close the popover -->\n <div class=\"rc-filter-overflow-backdrop\" (click)=\"CloseFilterOverflow()\"></div>\n <div class=\"rc-filter-overflow-popover\" role=\"menu\">\n <div class=\"rc-filter-overflow-header\">Filter by</div>\n @for (pill of ConditionalPills; track pill.Key) {\n <label class=\"rc-filter-overflow-row\" [class.rc-filter-overflow-row-restore]=\"pill.Variant === 'restore'\">\n <input type=\"checkbox\"\n [checked]=\"ChipSelections[pill.Key]\"\n (change)=\"TogglePill(pill.Key)\" />\n <i class=\"fa-solid {{ pill.Icon }}\" aria-hidden=\"true\"></i>\n <span class=\"rc-filter-overflow-label\">{{ pill.Label }}</span>\n <span class=\"rc-filter-overflow-count\">{{ pill.Count }}</span>\n </label>\n }\n <div class=\"rc-filter-overflow-actions\">\n <button class=\"rc-filter-overflow-clear\" (click)=\"SelectAllPill(); CloseFilterOverflow()\" type=\"button\">\n Clear all\n </button>\n <button class=\"rc-filter-overflow-done\" (click)=\"CloseFilterOverflow()\" type=\"button\">\n Done\n </button>\n </div>\n </div>\n }\n </div>\n }\n }\n </div>\n\n @if (filteredData.length !== viewData.length) {\n <div class=\"rc-filter-results\">\n Showing {{ filteredData.length }} of {{ viewData.length }} changes\n <button class=\"rc-clear-filters-link\" (click)=\"ClearFilters()\">Clear filters</button>\n </div>\n }\n\n <!-- Timeline -->\n <div class=\"rc-timeline\" [attr.aria-label]=\"'Timeline of changes for ' + record.EntityInfo.Name + ' record'\">\n @if (filteredData.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-filter\"\n Title=\"No changes match your current filters\"\n ActionText=\"Clear filters\"\n ActionIcon=\"fa-solid fa-rotate-left\"\n (Action)=\"ClearFilters()\" />\n } @else {\n @for (group of dateGroups; track group.label) {\n <div class=\"rc-date-group\">\n <div class=\"rc-date-label\">{{ group.label }}</div>\n\n @for (change of group.changes; track change.ID) {\n <div\n class=\"rc-card\"\n [attr.data-change-id]=\"change.ID\"\n [class]=\"getChangeTypeCardClass(change.Type)\"\n [class.expanded]=\"expandedItems.has(change.ID)\"\n [class.rc-card-restore]=\"isRestoreRow(change)\"\n [class.rc-card-highlight]=\"HighlightedChangeID === change.ID\"\n [class.rc-card-previewing]=\"IsChangePreviewedInForm(change)\"\n [attr.tabindex]=\"0\"\n [attr.aria-expanded]=\"expandedItems.has(change.ID)\"\n [attr.aria-label]=\"getTimelineItemLabel(change)\"\n (keydown)=\"onTimelineItemKeydown($event, change.ID)\"\n >\n <!-- Card Header -->\n <div class=\"rc-card-header\" (click)=\"toggleExpansion(change.ID)\">\n <div class=\"rc-card-header-left\">\n <span class=\"rc-card-type-badge\"\n [class.rc-card-type-badge-restore]=\"isRestoreRow(change)\">{{ getEffectiveBadgeText(change) }}</span>\n <span class=\"rc-card-summary\">{{ getChangeSummary(change) }}</span>\n\n @if (IsChangePreviewedInForm(change)) {\n <span class=\"rc-previewing-chip\" title=\"This version is currently rendered inside the form\">\n <i class=\"fa-solid fa-eye\" aria-hidden=\"true\"></i>\n Previewing in form\n </span>\n }\n\n <!-- Lineage chip \u2014 visible when this row was produced by a restore -->\n @if (isRestoreRow(change)) {\n @if (getRestoredFromSourceChange(change); as srcChange) {\n <a class=\"rc-restored-chip\"\n (click)=\"JumpToSourceChange(srcChange, $event)\"\n [title]=\"'Jump to source version (' + formatFullDateTime(srcChange.ChangedAt) + ')'\">\n <i class=\"fa-solid fa-link\" aria-hidden=\"true\"></i>\n Restored from {{ formatTime(srcChange.ChangedAt) }} {{ srcChange.ChangedAt ? 'on ' + (srcChange.ChangedAt | date:'mediumDate') : '' }}\n @if (srcChange.User) {\n by {{ getUserDisplayName(srcChange.User) }}\n }\n </a>\n } @else {\n <span class=\"rc-restored-chip rc-restored-chip-orphan\"\n title=\"Source version was not loaded into this view\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restored from earlier version\n </span>\n }\n }\n </div>\n <div class=\"rc-card-meta\">\n @if (CompareMode && change.FullRecordJSON && change.Type !== 'Delete') {\n <div class=\"rc-card-compare-pills\">\n <button\n type=\"button\"\n class=\"rc-card-compare-pill\"\n [class.active]=\"IsChangeSelectedAsCompareBase(change)\"\n (click)=\"SelectForComparison('base', change.ID, $event)\"\n aria-label=\"Set as Base Version A\">\n A\n </button>\n <button\n type=\"button\"\n class=\"rc-card-compare-pill rc-card-compare-pill--target\"\n [class.active]=\"IsChangeSelectedAsCompareTarget(change)\"\n (click)=\"SelectForComparison('target', change.ID, $event)\"\n aria-label=\"Set as Target Version B\">\n B\n </button>\n </div>\n }\n <div class=\"rc-card-user\">\n <div class=\"rc-avatar\">{{ getUserInitials(change.User) }}</div>\n {{ getUserDisplayName(change.User) }}\n </div>\n <span class=\"rc-card-time\" [title]=\"formatFullDateTime(change.ChangedAt)\">{{ formatTime(change.ChangedAt) }}</span>\n <span class=\"rc-card-source\" [class]=\"getSourceClass(change.Source)\">{{ change.Source }}</span>\n <span class=\"rc-card-status\" [class]=\"getStatusClass(change.Status)\">{{ change.Status }}</span>\n <i class=\"fa-solid fa-chevron-down rc-card-chevron\" aria-hidden=\"true\"></i>\n </div>\n </div>\n\n <!-- Card Body (expanded) -->\n @if (expandedItems.has(change.ID)) {\n <div class=\"rc-card-body\">\n <!-- Restore reason (when present) \u2014 Notion/Linear-style\n blockquote: a thin violet left bar + italic text,\n with a tiny \"Reason\" prefix. No box, no header,\n no large vertical footprint. Reads as a\n justification note rather than a callout. -->\n @if (getRestoreReason(change); as reason) {\n <blockquote class=\"rc-restore-reason\">\n <span class=\"rc-restore-reason-label\">Reason</span>\n <span class=\"rc-restore-reason-text\">{{ reason }}</span>\n </blockquote>\n }\n\n @if (change.Type === 'Create') {\n @if (change.FullRecordJSON) {\n @for (field of getCreatedFields(change); track field.name) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ field.displayName }}</div>\n <div class=\"rc-field-values\">\n <span class=\"rc-val-new\">{{ field.value }}</span>\n </div>\n </div>\n }\n }\n } @else if (change.Type === 'Delete') {\n <div class=\"rc-deletion-note\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n This record was permanently removed from the system.\n </div>\n } @else {\n <!-- Update / Snapshot / Restore: type-aware field changes -->\n @for (fc of getFieldChanges(change); track fc.field) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ fc.displayName }}</div>\n <div class=\"rc-field-values\">\n @if (fc.fieldType === 'boolean') {\n <div class=\"rc-bool-change\">\n <span class=\"rc-bool-dot\" [class.on]=\"fc.oldValue === 'true' || fc.oldValue === '1'\" [class.off]=\"fc.oldValue !== 'true' && fc.oldValue !== '1'\"></span>\n <span class=\"rc-bool-label old\">{{ fc.oldValue === 'true' || fc.oldValue === '1' ? 'Yes' : 'No' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-bool-dot\" [class.on]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.off]=\"fc.newValue !== 'true' && fc.newValue !== '1'\"></span>\n <span class=\"rc-bool-label new\" [class.active]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.inactive]=\"fc.newValue !== 'true' && fc.newValue !== '1'\">{{ fc.newValue === 'true' || fc.newValue === '1' ? 'Yes' : 'No' }}</span>\n </div>\n } @else if (fc.fieldType === 'date' || fc.fieldType === 'number') {\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n } @else if (fc.diffHtml) {\n <div class=\"rc-text-diff\" [innerHTML]=\"fc.diffHtml\"></div>\n } @else {\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n }\n </div>\n </div>\n }\n }\n\n @if (change.Comments) {\n <div class=\"rc-comments\">\n <i class=\"fa-solid fa-comment\" aria-hidden=\"true\"></i>\n {{ change.Comments }}\n </div>\n }\n\n @if (change.ErrorLog) {\n <div class=\"rc-errors\">\n <i class=\"fa-solid fa-exclamation-triangle\" aria-hidden=\"true\"></i>\n <pre class=\"rc-error-log\">{{ change.ErrorLog }}</pre>\n </div>\n }\n\n <!-- Restore & In-Form Preview actions: shown for Update, Create, and Snapshot rows.\n Hidden on Delete rows (handled via the Recycle Bin path)\n and on the most recent change (restoring/previewing current state is a no-op). -->\n @if (change.Type !== 'Delete' && !isMostRecentChange(change) && (AllowRestore || change.FullRecordJSON)) {\n <div class=\"rc-restore-action\">\n @if (change.FullRecordJSON) {\n <button\n type=\"button\"\n class=\"rc-preview-form-btn\"\n [class.rc-preview-form-btn--active]=\"IsChangePreviewedInForm(change)\"\n (click)=\"OnToggleFormPreview(change, $event)\"\n title=\"Render this historical version's field values directly inside the form\">\n <i class=\"fa-solid\" [class.fa-eye]=\"!IsChangePreviewedInForm(change)\" [class.fa-eye-slash]=\"IsChangePreviewedInForm(change)\" aria-hidden=\"true\"></i>\n {{ IsChangePreviewedInForm(change) ? 'Exit Form Preview' : 'Preview in Form' }}\n </button>\n }\n @if (AllowRestore) {\n <button\n type=\"button\"\n class=\"rc-restore-btn\"\n (click)=\"OnRestoreVersion(change, $event)\"\n title=\"Restore the entire record to its state at this version\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restore record to this version\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n\n <!-- Restore preview slide-in (reusable component) -->\n <mj-restore-preview-panel\n [Visible]=\"RestorePreviewVisible\"\n [Mode]=\"'live'\"\n [RecordChange]=\"RestorePreviewChange\"\n [LiveRecord]=\"record\"\n (RestoreConfirmed)=\"OnRestorePanelConfirmed($event)\"\n (RestoreCancelled)=\"OnRestorePanelCancelled()\">\n </mj-restore-preview-panel>\n\n @if (ShowCreateWizard) {\n <div class=\"rc-wizard-overlay\" (click)=\"OnLabelCreateCancelled()\">\n <div class=\"rc-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: ["/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Record Changes \u2014 Option A \"Clean Timeline\"\n Linear / Notion-inspired minimal timeline design\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* \u2500\u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Unified Header & Compact Labels Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 16px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-header-main {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n flex: 1;\n}\n\n.rc-header-title-row {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.rc-entity-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 24%, var(--mj-bg-surface));\n margin: 0;\n}\n\n.rc-header-sep {\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.rc-page-title {\n font-size: 17px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.rc-header-stats-row {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.rc-change-count {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.rc-change-count strong {\n color: var(--mj-text-primary);\n font-weight: 700;\n}\n\n.rc-stat-dot {\n color: var(--mj-text-disabled);\n}\n\n.rc-stat-latest {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n color: var(--mj-text-muted);\n}\n\n.rc-contributor-stack {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.rc-contributor-avatar {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 16%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1.5px solid var(--mj-bg-surface-card);\n font-size: 9px;\n font-weight: 700;\n margin-left: -5px;\n}\n\n.rc-contributor-avatar:first-child {\n margin-left: 0;\n}\n\n.rc-contributor-label {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-left: 2px;\n}\n\n.rc-header-actions {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.rc-labels-toggle-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-labels-toggle-btn:hover,\n.rc-labels-toggle-btn.active {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.rc-labels-toggle-btn i:first-child {\n color: var(--mj-brand-primary);\n font-size: 11px;\n}\n\n.rc-labels-caret {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.rc-labels-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: 9px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-create-label-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 11px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-create-label-btn:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n/* \u2500\u2500\u2500 Collapsible Version Labels Tray \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-labels-tray {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n padding: 10px 14px;\n margin-bottom: 14px;\n border: 1px solid var(--mj-border-default);\n}\n\n.rc-labels-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.rc-label-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n cursor: default;\n}\n\n.rc-label-chip:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-label-chip-icon { color: var(--mj-brand-primary); font-size: 10px; }\n\n.rc-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.rc-label-chip-meta {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.rc-label-chip-status {\n padding: 1px 5px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 9px;\n letter-spacing: 0.03em;\n}\n\n.label-status-active { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.label-status-archived { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.label-status-restored { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n\n.rc-label-chip-items { white-space: nowrap; }\n\n/* \u2500\u2500\u2500 Activity Over Time Burst-Aware Cluster Strip \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-activity-chart {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 12px 14px 10px;\n margin-bottom: 16px;\n}\n\n.rc-activity-chart-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n margin-bottom: 10px;\n flex-wrap: wrap;\n}\n\n.rc-activity-chart-title {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-secondary);\n}\n\n.rc-activity-chart-title i {\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n.rc-activity-chart-meta {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.rc-activity-bucket-pill {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 2px 8px;\n border-radius: 999px;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 35%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s ease, color 0.15s ease;\n}\n\n.rc-activity-bucket-pill:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.rc-activity-legend {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.rc-legend-item {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.rc-legend-dot {\n width: 7px;\n height: 7px;\n border-radius: 2px;\n}\n\n.rc-legend-dot--update { background: var(--mj-brand-primary); }\n.rc-legend-dot--create { background: var(--mj-status-success); }\n.rc-legend-dot--restore { background: var(--mj-status-warning); }\n\n.rc-burst-track {\n display: flex;\n align-items: stretch;\n gap: 0;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 8px 10px;\n overflow-x: auto;\n}\n\n.rc-burst-node {\n flex: 1 1 0;\n min-width: 78px;\n border-radius: 8px;\n border: 1px solid transparent;\n background: var(--mj-bg-surface);\n padding: 7px 8px 6px;\n cursor: pointer;\n transition: border-color 0.14s ease, box-shadow 0.14s ease, transform 0.14s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n box-shadow: var(--mj-shadow-sm);\n font-family: inherit;\n}\n\n.rc-burst-node:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-border-default));\n transform: translateY(-1px);\n}\n\n.rc-burst-node--selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 22%, transparent);\n}\n\n.rc-burst-pips {\n display: flex;\n align-items: flex-end;\n justify-content: center;\n gap: 3px;\n height: 28px;\n width: 100%;\n padding: 0 2px;\n}\n\n.rc-burst-pip {\n width: 6px;\n height: 18px;\n border-radius: 2px 2px 1px 1px;\n transition: transform 0.12s ease;\n flex-shrink: 0;\n}\n\n.rc-burst-pip--create { background: var(--mj-status-success); height: 22px; }\n.rc-burst-pip--update { background: var(--mj-brand-primary); height: 18px; }\n.rc-burst-pip--restore { background: var(--mj-status-warning); height: 24px; }\n.rc-burst-pip--delete { background: var(--mj-status-error); height: 20px; }\n\n.rc-burst-pip-overflow {\n font-size: 9px;\n font-weight: 700;\n color: var(--mj-text-muted);\n margin-left: 2px;\n align-self: center;\n}\n\n.rc-burst-count {\n font-size: 10px;\n font-weight: 700;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken);\n padding: 1px 6px;\n border-radius: 999px;\n line-height: 1.3;\n white-space: nowrap;\n}\n\n.rc-burst-node--selected .rc-burst-count {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.rc-burst-date {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n line-height: 1.2;\n}\n\n.rc-burst-sub {\n font-size: 9px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n line-height: 1.1;\n}\n\n.rc-gap-connector {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 0 5px;\n min-width: 44px;\n position: relative;\n flex-shrink: 0;\n}\n\n.rc-gap-line {\n width: 100%;\n border-top: 1.5px dashed var(--mj-border-default);\n position: relative;\n}\n\n.rc-gap-pill {\n margin-top: -8px;\n background: var(--mj-bg-surface-sunken);\n padding: 1px 4px;\n font-size: 9px;\n font-weight: 600;\n color: var(--mj-text-muted);\n border-radius: 4px;\n white-space: nowrap;\n}\n\n/* \u2500\u2500\u2500 Empty State (hint projected into <mj-empty-state> default slot) \u2500\u2500\u2500 */\n.rc-empty-state-hint {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: var(--mj-space-4);\n padding: 8px 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 20px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.rc-empty-state-hint i { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Filter Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-filter-bar {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n align-items: center;\n}\n\n.rc-search-wrap {\n position: relative;\n flex: 1;\n min-width: 180px;\n}\n\n.rc-search-wrap i {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-disabled);\n font-size: 13px;\n pointer-events: none;\n}\n\n.rc-search-box {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n outline: none;\n color: var(--mj-text-primary);\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.rc-search-box:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-search-box::placeholder { color: var(--mj-text-disabled); }\n\n.rc-filter-pill {\n padding: 7px 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n\n.rc-filter-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.rc-filter-pill.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.rc-filter-results {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-clear-filters-link {\n background: none;\n border: none;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 0;\n text-decoration: underline;\n}\n\n.rc-clear-filters-link:hover { color: var(--mj-brand-primary-hover); }\n\n/* \u2500\u2500\u2500 Timeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-timeline {\n position: relative;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Vertical line running through the timeline */\n.rc-timeline::before {\n content: '';\n position: absolute;\n left: 15px;\n top: 24px;\n bottom: 0;\n width: 2px;\n background: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Date Group \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-date-group { margin-bottom: 8px; }\n\n.rc-date-label {\n position: relative;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: var(--mj-text-disabled);\n padding: 16px 0 12px 44px;\n}\n\n/* Date dot on the timeline line */\n.rc-date-label::before {\n content: '';\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--mj-border-default);\n border: 2px solid var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Change Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card {\n position: relative;\n margin-left: 44px;\n margin-bottom: 12px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s;\n overflow: hidden;\n}\n\n.rc-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-card:focus {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* Colored dot on the timeline line for each card */\n.rc-card::before {\n content: '';\n position: absolute;\n left: -23px;\n top: 20px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n z-index: 1;\n}\n\n.rc-card.type-update::before {\n background: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-card.type-create::before {\n background: var(--mj-status-success);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-success) 15%, transparent);\n}\n\n.rc-card.type-delete::before {\n background: var(--mj-status-error);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n}\n\n/* \u2500\u2500\u2500 Card Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-header {\n padding: 14px 18px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n user-select: none;\n gap: 12px;\n}\n\n.rc-card-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n flex: 1;\n /* Allow the lineage chip to wrap to a second line on narrow panel widths\n instead of squeezing the title text into a \"Name and Description c...\"\n truncation. The badge stays on the first line; chip wraps gracefully. */\n flex-wrap: wrap;\n row-gap: 6px;\n}\n\n.rc-card-type-badge {\n padding: 3px 10px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.3px;\n text-transform: uppercase;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.type-update .rc-card-type-badge { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.type-create .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.type-delete .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n.rc-card-summary {\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-card-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.rc-card-user {\n display: flex;\n align-items: center;\n gap: 5px;\n white-space: nowrap;\n}\n\n.rc-avatar {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 8px;\n font-weight: 700;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.rc-card-time { white-space: nowrap; }\n\n.rc-card-source {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.source-internal { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.source-external { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n.rc-card-status {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n white-space: nowrap;\n}\n\n.status-complete { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-pending { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.status-unknown { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n.rc-card-chevron {\n color: var(--mj-text-disabled);\n transition: transform 0.2s;\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.rc-card.expanded .rc-card-chevron { transform: rotate(180deg); }\n\n/* \u2500\u2500\u2500 Card Body \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-body {\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Field Row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-field-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-field-row:last-child { border-bottom: none; }\n\n.rc-field-label {\n width: 140px;\n min-width: 140px;\n padding: 12px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.rc-field-values {\n flex: 1;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* \u2500\u2500\u2500 Atomic Change (numbers, dates) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-atomic-change {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.rc-val-old {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n font-weight: 400;\n}\n\n.rc-val-arrow {\n color: var(--mj-border-strong);\n font-size: 11px;\n flex-shrink: 0;\n}\n\n.rc-val-new {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n/* \u2500\u2500\u2500 Boolean Change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-bool-change {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-bool-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.rc-bool-dot.on { background: var(--mj-status-success); }\n.rc-bool-dot.off { background: var(--mj-border-strong); }\n\n.rc-bool-label {\n font-size: 13px;\n font-weight: 500;\n}\n\n.rc-bool-label.old {\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n}\n\n.rc-bool-label.new.active { color: var(--mj-status-success); }\n.rc-bool-label.new.inactive { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Text Diff (strings only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-text-diff {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n line-height: 1.6;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.rc-diff-added {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n padding: 1px 3px;\n border-radius: 3px;\n}\n\n.rc-diff-removed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n padding: 1px 3px;\n border-radius: 3px;\n text-decoration: line-through;\n}\n\n.rc-diff-unchanged {\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Deletion Note \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-deletion-note {\n padding: 16px 18px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-style: italic;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-deletion-note i {\n color: var(--mj-status-error);\n font-size: 14px;\n}\n\n/* \u2500\u2500\u2500 Comments & Errors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-comments {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-comments i {\n color: var(--mj-brand-primary);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-errors {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-errors i {\n color: var(--mj-status-error);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-error-log {\n background: var(--mj-bg-surface);\n padding: 8px;\n border-radius: 4px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n font-size: 12px;\n color: var(--mj-status-error);\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n flex: 1;\n}\n\n/* \u2500\u2500\u2500 Create Wizard Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-wizard-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-wizard-container {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 600px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 24px;\n animation: rc-slideUp 0.2s ease;\n}\n\n@keyframes rc-fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes rc-slideUp {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* \u2500\u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 768px) {\n .rc-card-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .rc-card-meta {\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .rc-field-row {\n flex-direction: column;\n }\n\n .rc-field-label {\n width: 100%;\n min-width: unset;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n }\n\n .rc-field-values {\n padding: 8px 16px;\n }\n\n .rc-atomic-change {\n flex-wrap: wrap;\n }\n\n .rc-filter-bar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .rc-search-wrap { min-width: unset; }\n\n .rc-filter-pill { justify-content: center; }\n\n .rc-page-header {\n flex-direction: column;\n gap: 12px;\n }\n\n .rc-header-meta { text-align: left; }\n}\n\n@media (max-width: 480px) {\n .rc-container { padding: 12px 16px; }\n\n .rc-card { margin-left: 36px; }\n\n .rc-date-label { padding-left: 36px; }\n\n .rc-card::before { left: -19px; }\n\n .rc-timeline::before { left: 12px; }\n\n .rc-date-label::before { left: 7px; }\n}\n\n/* \u2500\u2500\u2500 Restore & Form Preview Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card.rc-card-previewing {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.rc-previewing-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 2px 8px;\n font-size: 11px;\n font-weight: 600;\n border-radius: 999px;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.rc-card-preview-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1.1;\n}\n\n.rc-card-preview-btn:hover {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.rc-card-preview-btn--active {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n}\n\n.rc-restore-action {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n padding-top: 10px;\n margin-top: 10px;\n /* Breathing room from the card's bottom and right edges so the button\n doesn't sit flush against the border. */\n padding-right: 10px;\n padding-bottom: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.rc-preview-form-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1;\n}\n\n.rc-preview-form-btn:hover {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.rc-preview-form-btn--active {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.rc-restore-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1;\n}\n\n.rc-restore-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-restore-btn:active {\n transform: translateY(1px);\n box-shadow: none;\n}\n\n.rc-restore-btn i {\n font-size: 13px;\n}\n\n/* \u2500\u2500\u2500 Restore Preview Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-preview-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-restore-preview-panel {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 700px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 0;\n animation: rc-slideUp 0.2s ease;\n}\n\n.rc-restore-preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.rc-restore-preview-title i {\n color: var(--mj-brand-primary);\n}\n\n.rc-restore-preview-close {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 16px;\n transition: color 0.15s, background 0.15s;\n}\n\n.rc-restore-preview-close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-restore-preview-meta {\n display: flex;\n gap: 20px;\n padding: 12px 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-empty {\n padding: 24px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.rc-restore-preview-empty i {\n color: var(--mj-text-disabled);\n}\n\n/* Restore Preview Table */\n.rc-restore-preview-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.rc-restore-preview-table th {\n text-align: left;\n padding: 10px 16px;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-table td {\n padding: 10px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n vertical-align: top;\n}\n\n.rc-restore-preview-table tr:last-child td {\n border-bottom: none;\n}\n\n.rc-restore-preview-table tr.rc-diff-changed {\n background: color-mix(in srgb, var(--mj-status-warning) 5%, var(--mj-bg-surface));\n}\n\n.rc-restore-preview-table tr.rc-diff-unchanged {\n opacity: 0.6;\n}\n\n.rc-restore-field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n}\n\n.rc-restore-current {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-secondary);\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-version {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-indicator {\n text-align: center;\n width: 30px;\n}\n\n.rc-diff-changed .rc-restore-indicator i {\n color: var(--mj-status-warning);\n}\n\n.rc-diff-unchanged .rc-restore-indicator i {\n color: var(--mj-status-success);\n font-size: 12px;\n}\n\n/* Restore Preview Actions */\n.rc-restore-preview-actions {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-confirm-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-confirm-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.rc-restore-confirm-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.rc-restore-cancel-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-cancel-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.rc-restore-cancel-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore lineage + conditional filter chips + overflow popover\n * (added with the Restore Prior Version feature)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* \u2500\u2500\u2500 Filter pill enhancements \u2500\u2500\u2500 */\n\n.rc-filter-pill-count {\n margin-left: 4px;\n background: color-mix(in srgb, currentColor 12%, transparent);\n padding: 1px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-filter-pill.active .rc-filter-pill-count {\n background: color-mix(in srgb, var(--mj-text-inverse, #fff) 22%, transparent);\n}\n\n/* Restore-variant pill: violet treatment to set it apart from type pills */\n.rc-filter-pill-restore {\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n color: color-mix(in srgb, var(--mj-status-info) 80%, var(--mj-text-secondary));\n border-color: color-mix(in srgb, var(--mj-status-info) 30%, var(--mj-border-default));\n}\n.rc-filter-pill-restore:hover {\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n.rc-filter-pill-restore.active {\n background: var(--mj-status-info);\n color: var(--mj-text-inverse, #fff);\n border-color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Overflow filter popover \u2500\u2500\u2500 */\n\n.rc-filter-overflow-wrap {\n position: relative;\n display: inline-block;\n}\n\n.rc-filter-pill-overflow {\n /* Overflow trigger inherits the standard filter pill look */\n}\n\n.rc-filter-overflow-caret {\n font-size: 9px;\n margin-left: 2px;\n}\n\n.rc-filter-overflow-backdrop {\n position: fixed;\n inset: 0;\n z-index: 10;\n}\n\n.rc-filter-overflow-popover {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: 11;\n min-width: 240px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 14px 40px rgba(0, 0, 0, 0.18);\n padding: 8px;\n}\n\n.rc-filter-overflow-header {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n font-weight: 600;\n padding: 6px 8px 8px;\n}\n\n.rc-filter-overflow-row {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 7px 8px;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n\n.rc-filter-overflow-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-filter-overflow-row input[type=\"checkbox\"] {\n margin: 0;\n accent-color: var(--mj-brand-primary);\n}\n\n.rc-filter-overflow-row i {\n color: var(--mj-text-muted);\n font-size: 12px;\n width: 14px;\n text-align: center;\n}\n\n.rc-filter-overflow-row-restore i {\n color: var(--mj-status-info);\n}\n\n.rc-filter-overflow-label {\n flex: 1;\n}\n\n.rc-filter-overflow-count {\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 500;\n}\n\n.rc-filter-overflow-actions {\n display: flex;\n justify-content: space-between;\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 8px;\n margin-top: 6px;\n}\n\n.rc-filter-overflow-clear,\n.rc-filter-overflow-done {\n background: none;\n border: none;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 4px 10px;\n border-radius: 5px;\n}\n\n.rc-filter-overflow-clear {\n color: var(--mj-text-muted);\n}\n.rc-filter-overflow-clear:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.rc-filter-overflow-done {\n color: var(--mj-brand-primary);\n}\n.rc-filter-overflow-done:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n/* \u2500\u2500\u2500 Snapshot type badge + card accent \u2500\u2500\u2500 */\n\n.type-snapshot .rc-card-type-badge {\n background: color-mix(in srgb, var(--mj-text-muted) 15%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Restore Source pill (in card meta) \u2500\u2500\u2500 */\n\n.source-restore {\n background: color-mix(in srgb, var(--mj-status-info) 12%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Restore card variant: violet left accent \u2500\u2500\u2500 */\n\n.rc-card.rc-card-restore {\n border-left: 3px solid var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Lineage chip \u2500\u2500\u2500 */\n\n/* Lineage chip \u2014 outline-only \"interactive link\" treatment so it reads as\n distinct from the filled RESTORE badge sitting next to it. The badge says\n \"this row IS a restore\" (filled, static); the chip says \"click here to\n see the source version\" (outline, hoverable). */\n.rc-restored-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n margin-left: 8px;\n padding: 2px 9px;\n border-radius: 11px;\n font-size: 11px;\n font-weight: 500;\n background: transparent;\n color: color-mix(in srgb, var(--mj-status-info) 90%, var(--mj-text-primary));\n border: 1px solid color-mix(in srgb, var(--mj-status-info) 40%, var(--mj-border-default));\n cursor: pointer;\n text-decoration: none;\n white-space: nowrap;\n transition: background-color 0.12s, border-color 0.12s, color 0.12s;\n}\n\n.rc-restored-chip:hover {\n background: color-mix(in srgb, var(--mj-status-info) 12%, transparent);\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n\n.rc-restored-chip i {\n font-size: 10px;\n}\n\n.rc-restored-chip-orphan {\n cursor: default;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n border-color: var(--mj-border-default);\n}\n\n.rc-restored-chip-orphan:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Card highlight (when jumped-to via lineage chip) \u2500\u2500\u2500 */\n\n.rc-card.rc-card-highlight {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n animation: rc-card-pulse 1.4s ease-in-out;\n}\n\n@keyframes rc-card-pulse {\n 0%, 100% { background: var(--mj-bg-surface); }\n 50% { background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface)); }\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore-row badge override + Restore Reason block\n * (mockup-aligned treatment for restore rows in the timeline)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* The base type-update badge styling would otherwise paint a restore row's\n badge blue with \"Update\" text. Override to violet + \"Restore\" text so it\n matches the source pill, lineage chip, and card border. */\n.rc-card-type-badge.rc-card-type-badge-restore {\n background: color-mix(in srgb, var(--mj-status-info) 14%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* Restore reason \u2014 minimal blockquote treatment.\n A thin violet left bar + italic text reads like a margin note rather than\n a heavy callout. Visually connected to the restore family (left bar uses\n the same violet as the badge / source pill / card border) without\n competing with the field-diff rows that follow. */\n.rc-restore-reason {\n /* Indented in from the card body edge so it visually nests one level\n deeper than the field-diff rows that follow, and given generous\n vertical breathing room so it doesn't crowd the lineage chip above\n or the first field row below. */\n margin: 14px 8px 18px 18px;\n padding: 0 0 0 12px;\n border-left: 2px solid color-mix(in srgb, var(--mj-status-info) 55%, var(--mj-border-default));\n display: flex;\n align-items: baseline;\n gap: 8px;\n font-size: 13px;\n line-height: 1.5;\n}\n\n.rc-restore-reason-label {\n flex-shrink: 0;\n font-size: 11px;\n font-weight: 600;\n color: color-mix(in srgb, var(--mj-status-info) 75%, var(--mj-text-muted));\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n.rc-restore-reason-text {\n color: var(--mj-text-secondary);\n font-style: italic;\n}\n\n/* \u2500\u2500\u2500 Cross-Version Diff Comparison Workbench (vA <-> vB) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-compare-toggle-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-compare-toggle-btn:hover,\n.rc-compare-toggle-btn.active {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.rc-compare-panel {\n background: var(--mj-bg-surface);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n border-radius: 10px;\n margin-bottom: 16px;\n overflow: hidden;\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-compare-toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface-sunken));\n border-bottom: 1px solid var(--mj-border-default);\n flex-wrap: wrap;\n}\n\n.rc-compare-slot {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: 1;\n min-width: 190px;\n}\n\n.rc-compare-badge {\n padding: 2px 7px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n white-space: nowrap;\n}\n\n.rc-compare-badge--base {\n background: color-mix(in srgb, var(--mj-status-warning) 16%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.rc-compare-badge--target {\n background: color-mix(in srgb, var(--mj-status-success) 16%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.rc-compare-select {\n flex: 1;\n min-width: 0;\n padding: 5px 8px;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12px;\n font-family: inherit;\n outline: none;\n}\n\n.rc-compare-select:focus {\n border-color: var(--mj-brand-primary);\n}\n\n.rc-compare-swap-btn,\n.rc-compare-action-btn {\n width: 28px;\n height: 28px;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n flex-shrink: 0;\n transition: all 0.15s ease;\n}\n\n.rc-compare-swap-btn:hover,\n.rc-compare-action-btn:hover,\n.rc-compare-action-btn.active {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.rc-compare-summary {\n padding: 8px 14px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-compare-diff-list {\n max-height: 280px;\n overflow-y: auto;\n}\n\n.rc-compare-empty {\n padding: 14px 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.rc-compare-empty i {\n color: var(--mj-status-success);\n}\n\n.rc-card-compare-pills {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.rc-card-compare-pill {\n min-width: 22px;\n height: 20px;\n padding: 0 6px;\n border-radius: 5px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 10px;\n font-weight: 700;\n cursor: pointer;\n transition: all 0.12s ease;\n}\n\n.rc-card-compare-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-primary);\n}\n\n.rc-card-compare-pill.active {\n background: var(--mj-status-warning);\n border-color: var(--mj-status-warning);\n color: var(--mj-text-inverse);\n}\n\n.rc-card-compare-pill--target.active {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n"] }]
|
|
1584
2566
|
}], () => [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i1.MJNotificationService }, { type: i2.DomSanitizer }], { DialogClosed: [{
|
|
1585
2567
|
type: Output
|
|
1586
2568
|
}], dialogClosed: [{
|
|
@@ -1589,8 +2571,24 @@ export class RecordChangesComponent extends BaseAngularComponent {
|
|
|
1589
2571
|
type: Input
|
|
1590
2572
|
}], AllowRestore: [{
|
|
1591
2573
|
type: Input
|
|
2574
|
+
}], PreviewedChangeID: [{
|
|
2575
|
+
type: Input
|
|
2576
|
+
}], PreviewVersionSelected: [{
|
|
2577
|
+
type: Output
|
|
1592
2578
|
}], RestoreRequested: [{
|
|
1593
2579
|
type: Output
|
|
2580
|
+
}], BurstResolution: [{
|
|
2581
|
+
type: Input
|
|
2582
|
+
}], BurstCoalesceStrategy: [{
|
|
2583
|
+
type: Input
|
|
2584
|
+
}], BurstSessionGapHours: [{
|
|
2585
|
+
type: Input
|
|
2586
|
+
}], BurstMaxClusters: [{
|
|
2587
|
+
type: Input
|
|
2588
|
+
}], BurstEraZoomThreshold: [{
|
|
2589
|
+
type: Input
|
|
2590
|
+
}], AllowBurstZoom: [{
|
|
2591
|
+
type: Input
|
|
1594
2592
|
}] }); })();
|
|
1595
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RecordChangesComponent, { className: "RecordChangesComponent", filePath: "src/lib/ng-record-changes.component.ts", lineNumber:
|
|
2593
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RecordChangesComponent, { className: "RecordChangesComponent", filePath: "src/lib/ng-record-changes.component.ts", lineNumber: 181 }); })();
|
|
1596
2594
|
//# sourceMappingURL=ng-record-changes.component.js.map
|