@mj-biz-apps/contracts-ng 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/lib/form-panels/contract-form.panels.d.ts +111 -0
  2. package/dist/lib/form-panels/contract-form.panels.d.ts.map +1 -0
  3. package/dist/lib/form-panels/contract-form.panels.js +1002 -0
  4. package/dist/lib/form-panels/contract-form.panels.js.map +1 -0
  5. package/dist/lib/form-panels/contract-form.policy.d.ts +5 -0
  6. package/dist/lib/form-panels/contract-form.policy.d.ts.map +1 -0
  7. package/dist/lib/form-panels/contract-form.policy.js +33 -0
  8. package/dist/lib/form-panels/contract-form.policy.js.map +1 -0
  9. package/dist/lib/form-panels/contract.panels.d.ts +55 -3
  10. package/dist/lib/form-panels/contract.panels.d.ts.map +1 -1
  11. package/dist/lib/form-panels/contract.panels.js +619 -362
  12. package/dist/lib/form-panels/contract.panels.js.map +1 -1
  13. package/dist/lib/form-panels/organization.panels.d.ts +4 -13
  14. package/dist/lib/form-panels/organization.panels.d.ts.map +1 -1
  15. package/dist/lib/form-panels/organization.panels.js +54 -62
  16. package/dist/lib/form-panels/organization.panels.js.map +1 -1
  17. package/dist/lib/form-panels/person.panels.d.ts +14 -0
  18. package/dist/lib/form-panels/person.panels.d.ts.map +1 -0
  19. package/dist/lib/form-panels/person.panels.js +108 -0
  20. package/dist/lib/form-panels/person.panels.js.map +1 -0
  21. package/dist/lib/form-panels/supersede.panel.d.ts +29 -3
  22. package/dist/lib/form-panels/supersede.panel.d.ts.map +1 -1
  23. package/dist/lib/form-panels/supersede.panel.js +81 -23
  24. package/dist/lib/form-panels/supersede.panel.js.map +1 -1
  25. package/dist/lib/pages/contracts-dashboard.page.d.ts +37 -17
  26. package/dist/lib/pages/contracts-dashboard.page.d.ts.map +1 -1
  27. package/dist/lib/pages/contracts-dashboard.page.js +365 -63
  28. package/dist/lib/pages/contracts-dashboard.page.js.map +1 -1
  29. package/dist/lib/sections/section-shell.component.js +2 -2
  30. package/dist/public-api.d.ts +3 -1
  31. package/dist/public-api.d.ts.map +1 -1
  32. package/dist/public-api.js +15 -4
  33. package/dist/public-api.js.map +1 -1
  34. package/package.json +2 -3
  35. package/dist/lib/form-panels/record-files.panel.d.ts +0 -151
  36. package/dist/lib/form-panels/record-files.panel.d.ts.map +0 -1
  37. package/dist/lib/form-panels/record-files.panel.js +0 -1046
  38. package/dist/lib/form-panels/record-files.panel.js.map +0 -1
@@ -0,0 +1,1002 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ /**
8
+ * @fileoverview Contract form body — Overview plus organized rail sections.
9
+ *
10
+ * Replaces leftover generated field dumps (Contract Details, Stakeholders, Provenance,
11
+ * Lifecycle, Notes) with:
12
+ * Overview (exec briefing) · Agreement · Parties · Dates · Renewal · Notes
13
+ * Modifications · Lineage · Re-papering · Provenance
14
+ *
15
+ * Dates / Renewal / Lineage / Re-papering already live in sibling files.
16
+ * Files on a contract are MJ's stock attachments (form toolbar), not a custom Documents section.
17
+ * `contributionKey` equals each panel's `SectionKey`. Overview is the only
18
+ * `inclusion: 'Primary'` so it leads; the rest sort into the related band by sortKey.
19
+ *
20
+ * @module @mj-biz-apps/contracts-ng
21
+ */
22
+ import { Component, ViewEncapsulation } from '@angular/core';
23
+ import { CommonModule } from '@angular/common';
24
+ import { CompositeKey } from '@memberjunction/core';
25
+ import { RegisterClassEx } from '@memberjunction/global';
26
+ import { BaseFormPanel, BaseFormsModule } from '@memberjunction/ng-base-forms';
27
+ import { MJC_ENTITIES, MJC_FOREIGN_ENTITIES } from '../data/entity-names';
28
+ import * as i0 from "@angular/core";
29
+ import * as i1 from "@memberjunction/ng-base-forms";
30
+ function MJCContractOverviewPanel_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
31
+ i0.ɵɵelementStart(0, "div", 19);
32
+ i0.ɵɵelement(1, "i", 20);
33
+ i0.ɵɵtext(2);
34
+ i0.ɵɵelementEnd();
35
+ } if (rf & 2) {
36
+ const h_r1 = ctx.$implicit;
37
+ i0.ɵɵadvance(2);
38
+ i0.ɵɵtextInterpolate1(" ", h_r1, " ");
39
+ } }
40
+ function MJCContractOverviewPanel_Conditional_2_Template(rf, ctx) { if (rf & 1) {
41
+ i0.ɵɵelementStart(0, "div", 2);
42
+ i0.ɵɵrepeaterCreate(1, MJCContractOverviewPanel_Conditional_2_For_2_Template, 3, 1, "div", 19, i0.ɵɵrepeaterTrackByIdentity);
43
+ i0.ɵɵelementEnd();
44
+ } if (rf & 2) {
45
+ const ctx_r1 = i0.ɵɵnextContext();
46
+ i0.ɵɵadvance();
47
+ i0.ɵɵrepeater(ctx_r1.Health);
48
+ } }
49
+ function MJCContractOverviewPanel_Conditional_3_Template(rf, ctx) { if (rf & 1) {
50
+ i0.ɵɵelementStart(0, "div", 3);
51
+ i0.ɵɵelement(1, "i", 21);
52
+ i0.ɵɵtext(2, " No issues. ");
53
+ i0.ɵɵelementEnd();
54
+ } }
55
+ function MJCContractOverviewPanel_Conditional_41_Template(rf, ctx) { if (rf & 1) {
56
+ const _r3 = i0.ɵɵgetCurrentView();
57
+ i0.ɵɵelementStart(0, "button", 22);
58
+ i0.ɵɵlistener("click", function MJCContractOverviewPanel_Conditional_41_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OpenCustomer($event)); });
59
+ i0.ɵɵtext(1);
60
+ i0.ɵɵelementEnd();
61
+ } if (rf & 2) {
62
+ const ctx_r1 = i0.ɵɵnextContext();
63
+ i0.ɵɵadvance();
64
+ i0.ɵɵtextInterpolate(ctx_r1.CustomerName);
65
+ } }
66
+ function MJCContractOverviewPanel_Conditional_42_Template(rf, ctx) { if (rf & 1) {
67
+ i0.ɵɵtext(0);
68
+ } if (rf & 2) {
69
+ const ctx_r1 = i0.ɵɵnextContext();
70
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.CustomerName || "\u2014", " ");
71
+ } }
72
+ function MJCContractOverviewPanel_Conditional_47_Template(rf, ctx) { if (rf & 1) {
73
+ const _r4 = i0.ɵɵgetCurrentView();
74
+ i0.ɵɵelementStart(0, "button", 22);
75
+ i0.ɵɵlistener("click", function MJCContractOverviewPanel_Conditional_47_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OpenContact($event)); });
76
+ i0.ɵɵtext(1);
77
+ i0.ɵɵelementEnd();
78
+ } if (rf & 2) {
79
+ const ctx_r1 = i0.ɵɵnextContext();
80
+ i0.ɵɵadvance();
81
+ i0.ɵɵtextInterpolate(ctx_r1.ContactName);
82
+ } }
83
+ function MJCContractOverviewPanel_Conditional_48_Template(rf, ctx) { if (rf & 1) {
84
+ i0.ɵɵtext(0);
85
+ } if (rf & 2) {
86
+ const ctx_r1 = i0.ɵɵnextContext();
87
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.ContactName || "\u2014", " ");
88
+ } }
89
+ function MJCContractOverviewPanel_Conditional_89_Conditional_4_Template(rf, ctx) { if (rf & 1) {
90
+ const _r5 = i0.ɵɵgetCurrentView();
91
+ i0.ɵɵelementStart(0, "button", 22);
92
+ i0.ɵɵlistener("click", function MJCContractOverviewPanel_Conditional_89_Conditional_4_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenSource($event)); });
93
+ i0.ɵɵtext(1);
94
+ i0.ɵɵelementEnd();
95
+ } if (rf & 2) {
96
+ const ctx_r1 = i0.ɵɵnextContext(2);
97
+ i0.ɵɵadvance();
98
+ i0.ɵɵtextInterpolate(ctx_r1.SourceLabel);
99
+ } }
100
+ function MJCContractOverviewPanel_Conditional_89_Conditional_5_Template(rf, ctx) { if (rf & 1) {
101
+ i0.ɵɵtext(0);
102
+ } if (rf & 2) {
103
+ const ctx_r1 = i0.ɵɵnextContext(2);
104
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.SourceLabel, " ");
105
+ } }
106
+ function MJCContractOverviewPanel_Conditional_89_Template(rf, ctx) { if (rf & 1) {
107
+ i0.ɵɵelementStart(0, "div")(1, "div", 6);
108
+ i0.ɵɵtext(2, "Created from");
109
+ i0.ɵɵelementEnd();
110
+ i0.ɵɵelementStart(3, "div", 7);
111
+ i0.ɵɵconditionalCreate(4, MJCContractOverviewPanel_Conditional_89_Conditional_4_Template, 2, 1, "button", 13)(5, MJCContractOverviewPanel_Conditional_89_Conditional_5_Template, 1, 1);
112
+ i0.ɵɵelementEnd()();
113
+ } if (rf & 2) {
114
+ const ctx_r1 = i0.ɵɵnextContext();
115
+ i0.ɵɵadvance(4);
116
+ i0.ɵɵconditional(ctx_r1.CanOpenSource ? 4 : 5);
117
+ } }
118
+ function MJCContractOverviewPanel_Conditional_94_Template(rf, ctx) { if (rf & 1) {
119
+ i0.ɵɵelementStart(0, "p", 17);
120
+ i0.ɵɵtext(1);
121
+ i0.ɵɵelementEnd();
122
+ } if (rf & 2) {
123
+ const ctx_r1 = i0.ɵɵnextContext();
124
+ i0.ɵɵadvance();
125
+ i0.ɵɵtextInterpolate(ctx_r1.NextMove);
126
+ } }
127
+ function MJCContractOverviewPanel_Conditional_95_Template(rf, ctx) { if (rf & 1) {
128
+ i0.ɵɵelementStart(0, "p", 18);
129
+ i0.ɵɵtext(1, "No action needed.");
130
+ i0.ɵɵelementEnd();
131
+ } }
132
+ const _forTrack0 = ($index, $item) => $item.name;
133
+ function MJCContractAgreementPanel_For_3_Template(rf, ctx) { if (rf & 1) {
134
+ const _r1 = i0.ɵɵgetCurrentView();
135
+ i0.ɵɵelementStart(0, "div", 3)(1, "mj-form-field", 4);
136
+ i0.ɵɵlistener("Navigate", function MJCContractAgreementPanel_For_3_Template_mj_form_field_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.FormComponent.OnFormNavigate($event)); });
137
+ i0.ɵɵelementEnd()();
138
+ } if (rf & 2) {
139
+ const f_r3 = ctx.$implicit;
140
+ const ctx_r1 = i0.ɵɵnextContext();
141
+ i0.ɵɵclassProp("mjc-fg--span", f_r3.span);
142
+ i0.ɵɵadvance();
143
+ i0.ɵɵproperty("Record", ctx_r1.Record)("ShowLabel", true)("FieldName", f_r3.name)("Type", f_r3.type)("EditMode", f_r3.readOnly ? false : ctx_r1.EditMode)("FormContext", ctx_r1.FormContext)("LinkType", f_r3.link ?? "None");
144
+ } }
145
+ function MJCContractPartiesPanel_For_3_Template(rf, ctx) { if (rf & 1) {
146
+ const _r1 = i0.ɵɵgetCurrentView();
147
+ i0.ɵɵelementStart(0, "div", 3)(1, "mj-form-field", 4);
148
+ i0.ɵɵlistener("Navigate", function MJCContractPartiesPanel_For_3_Template_mj_form_field_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.FormComponent.OnFormNavigate($event)); });
149
+ i0.ɵɵelementEnd()();
150
+ } if (rf & 2) {
151
+ const f_r3 = ctx.$implicit;
152
+ const ctx_r1 = i0.ɵɵnextContext();
153
+ i0.ɵɵclassProp("mjc-fg--span", f_r3.span);
154
+ i0.ɵɵadvance();
155
+ i0.ɵɵproperty("Record", ctx_r1.Record)("ShowLabel", true)("FieldName", f_r3.name)("Type", f_r3.type)("EditMode", f_r3.readOnly ? false : ctx_r1.EditMode)("FormContext", ctx_r1.FormContext)("LinkType", f_r3.link ?? "None");
156
+ } }
157
+ const _c0 = "\n .mjc-fields-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--mj-space-4) var(--mj-space-5);\n padding: var(--mj-space-4) var(--mj-space-5);\n }\n @media (max-width: 720px) { .mjc-fields-grid { grid-template-columns: 1fr; } }\n .mjc-fg { min-width: 0; }\n .mjc-fg--span { grid-column: 1 / -1; }\n .mjc-fg .mj-forms-field {\n display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding: 0;\n }\n .mjc-fg .mj-forms-field-label {\n font-size: var(--mj-text-xs); font-weight: 700; letter-spacing: .06em;\n text-transform: uppercase; color: var(--mj-text-muted);\n }\n .mjc-fg .mj-forms-field--editing:hover { margin: 0; padding: 0; }\n";
158
+ function MJCContractNotesPanel_For_3_Template(rf, ctx) { if (rf & 1) {
159
+ const _r1 = i0.ɵɵgetCurrentView();
160
+ i0.ɵɵelementStart(0, "div", 3)(1, "mj-form-field", 4);
161
+ i0.ɵɵlistener("Navigate", function MJCContractNotesPanel_For_3_Template_mj_form_field_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.FormComponent.OnFormNavigate($event)); });
162
+ i0.ɵɵelementEnd()();
163
+ } if (rf & 2) {
164
+ const f_r3 = ctx.$implicit;
165
+ const ctx_r1 = i0.ɵɵnextContext();
166
+ i0.ɵɵclassProp("mjc-fg--span", f_r3.span);
167
+ i0.ɵɵadvance();
168
+ i0.ɵɵproperty("Record", ctx_r1.Record)("ShowLabel", true)("FieldName", f_r3.name)("Type", f_r3.type)("EditMode", f_r3.readOnly ? false : ctx_r1.EditMode)("FormContext", ctx_r1.FormContext)("LinkType", f_r3.link ?? "None");
169
+ } }
170
+ function MJCContractProvenanceFieldsPanel_For_3_Template(rf, ctx) { if (rf & 1) {
171
+ const _r1 = i0.ɵɵgetCurrentView();
172
+ i0.ɵɵelementStart(0, "div", 3)(1, "mj-form-field", 4);
173
+ i0.ɵɵlistener("Navigate", function MJCContractProvenanceFieldsPanel_For_3_Template_mj_form_field_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.FormComponent.OnFormNavigate($event)); });
174
+ i0.ɵɵelementEnd()();
175
+ } if (rf & 2) {
176
+ const f_r3 = ctx.$implicit;
177
+ const ctx_r1 = i0.ɵɵnextContext();
178
+ i0.ɵɵclassProp("mjc-fg--span", f_r3.span);
179
+ i0.ɵɵadvance();
180
+ i0.ɵɵproperty("Record", ctx_r1.Record)("ShowLabel", true)("FieldName", f_r3.name)("Type", f_r3.type)("EditMode", f_r3.readOnly ? false : ctx_r1.EditMode)("FormContext", ctx_r1.FormContext)("LinkType", f_r3.link ?? "None");
181
+ } }
182
+ function MJCContractLifecyclePanel_For_3_Template(rf, ctx) { if (rf & 1) {
183
+ const _r1 = i0.ɵɵgetCurrentView();
184
+ i0.ɵɵelementStart(0, "div", 3)(1, "mj-form-field", 4);
185
+ i0.ɵɵlistener("Navigate", function MJCContractLifecyclePanel_For_3_Template_mj_form_field_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.FormComponent.OnFormNavigate($event)); });
186
+ i0.ɵɵelementEnd()();
187
+ } if (rf & 2) {
188
+ const f_r3 = ctx.$implicit;
189
+ const ctx_r1 = i0.ɵɵnextContext();
190
+ i0.ɵɵclassProp("mjc-fg--span", f_r3.span);
191
+ i0.ɵɵadvance();
192
+ i0.ɵɵproperty("Record", ctx_r1.Record)("ShowLabel", true)("FieldName", f_r3.name)("Type", f_r3.type)("EditMode", f_r3.readOnly ? false : ctx_r1.EditMode)("FormContext", ctx_r1.FormContext)("LinkType", f_r3.link ?? "None");
193
+ } }
194
+ function MJCContractModificationsPanel_Conditional_1_Template(rf, ctx) { if (rf & 1) {
195
+ const _r1 = i0.ɵɵgetCurrentView();
196
+ i0.ɵɵelementStart(0, "mj-explorer-entity-data-grid", 2);
197
+ i0.ɵɵlistener("Navigate", function MJCContractModificationsPanel_Conditional_1_Template_mj_explorer_entity_data_grid_Navigate_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.FormComponent.OnFormNavigate($event)); })("AfterDataLoad", function MJCContractModificationsPanel_Conditional_1_Template_mj_explorer_entity_data_grid_AfterDataLoad_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDataLoad($event)); });
198
+ i0.ɵɵelementEnd();
199
+ } if (rf & 2) {
200
+ const ctx_r1 = i0.ɵɵnextContext();
201
+ i0.ɵɵproperty("Params", ctx_r1.FormComponent.BuildRelationshipViewParamsByEntityName(ctx_r1.Entity, "ContractID"))("NewRecordValues", ctx_r1.FormComponent.NewRecordValues(ctx_r1.Entity, "ContractID"))("AllowLoad", ctx_r1.FormComponent.IsSectionExpanded("modifications"))("ShowToolbar", true);
202
+ } }
203
+ const E = MJC_ENTITIES.Contract;
204
+ const FIELD_STYLES = `
205
+ .mjc-fields-grid {
206
+ display: grid;
207
+ grid-template-columns: 1fr 1fr;
208
+ gap: var(--mj-space-4) var(--mj-space-5);
209
+ padding: var(--mj-space-4) var(--mj-space-5);
210
+ }
211
+ @media (max-width: 720px) { .mjc-fields-grid { grid-template-columns: 1fr; } }
212
+ .mjc-fg { min-width: 0; }
213
+ .mjc-fg--span { grid-column: 1 / -1; }
214
+ .mjc-fg .mj-forms-field {
215
+ display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding: 0;
216
+ }
217
+ .mjc-fg .mj-forms-field-label {
218
+ font-size: var(--mj-text-xs); font-weight: 700; letter-spacing: .06em;
219
+ text-transform: uppercase; color: var(--mj-text-muted);
220
+ }
221
+ .mjc-fg .mj-forms-field--editing:hover { margin: 0; padding: 0; }
222
+ `;
223
+ function dateLabel(d) {
224
+ if (!d)
225
+ return '—';
226
+ return new Date(d).toLocaleDateString(undefined, { day: 'numeric', month: 'short', year: 'numeric', timeZone: 'UTC' });
227
+ }
228
+ function endsInText(days) {
229
+ if (days == null)
230
+ return '';
231
+ if (days < 0)
232
+ return `ended ${Math.abs(days)} days ago`;
233
+ if (days === 0)
234
+ return 'ends today';
235
+ if (days < 60)
236
+ return `in ${days} days`;
237
+ const months = Math.round(days / 30);
238
+ return `in ${months} month${months === 1 ? '' : 's'}`;
239
+ }
240
+ /**
241
+ * The whole clause, verb included, because the verb has to agree with the tense
242
+ * `endsInText` picks. Writing `Term ends ${endsInText(d)}` reads "Term ends ends
243
+ * today" on the day a term ends, and "Term ends ended 3 days ago" behind it.
244
+ */
245
+ function termEndsText(days) {
246
+ if (days == null)
247
+ return '';
248
+ if (days < 0)
249
+ return `Term ${endsInText(days)}`;
250
+ if (days === 0)
251
+ return 'Term ends today';
252
+ return `Term ends ${endsInText(days)}`;
253
+ }
254
+ /* ── Overview ─────────────────────────────────────────────────────────────── */
255
+ let MJCContractOverviewPanel = class MJCContractOverviewPanel extends BaseFormPanel {
256
+ dateLabel = dateLabel;
257
+ get State() { return this.Record?.State || 'Draft'; }
258
+ get TypeName() { return this.Record?.ContractType ?? ''; }
259
+ get CustomerName() { return this.Record?.CustomerOrganization ?? ''; }
260
+ get ContactName() { return this.Record?.PrimaryContactPerson ?? ''; }
261
+ get CompanyName() { return this.Record?.Company ?? ''; }
262
+ get TemplateName() { return this.Record?.ContractTemplate ?? ''; }
263
+ get IncreaseLabel() {
264
+ const n = this.Record?.AnnualIncreasePercent;
265
+ return n == null ? '—' : `${n}%`;
266
+ }
267
+ DaysLabel(n) {
268
+ return n == null ? '—' : `${n} days`;
269
+ }
270
+ get StateTone() {
271
+ switch (this.State) {
272
+ case 'Active':
273
+ case 'Executed': return 'success';
274
+ case 'Terminated': return 'warning';
275
+ default: return 'muted';
276
+ }
277
+ }
278
+ get EndClock() {
279
+ if (this.Record?.TerminatedDate)
280
+ return 'Terminated';
281
+ const d = this.Record?.DaysToEnd;
282
+ if (d == null)
283
+ return 'Undated';
284
+ return endsInText(d).replace(/^in /, '').replace(/^ended /, '') || '—';
285
+ }
286
+ get EndTone() {
287
+ const d = this.Record?.DaysToEnd;
288
+ if (this.State === 'Active' && (d == null || d <= 120))
289
+ return 'warning';
290
+ if (d != null && d < 0)
291
+ return 'warning';
292
+ if (this.State === 'Active')
293
+ return 'success';
294
+ return 'muted';
295
+ }
296
+ get NoticeClock() {
297
+ const d = this.Record?.RenewalNoticeDeadline;
298
+ if (!d)
299
+ return 'None';
300
+ const days = daysUntil(d);
301
+ if (days == null)
302
+ return dateLabel(d);
303
+ if (days < 0)
304
+ return `${Math.abs(days)}d past`;
305
+ if (days === 0)
306
+ return 'Today';
307
+ return `${days}d`;
308
+ }
309
+ get NoticeTone() {
310
+ const d = this.Record?.RenewalNoticeDeadline;
311
+ if (!d)
312
+ return 'muted';
313
+ const days = daysUntil(d);
314
+ if (days != null && days <= 30)
315
+ return 'warning';
316
+ return 'muted';
317
+ }
318
+ get HasSource() {
319
+ return !!this.Record?.CreatingEntity;
320
+ }
321
+ get CanOpenSource() {
322
+ return !!(this.Record?.CreatingEntity && this.Record?.CreatingRecordID);
323
+ }
324
+ get SourceLabel() {
325
+ return this.Record?.CreatingEntity ?? '';
326
+ }
327
+ get Health() {
328
+ const out = [];
329
+ if (!this.Record)
330
+ return out;
331
+ if (this.Record.IsAwaitingDocument) {
332
+ out.push('Executed agreement not attached.');
333
+ }
334
+ if (this.Record.IsInCancellationWindow) {
335
+ out.push('Cancellation window is open.');
336
+ }
337
+ const end = this.Record.DaysToEnd;
338
+ if (end != null && end < 0 && !this.Record.TerminatedDate) {
339
+ out.push('The term has ended and no termination date is recorded.');
340
+ }
341
+ else if (this.State === 'Active' && end != null && end <= 120) {
342
+ out.push(`${termEndsText(end)}.`);
343
+ }
344
+ const notice = daysUntil(this.Record.RenewalNoticeDeadline);
345
+ if (notice != null && notice < 0) {
346
+ out.push('Renewal notice deadline has already passed.');
347
+ }
348
+ else if (notice != null && notice <= 30) {
349
+ out.push(`Renewal notice due by ${dateLabel(this.Record.RenewalNoticeDeadline)}.`);
350
+ }
351
+ if (this.Record.HasModifications) {
352
+ out.push('Standard agreement was modified.');
353
+ }
354
+ if (this.State === 'Active' && !this.Record.EndDate) {
355
+ out.push('Active with no end date.');
356
+ }
357
+ return out;
358
+ }
359
+ get NextMove() {
360
+ if (this.Record?.IsAwaitingDocument)
361
+ return 'Attach the executed agreement.';
362
+ if (this.Record?.IsInCancellationWindow)
363
+ return 'Cancellation window is open. Confirm whether the customer is renewing.';
364
+ const notice = daysUntil(this.Record?.RenewalNoticeDeadline);
365
+ if (notice != null && notice <= 30) {
366
+ return `Send the renewal notice. Deadline ${dateLabel(this.Record?.RenewalNoticeDeadline)}.`;
367
+ }
368
+ const end = this.Record?.DaysToEnd;
369
+ if (this.State === 'Active' && end != null && end <= 120) {
370
+ return `Begin renewal discussion. ${termEndsText(end)}.`;
371
+ }
372
+ if (this.Record?.HasModifications)
373
+ return 'Review the modifications to the standard agreement.';
374
+ return null;
375
+ }
376
+ OpenCustomer(event) {
377
+ this.open(event, MJC_FOREIGN_ENTITIES.Organization, this.Record?.CustomerOrganizationID);
378
+ }
379
+ OpenContact(event) {
380
+ this.open(event, MJC_FOREIGN_ENTITIES.Person, this.Record?.PrimaryContactPersonID);
381
+ }
382
+ OpenSource(event) {
383
+ const entity = this.Record?.CreatingEntity;
384
+ const id = this.Record?.CreatingRecordID;
385
+ if (!entity || !id)
386
+ return;
387
+ this.open(event, entity, id);
388
+ }
389
+ open(event, entity, id) {
390
+ if (!id)
391
+ return;
392
+ event.preventDefault();
393
+ this.FormComponent.OnFormNavigate({
394
+ Kind: 'record',
395
+ EntityName: entity,
396
+ PrimaryKey: CompositeKey.FromID(id),
397
+ OpenInNewTab: event.ctrlKey || event.metaKey,
398
+ });
399
+ }
400
+ static ɵfac = /*@__PURE__*/ (() => { let ɵMJCContractOverviewPanel_BaseFactory; return function MJCContractOverviewPanel_Factory(__ngFactoryType__) { return (ɵMJCContractOverviewPanel_BaseFactory || (ɵMJCContractOverviewPanel_BaseFactory = i0.ɵɵgetInheritedFactory(MJCContractOverviewPanel)))(__ngFactoryType__ || MJCContractOverviewPanel); }; })();
401
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJCContractOverviewPanel, selectors: [["mjc-contract-overview-panel"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 96, vars: 25, consts: [["SectionKey", "overview", "SectionName", "Overview", "Icon", "fa-solid fa-chart-pie", 3, "Form", "FormContext", "DefaultExpanded"], [1, "mjc-ov"], [1, "mjc-ov-health"], [1, "mjc-ov-ok"], [1, "mjc-ov-strip"], [1, "mjc-ov-kpi"], [1, "l"], [1, "v"], [1, "s"], [1, "mjc-ov-grid"], [1, "mjc-ov-card"], [1, "fa-solid", "fa-building"], [1, "mjc-ov-facts"], ["type", "button", 1, "mjc-ov-link"], [1, "fa-solid", "fa-scale-balanced"], [1, "mjc-ov-card", "mjc-ov-card--wide"], [1, "fa-solid", "fa-person-walking"], [1, "mjc-ov-next"], [1, "mjc-ov-empty"], [1, "mjc-ov-alert"], ["aria-hidden", "true", 1, "fa-solid", "fa-triangle-exclamation"], ["aria-hidden", "true", 1, "fa-solid", "fa-circle-check"], ["type", "button", 1, "mjc-ov-link", 3, "click"]], template: function MJCContractOverviewPanel_Template(rf, ctx) { if (rf & 1) {
402
+ i0.ɵɵelementStart(0, "mj-collapsible-panel", 0)(1, "div", 1);
403
+ i0.ɵɵconditionalCreate(2, MJCContractOverviewPanel_Conditional_2_Template, 3, 0, "div", 2)(3, MJCContractOverviewPanel_Conditional_3_Template, 3, 0, "div", 3);
404
+ i0.ɵɵelementStart(4, "div", 4)(5, "div", 5)(6, "div", 6);
405
+ i0.ɵɵtext(7, "State");
406
+ i0.ɵɵelementEnd();
407
+ i0.ɵɵelementStart(8, "div", 7);
408
+ i0.ɵɵtext(9);
409
+ i0.ɵɵelementEnd();
410
+ i0.ɵɵelementStart(10, "div", 8);
411
+ i0.ɵɵtext(11);
412
+ i0.ɵɵelementEnd()();
413
+ i0.ɵɵelementStart(12, "div", 5)(13, "div", 6);
414
+ i0.ɵɵtext(14, "Term ends");
415
+ i0.ɵɵelementEnd();
416
+ i0.ɵɵelementStart(15, "div", 7);
417
+ i0.ɵɵtext(16);
418
+ i0.ɵɵelementEnd();
419
+ i0.ɵɵelementStart(17, "div", 8);
420
+ i0.ɵɵtext(18);
421
+ i0.ɵɵelementEnd()();
422
+ i0.ɵɵelementStart(19, "div", 5)(20, "div", 6);
423
+ i0.ɵɵtext(21, "Notice");
424
+ i0.ɵɵelementEnd();
425
+ i0.ɵɵelementStart(22, "div", 7);
426
+ i0.ɵɵtext(23);
427
+ i0.ɵɵelementEnd();
428
+ i0.ɵɵelementStart(24, "div", 8);
429
+ i0.ɵɵtext(25);
430
+ i0.ɵɵelementEnd()();
431
+ i0.ɵɵelementStart(26, "div", 5)(27, "div", 6);
432
+ i0.ɵɵtext(28, "Auto-renew");
433
+ i0.ɵɵelementEnd();
434
+ i0.ɵɵelementStart(29, "div", 7);
435
+ i0.ɵɵtext(30);
436
+ i0.ɵɵelementEnd()()();
437
+ i0.ɵɵelementStart(31, "div", 9)(32, "article", 10)(33, "header");
438
+ i0.ɵɵelement(34, "i", 11);
439
+ i0.ɵɵtext(35, " Parties");
440
+ i0.ɵɵelementEnd();
441
+ i0.ɵɵelementStart(36, "div", 12)(37, "div")(38, "div", 6);
442
+ i0.ɵɵtext(39, "Customer");
443
+ i0.ɵɵelementEnd();
444
+ i0.ɵɵelementStart(40, "div", 7);
445
+ i0.ɵɵconditionalCreate(41, MJCContractOverviewPanel_Conditional_41_Template, 2, 1, "button", 13)(42, MJCContractOverviewPanel_Conditional_42_Template, 1, 1);
446
+ i0.ɵɵelementEnd()();
447
+ i0.ɵɵelementStart(43, "div")(44, "div", 6);
448
+ i0.ɵɵtext(45, "Contact");
449
+ i0.ɵɵelementEnd();
450
+ i0.ɵɵelementStart(46, "div", 7);
451
+ i0.ɵɵconditionalCreate(47, MJCContractOverviewPanel_Conditional_47_Template, 2, 1, "button", 13)(48, MJCContractOverviewPanel_Conditional_48_Template, 1, 1);
452
+ i0.ɵɵelementEnd()();
453
+ i0.ɵɵelementStart(49, "div")(50, "div", 6);
454
+ i0.ɵɵtext(51, "Company");
455
+ i0.ɵɵelementEnd();
456
+ i0.ɵɵelementStart(52, "div", 7);
457
+ i0.ɵɵtext(53);
458
+ i0.ɵɵelementEnd()();
459
+ i0.ɵɵelementStart(54, "div")(55, "div", 6);
460
+ i0.ɵɵtext(56, "Agreement");
461
+ i0.ɵɵelementEnd();
462
+ i0.ɵɵelementStart(57, "div", 7);
463
+ i0.ɵɵtext(58);
464
+ i0.ɵɵelementEnd()()()();
465
+ i0.ɵɵelementStart(59, "article", 10)(60, "header");
466
+ i0.ɵɵelement(61, "i", 14);
467
+ i0.ɵɵtext(62, " Obligation");
468
+ i0.ɵɵelementEnd();
469
+ i0.ɵɵelementStart(63, "div", 12)(64, "div")(65, "div", 6);
470
+ i0.ɵɵtext(66, "Executed");
471
+ i0.ɵɵelementEnd();
472
+ i0.ɵɵelementStart(67, "div", 7);
473
+ i0.ɵɵtext(68);
474
+ i0.ɵɵelementEnd()();
475
+ i0.ɵɵelementStart(69, "div")(70, "div", 6);
476
+ i0.ɵɵtext(71, "Effective");
477
+ i0.ɵɵelementEnd();
478
+ i0.ɵɵelementStart(72, "div", 7);
479
+ i0.ɵɵtext(73);
480
+ i0.ɵɵelementEnd()();
481
+ i0.ɵɵelementStart(74, "div")(75, "div", 6);
482
+ i0.ɵɵtext(76, "Notice we owe");
483
+ i0.ɵɵelementEnd();
484
+ i0.ɵɵelementStart(77, "div", 7);
485
+ i0.ɵɵtext(78);
486
+ i0.ɵɵelementEnd()();
487
+ i0.ɵɵelementStart(79, "div")(80, "div", 6);
488
+ i0.ɵɵtext(81, "Cancel window");
489
+ i0.ɵɵelementEnd();
490
+ i0.ɵɵelementStart(82, "div", 7);
491
+ i0.ɵɵtext(83);
492
+ i0.ɵɵelementEnd()();
493
+ i0.ɵɵelementStart(84, "div")(85, "div", 6);
494
+ i0.ɵɵtext(86, "Annual increase");
495
+ i0.ɵɵelementEnd();
496
+ i0.ɵɵelementStart(87, "div", 7);
497
+ i0.ɵɵtext(88);
498
+ i0.ɵɵelementEnd()();
499
+ i0.ɵɵconditionalCreate(89, MJCContractOverviewPanel_Conditional_89_Template, 6, 1, "div");
500
+ i0.ɵɵelementEnd()();
501
+ i0.ɵɵelementStart(90, "article", 15)(91, "header");
502
+ i0.ɵɵelement(92, "i", 16);
503
+ i0.ɵɵtext(93, " Next step");
504
+ i0.ɵɵelementEnd();
505
+ i0.ɵɵconditionalCreate(94, MJCContractOverviewPanel_Conditional_94_Template, 2, 1, "p", 17)(95, MJCContractOverviewPanel_Conditional_95_Template, 2, 0, "p", 18);
506
+ i0.ɵɵelementEnd()()()();
507
+ } if (rf & 2) {
508
+ i0.ɵɵproperty("Form", ctx.FormComponent)("FormContext", ctx.FormContext)("DefaultExpanded", true);
509
+ i0.ɵɵadvance(2);
510
+ i0.ɵɵconditional(ctx.Health.length ? 2 : ctx.Record.IsSaved ? 3 : -1);
511
+ i0.ɵɵadvance(3);
512
+ i0.ɵɵattribute("data-tone", ctx.StateTone);
513
+ i0.ɵɵadvance(4);
514
+ i0.ɵɵtextInterpolate(ctx.State);
515
+ i0.ɵɵadvance(2);
516
+ i0.ɵɵtextInterpolate(ctx.TypeName || "No type");
517
+ i0.ɵɵadvance();
518
+ i0.ɵɵattribute("data-tone", ctx.EndTone);
519
+ i0.ɵɵadvance(4);
520
+ i0.ɵɵtextInterpolate(ctx.EndClock);
521
+ i0.ɵɵadvance(2);
522
+ i0.ɵɵtextInterpolate(ctx.dateLabel(ctx.Record.EndDate));
523
+ i0.ɵɵadvance();
524
+ i0.ɵɵattribute("data-tone", ctx.NoticeTone);
525
+ i0.ɵɵadvance(4);
526
+ i0.ɵɵtextInterpolate(ctx.NoticeClock);
527
+ i0.ɵɵadvance(2);
528
+ i0.ɵɵtextInterpolate(ctx.dateLabel(ctx.Record.RenewalNoticeDeadline));
529
+ i0.ɵɵadvance(5);
530
+ i0.ɵɵtextInterpolate(ctx.Record.AutoRenew ? "Yes" : "No");
531
+ i0.ɵɵadvance(11);
532
+ i0.ɵɵconditional(ctx.Record.CustomerOrganizationID && ctx.CustomerName ? 41 : 42);
533
+ i0.ɵɵadvance(6);
534
+ i0.ɵɵconditional(ctx.Record.PrimaryContactPersonID && ctx.ContactName ? 47 : 48);
535
+ i0.ɵɵadvance(6);
536
+ i0.ɵɵtextInterpolate(ctx.CompanyName || "\u2014");
537
+ i0.ɵɵadvance(5);
538
+ i0.ɵɵtextInterpolate(ctx.TemplateName || "None");
539
+ i0.ɵɵadvance(10);
540
+ i0.ɵɵtextInterpolate(ctx.dateLabel(ctx.Record.ExecutedDate));
541
+ i0.ɵɵadvance(5);
542
+ i0.ɵɵtextInterpolate(ctx.dateLabel(ctx.Record.EffectiveDate));
543
+ i0.ɵɵadvance(5);
544
+ i0.ɵɵtextInterpolate(ctx.DaysLabel(ctx.Record.RenewalNoticeDays));
545
+ i0.ɵɵadvance(5);
546
+ i0.ɵɵtextInterpolate(ctx.DaysLabel(ctx.Record.CancellationWindowDays));
547
+ i0.ɵɵadvance(5);
548
+ i0.ɵɵtextInterpolate(ctx.IncreaseLabel);
549
+ i0.ɵɵadvance();
550
+ i0.ɵɵconditional(ctx.HasSource ? 89 : -1);
551
+ i0.ɵɵadvance(5);
552
+ i0.ɵɵconditional(ctx.NextMove ? 94 : 95);
553
+ } }, dependencies: [CommonModule, BaseFormsModule, i1.MjCollapsiblePanelComponent], styles: ["\n .mjc-ov { display: flex; flex-direction: column; gap: var(--mj-space-4); padding: var(--mj-space-3) var(--mj-space-4) var(--mj-space-5); }\n .mjc-ov-health { display: flex; flex-direction: column; gap: var(--mj-space-2); }\n .mjc-ov-alert {\n display: flex; align-items: center; gap: var(--mj-space-2);\n padding: var(--mj-space-2) var(--mj-space-3);\n background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text);\n border-radius: var(--mj-radius-md); font-size: var(--mj-text-sm); font-weight: 600;\n }\n .mjc-ov-ok {\n display: flex; align-items: center; gap: var(--mj-space-2);\n padding: var(--mj-space-2) var(--mj-space-3);\n background: var(--mj-status-success-bg); color: var(--mj-status-success-text);\n border-radius: var(--mj-radius-md); font-size: var(--mj-text-sm); font-weight: 600;\n }\n .mjc-ov-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--mj-space-3); }\n @media (max-width: 900px) { .mjc-ov-strip { grid-template-columns: 1fr 1fr; } }\n .mjc-ov-kpi {\n background: var(--mj-bg-page); border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md); padding: var(--mj-space-3) var(--mj-space-4);\n }\n .mjc-ov-kpi .l {\n font-size: var(--mj-text-xs); text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700;\n }\n .mjc-ov-kpi .v { font-size: 1.35rem; font-weight: 800; letter-spacing: -.02em; margin-top: 4px; line-height: 1.2; }\n .mjc-ov-kpi .s { color: var(--mj-text-muted); font-size: var(--mj-text-sm); margin-top: 2px; }\n .mjc-ov-kpi[data-tone='warning'] .v { color: var(--mj-status-warning-text); }\n .mjc-ov-kpi[data-tone='success'] .v { color: var(--mj-status-success-text); }\n .mjc-ov-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--mj-space-3); }\n @media (max-width: 800px) { .mjc-ov-grid { grid-template-columns: 1fr; } }\n .mjc-ov-card {\n background: var(--mj-bg-page); border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md); padding: var(--mj-space-3) var(--mj-space-4);\n }\n .mjc-ov-card--wide { grid-column: 1 / -1; }\n .mjc-ov-card header {\n display: flex; align-items: center; gap: 8px;\n font-weight: 700; margin-bottom: var(--mj-space-3); color: var(--mj-text-primary);\n }\n .mjc-ov-card header i { color: var(--mj-brand-primary); width: 1.1rem; text-align: center; }\n .mjc-ov-facts { display: grid; grid-template-columns: 1fr 1fr; gap: var(--mj-space-3); }\n .mjc-ov-facts .l {\n font-size: var(--mj-text-xs); text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700;\n }\n .mjc-ov-facts .v { font-weight: 650; margin-top: 2px; }\n .mjc-ov-link {\n border: 0; padding: 0; background: transparent; color: var(--mj-text-link);\n cursor: pointer; font: inherit; font-weight: 650; text-align: left;\n }\n .mjc-ov-link:hover { text-decoration: underline; }\n .mjc-ov-next { margin: 0; font-size: 1.05rem; font-weight: 650; }\n .mjc-ov-empty { color: var(--mj-text-muted); margin: 0; }\n "], encapsulation: 2 });
554
+ };
555
+ MJCContractOverviewPanel = __decorate([
556
+ RegisterClassEx(BaseFormPanel, {
557
+ key: 'contracts:overview',
558
+ skipNullKeyWarning: true,
559
+ metadata: {
560
+ entity: E,
561
+ slot: 'after-fields',
562
+ sortKey: 200,
563
+ contributionKey: 'overview',
564
+ inclusion: 'Primary',
565
+ replacesSectionKey: 'contractDetails',
566
+ },
567
+ })
568
+ ], MJCContractOverviewPanel);
569
+ export { MJCContractOverviewPanel };
570
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJCContractOverviewPanel, [{
571
+ type: Component,
572
+ args: [{ selector: 'mjc-contract-overview-panel', standalone: true, encapsulation: ViewEncapsulation.None, imports: [CommonModule, BaseFormsModule], template: `
573
+ <mj-collapsible-panel
574
+ SectionKey="overview"
575
+ SectionName="Overview"
576
+ Icon="fa-solid fa-chart-pie"
577
+ [Form]="FormComponent"
578
+ [FormContext]="FormContext"
579
+ [DefaultExpanded]="true">
580
+ <div class="mjc-ov">
581
+ @if (Health.length) {
582
+ <div class="mjc-ov-health">
583
+ @for (h of Health; track h) {
584
+ <div class="mjc-ov-alert">
585
+ <i class="fa-solid fa-triangle-exclamation" aria-hidden="true"></i>
586
+ {{ h }}
587
+ </div>
588
+ }
589
+ </div>
590
+ } @else if (Record.IsSaved) {
591
+ <div class="mjc-ov-ok">
592
+ <i class="fa-solid fa-circle-check" aria-hidden="true"></i>
593
+ No issues.
594
+ </div>
595
+ }
596
+
597
+ <div class="mjc-ov-strip">
598
+ <div class="mjc-ov-kpi" [attr.data-tone]="StateTone">
599
+ <div class="l">State</div>
600
+ <div class="v">{{ State }}</div>
601
+ <div class="s">{{ TypeName || 'No type' }}</div>
602
+ </div>
603
+ <div class="mjc-ov-kpi" [attr.data-tone]="EndTone">
604
+ <div class="l">Term ends</div>
605
+ <div class="v">{{ EndClock }}</div>
606
+ <div class="s">{{ dateLabel(Record.EndDate) }}</div>
607
+ </div>
608
+ <div class="mjc-ov-kpi" [attr.data-tone]="NoticeTone">
609
+ <div class="l">Notice</div>
610
+ <div class="v">{{ NoticeClock }}</div>
611
+ <div class="s">{{ dateLabel(Record.RenewalNoticeDeadline) }}</div>
612
+ </div>
613
+ <div class="mjc-ov-kpi">
614
+ <div class="l">Auto-renew</div>
615
+ <div class="v">{{ Record.AutoRenew ? 'Yes' : 'No' }}</div>
616
+ </div>
617
+ </div>
618
+
619
+ <div class="mjc-ov-grid">
620
+ <article class="mjc-ov-card">
621
+ <header><i class="fa-solid fa-building"></i> Parties</header>
622
+ <div class="mjc-ov-facts">
623
+ <div>
624
+ <div class="l">Customer</div>
625
+ <div class="v">
626
+ @if (Record.CustomerOrganizationID && CustomerName) {
627
+ <button type="button" class="mjc-ov-link" (click)="OpenCustomer($event)">{{ CustomerName }}</button>
628
+ } @else { {{ CustomerName || '—' }} }
629
+ </div>
630
+ </div>
631
+ <div>
632
+ <div class="l">Contact</div>
633
+ <div class="v">
634
+ @if (Record.PrimaryContactPersonID && ContactName) {
635
+ <button type="button" class="mjc-ov-link" (click)="OpenContact($event)">{{ ContactName }}</button>
636
+ } @else { {{ ContactName || '—' }} }
637
+ </div>
638
+ </div>
639
+ <div><div class="l">Company</div><div class="v">{{ CompanyName || '—' }}</div></div>
640
+ <div><div class="l">Agreement</div><div class="v">{{ TemplateName || 'None' }}</div></div>
641
+ </div>
642
+ </article>
643
+ <article class="mjc-ov-card">
644
+ <header><i class="fa-solid fa-scale-balanced"></i> Obligation</header>
645
+ <div class="mjc-ov-facts">
646
+ <div><div class="l">Executed</div><div class="v">{{ dateLabel(Record.ExecutedDate) }}</div></div>
647
+ <div><div class="l">Effective</div><div class="v">{{ dateLabel(Record.EffectiveDate) }}</div></div>
648
+ <div><div class="l">Notice we owe</div><div class="v">{{ DaysLabel(Record.RenewalNoticeDays) }}</div></div>
649
+ <div><div class="l">Cancel window</div><div class="v">{{ DaysLabel(Record.CancellationWindowDays) }}</div></div>
650
+ <div><div class="l">Annual increase</div><div class="v">{{ IncreaseLabel }}</div></div>
651
+ @if (HasSource) {
652
+ <div><div class="l">Created from</div>
653
+ <div class="v">
654
+ @if (CanOpenSource) {
655
+ <button type="button" class="mjc-ov-link" (click)="OpenSource($event)">{{ SourceLabel }}</button>
656
+ } @else { {{ SourceLabel }} }
657
+ </div>
658
+ </div>
659
+ }
660
+ </div>
661
+ </article>
662
+ <article class="mjc-ov-card mjc-ov-card--wide">
663
+ <header><i class="fa-solid fa-person-walking"></i> Next step</header>
664
+ @if (NextMove) {
665
+ <p class="mjc-ov-next">{{ NextMove }}</p>
666
+ } @else {
667
+ <p class="mjc-ov-empty">No action needed.</p>
668
+ }
669
+ </article>
670
+ </div>
671
+ </div>
672
+ </mj-collapsible-panel>
673
+ `, styles: ["\n .mjc-ov { display: flex; flex-direction: column; gap: var(--mj-space-4); padding: var(--mj-space-3) var(--mj-space-4) var(--mj-space-5); }\n .mjc-ov-health { display: flex; flex-direction: column; gap: var(--mj-space-2); }\n .mjc-ov-alert {\n display: flex; align-items: center; gap: var(--mj-space-2);\n padding: var(--mj-space-2) var(--mj-space-3);\n background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text);\n border-radius: var(--mj-radius-md); font-size: var(--mj-text-sm); font-weight: 600;\n }\n .mjc-ov-ok {\n display: flex; align-items: center; gap: var(--mj-space-2);\n padding: var(--mj-space-2) var(--mj-space-3);\n background: var(--mj-status-success-bg); color: var(--mj-status-success-text);\n border-radius: var(--mj-radius-md); font-size: var(--mj-text-sm); font-weight: 600;\n }\n .mjc-ov-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--mj-space-3); }\n @media (max-width: 900px) { .mjc-ov-strip { grid-template-columns: 1fr 1fr; } }\n .mjc-ov-kpi {\n background: var(--mj-bg-page); border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md); padding: var(--mj-space-3) var(--mj-space-4);\n }\n .mjc-ov-kpi .l {\n font-size: var(--mj-text-xs); text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700;\n }\n .mjc-ov-kpi .v { font-size: 1.35rem; font-weight: 800; letter-spacing: -.02em; margin-top: 4px; line-height: 1.2; }\n .mjc-ov-kpi .s { color: var(--mj-text-muted); font-size: var(--mj-text-sm); margin-top: 2px; }\n .mjc-ov-kpi[data-tone='warning'] .v { color: var(--mj-status-warning-text); }\n .mjc-ov-kpi[data-tone='success'] .v { color: var(--mj-status-success-text); }\n .mjc-ov-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--mj-space-3); }\n @media (max-width: 800px) { .mjc-ov-grid { grid-template-columns: 1fr; } }\n .mjc-ov-card {\n background: var(--mj-bg-page); border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md); padding: var(--mj-space-3) var(--mj-space-4);\n }\n .mjc-ov-card--wide { grid-column: 1 / -1; }\n .mjc-ov-card header {\n display: flex; align-items: center; gap: 8px;\n font-weight: 700; margin-bottom: var(--mj-space-3); color: var(--mj-text-primary);\n }\n .mjc-ov-card header i { color: var(--mj-brand-primary); width: 1.1rem; text-align: center; }\n .mjc-ov-facts { display: grid; grid-template-columns: 1fr 1fr; gap: var(--mj-space-3); }\n .mjc-ov-facts .l {\n font-size: var(--mj-text-xs); text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700;\n }\n .mjc-ov-facts .v { font-weight: 650; margin-top: 2px; }\n .mjc-ov-link {\n border: 0; padding: 0; background: transparent; color: var(--mj-text-link);\n cursor: pointer; font: inherit; font-weight: 650; text-align: left;\n }\n .mjc-ov-link:hover { text-decoration: underline; }\n .mjc-ov-next { margin: 0; font-size: 1.05rem; font-weight: 650; }\n .mjc-ov-empty { color: var(--mj-text-muted); margin: 0; }\n "] }]
674
+ }], null, null); })();
675
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJCContractOverviewPanel, { className: "MJCContractOverviewPanel", filePath: "lib/form-panels/contract-form.panels.ts", lineNumber: 271 }); })();
676
+ function daysUntil(d) {
677
+ if (!d)
678
+ return null;
679
+ const iso = d instanceof Date
680
+ ? `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, '0')}-${String(d.getUTCDate()).padStart(2, '0')}`
681
+ : String(d).slice(0, 10);
682
+ const t = Date.parse(`${iso}T00:00:00Z`);
683
+ if (!Number.isFinite(t))
684
+ return null;
685
+ const now = new Date();
686
+ const today = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
687
+ return Math.round((t - today) / 86_400_000);
688
+ }
689
+ /* ── Field sections ───────────────────────────────────────────────────────── */
690
+ let MJCContractAgreementPanel = class MJCContractAgreementPanel extends BaseFormPanel {
691
+ Fields = [
692
+ { name: 'ContractNumber', type: 'textbox', readOnly: true },
693
+ { name: 'ContractTypeID', type: 'textbox', link: 'Record' },
694
+ { name: 'ContractTemplateID', type: 'textbox', link: 'Record' },
695
+ { name: 'SigningProviderURL', type: 'textbox', link: 'URL' },
696
+ { name: 'HasModifications', type: 'checkbox', readOnly: true },
697
+ { name: 'Description', type: 'textarea', span: true },
698
+ ];
699
+ static ɵfac = /*@__PURE__*/ (() => { let ɵMJCContractAgreementPanel_BaseFactory; return function MJCContractAgreementPanel_Factory(__ngFactoryType__) { return (ɵMJCContractAgreementPanel_BaseFactory || (ɵMJCContractAgreementPanel_BaseFactory = i0.ɵɵgetInheritedFactory(MJCContractAgreementPanel)))(__ngFactoryType__ || MJCContractAgreementPanel); }; })();
700
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJCContractAgreementPanel, selectors: [["mjc-contract-agreement-panel"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [["SectionKey", "agreement", "SectionName", "Agreement", "Icon", "fa-solid fa-file-contract", 3, "Form", "FormContext"], [1, "mjc-fields-grid"], [1, "mjc-fg", 3, "mjc-fg--span"], [1, "mjc-fg"], [3, "Navigate", "Record", "ShowLabel", "FieldName", "Type", "EditMode", "FormContext", "LinkType"]], template: function MJCContractAgreementPanel_Template(rf, ctx) { if (rf & 1) {
701
+ i0.ɵɵelementStart(0, "mj-collapsible-panel", 0)(1, "div", 1);
702
+ i0.ɵɵrepeaterCreate(2, MJCContractAgreementPanel_For_3_Template, 2, 9, "div", 2, _forTrack0);
703
+ i0.ɵɵelementEnd()();
704
+ } if (rf & 2) {
705
+ i0.ɵɵproperty("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
706
+ i0.ɵɵadvance(2);
707
+ i0.ɵɵrepeater(ctx.Fields);
708
+ } }, dependencies: [CommonModule, BaseFormsModule, i1.MjFormFieldComponent, i1.MjCollapsiblePanelComponent], styles: [_c0], encapsulation: 2 });
709
+ };
710
+ MJCContractAgreementPanel = __decorate([
711
+ RegisterClassEx(BaseFormPanel, {
712
+ key: 'contracts:agreement',
713
+ skipNullKeyWarning: true,
714
+ metadata: { entity: E, slot: 'after-fields', sortKey: 95, contributionKey: 'agreement' },
715
+ })
716
+ ], MJCContractAgreementPanel);
717
+ export { MJCContractAgreementPanel };
718
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJCContractAgreementPanel, [{
719
+ type: Component,
720
+ args: [{ selector: 'mjc-contract-agreement-panel', standalone: true, encapsulation: ViewEncapsulation.None, imports: [CommonModule, BaseFormsModule], template: `
721
+ <mj-collapsible-panel SectionKey="agreement" SectionName="Agreement" Icon="fa-solid fa-file-contract"
722
+ [Form]="FormComponent" [FormContext]="FormContext">
723
+ <div class="mjc-fields-grid">
724
+ @for (f of Fields; track f.name) {
725
+ <div class="mjc-fg" [class.mjc-fg--span]="f.span">
726
+ <mj-form-field [Record]="Record" [ShowLabel]="true" [FieldName]="f.name" [Type]="f.type"
727
+ [EditMode]="f.readOnly ? false : EditMode" [FormContext]="FormContext"
728
+ [LinkType]="f.link ?? 'None'"
729
+ (Navigate)="FormComponent.OnFormNavigate($event)"></mj-form-field>
730
+ </div>
731
+ }
732
+ </div>
733
+ </mj-collapsible-panel>
734
+ `, styles: ["\n .mjc-fields-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--mj-space-4) var(--mj-space-5);\n padding: var(--mj-space-4) var(--mj-space-5);\n }\n @media (max-width: 720px) { .mjc-fields-grid { grid-template-columns: 1fr; } }\n .mjc-fg { min-width: 0; }\n .mjc-fg--span { grid-column: 1 / -1; }\n .mjc-fg .mj-forms-field {\n display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding: 0;\n }\n .mjc-fg .mj-forms-field-label {\n font-size: var(--mj-text-xs); font-weight: 700; letter-spacing: .06em;\n text-transform: uppercase; color: var(--mj-text-muted);\n }\n .mjc-fg .mj-forms-field--editing:hover { margin: 0; padding: 0; }\n"] }]
735
+ }], null, null); })();
736
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJCContractAgreementPanel, { className: "MJCContractAgreementPanel", filePath: "lib/form-panels/contract-form.panels.ts", lineNumber: 441 }); })();
737
+ let MJCContractPartiesPanel = class MJCContractPartiesPanel extends BaseFormPanel {
738
+ /**
739
+ * Record links on these fields emit `Navigate` from `mj-form-field`. That output must be
740
+ * forwarded to `FormComponent.OnFormNavigate`, which Explorer maps onto
741
+ * `NavigationService.OpenEntityRecord`. Without the binding the cells look like links and
742
+ * do nothing — Overview's customer/contact buttons already go through this path.
743
+ */
744
+ Fields = [
745
+ { name: 'CustomerOrganizationID', type: 'textbox', link: 'Record' },
746
+ { name: 'PrimaryContactPersonID', type: 'textbox', link: 'Record' },
747
+ { name: 'CompanyID', type: 'textbox', link: 'Record' },
748
+ ];
749
+ static ɵfac = /*@__PURE__*/ (() => { let ɵMJCContractPartiesPanel_BaseFactory; return function MJCContractPartiesPanel_Factory(__ngFactoryType__) { return (ɵMJCContractPartiesPanel_BaseFactory || (ɵMJCContractPartiesPanel_BaseFactory = i0.ɵɵgetInheritedFactory(MJCContractPartiesPanel)))(__ngFactoryType__ || MJCContractPartiesPanel); }; })();
750
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJCContractPartiesPanel, selectors: [["mjc-contract-parties-panel"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [["SectionKey", "parties", "SectionName", "Parties", "Icon", "fa-solid fa-building", 3, "Form", "FormContext"], [1, "mjc-fields-grid"], [1, "mjc-fg", 3, "mjc-fg--span"], [1, "mjc-fg"], [3, "Navigate", "Record", "ShowLabel", "FieldName", "Type", "EditMode", "FormContext", "LinkType"]], template: function MJCContractPartiesPanel_Template(rf, ctx) { if (rf & 1) {
751
+ i0.ɵɵelementStart(0, "mj-collapsible-panel", 0)(1, "div", 1);
752
+ i0.ɵɵrepeaterCreate(2, MJCContractPartiesPanel_For_3_Template, 2, 9, "div", 2, _forTrack0);
753
+ i0.ɵɵelementEnd()();
754
+ } if (rf & 2) {
755
+ i0.ɵɵproperty("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
756
+ i0.ɵɵadvance(2);
757
+ i0.ɵɵrepeater(ctx.Fields);
758
+ } }, dependencies: [CommonModule, BaseFormsModule, i1.MjFormFieldComponent, i1.MjCollapsiblePanelComponent], styles: [_c0], encapsulation: 2 });
759
+ };
760
+ MJCContractPartiesPanel = __decorate([
761
+ RegisterClassEx(BaseFormPanel, {
762
+ key: 'contracts:parties',
763
+ skipNullKeyWarning: true,
764
+ metadata: {
765
+ entity: E, slot: 'after-fields', sortKey: 92, contributionKey: 'parties',
766
+ replacesSectionKey: 'stakeholders',
767
+ },
768
+ })
769
+ ], MJCContractPartiesPanel);
770
+ export { MJCContractPartiesPanel };
771
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJCContractPartiesPanel, [{
772
+ type: Component,
773
+ args: [{ selector: 'mjc-contract-parties-panel', standalone: true, encapsulation: ViewEncapsulation.None, imports: [CommonModule, BaseFormsModule], template: `
774
+ <mj-collapsible-panel SectionKey="parties" SectionName="Parties" Icon="fa-solid fa-building"
775
+ [Form]="FormComponent" [FormContext]="FormContext">
776
+ <div class="mjc-fields-grid">
777
+ @for (f of Fields; track f.name) {
778
+ <div class="mjc-fg" [class.mjc-fg--span]="f.span">
779
+ <mj-form-field [Record]="Record" [ShowLabel]="true" [FieldName]="f.name" [Type]="f.type"
780
+ [EditMode]="f.readOnly ? false : EditMode" [FormContext]="FormContext"
781
+ [LinkType]="f.link ?? 'None'"
782
+ (Navigate)="FormComponent.OnFormNavigate($event)"></mj-form-field>
783
+ </div>
784
+ }
785
+ </div>
786
+ </mj-collapsible-panel>
787
+ `, styles: ["\n .mjc-fields-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--mj-space-4) var(--mj-space-5);\n padding: var(--mj-space-4) var(--mj-space-5);\n }\n @media (max-width: 720px) { .mjc-fields-grid { grid-template-columns: 1fr; } }\n .mjc-fg { min-width: 0; }\n .mjc-fg--span { grid-column: 1 / -1; }\n .mjc-fg .mj-forms-field {\n display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding: 0;\n }\n .mjc-fg .mj-forms-field-label {\n font-size: var(--mj-text-xs); font-weight: 700; letter-spacing: .06em;\n text-transform: uppercase; color: var(--mj-text-muted);\n }\n .mjc-fg .mj-forms-field--editing:hover { margin: 0; padding: 0; }\n"] }]
788
+ }], null, null); })();
789
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJCContractPartiesPanel, { className: "MJCContractPartiesPanel", filePath: "lib/form-panels/contract-form.panels.ts", lineNumber: 482 }); })();
790
+ let MJCContractNotesPanel = class MJCContractNotesPanel extends BaseFormPanel {
791
+ Fields = [
792
+ { name: 'Notes', type: 'textarea', span: true },
793
+ ];
794
+ static ɵfac = /*@__PURE__*/ (() => { let ɵMJCContractNotesPanel_BaseFactory; return function MJCContractNotesPanel_Factory(__ngFactoryType__) { return (ɵMJCContractNotesPanel_BaseFactory || (ɵMJCContractNotesPanel_BaseFactory = i0.ɵɵgetInheritedFactory(MJCContractNotesPanel)))(__ngFactoryType__ || MJCContractNotesPanel); }; })();
795
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJCContractNotesPanel, selectors: [["mjc-contract-notes-panel"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [["SectionKey", "notes", "SectionName", "Notes", "Icon", "fa-solid fa-align-left", 3, "Form", "FormContext"], [1, "mjc-fields-grid"], [1, "mjc-fg", 3, "mjc-fg--span"], [1, "mjc-fg"], [3, "Navigate", "Record", "ShowLabel", "FieldName", "Type", "EditMode", "FormContext", "LinkType"]], template: function MJCContractNotesPanel_Template(rf, ctx) { if (rf & 1) {
796
+ i0.ɵɵelementStart(0, "mj-collapsible-panel", 0)(1, "div", 1);
797
+ i0.ɵɵrepeaterCreate(2, MJCContractNotesPanel_For_3_Template, 2, 9, "div", 2, _forTrack0);
798
+ i0.ɵɵelementEnd()();
799
+ } if (rf & 2) {
800
+ i0.ɵɵproperty("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
801
+ i0.ɵɵadvance(2);
802
+ i0.ɵɵrepeater(ctx.Fields);
803
+ } }, dependencies: [CommonModule, BaseFormsModule, i1.MjFormFieldComponent, i1.MjCollapsiblePanelComponent], styles: [_c0], encapsulation: 2 });
804
+ };
805
+ MJCContractNotesPanel = __decorate([
806
+ RegisterClassEx(BaseFormPanel, {
807
+ key: 'contracts:notes',
808
+ skipNullKeyWarning: true,
809
+ metadata: {
810
+ entity: E, slot: 'after-fields', sortKey: 80, contributionKey: 'notes',
811
+ replacesSectionKey: 'notesAndMetadata',
812
+ },
813
+ })
814
+ ], MJCContractNotesPanel);
815
+ export { MJCContractNotesPanel };
816
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJCContractNotesPanel, [{
817
+ type: Component,
818
+ args: [{ selector: 'mjc-contract-notes-panel', standalone: true, encapsulation: ViewEncapsulation.None, imports: [CommonModule, BaseFormsModule], template: `
819
+ <mj-collapsible-panel SectionKey="notes" SectionName="Notes" Icon="fa-solid fa-align-left"
820
+ [Form]="FormComponent" [FormContext]="FormContext">
821
+ <div class="mjc-fields-grid">
822
+ @for (f of Fields; track f.name) {
823
+ <div class="mjc-fg" [class.mjc-fg--span]="f.span">
824
+ <mj-form-field [Record]="Record" [ShowLabel]="true" [FieldName]="f.name" [Type]="f.type"
825
+ [EditMode]="f.readOnly ? false : EditMode" [FormContext]="FormContext"
826
+ [LinkType]="f.link ?? 'None'"
827
+ (Navigate)="FormComponent.OnFormNavigate($event)"></mj-form-field>
828
+ </div>
829
+ }
830
+ </div>
831
+ </mj-collapsible-panel>
832
+ `, styles: ["\n .mjc-fields-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--mj-space-4) var(--mj-space-5);\n padding: var(--mj-space-4) var(--mj-space-5);\n }\n @media (max-width: 720px) { .mjc-fields-grid { grid-template-columns: 1fr; } }\n .mjc-fg { min-width: 0; }\n .mjc-fg--span { grid-column: 1 / -1; }\n .mjc-fg .mj-forms-field {\n display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding: 0;\n }\n .mjc-fg .mj-forms-field-label {\n font-size: var(--mj-text-xs); font-weight: 700; letter-spacing: .06em;\n text-transform: uppercase; color: var(--mj-text-muted);\n }\n .mjc-fg .mj-forms-field--editing:hover { margin: 0; padding: 0; }\n"] }]
833
+ }], null, null); })();
834
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJCContractNotesPanel, { className: "MJCContractNotesPanel", filePath: "lib/form-panels/contract-form.panels.ts", lineNumber: 526 }); })();
835
+ let MJCContractProvenanceFieldsPanel = class MJCContractProvenanceFieldsPanel extends BaseFormPanel {
836
+ /**
837
+ * READ-ONLY, and the section KEPT — a deliberate departure from issue #28 item 18.
838
+ *
839
+ * Item 18 says to hide this section entirely, on the stated grounds that the hero's Source Deal
840
+ * link (item 1) replaces it. That premise does not hold yet. Item 1 renders the stat ONLY when
841
+ * `CreatingEntityID` and `CreatingRecordID` are both set, and on this database exactly one contract
842
+ * of eleven has them — `CTR-000026`, whose pair was typed in by hand: the entity is
843
+ * `MJ: Explorer Navigation Items` rather than Deals and the record id is not a valid UUID. So on
844
+ * every contract a person can currently open, the replacement is invisible. Hiding this section
845
+ * today would remove the only visible provenance for a stat that does not appear.
846
+ *
847
+ * WHAT ITEM 18 IS ACTUALLY ABOUT, and this half is not in doubt: these two fields rendered as
848
+ * ordinary inputs a person could type into, which is how that junk pair got there.
849
+ * `CreatingEntityID` is a real FK to `__mj.Entity` and `CreatingRecordID` is the row it names, and
850
+ * `CK_Contract_CreatingPairBothOrNeither` requires both or neither — so editing one field alone
851
+ * produces a save the constraint refuses, and editing both silently re-points a contract's
852
+ * provenance at an unrelated record, which is then what the hero's link displays. The server sets
853
+ * this pair (`LiveContractsSeam.setProvenance`, on Close-Won) and nothing else should.
854
+ *
855
+ * Read-only closes that defect and keeps the ids visible beneath the hero's human-readable name —
856
+ * complements rather than duplicates. Revisit hiding the section once a contract created by a real
857
+ * Close-Won deal exists to verify item 1 against.
858
+ */
859
+ Fields = [
860
+ { name: 'CreatingEntityID', type: 'textbox', link: 'Record', readOnly: true },
861
+ { name: 'CreatingRecordID', type: 'textbox', readOnly: true },
862
+ ];
863
+ static ɵfac = /*@__PURE__*/ (() => { let ɵMJCContractProvenanceFieldsPanel_BaseFactory; return function MJCContractProvenanceFieldsPanel_Factory(__ngFactoryType__) { return (ɵMJCContractProvenanceFieldsPanel_BaseFactory || (ɵMJCContractProvenanceFieldsPanel_BaseFactory = i0.ɵɵgetInheritedFactory(MJCContractProvenanceFieldsPanel)))(__ngFactoryType__ || MJCContractProvenanceFieldsPanel); }; })();
864
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJCContractProvenanceFieldsPanel, selectors: [["mjc-contract-provenance-panel"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [["SectionKey", "origin", "SectionName", "Provenance", "Icon", "fa-solid fa-diagram-project", 3, "Form", "FormContext"], [1, "mjc-fields-grid"], [1, "mjc-fg", 3, "mjc-fg--span"], [1, "mjc-fg"], [3, "Navigate", "Record", "ShowLabel", "FieldName", "Type", "EditMode", "FormContext", "LinkType"]], template: function MJCContractProvenanceFieldsPanel_Template(rf, ctx) { if (rf & 1) {
865
+ i0.ɵɵelementStart(0, "mj-collapsible-panel", 0)(1, "div", 1);
866
+ i0.ɵɵrepeaterCreate(2, MJCContractProvenanceFieldsPanel_For_3_Template, 2, 9, "div", 2, _forTrack0);
867
+ i0.ɵɵelementEnd()();
868
+ } if (rf & 2) {
869
+ i0.ɵɵproperty("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
870
+ i0.ɵɵadvance(2);
871
+ i0.ɵɵrepeater(ctx.Fields);
872
+ } }, dependencies: [CommonModule, BaseFormsModule, i1.MjFormFieldComponent, i1.MjCollapsiblePanelComponent], styles: [_c0], encapsulation: 2 });
873
+ };
874
+ MJCContractProvenanceFieldsPanel = __decorate([
875
+ RegisterClassEx(BaseFormPanel, {
876
+ key: 'contracts:provenance',
877
+ skipNullKeyWarning: true,
878
+ metadata: {
879
+ entity: E, slot: 'after-fields', sortKey: 35, contributionKey: 'origin',
880
+ replacesSectionKey: 'provenance',
881
+ },
882
+ })
883
+ ], MJCContractProvenanceFieldsPanel);
884
+ export { MJCContractProvenanceFieldsPanel };
885
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJCContractProvenanceFieldsPanel, [{
886
+ type: Component,
887
+ args: [{ selector: 'mjc-contract-provenance-panel', standalone: true, encapsulation: ViewEncapsulation.None, imports: [CommonModule, BaseFormsModule], template: `
888
+ <mj-collapsible-panel SectionKey="origin" SectionName="Provenance" Icon="fa-solid fa-diagram-project"
889
+ [Form]="FormComponent" [FormContext]="FormContext">
890
+ <div class="mjc-fields-grid">
891
+ @for (f of Fields; track f.name) {
892
+ <div class="mjc-fg" [class.mjc-fg--span]="f.span">
893
+ <mj-form-field [Record]="Record" [ShowLabel]="true" [FieldName]="f.name" [Type]="f.type"
894
+ [EditMode]="f.readOnly ? false : EditMode" [FormContext]="FormContext"
895
+ [LinkType]="f.link ?? 'None'"
896
+ (Navigate)="FormComponent.OnFormNavigate($event)"></mj-form-field>
897
+ </div>
898
+ }
899
+ </div>
900
+ </mj-collapsible-panel>
901
+ `, styles: ["\n .mjc-fields-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--mj-space-4) var(--mj-space-5);\n padding: var(--mj-space-4) var(--mj-space-5);\n }\n @media (max-width: 720px) { .mjc-fields-grid { grid-template-columns: 1fr; } }\n .mjc-fg { min-width: 0; }\n .mjc-fg--span { grid-column: 1 / -1; }\n .mjc-fg .mj-forms-field {\n display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding: 0;\n }\n .mjc-fg .mj-forms-field-label {\n font-size: var(--mj-text-xs); font-weight: 700; letter-spacing: .06em;\n text-transform: uppercase; color: var(--mj-text-muted);\n }\n .mjc-fg .mj-forms-field--editing:hover { margin: 0; padding: 0; }\n"] }]
902
+ }], null, null); })();
903
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJCContractProvenanceFieldsPanel, { className: "MJCContractProvenanceFieldsPanel", filePath: "lib/form-panels/contract-form.panels.ts", lineNumber: 562 }); })();
904
+ let MJCContractLifecyclePanel = class MJCContractLifecyclePanel extends BaseFormPanel {
905
+ Fields = [
906
+ { name: 'ParentContractID', type: 'textbox', link: 'Record' },
907
+ { name: 'SupersededByContractID', type: 'textbox', link: 'Record', readOnly: true },
908
+ ];
909
+ static ɵfac = /*@__PURE__*/ (() => { let ɵMJCContractLifecyclePanel_BaseFactory; return function MJCContractLifecyclePanel_Factory(__ngFactoryType__) { return (ɵMJCContractLifecyclePanel_BaseFactory || (ɵMJCContractLifecyclePanel_BaseFactory = i0.ɵɵgetInheritedFactory(MJCContractLifecyclePanel)))(__ngFactoryType__ || MJCContractLifecyclePanel); }; })();
910
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJCContractLifecyclePanel, selectors: [["mjc-contract-lifecycle-panel"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [["SectionKey", "lifecycle", "SectionName", "Change orders", "Icon", "fa-solid fa-code-branch", 3, "Form", "FormContext"], [1, "mjc-fields-grid"], [1, "mjc-fg", 3, "mjc-fg--span"], [1, "mjc-fg"], [3, "Navigate", "Record", "ShowLabel", "FieldName", "Type", "EditMode", "FormContext", "LinkType"]], template: function MJCContractLifecyclePanel_Template(rf, ctx) { if (rf & 1) {
911
+ i0.ɵɵelementStart(0, "mj-collapsible-panel", 0)(1, "div", 1);
912
+ i0.ɵɵrepeaterCreate(2, MJCContractLifecyclePanel_For_3_Template, 2, 9, "div", 2, _forTrack0);
913
+ i0.ɵɵelementEnd()();
914
+ } if (rf & 2) {
915
+ i0.ɵɵproperty("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
916
+ i0.ɵɵadvance(2);
917
+ i0.ɵɵrepeater(ctx.Fields);
918
+ } }, dependencies: [CommonModule, BaseFormsModule, i1.MjFormFieldComponent, i1.MjCollapsiblePanelComponent], styles: [_c0], encapsulation: 2 });
919
+ };
920
+ MJCContractLifecyclePanel = __decorate([
921
+ RegisterClassEx(BaseFormPanel, {
922
+ key: 'contracts:lifecycle-fields',
923
+ skipNullKeyWarning: true,
924
+ metadata: {
925
+ entity: E, slot: 'after-fields', sortKey: 50, contributionKey: 'lifecycle',
926
+ replacesSectionKey: 'contractLifecycle',
927
+ },
928
+ })
929
+ ], MJCContractLifecyclePanel);
930
+ export { MJCContractLifecyclePanel };
931
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJCContractLifecyclePanel, [{
932
+ type: Component,
933
+ args: [{ selector: 'mjc-contract-lifecycle-panel', standalone: true, encapsulation: ViewEncapsulation.None, imports: [CommonModule, BaseFormsModule], template: `
934
+ <mj-collapsible-panel SectionKey="lifecycle" SectionName="Change orders" Icon="fa-solid fa-code-branch"
935
+ [Form]="FormComponent" [FormContext]="FormContext">
936
+ <div class="mjc-fields-grid">
937
+ @for (f of Fields; track f.name) {
938
+ <div class="mjc-fg" [class.mjc-fg--span]="f.span">
939
+ <mj-form-field [Record]="Record" [ShowLabel]="true" [FieldName]="f.name" [Type]="f.type"
940
+ [EditMode]="f.readOnly ? false : EditMode" [FormContext]="FormContext"
941
+ [LinkType]="f.link ?? 'None'"
942
+ (Navigate)="FormComponent.OnFormNavigate($event)"></mj-form-field>
943
+ </div>
944
+ }
945
+ </div>
946
+ </mj-collapsible-panel>
947
+ `, styles: ["\n .mjc-fields-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--mj-space-4) var(--mj-space-5);\n padding: var(--mj-space-4) var(--mj-space-5);\n }\n @media (max-width: 720px) { .mjc-fields-grid { grid-template-columns: 1fr; } }\n .mjc-fg { min-width: 0; }\n .mjc-fg--span { grid-column: 1 / -1; }\n .mjc-fg .mj-forms-field {\n display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding: 0;\n }\n .mjc-fg .mj-forms-field-label {\n font-size: var(--mj-text-xs); font-weight: 700; letter-spacing: .06em;\n text-transform: uppercase; color: var(--mj-text-muted);\n }\n .mjc-fg .mj-forms-field--editing:hover { margin: 0; padding: 0; }\n"] }]
948
+ }], null, null); })();
949
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJCContractLifecyclePanel, { className: "MJCContractLifecyclePanel", filePath: "lib/form-panels/contract-form.panels.ts", lineNumber: 622 }); })();
950
+ let MJCContractModificationsPanel = class MJCContractModificationsPanel extends BaseFormPanel {
951
+ Entity = MJC_ENTITIES.ContractTemplateModification;
952
+ OnDataLoad(event) {
953
+ this.FormComponent.SetSectionRowCount('modifications', event.totalRowCount);
954
+ }
955
+ static ɵfac = /*@__PURE__*/ (() => { let ɵMJCContractModificationsPanel_BaseFactory; return function MJCContractModificationsPanel_Factory(__ngFactoryType__) { return (ɵMJCContractModificationsPanel_BaseFactory || (ɵMJCContractModificationsPanel_BaseFactory = i0.ɵɵgetInheritedFactory(MJCContractModificationsPanel)))(__ngFactoryType__ || MJCContractModificationsPanel); }; })();
956
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJCContractModificationsPanel, selectors: [["mjc-contract-modifications-panel"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 5, consts: [["SectionKey", "modifications", "SectionName", "Modifications", "Icon", "fa-solid fa-file-circle-exclamation", "Variant", "related-entity", 3, "Form", "FormContext", "DefaultExpanded", "BadgeCount"], [3, "Params", "NewRecordValues", "AllowLoad", "ShowToolbar"], [3, "Navigate", "AfterDataLoad", "Params", "NewRecordValues", "AllowLoad", "ShowToolbar"]], template: function MJCContractModificationsPanel_Template(rf, ctx) { if (rf & 1) {
957
+ i0.ɵɵelementStart(0, "mj-collapsible-panel", 0);
958
+ i0.ɵɵconditionalCreate(1, MJCContractModificationsPanel_Conditional_1_Template, 1, 4, "mj-explorer-entity-data-grid", 1);
959
+ i0.ɵɵelementEnd();
960
+ } if (rf & 2) {
961
+ i0.ɵɵproperty("Form", ctx.FormComponent)("FormContext", ctx.FormContext)("DefaultExpanded", false)("BadgeCount", ctx.FormComponent.GetSectionRowCount("modifications"));
962
+ i0.ɵɵadvance();
963
+ i0.ɵɵconditional(ctx.Record.IsSaved ? 1 : -1);
964
+ } }, dependencies: [CommonModule, BaseFormsModule, i1.MjCollapsiblePanelComponent, i1.ExplorerEntityDataGridComponent], encapsulation: 2 });
965
+ };
966
+ MJCContractModificationsPanel = __decorate([
967
+ RegisterClassEx(BaseFormPanel, {
968
+ key: 'contracts:related-modifications',
969
+ skipNullKeyWarning: true,
970
+ metadata: {
971
+ entity: E, slot: 'after-related', sortKey: 70, contributionKey: 'modifications',
972
+ relatedEntity: MJC_ENTITIES.ContractTemplateModification, relatedJoinField: 'ContractID',
973
+ },
974
+ })
975
+ ], MJCContractModificationsPanel);
976
+ export { MJCContractModificationsPanel };
977
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJCContractModificationsPanel, [{
978
+ type: Component,
979
+ args: [{
980
+ selector: 'mjc-contract-modifications-panel',
981
+ standalone: true,
982
+ imports: [CommonModule, BaseFormsModule],
983
+ template: `
984
+ <mj-collapsible-panel SectionKey="modifications" SectionName="Modifications" Icon="fa-solid fa-file-circle-exclamation"
985
+ Variant="related-entity" [Form]="FormComponent" [FormContext]="FormContext" [DefaultExpanded]="false"
986
+ [BadgeCount]="FormComponent.GetSectionRowCount('modifications')">
987
+ @if (Record.IsSaved) {
988
+ <mj-explorer-entity-data-grid
989
+ [Params]="FormComponent.BuildRelationshipViewParamsByEntityName(Entity, 'ContractID')"
990
+ [NewRecordValues]="FormComponent.NewRecordValues(Entity, 'ContractID')"
991
+ [AllowLoad]="FormComponent.IsSectionExpanded('modifications')"
992
+ [ShowToolbar]="true"
993
+ (Navigate)="FormComponent.OnFormNavigate($event)"
994
+ (AfterDataLoad)="OnDataLoad($event)">
995
+ </mj-explorer-entity-data-grid>
996
+ }
997
+ </mj-collapsible-panel>
998
+ `,
999
+ }]
1000
+ }], null, null); })();
1001
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJCContractModificationsPanel, { className: "MJCContractModificationsPanel", filePath: "lib/form-panels/contract-form.panels.ts", lineNumber: 658 }); })();
1002
+ //# sourceMappingURL=contract-form.panels.js.map