@mj-biz-apps/contracts-ng 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +183 -0
- package/dist/lib/data/entity-names.d.ts +29 -0
- package/dist/lib/data/entity-names.d.ts.map +1 -0
- package/dist/lib/data/entity-names.js +29 -0
- package/dist/lib/data/entity-names.js.map +1 -0
- package/dist/lib/data/provider.d.ts +44 -0
- package/dist/lib/data/provider.d.ts.map +1 -0
- package/dist/lib/data/provider.js +48 -0
- package/dist/lib/data/provider.js.map +1 -0
- package/dist/lib/directives/fk-navigate.directive.d.ts +63 -0
- package/dist/lib/directives/fk-navigate.directive.d.ts.map +1 -0
- package/dist/lib/directives/fk-navigate.directive.js +99 -0
- package/dist/lib/directives/fk-navigate.directive.js.map +1 -0
- package/dist/lib/form-panels/contract.panels.d.ts +124 -0
- package/dist/lib/form-panels/contract.panels.d.ts.map +1 -0
- package/dist/lib/form-panels/contract.panels.js +1167 -0
- package/dist/lib/form-panels/contract.panels.js.map +1 -0
- package/dist/lib/form-panels/organization.panels.d.ts +23 -0
- package/dist/lib/form-panels/organization.panels.d.ts.map +1 -0
- package/dist/lib/form-panels/organization.panels.js +118 -0
- package/dist/lib/form-panels/organization.panels.js.map +1 -0
- package/dist/lib/form-panels/record-files.panel.d.ts +151 -0
- package/dist/lib/form-panels/record-files.panel.d.ts.map +1 -0
- package/dist/lib/form-panels/record-files.panel.js +1046 -0
- package/dist/lib/form-panels/record-files.panel.js.map +1 -0
- package/dist/lib/form-panels/supersede.panel.d.ts +68 -0
- package/dist/lib/form-panels/supersede.panel.d.ts.map +1 -0
- package/dist/lib/form-panels/supersede.panel.js +415 -0
- package/dist/lib/form-panels/supersede.panel.js.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContract/mjbizappscontractscontract.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContract/mjbizappscontractscontract.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContract/mjbizappscontractscontract.form.component.js +196 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContract/mjbizappscontractscontract.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplate/mjbizappscontractscontracttemplate.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplate/mjbizappscontractscontracttemplate.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplate/mjbizappscontractscontracttemplate.form.component.js +120 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplate/mjbizappscontractscontracttemplate.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateModification/mjbizappscontractscontracttemplatemodification.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateModification/mjbizappscontractscontracttemplatemodification.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateModification/mjbizappscontractscontracttemplatemodification.form.component.js +79 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateModification/mjbizappscontractscontracttemplatemodification.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateProvision/mjbizappscontractscontracttemplateprovision.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateProvision/mjbizappscontractscontracttemplateprovision.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateProvision/mjbizappscontractscontracttemplateprovision.form.component.js +79 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateProvision/mjbizappscontractscontracttemplateprovision.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateType/mjbizappscontractscontracttemplatetype.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateType/mjbizappscontractscontracttemplatetype.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateType/mjbizappscontractscontracttemplatetype.form.component.js +86 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractTemplateType/mjbizappscontractscontracttemplatetype.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractType/mjbizappscontractscontracttype.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractType/mjbizappscontractscontracttype.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractType/mjbizappscontractscontracttype.form.component.js +100 -0
- package/dist/lib/generated/Entities/mjBizAppsContractsContractType/mjbizappscontractscontracttype.form.component.js.map +1 -0
- package/dist/lib/generated/generated-forms.module.d.ts +23 -0
- package/dist/lib/generated/generated-forms.module.d.ts.map +1 -0
- package/dist/lib/generated/generated-forms.module.js +78 -0
- package/dist/lib/generated/generated-forms.module.js.map +1 -0
- package/dist/lib/pages/configuration.page.d.ts +83 -0
- package/dist/lib/pages/configuration.page.d.ts.map +1 -0
- package/dist/lib/pages/configuration.page.js +240 -0
- package/dist/lib/pages/configuration.page.js.map +1 -0
- package/dist/lib/pages/contract-grid.page.d.ts +169 -0
- package/dist/lib/pages/contract-grid.page.d.ts.map +1 -0
- package/dist/lib/pages/contract-grid.page.js +487 -0
- package/dist/lib/pages/contract-grid.page.js.map +1 -0
- package/dist/lib/pages/contracts-dashboard.page.d.ts +56 -0
- package/dist/lib/pages/contracts-dashboard.page.d.ts.map +1 -0
- package/dist/lib/pages/contracts-dashboard.page.js +215 -0
- package/dist/lib/pages/contracts-dashboard.page.js.map +1 -0
- package/dist/lib/pages/modifications.page.d.ts +96 -0
- package/dist/lib/pages/modifications.page.d.ts.map +1 -0
- package/dist/lib/pages/modifications.page.js +243 -0
- package/dist/lib/pages/modifications.page.js.map +1 -0
- package/dist/lib/pages/templates.page.d.ts +120 -0
- package/dist/lib/pages/templates.page.d.ts.map +1 -0
- package/dist/lib/pages/templates.page.js +258 -0
- package/dist/lib/pages/templates.page.js.map +1 -0
- package/dist/lib/sections/contracts-sections.component.d.ts +112 -0
- package/dist/lib/sections/contracts-sections.component.d.ts.map +1 -0
- package/dist/lib/sections/contracts-sections.component.js +412 -0
- package/dist/lib/sections/contracts-sections.component.js.map +1 -0
- package/dist/lib/sections/section-nav.model.d.ts +78 -0
- package/dist/lib/sections/section-nav.model.d.ts.map +1 -0
- package/dist/lib/sections/section-nav.model.js +110 -0
- package/dist/lib/sections/section-nav.model.js.map +1 -0
- package/dist/lib/sections/section-shell.component.d.ts +73 -0
- package/dist/lib/sections/section-shell.component.d.ts.map +1 -0
- package/dist/lib/sections/section-shell.component.js +170 -0
- package/dist/lib/sections/section-shell.component.js.map +1 -0
- package/dist/public-api.d.ts +44 -0
- package/dist/public-api.d.ts.map +1 -0
- package/dist/public-api.js +105 -0
- package/dist/public-api.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,1167 @@
|
|
|
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 The Contract form's panels — built to `mockups-v2/contract-form.html`.
|
|
9
|
+
*
|
|
10
|
+
* v1 replaced the generated Contract form outright. v2 does not: every panel here is a `BaseFormPanel`
|
|
11
|
+
* contribution, so CodeGen can regenerate the form freely and these keep working.
|
|
12
|
+
*
|
|
13
|
+
* THREE THINGS AN EARLIER VERSION OF THIS FILE GOT WRONG, all visible on screen and none in the source:
|
|
14
|
+
*
|
|
15
|
+
* 1. **The panels were not `<mj-collapsible-panel>`s.** They were hand-rolled `<div class="card">`s, so
|
|
16
|
+
* they had none of MJ's panel chrome — hence text with no card behind it, cards touching each other,
|
|
17
|
+
* and content overflowing. The one panel that looked right (Documents) was the one panel built on
|
|
18
|
+
* the real component.
|
|
19
|
+
* 2a. **`contributionKey` MUST EQUAL the panel's own `SectionKey`, and must DIFFER from
|
|
20
|
+
* `replacesSectionKey`.** This is the rule that took longest to find, because breaking it fails
|
|
21
|
+
* two different ways. The container resolves contribution chrome by `contributionKey`
|
|
22
|
+
* (`contributionRailKey`) but builds the rail's groups from the rendered panels' `SectionKey`
|
|
23
|
+
* (`BuildDefaultChromeSpec` over `visiblePanels`) — so if they differ, the `Primary` inclusion is
|
|
24
|
+
* computed and then never attaches to any rendered panel, and the panel folds into Details.
|
|
25
|
+
* And if the panel's own `SectionKey` equals its `replacesSectionKey`, the replacement adds that
|
|
26
|
+
* key to `HiddenSectionKeys`, which filters out the panel ITSELF — the section disappeared from
|
|
27
|
+
* the form entirely, taking the dates and renewal fields with it. Both were live here at once.
|
|
28
|
+
*
|
|
29
|
+
* 2. **No `inclusion: 'Primary'`.** Under `Layout: 'left-nav'` the forms guide is explicit: *"Field
|
|
30
|
+
* panels collapse into one **Details** item"*, and named rail entries come from Primary
|
|
31
|
+
* contributions. Without it, every panel folded into `Details` and the form had exactly one section
|
|
32
|
+
* — the "everything in one page" problem.
|
|
33
|
+
* 3. **The hero was one line.** The mockup's hero is identity + chips + a meta row + a five-stat strip,
|
|
34
|
+
* and the stats are the part a reader actually scans.
|
|
35
|
+
*
|
|
36
|
+
* The hero lives in `before-fields` with NO `replacesSectionKey`: the mockup keeps the generated fields
|
|
37
|
+
* as their own Overview section, and content in `before-fields` stays put across rail sections, which is
|
|
38
|
+
* what makes the hero persistent chrome rather than a section.
|
|
39
|
+
*
|
|
40
|
+
* @module @mj-biz-apps/contracts-ng
|
|
41
|
+
*/
|
|
42
|
+
import { ChangeDetectorRef, Component, ViewEncapsulation, inject } from '@angular/core';
|
|
43
|
+
import { CommonModule } from '@angular/common';
|
|
44
|
+
import { FormsModule } from '@angular/forms';
|
|
45
|
+
import { RegisterClassEx } from '@memberjunction/global';
|
|
46
|
+
import { BaseFormPanel, BaseFormsModule } from '@memberjunction/ng-base-forms';
|
|
47
|
+
import { HierarchyTreeComponent } from '@memberjunction/ng-hierarchy-tree';
|
|
48
|
+
import { NavigationService } from '@memberjunction/ng-shared';
|
|
49
|
+
import { MJC_ENTITIES } from '../data/entity-names';
|
|
50
|
+
import * as i0 from "@angular/core";
|
|
51
|
+
import * as i1 from "@angular/common";
|
|
52
|
+
import * as i2 from "@angular/forms";
|
|
53
|
+
import * as i3 from "@memberjunction/ng-base-forms";
|
|
54
|
+
function MJCContractHeroPanel_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
55
|
+
i0.ɵɵdomElementStart(0, "span", 8);
|
|
56
|
+
i0.ɵɵtext(1);
|
|
57
|
+
i0.ɵɵdomElementEnd();
|
|
58
|
+
} if (rf & 2) {
|
|
59
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
60
|
+
i0.ɵɵadvance();
|
|
61
|
+
i0.ɵɵtextInterpolate(ctx_r0.TypeName);
|
|
62
|
+
} }
|
|
63
|
+
function MJCContractHeroPanel_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
64
|
+
i0.ɵɵdomElementStart(0, "span", 9);
|
|
65
|
+
i0.ɵɵdomElement(1, "i", 19);
|
|
66
|
+
i0.ɵɵtext(2, " Agreement modified ");
|
|
67
|
+
i0.ɵɵdomElementEnd();
|
|
68
|
+
} }
|
|
69
|
+
function MJCContractHeroPanel_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
70
|
+
i0.ɵɵdomElementStart(0, "span", 10);
|
|
71
|
+
i0.ɵɵdomElement(1, "i", 20);
|
|
72
|
+
i0.ɵɵtext(2, " Awaiting document ");
|
|
73
|
+
i0.ɵɵdomElementEnd();
|
|
74
|
+
} }
|
|
75
|
+
function MJCContractHeroPanel_Conditional_24_Template(rf, ctx) { if (rf & 1) {
|
|
76
|
+
i0.ɵɵdomElementStart(0, "span");
|
|
77
|
+
i0.ɵɵtext(1, "Contact: ");
|
|
78
|
+
i0.ɵɵdomElementStart(2, "strong");
|
|
79
|
+
i0.ɵɵtext(3);
|
|
80
|
+
i0.ɵɵdomElementEnd()();
|
|
81
|
+
} if (rf & 2) {
|
|
82
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
83
|
+
i0.ɵɵadvance(3);
|
|
84
|
+
i0.ɵɵtextInterpolate(ctx_r0.ContactName);
|
|
85
|
+
} }
|
|
86
|
+
function MJCContractHeroPanel_Conditional_32_Template(rf, ctx) { if (rf & 1) {
|
|
87
|
+
i0.ɵɵdomElementStart(0, "span", 17);
|
|
88
|
+
i0.ɵɵtext(1, "not signed yet");
|
|
89
|
+
i0.ɵɵdomElementEnd();
|
|
90
|
+
} }
|
|
91
|
+
function MJCContractHeroPanel_Conditional_45_Template(rf, ctx) { if (rf & 1) {
|
|
92
|
+
i0.ɵɵdomElementStart(0, "span", 17);
|
|
93
|
+
i0.ɵɵtext(1);
|
|
94
|
+
i0.ɵɵdomElementEnd();
|
|
95
|
+
} if (rf & 2) {
|
|
96
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
97
|
+
i0.ɵɵadvance();
|
|
98
|
+
i0.ɵɵtextInterpolate(ctx_r0.EndsInText);
|
|
99
|
+
} }
|
|
100
|
+
function MJCContractHeroPanel_Conditional_51_Template(rf, ctx) { if (rf & 1) {
|
|
101
|
+
i0.ɵɵdomElementStart(0, "span", 17);
|
|
102
|
+
i0.ɵɵtext(1, "no standard terms referenced");
|
|
103
|
+
i0.ɵɵdomElementEnd();
|
|
104
|
+
} }
|
|
105
|
+
function MJCContractHeroPanel_Conditional_57_Template(rf, ctx) { if (rf & 1) {
|
|
106
|
+
i0.ɵɵdomElementStart(0, "span", 17);
|
|
107
|
+
i0.ɵɵtext(1, "entered directly");
|
|
108
|
+
i0.ɵɵdomElementEnd();
|
|
109
|
+
} }
|
|
110
|
+
function MJCContractHeroPanel_Conditional_58_Template(rf, ctx) { if (rf & 1) {
|
|
111
|
+
i0.ɵɵdomElementStart(0, "div", 18);
|
|
112
|
+
i0.ɵɵtext(1, " The contract number is minted on first save, from a counter taken under a lock \u2014 so it cannot collide with another contract created at the same moment. ");
|
|
113
|
+
i0.ɵɵdomElementEnd();
|
|
114
|
+
} }
|
|
115
|
+
function MJCContractRenewalPanel_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
116
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
117
|
+
i0.ɵɵelementStart(0, "select", 13);
|
|
118
|
+
i0.ɵɵlistener("ngModelChange", function MJCContractRenewalPanel_Conditional_8_Template_select_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Set("AutoRenew", $event)); });
|
|
119
|
+
i0.ɵɵelementStart(1, "option", 14);
|
|
120
|
+
i0.ɵɵtext(2, "Yes");
|
|
121
|
+
i0.ɵɵelementEnd();
|
|
122
|
+
i0.ɵɵelementStart(3, "option", 14);
|
|
123
|
+
i0.ɵɵtext(4, "No");
|
|
124
|
+
i0.ɵɵelementEnd()();
|
|
125
|
+
} if (rf & 2) {
|
|
126
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
127
|
+
i0.ɵɵproperty("ngModel", ctx_r1.Record.AutoRenew);
|
|
128
|
+
i0.ɵɵadvance();
|
|
129
|
+
i0.ɵɵproperty("ngValue", true);
|
|
130
|
+
i0.ɵɵadvance(2);
|
|
131
|
+
i0.ɵɵproperty("ngValue", false);
|
|
132
|
+
} }
|
|
133
|
+
function MJCContractRenewalPanel_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
134
|
+
i0.ɵɵelementStart(0, "div", 6);
|
|
135
|
+
i0.ɵɵtext(1);
|
|
136
|
+
i0.ɵɵelementEnd();
|
|
137
|
+
} if (rf & 2) {
|
|
138
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
139
|
+
i0.ɵɵadvance();
|
|
140
|
+
i0.ɵɵtextInterpolate(ctx_r1.Record.AutoRenew ? "Yes" : "No");
|
|
141
|
+
} }
|
|
142
|
+
function MJCContractRenewalPanel_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
143
|
+
i0.ɵɵelementStart(0, "div", 7);
|
|
144
|
+
i0.ɵɵtext(1, "someone must act for this to continue");
|
|
145
|
+
i0.ɵɵelementEnd();
|
|
146
|
+
} }
|
|
147
|
+
function MJCContractRenewalPanel_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
148
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
149
|
+
i0.ɵɵelementStart(0, "input", 15);
|
|
150
|
+
i0.ɵɵlistener("ngModelChange", function MJCContractRenewalPanel_Conditional_14_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Set("RenewalNoticeDays", $event)); });
|
|
151
|
+
i0.ɵɵelementEnd();
|
|
152
|
+
} if (rf & 2) {
|
|
153
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
154
|
+
i0.ɵɵproperty("ngModel", ctx_r1.Record.RenewalNoticeDays);
|
|
155
|
+
} }
|
|
156
|
+
function MJCContractRenewalPanel_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
157
|
+
i0.ɵɵelementStart(0, "div", 6);
|
|
158
|
+
i0.ɵɵtext(1);
|
|
159
|
+
i0.ɵɵelementEnd();
|
|
160
|
+
} if (rf & 2) {
|
|
161
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
162
|
+
i0.ɵɵadvance();
|
|
163
|
+
i0.ɵɵtextInterpolate(ctx_r1.Record.RenewalNoticeDays ? ctx_r1.Record.RenewalNoticeDays + " days" : "\u2014");
|
|
164
|
+
} }
|
|
165
|
+
function MJCContractRenewalPanel_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
166
|
+
i0.ɵɵelementStart(0, "div", 7);
|
|
167
|
+
i0.ɵɵtext(1);
|
|
168
|
+
i0.ɵɵpipe(2, "date");
|
|
169
|
+
i0.ɵɵelementEnd();
|
|
170
|
+
} if (rf & 2) {
|
|
171
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
172
|
+
i0.ɵɵadvance();
|
|
173
|
+
i0.ɵɵtextInterpolate1("deadline: ", i0.ɵɵpipeBind2(2, 1, ctx_r1.NoticeDeadline, "d MMM y"));
|
|
174
|
+
} }
|
|
175
|
+
function MJCContractRenewalPanel_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
176
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
177
|
+
i0.ɵɵelementStart(0, "input", 16);
|
|
178
|
+
i0.ɵɵlistener("ngModelChange", function MJCContractRenewalPanel_Conditional_20_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Set("CancellationWindowDays", $event)); });
|
|
179
|
+
i0.ɵɵelementEnd();
|
|
180
|
+
} if (rf & 2) {
|
|
181
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
182
|
+
i0.ɵɵproperty("ngModel", ctx_r1.Record.CancellationWindowDays);
|
|
183
|
+
} }
|
|
184
|
+
function MJCContractRenewalPanel_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
185
|
+
i0.ɵɵelementStart(0, "div", 6);
|
|
186
|
+
i0.ɵɵtext(1);
|
|
187
|
+
i0.ɵɵelementEnd();
|
|
188
|
+
} if (rf & 2) {
|
|
189
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
190
|
+
i0.ɵɵadvance();
|
|
191
|
+
i0.ɵɵtextInterpolate(ctx_r1.Record.CancellationWindowDays ? ctx_r1.Record.CancellationWindowDays + " days" : "\u2014");
|
|
192
|
+
} }
|
|
193
|
+
function MJCContractRenewalPanel_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
194
|
+
i0.ɵɵelementStart(0, "div", 7);
|
|
195
|
+
i0.ɵɵtext(1, "the window is open now");
|
|
196
|
+
i0.ɵɵelementEnd();
|
|
197
|
+
} }
|
|
198
|
+
function MJCContractRenewalPanel_Conditional_26_Template(rf, ctx) { if (rf & 1) {
|
|
199
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
200
|
+
i0.ɵɵelementStart(0, "input", 17);
|
|
201
|
+
i0.ɵɵlistener("ngModelChange", function MJCContractRenewalPanel_Conditional_26_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Set("AnnualIncreasePercent", $event)); });
|
|
202
|
+
i0.ɵɵelementEnd();
|
|
203
|
+
} if (rf & 2) {
|
|
204
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
205
|
+
i0.ɵɵproperty("ngModel", ctx_r1.Record.AnnualIncreasePercent);
|
|
206
|
+
} }
|
|
207
|
+
function MJCContractRenewalPanel_Conditional_27_Template(rf, ctx) { if (rf & 1) {
|
|
208
|
+
i0.ɵɵelementStart(0, "div", 6);
|
|
209
|
+
i0.ɵɵtext(1);
|
|
210
|
+
i0.ɵɵelementEnd();
|
|
211
|
+
} if (rf & 2) {
|
|
212
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
213
|
+
i0.ɵɵadvance();
|
|
214
|
+
i0.ɵɵtextInterpolate(ctx_r1.Record.AnnualIncreasePercent !== null ? ctx_r1.Record.AnnualIncreasePercent + "%" : "\u2014");
|
|
215
|
+
} }
|
|
216
|
+
function MJCContractRenewalPanel_Conditional_30_Template(rf, ctx) { if (rf & 1) {
|
|
217
|
+
i0.ɵɵelementStart(0, "div", 12);
|
|
218
|
+
i0.ɵɵtext(1, " No renewal terms recorded. If the agreement states any, recording them is what puts this contract on the renewals watchlist. ");
|
|
219
|
+
i0.ɵɵelementEnd();
|
|
220
|
+
} }
|
|
221
|
+
function MJCContractDatesPanel_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
222
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
223
|
+
i0.ɵɵelementStart(0, "input", 12);
|
|
224
|
+
i0.ɵɵlistener("ngModelChange", function MJCContractDatesPanel_Conditional_6_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetDate("ExecutedDate", $event)); });
|
|
225
|
+
i0.ɵɵelementEnd();
|
|
226
|
+
} if (rf & 2) {
|
|
227
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
228
|
+
i0.ɵɵproperty("ngModel", ctx_r1.AsInput(ctx_r1.Record.ExecutedDate));
|
|
229
|
+
} }
|
|
230
|
+
function MJCContractDatesPanel_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
231
|
+
i0.ɵɵelementStart(0, "div", 5);
|
|
232
|
+
i0.ɵɵtext(1);
|
|
233
|
+
i0.ɵɵpipe(2, "date");
|
|
234
|
+
i0.ɵɵelementEnd();
|
|
235
|
+
} if (rf & 2) {
|
|
236
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
237
|
+
i0.ɵɵadvance();
|
|
238
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(2, 1, ctx_r1.Record.ExecutedDate, "d MMM y") || "\u2014");
|
|
239
|
+
} }
|
|
240
|
+
function MJCContractDatesPanel_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
241
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
242
|
+
i0.ɵɵelementStart(0, "input", 13);
|
|
243
|
+
i0.ɵɵlistener("ngModelChange", function MJCContractDatesPanel_Conditional_13_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetDate("EffectiveDate", $event)); });
|
|
244
|
+
i0.ɵɵelementEnd();
|
|
245
|
+
} if (rf & 2) {
|
|
246
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
247
|
+
i0.ɵɵproperty("ngModel", ctx_r1.AsInput(ctx_r1.Record.EffectiveDate));
|
|
248
|
+
} }
|
|
249
|
+
function MJCContractDatesPanel_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
250
|
+
i0.ɵɵelementStart(0, "div", 5);
|
|
251
|
+
i0.ɵɵtext(1);
|
|
252
|
+
i0.ɵɵpipe(2, "date");
|
|
253
|
+
i0.ɵɵelementEnd();
|
|
254
|
+
} if (rf & 2) {
|
|
255
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
256
|
+
i0.ɵɵadvance();
|
|
257
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(2, 1, ctx_r1.Record.EffectiveDate, "d MMM y") || "\u2014");
|
|
258
|
+
} }
|
|
259
|
+
function MJCContractDatesPanel_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
260
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
261
|
+
i0.ɵɵelementStart(0, "input", 14);
|
|
262
|
+
i0.ɵɵlistener("ngModelChange", function MJCContractDatesPanel_Conditional_18_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetDate("EndDate", $event)); });
|
|
263
|
+
i0.ɵɵelementEnd();
|
|
264
|
+
} if (rf & 2) {
|
|
265
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
266
|
+
i0.ɵɵproperty("ngModel", ctx_r1.AsInput(ctx_r1.Record.EndDate));
|
|
267
|
+
} }
|
|
268
|
+
function MJCContractDatesPanel_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
269
|
+
i0.ɵɵelementStart(0, "div", 5);
|
|
270
|
+
i0.ɵɵtext(1);
|
|
271
|
+
i0.ɵɵpipe(2, "date");
|
|
272
|
+
i0.ɵɵelementEnd();
|
|
273
|
+
} if (rf & 2) {
|
|
274
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
275
|
+
i0.ɵɵadvance();
|
|
276
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(2, 1, ctx_r1.Record.EndDate, "d MMM y") || "\u2014");
|
|
277
|
+
} }
|
|
278
|
+
function MJCContractDatesPanel_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
279
|
+
i0.ɵɵelementStart(0, "div", 6);
|
|
280
|
+
i0.ɵɵtext(1);
|
|
281
|
+
i0.ɵɵelementEnd();
|
|
282
|
+
} if (rf & 2) {
|
|
283
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
284
|
+
i0.ɵɵadvance();
|
|
285
|
+
i0.ɵɵtextInterpolate(ctx_r1.EndsInText);
|
|
286
|
+
} }
|
|
287
|
+
function MJCContractDatesPanel_Conditional_24_Template(rf, ctx) { if (rf & 1) {
|
|
288
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
289
|
+
i0.ɵɵelementStart(0, "input", 15);
|
|
290
|
+
i0.ɵɵlistener("ngModelChange", function MJCContractDatesPanel_Conditional_24_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetDate("TerminatedDate", $event)); });
|
|
291
|
+
i0.ɵɵelementEnd();
|
|
292
|
+
} if (rf & 2) {
|
|
293
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
294
|
+
i0.ɵɵproperty("ngModel", ctx_r1.AsInput(ctx_r1.Record.TerminatedDate));
|
|
295
|
+
} }
|
|
296
|
+
function MJCContractDatesPanel_Conditional_25_Template(rf, ctx) { if (rf & 1) {
|
|
297
|
+
i0.ɵɵelementStart(0, "div", 5);
|
|
298
|
+
i0.ɵɵtext(1);
|
|
299
|
+
i0.ɵɵpipe(2, "date");
|
|
300
|
+
i0.ɵɵelementEnd();
|
|
301
|
+
} if (rf & 2) {
|
|
302
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
303
|
+
i0.ɵɵclassProp("mjc-val--ro", !ctx_r1.Record.TerminatedDate);
|
|
304
|
+
i0.ɵɵadvance();
|
|
305
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(2, 3, ctx_r1.Record.TerminatedDate, "d MMM y") || "\u2014");
|
|
306
|
+
} }
|
|
307
|
+
function MJCContractLineagePanel_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
308
|
+
i0.ɵɵelementStart(0, "p", 4);
|
|
309
|
+
i0.ɵɵtext(1, " This is a change order to ");
|
|
310
|
+
i0.ɵɵelementStart(2, "strong");
|
|
311
|
+
i0.ɵɵtext(3);
|
|
312
|
+
i0.ɵɵelementEnd();
|
|
313
|
+
i0.ɵɵtext(4, ". ");
|
|
314
|
+
i0.ɵɵelementEnd();
|
|
315
|
+
} if (rf & 2) {
|
|
316
|
+
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
317
|
+
i0.ɵɵadvance(3);
|
|
318
|
+
i0.ɵɵtextInterpolate(ctx_r0.ParentName);
|
|
319
|
+
} }
|
|
320
|
+
function MJCContractLineagePanel_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
321
|
+
i0.ɵɵelementStart(0, "div", 1);
|
|
322
|
+
i0.ɵɵconditionalCreate(1, MJCContractLineagePanel_Conditional_2_Conditional_1_Template, 5, 1, "p", 4);
|
|
323
|
+
i0.ɵɵelementEnd();
|
|
324
|
+
} if (rf & 2) {
|
|
325
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
326
|
+
i0.ɵɵadvance();
|
|
327
|
+
i0.ɵɵconditional(ctx_r0.ParentName ? 1 : -1);
|
|
328
|
+
} }
|
|
329
|
+
function MJCContractLineagePanel_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
330
|
+
i0.ɵɵelementStart(0, "div", 3);
|
|
331
|
+
i0.ɵɵtext(1, " A standalone agreement \u2014 nothing above it, no change orders, and nothing has replaced it. ");
|
|
332
|
+
i0.ɵɵelementEnd();
|
|
333
|
+
} }
|
|
334
|
+
/** Chip variant per lifecycle state — colour carries meaning, so each state gets a considered one. */
|
|
335
|
+
function chipClassFor(state) {
|
|
336
|
+
switch (state) {
|
|
337
|
+
case 'Active': return 'mjc-chip--ok';
|
|
338
|
+
case 'Executed': return 'mjc-chip--info'; // signed, waiting — good news, not yet in force
|
|
339
|
+
case 'Terminated': return 'mjc-chip--error';
|
|
340
|
+
case 'Expired': return 'mjc-chip--muted';
|
|
341
|
+
case 'Superseded': return 'mjc-chip--muted';
|
|
342
|
+
default: return 'mjc-chip--muted'; // Draft
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
/* ────────────────────────────────────────────────────────────────────────────
|
|
346
|
+
* 1 · Hero — persistent identity, above the rail
|
|
347
|
+
* ──────────────────────────────────────────────────────────────────────────── */
|
|
348
|
+
let MJCContractHeroPanel = class MJCContractHeroPanel extends BaseFormPanel {
|
|
349
|
+
/**
|
|
350
|
+
* The human name for this agreement: its description, falling back to the number.
|
|
351
|
+
*
|
|
352
|
+
* The mockup's hero title is a descriptive line ("Sidecar — Learning Hub, 2-year"), not the contract
|
|
353
|
+
* number — the number is already in the meta row directly beneath, and repeating it as the headline
|
|
354
|
+
* wastes the one place a reader looks first.
|
|
355
|
+
*/
|
|
356
|
+
get Title() {
|
|
357
|
+
return this.Record?.Description?.trim() || this.Record?.ContractNumber || 'New contract';
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* READ from the view's derived column. Application code does not re-derive state (Marcelo,
|
|
361
|
+
* 2026-08-19) — the view is the single authority, and `DeriveContractState()` is now for tests
|
|
362
|
+
* and the equivalence harness only.
|
|
363
|
+
*
|
|
364
|
+
* This panel used to re-derive it in the browser so the chip tracked UNSAVED date edits. That
|
|
365
|
+
* bought a live-updating chip and cost the thing worth more: a second implementation that could
|
|
366
|
+
* disagree with the view, which is exactly what happened — the two diverged on the termination
|
|
367
|
+
* boundary and no test could see it. The chip now shows what is PERSISTED, which is also the
|
|
368
|
+
* more honest claim: a state chip that reacts to an unsaved date is asserting something no
|
|
369
|
+
* query would agree with until the record is saved.
|
|
370
|
+
*
|
|
371
|
+
* A never-saved record has no column value, and `Draft` is not a guess there — it is what the
|
|
372
|
+
* view's own `ELSE` branch returns for a row with no dates, which is every new contract.
|
|
373
|
+
*/
|
|
374
|
+
get State() {
|
|
375
|
+
return this.Record?.State || 'Draft';
|
|
376
|
+
}
|
|
377
|
+
get StateChipClass() { return chipClassFor(this.State); }
|
|
378
|
+
/* Joined name columns off the base view, through typed members (D-23 / D-26). */
|
|
379
|
+
get TypeName() { return this.Record?.ContractType ?? ''; }
|
|
380
|
+
get CustomerName() { return this.Record?.CustomerOrganization ?? ''; }
|
|
381
|
+
get CompanyName() { return this.Record?.Company ?? ''; }
|
|
382
|
+
get ContactName() { return this.Record?.PrimaryContactPerson ?? ''; }
|
|
383
|
+
get TemplateName() { return this.Record?.ContractTemplate ?? ''; }
|
|
384
|
+
get CreatingEntityName() { return this.Record?.CreatingEntity ?? ''; }
|
|
385
|
+
get IsAwaitingDocument() { return this.Record?.IsAwaitingDocument === true; }
|
|
386
|
+
get DaysToEnd() { return this.Record?.DaysToEnd ?? null; }
|
|
387
|
+
/** "in 16 months" reads better than "in 487 days" past a couple of months — the mockup's phrasing. */
|
|
388
|
+
get EndsInText() {
|
|
389
|
+
const d = this.DaysToEnd;
|
|
390
|
+
if (d === null)
|
|
391
|
+
return '';
|
|
392
|
+
if (d < 0)
|
|
393
|
+
return `ended ${Math.abs(d)} days ago`;
|
|
394
|
+
if (d === 0)
|
|
395
|
+
return 'ends today';
|
|
396
|
+
if (d < 60)
|
|
397
|
+
return `in ${d} days`;
|
|
398
|
+
const months = Math.round(d / 30);
|
|
399
|
+
return `in ${months} month${months === 1 ? '' : 's'}`;
|
|
400
|
+
}
|
|
401
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵMJCContractHeroPanel_BaseFactory; return function MJCContractHeroPanel_Factory(__ngFactoryType__) { return (ɵMJCContractHeroPanel_BaseFactory || (ɵMJCContractHeroPanel_BaseFactory = i0.ɵɵgetInheritedFactory(MJCContractHeroPanel)))(__ngFactoryType__ || MJCContractHeroPanel); }; })();
|
|
402
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJCContractHeroPanel, selectors: [["mjc-contract-hero-panel"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 59, vars: 30, consts: [[1, "mjc-hero"], [1, "mjc-hero__identity"], [1, "mjc-hero__avatar"], ["aria-hidden", "true", 1, "fa-solid", "fa-file-signature"], [1, "mjc-hero__copy"], [1, "mjc-hero__title-row"], [1, "mjc-hero__title"], [1, "mjc-chip"], [1, "mjc-chip", "mjc-chip--info"], ["title", "This contract deviates from the standard agreement \u2014 read the paper", 1, "mjc-chip", "mjc-chip--warn"], ["title", "This contract type expects an executed document and none is attached", 1, "mjc-chip", "mjc-chip--warn"], [1, "mjc-hero__meta"], [1, "mjc-mono"], [1, "mjc-hero__stats"], [1, "mjc-stat"], [1, "mjc-stat__label"], [1, "mjc-stat__value"], [1, "mjc-stat__sub"], [1, "mjc-flag"], ["aria-hidden", "true", 1, "fa-solid", "fa-triangle-exclamation"], ["aria-hidden", "true", 1, "fa-solid", "fa-file-circle-question"]], template: function MJCContractHeroPanel_Template(rf, ctx) { if (rf & 1) {
|
|
403
|
+
i0.ɵɵdomElementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
|
|
404
|
+
i0.ɵɵdomElement(3, "i", 3);
|
|
405
|
+
i0.ɵɵdomElementEnd();
|
|
406
|
+
i0.ɵɵdomElementStart(4, "div", 4)(5, "div", 5)(6, "h1", 6);
|
|
407
|
+
i0.ɵɵtext(7);
|
|
408
|
+
i0.ɵɵdomElementEnd();
|
|
409
|
+
i0.ɵɵdomElementStart(8, "span", 7);
|
|
410
|
+
i0.ɵɵtext(9);
|
|
411
|
+
i0.ɵɵdomElementEnd();
|
|
412
|
+
i0.ɵɵconditionalCreate(10, MJCContractHeroPanel_Conditional_10_Template, 2, 1, "span", 8);
|
|
413
|
+
i0.ɵɵconditionalCreate(11, MJCContractHeroPanel_Conditional_11_Template, 3, 0, "span", 9);
|
|
414
|
+
i0.ɵɵconditionalCreate(12, MJCContractHeroPanel_Conditional_12_Template, 3, 0, "span", 10);
|
|
415
|
+
i0.ɵɵdomElementEnd();
|
|
416
|
+
i0.ɵɵdomElementStart(13, "div", 11)(14, "span", 12);
|
|
417
|
+
i0.ɵɵtext(15);
|
|
418
|
+
i0.ɵɵdomElementEnd();
|
|
419
|
+
i0.ɵɵdomElementStart(16, "span");
|
|
420
|
+
i0.ɵɵtext(17, "Customer: ");
|
|
421
|
+
i0.ɵɵdomElementStart(18, "strong");
|
|
422
|
+
i0.ɵɵtext(19);
|
|
423
|
+
i0.ɵɵdomElementEnd()();
|
|
424
|
+
i0.ɵɵdomElementStart(20, "span");
|
|
425
|
+
i0.ɵɵtext(21, "Selling: ");
|
|
426
|
+
i0.ɵɵdomElementStart(22, "strong");
|
|
427
|
+
i0.ɵɵtext(23);
|
|
428
|
+
i0.ɵɵdomElementEnd()();
|
|
429
|
+
i0.ɵɵconditionalCreate(24, MJCContractHeroPanel_Conditional_24_Template, 4, 1, "span");
|
|
430
|
+
i0.ɵɵdomElementEnd()()();
|
|
431
|
+
i0.ɵɵdomElementStart(25, "div", 13)(26, "div", 14)(27, "span", 15);
|
|
432
|
+
i0.ɵɵtext(28, "Executed");
|
|
433
|
+
i0.ɵɵdomElementEnd();
|
|
434
|
+
i0.ɵɵdomElementStart(29, "span", 16);
|
|
435
|
+
i0.ɵɵtext(30);
|
|
436
|
+
i0.ɵɵpipe(31, "date");
|
|
437
|
+
i0.ɵɵdomElementEnd();
|
|
438
|
+
i0.ɵɵconditionalCreate(32, MJCContractHeroPanel_Conditional_32_Template, 2, 0, "span", 17);
|
|
439
|
+
i0.ɵɵdomElementEnd();
|
|
440
|
+
i0.ɵɵdomElementStart(33, "div", 14)(34, "span", 15);
|
|
441
|
+
i0.ɵɵtext(35, "Effective");
|
|
442
|
+
i0.ɵɵdomElementEnd();
|
|
443
|
+
i0.ɵɵdomElementStart(36, "span", 16);
|
|
444
|
+
i0.ɵɵtext(37);
|
|
445
|
+
i0.ɵɵpipe(38, "date");
|
|
446
|
+
i0.ɵɵdomElementEnd()();
|
|
447
|
+
i0.ɵɵdomElementStart(39, "div", 14)(40, "span", 15);
|
|
448
|
+
i0.ɵɵtext(41, "Term ends");
|
|
449
|
+
i0.ɵɵdomElementEnd();
|
|
450
|
+
i0.ɵɵdomElementStart(42, "span", 16);
|
|
451
|
+
i0.ɵɵtext(43);
|
|
452
|
+
i0.ɵɵpipe(44, "date");
|
|
453
|
+
i0.ɵɵdomElementEnd();
|
|
454
|
+
i0.ɵɵconditionalCreate(45, MJCContractHeroPanel_Conditional_45_Template, 2, 1, "span", 17);
|
|
455
|
+
i0.ɵɵdomElementEnd();
|
|
456
|
+
i0.ɵɵdomElementStart(46, "div", 14)(47, "span", 15);
|
|
457
|
+
i0.ɵɵtext(48, "Agreement");
|
|
458
|
+
i0.ɵɵdomElementEnd();
|
|
459
|
+
i0.ɵɵdomElementStart(49, "span", 16);
|
|
460
|
+
i0.ɵɵtext(50);
|
|
461
|
+
i0.ɵɵdomElementEnd();
|
|
462
|
+
i0.ɵɵconditionalCreate(51, MJCContractHeroPanel_Conditional_51_Template, 2, 0, "span", 17);
|
|
463
|
+
i0.ɵɵdomElementEnd();
|
|
464
|
+
i0.ɵɵdomElementStart(52, "div", 14)(53, "span", 15);
|
|
465
|
+
i0.ɵɵtext(54, "Created by");
|
|
466
|
+
i0.ɵɵdomElementEnd();
|
|
467
|
+
i0.ɵɵdomElementStart(55, "span", 16);
|
|
468
|
+
i0.ɵɵtext(56);
|
|
469
|
+
i0.ɵɵdomElementEnd();
|
|
470
|
+
i0.ɵɵconditionalCreate(57, MJCContractHeroPanel_Conditional_57_Template, 2, 0, "span", 17);
|
|
471
|
+
i0.ɵɵdomElementEnd()();
|
|
472
|
+
i0.ɵɵconditionalCreate(58, MJCContractHeroPanel_Conditional_58_Template, 2, 0, "div", 18);
|
|
473
|
+
i0.ɵɵdomElementEnd();
|
|
474
|
+
} if (rf & 2) {
|
|
475
|
+
i0.ɵɵadvance(7);
|
|
476
|
+
i0.ɵɵtextInterpolate(ctx.Title);
|
|
477
|
+
i0.ɵɵadvance();
|
|
478
|
+
i0.ɵɵclassMap("mjc-chip " + ctx.StateChipClass);
|
|
479
|
+
i0.ɵɵadvance();
|
|
480
|
+
i0.ɵɵtextInterpolate(ctx.State);
|
|
481
|
+
i0.ɵɵadvance();
|
|
482
|
+
i0.ɵɵconditional(ctx.TypeName ? 10 : -1);
|
|
483
|
+
i0.ɵɵadvance();
|
|
484
|
+
i0.ɵɵconditional(ctx.Record.HasModifications ? 11 : -1);
|
|
485
|
+
i0.ɵɵadvance();
|
|
486
|
+
i0.ɵɵconditional(ctx.IsAwaitingDocument ? 12 : -1);
|
|
487
|
+
i0.ɵɵadvance(3);
|
|
488
|
+
i0.ɵɵtextInterpolate(ctx.Record.ContractNumber || "Unnumbered");
|
|
489
|
+
i0.ɵɵadvance(4);
|
|
490
|
+
i0.ɵɵtextInterpolate(ctx.CustomerName || "\u2014");
|
|
491
|
+
i0.ɵɵadvance(4);
|
|
492
|
+
i0.ɵɵtextInterpolate(ctx.CompanyName || "\u2014");
|
|
493
|
+
i0.ɵɵadvance();
|
|
494
|
+
i0.ɵɵconditional(ctx.ContactName ? 24 : -1);
|
|
495
|
+
i0.ɵɵadvance(6);
|
|
496
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(31, 21, ctx.Record.ExecutedDate, "d MMM y") || "\u2014");
|
|
497
|
+
i0.ɵɵadvance(2);
|
|
498
|
+
i0.ɵɵconditional(!ctx.Record.ExecutedDate ? 32 : -1);
|
|
499
|
+
i0.ɵɵadvance(5);
|
|
500
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(38, 24, ctx.Record.EffectiveDate, "d MMM y") || "\u2014");
|
|
501
|
+
i0.ɵɵadvance(6);
|
|
502
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(44, 27, ctx.Record.EndDate, "d MMM y") || "\u2014");
|
|
503
|
+
i0.ɵɵadvance(2);
|
|
504
|
+
i0.ɵɵconditional(ctx.DaysToEnd !== null ? 45 : -1);
|
|
505
|
+
i0.ɵɵadvance(5);
|
|
506
|
+
i0.ɵɵtextInterpolate(ctx.TemplateName || "\u2014");
|
|
507
|
+
i0.ɵɵadvance();
|
|
508
|
+
i0.ɵɵconditional(!ctx.TemplateName ? 51 : -1);
|
|
509
|
+
i0.ɵɵadvance(5);
|
|
510
|
+
i0.ɵɵtextInterpolate(ctx.CreatingEntityName || "\u2014");
|
|
511
|
+
i0.ɵɵadvance();
|
|
512
|
+
i0.ɵɵconditional(!ctx.CreatingEntityName ? 57 : -1);
|
|
513
|
+
i0.ɵɵadvance();
|
|
514
|
+
i0.ɵɵconditional(!ctx.Record.ContractNumber ? 58 : -1);
|
|
515
|
+
} }, dependencies: [CommonModule, BaseFormsModule, i1.DatePipe], encapsulation: 2 });
|
|
516
|
+
};
|
|
517
|
+
MJCContractHeroPanel = __decorate([
|
|
518
|
+
RegisterClassEx(BaseFormPanel, {
|
|
519
|
+
key: 'contracts:hero',
|
|
520
|
+
skipNullKeyWarning: true,
|
|
521
|
+
metadata: {
|
|
522
|
+
entity: MJC_ENTITIES.Contract,
|
|
523
|
+
slot: 'before-fields',
|
|
524
|
+
sortKey: 100,
|
|
525
|
+
contributionKey: 'header',
|
|
526
|
+
},
|
|
527
|
+
})
|
|
528
|
+
], MJCContractHeroPanel);
|
|
529
|
+
export { MJCContractHeroPanel };
|
|
530
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJCContractHeroPanel, [{
|
|
531
|
+
type: Component,
|
|
532
|
+
args: [{
|
|
533
|
+
selector: 'mjc-contract-hero-panel',
|
|
534
|
+
standalone: true,
|
|
535
|
+
encapsulation: ViewEncapsulation.None,
|
|
536
|
+
imports: [CommonModule, BaseFormsModule],
|
|
537
|
+
template: `
|
|
538
|
+
<div class="mjc-hero">
|
|
539
|
+
<div class="mjc-hero__identity">
|
|
540
|
+
<div class="mjc-hero__avatar"><i class="fa-solid fa-file-signature" aria-hidden="true"></i></div>
|
|
541
|
+
<div class="mjc-hero__copy">
|
|
542
|
+
<div class="mjc-hero__title-row">
|
|
543
|
+
<h1 class="mjc-hero__title">{{ Title }}</h1>
|
|
544
|
+
<span class="mjc-chip" [class]="'mjc-chip ' + StateChipClass">{{ State }}</span>
|
|
545
|
+
@if (TypeName) { <span class="mjc-chip mjc-chip--info">{{ TypeName }}</span> }
|
|
546
|
+
@if (Record.HasModifications) {
|
|
547
|
+
<span class="mjc-chip mjc-chip--warn"
|
|
548
|
+
title="This contract deviates from the standard agreement — read the paper">
|
|
549
|
+
<i class="fa-solid fa-triangle-exclamation" aria-hidden="true"></i> Agreement modified
|
|
550
|
+
</span>
|
|
551
|
+
}
|
|
552
|
+
@if (IsAwaitingDocument) {
|
|
553
|
+
<span class="mjc-chip mjc-chip--warn"
|
|
554
|
+
title="This contract type expects an executed document and none is attached">
|
|
555
|
+
<i class="fa-solid fa-file-circle-question" aria-hidden="true"></i> Awaiting document
|
|
556
|
+
</span>
|
|
557
|
+
}
|
|
558
|
+
</div>
|
|
559
|
+
<div class="mjc-hero__meta">
|
|
560
|
+
<span class="mjc-mono">{{ Record.ContractNumber || 'Unnumbered' }}</span>
|
|
561
|
+
<span>Customer: <strong>{{ CustomerName || '—' }}</strong></span>
|
|
562
|
+
<span>Selling: <strong>{{ CompanyName || '—' }}</strong></span>
|
|
563
|
+
@if (ContactName) { <span>Contact: <strong>{{ ContactName }}</strong></span> }
|
|
564
|
+
</div>
|
|
565
|
+
</div>
|
|
566
|
+
</div>
|
|
567
|
+
|
|
568
|
+
<div class="mjc-hero__stats">
|
|
569
|
+
<div class="mjc-stat">
|
|
570
|
+
<span class="mjc-stat__label">Executed</span>
|
|
571
|
+
<span class="mjc-stat__value">{{ (Record.ExecutedDate | date: 'd MMM y') || '—' }}</span>
|
|
572
|
+
@if (!Record.ExecutedDate) { <span class="mjc-stat__sub">not signed yet</span> }
|
|
573
|
+
</div>
|
|
574
|
+
<div class="mjc-stat">
|
|
575
|
+
<span class="mjc-stat__label">Effective</span>
|
|
576
|
+
<span class="mjc-stat__value">{{ (Record.EffectiveDate | date: 'd MMM y') || '—' }}</span>
|
|
577
|
+
</div>
|
|
578
|
+
<div class="mjc-stat">
|
|
579
|
+
<span class="mjc-stat__label">Term ends</span>
|
|
580
|
+
<span class="mjc-stat__value">{{ (Record.EndDate | date: 'd MMM y') || '—' }}</span>
|
|
581
|
+
@if (DaysToEnd !== null) { <span class="mjc-stat__sub">{{ EndsInText }}</span> }
|
|
582
|
+
</div>
|
|
583
|
+
<div class="mjc-stat">
|
|
584
|
+
<span class="mjc-stat__label">Agreement</span>
|
|
585
|
+
<span class="mjc-stat__value">{{ TemplateName || '—' }}</span>
|
|
586
|
+
@if (!TemplateName) { <span class="mjc-stat__sub">no standard terms referenced</span> }
|
|
587
|
+
</div>
|
|
588
|
+
<div class="mjc-stat">
|
|
589
|
+
<span class="mjc-stat__label">Created by</span>
|
|
590
|
+
<span class="mjc-stat__value">{{ CreatingEntityName || '—' }}</span>
|
|
591
|
+
@if (!CreatingEntityName) { <span class="mjc-stat__sub">entered directly</span> }
|
|
592
|
+
</div>
|
|
593
|
+
</div>
|
|
594
|
+
|
|
595
|
+
@if (!Record.ContractNumber) {
|
|
596
|
+
<div class="mjc-flag">
|
|
597
|
+
The contract number is minted on first save, from a counter taken under a lock — so it
|
|
598
|
+
cannot collide with another contract created at the same moment.
|
|
599
|
+
</div>
|
|
600
|
+
}
|
|
601
|
+
</div>
|
|
602
|
+
`,
|
|
603
|
+
}]
|
|
604
|
+
}], null, null); })();
|
|
605
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJCContractHeroPanel, { className: "MJCContractHeroPanel", filePath: "lib/form-panels/contract.panels.ts", lineNumber: 144 }); })();
|
|
606
|
+
/* ────────────────────────────────────────────────────────────────────────────
|
|
607
|
+
* 2 · Renewal terms — a real rail section
|
|
608
|
+
* ──────────────────────────────────────────────────────────────────────────── */
|
|
609
|
+
let MJCContractRenewalPanel = class MJCContractRenewalPanel extends BaseFormPanel {
|
|
610
|
+
/**
|
|
611
|
+
* Write a field through the typed entity. Named `Set` rather than bound with two-way `[(ngModel)]`
|
|
612
|
+
* so the write goes through one place — a two-way binding on `Record.X` works but gives no hook for
|
|
613
|
+
* the dirty notification the form toolbar needs.
|
|
614
|
+
*/
|
|
615
|
+
Set(field, value) {
|
|
616
|
+
this.Record[field] = value;
|
|
617
|
+
}
|
|
618
|
+
/** The authoritative view column — unlike State, nobody wants this tracking a half-typed edit. */
|
|
619
|
+
get NoticeDeadline() { return this.Record?.RenewalNoticeDeadline ?? null; }
|
|
620
|
+
get InCancellationWindow() { return this.Record?.IsInCancellationWindow === true; }
|
|
621
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵMJCContractRenewalPanel_BaseFactory; return function MJCContractRenewalPanel_Factory(__ngFactoryType__) { return (ɵMJCContractRenewalPanel_BaseFactory || (ɵMJCContractRenewalPanel_BaseFactory = i0.ɵɵgetInheritedFactory(MJCContractRenewalPanel)))(__ngFactoryType__ || MJCContractRenewalPanel); }; })();
|
|
622
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJCContractRenewalPanel, selectors: [["mjc-contract-renewal-panel"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 31, vars: 10, consts: [["SectionKey", "renewal", "SectionName", "Renewal terms", "Icon", "fa-solid fa-calendar-days", 3, "Form", "FormContext"], [1, "mjc-body"], [1, "mjc-chip", "mjc-chip--muted"], [1, "mjc-fields"], [1, "mjc-field"], ["aria-label", "Does this agreement auto-renew?", 3, "ngModel"], [1, "mjc-val"], [1, "mjc-hint"], ["type", "number", "min", "0", "aria-label", "Renewal notice days", 2, "width", "100%", 3, "ngModel"], ["type", "number", "min", "0", "aria-label", "Cancellation window days", 2, "width", "100%", 3, "ngModel"], ["type", "number", "min", "0", "step", "0.01", "aria-label", "Annual increase percent", 2, "width", "100%", 3, "ngModel"], [1, "mjc-note"], [1, "mjc-empty"], ["aria-label", "Does this agreement auto-renew?", 3, "ngModelChange", "ngModel"], [3, "ngValue"], ["type", "number", "min", "0", "aria-label", "Renewal notice days", 2, "width", "100%", 3, "ngModelChange", "ngModel"], ["type", "number", "min", "0", "aria-label", "Cancellation window days", 2, "width", "100%", 3, "ngModelChange", "ngModel"], ["type", "number", "min", "0", "step", "0.01", "aria-label", "Annual increase percent", 2, "width", "100%", 3, "ngModelChange", "ngModel"]], template: function MJCContractRenewalPanel_Template(rf, ctx) { if (rf & 1) {
|
|
623
|
+
i0.ɵɵelementStart(0, "mj-collapsible-panel", 0)(1, "div", 1)(2, "span", 2);
|
|
624
|
+
i0.ɵɵtext(3, "as stated in the agreement");
|
|
625
|
+
i0.ɵɵelementEnd();
|
|
626
|
+
i0.ɵɵelementStart(4, "div", 3)(5, "div", 4)(6, "label");
|
|
627
|
+
i0.ɵɵtext(7, "Auto-renews");
|
|
628
|
+
i0.ɵɵelementEnd();
|
|
629
|
+
i0.ɵɵconditionalCreate(8, MJCContractRenewalPanel_Conditional_8_Template, 5, 3, "select", 5)(9, MJCContractRenewalPanel_Conditional_9_Template, 2, 1, "div", 6);
|
|
630
|
+
i0.ɵɵconditionalCreate(10, MJCContractRenewalPanel_Conditional_10_Template, 2, 0, "div", 7);
|
|
631
|
+
i0.ɵɵelementEnd();
|
|
632
|
+
i0.ɵɵelementStart(11, "div", 4)(12, "label");
|
|
633
|
+
i0.ɵɵtext(13, "Renewal notice we owe (days)");
|
|
634
|
+
i0.ɵɵelementEnd();
|
|
635
|
+
i0.ɵɵconditionalCreate(14, MJCContractRenewalPanel_Conditional_14_Template, 1, 1, "input", 8)(15, MJCContractRenewalPanel_Conditional_15_Template, 2, 1, "div", 6);
|
|
636
|
+
i0.ɵɵconditionalCreate(16, MJCContractRenewalPanel_Conditional_16_Template, 3, 4, "div", 7);
|
|
637
|
+
i0.ɵɵelementEnd();
|
|
638
|
+
i0.ɵɵelementStart(17, "div", 4)(18, "label");
|
|
639
|
+
i0.ɵɵtext(19, "Notice to cancel (days)");
|
|
640
|
+
i0.ɵɵelementEnd();
|
|
641
|
+
i0.ɵɵconditionalCreate(20, MJCContractRenewalPanel_Conditional_20_Template, 1, 1, "input", 9)(21, MJCContractRenewalPanel_Conditional_21_Template, 2, 1, "div", 6);
|
|
642
|
+
i0.ɵɵconditionalCreate(22, MJCContractRenewalPanel_Conditional_22_Template, 2, 0, "div", 7);
|
|
643
|
+
i0.ɵɵelementEnd();
|
|
644
|
+
i0.ɵɵelementStart(23, "div", 4)(24, "label");
|
|
645
|
+
i0.ɵɵtext(25, "Annual increase (%)");
|
|
646
|
+
i0.ɵɵelementEnd();
|
|
647
|
+
i0.ɵɵconditionalCreate(26, MJCContractRenewalPanel_Conditional_26_Template, 1, 1, "input", 10)(27, MJCContractRenewalPanel_Conditional_27_Template, 2, 1, "div", 6);
|
|
648
|
+
i0.ɵɵelementEnd()();
|
|
649
|
+
i0.ɵɵelementStart(28, "p", 11);
|
|
650
|
+
i0.ɵɵtext(29, " These record what the signed paper says. The subscription in orders holds the operational setting and may legitimately differ \u2014 a mismatch is a finding, not a bug. ");
|
|
651
|
+
i0.ɵɵelementEnd();
|
|
652
|
+
i0.ɵɵconditionalCreate(30, MJCContractRenewalPanel_Conditional_30_Template, 2, 0, "div", 12);
|
|
653
|
+
i0.ɵɵelementEnd()();
|
|
654
|
+
} if (rf & 2) {
|
|
655
|
+
i0.ɵɵproperty("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
|
|
656
|
+
i0.ɵɵadvance(8);
|
|
657
|
+
i0.ɵɵconditional(ctx.EditMode ? 8 : 9);
|
|
658
|
+
i0.ɵɵadvance(2);
|
|
659
|
+
i0.ɵɵconditional(!ctx.Record.AutoRenew ? 10 : -1);
|
|
660
|
+
i0.ɵɵadvance(4);
|
|
661
|
+
i0.ɵɵconditional(ctx.EditMode ? 14 : 15);
|
|
662
|
+
i0.ɵɵadvance(2);
|
|
663
|
+
i0.ɵɵconditional(ctx.NoticeDeadline ? 16 : -1);
|
|
664
|
+
i0.ɵɵadvance(4);
|
|
665
|
+
i0.ɵɵconditional(ctx.EditMode ? 20 : 21);
|
|
666
|
+
i0.ɵɵadvance(2);
|
|
667
|
+
i0.ɵɵconditional(ctx.InCancellationWindow ? 22 : -1);
|
|
668
|
+
i0.ɵɵadvance(4);
|
|
669
|
+
i0.ɵɵconditional(ctx.EditMode ? 26 : 27);
|
|
670
|
+
i0.ɵɵadvance(4);
|
|
671
|
+
i0.ɵɵconditional(!ctx.Record.RenewalNoticeDays && !ctx.Record.CancellationWindowDays && ctx.Record.AnnualIncreasePercent === null ? 30 : -1);
|
|
672
|
+
} }, dependencies: [CommonModule, FormsModule, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.NumberValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.MinValidator, i2.NgModel, BaseFormsModule, i3.MjCollapsiblePanelComponent, i1.DatePipe], encapsulation: 2 });
|
|
673
|
+
};
|
|
674
|
+
MJCContractRenewalPanel = __decorate([
|
|
675
|
+
RegisterClassEx(BaseFormPanel, {
|
|
676
|
+
key: 'contracts:renewal-terms',
|
|
677
|
+
skipNullKeyWarning: true,
|
|
678
|
+
metadata: {
|
|
679
|
+
entity: MJC_ENTITIES.Contract,
|
|
680
|
+
slot: 'after-fields',
|
|
681
|
+
sortKey: 85,
|
|
682
|
+
contributionKey: 'renewal',
|
|
683
|
+
// REPLACES the generated `renewalTerms` section rather than sitting beside it. Two reasons, and
|
|
684
|
+
// the second is the one that makes the rail work:
|
|
685
|
+
//
|
|
686
|
+
// 1. Without it the four fields render TWICE — once in the generated field list and once here.
|
|
687
|
+
// 2. Under `left-nav`, MJ folds every *leftover* field panel into a single `Details` rail item.
|
|
688
|
+
// A section that a Primary contribution REPLACES is no longer leftover, so it earns its own
|
|
689
|
+
// rail entry. That is the mechanism behind the mockup's rail, and without the replacement
|
|
690
|
+
// this panel folded into Details and the form read as one long page.
|
|
691
|
+
replacesSectionKey: 'renewalTerms',
|
|
692
|
+
// NO `inclusion: 'Primary'` — and that omission is what puts Details FIRST.
|
|
693
|
+
//
|
|
694
|
+
// The rail is assembled as fixed BANDS, not from a sortable flat list:
|
|
695
|
+
// `spec.Groups = [...leads, ...details, ...related, ...more]`
|
|
696
|
+
// (`resolve-form-chrome.ts:761`). A panel joins the LEAD band purely by declaring
|
|
697
|
+
// `inclusion: 'Primary'` (`isLeadContribution`, `:313`), and every lead therefore renders
|
|
698
|
+
// BEFORE Details. With all of these marked Primary, Details sat fourth.
|
|
699
|
+
//
|
|
700
|
+
// Reordering `spec.Groups` from a `BaseFormPolicy.DecorateChrome` cannot fix that:
|
|
701
|
+
// `StabilizeFirstClassGroupOrder` re-imposes the bands, and its own comment says it moves
|
|
702
|
+
// groups "into the lead band before Details" — so the reorder is silently undone. Only a
|
|
703
|
+
// user's drag order (`OrderChromeGroups`) outranks the bands, and that is a per-user
|
|
704
|
+
// preference an app cannot ship.
|
|
705
|
+
//
|
|
706
|
+
// Dropping Primary moves these into the `related` band, which sorts DESCENDING by sortKey
|
|
707
|
+
// (`:753`), so the numbers below are the running order after Details.
|
|
708
|
+
},
|
|
709
|
+
})
|
|
710
|
+
], MJCContractRenewalPanel);
|
|
711
|
+
export { MJCContractRenewalPanel };
|
|
712
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJCContractRenewalPanel, [{
|
|
713
|
+
type: Component,
|
|
714
|
+
args: [{
|
|
715
|
+
selector: 'mjc-contract-renewal-panel',
|
|
716
|
+
standalone: true,
|
|
717
|
+
encapsulation: ViewEncapsulation.None,
|
|
718
|
+
imports: [CommonModule, FormsModule, BaseFormsModule],
|
|
719
|
+
template: `
|
|
720
|
+
<mj-collapsible-panel
|
|
721
|
+
SectionKey="renewal"
|
|
722
|
+
SectionName="Renewal terms"
|
|
723
|
+
Icon="fa-solid fa-calendar-days"
|
|
724
|
+
[Form]="FormComponent"
|
|
725
|
+
[FormContext]="FormContext">
|
|
726
|
+
|
|
727
|
+
<div class="mjc-body">
|
|
728
|
+
<span class="mjc-chip mjc-chip--muted">as stated in the agreement</span>
|
|
729
|
+
|
|
730
|
+
<div class="mjc-fields">
|
|
731
|
+
<div class="mjc-field">
|
|
732
|
+
<label>Auto-renews</label>
|
|
733
|
+
@if (EditMode) {
|
|
734
|
+
<select [ngModel]="Record.AutoRenew" (ngModelChange)="Set('AutoRenew', $event)"
|
|
735
|
+
aria-label="Does this agreement auto-renew?">
|
|
736
|
+
<option [ngValue]="true">Yes</option>
|
|
737
|
+
<option [ngValue]="false">No</option>
|
|
738
|
+
</select>
|
|
739
|
+
} @else {
|
|
740
|
+
<div class="mjc-val">{{ Record.AutoRenew ? 'Yes' : 'No' }}</div>
|
|
741
|
+
}
|
|
742
|
+
@if (!Record.AutoRenew) {
|
|
743
|
+
<div class="mjc-hint">someone must act for this to continue</div>
|
|
744
|
+
}
|
|
745
|
+
</div>
|
|
746
|
+
<div class="mjc-field">
|
|
747
|
+
<label>Renewal notice we owe (days)</label>
|
|
748
|
+
@if (EditMode) {
|
|
749
|
+
<input type="number" min="0" style="width:100%" [ngModel]="Record.RenewalNoticeDays"
|
|
750
|
+
(ngModelChange)="Set('RenewalNoticeDays', $event)" aria-label="Renewal notice days" />
|
|
751
|
+
} @else {
|
|
752
|
+
<div class="mjc-val">{{ Record.RenewalNoticeDays ? Record.RenewalNoticeDays + ' days' : '—' }}</div>
|
|
753
|
+
}
|
|
754
|
+
@if (NoticeDeadline) {
|
|
755
|
+
<div class="mjc-hint">deadline: {{ NoticeDeadline | date: 'd MMM y' }}</div>
|
|
756
|
+
}
|
|
757
|
+
</div>
|
|
758
|
+
<div class="mjc-field">
|
|
759
|
+
<label>Notice to cancel (days)</label>
|
|
760
|
+
@if (EditMode) {
|
|
761
|
+
<input type="number" min="0" style="width:100%" [ngModel]="Record.CancellationWindowDays"
|
|
762
|
+
(ngModelChange)="Set('CancellationWindowDays', $event)" aria-label="Cancellation window days" />
|
|
763
|
+
} @else {
|
|
764
|
+
<div class="mjc-val">{{ Record.CancellationWindowDays ? Record.CancellationWindowDays + ' days' : '—' }}</div>
|
|
765
|
+
}
|
|
766
|
+
@if (InCancellationWindow) { <div class="mjc-hint">the window is open now</div> }
|
|
767
|
+
</div>
|
|
768
|
+
<div class="mjc-field">
|
|
769
|
+
<label>Annual increase (%)</label>
|
|
770
|
+
@if (EditMode) {
|
|
771
|
+
<input type="number" min="0" step="0.01" style="width:100%" [ngModel]="Record.AnnualIncreasePercent"
|
|
772
|
+
(ngModelChange)="Set('AnnualIncreasePercent', $event)" aria-label="Annual increase percent" />
|
|
773
|
+
} @else {
|
|
774
|
+
<div class="mjc-val">{{ Record.AnnualIncreasePercent !== null ? Record.AnnualIncreasePercent + '%' : '—' }}</div>
|
|
775
|
+
}
|
|
776
|
+
</div>
|
|
777
|
+
</div>
|
|
778
|
+
|
|
779
|
+
<p class="mjc-note">
|
|
780
|
+
These record what the signed paper says. The subscription in orders holds the operational
|
|
781
|
+
setting and may legitimately differ — a mismatch is a finding, not a bug.
|
|
782
|
+
</p>
|
|
783
|
+
|
|
784
|
+
@if (!Record.RenewalNoticeDays && !Record.CancellationWindowDays && Record.AnnualIncreasePercent === null) {
|
|
785
|
+
<div class="mjc-empty">
|
|
786
|
+
No renewal terms recorded. If the agreement states any, recording them is what puts this
|
|
787
|
+
contract on the renewals watchlist.
|
|
788
|
+
</div>
|
|
789
|
+
}
|
|
790
|
+
</div>
|
|
791
|
+
</mj-collapsible-panel>
|
|
792
|
+
`,
|
|
793
|
+
}]
|
|
794
|
+
}], null, null); })();
|
|
795
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJCContractRenewalPanel, { className: "MJCContractRenewalPanel", filePath: "lib/form-panels/contract.panels.ts", lineNumber: 318 }); })();
|
|
796
|
+
/* ────────────────────────────────────────────────────────────────────────────
|
|
797
|
+
* 2b · Dates — its own rail section, replacing the generated `datesAndTerms`
|
|
798
|
+
* ──────────────────────────────────────────────────────────────────────────── */
|
|
799
|
+
/**
|
|
800
|
+
* The four dates, with the one piece of interpretation a reader needs.
|
|
801
|
+
*
|
|
802
|
+
* Exists as a panel for the same two reasons as Renewal terms: it earns a rail entry by REPLACING a
|
|
803
|
+
* named field section (a replaced section is not "leftover", so left-nav does not fold it into
|
|
804
|
+
* Details), and it can say things the generated field list cannot — that an executed date before the
|
|
805
|
+
* effective date is normal, and that a terminated date is a fact rather than a projection.
|
|
806
|
+
*
|
|
807
|
+
* The generated form renders these as datetime inputs with a time component (`7/19/2025, 7:00:00 PM`)
|
|
808
|
+
* because the underlying columns are `date` but the default control is a datetime picker. They are
|
|
809
|
+
* calendar dates — a contract does not start at 7pm — so this panel renders them as dates.
|
|
810
|
+
*/
|
|
811
|
+
let MJCContractDatesPanel = class MJCContractDatesPanel extends BaseFormPanel {
|
|
812
|
+
/** `<input type="date">` needs `yyyy-MM-dd`; the entity hands back a Date or an ISO string. */
|
|
813
|
+
AsInput(v) {
|
|
814
|
+
if (!v)
|
|
815
|
+
return '';
|
|
816
|
+
const d = v instanceof Date ? v : new Date(String(v));
|
|
817
|
+
return Number.isNaN(d.getTime()) ? '' : d.toISOString().slice(0, 10);
|
|
818
|
+
}
|
|
819
|
+
SetDate(field, value) {
|
|
820
|
+
this.Record[field] = value ? new Date(value + 'T00:00:00Z') : null;
|
|
821
|
+
}
|
|
822
|
+
get EndsInText() {
|
|
823
|
+
const d = this.Record?.DaysToEnd ?? null;
|
|
824
|
+
if (d === null)
|
|
825
|
+
return '';
|
|
826
|
+
if (d < 0)
|
|
827
|
+
return `ended ${Math.abs(d)} days ago`;
|
|
828
|
+
if (d === 0)
|
|
829
|
+
return 'ends today';
|
|
830
|
+
return d < 60 ? `in ${d} days` : `in ${Math.round(d / 30)} months`;
|
|
831
|
+
}
|
|
832
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵMJCContractDatesPanel_BaseFactory; return function MJCContractDatesPanel_Factory(__ngFactoryType__) { return (ɵMJCContractDatesPanel_BaseFactory || (ɵMJCContractDatesPanel_BaseFactory = i0.ɵɵgetInheritedFactory(MJCContractDatesPanel)))(__ngFactoryType__ || MJCContractDatesPanel); }; })();
|
|
833
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJCContractDatesPanel, selectors: [["mjc-contract-dates-panel"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 33, vars: 7, consts: [["SectionKey", "dates", "SectionName", "Dates", "Icon", "fa-solid fa-calendar", 3, "Form", "FormContext"], [1, "mjc-body"], [1, "mjc-fields"], [1, "mjc-field"], ["type", "date", "aria-label", "Executed date", 2, "width", "100%", 3, "ngModel"], [1, "mjc-val"], [1, "mjc-hint"], ["type", "date", "aria-label", "Effective date", 2, "width", "100%", 3, "ngModel"], ["type", "date", "aria-label", "End date", 2, "width", "100%", 3, "ngModel"], ["type", "date", "aria-label", "Terminated date", 2, "width", "100%", 3, "ngModel"], [1, "mjc-val", 3, "mjc-val--ro"], [1, "mjc-note"], ["type", "date", "aria-label", "Executed date", 2, "width", "100%", 3, "ngModelChange", "ngModel"], ["type", "date", "aria-label", "Effective date", 2, "width", "100%", 3, "ngModelChange", "ngModel"], ["type", "date", "aria-label", "End date", 2, "width", "100%", 3, "ngModelChange", "ngModel"], ["type", "date", "aria-label", "Terminated date", 2, "width", "100%", 3, "ngModelChange", "ngModel"]], template: function MJCContractDatesPanel_Template(rf, ctx) { if (rf & 1) {
|
|
834
|
+
i0.ɵɵelementStart(0, "mj-collapsible-panel", 0)(1, "div", 1)(2, "div", 2)(3, "div", 3)(4, "label");
|
|
835
|
+
i0.ɵɵtext(5, "Executed date");
|
|
836
|
+
i0.ɵɵelementEnd();
|
|
837
|
+
i0.ɵɵconditionalCreate(6, MJCContractDatesPanel_Conditional_6_Template, 1, 1, "input", 4)(7, MJCContractDatesPanel_Conditional_7_Template, 3, 4, "div", 5);
|
|
838
|
+
i0.ɵɵelementStart(8, "div", 6);
|
|
839
|
+
i0.ɵɵtext(9, "may precede the effective date \u2014 that is normal, not an anomaly");
|
|
840
|
+
i0.ɵɵelementEnd()();
|
|
841
|
+
i0.ɵɵelementStart(10, "div", 3)(11, "label");
|
|
842
|
+
i0.ɵɵtext(12, "Effective date");
|
|
843
|
+
i0.ɵɵelementEnd();
|
|
844
|
+
i0.ɵɵconditionalCreate(13, MJCContractDatesPanel_Conditional_13_Template, 1, 1, "input", 7)(14, MJCContractDatesPanel_Conditional_14_Template, 3, 4, "div", 5);
|
|
845
|
+
i0.ɵɵelementEnd();
|
|
846
|
+
i0.ɵɵelementStart(15, "div", 3)(16, "label");
|
|
847
|
+
i0.ɵɵtext(17, "End date");
|
|
848
|
+
i0.ɵɵelementEnd();
|
|
849
|
+
i0.ɵɵconditionalCreate(18, MJCContractDatesPanel_Conditional_18_Template, 1, 1, "input", 8)(19, MJCContractDatesPanel_Conditional_19_Template, 3, 4, "div", 5);
|
|
850
|
+
i0.ɵɵconditionalCreate(20, MJCContractDatesPanel_Conditional_20_Template, 2, 1, "div", 6);
|
|
851
|
+
i0.ɵɵelementEnd();
|
|
852
|
+
i0.ɵɵelementStart(21, "div", 3)(22, "label");
|
|
853
|
+
i0.ɵɵtext(23, "Terminated date");
|
|
854
|
+
i0.ɵɵelementEnd();
|
|
855
|
+
i0.ɵɵconditionalCreate(24, MJCContractDatesPanel_Conditional_24_Template, 1, 1, "input", 9)(25, MJCContractDatesPanel_Conditional_25_Template, 3, 6, "div", 10);
|
|
856
|
+
i0.ɵɵelementStart(26, "div", 6);
|
|
857
|
+
i0.ɵɵtext(27, " a fact about what happened \u2014 set it and the contract reads Terminated regardless of its term ");
|
|
858
|
+
i0.ɵɵelementEnd()()();
|
|
859
|
+
i0.ɵɵelementStart(28, "p", 11);
|
|
860
|
+
i0.ɵɵtext(29, " The lifecycle is ");
|
|
861
|
+
i0.ɵɵelementStart(30, "strong");
|
|
862
|
+
i0.ɵɵtext(31, "derived");
|
|
863
|
+
i0.ɵɵelementEnd();
|
|
864
|
+
i0.ɵɵtext(32, " from these four dates and the two lineage links, not stored \u2014 so a state can never disagree with the dates it came from. ");
|
|
865
|
+
i0.ɵɵelementEnd()()();
|
|
866
|
+
} if (rf & 2) {
|
|
867
|
+
i0.ɵɵproperty("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
|
|
868
|
+
i0.ɵɵadvance(6);
|
|
869
|
+
i0.ɵɵconditional(ctx.EditMode ? 6 : 7);
|
|
870
|
+
i0.ɵɵadvance(7);
|
|
871
|
+
i0.ɵɵconditional(ctx.EditMode ? 13 : 14);
|
|
872
|
+
i0.ɵɵadvance(5);
|
|
873
|
+
i0.ɵɵconditional(ctx.EditMode ? 18 : 19);
|
|
874
|
+
i0.ɵɵadvance(2);
|
|
875
|
+
i0.ɵɵconditional(ctx.Record.DaysToEnd !== null ? 20 : -1);
|
|
876
|
+
i0.ɵɵadvance(4);
|
|
877
|
+
i0.ɵɵconditional(ctx.EditMode ? 24 : 25);
|
|
878
|
+
} }, dependencies: [CommonModule, FormsModule, i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel, BaseFormsModule, i3.MjCollapsiblePanelComponent, i1.DatePipe], encapsulation: 2 });
|
|
879
|
+
};
|
|
880
|
+
MJCContractDatesPanel = __decorate([
|
|
881
|
+
RegisterClassEx(BaseFormPanel, {
|
|
882
|
+
key: 'contracts:dates',
|
|
883
|
+
skipNullKeyWarning: true,
|
|
884
|
+
metadata: {
|
|
885
|
+
entity: MJC_ENTITIES.Contract,
|
|
886
|
+
slot: 'after-fields',
|
|
887
|
+
sortKey: 90,
|
|
888
|
+
contributionKey: 'dates',
|
|
889
|
+
replacesSectionKey: 'datesAndTerms',
|
|
890
|
+
// NO `inclusion: 'Primary'` — and that omission is what puts Details FIRST.
|
|
891
|
+
//
|
|
892
|
+
// The rail is assembled as fixed BANDS, not from a sortable flat list:
|
|
893
|
+
// `spec.Groups = [...leads, ...details, ...related, ...more]`
|
|
894
|
+
// (`resolve-form-chrome.ts:761`). A panel joins the LEAD band purely by declaring
|
|
895
|
+
// `inclusion: 'Primary'` (`isLeadContribution`, `:313`), and every lead therefore renders
|
|
896
|
+
// BEFORE Details. With all of these marked Primary, Details sat fourth.
|
|
897
|
+
//
|
|
898
|
+
// Reordering `spec.Groups` from a `BaseFormPolicy.DecorateChrome` cannot fix that:
|
|
899
|
+
// `StabilizeFirstClassGroupOrder` re-imposes the bands, and its own comment says it moves
|
|
900
|
+
// groups "into the lead band before Details" — so the reorder is silently undone. Only a
|
|
901
|
+
// user's drag order (`OrderChromeGroups`) outranks the bands, and that is a per-user
|
|
902
|
+
// preference an app cannot ship.
|
|
903
|
+
//
|
|
904
|
+
// Dropping Primary moves these into the `related` band, which sorts DESCENDING by sortKey
|
|
905
|
+
// (`:753`), so the numbers below are the running order after Details.
|
|
906
|
+
},
|
|
907
|
+
})
|
|
908
|
+
], MJCContractDatesPanel);
|
|
909
|
+
export { MJCContractDatesPanel };
|
|
910
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJCContractDatesPanel, [{
|
|
911
|
+
type: Component,
|
|
912
|
+
args: [{
|
|
913
|
+
selector: 'mjc-contract-dates-panel',
|
|
914
|
+
standalone: true,
|
|
915
|
+
encapsulation: ViewEncapsulation.None,
|
|
916
|
+
imports: [CommonModule, FormsModule, BaseFormsModule],
|
|
917
|
+
template: `
|
|
918
|
+
<mj-collapsible-panel
|
|
919
|
+
SectionKey="dates"
|
|
920
|
+
SectionName="Dates"
|
|
921
|
+
Icon="fa-solid fa-calendar"
|
|
922
|
+
[Form]="FormComponent"
|
|
923
|
+
[FormContext]="FormContext">
|
|
924
|
+
|
|
925
|
+
<div class="mjc-body">
|
|
926
|
+
<div class="mjc-fields">
|
|
927
|
+
<div class="mjc-field">
|
|
928
|
+
<label>Executed date</label>
|
|
929
|
+
@if (EditMode) {
|
|
930
|
+
<input type="date" style="width:100%" [ngModel]="AsInput(Record.ExecutedDate)"
|
|
931
|
+
(ngModelChange)="SetDate('ExecutedDate', $event)" aria-label="Executed date" />
|
|
932
|
+
} @else {
|
|
933
|
+
<div class="mjc-val">{{ (Record.ExecutedDate | date: 'd MMM y') || '—' }}</div>
|
|
934
|
+
}
|
|
935
|
+
<div class="mjc-hint">may precede the effective date — that is normal, not an anomaly</div>
|
|
936
|
+
</div>
|
|
937
|
+
<div class="mjc-field">
|
|
938
|
+
<label>Effective date</label>
|
|
939
|
+
@if (EditMode) {
|
|
940
|
+
<input type="date" style="width:100%" [ngModel]="AsInput(Record.EffectiveDate)"
|
|
941
|
+
(ngModelChange)="SetDate('EffectiveDate', $event)" aria-label="Effective date" />
|
|
942
|
+
} @else {
|
|
943
|
+
<div class="mjc-val">{{ (Record.EffectiveDate | date: 'd MMM y') || '—' }}</div>
|
|
944
|
+
}
|
|
945
|
+
</div>
|
|
946
|
+
<div class="mjc-field">
|
|
947
|
+
<label>End date</label>
|
|
948
|
+
@if (EditMode) {
|
|
949
|
+
<input type="date" style="width:100%" [ngModel]="AsInput(Record.EndDate)"
|
|
950
|
+
(ngModelChange)="SetDate('EndDate', $event)" aria-label="End date" />
|
|
951
|
+
} @else {
|
|
952
|
+
<div class="mjc-val">{{ (Record.EndDate | date: 'd MMM y') || '—' }}</div>
|
|
953
|
+
}
|
|
954
|
+
@if (Record.DaysToEnd !== null) { <div class="mjc-hint">{{ EndsInText }}</div> }
|
|
955
|
+
</div>
|
|
956
|
+
<div class="mjc-field">
|
|
957
|
+
<label>Terminated date</label>
|
|
958
|
+
@if (EditMode) {
|
|
959
|
+
<input type="date" style="width:100%" [ngModel]="AsInput(Record.TerminatedDate)"
|
|
960
|
+
(ngModelChange)="SetDate('TerminatedDate', $event)" aria-label="Terminated date" />
|
|
961
|
+
} @else {
|
|
962
|
+
<div class="mjc-val" [class.mjc-val--ro]="!Record.TerminatedDate">{{ (Record.TerminatedDate | date: 'd MMM y') || '—' }}</div>
|
|
963
|
+
}
|
|
964
|
+
<div class="mjc-hint">
|
|
965
|
+
a fact about what happened — set it and the contract reads Terminated regardless of its term
|
|
966
|
+
</div>
|
|
967
|
+
</div>
|
|
968
|
+
</div>
|
|
969
|
+
|
|
970
|
+
<p class="mjc-note">
|
|
971
|
+
The lifecycle is <strong>derived</strong> from these four dates and the two lineage links, not
|
|
972
|
+
stored — so a state can never disagree with the dates it came from.
|
|
973
|
+
</p>
|
|
974
|
+
</div>
|
|
975
|
+
</mj-collapsible-panel>
|
|
976
|
+
`,
|
|
977
|
+
}]
|
|
978
|
+
}], null, null); })();
|
|
979
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJCContractDatesPanel, { className: "MJCContractDatesPanel", filePath: "lib/form-panels/contract.panels.ts", lineNumber: 442 }); })();
|
|
980
|
+
/* ────────────────────────────────────────────────────────────────────────────
|
|
981
|
+
* 4 · Lineage — change orders and supersession, read-only
|
|
982
|
+
* ──────────────────────────────────────────────────────────────────────────── */
|
|
983
|
+
let MJCContractLineagePanel = class MJCContractLineagePanel extends BaseFormPanel {
|
|
984
|
+
cdr = inject(ChangeDetectorRef);
|
|
985
|
+
navigation = inject(NavigationService);
|
|
986
|
+
/**
|
|
987
|
+
* The whole tree, declared rather than fetched.
|
|
988
|
+
*
|
|
989
|
+
* `ParentContractID` is an ordinary self-referential hierarchy, so MJ's tree does the recursive
|
|
990
|
+
* read, the expand/collapse state, the search box and — the part that matters — turns each node
|
|
991
|
+
* into something you can OPEN. The hand-rolled table this replaces could show a change order's
|
|
992
|
+
* number but gave no way to get to it, which is most of what a person wants from a lineage panel.
|
|
993
|
+
*
|
|
994
|
+
* NO `ExtraFilter`, deliberately — the component does the scoping better than a filter could. Given
|
|
995
|
+
* the whole entity plus `ActiveRecordID`, it focuses this contract's subtree on its own (the header
|
|
996
|
+
* reads "Focusing subtree: CTR-…") and offers "View Full Hierarchy" to widen. A filter rooted at
|
|
997
|
+
* the current record would hard-hide the parent a change order needs to show ABOVE it, with no way
|
|
998
|
+
* back out. Ordering is by contract number so siblings read in the order they were issued.
|
|
999
|
+
*/
|
|
1000
|
+
get TreeConfig() {
|
|
1001
|
+
return {
|
|
1002
|
+
EntityName: MJC_ENTITIES.Contract,
|
|
1003
|
+
ParentField: 'ParentContractID',
|
|
1004
|
+
NameField: 'ContractNumber',
|
|
1005
|
+
SubtitleField: 'Description',
|
|
1006
|
+
OrderBy: 'ContractNumber ASC',
|
|
1007
|
+
ShowSearch: true,
|
|
1008
|
+
InitialExpandDepth: 2,
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
/** Whether anything hangs beneath this contract — drives the empty state, nothing else. */
|
|
1012
|
+
HasChildren = false;
|
|
1013
|
+
loadStarted = false;
|
|
1014
|
+
/**
|
|
1015
|
+
* Open the contract a node stands for.
|
|
1016
|
+
*
|
|
1017
|
+
* The node carries a real `CompositeKey`, so this does not have to guess that the primary key is
|
|
1018
|
+
* called `ID` — the same reasoning as `MJCFkNavigateDirective`, which would break on the first
|
|
1019
|
+
* natural-key entity it met, and would break as a WRONG-RECORD navigation rather than an error.
|
|
1020
|
+
*/
|
|
1021
|
+
OpenNode(e) {
|
|
1022
|
+
const key = e?.Node?.PrimaryKey;
|
|
1023
|
+
if (!key)
|
|
1024
|
+
return;
|
|
1025
|
+
this.navigation.OpenEntityRecord(MJC_ENTITIES.Contract, key);
|
|
1026
|
+
}
|
|
1027
|
+
get ParentName() { return this.Record?.ParentContract ?? ''; }
|
|
1028
|
+
get Count() {
|
|
1029
|
+
this.ensureLoaded();
|
|
1030
|
+
return this.ChildCount > 0 ? this.ChildCount : undefined;
|
|
1031
|
+
}
|
|
1032
|
+
/** Direct children, for the badge. The TREE renders the hierarchy; this is just the count. */
|
|
1033
|
+
ChildCount = 0;
|
|
1034
|
+
/**
|
|
1035
|
+
* Read the children ONCE, lazily on first template read.
|
|
1036
|
+
*
|
|
1037
|
+
* `BaseFormPanel` has no lifecycle hook of its own and the slot host sets `Record` before view init,
|
|
1038
|
+
* so the first template read is the earliest reliable moment. Read as a table rather than an
|
|
1039
|
+
* embedded grid: a grid inside a panel inside a rail section is three nested scroll contexts, and
|
|
1040
|
+
* the mockup renders four columns of read-only facts, which is a table.
|
|
1041
|
+
*/
|
|
1042
|
+
ensureLoaded() {
|
|
1043
|
+
if (this.loadStarted || !this.Record?.ID)
|
|
1044
|
+
return;
|
|
1045
|
+
this.loadStarted = true;
|
|
1046
|
+
void this.load();
|
|
1047
|
+
}
|
|
1048
|
+
async load() {
|
|
1049
|
+
const me = this.Record.ID;
|
|
1050
|
+
const rv = await this.scopedRunView();
|
|
1051
|
+
// Only the COUNT, for the badge and the empty state — mj-hierarchy-tree reads the hierarchy
|
|
1052
|
+
// itself from TreeConfig, so duplicating that read here would be a second source of truth.
|
|
1053
|
+
try {
|
|
1054
|
+
const r = await rv.RunView({
|
|
1055
|
+
EntityName: MJC_ENTITIES.Contract,
|
|
1056
|
+
Fields: ['ID'],
|
|
1057
|
+
ExtraFilter: `ParentContractID = '${me}'`,
|
|
1058
|
+
ResultType: 'simple',
|
|
1059
|
+
});
|
|
1060
|
+
this.ChildCount = r?.Success ? r.Results.length : 0;
|
|
1061
|
+
this.HasChildren = this.ChildCount > 0;
|
|
1062
|
+
}
|
|
1063
|
+
catch {
|
|
1064
|
+
this.ChildCount = 0;
|
|
1065
|
+
this.HasChildren = false;
|
|
1066
|
+
}
|
|
1067
|
+
this.cdr.detectChanges();
|
|
1068
|
+
}
|
|
1069
|
+
async scopedRunView() {
|
|
1070
|
+
const { ScopedRunView } = await import('../data/provider');
|
|
1071
|
+
return ScopedRunView(this.FormComponent?.ProviderToUse);
|
|
1072
|
+
}
|
|
1073
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵMJCContractLineagePanel_BaseFactory; return function MJCContractLineagePanel_Factory(__ngFactoryType__) { return (ɵMJCContractLineagePanel_BaseFactory || (ɵMJCContractLineagePanel_BaseFactory = i0.ɵɵgetInheritedFactory(MJCContractLineagePanel)))(__ngFactoryType__ || MJCContractLineagePanel); }; })();
|
|
1074
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJCContractLineagePanel, selectors: [["mjc-contract-lineage-panel"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 9, consts: [["SectionKey", "contractLineage", "SectionName", "Lineage", "Icon", "fa-solid fa-sitemap", "Variant", "related-entity", 3, "BadgeCount", "Form", "FormContext"], [1, "mjc-body"], [3, "NodeDoubleClick", "Config", "ActiveRecordID"], [1, "mjc-empty"], [1, "mjc-note"]], template: function MJCContractLineagePanel_Template(rf, ctx) { if (rf & 1) {
|
|
1075
|
+
i0.ɵɵelementStart(0, "mj-collapsible-panel", 0)(1, "div", 1);
|
|
1076
|
+
i0.ɵɵconditionalCreate(2, MJCContractLineagePanel_Conditional_2_Template, 2, 1, "div", 1);
|
|
1077
|
+
i0.ɵɵelementStart(3, "mj-hierarchy-tree", 2);
|
|
1078
|
+
i0.ɵɵlistener("NodeDoubleClick", function MJCContractLineagePanel_Template_mj_hierarchy_tree_NodeDoubleClick_3_listener($event) { return ctx.OpenNode($event); });
|
|
1079
|
+
i0.ɵɵelementEnd();
|
|
1080
|
+
i0.ɵɵconditionalCreate(4, MJCContractLineagePanel_Conditional_4_Template, 2, 0, "div", 3);
|
|
1081
|
+
i0.ɵɵelementEnd()();
|
|
1082
|
+
} if (rf & 2) {
|
|
1083
|
+
i0.ɵɵproperty("BadgeCount", ctx.Count)("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
|
|
1084
|
+
i0.ɵɵadvance();
|
|
1085
|
+
i0.ɵɵclassProp("mjc-body--flush", ctx.HasChildren);
|
|
1086
|
+
i0.ɵɵadvance();
|
|
1087
|
+
i0.ɵɵconditional(ctx.ParentName ? 2 : -1);
|
|
1088
|
+
i0.ɵɵadvance();
|
|
1089
|
+
i0.ɵɵproperty("Config", ctx.TreeConfig)("ActiveRecordID", (ctx.Record == null ? null : ctx.Record.ID) ?? undefined);
|
|
1090
|
+
i0.ɵɵadvance();
|
|
1091
|
+
i0.ɵɵconditional(!ctx.ParentName && !ctx.HasChildren ? 4 : -1);
|
|
1092
|
+
} }, dependencies: [CommonModule, FormsModule, BaseFormsModule, i3.MjCollapsiblePanelComponent, HierarchyTreeComponent], styles: ["\n /* A PINNED FLOOR, not a percentage. height:100% cannot work here: it resolves against\n .mj-forms-panel-content, which the variant sets to height:auto, and 100% of auto collapses\n straight back to auto - measured blank. AG Grid escapes this because the grid supplies its\n own intrinsic height; a plain div does not. A px min-height resolves regardless of what the\n parent computes to, and stays under the variant's own 800px cap. */\n /* DIRECT child only. As a descendant selector this also matched the nested .mjc-body wrapper\n inside the panel, so the floor applied twice and left a tall empty block above the tree. */\n mjc-contract-lineage-panel > .mjc-body {\n min-height: 440px;\n overflow-y: auto;\n }\n mjc-contract-lineage-panel mj-hierarchy-tree { display: block; min-height: 380px; }\n "], encapsulation: 2 });
|
|
1093
|
+
};
|
|
1094
|
+
MJCContractLineagePanel = __decorate([
|
|
1095
|
+
RegisterClassEx(BaseFormPanel, {
|
|
1096
|
+
key: 'contracts:lineage',
|
|
1097
|
+
skipNullKeyWarning: true,
|
|
1098
|
+
metadata: {
|
|
1099
|
+
entity: MJC_ENTITIES.Contract,
|
|
1100
|
+
slot: 'after-related',
|
|
1101
|
+
sortKey: 65,
|
|
1102
|
+
contributionKey: 'lineage',
|
|
1103
|
+
relatedEntity: MJC_ENTITIES.Contract,
|
|
1104
|
+
relatedJoinField: 'ParentContractID',
|
|
1105
|
+
// NO `inclusion: 'Primary'` — and that omission is what puts Details FIRST.
|
|
1106
|
+
//
|
|
1107
|
+
// The rail is assembled as fixed BANDS, not from a sortable flat list:
|
|
1108
|
+
// `spec.Groups = [...leads, ...details, ...related, ...more]`
|
|
1109
|
+
// (`resolve-form-chrome.ts:761`). A panel joins the LEAD band purely by declaring
|
|
1110
|
+
// `inclusion: 'Primary'` (`isLeadContribution`, `:313`), and every lead therefore renders
|
|
1111
|
+
// BEFORE Details. With all of these marked Primary, Details sat fourth.
|
|
1112
|
+
//
|
|
1113
|
+
// Reordering `spec.Groups` from a `BaseFormPolicy.DecorateChrome` cannot fix that:
|
|
1114
|
+
// `StabilizeFirstClassGroupOrder` re-imposes the bands, and its own comment says it moves
|
|
1115
|
+
// groups "into the lead band before Details" — so the reorder is silently undone. Only a
|
|
1116
|
+
// user's drag order (`OrderChromeGroups`) outranks the bands, and that is a per-user
|
|
1117
|
+
// preference an app cannot ship.
|
|
1118
|
+
//
|
|
1119
|
+
// Dropping Primary moves these into the `related` band, which sorts DESCENDING by sortKey
|
|
1120
|
+
// (`:753`), so the numbers below are the running order after Details.
|
|
1121
|
+
},
|
|
1122
|
+
})
|
|
1123
|
+
], MJCContractLineagePanel);
|
|
1124
|
+
export { MJCContractLineagePanel };
|
|
1125
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJCContractLineagePanel, [{
|
|
1126
|
+
type: Component,
|
|
1127
|
+
args: [{ selector: 'mjc-contract-lineage-panel', standalone: true, encapsulation: ViewEncapsulation.None, imports: [CommonModule, FormsModule, BaseFormsModule, HierarchyTreeComponent], template: `
|
|
1128
|
+
<mj-collapsible-panel
|
|
1129
|
+
SectionKey="contractLineage"
|
|
1130
|
+
SectionName="Lineage"
|
|
1131
|
+
Icon="fa-solid fa-sitemap"
|
|
1132
|
+
Variant="related-entity"
|
|
1133
|
+
[BadgeCount]="Count"
|
|
1134
|
+
[Form]="FormComponent"
|
|
1135
|
+
[FormContext]="FormContext">
|
|
1136
|
+
|
|
1137
|
+
<div class="mjc-body" [class.mjc-body--flush]="HasChildren">
|
|
1138
|
+
@if (ParentName) {
|
|
1139
|
+
<div class="mjc-body">
|
|
1140
|
+
@if (ParentName) {
|
|
1141
|
+
<p class="mjc-note">
|
|
1142
|
+
This is a change order to <strong>{{ ParentName }}</strong>.
|
|
1143
|
+
</p>
|
|
1144
|
+
}
|
|
1145
|
+
</div>
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
<!-- The parent/child tree is MJ's, not ours: ParentContractID is an ordinary
|
|
1149
|
+
self-referential hierarchy, which is exactly what mj-hierarchy-tree consumes. It
|
|
1150
|
+
loads its own data from the Config, highlights the contract being viewed, and its
|
|
1151
|
+
nodes NAVIGATE — the thing the hand-rolled table could never do. -->
|
|
1152
|
+
<mj-hierarchy-tree
|
|
1153
|
+
[Config]="TreeConfig"
|
|
1154
|
+
[ActiveRecordID]="Record?.ID ?? undefined"
|
|
1155
|
+
(NodeDoubleClick)="OpenNode($event)" />
|
|
1156
|
+
|
|
1157
|
+
@if (!ParentName && !HasChildren) {
|
|
1158
|
+
<div class="mjc-empty">
|
|
1159
|
+
A standalone agreement — nothing above it, no change orders, and nothing has replaced it.
|
|
1160
|
+
</div>
|
|
1161
|
+
}
|
|
1162
|
+
</div>
|
|
1163
|
+
</mj-collapsible-panel>
|
|
1164
|
+
`, styles: ["\n /* A PINNED FLOOR, not a percentage. height:100% cannot work here: it resolves against\n .mj-forms-panel-content, which the variant sets to height:auto, and 100% of auto collapses\n straight back to auto - measured blank. AG Grid escapes this because the grid supplies its\n own intrinsic height; a plain div does not. A px min-height resolves regardless of what the\n parent computes to, and stays under the variant's own 800px cap. */\n /* DIRECT child only. As a descendant selector this also matched the nested .mjc-body wrapper\n inside the panel, so the floor applied twice and left a tall empty block above the tree. */\n mjc-contract-lineage-panel > .mjc-body {\n min-height: 440px;\n overflow-y: auto;\n }\n mjc-contract-lineage-panel mj-hierarchy-tree { display: block; min-height: 380px; }\n "] }]
|
|
1165
|
+
}], null, null); })();
|
|
1166
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJCContractLineagePanel, { className: "MJCContractLineagePanel", filePath: "lib/form-panels/contract.panels.ts", lineNumber: 572 }); })();
|
|
1167
|
+
//# sourceMappingURL=contract.panels.js.map
|