@mj-biz-apps/orders-ng 5.12.0 → 5.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/custom/OrderHeader/order-lines-editor.component.d.ts +21 -0
- package/dist/lib/custom/OrderHeader/order-lines-editor.component.d.ts.map +1 -1
- package/dist/lib/custom/OrderHeader/order-lines-editor.component.js +84 -24
- package/dist/lib/custom/OrderHeader/order-lines-editor.component.js.map +1 -1
- package/dist/lib/custom/Product/product-save-guard-form.component.d.ts +58 -0
- package/dist/lib/custom/Product/product-save-guard-form.component.d.ts.map +1 -0
- package/dist/lib/custom/Product/product-save-guard-form.component.js +360 -0
- package/dist/lib/custom/Product/product-save-guard-form.component.js.map +1 -0
- package/dist/lib/custom/Product/widgets/product-accounting-widget.component.js +2 -2
- package/dist/lib/custom/custom-forms.module.d.ts +25 -24
- package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
- package/dist/lib/custom/custom-forms.module.js +6 -0
- package/dist/lib/custom/custom-forms.module.js.map +1 -1
- package/dist/lib/data/orders-queries.d.ts +37 -1
- package/dist/lib/data/orders-queries.d.ts.map +1 -1
- package/dist/lib/data/orders-queries.js +69 -8
- package/dist/lib/data/orders-queries.js.map +1 -1
- package/dist/lib/form-panels/catalog-overviews.panels.d.ts.map +1 -1
- package/dist/lib/form-panels/catalog-overviews.panels.js +12 -10
- package/dist/lib/form-panels/catalog-overviews.panels.js.map +1 -1
- package/dist/lib/form-panels/product-header.panel.d.ts +6 -1
- package/dist/lib/form-panels/product-header.panel.d.ts.map +1 -1
- package/dist/lib/form-panels/product-header.panel.js +10 -3
- package/dist/lib/form-panels/product-header.panel.js.map +1 -1
- package/dist/lib/pages/catalog/pricing.page.d.ts.map +1 -1
- package/dist/lib/pages/catalog/pricing.page.js +100 -132
- package/dist/lib/pages/catalog/pricing.page.js.map +1 -1
- package/dist/lib/pages/catalog/products.page.d.ts.map +1 -1
- package/dist/lib/pages/catalog/products.page.js +63 -74
- package/dist/lib/pages/catalog/products.page.js.map +1 -1
- package/dist/lib/pages/orders/fulfillment.page.d.ts.map +1 -1
- package/dist/lib/pages/orders/fulfillment.page.js +9 -11
- package/dist/lib/pages/orders/fulfillment.page.js.map +1 -1
- package/dist/lib/pages/orders/order-document.page.d.ts.map +1 -1
- package/dist/lib/pages/orders/order-document.page.js +48 -51
- package/dist/lib/pages/orders/order-document.page.js.map +1 -1
- package/dist/lib/pages/orders/orders-dashboard.page.d.ts.map +1 -1
- package/dist/lib/pages/orders/orders-dashboard.page.js +38 -39
- package/dist/lib/pages/orders/orders-dashboard.page.js.map +1 -1
- package/dist/lib/pages/orders/return.page.d.ts.map +1 -1
- package/dist/lib/pages/orders/return.page.js +78 -100
- package/dist/lib/pages/orders/return.page.js.map +1 -1
- package/dist/lib/pages/payments/account-credit.page.d.ts.map +1 -1
- package/dist/lib/pages/payments/account-credit.page.js +46 -56
- package/dist/lib/pages/payments/account-credit.page.js.map +1 -1
- package/dist/lib/pages/payments/payments-dashboard.page.d.ts.map +1 -1
- package/dist/lib/pages/payments/payments-dashboard.page.js +53 -64
- package/dist/lib/pages/payments/payments-dashboard.page.js.map +1 -1
- package/dist/lib/pages/payments/refund.page.d.ts.map +1 -1
- package/dist/lib/pages/payments/refund.page.js +75 -87
- package/dist/lib/pages/payments/refund.page.js.map +1 -1
- package/dist/lib/pages/receivables/customer-ar.page.d.ts.map +1 -1
- package/dist/lib/pages/receivables/customer-ar.page.js +20 -28
- package/dist/lib/pages/receivables/customer-ar.page.js.map +1 -1
- package/dist/lib/pages/receivables/overdue.page.d.ts +2 -2
- package/dist/lib/pages/receivables/overdue.page.d.ts.map +1 -1
- package/dist/lib/pages/receivables/overdue.page.js +21 -24
- package/dist/lib/pages/receivables/overdue.page.js.map +1 -1
- package/dist/lib/pages/receivables/subscriptions.page.d.ts.map +1 -1
- package/dist/lib/pages/receivables/subscriptions.page.js +62 -87
- package/dist/lib/pages/receivables/subscriptions.page.js.map +1 -1
- package/dist/lib/panels/allocation-grid.component.d.ts.map +1 -1
- package/dist/lib/panels/allocation-grid.component.js +17 -40
- package/dist/lib/panels/allocation-grid.component.js.map +1 -1
- package/dist/lib/panels/chips.component.js +2 -2
- package/dist/lib/panels/chips.component.js.map +1 -1
- package/dist/lib/panels/decomposition-ladder.component.d.ts.map +1 -1
- package/dist/lib/panels/decomposition-ladder.component.js +1 -1
- package/dist/lib/panels/decomposition-ladder.component.js.map +1 -1
- package/dist/lib/panels/journal-entry-preview.component.d.ts +1 -1
- package/dist/lib/panels/journal-entry-preview.component.d.ts.map +1 -1
- package/dist/lib/panels/journal-entry-preview.component.js +28 -32
- package/dist/lib/panels/journal-entry-preview.component.js.map +1 -1
- package/dist/lib/panels/order-stages.js +2 -2
- package/dist/lib/panels/order-stages.js.map +1 -1
- package/dist/lib/panels/product-lookup-names.d.ts +22 -0
- package/dist/lib/panels/product-lookup-names.d.ts.map +1 -0
- package/dist/lib/panels/product-lookup-names.js +41 -0
- package/dist/lib/panels/product-lookup-names.js.map +1 -0
- package/dist/lib/sections/orders-sections.component.js +8 -8
- package/dist/lib/sections/section-nav.model.js +3 -3
- package/dist/lib/sections/section-nav.model.js.map +1 -1
- package/dist/lib/sections/section-shell.component.d.ts +1 -1
- package/dist/lib/sections/section-shell.component.js +1 -1
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +2 -2
|
@@ -26,6 +26,9 @@ export declare class MJOOrderLinesEditorComponent implements OnDestroy {
|
|
|
26
26
|
PricingChanged: EventEmitter<MJOPricingState>;
|
|
27
27
|
Navigate: EventEmitter<FormNavigationEvent>;
|
|
28
28
|
Catalog: MJOProductOption[];
|
|
29
|
+
/** Bumped whenever `Catalog` is replaced, so `PickerResults` knows its cache is stale. */
|
|
30
|
+
private catalogVersion;
|
|
31
|
+
private pickerCache;
|
|
29
32
|
Pricing: MJOPricingState;
|
|
30
33
|
ProductQuery: string;
|
|
31
34
|
PickerCursor: number;
|
|
@@ -41,6 +44,15 @@ export declare class MJOOrderLinesEditorComponent implements OnDestroy {
|
|
|
41
44
|
private readonly customAmountLineIds;
|
|
42
45
|
private readonly defaultUnitByLine;
|
|
43
46
|
get Lines(): mjBizAppsOrdersOrderLineEntity[];
|
|
47
|
+
/**
|
|
48
|
+
* The rows the picker shows, ranked by `RankCatalogMatches`.
|
|
49
|
+
*
|
|
50
|
+
* MEMOISED, and that is not premature. This is a getter the template reads, so Angular calls it
|
|
51
|
+
* on every change-detection pass — and it now ranks the ENTIRE active catalog rather than the
|
|
52
|
+
* first 500 rows, because the 500-row cap is what made products past it unfindable. Re-sorting
|
|
53
|
+
* every product on every keystroke's worth of change detection is the cost of removing the cap;
|
|
54
|
+
* the cache key is the only thing that can change the answer, so nothing goes stale.
|
|
55
|
+
*/
|
|
44
56
|
get PickerResults(): MJOProductOption[];
|
|
45
57
|
OpenPicker(): void;
|
|
46
58
|
OnProductQueryChange(): void;
|
|
@@ -91,6 +103,15 @@ export declare class MJOOrderLinesEditorComponent implements OnDestroy {
|
|
|
91
103
|
private dateInputValue;
|
|
92
104
|
Remove(line: mjBizAppsOrdersOrderLineEntity): void;
|
|
93
105
|
ProductFor(line: mjBizAppsOrdersOrderLineEntity): MJOProductOption | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* True when this product belongs to a different company than the order's selling company.
|
|
108
|
+
*
|
|
109
|
+
* Selling another company's product is INTENDED — BCC sells SoundPost products — so this marks
|
|
110
|
+
* a row, it never hides one. It is the same test for a picker row and for a line already added,
|
|
111
|
+
* which is the point of it being one function: the label a user chose by must still be there
|
|
112
|
+
* after they chose it.
|
|
113
|
+
*/
|
|
114
|
+
IsForeignCompany(product: MJOProductOption): boolean;
|
|
94
115
|
/** True when the line books to a different company than the order's selling company. */
|
|
95
116
|
ShowsForeignRevenue(line: mjBizAppsOrdersOrderLineEntity): boolean;
|
|
96
117
|
PricedLine(line: mjBizAppsOrdersOrderLineEntity): MJOLinePrice | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"order-lines-editor.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/custom/OrderHeader/order-lines-editor.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,YAAY,EAAS,SAAS,EAA6B,MAAM,eAAe,CAAC;AAGpI,OAAO,EACH,UAAU,EAIV,KAAK,iBAAiB,EAEzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACH,iBAAiB,EAEjB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAC3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACH,iBAAiB,EAUjB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,8BAA8B,EACtC,MAAM,8BAA8B,CAAC;AAItC,OAAO,
|
|
1
|
+
{"version":3,"file":"order-lines-editor.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/custom/OrderHeader/order-lines-editor.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,YAAY,EAAS,SAAS,EAA6B,MAAM,eAAe,CAAC;AAGpI,OAAO,EACH,UAAU,EAIV,KAAK,iBAAiB,EAEzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACH,iBAAiB,EAEjB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAC3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACH,iBAAiB,EAUjB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,8BAA8B,EACtC,MAAM,8BAA8B,CAAC;AAItC,OAAO,EAKH,KAAK,gBAAgB,EACxB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAuB,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,0CAA0C,CAAC;;AAiBxH;;;;;;;;GAQG;AACH,qBAca,4BAA6B,YAAW,SAAS;IAC1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA6B;IAEjD,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IAErC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAC1C,QAAQ,UAAQ;IAEhC,IACW,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,EAI/C;IACD,IAAW,KAAK,IAAI,iBAAiB,GAAG,IAAI,CAE3C;IAEgB,cAAc,gCAAuC;IACrD,QAAQ,oCAA2C;IAE7D,OAAO,EAAE,gBAAgB,EAAE,CAAM;IACxC,0FAA0F;IAC1F,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,WAAW,CAA6D;IACzE,OAAO,EAAE,eAAe,CAAiD;IACzE,YAAY,SAAM;IAClB,YAAY,SAAK;IACjB,UAAU,UAAS;IAC1B,mFAAmF;IAC5E,aAAa,UAAS;IACtB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IACjB,OAAO,CAAC,UAAU,CAAC,CAA0B;IACtE,wFAAwF;IACjF,YAAY,EAAE,iBAAiB,CAAU;IAChD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAwC;IACzE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAqB;IAC3D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoC;IAEtE,IAAW,KAAK,IAAI,8BAA8B,EAAE,CAEnD;IAED;;;;;;;;OAQG;IACH,IAAW,aAAa,IAAI,gBAAgB,EAAE,CAc7C;IAEM,UAAU,IAAI,IAAI;IAMlB,oBAAoB,IAAI,IAAI;IAQ5B,eAAe,IAAI,IAAI;IAQvB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAyBjC,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D,IAAI,CAAC,IAAI,EAAE,8BAA8B,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAO/D,WAAW,CAAC,IAAI,EAAE,8BAA8B,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IASrE,aAAa,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO;IAK5D,mBAAmB,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO;IAelE,kBAAkB,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO;IAIxE;;;;OAIG;IACI,cAAc,CAAC,IAAI,EAAE,8BAA8B,GAAG,MAAM;IAInE,yFAAyF;IAClF,yBAAyB,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO;IAsB/E,iGAAiG;IACjG,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAkC;IACrE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAqB;IAE1D;;;;;;OAMG;IACI,oBAAoB,CAAC,IAAI,EAAE,8BAA8B,GAAG,IAAI,GAAG,IAAI;IAW9E;;;;;;;;OAQG;IACI,mBAAmB,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO;IAIzE,wDAAwD;IACjD,sBAAsB,CAAC,IAAI,EAAE,8BAA8B,GAAG,MAAM;YAI7D,gBAAgB;IAoBvB,YAAY,CAAC,IAAI,EAAE,8BAA8B,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAwB7E,uFAAuF;IAChF,cAAc,CAAC,IAAI,EAAE,8BAA8B,GAAG,IAAI;IAKjE,kEAAkE;IAClE,OAAO,CAAC,cAAc;IAMf,MAAM,CAAC,IAAI,EAAE,8BAA8B,GAAG,IAAI;IASlD,UAAU,CAAC,IAAI,EAAE,8BAA8B,GAAG,gBAAgB,GAAG,SAAS;IAIrF;;;;;;;OAOG;IACI,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;IAS3D,wFAAwF;IACjF,mBAAmB,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO;IAKlE,UAAU,CAAC,IAAI,EAAE,8BAA8B,GAAG,YAAY,GAAG,SAAS;IAIjF,IAAW,WAAW,IAAI,OAAO,CAEhC;IAEM,aAAa,CAAC,IAAI,EAAE,8BAA8B,GAAG,eAAe,EAAE;IAItE,eAAe,CAAC,IAAI,EAAE,8BAA8B,GAAG,MAAM;IAO7D,WAAW,CAAC,IAAI,EAAE,8BAA8B,GAAG,MAAM,GAAG,IAAI;IAKvE;;;;;;;;;OASG;IACI,YAAY,CAAC,IAAI,EAAE,8BAA8B,GAAG,MAAM;IAU1D,gBAAgB,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO;IAI/D,kBAAkB,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO;IAYjE,WAAW,CAAC,IAAI,EAAE,8BAA8B,GAAG,MAAM,GAAG,IAAI;IAKhE,cAAc,CAAC,IAAI,EAAE,8BAA8B,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IA0BxE,UAAU,CAAC,IAAI,EAAE,8BAA8B,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAapE,oBAAoB,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO;IAInE,oBAAoB,CAAC,IAAI,EAAE,8BAA8B,GAAG,IAAI;IAahE,kBAAkB,CAAC,IAAI,EAAE,8BAA8B,GAAG,IAAI;IAI9D,aAAa,CAAC,IAAI,EAAE,8BAA8B,GAAG,IAAI;IAOzD,YAAY,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO;IAM3D,kBAAkB,CAAC,IAAI,EAAE,8BAA8B,GAAG,MAAM;IAKhE,iBAAiB,CAAC,IAAI,EAAE,8BAA8B,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAS3E,WAAW,CAAC,IAAI,EAAE,8BAA8B,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAWrE,mBAAmB,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAIrD,sBAAsB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAK5D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IAE/C,YAAY,CAAC,IAAI,EAAE,8BAA8B,GAAG,UAAU,GAAG,IAAI;IAsBrE,sBAAsB,CAAC,IAAI,EAAE,8BAA8B,GAAG,gBAAgB;IAI9E,eAAe,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO;IAI9D,eAAe,CAAC,IAAI,EAAE,8BAA8B,GAAG,IAAI;IAK3D,cAAc,CAAC,IAAI,EAAE,8BAA8B,GAAG,MAAM;IAI5D,aAAa,CAAC,IAAI,EAAE,8BAA8B,GAAG,MAAM;IAI3D,WAAW,IAAI,IAAI;IAK1B,OAAO,KAAK,QAAQ,GAEnB;YAEa,YAAY;IAY1B,OAAO,CAAC,WAAW;YAaL,YAAY;YAOZ,eAAe;YAUf,iBAAiB;YAYjB,iBAAiB;IAe/B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,mBAAmB;YAQb,WAAW;IAWzB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,cAAc;YAIR,mBAAmB;YAQnB,yBAAyB;YAuBzB,oBAAoB;YAMpB,iBAAiB;yCAzuBtB,4BAA4B;2CAA5B,4BAA4B;CA8wBxC"}
|
|
@@ -8,7 +8,7 @@ import { OrderLineEntity, ClampLineQuantity, ListApplicablePrices, LoadOrdersEng
|
|
|
8
8
|
import { MJOConsequenceChipComponent, MJOPriceSourceBadgeComponent } from '../../panels/chips.component.js';
|
|
9
9
|
import { FormatMoney, MJOMoneyPipe } from '../../panels/money-format.js';
|
|
10
10
|
import { MJO_ENTITIES } from '../../data/entity-names.js';
|
|
11
|
-
import { ContinuationStartFrom, GetCatalogOptions, GetSubscriptionContinuation, } from '../../data/orders-queries.js';
|
|
11
|
+
import { ContinuationStartFrom, GetCatalogOptions, GetSubscriptionContinuation, RankCatalogMatches, } from '../../data/orders-queries.js';
|
|
12
12
|
import { MJOPricingScheduler } from '../../services/pricing-scheduler.service.js';
|
|
13
13
|
import { ExtensionCollapsedHint, ExtensionToggleLabel, } from './line-extension-fields.js';
|
|
14
14
|
import { CachedExtensionEntityInfo, CachedExtensionFormConfig } from './line-extension-cache.js';
|
|
@@ -410,6 +410,19 @@ function MJOOrderLinesEditorComponent_ForEmpty_3_Template(rf, ctx) { if (rf & 1)
|
|
|
410
410
|
i0.ɵɵtext(5, "Search the catalog to add the first line.");
|
|
411
411
|
i0.ɵɵelementEnd()();
|
|
412
412
|
} }
|
|
413
|
+
function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
414
|
+
i0.ɵɵelementStart(0, "span", 79);
|
|
415
|
+
i0.ɵɵelement(1, "i", 80);
|
|
416
|
+
i0.ɵɵtext(2);
|
|
417
|
+
i0.ɵɵelementEnd();
|
|
418
|
+
} if (rf & 2) {
|
|
419
|
+
const product_r16 = i0.ɵɵnextContext().$implicit;
|
|
420
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
421
|
+
i0.ɵɵclassProp("is-foreign", ctx_r2.IsForeignCompany(product_r16));
|
|
422
|
+
i0.ɵɵattribute("title", ctx_r2.IsForeignCompany(product_r16) ? "Sold by " + product_r16.CompanyName + ", not this order's company" : product_r16.CompanyName);
|
|
423
|
+
i0.ɵɵadvance(2);
|
|
424
|
+
i0.ɵɵtextInterpolate1(" ", product_r16.CompanyName, " ");
|
|
425
|
+
} }
|
|
413
426
|
function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
414
427
|
const _r15 = i0.ɵɵgetCurrentView();
|
|
415
428
|
i0.ɵɵelementStart(0, "button", 71);
|
|
@@ -417,15 +430,17 @@ function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Template
|
|
|
417
430
|
i0.ɵɵelementStart(1, "span", 72)(2, "span", 73);
|
|
418
431
|
i0.ɵɵtext(3);
|
|
419
432
|
i0.ɵɵelementEnd();
|
|
420
|
-
i0.ɵɵelementStart(4, "span", 74);
|
|
421
|
-
i0.ɵɵtext(
|
|
433
|
+
i0.ɵɵelementStart(4, "span", 74)(5, "span", 75);
|
|
434
|
+
i0.ɵɵtext(6);
|
|
435
|
+
i0.ɵɵelementEnd();
|
|
436
|
+
i0.ɵɵconditionalCreate(7, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Conditional_7_Template, 3, 4, "span", 76);
|
|
422
437
|
i0.ɵɵelementEnd()();
|
|
423
|
-
i0.ɵɵelementStart(
|
|
424
|
-
i0.ɵɵtext(
|
|
425
|
-
i0.ɵɵpipe(
|
|
438
|
+
i0.ɵɵelementStart(8, "span", 77)(9, "span", 78);
|
|
439
|
+
i0.ɵɵtext(10);
|
|
440
|
+
i0.ɵɵpipe(11, "mjoMoney");
|
|
426
441
|
i0.ɵɵelementEnd();
|
|
427
|
-
i0.ɵɵelementStart(
|
|
428
|
-
i0.ɵɵtext(
|
|
442
|
+
i0.ɵɵelementStart(12, "span", 75);
|
|
443
|
+
i0.ɵɵtext(13);
|
|
429
444
|
i0.ɵɵelementEnd()()();
|
|
430
445
|
} if (rf & 2) {
|
|
431
446
|
const product_r16 = ctx.$implicit;
|
|
@@ -435,10 +450,12 @@ function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Template
|
|
|
435
450
|
i0.ɵɵattribute("aria-selected", ɵ$index_194_r17 === ctx_r2.PickerCursor);
|
|
436
451
|
i0.ɵɵadvance(3);
|
|
437
452
|
i0.ɵɵtextInterpolate(product_r16.Name);
|
|
438
|
-
i0.ɵɵadvance(2);
|
|
439
|
-
i0.ɵɵtextInterpolate3("", product_r16.SKU, " \u00B7 ", product_r16.TypeName, " \u00B7 ", product_r16.CompanyName);
|
|
440
453
|
i0.ɵɵadvance(3);
|
|
441
|
-
i0.ɵɵ
|
|
454
|
+
i0.ɵɵtextInterpolate2("", product_r16.SKU, " \u00B7 ", product_r16.TypeName);
|
|
455
|
+
i0.ɵɵadvance();
|
|
456
|
+
i0.ɵɵconditional(product_r16.CompanyName ? 7 : -1);
|
|
457
|
+
i0.ɵɵadvance(3);
|
|
458
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(11, 9, product_r16.ListPrice));
|
|
442
459
|
i0.ɵɵadvance(3);
|
|
443
460
|
i0.ɵɵtextInterpolate(product_r16.Taxable ? "taxable" : "untaxable");
|
|
444
461
|
} }
|
|
@@ -455,7 +472,7 @@ function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Con
|
|
|
455
472
|
i0.ɵɵtext(0, " No product matches that. ");
|
|
456
473
|
} }
|
|
457
474
|
function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Template(rf, ctx) { if (rf & 1) {
|
|
458
|
-
i0.ɵɵelementStart(0, "div", 70)(1, "span",
|
|
475
|
+
i0.ɵɵelementStart(0, "div", 70)(1, "span", 81);
|
|
459
476
|
i0.ɵɵconditionalCreate(2, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Conditional_2_Template, 1, 1)(3, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Conditional_3_Template, 1, 0)(4, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Conditional_4_Template, 1, 0);
|
|
460
477
|
i0.ɵɵelementEnd()();
|
|
461
478
|
} if (rf & 2) {
|
|
@@ -465,7 +482,7 @@ function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Tem
|
|
|
465
482
|
} }
|
|
466
483
|
function MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
467
484
|
i0.ɵɵelementStart(0, "div", 68);
|
|
468
|
-
i0.ɵɵrepeaterCreate(1, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Template,
|
|
485
|
+
i0.ɵɵrepeaterCreate(1, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_For_2_Template, 14, 11, "button", 69, _forTrack0, false, MJOOrderLinesEditorComponent_Conditional_4_Conditional_5_ForEmpty_3_Template, 5, 1, "div", 70);
|
|
469
486
|
i0.ɵɵelementEnd();
|
|
470
487
|
} if (rf & 2) {
|
|
471
488
|
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
@@ -491,6 +508,14 @@ function MJOOrderLinesEditorComponent_Conditional_4_Template(rf, ctx) { if (rf &
|
|
|
491
508
|
i0.ɵɵadvance();
|
|
492
509
|
i0.ɵɵconditional(ctx_r2.PickerOpen ? 5 : -1);
|
|
493
510
|
} }
|
|
511
|
+
/**
|
|
512
|
+
* How many catalog rows the picker offers at once.
|
|
513
|
+
*
|
|
514
|
+
* The list is capped for the READER, not for the search — the search runs over the whole active
|
|
515
|
+
* catalog. Bounded because the drop-down scrolls inside 240px and a list nobody scrolls to the end
|
|
516
|
+
* of is a list that stopped helping; the ranking is what puts the right row inside this window.
|
|
517
|
+
*/
|
|
518
|
+
const PICKER_RESULT_LIMIT = 12;
|
|
494
519
|
/**
|
|
495
520
|
* Inline catalog picker + line cards for an order header.
|
|
496
521
|
*
|
|
@@ -519,6 +544,9 @@ export class MJOOrderLinesEditorComponent {
|
|
|
519
544
|
PricingChanged = new EventEmitter();
|
|
520
545
|
Navigate = new EventEmitter();
|
|
521
546
|
Catalog = [];
|
|
547
|
+
/** Bumped whenever `Catalog` is replaced, so `PickerResults` knows its cache is stale. */
|
|
548
|
+
catalogVersion = 0;
|
|
549
|
+
pickerCache = null;
|
|
522
550
|
Pricing = { Result: null, Loading: false, Error: null };
|
|
523
551
|
ProductQuery = '';
|
|
524
552
|
PickerCursor = 0;
|
|
@@ -536,10 +564,26 @@ export class MJOOrderLinesEditorComponent {
|
|
|
536
564
|
get Lines() {
|
|
537
565
|
return [...(this._order?.Lines.Items ?? [])];
|
|
538
566
|
}
|
|
567
|
+
/**
|
|
568
|
+
* The rows the picker shows, ranked by `RankCatalogMatches`.
|
|
569
|
+
*
|
|
570
|
+
* MEMOISED, and that is not premature. This is a getter the template reads, so Angular calls it
|
|
571
|
+
* on every change-detection pass — and it now ranks the ENTIRE active catalog rather than the
|
|
572
|
+
* first 500 rows, because the 500-row cap is what made products past it unfindable. Re-sorting
|
|
573
|
+
* every product on every keystroke's worth of change detection is the cost of removing the cap;
|
|
574
|
+
* the cache key is the only thing that can change the answer, so nothing goes stale.
|
|
575
|
+
*/
|
|
539
576
|
get PickerResults() {
|
|
540
|
-
const
|
|
541
|
-
const
|
|
542
|
-
|
|
577
|
+
const query = this.ProductQuery.trim().toLowerCase();
|
|
578
|
+
const companyID = String(this._order?.CompanyID ?? '');
|
|
579
|
+
const key = `${this.catalogVersion}|${companyID}|${query}`;
|
|
580
|
+
if (this.pickerCache?.Key !== key) {
|
|
581
|
+
this.pickerCache = {
|
|
582
|
+
Key: key,
|
|
583
|
+
Results: RankCatalogMatches(this.Catalog, query, companyID || null).slice(0, PICKER_RESULT_LIMIT),
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
return this.pickerCache.Results;
|
|
543
587
|
}
|
|
544
588
|
OpenPicker() {
|
|
545
589
|
this.PickerOpen = true;
|
|
@@ -547,6 +591,10 @@ export class MJOOrderLinesEditorComponent {
|
|
|
547
591
|
this.updatePickerFlip();
|
|
548
592
|
}
|
|
549
593
|
OnProductQueryChange() {
|
|
594
|
+
// Back to the top on every edit. The list is RANKED now, so row 0 is the best match for what
|
|
595
|
+
// was just typed — leaving the cursor where it was points it at whatever happens to occupy
|
|
596
|
+
// that position in a different result set, which is what Enter would then add.
|
|
597
|
+
this.PickerCursor = 0;
|
|
550
598
|
if (this.PickerOpen)
|
|
551
599
|
this.updatePickerFlip();
|
|
552
600
|
}
|
|
@@ -769,10 +817,16 @@ export class MJOOrderLinesEditorComponent {
|
|
|
769
817
|
ProductFor(line) {
|
|
770
818
|
return this.Catalog.find((p) => UUIDsEqual(p.ID, line.ProductID));
|
|
771
819
|
}
|
|
772
|
-
/**
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
820
|
+
/**
|
|
821
|
+
* True when this product belongs to a different company than the order's selling company.
|
|
822
|
+
*
|
|
823
|
+
* Selling another company's product is INTENDED — BCC sells SoundPost products — so this marks
|
|
824
|
+
* a row, it never hides one. It is the same test for a picker row and for a line already added,
|
|
825
|
+
* which is the point of it being one function: the label a user chose by must still be there
|
|
826
|
+
* after they chose it.
|
|
827
|
+
*/
|
|
828
|
+
IsForeignCompany(product) {
|
|
829
|
+
if (!product.CompanyName)
|
|
776
830
|
return false;
|
|
777
831
|
const sellingID = this._order?.CompanyID;
|
|
778
832
|
if (product.CompanyID && sellingID)
|
|
@@ -782,6 +836,11 @@ export class MJOOrderLinesEditorComponent {
|
|
|
782
836
|
return true;
|
|
783
837
|
return product.CompanyName.trim().toLowerCase() !== String(sellingName).trim().toLowerCase();
|
|
784
838
|
}
|
|
839
|
+
/** True when the line books to a different company than the order's selling company. */
|
|
840
|
+
ShowsForeignRevenue(line) {
|
|
841
|
+
const product = this.ProductFor(line);
|
|
842
|
+
return product ? this.IsForeignCompany(product) : false;
|
|
843
|
+
}
|
|
785
844
|
PricedLine(line) {
|
|
786
845
|
return this.Pricing.Result?.Lines.find((priced) => UUIDsEqual(priced.ClientKey, line.ID));
|
|
787
846
|
}
|
|
@@ -1087,6 +1146,7 @@ export class MJOOrderLinesEditorComponent {
|
|
|
1087
1146
|
this.Catalog = [];
|
|
1088
1147
|
this.CatalogError = error instanceof Error ? error.message : String(error);
|
|
1089
1148
|
}
|
|
1149
|
+
this.catalogVersion++;
|
|
1090
1150
|
}
|
|
1091
1151
|
updatePickerFlip() {
|
|
1092
1152
|
// Measure after the list is in the DOM so max-height (240px) is the right budget.
|
|
@@ -1222,7 +1282,7 @@ export class MJOOrderLinesEditorComponent {
|
|
|
1222
1282
|
} if (rf & 2) {
|
|
1223
1283
|
let _t;
|
|
1224
1284
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.pickerHost = _t.first);
|
|
1225
|
-
} }, inputs: { Provider: "Provider", EditMode: "EditMode", Order: "Order" }, outputs: { PricingChanged: "PricingChanged", Navigate: "Navigate" }, decls: 5, vars: 2, consts: [["pickerHost", ""], [1, "mjo-ol"], [1, "mjo-ol-card"], [1, "mjo-ol-empty"], [1, "mj-typeahead", "mjo-ol-picker"], [1, "mjo-ol-card__top"], [1, "mjo-ol-card__id"], ["type", "button", 1, "mjo-ol-card__name", 3, "click"], [1, "mjo-ol-card__meta"], [1, "mjo-ol-qty"], [1, "mjo-ol-qty__value"], [1, "mjo-ol-card__price"], [1, "mjo-ol-card__price-row"], [1, "mjo-ol-card__amt"], ["type", "button", 1, "mjo-ol-iconbtn", "mjo-ol-price__pencil"], [1, "mjo-ol-overpill"], [3, "Source", "Settled", "Overridden"], [1, "mjo-ol-card__err"], [1, "mjo-ol-card__tot"], ["type", "button", 1, "mjo-ol-iconbtn"], ["role", "region", 1, "mjo-ol-override"], [1, "mjo-ol-card__conseq"], [1, "mjo-ol-card__why"], [1, "mjo-ol-term"], [1, "mjo-ol-ext", 3, "is-open"], ["type", "button", "aria-label", "Decrease quantity", 3, "click"], ["aria-label", "Quantity", 3, "change", "value"], ["type", "button", "aria-label", "Increase quantity", 3, "click", "disabled"], ["type", "button", 1, "mjo-ol-iconbtn", "mjo-ol-price__pencil", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-pencil"], ["type", "button", 1, "mjo-ol-iconbtn", 3, "click"], ["aria-hidden", "true", 1, "fa-regular", "fa-trash-can"], [1, "mjo-ol-override__row"], ["aria-label", "Named price", 1, "mjo-ol-price__pick", 3, "change", "value"], ["value", ""], ["value", "__custom__"], [3, "value"], ["type", "number", "step", "0.01", "min", "0", "aria-label", "Custom unit price", 1, "mjo-ol-price__amt", 3, "value"], [1, "mjo-ol-override__reason"], ["rows", "2", "placeholder", "Optional \u2014 why this price differs from the default", 3, "input", "disabled", "value"], [1, "mjo-ol-override__actions"], ["type", "button", 1, "mjo-ol-override__done", 3, "click"], ["type", "button", 1, "mjo-ol-override__reset", 3, "click"], ["type", "number", "step", "0.01", "min", "0", "aria-label", "Custom unit price", 1, "mjo-ol-price__amt", 3, "change", "value"], ["Kind", "fulfillment"], ["Kind", "untaxable"], ["Kind", "company"], [1, "mjo-ol-term__label"], [1, "mjo-ol-term__value", "is-dictated"], [1, "mjo-ol-term__value"], [1, "mjo-ol-term__hint"], ["type", "date", 1, "mjo-ol-term__input", 3, "change", "id", "value"], ["type", "button", 1, "mjo-ol-term__reset"], ["type", "button", 1, "mjo-ol-term__reset", 3, "click"], [1, "mjo-ol-ext"], ["type", "button", 1, "mjo-ol-ext__toggle", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-right", "mjo-ol-ext__chev"], [1, "mjo-ol-ext__label"], [1, "mjo-ol-ext__hint"], [1, "mjo-ol-ext__body", 3, "id"], [1, "mjo-ol-ext__clip"], [3, "FormCreated", "Navigate", "Record", "EditMode", "Config"], ["aria-hidden", "true", 1, "fa-solid", "fa-cart-plus"], [1, "mjo-ol-empty__title"], [1, "mjo-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-plus"], ["placeholder", "Add product \u2014 type a name or SKU\u2026", "autocomplete", "off", "role", "combobox", "aria-label", "Add a product", 3, "ngModelChange", "focus", "blur", "keydown", "ngModel"], ["role", "listbox", 1, "mj-typeahead-list", "is-open", 3, "is-up"], ["role", "listbox", 1, "mj-typeahead-list", "is-open"], ["type", "button", "role", "option", 1, "mj-typeahead-item", "mjo-ol-pick", 3, "is-cursor"], [1, "mj-typeahead-item"], ["type", "button", "role", "option", 1, "mj-typeahead-item", "mjo-ol-pick", 3, "mousedown"], [1, "mjo-ol-pick__body"], [1, "name"], [1, "sub"], [1, "end"], [1, "mjo-ol-pick__price"], [1, "muted", "small"]], template: function MJOOrderLinesEditorComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1285
|
+
} }, inputs: { Provider: "Provider", EditMode: "EditMode", Order: "Order" }, outputs: { PricingChanged: "PricingChanged", Navigate: "Navigate" }, decls: 5, vars: 2, consts: [["pickerHost", ""], [1, "mjo-ol"], [1, "mjo-ol-card"], [1, "mjo-ol-empty"], [1, "mj-typeahead", "mjo-ol-picker"], [1, "mjo-ol-card__top"], [1, "mjo-ol-card__id"], ["type", "button", 1, "mjo-ol-card__name", 3, "click"], [1, "mjo-ol-card__meta"], [1, "mjo-ol-qty"], [1, "mjo-ol-qty__value"], [1, "mjo-ol-card__price"], [1, "mjo-ol-card__price-row"], [1, "mjo-ol-card__amt"], ["type", "button", 1, "mjo-ol-iconbtn", "mjo-ol-price__pencil"], [1, "mjo-ol-overpill"], [3, "Source", "Settled", "Overridden"], [1, "mjo-ol-card__err"], [1, "mjo-ol-card__tot"], ["type", "button", 1, "mjo-ol-iconbtn"], ["role", "region", 1, "mjo-ol-override"], [1, "mjo-ol-card__conseq"], [1, "mjo-ol-card__why"], [1, "mjo-ol-term"], [1, "mjo-ol-ext", 3, "is-open"], ["type", "button", "aria-label", "Decrease quantity", 3, "click"], ["aria-label", "Quantity", 3, "change", "value"], ["type", "button", "aria-label", "Increase quantity", 3, "click", "disabled"], ["type", "button", 1, "mjo-ol-iconbtn", "mjo-ol-price__pencil", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-pencil"], ["type", "button", 1, "mjo-ol-iconbtn", 3, "click"], ["aria-hidden", "true", 1, "fa-regular", "fa-trash-can"], [1, "mjo-ol-override__row"], ["aria-label", "Named price", 1, "mjo-ol-price__pick", 3, "change", "value"], ["value", ""], ["value", "__custom__"], [3, "value"], ["type", "number", "step", "0.01", "min", "0", "aria-label", "Custom unit price", 1, "mjo-ol-price__amt", 3, "value"], [1, "mjo-ol-override__reason"], ["rows", "2", "placeholder", "Optional \u2014 why this price differs from the default", 3, "input", "disabled", "value"], [1, "mjo-ol-override__actions"], ["type", "button", 1, "mjo-ol-override__done", 3, "click"], ["type", "button", 1, "mjo-ol-override__reset", 3, "click"], ["type", "number", "step", "0.01", "min", "0", "aria-label", "Custom unit price", 1, "mjo-ol-price__amt", 3, "change", "value"], ["Kind", "fulfillment"], ["Kind", "untaxable"], ["Kind", "company"], [1, "mjo-ol-term__label"], [1, "mjo-ol-term__value", "is-dictated"], [1, "mjo-ol-term__value"], [1, "mjo-ol-term__hint"], ["type", "date", 1, "mjo-ol-term__input", 3, "change", "id", "value"], ["type", "button", 1, "mjo-ol-term__reset"], ["type", "button", 1, "mjo-ol-term__reset", 3, "click"], [1, "mjo-ol-ext"], ["type", "button", 1, "mjo-ol-ext__toggle", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-right", "mjo-ol-ext__chev"], [1, "mjo-ol-ext__label"], [1, "mjo-ol-ext__hint"], [1, "mjo-ol-ext__body", 3, "id"], [1, "mjo-ol-ext__clip"], [3, "FormCreated", "Navigate", "Record", "EditMode", "Config"], ["aria-hidden", "true", 1, "fa-solid", "fa-cart-plus"], [1, "mjo-ol-empty__title"], [1, "mjo-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-plus"], ["placeholder", "Add product \u2014 type a name or SKU\u2026", "autocomplete", "off", "role", "combobox", "aria-label", "Add a product", 3, "ngModelChange", "focus", "blur", "keydown", "ngModel"], ["role", "listbox", 1, "mj-typeahead-list", "is-open", 3, "is-up"], ["role", "listbox", 1, "mj-typeahead-list", "is-open"], ["type", "button", "role", "option", 1, "mj-typeahead-item", "mjo-ol-pick", 3, "is-cursor"], [1, "mj-typeahead-item"], ["type", "button", "role", "option", 1, "mj-typeahead-item", "mjo-ol-pick", 3, "mousedown"], [1, "mjo-ol-pick__body"], [1, "name"], [1, "mjo-ol-pick__meta"], [1, "sub"], [1, "mjo-ol-pick__company", 3, "is-foreign"], [1, "end"], [1, "mjo-ol-pick__price"], [1, "mjo-ol-pick__company"], ["aria-hidden", "true", 1, "fa-solid", "fa-building"], [1, "muted", "small"]], template: function MJOOrderLinesEditorComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1226
1286
|
i0.ɵɵelementStart(0, "div", 1);
|
|
1227
1287
|
i0.ɵɵrepeaterCreate(1, MJOOrderLinesEditorComponent_For_2_Template, 30, 21, "div", 2, _forTrack0, false, MJOOrderLinesEditorComponent_ForEmpty_3_Template, 6, 0, "div", 3);
|
|
1228
1288
|
i0.ɵɵconditionalCreate(4, MJOOrderLinesEditorComponent_Conditional_4_Template, 6, 3, "div", 4);
|
|
@@ -1235,7 +1295,7 @@ export class MJOOrderLinesEditorComponent {
|
|
|
1235
1295
|
} }, dependencies: [CommonModule,
|
|
1236
1296
|
FormsModule, i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, BaseFormsModule, i2.MjEntityFormHostComponent, MJOConsequenceChipComponent,
|
|
1237
1297
|
MJOPriceSourceBadgeComponent,
|
|
1238
|
-
MJOMoneyPipe], styles: ["[_nghost-%COMP%] { display: block; }\n\n.mjo-ol[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-card[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-md);\n padding: var(--mj-space-3);\n}\n\n.mjo-ol-card[_ngcontent-%COMP%]:has(.mjo-ol-ext.is-open) {\n padding-bottom: var(--mj-space-1);\n}\n\n.mjo-ol-card__top[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n}\n\n.mjo-ol-card__id[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.mjo-ol-card__name[_ngcontent-%COMP%] {\n display: inline;\n padding: 0;\n border: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-link);\n text-align: left;\n cursor: pointer;\n text-decoration: none;\n}\n\n.mjo-ol-card__name[_ngcontent-%COMP%]:hover { text-decoration: underline; }\n\n.mjo-ol-card__meta[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n background: var(--mj-bg-surface);\n flex: none;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-secondary);\n width: 26px;\n height: 28px;\n font-size: 11px;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:disabled {\n cursor: default;\n color: var(--mj-text-disabled);\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n background: transparent;\n width: 46px;\n text-align: center;\n font: inherit;\n font-variant-numeric: tabular-nums;\n color: inherit;\n}\n\n.mjo-ol-qty.is-locked[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n background: transparent;\n}\n\n.mjo-ol-qty__value[_ngcontent-%COMP%] {\n min-width: 46px;\n padding: 0 10px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-card__price[_ngcontent-%COMP%] {\n flex: none;\n min-width: 108px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.mjo-ol-card__price-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 2px;\n height: 28px;\n}\n\n.mjo-ol-price__pencil[_ngcontent-%COMP%] {\n flex: none;\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-price__pencil[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-link);\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-price__pick[_ngcontent-%COMP%], \n.mjo-ol-price__amt[_ngcontent-%COMP%], \n.mjo-ol-override__reason[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n box-sizing: border-box;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-price__pick[_ngcontent-%COMP%] {\n height: 28px;\n padding: 0 6px;\n text-align: left;\n flex: 1 1 180px;\n max-width: 240px;\n width: auto;\n}\n\n.mjo-ol-price__amt[_ngcontent-%COMP%] {\n height: 28px;\n padding: 0 8px;\n text-align: right;\n font-weight: var(--mj-font-semibold);\n width: 108px;\n flex: none;\n}\n\n.mjo-ol-override[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n padding: var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-override__reason[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: block;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n\n.mjo-ol-override__reason.is-off[_ngcontent-%COMP%] {\n opacity: 0.55;\n}\n\n.mjo-ol-override__reason[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]:disabled {\n cursor: not-allowed;\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__reason[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 48px;\n padding: 6px 8px;\n text-align: left;\n font-variant-numeric: normal;\n}\n\n.mjo-ol-override__actions[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-2);\n justify-content: flex-end;\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%], \n.mjo-ol-override__reset[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n cursor: pointer;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n padding: 4px 8px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%] {\n color: var(--mj-text-link);\n}\n\n.mjo-ol-override__reset[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%]:hover, \n.mjo-ol-override__reset[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-card__amt[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-overpill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-status-warning-text);\n background: color-mix(in srgb, var(--mj-status-warning-text) 16%, transparent);\n}\n\n.mjo-ol-card__err[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n margin-top: 2px;\n}\n\n.mjo-ol-card__tot[_ngcontent-%COMP%] {\n flex: none;\n min-width: 104px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n text-align: right;\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-iconbtn[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-iconbtn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-status-error);\n}\n\n.mjo-ol-card__conseq[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n\n\n\n.mjo-ol-term[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n.mjo-ol-term__label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__input[_ngcontent-%COMP%] {\n height: 28px;\n padding: 0 var(--mj-space-2);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: var(--mj-text-sm);\n}\n\n\n\n\n.mjo-ol-term__input.is-default[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__value[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n}\n\n\n\n\n.mjo-ol-term__value.is-dictated[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__reset[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n padding: 0;\n color: var(--mj-text-link);\n font-size: var(--mj-text-xs);\n cursor: pointer;\n}\n\n.mjo-ol-term__reset[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.mjo-ol-term__hint[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-card__why[_ngcontent-%COMP%] {\n margin-top: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n line-height: 1.35;\n}\n\n.mjo-ol-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-1);\n padding: var(--mj-space-4) var(--mj-space-3);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n text-align: center;\n}\n\n.mjo-ol-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-2xl);\n color: var(--mj-brand-primary);\n}\n\n.mjo-ol-empty__title[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-picker[_ngcontent-%COMP%] {\n position: relative;\n z-index: 20;\n}\n\n.mjo-ol-picker[_ngcontent-%COMP%]:has(.mj-typeahead-list.is-open) {\n z-index: 40;\n}\n\n.mjo-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n padding: 8px 10px;\n}\n\n.mjo-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-text-muted); font-size: 12px; }\n\n.mjo-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n color: inherit;\n width: 100%;\n}\n\n.mj-typeahead-list[_ngcontent-%COMP%] {\n display: none;\n position: absolute;\n left: 0;\n right: 0;\n top: calc(100% + 4px);\n max-height: 240px;\n overflow: auto;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md, 0 8px 24px rgba(0, 0, 0, 0.18));\n z-index: 30;\n}\n\n.mj-typeahead-list.is-open[_ngcontent-%COMP%] { display: block; }\n\n.mj-typeahead-list.is-up[_ngcontent-%COMP%] {\n top: auto;\n bottom: calc(100% + 4px);\n}\n\n.mj-typeahead-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n width: 100%;\n padding: 8px 12px;\n border: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n font: inherit;\n}\n\n.mj-typeahead-item[_ngcontent-%COMP%]:last-child { border-bottom: 0; }\n\n.mj-typeahead-item[_ngcontent-%COMP%]:hover, \n.mj-typeahead-item.is-cursor[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-pick__body[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.mjo-ol-pick[_ngcontent-%COMP%] .name[_ngcontent-%COMP%] { font-size: 13px; font-weight: var(--mj-font-semibold); }\n.mjo-ol-pick[_ngcontent-%COMP%] .sub[_ngcontent-%COMP%] { font-size: 11.5px; color: var(--mj-text-muted); }\n.mjo-ol-pick[_ngcontent-%COMP%] .end[_ngcontent-%COMP%] {\n margin-left: auto;\n text-align: right;\n display: flex;\n flex-direction: column;\n gap: 1px;\n flex: 0 0 auto;\n}\n.mjo-ol-pick__price[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-ext-err[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] {\n margin-top: var(--mj-space-2);\n padding-top: var(--mj-space-1);\n border-top: 1px dashed var(--mj-border-subtle);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n.mjo-ol-ext__chev[_ngcontent-%COMP%] {\n flex: none;\n width: 12px;\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 160ms ease;\n}\n\n.mjo-ol-ext.is-open[_ngcontent-%COMP%] .mjo-ol-ext__chev[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n.mjo-ol-ext__label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n letter-spacing: 0.01em;\n}\n\n.mjo-ol-ext__hint[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mjo-ol-ext__body[_ngcontent-%COMP%] {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 180ms ease;\n}\n\n.mjo-ol-ext.is-open[_ngcontent-%COMP%] .mjo-ol-ext__body[_ngcontent-%COMP%] {\n grid-template-rows: 1fr;\n}\n\n.mjo-ol-ext__clip[_ngcontent-%COMP%] {\n overflow: hidden;\n min-height: 0;\n}\n\n\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-record-form-container, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-record-form-container, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-container {\n display: block;\n padding: 0;\n margin: 0;\n border: 0;\n background: transparent;\n box-shadow: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-toolbar, \n.mjo-ol-ext[_ngcontent-%COMP%] mj-form-toolbar {\n display: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel {\n border: 0;\n background: transparent;\n box-shadow: none;\n margin: 0;\n padding: 0;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-collapsible-panel + mj-collapsible-panel .mj-forms-panel {\n margin-top: calc(-1 * var(--mj-space-1));\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-header {\n display: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-body, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-content {\n max-height: none;\n overflow: visible;\n padding: 0;\n margin: 0;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-form-field:last-child, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-form-field:last-child {\n margin-bottom: 0;\n}\n\n@media (max-width: 720px) {\n .mjo-ol-card__top[_ngcontent-%COMP%] { flex-wrap: wrap; }\n .mjo-ol-card__price[_ngcontent-%COMP%], .mjo-ol-card__tot[_ngcontent-%COMP%] { width: auto; }\n}"] });
|
|
1298
|
+
MJOMoneyPipe], styles: ["[_nghost-%COMP%] { display: block; }\n\n.mjo-ol[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-card[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-md);\n padding: var(--mj-space-3);\n}\n\n.mjo-ol-card[_ngcontent-%COMP%]:has(.mjo-ol-ext.is-open) {\n padding-bottom: var(--mj-space-1);\n}\n\n.mjo-ol-card__top[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n}\n\n.mjo-ol-card__id[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.mjo-ol-card__name[_ngcontent-%COMP%] {\n display: inline;\n padding: 0;\n border: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-link);\n text-align: left;\n cursor: pointer;\n text-decoration: none;\n}\n\n.mjo-ol-card__name[_ngcontent-%COMP%]:hover { text-decoration: underline; }\n\n.mjo-ol-card__meta[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n background: var(--mj-bg-surface);\n flex: none;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-secondary);\n width: 26px;\n height: 28px;\n font-size: 11px;\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:disabled {\n cursor: default;\n color: var(--mj-text-disabled);\n}\n\n.mjo-ol-qty[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n background: transparent;\n width: 46px;\n text-align: center;\n font: inherit;\n font-variant-numeric: tabular-nums;\n color: inherit;\n}\n\n.mjo-ol-qty.is-locked[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n background: transparent;\n}\n\n.mjo-ol-qty__value[_ngcontent-%COMP%] {\n min-width: 46px;\n padding: 0 10px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-card__price[_ngcontent-%COMP%] {\n flex: none;\n min-width: 108px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.mjo-ol-card__price-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 2px;\n height: 28px;\n}\n\n.mjo-ol-price__pencil[_ngcontent-%COMP%] {\n flex: none;\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-price__pencil[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-link);\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-price__pick[_ngcontent-%COMP%], \n.mjo-ol-price__amt[_ngcontent-%COMP%], \n.mjo-ol-override__reason[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n box-sizing: border-box;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-price__pick[_ngcontent-%COMP%] {\n height: 28px;\n padding: 0 6px;\n text-align: left;\n flex: 1 1 180px;\n max-width: 240px;\n width: auto;\n}\n\n.mjo-ol-price__amt[_ngcontent-%COMP%] {\n height: 28px;\n padding: 0 8px;\n text-align: right;\n font-weight: var(--mj-font-semibold);\n width: 108px;\n flex: none;\n}\n\n.mjo-ol-override[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n padding: var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-override__reason[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: block;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n\n.mjo-ol-override__reason.is-off[_ngcontent-%COMP%] {\n opacity: 0.55;\n}\n\n.mjo-ol-override__reason[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]:disabled {\n cursor: not-allowed;\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__reason[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 48px;\n padding: 6px 8px;\n text-align: left;\n font-variant-numeric: normal;\n}\n\n.mjo-ol-override__actions[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-2);\n justify-content: flex-end;\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%], \n.mjo-ol-override__reset[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n cursor: pointer;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n padding: 4px 8px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%] {\n color: var(--mj-text-link);\n}\n\n.mjo-ol-override__reset[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-override__done[_ngcontent-%COMP%]:hover, \n.mjo-ol-override__reset[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-card__amt[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-overpill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-status-warning-text);\n background: color-mix(in srgb, var(--mj-status-warning-text) 16%, transparent);\n}\n\n.mjo-ol-card__err[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n margin-top: 2px;\n}\n\n.mjo-ol-card__tot[_ngcontent-%COMP%] {\n flex: none;\n min-width: 104px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n text-align: right;\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-iconbtn[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-iconbtn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-status-error);\n}\n\n.mjo-ol-card__conseq[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n\n\n\n.mjo-ol-term[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n.mjo-ol-term__label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__input[_ngcontent-%COMP%] {\n height: 28px;\n padding: 0 var(--mj-space-2);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: var(--mj-text-sm);\n}\n\n\n\n\n.mjo-ol-term__input.is-default[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__value[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n}\n\n\n\n\n.mjo-ol-term__value.is-dictated[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__reset[_ngcontent-%COMP%] {\n border: 0;\n background: transparent;\n padding: 0;\n color: var(--mj-text-link);\n font-size: var(--mj-text-xs);\n cursor: pointer;\n}\n\n.mjo-ol-term__reset[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.mjo-ol-term__hint[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-card__why[_ngcontent-%COMP%] {\n margin-top: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n line-height: 1.35;\n}\n\n.mjo-ol-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-1);\n padding: var(--mj-space-4) var(--mj-space-3);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n text-align: center;\n}\n\n.mjo-ol-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-2xl);\n color: var(--mj-brand-primary);\n}\n\n.mjo-ol-empty__title[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-picker[_ngcontent-%COMP%] {\n position: relative;\n z-index: 20;\n}\n\n.mjo-ol-picker[_ngcontent-%COMP%]:has(.mj-typeahead-list.is-open) {\n z-index: 40;\n}\n\n.mjo-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n padding: 8px 10px;\n}\n\n.mjo-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-text-muted); font-size: 12px; }\n\n.mjo-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n color: inherit;\n width: 100%;\n}\n\n.mj-typeahead-list[_ngcontent-%COMP%] {\n display: none;\n position: absolute;\n left: 0;\n right: 0;\n top: calc(100% + 4px);\n max-height: 240px;\n overflow: auto;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md, 0 8px 24px rgba(0, 0, 0, 0.18));\n z-index: 30;\n}\n\n.mj-typeahead-list.is-open[_ngcontent-%COMP%] { display: block; }\n\n.mj-typeahead-list.is-up[_ngcontent-%COMP%] {\n top: auto;\n bottom: calc(100% + 4px);\n}\n\n.mj-typeahead-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n width: 100%;\n padding: 8px 12px;\n border: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n font: inherit;\n}\n\n.mj-typeahead-item[_ngcontent-%COMP%]:last-child { border-bottom: 0; }\n\n.mj-typeahead-item[_ngcontent-%COMP%]:hover, \n.mj-typeahead-item.is-cursor[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-pick__body[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.mjo-ol-pick[_ngcontent-%COMP%] .name[_ngcontent-%COMP%] { font-size: 13px; font-weight: var(--mj-font-semibold); }\n.mjo-ol-pick[_ngcontent-%COMP%] .sub[_ngcontent-%COMP%] { font-size: 11.5px; color: var(--mj-text-muted); }\n\n\n\n\n\n\n\n\n.mjo-ol-pick__meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n min-width: 0;\n}\n\n.mjo-ol-pick__company[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex: 0 0 auto;\n font-size: 11px;\n line-height: 1.2;\n padding: 2px 6px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-pick__company[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 9.5px; color: var(--mj-text-muted); }\n\n\n\n.mjo-ol-pick__company.is-foreign[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-status-info); }\n.mjo-ol-pick__company.is-foreign[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n.mjo-ol-pick[_ngcontent-%COMP%] .end[_ngcontent-%COMP%] {\n margin-left: auto;\n text-align: right;\n display: flex;\n flex-direction: column;\n gap: 1px;\n flex: 0 0 auto;\n}\n.mjo-ol-pick__price[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-ext-err[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] {\n margin-top: var(--mj-space-2);\n padding-top: var(--mj-space-1);\n border-top: 1px dashed var(--mj-border-subtle);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-ext__toggle[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n.mjo-ol-ext__chev[_ngcontent-%COMP%] {\n flex: none;\n width: 12px;\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 160ms ease;\n}\n\n.mjo-ol-ext.is-open[_ngcontent-%COMP%] .mjo-ol-ext__chev[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n.mjo-ol-ext__label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n letter-spacing: 0.01em;\n}\n\n.mjo-ol-ext__hint[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mjo-ol-ext__body[_ngcontent-%COMP%] {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 180ms ease;\n}\n\n.mjo-ol-ext.is-open[_ngcontent-%COMP%] .mjo-ol-ext__body[_ngcontent-%COMP%] {\n grid-template-rows: 1fr;\n}\n\n.mjo-ol-ext__clip[_ngcontent-%COMP%] {\n overflow: hidden;\n min-height: 0;\n}\n\n\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-record-form-container, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-record-form-container, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-container {\n display: block;\n padding: 0;\n margin: 0;\n border: 0;\n background: transparent;\n box-shadow: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-toolbar, \n.mjo-ol-ext[_ngcontent-%COMP%] mj-form-toolbar {\n display: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel {\n border: 0;\n background: transparent;\n box-shadow: none;\n margin: 0;\n padding: 0;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-collapsible-panel + mj-collapsible-panel .mj-forms-panel {\n margin-top: calc(-1 * var(--mj-space-1));\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-header {\n display: none;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-body, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-forms-panel-content {\n max-height: none;\n overflow: visible;\n padding: 0;\n margin: 0;\n}\n\n.mjo-ol-ext[_ngcontent-%COMP%] mj-form-field:last-child, \n.mjo-ol-ext[_ngcontent-%COMP%] .mj-form-field:last-child {\n margin-bottom: 0;\n}\n\n@media (max-width: 720px) {\n .mjo-ol-card__top[_ngcontent-%COMP%] { flex-wrap: wrap; }\n .mjo-ol-card__price[_ngcontent-%COMP%], .mjo-ol-card__tot[_ngcontent-%COMP%] { width: auto; }\n}"] });
|
|
1239
1299
|
}
|
|
1240
1300
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJOOrderLinesEditorComponent, [{
|
|
1241
1301
|
type: Component,
|
|
@@ -1246,7 +1306,7 @@ export class MJOOrderLinesEditorComponent {
|
|
|
1246
1306
|
MJOConsequenceChipComponent,
|
|
1247
1307
|
MJOPriceSourceBadgeComponent,
|
|
1248
1308
|
MJOMoneyPipe,
|
|
1249
|
-
], template: "<div class=\"mjo-ol\">\n @for (line of Lines; track line.ID) {\n <div class=\"mjo-ol-card\">\n <div class=\"mjo-ol-card__top\">\n <div class=\"mjo-ol-card__id\">\n <button type=\"button\" class=\"mjo-ol-card__name\" (click)=\"OpenProduct(line, $event)\">\n {{ ProductFor(line)?.Name ?? 'Product' }}\n </button>\n <div class=\"mjo-ol-card__meta\">\n {{ ProductFor(line)?.SKU }}\n @if (ProductFor(line)?.TypeName) {\n \u00B7 {{ ProductFor(line)?.TypeName }}\n }\n </div>\n </div>\n\n <div class=\"mjo-ol-qty\" [class.is-locked]=\"!EditMode || QuantityCappedToOne(line)\">\n @if (EditMode && !QuantityCappedToOne(line)) {\n <button type=\"button\" (click)=\"Bump(line, -1)\" aria-label=\"Decrease quantity\">\u2212</button>\n <input\n [value]=\"line.Quantity\"\n (change)=\"SetQuantity(line, $event)\"\n aria-label=\"Quantity\">\n <button type=\"button\" (click)=\"Bump(line, 1)\" [disabled]=\"QuantityAtMax(line)\" aria-label=\"Increase quantity\">+</button>\n } @else {\n <span class=\"mjo-ol-qty__value\">{{ line.Quantity }}</span>\n }\n </div>\n\n <div class=\"mjo-ol-card__price\">\n <div class=\"mjo-ol-card__price-row\">\n <div class=\"mjo-ol-card__amt\">{{ DisplayUnit(line) | mjoMoney }}</div>\n @if (CanOverride) {\n <button\n type=\"button\"\n class=\"mjo-ol-iconbtn mjo-ol-price__pencil\"\n (click)=\"ToggleOverrideEditor(line)\"\n [attr.aria-expanded]=\"IsOverrideEditorOpen(line)\"\n [attr.aria-label]=\"IsOverridden(line) ? 'Edit price override' : 'Override price'\">\n <i class=\"fa-solid fa-pencil\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n @if (IsOverridden(line)) {\n <span class=\"mjo-ol-overpill\">overridden</span>\n } @else {\n <mjo-price-source-badge\n [Source]=\"PricedLine(line)?.PriceSource ?? null\"\n [Settled]=\"!Pricing.Loading\"\n [Overridden]=\"false\" />\n }\n @if (PricedLine(line)?.Error; as why) {\n <div class=\"mjo-ol-card__err\">{{ why }}</div>\n }\n </div>\n\n <div class=\"mjo-ol-card__tot\">{{ PricedLine(line)?.NetAmount | mjoMoney }}</div>\n\n @if (EditMode) {\n <button\n type=\"button\"\n class=\"mjo-ol-iconbtn\"\n (click)=\"Remove(line)\"\n [attr.aria-label]=\"'Remove ' + (ProductFor(line)?.Name ?? 'line')\">\n <i class=\"fa-regular fa-trash-can\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n\n @if (IsOverrideEditorOpen(line)) {\n <div class=\"mjo-ol-override\" role=\"region\" [attr.aria-label]=\"'Override price for ' + (ProductFor(line)?.Name ?? 'line')\">\n <div class=\"mjo-ol-override__row\">\n <select\n class=\"mjo-ol-price__pick\"\n [value]=\"SelectedPriceID(line)\"\n (change)=\"PickNamedPrice(line, $event)\"\n aria-label=\"Named price\">\n <option value=\"\">{{ DefaultLabel(line) }}</option>\n @if (OverrideKind === 'any') {\n <option value=\"__custom__\">Custom amount</option>\n }\n @for (price of ApplicableFor(line); track price.ID) {\n <option [value]=\"price.ID\">{{ price.Name }} \u00B7 {{ price.UnitPrice | mjoMoney }}</option>\n }\n </select>\n @if (ShowCustomAmount(line)) {\n <input\n class=\"mjo-ol-price__amt\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n [value]=\"DisplayUnit(line)\"\n (change)=\"TypeAmount(line, $event)\"\n aria-label=\"Custom unit price\">\n }\n </div>\n <label class=\"mjo-ol-override__reason\" [class.is-off]=\"!CanExplainOverride(line)\">\n <span>Override Explanation</span>\n <textarea\n rows=\"2\"\n [disabled]=\"!CanExplainOverride(line)\"\n [value]=\"OverrideReasonText(line)\"\n (input)=\"SetOverrideReason(line, $event)\"\n placeholder=\"Optional \u2014 why this price differs from the default\"></textarea>\n </label>\n <div class=\"mjo-ol-override__actions\">\n <button type=\"button\" class=\"mjo-ol-override__done\" (click)=\"DoneOverrideEditor(line)\">Done</button>\n <button type=\"button\" class=\"mjo-ol-override__reset\" (click)=\"ResetOverride(line)\">Use Default Price</button>\n </div>\n </div>\n }\n\n <div class=\"mjo-ol-card__conseq\">\n @if (ProductFor(line); as product) {\n @if (product.TypeName === 'Goods') {\n <mjo-consequence-chip Kind=\"fulfillment\">Ships \u2014 holds the order at Posted</mjo-consequence-chip>\n }\n @if (!product.Taxable) {\n <mjo-consequence-chip Kind=\"untaxable\">Untaxable</mjo-consequence-chip>\n }\n @if (ShowsForeignRevenue(line)) {\n <mjo-consequence-chip Kind=\"company\">Revenue to {{ product.CompanyName }}</mjo-consequence-chip>\n }\n }\n </div>\n @if (OverrideReasonText(line); as why) {\n <div class=\"mjo-ol-card__why\">{{ why }}</div>\n }\n\n <!--\n TERM START \u2014 subscription lines only (D-TERMSTART).\n The order date says when the sale was booked; this says when coverage begins, and an\n agreement settles the two independently. Shown on the card rather than behind the\n extension disclosure because it is a term fact, and not every subscription product\n type has an extension form to hide it in.\n -->\n @if (IsSubscriptionLine(line)) {\n <div class=\"mjo-ol-term\">\n <!-- `for` only when there IS an input to point at. A label targeting a missing\n id is a dead control to a screen reader. -->\n <label\n class=\"mjo-ol-term__label\"\n [attr.for]=\"EditMode && !TermStartIsDictated(line) ? 'mjo-ol-term-' + line.ID : null\">\n Term start\n </label>\n <!-- A renewal of LIVE coverage has no choice to offer: the term begins the day\n after the current one ends. Read-only rather than editable-and-ignored. -->\n @if (TermStartIsDictated(line)) {\n <span class=\"mjo-ol-term__value is-dictated\">{{ ContinuationStartValue(line) }}</span>\n } @else if (EditMode) {\n <input\n type=\"date\"\n class=\"mjo-ol-term__input\"\n [class.is-default]=\"TermStartFollowsOrderDate(line)\"\n [id]=\"'mjo-ol-term-' + line.ID\"\n [value]=\"TermStartValue(line)\"\n (change)=\"SetTermStart(line, $event)\">\n <!-- Offered only when there is something to reset. A button that clears a\n value the line never stated does nothing and invites the reader to\n wonder what it did. -->\n @if (!TermStartFollowsOrderDate(line)) {\n <button\n type=\"button\"\n class=\"mjo-ol-term__reset\"\n (click)=\"ResetTermStart(line)\">\n Reset to order date\n </button>\n }\n } @else {\n <span class=\"mjo-ol-term__value\">{{ TermStartValue(line) }}</span>\n }\n <span class=\"mjo-ol-term__hint\">\n @if (TermStartIsDictated(line)) {\n Continuing existing coverage, so the term begins the day after the current\n one ends \u2014 not something this line can set.\n } @else if (TermStartFollowsOrderDate(line)) {\n Following the order date. The subscription type's rules may still adjust\n the actual start.\n } @else {\n Stated on this line, so a later change to the order date leaves it alone.\n }\n </span>\n </div>\n }\n\n @if (ExtensionFor(line); as ext) {\n <div class=\"mjo-ol-ext\" [class.is-open]=\"IsExtensionOpen(line)\">\n <button\n type=\"button\"\n class=\"mjo-ol-ext__toggle\"\n (click)=\"ToggleExtension(line)\"\n [attr.aria-expanded]=\"IsExtensionOpen(line)\"\n [attr.aria-controls]=\"'mjo-ol-ext-' + line.ID\">\n <i class=\"fa-solid fa-chevron-right mjo-ol-ext__chev\" aria-hidden=\"true\"></i>\n <span class=\"mjo-ol-ext__label\">{{ ExtensionLabel(line) }}</span>\n @if (!IsExtensionOpen(line)) {\n <span class=\"mjo-ol-ext__hint\">{{ ExtensionHint(line) }}</span>\n }\n </button>\n <div\n class=\"mjo-ol-ext__body\"\n [id]=\"'mjo-ol-ext-' + line.ID\"\n [attr.inert]=\"IsExtensionOpen(line) ? null : ''\"\n [attr.aria-hidden]=\"!IsExtensionOpen(line)\">\n <div class=\"mjo-ol-ext__clip\">\n <mj-entity-form-host\n [Record]=\"ext\"\n [EditMode]=\"EditMode\"\n [Config]=\"ExtensionFormConfigFor(line)\"\n (FormCreated)=\"OnExtensionFormCreated($event)\"\n (Navigate)=\"OnExtensionNavigate($event)\">\n </mj-entity-form-host>\n </div>\n </div>\n </div>\n }\n </div>\n } @empty {\n <div class=\"mjo-ol-empty\">\n <i class=\"fa-solid fa-cart-plus\" aria-hidden=\"true\"></i>\n <div class=\"mjo-ol-empty__title\">Nothing on this order yet</div>\n <div>Search the catalog to add the first line.</div>\n </div>\n }\n\n @if (EditMode) {\n <div class=\"mj-typeahead mjo-ol-picker\" #pickerHost>\n <div class=\"mjo-search\">\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i>\n <input\n [(ngModel)]=\"ProductQuery\"\n (ngModelChange)=\"OnProductQueryChange()\"\n (focus)=\"OpenPicker()\"\n (blur)=\"ClosePickerSoon()\"\n (keydown)=\"OnPickerKey($event)\"\n placeholder=\"Add product \u2014 type a name or SKU\u2026\"\n autocomplete=\"off\"\n role=\"combobox\"\n aria-label=\"Add a product\"\n [attr.aria-expanded]=\"PickerOpen\">\n </div>\n\n @if (PickerOpen) {\n <div class=\"mj-typeahead-list is-open\" [class.is-up]=\"PickerOpensUp\" role=\"listbox\">\n @for (product of PickerResults; track product.ID; let i = $index) {\n <button\n type=\"button\"\n class=\"mj-typeahead-item mjo-ol-pick\"\n [class.is-cursor]=\"i === PickerCursor\"\n role=\"option\"\n [attr.aria-selected]=\"i === PickerCursor\"\n (mousedown)=\"AddProduct(product)\">\n <span class=\"mjo-ol-pick__body\">\n <span class=\"name\">{{ product.Name }}</span>\n <span class=\"sub\">{{ product.SKU }} \u00B7 {{ product.TypeName }} \u00B7 {{ product.CompanyName }}</span>\n </span>\n <span class=\"end\">\n <span class=\"mjo-ol-pick__price\">{{ product.ListPrice | mjoMoney }}</span>\n <span class=\"sub\">{{ product.Taxable ? 'taxable' : 'untaxable' }}</span>\n </span>\n </button>\n } @empty {\n <div class=\"mj-typeahead-item\">\n <span class=\"muted small\">\n @if (CatalogError) { {{ CatalogError }} }\n @else if (Catalog.length === 0) { Loading catalog\u2026 }\n @else { No product matches that. }\n </span>\n </div>\n }\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host { display: block; }\n\n.mjo-ol {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-card {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-md);\n padding: var(--mj-space-3);\n}\n\n.mjo-ol-card:has(.mjo-ol-ext.is-open) {\n padding-bottom: var(--mj-space-1);\n}\n\n.mjo-ol-card__top {\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n}\n\n.mjo-ol-card__id { flex: 1; min-width: 0; }\n\n.mjo-ol-card__name {\n display: inline;\n padding: 0;\n border: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-link);\n text-align: left;\n cursor: pointer;\n text-decoration: none;\n}\n\n.mjo-ol-card__name:hover { text-decoration: underline; }\n\n.mjo-ol-card__meta {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.mjo-ol-qty {\n display: inline-flex;\n align-items: center;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n background: var(--mj-bg-surface);\n flex: none;\n}\n\n.mjo-ol-qty button {\n border: 0;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-secondary);\n width: 26px;\n height: 28px;\n font-size: 11px;\n}\n\n.mjo-ol-qty button:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-qty button:disabled {\n cursor: default;\n color: var(--mj-text-disabled);\n}\n\n.mjo-ol-qty input {\n border: 0;\n outline: 0;\n background: transparent;\n width: 46px;\n text-align: center;\n font: inherit;\n font-variant-numeric: tabular-nums;\n color: inherit;\n}\n\n.mjo-ol-qty.is-locked {\n border-color: var(--mj-border-default);\n background: transparent;\n}\n\n.mjo-ol-qty__value {\n min-width: 46px;\n padding: 0 10px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-card__price {\n flex: none;\n min-width: 108px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.mjo-ol-card__price-row {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 2px;\n height: 28px;\n}\n\n.mjo-ol-price__pencil {\n flex: none;\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-price__pencil:hover {\n color: var(--mj-text-link);\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-price__pick,\n.mjo-ol-price__amt,\n.mjo-ol-override__reason textarea {\n display: block;\n width: 100%;\n box-sizing: border-box;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-price__pick {\n height: 28px;\n padding: 0 6px;\n text-align: left;\n flex: 1 1 180px;\n max-width: 240px;\n width: auto;\n}\n\n.mjo-ol-price__amt {\n height: 28px;\n padding: 0 8px;\n text-align: right;\n font-weight: var(--mj-font-semibold);\n width: 108px;\n flex: none;\n}\n\n.mjo-ol-override {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n padding: var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__row {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-override__reason span {\n display: block;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n\n.mjo-ol-override__reason.is-off {\n opacity: 0.55;\n}\n\n.mjo-ol-override__reason textarea:disabled {\n cursor: not-allowed;\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__reason textarea {\n resize: vertical;\n min-height: 48px;\n padding: 6px 8px;\n text-align: left;\n font-variant-numeric: normal;\n}\n\n.mjo-ol-override__actions {\n display: flex;\n gap: var(--mj-space-2);\n justify-content: flex-end;\n}\n\n.mjo-ol-override__done,\n.mjo-ol-override__reset {\n border: 0;\n background: transparent;\n cursor: pointer;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n padding: 4px 8px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-override__done {\n color: var(--mj-text-link);\n}\n\n.mjo-ol-override__reset {\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-override__done:hover,\n.mjo-ol-override__reset:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-card__amt {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-overpill {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-status-warning-text);\n background: color-mix(in srgb, var(--mj-status-warning-text) 16%, transparent);\n}\n\n.mjo-ol-card__err {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n margin-top: 2px;\n}\n\n.mjo-ol-card__tot {\n flex: none;\n min-width: 104px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n text-align: right;\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-iconbtn {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-iconbtn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-status-error);\n}\n\n.mjo-ol-card__conseq {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n/* Term start \u2014 subscription lines only. One row that wraps, so the hint drops below the field on a\n narrow card rather than squeezing the date input. */\n.mjo-ol-term {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n.mjo-ol-term__label {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__input {\n height: 28px;\n padding: 0 var(--mj-space-2);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: var(--mj-text-sm);\n}\n\n/* A DEFAULT reads quieter than a stated value \u2014 the same distinction the order header draws\n between a date somebody chose and one that fell out of a rule. */\n.mjo-ol-term__input.is-default {\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__value {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n}\n\n/* A dictated date is a FACT, not a disabled input: shown in the read-mode weight in edit mode too,\n so nothing on the card suggests a control that has been switched off. */\n.mjo-ol-term__value.is-dictated {\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__reset {\n border: 0;\n background: transparent;\n padding: 0;\n color: var(--mj-text-link);\n font-size: var(--mj-text-xs);\n cursor: pointer;\n}\n\n.mjo-ol-term__reset:hover {\n text-decoration: underline;\n}\n\n.mjo-ol-term__hint {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-card__why {\n margin-top: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n line-height: 1.35;\n}\n\n.mjo-ol-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-1);\n padding: var(--mj-space-4) var(--mj-space-3);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n text-align: center;\n}\n\n.mjo-ol-empty i {\n font-size: var(--mj-text-2xl);\n color: var(--mj-brand-primary);\n}\n\n.mjo-ol-empty__title {\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-picker {\n position: relative;\n z-index: 20;\n}\n\n.mjo-ol-picker:has(.mj-typeahead-list.is-open) {\n z-index: 40;\n}\n\n.mjo-search {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n padding: 8px 10px;\n}\n\n.mjo-search i { color: var(--mj-text-muted); font-size: 12px; }\n\n.mjo-search input {\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n color: inherit;\n width: 100%;\n}\n\n.mj-typeahead-list {\n display: none;\n position: absolute;\n left: 0;\n right: 0;\n top: calc(100% + 4px);\n max-height: 240px;\n overflow: auto;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md, 0 8px 24px rgba(0, 0, 0, 0.18));\n z-index: 30;\n}\n\n.mj-typeahead-list.is-open { display: block; }\n\n.mj-typeahead-list.is-up {\n top: auto;\n bottom: calc(100% + 4px);\n}\n\n.mj-typeahead-item {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n width: 100%;\n padding: 8px 12px;\n border: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n font: inherit;\n}\n\n.mj-typeahead-item:last-child { border-bottom: 0; }\n\n.mj-typeahead-item:hover,\n.mj-typeahead-item.is-cursor {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-pick__body {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.mjo-ol-pick .name { font-size: 13px; font-weight: var(--mj-font-semibold); }\n.mjo-ol-pick .sub { font-size: 11.5px; color: var(--mj-text-muted); }\n.mjo-ol-pick .end {\n margin-left: auto;\n text-align: right;\n display: flex;\n flex-direction: column;\n gap: 1px;\n flex: 0 0 auto;\n}\n.mjo-ol-pick__price {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-ext-err {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-ext {\n margin-top: var(--mj-space-2);\n padding-top: var(--mj-space-1);\n border-top: 1px dashed var(--mj-border-subtle);\n}\n\n.mjo-ol-ext__toggle {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-ext__toggle:hover {\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-ext__toggle:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n.mjo-ol-ext__chev {\n flex: none;\n width: 12px;\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 160ms ease;\n}\n\n.mjo-ol-ext.is-open .mjo-ol-ext__chev {\n transform: rotate(90deg);\n}\n\n.mjo-ol-ext__label {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n letter-spacing: 0.01em;\n}\n\n.mjo-ol-ext__hint {\n margin-left: auto;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mjo-ol-ext__body {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 180ms ease;\n}\n\n.mjo-ol-ext.is-open .mjo-ol-ext__body {\n grid-template-rows: 1fr;\n}\n\n.mjo-ol-ext__clip {\n overflow: hidden;\n min-height: 0;\n}\n\n/* Flatten the embedded extension form so its fields sit in the line card. */\n.mjo-ol-ext ::ng-deep mj-record-form-container,\n.mjo-ol-ext ::ng-deep .mj-record-form-container,\n.mjo-ol-ext ::ng-deep .mj-forms-container {\n display: block;\n padding: 0;\n margin: 0;\n border: 0;\n background: transparent;\n box-shadow: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-toolbar,\n.mjo-ol-ext ::ng-deep mj-form-toolbar {\n display: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel {\n border: 0;\n background: transparent;\n box-shadow: none;\n margin: 0;\n padding: 0;\n}\n\n.mjo-ol-ext ::ng-deep mj-collapsible-panel + mj-collapsible-panel .mj-forms-panel {\n margin-top: calc(-1 * var(--mj-space-1));\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel-header {\n display: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel-body,\n.mjo-ol-ext ::ng-deep .mj-forms-panel-content {\n max-height: none;\n overflow: visible;\n padding: 0;\n margin: 0;\n}\n\n.mjo-ol-ext ::ng-deep mj-form-field:last-child,\n.mjo-ol-ext ::ng-deep .mj-form-field:last-child {\n margin-bottom: 0;\n}\n\n@media (max-width: 720px) {\n .mjo-ol-card__top { flex-wrap: wrap; }\n .mjo-ol-card__price, .mjo-ol-card__tot { width: auto; }\n}\n"] }]
|
|
1309
|
+
], template: "<div class=\"mjo-ol\">\n @for (line of Lines; track line.ID) {\n <div class=\"mjo-ol-card\">\n <div class=\"mjo-ol-card__top\">\n <div class=\"mjo-ol-card__id\">\n <button type=\"button\" class=\"mjo-ol-card__name\" (click)=\"OpenProduct(line, $event)\">\n {{ ProductFor(line)?.Name ?? 'Product' }}\n </button>\n <div class=\"mjo-ol-card__meta\">\n {{ ProductFor(line)?.SKU }}\n @if (ProductFor(line)?.TypeName) {\n \u00B7 {{ ProductFor(line)?.TypeName }}\n }\n </div>\n </div>\n\n <div class=\"mjo-ol-qty\" [class.is-locked]=\"!EditMode || QuantityCappedToOne(line)\">\n @if (EditMode && !QuantityCappedToOne(line)) {\n <button type=\"button\" (click)=\"Bump(line, -1)\" aria-label=\"Decrease quantity\">\u2212</button>\n <input\n [value]=\"line.Quantity\"\n (change)=\"SetQuantity(line, $event)\"\n aria-label=\"Quantity\">\n <button type=\"button\" (click)=\"Bump(line, 1)\" [disabled]=\"QuantityAtMax(line)\" aria-label=\"Increase quantity\">+</button>\n } @else {\n <span class=\"mjo-ol-qty__value\">{{ line.Quantity }}</span>\n }\n </div>\n\n <div class=\"mjo-ol-card__price\">\n <div class=\"mjo-ol-card__price-row\">\n <div class=\"mjo-ol-card__amt\">{{ DisplayUnit(line) | mjoMoney }}</div>\n @if (CanOverride) {\n <button\n type=\"button\"\n class=\"mjo-ol-iconbtn mjo-ol-price__pencil\"\n (click)=\"ToggleOverrideEditor(line)\"\n [attr.aria-expanded]=\"IsOverrideEditorOpen(line)\"\n [attr.aria-label]=\"IsOverridden(line) ? 'Edit price override' : 'Override price'\">\n <i class=\"fa-solid fa-pencil\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n @if (IsOverridden(line)) {\n <span class=\"mjo-ol-overpill\">overridden</span>\n } @else {\n <mjo-price-source-badge\n [Source]=\"PricedLine(line)?.PriceSource ?? null\"\n [Settled]=\"!Pricing.Loading\"\n [Overridden]=\"false\" />\n }\n @if (PricedLine(line)?.Error; as why) {\n <div class=\"mjo-ol-card__err\">{{ why }}</div>\n }\n </div>\n\n <div class=\"mjo-ol-card__tot\">{{ PricedLine(line)?.NetAmount | mjoMoney }}</div>\n\n @if (EditMode) {\n <button\n type=\"button\"\n class=\"mjo-ol-iconbtn\"\n (click)=\"Remove(line)\"\n [attr.aria-label]=\"'Remove ' + (ProductFor(line)?.Name ?? 'line')\">\n <i class=\"fa-regular fa-trash-can\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n\n @if (IsOverrideEditorOpen(line)) {\n <div class=\"mjo-ol-override\" role=\"region\" [attr.aria-label]=\"'Override price for ' + (ProductFor(line)?.Name ?? 'line')\">\n <div class=\"mjo-ol-override__row\">\n <select\n class=\"mjo-ol-price__pick\"\n [value]=\"SelectedPriceID(line)\"\n (change)=\"PickNamedPrice(line, $event)\"\n aria-label=\"Named price\">\n <option value=\"\">{{ DefaultLabel(line) }}</option>\n @if (OverrideKind === 'any') {\n <option value=\"__custom__\">Custom amount</option>\n }\n @for (price of ApplicableFor(line); track price.ID) {\n <option [value]=\"price.ID\">{{ price.Name }} \u00B7 {{ price.UnitPrice | mjoMoney }}</option>\n }\n </select>\n @if (ShowCustomAmount(line)) {\n <input\n class=\"mjo-ol-price__amt\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n [value]=\"DisplayUnit(line)\"\n (change)=\"TypeAmount(line, $event)\"\n aria-label=\"Custom unit price\">\n }\n </div>\n <label class=\"mjo-ol-override__reason\" [class.is-off]=\"!CanExplainOverride(line)\">\n <span>Override Explanation</span>\n <textarea\n rows=\"2\"\n [disabled]=\"!CanExplainOverride(line)\"\n [value]=\"OverrideReasonText(line)\"\n (input)=\"SetOverrideReason(line, $event)\"\n placeholder=\"Optional \u2014 why this price differs from the default\"></textarea>\n </label>\n <div class=\"mjo-ol-override__actions\">\n <button type=\"button\" class=\"mjo-ol-override__done\" (click)=\"DoneOverrideEditor(line)\">Done</button>\n <button type=\"button\" class=\"mjo-ol-override__reset\" (click)=\"ResetOverride(line)\">Use Default Price</button>\n </div>\n </div>\n }\n\n <div class=\"mjo-ol-card__conseq\">\n @if (ProductFor(line); as product) {\n @if (product.TypeName === 'Goods') {\n <mjo-consequence-chip Kind=\"fulfillment\">Ships \u2014 holds the order at Posted</mjo-consequence-chip>\n }\n @if (!product.Taxable) {\n <mjo-consequence-chip Kind=\"untaxable\">Untaxable</mjo-consequence-chip>\n }\n @if (ShowsForeignRevenue(line)) {\n <mjo-consequence-chip Kind=\"company\">Revenue to {{ product.CompanyName }}</mjo-consequence-chip>\n }\n }\n </div>\n @if (OverrideReasonText(line); as why) {\n <div class=\"mjo-ol-card__why\">{{ why }}</div>\n }\n\n <!--\n TERM START \u2014 subscription lines only (D-TERMSTART).\n The order date says when the sale was booked; this says when coverage begins, and an\n agreement settles the two independently. Shown on the card rather than behind the\n extension disclosure because it is a term fact, and not every subscription product\n type has an extension form to hide it in.\n -->\n @if (IsSubscriptionLine(line)) {\n <div class=\"mjo-ol-term\">\n <!-- `for` only when there IS an input to point at. A label targeting a missing\n id is a dead control to a screen reader. -->\n <label\n class=\"mjo-ol-term__label\"\n [attr.for]=\"EditMode && !TermStartIsDictated(line) ? 'mjo-ol-term-' + line.ID : null\">\n Term start\n </label>\n <!-- A renewal of LIVE coverage has no choice to offer: the term begins the day\n after the current one ends. Read-only rather than editable-and-ignored. -->\n @if (TermStartIsDictated(line)) {\n <span class=\"mjo-ol-term__value is-dictated\">{{ ContinuationStartValue(line) }}</span>\n } @else if (EditMode) {\n <input\n type=\"date\"\n class=\"mjo-ol-term__input\"\n [class.is-default]=\"TermStartFollowsOrderDate(line)\"\n [id]=\"'mjo-ol-term-' + line.ID\"\n [value]=\"TermStartValue(line)\"\n (change)=\"SetTermStart(line, $event)\">\n <!-- Offered only when there is something to reset. A button that clears a\n value the line never stated does nothing and invites the reader to\n wonder what it did. -->\n @if (!TermStartFollowsOrderDate(line)) {\n <button\n type=\"button\"\n class=\"mjo-ol-term__reset\"\n (click)=\"ResetTermStart(line)\">\n Reset to order date\n </button>\n }\n } @else {\n <span class=\"mjo-ol-term__value\">{{ TermStartValue(line) }}</span>\n }\n <span class=\"mjo-ol-term__hint\">\n @if (TermStartIsDictated(line)) {\n Continuing existing coverage, so the term begins the day after the current\n one ends \u2014 not something this line can set.\n } @else if (TermStartFollowsOrderDate(line)) {\n Following the order date. The subscription type's rules may still adjust\n the actual start.\n } @else {\n Stated on this line, so a later change to the order date leaves it alone.\n }\n </span>\n </div>\n }\n\n @if (ExtensionFor(line); as ext) {\n <div class=\"mjo-ol-ext\" [class.is-open]=\"IsExtensionOpen(line)\">\n <button\n type=\"button\"\n class=\"mjo-ol-ext__toggle\"\n (click)=\"ToggleExtension(line)\"\n [attr.aria-expanded]=\"IsExtensionOpen(line)\"\n [attr.aria-controls]=\"'mjo-ol-ext-' + line.ID\">\n <i class=\"fa-solid fa-chevron-right mjo-ol-ext__chev\" aria-hidden=\"true\"></i>\n <span class=\"mjo-ol-ext__label\">{{ ExtensionLabel(line) }}</span>\n @if (!IsExtensionOpen(line)) {\n <span class=\"mjo-ol-ext__hint\">{{ ExtensionHint(line) }}</span>\n }\n </button>\n <div\n class=\"mjo-ol-ext__body\"\n [id]=\"'mjo-ol-ext-' + line.ID\"\n [attr.inert]=\"IsExtensionOpen(line) ? null : ''\"\n [attr.aria-hidden]=\"!IsExtensionOpen(line)\">\n <div class=\"mjo-ol-ext__clip\">\n <mj-entity-form-host\n [Record]=\"ext\"\n [EditMode]=\"EditMode\"\n [Config]=\"ExtensionFormConfigFor(line)\"\n (FormCreated)=\"OnExtensionFormCreated($event)\"\n (Navigate)=\"OnExtensionNavigate($event)\">\n </mj-entity-form-host>\n </div>\n </div>\n </div>\n }\n </div>\n } @empty {\n <div class=\"mjo-ol-empty\">\n <i class=\"fa-solid fa-cart-plus\" aria-hidden=\"true\"></i>\n <div class=\"mjo-ol-empty__title\">Nothing on this order yet</div>\n <div>Search the catalog to add the first line.</div>\n </div>\n }\n\n @if (EditMode) {\n <div class=\"mj-typeahead mjo-ol-picker\" #pickerHost>\n <div class=\"mjo-search\">\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i>\n <input\n [(ngModel)]=\"ProductQuery\"\n (ngModelChange)=\"OnProductQueryChange()\"\n (focus)=\"OpenPicker()\"\n (blur)=\"ClosePickerSoon()\"\n (keydown)=\"OnPickerKey($event)\"\n placeholder=\"Add product \u2014 type a name or SKU\u2026\"\n autocomplete=\"off\"\n role=\"combobox\"\n aria-label=\"Add a product\"\n [attr.aria-expanded]=\"PickerOpen\">\n </div>\n\n @if (PickerOpen) {\n <div class=\"mj-typeahead-list is-open\" [class.is-up]=\"PickerOpensUp\" role=\"listbox\">\n @for (product of PickerResults; track product.ID; let i = $index) {\n <button\n type=\"button\"\n class=\"mj-typeahead-item mjo-ol-pick\"\n [class.is-cursor]=\"i === PickerCursor\"\n role=\"option\"\n [attr.aria-selected]=\"i === PickerCursor\"\n (mousedown)=\"AddProduct(product)\">\n <span class=\"mjo-ol-pick__body\">\n <span class=\"name\">{{ product.Name }}</span>\n <span class=\"mjo-ol-pick__meta\">\n <span class=\"sub\">{{ product.SKU }} \u00B7 {{ product.TypeName }}</span>\n @if (product.CompanyName) {\n <span\n class=\"mjo-ol-pick__company\"\n [class.is-foreign]=\"IsForeignCompany(product)\"\n [attr.title]=\"IsForeignCompany(product)\n ? 'Sold by ' + product.CompanyName + ', not this order\\'s company'\n : product.CompanyName\">\n <i class=\"fa-solid fa-building\" aria-hidden=\"true\"></i>\n {{ product.CompanyName }}\n </span>\n }\n </span>\n </span>\n <span class=\"end\">\n <span class=\"mjo-ol-pick__price\">{{ product.ListPrice | mjoMoney }}</span>\n <span class=\"sub\">{{ product.Taxable ? 'taxable' : 'untaxable' }}</span>\n </span>\n </button>\n } @empty {\n <div class=\"mj-typeahead-item\">\n <span class=\"muted small\">\n @if (CatalogError) { {{ CatalogError }} }\n @else if (Catalog.length === 0) { Loading catalog\u2026 }\n @else { No product matches that. }\n </span>\n </div>\n }\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host { display: block; }\n\n.mjo-ol {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-card {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-md);\n padding: var(--mj-space-3);\n}\n\n.mjo-ol-card:has(.mjo-ol-ext.is-open) {\n padding-bottom: var(--mj-space-1);\n}\n\n.mjo-ol-card__top {\n display: flex;\n align-items: flex-start;\n gap: var(--mj-space-3);\n}\n\n.mjo-ol-card__id { flex: 1; min-width: 0; }\n\n.mjo-ol-card__name {\n display: inline;\n padding: 0;\n border: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-link);\n text-align: left;\n cursor: pointer;\n text-decoration: none;\n}\n\n.mjo-ol-card__name:hover { text-decoration: underline; }\n\n.mjo-ol-card__meta {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.mjo-ol-qty {\n display: inline-flex;\n align-items: center;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n background: var(--mj-bg-surface);\n flex: none;\n}\n\n.mjo-ol-qty button {\n border: 0;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-secondary);\n width: 26px;\n height: 28px;\n font-size: 11px;\n}\n\n.mjo-ol-qty button:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-qty button:disabled {\n cursor: default;\n color: var(--mj-text-disabled);\n}\n\n.mjo-ol-qty input {\n border: 0;\n outline: 0;\n background: transparent;\n width: 46px;\n text-align: center;\n font: inherit;\n font-variant-numeric: tabular-nums;\n color: inherit;\n}\n\n.mjo-ol-qty.is-locked {\n border-color: var(--mj-border-default);\n background: transparent;\n}\n\n.mjo-ol-qty__value {\n min-width: 46px;\n padding: 0 10px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-card__price {\n flex: none;\n min-width: 108px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.mjo-ol-card__price-row {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 2px;\n height: 28px;\n}\n\n.mjo-ol-price__pencil {\n flex: none;\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-price__pencil:hover {\n color: var(--mj-text-link);\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-price__pick,\n.mjo-ol-price__amt,\n.mjo-ol-override__reason textarea {\n display: block;\n width: 100%;\n box-sizing: border-box;\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface);\n color: inherit;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-variant-numeric: tabular-nums;\n}\n\n.mjo-ol-price__pick {\n height: 28px;\n padding: 0 6px;\n text-align: left;\n flex: 1 1 180px;\n max-width: 240px;\n width: auto;\n}\n\n.mjo-ol-price__amt {\n height: 28px;\n padding: 0 8px;\n text-align: right;\n font-weight: var(--mj-font-semibold);\n width: 108px;\n flex: none;\n}\n\n.mjo-ol-override {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n padding: var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__row {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n}\n\n.mjo-ol-override__reason span {\n display: block;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n margin-bottom: 4px;\n}\n\n.mjo-ol-override__reason.is-off {\n opacity: 0.55;\n}\n\n.mjo-ol-override__reason textarea:disabled {\n cursor: not-allowed;\n background: var(--mj-bg-surface-subtle, var(--mj-bg-surface));\n}\n\n.mjo-ol-override__reason textarea {\n resize: vertical;\n min-height: 48px;\n padding: 6px 8px;\n text-align: left;\n font-variant-numeric: normal;\n}\n\n.mjo-ol-override__actions {\n display: flex;\n gap: var(--mj-space-2);\n justify-content: flex-end;\n}\n\n.mjo-ol-override__done,\n.mjo-ol-override__reset {\n border: 0;\n background: transparent;\n cursor: pointer;\n font: inherit;\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n padding: 4px 8px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-override__done {\n color: var(--mj-text-link);\n}\n\n.mjo-ol-override__reset {\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-override__done:hover,\n.mjo-ol-override__reset:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-card__amt {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-overpill {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-status-warning-text);\n background: color-mix(in srgb, var(--mj-status-warning-text) 16%, transparent);\n}\n\n.mjo-ol-card__err {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n margin-top: 2px;\n}\n\n.mjo-ol-card__tot {\n flex: none;\n min-width: 104px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n text-align: right;\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n line-height: 28px;\n}\n\n.mjo-ol-iconbtn {\n border: 0;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-iconbtn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-status-error);\n}\n\n.mjo-ol-card__conseq {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n/* Term start \u2014 subscription lines only. One row that wraps, so the hint drops below the field on a\n narrow card rather than squeezing the date input. */\n.mjo-ol-term {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-wrap: wrap;\n margin-top: var(--mj-space-2);\n}\n\n.mjo-ol-term__label {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-term__input {\n height: 28px;\n padding: 0 var(--mj-space-2);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: var(--mj-text-sm);\n}\n\n/* A DEFAULT reads quieter than a stated value \u2014 the same distinction the order header draws\n between a date somebody chose and one that fell out of a rule. */\n.mjo-ol-term__input.is-default {\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__value {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n font-variant-numeric: tabular-nums;\n}\n\n/* A dictated date is a FACT, not a disabled input: shown in the read-mode weight in edit mode too,\n so nothing on the card suggests a control that has been switched off. */\n.mjo-ol-term__value.is-dictated {\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-term__reset {\n border: 0;\n background: transparent;\n padding: 0;\n color: var(--mj-text-link);\n font-size: var(--mj-text-xs);\n cursor: pointer;\n}\n\n.mjo-ol-term__reset:hover {\n text-decoration: underline;\n}\n\n.mjo-ol-term__hint {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mjo-ol-card__why {\n margin-top: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n line-height: 1.35;\n}\n\n.mjo-ol-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-1);\n padding: var(--mj-space-4) var(--mj-space-3);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n text-align: center;\n}\n\n.mjo-ol-empty i {\n font-size: var(--mj-text-2xl);\n color: var(--mj-brand-primary);\n}\n\n.mjo-ol-empty__title {\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-picker {\n position: relative;\n z-index: 20;\n}\n\n.mjo-ol-picker:has(.mj-typeahead-list.is-open) {\n z-index: 40;\n}\n\n.mjo-search {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n padding: 8px 10px;\n}\n\n.mjo-search i { color: var(--mj-text-muted); font-size: 12px; }\n\n.mjo-search input {\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: var(--mj-text-sm);\n color: inherit;\n width: 100%;\n}\n\n.mj-typeahead-list {\n display: none;\n position: absolute;\n left: 0;\n right: 0;\n top: calc(100% + 4px);\n max-height: 240px;\n overflow: auto;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md, 0 8px 24px rgba(0, 0, 0, 0.18));\n z-index: 30;\n}\n\n.mj-typeahead-list.is-open { display: block; }\n\n.mj-typeahead-list.is-up {\n top: auto;\n bottom: calc(100% + 4px);\n}\n\n.mj-typeahead-item {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n width: 100%;\n padding: 8px 12px;\n border: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n font: inherit;\n}\n\n.mj-typeahead-item:last-child { border-bottom: 0; }\n\n.mj-typeahead-item:hover,\n.mj-typeahead-item.is-cursor {\n background: var(--mj-bg-surface-hover);\n}\n\n.mjo-ol-pick__body {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.mjo-ol-pick .name { font-size: 13px; font-weight: var(--mj-font-semibold); }\n.mjo-ol-pick .sub { font-size: 11.5px; color: var(--mj-text-muted); }\n\n/*\n COMPANY IS ITS OWN ELEMENT, not the third item in a muted \"SKU \u00B7 type \u00B7 company\" run.\n Two similarly named products from different companies are exactly what this picker has to let\n someone tell apart before they pick, and a company set in the same muted grey as everything\n else, in third position, is not something anyone reads at speed.\n*/\n.mjo-ol-pick__meta {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n min-width: 0;\n}\n\n.mjo-ol-pick__company {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex: 0 0 auto;\n font-size: 11px;\n line-height: 1.2;\n padding: 2px 6px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-sm);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.mjo-ol-pick__company i { font-size: 9.5px; color: var(--mj-text-muted); }\n\n/* Another company's product \u2014 offered on purpose (BCC sells SoundPost), so it is marked, not hidden. */\n.mjo-ol-pick__company.is-foreign i { color: var(--mj-status-info); }\n.mjo-ol-pick__company.is-foreign {\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n.mjo-ol-pick .end {\n margin-left: auto;\n text-align: right;\n display: flex;\n flex-direction: column;\n gap: 1px;\n flex: 0 0 auto;\n}\n.mjo-ol-pick__price {\n font-variant-numeric: tabular-nums;\n font-weight: var(--mj-font-semibold);\n}\n\n.mjo-ol-ext-err {\n font-size: var(--mj-text-xs);\n color: var(--mj-status-error-text);\n}\n\n.mjo-ol-ext {\n margin-top: var(--mj-space-2);\n padding-top: var(--mj-space-1);\n border-top: 1px dashed var(--mj-border-subtle);\n}\n\n.mjo-ol-ext__toggle {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-1) 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n border-radius: var(--mj-radius-sm);\n}\n\n.mjo-ol-ext__toggle:hover {\n color: var(--mj-text-primary);\n}\n\n.mjo-ol-ext__toggle:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n.mjo-ol-ext__chev {\n flex: none;\n width: 12px;\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 160ms ease;\n}\n\n.mjo-ol-ext.is-open .mjo-ol-ext__chev {\n transform: rotate(90deg);\n}\n\n.mjo-ol-ext__label {\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n letter-spacing: 0.01em;\n}\n\n.mjo-ol-ext__hint {\n margin-left: auto;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mjo-ol-ext__body {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 180ms ease;\n}\n\n.mjo-ol-ext.is-open .mjo-ol-ext__body {\n grid-template-rows: 1fr;\n}\n\n.mjo-ol-ext__clip {\n overflow: hidden;\n min-height: 0;\n}\n\n/* Flatten the embedded extension form so its fields sit in the line card. */\n.mjo-ol-ext ::ng-deep mj-record-form-container,\n.mjo-ol-ext ::ng-deep .mj-record-form-container,\n.mjo-ol-ext ::ng-deep .mj-forms-container {\n display: block;\n padding: 0;\n margin: 0;\n border: 0;\n background: transparent;\n box-shadow: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-toolbar,\n.mjo-ol-ext ::ng-deep mj-form-toolbar {\n display: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel {\n border: 0;\n background: transparent;\n box-shadow: none;\n margin: 0;\n padding: 0;\n}\n\n.mjo-ol-ext ::ng-deep mj-collapsible-panel + mj-collapsible-panel .mj-forms-panel {\n margin-top: calc(-1 * var(--mj-space-1));\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel-header {\n display: none;\n}\n\n.mjo-ol-ext ::ng-deep .mj-forms-panel-body,\n.mjo-ol-ext ::ng-deep .mj-forms-panel-content {\n max-height: none;\n overflow: visible;\n padding: 0;\n margin: 0;\n}\n\n.mjo-ol-ext ::ng-deep mj-form-field:last-child,\n.mjo-ol-ext ::ng-deep .mj-form-field:last-child {\n margin-bottom: 0;\n}\n\n@media (max-width: 720px) {\n .mjo-ol-card__top { flex-wrap: wrap; }\n .mjo-ol-card__price, .mjo-ol-card__tot { width: auto; }\n}\n"] }]
|
|
1250
1310
|
}], null, { Provider: [{
|
|
1251
1311
|
type: Input
|
|
1252
1312
|
}], EditMode: [{
|
|
@@ -1261,5 +1321,5 @@ export class MJOOrderLinesEditorComponent {
|
|
|
1261
1321
|
type: ViewChild,
|
|
1262
1322
|
args: ['pickerHost']
|
|
1263
1323
|
}] }); })();
|
|
1264
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJOOrderLinesEditorComponent, { className: "MJOOrderLinesEditorComponent", filePath: "lib/custom/OrderHeader/order-lines-editor.component.ts", lineNumber:
|
|
1324
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJOOrderLinesEditorComponent, { className: "MJOOrderLinesEditorComponent", filePath: "lib/custom/OrderHeader/order-lines-editor.component.ts", lineNumber: 84 }); })();
|
|
1265
1325
|
//# sourceMappingURL=order-lines-editor.component.js.map
|