@metrifox/angular-sdk 0.0.2-beta.2 → 0.0.2-beta.3
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/fesm2022/index.mjs +1536 -1343
- package/dist/lib/metrifox.service.d.ts +5 -5
- package/dist/lib/types/enum.d.ts +4 -2
- package/dist/lib/types/interface.d.ts +5 -0
- package/dist/modules/customer-portal/components/billing-history.component.d.ts +3 -2
- package/dist/modules/customer-portal/components/credit/credit-balance-section.component.d.ts +12 -10
- package/dist/modules/customer-portal/components/customer-portal.component.d.ts +7 -7
- package/dist/modules/customer-portal/components/entitlements/entitlement-summary.component.d.ts +15 -0
- package/dist/modules/customer-portal/components/entitlements/entitlement-usage.component.d.ts +35 -0
- package/dist/modules/customer-portal/components/entitlements/entitlements-section.component.d.ts +5 -21
- package/dist/modules/customer-portal/components/invoice-preview.component.d.ts +8 -7
- package/dist/modules/customer-portal/components/payment.component.d.ts +4 -3
- package/dist/modules/customer-portal/components/plan/plans-section.component.d.ts +28 -26
- package/dist/modules/customer-portal/components/subscription/subscription-details.component.d.ts +12 -0
- package/dist/modules/customer-portal/components/subscription/subscription-items.component.d.ts +27 -0
- package/dist/modules/customer-portal/components/subscription/subscription-section.component.d.ts +5 -25
- package/dist/modules/pricing-table/components/pricing-table.component.d.ts +12 -6
- package/dist/modules/pricing-table/utils/defaults.d.ts +2 -0
- package/dist/public-api.d.ts +10 -10
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/fesm2022/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, Injectable, EventEmitter,
|
|
2
|
+
import { signal, Injectable, EventEmitter, Output, Input, ChangeDetectionStrategy, Component, inject, computed, NgModule } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common/http';
|
|
4
4
|
import { HttpHeaders, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
|
5
5
|
import { BehaviorSubject, throwError, Subject, takeUntil, forkJoin } from 'rxjs';
|
|
@@ -175,6 +175,9 @@ function customerPortalThemeToCssVars(theme) {
|
|
|
175
175
|
// Plan Button
|
|
176
176
|
s(vars, '--pt-button-bg', theme.plans?.planButton?.background);
|
|
177
177
|
s(vars, '--pt-button-text', theme.plans?.planButton?.textColor);
|
|
178
|
+
s(vars, '--pt-button-secondary-bg', theme.plans?.planButton?.secondaryBackground);
|
|
179
|
+
s(vars, '--pt-button-secondary-text', theme.plans?.planButton?.secondaryTextColor);
|
|
180
|
+
s(vars, '--pt-button-link', theme.plans?.planButton?.textButtonColor);
|
|
178
181
|
// Plan Toggle
|
|
179
182
|
s(vars, '--pt-interval-bg', theme.plans?.planToggle?.background);
|
|
180
183
|
s(vars, '--pt-interval-active-bg', theme.plans?.planToggle?.activeBackground);
|
|
@@ -269,8 +272,8 @@ function getGradient(theme) {
|
|
|
269
272
|
const gradientColor = theme.plans?.currentPlanCard?.gradientColor;
|
|
270
273
|
return {
|
|
271
274
|
gradient: {
|
|
272
|
-
100: `linear-gradient(180deg, ${gradientColor} 4.81%, rgba(222, 247, 100, 0) 42.31%)
|
|
273
|
-
}
|
|
275
|
+
100: `linear-gradient(180deg, ${gradientColor} 4.81%, rgba(222, 247, 100, 0) 42.31%)`
|
|
276
|
+
}
|
|
274
277
|
};
|
|
275
278
|
}
|
|
276
279
|
/**
|
|
@@ -326,7 +329,7 @@ class MetrifoxService {
|
|
|
326
329
|
const fullConfig = {
|
|
327
330
|
...config,
|
|
328
331
|
baseUrl: config.baseUrl || DEFAULT_BASE_URL,
|
|
329
|
-
webAppUrl: config.webAppUrl || DEFAULT_WEB_APP_URL
|
|
332
|
+
webAppUrl: config.webAppUrl || DEFAULT_WEB_APP_URL
|
|
330
333
|
};
|
|
331
334
|
MetrifoxService._config.set(fullConfig);
|
|
332
335
|
MetrifoxService._initialized.set(true);
|
|
@@ -397,7 +400,7 @@ class MetrifoxService {
|
|
|
397
400
|
const clientKey = MetrifoxService.getClientKey();
|
|
398
401
|
return new HttpHeaders({
|
|
399
402
|
'x-client-key': clientKey,
|
|
400
|
-
'Content-Type': 'application/json'
|
|
403
|
+
'Content-Type': 'application/json'
|
|
401
404
|
});
|
|
402
405
|
}
|
|
403
406
|
/**
|
|
@@ -442,7 +445,7 @@ class MetrifoxService {
|
|
|
442
445
|
return this.http
|
|
443
446
|
.get(url, {
|
|
444
447
|
headers: this.getHeaders(),
|
|
445
|
-
params: params
|
|
448
|
+
params: params
|
|
446
449
|
})
|
|
447
450
|
.pipe(map((response) => response.data), catchError(this.handleError));
|
|
448
451
|
}
|
|
@@ -537,7 +540,7 @@ class MetrifoxService {
|
|
|
537
540
|
const url = `${MetrifoxService.getBaseUrl()}/sdk/subscriptions/schedule-cancellation`;
|
|
538
541
|
return this.http
|
|
539
542
|
.post(url, { subscription_id: subscriptionId, ...options }, {
|
|
540
|
-
headers: this.getHeaders()
|
|
543
|
+
headers: this.getHeaders()
|
|
541
544
|
})
|
|
542
545
|
.pipe(map((response) => response.data), catchError(this.handleError));
|
|
543
546
|
}
|
|
@@ -612,8 +615,8 @@ class MetrifoxService {
|
|
|
612
615
|
params: {
|
|
613
616
|
offering_key: params.offeringKey,
|
|
614
617
|
...(params.billingInterval && { billing_interval: params.billingInterval }),
|
|
615
|
-
...(params.customerKey && { customer_key: params.customerKey })
|
|
616
|
-
}
|
|
618
|
+
...(params.customerKey && { customer_key: params.customerKey })
|
|
619
|
+
}
|
|
617
620
|
})
|
|
618
621
|
.pipe(map((response) => response.data.checkout_url), catchError(this.handleError));
|
|
619
622
|
}
|
|
@@ -621,7 +624,7 @@ class MetrifoxService {
|
|
|
621
624
|
* Build checkout URL manually
|
|
622
625
|
*/
|
|
623
626
|
buildCheckoutUrl(checkoutUsername, offeringKey, options) {
|
|
624
|
-
|
|
627
|
+
const url = `${MetrifoxService.getWebAppUrl()}/${checkoutUsername}/checkout/${offeringKey}`;
|
|
625
628
|
const params = new URLSearchParams();
|
|
626
629
|
if (options?.billingPeriod) {
|
|
627
630
|
params.set('billing_period', options.billingPeriod);
|
|
@@ -644,7 +647,7 @@ class MetrifoxService {
|
|
|
644
647
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: MetrifoxService, decorators: [{
|
|
645
648
|
type: Injectable,
|
|
646
649
|
args: [{
|
|
647
|
-
providedIn: 'root'
|
|
650
|
+
providedIn: 'root'
|
|
648
651
|
}]
|
|
649
652
|
}], ctorParameters: () => [{ type: i1.HttpClient }] });
|
|
650
653
|
/**
|
|
@@ -656,20 +659,20 @@ function metrifoxInit(config) {
|
|
|
656
659
|
}
|
|
657
660
|
|
|
658
661
|
const ICONS$1 = {
|
|
659
|
-
money:
|
|
660
|
-
cardReceive:
|
|
661
|
-
settings:
|
|
662
|
-
settingsAlt:
|
|
663
|
-
closeCircle:
|
|
664
|
-
walletEmpty:
|
|
665
|
-
noteEmpty:
|
|
666
|
-
receipt:
|
|
667
|
-
radar:
|
|
668
|
-
arrowDown:
|
|
669
|
-
arrowDownRight:
|
|
670
|
-
subtitle:
|
|
671
|
-
subtitleLarge:
|
|
672
|
-
check:
|
|
662
|
+
money: '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M17 21.25H7c-3.65 0-5.75-2.1-5.75-5.75v-7c0-3.65 2.1-5.75 5.75-5.75h10c3.65 0 5.75 2.1 5.75 5.75v7c0 3.65-2.1 5.75-5.75 5.75Zm-10-17c-2.86 0-4.25 1.39-4.25 4.25v7c0 2.86 1.39 4.25 4.25 4.25h10c2.86 0 4.25-1.39 4.25-4.25v-7c0-2.86-1.39-4.25-4.25-4.25H7Z"></path><path d="M12 15.75c-2.07 0-3.75-1.68-3.75-3.75 0-2.07 1.68-3.75 3.75-3.75 2.07 0 3.75 1.68 3.75 3.75 0 2.07-1.68 3.75-3.75 3.75Zm0-6c-1.24 0-2.25 1.01-2.25 2.25s1.01 2.25 2.25 2.25 2.25-1.01 2.25-2.25S13.24 9.75 12 9.75ZM5.5 15.25c-.41 0-.75-.34-.75-.75v-5c0-.41.34-.75.75-.75s.75.34.75.75v5c0 .41-.34.75-.75.75ZM18.5 15.25c-.41 0-.75-.34-.75-.75v-5c0-.41.34-.75.75-.75s.75.34.75.75v5c0 .41-.34.75-.75.75Z"></path></svg>',
|
|
663
|
+
cardReceive: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2 8.5H14.5"/><path d="M6 16.5H8"/><path d="M10.5 16.5H14.5"/><path d="M22 12.03V16.11C22 19.62 21.11 20.5 17.56 20.5H6.44C2.89 20.5 2 19.62 2 16.11V7.89C2 4.38 2.89 3.5 6.44 3.5H14.5"/><path d="M20 3.5V9.5L22 7.5"/><path d="M20 9.5L18 7.5"/></svg>',
|
|
664
|
+
settings: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>',
|
|
665
|
+
settingsAlt: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>',
|
|
666
|
+
closeCircle: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.49 2 2 6.49 2 12s4.49 10 10 10 10-4.49 10-10S17.51 2 12 2Zm3.36 12.3c.29.29.29.77 0 1.06-.15.15-.34.22-.53.22s-.38-.07-.53-.22l-2.3-2.3-2.3 2.3c-.15.15-.34.22-.53.22s-.38-.07-.53-.22a.754.754 0 0 1 0-1.06l2.3-2.3-2.3-2.3a.754.754 0 0 1 0-1.06c.29-.29.77-.29 1.06 0l2.3 2.3 2.3-2.3c.29-.29.77-.29 1.06 0 .29.29.29.77 0 1.06l-2.3 2.3 2.3 2.3Z"/></svg>',
|
|
667
|
+
walletEmpty: '<svg xmlns="http://www.w3.org/2000/svg" width="84" height="84" viewBox="0 0 24 24" fill="none" stroke="#9CA3AF" stroke-width="1"><path d="M18.04 13.55c-.42.41-.66 1-.6 1.63.09 1.08 1.08 1.87 2.16 1.87h1.9v1.19c0 2.07-1.69 3.76-3.76 3.76H6.26c-2.07 0-3.76-1.69-3.76-3.76v-6.73c0-2.07 1.69-3.76 3.76-3.76h11.48c2.07 0 3.76 1.69 3.76 3.76v1.44h-2.02c-.56 0-1.07.22-1.44.6Z"/><path d="M2.5 12.41V7.84c0-1.19.73-2.25 1.84-2.67l7.94-3a1.9 1.9 0 0 1 2.57 1.78v3.8"/><path d="M22.56 13.97v2.06c0 .55-.44 1-1 1.02h-1.96c-1.08 0-2.07-.79-2.16-1.87-.06-.63.18-1.22.6-1.63.37-.38.88-.6 1.44-.6h2.08c.56.02 1 .47 1 1.02Z"/><path d="M7 12h7"/></svg>',
|
|
668
|
+
noteEmpty: '<svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" viewBox="0 0 24 24" fill="none" stroke="#E5E5E5" stroke-width="1"><path d="M8 2v3M16 2v3M3.5 9.09h17M21 8.5V17c0 3-1.5 5-5 5H8c-3.5 0-5-2-5-5V8.5c0-3 1.5-5 5-5h8c3.5 0 5 2 5 5Z"/><path d="M15.695 13.7h.009M15.695 16.7h.009M11.995 13.7h.01M11.995 16.7h.01M8.294 13.7h.01M8.294 16.7h.01"/></svg>',
|
|
669
|
+
receipt: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M22 6V8.42C22 10 21 11 19.42 11H16V4.01C16 2.9 16.91 2 18.02 2C19.11 2.01 20.11 2.45 20.83 3.17C21.55 3.9 22 4.9 22 6Z" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M2 7V21C2 21.83 2.94 22.3 3.6 21.8L5.31 20.52C5.71 20.22 6.27 20.26 6.63 20.62L8.29 22.29C8.68 22.68 9.32 22.68 9.71 22.29L11.39 20.61C11.74 20.26 12.3 20.22 12.69 20.52L14.4 21.8C15.06 22.29 16 21.82 16 21V4C16 2.9 16.9 2 18 2H7H6C3 2 2 3.79 2 6V7Z" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M9 13.01H12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M9 9.01H12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M5.99609 13H6.00508" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M5.99609 9H6.00508" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',
|
|
670
|
+
radar: '<svg width="16" height="16" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.99967 3.33333C5.11301 2.5 6.49967 2 7.99967 2C11.6797 2 14.6663 4.98667 14.6663 8.66667C14.6663 12.3467 11.6797 15.3333 7.99967 15.3333C4.31967 15.3333 1.33301 12.3467 1.33301 8.66667C1.33301 7.46 1.653 6.32666 2.21967 5.34666L7.99967 8.66667" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>',
|
|
671
|
+
arrowDown: '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"></path></svg>',
|
|
672
|
+
arrowDownRight: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M7 7l10 10M17 7v10H7"/></svg>',
|
|
673
|
+
subtitle: '<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M9.99967 15.1663H5.99967C2.37967 15.1663 0.833008 13.6197 0.833008 9.99967V5.99967C0.833008 2.37967 2.37967 0.833008 5.99967 0.833008H9.99967C13.6197 0.833008 15.1663 2.37967 15.1663 5.99967V9.99967C15.1663 13.6197 13.6197 15.1663 9.99967 15.1663ZM5.99967 1.83301C2.92634 1.83301 1.83301 2.92634 1.83301 5.99967V9.99967C1.83301 13.073 2.92634 14.1663 5.99967 14.1663H9.99967C13.073 14.1663 14.1663 13.073 14.1663 9.99967V5.99967C14.1663 2.92634 13.073 1.83301 9.99967 1.83301H5.99967Z"/><path d="M11.6669 11.8867H10.4336C10.1603 11.8867 9.93359 11.6601 9.93359 11.3867C9.93359 11.1134 10.1603 10.8867 10.4336 10.8867H11.6669C11.9403 10.8867 12.1669 11.1134 12.1669 11.3867C12.1669 11.6601 11.9403 11.8867 11.6669 11.8867Z"/><path d="M8.64634 11.8867H4.33301C4.05967 11.8867 3.83301 11.6601 3.83301 11.3867C3.83301 11.1134 4.05967 10.8867 4.33301 10.8867H8.64634C8.91967 10.8867 9.14634 11.1134 9.14634 11.3867C9.14634 11.6601 8.92634 11.8867 8.64634 11.8867Z"/><path d="M11.6671 9.37988H7.98047C7.70714 9.37988 7.48047 9.15322 7.48047 8.87988C7.48047 8.60655 7.70714 8.37988 7.98047 8.37988H11.6671C11.9405 8.37988 12.1671 8.60655 12.1671 8.87988C12.1671 9.15322 11.9405 9.37988 11.6671 9.37988Z"/><path d="M6.17967 9.37988H4.33301C4.05967 9.37988 3.83301 9.15322 3.83301 8.87988C3.83301 8.60655 4.05967 8.37988 4.33301 8.37988H6.17967C6.45301 8.37988 6.67967 8.60655 6.67967 8.87988C6.67967 9.15322 6.45301 9.37988 6.17967 9.37988Z"/></svg>',
|
|
674
|
+
subtitleLarge: '<svg width="40" height="40" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M9.99967 15.1663H5.99967C2.37967 15.1663 0.833008 13.6197 0.833008 9.99967V5.99967C0.833008 2.37967 2.37967 0.833008 5.99967 0.833008H9.99967C13.6197 0.833008 15.1663 2.37967 15.1663 5.99967V9.99967C15.1663 13.6197 13.6197 15.1663 9.99967 15.1663ZM5.99967 1.83301C2.92634 1.83301 1.83301 2.92634 1.83301 5.99967V9.99967C1.83301 13.073 2.92634 14.1663 5.99967 14.1663H9.99967C13.073 14.1663 14.1663 13.073 14.1663 9.99967V5.99967C14.1663 2.92634 13.073 1.83301 9.99967 1.83301H5.99967Z"/><path d="M11.6669 11.8867H10.4336C10.1603 11.8867 9.93359 11.6601 9.93359 11.3867C9.93359 11.1134 10.1603 10.8867 10.4336 10.8867H11.6669C11.9403 10.8867 12.1669 11.1134 12.1669 11.3867C12.1669 11.6601 11.9403 11.8867 11.6669 11.8867Z"/><path d="M8.64634 11.8867H4.33301C4.05967 11.8867 3.83301 11.6601 3.83301 11.3867C3.83301 11.1134 4.05967 10.8867 4.33301 10.8867H8.64634C8.91967 10.8867 9.14634 11.1134 9.14634 11.3867C9.14634 11.6601 8.92634 11.8867 8.64634 11.8867Z"/><path d="M11.6671 9.37988H7.98047C7.70714 9.37988 7.48047 9.15322 7.48047 8.87988C7.48047 8.60655 7.70714 8.37988 7.98047 8.37988H11.6671C11.9405 8.37988 12.1671 8.60655 12.1671 8.87988C12.1671 9.15322 11.9405 9.37988 11.6671 9.37988Z"/><path d="M6.17967 9.37988H4.33301C4.05967 9.37988 3.83301 9.15322 3.83301 8.87988C3.83301 8.60655 4.05967 8.37988 4.33301 8.37988H6.17967C6.45301 8.37988 6.67967 8.60655 6.67967 8.87988C6.67967 9.15322 6.45301 9.37988 6.17967 9.37988Z"/></svg>',
|
|
675
|
+
check: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>'
|
|
673
676
|
};
|
|
674
677
|
|
|
675
678
|
const iconCache = new Map();
|
|
@@ -688,14 +691,14 @@ const defaultCustomerPortalTheme = {
|
|
|
688
691
|
backgroundColor: '#ffffff',
|
|
689
692
|
borderRadius: '16px',
|
|
690
693
|
fontFamily: 'inherit',
|
|
691
|
-
containerPadding: '24px'
|
|
694
|
+
containerPadding: '24px'
|
|
692
695
|
},
|
|
693
696
|
tabs: {
|
|
694
697
|
tabBackground: '#ffffff',
|
|
695
698
|
tabBorderColor: '#E4E4E7',
|
|
696
699
|
activeTabBackground: '#3D3D3D',
|
|
697
700
|
activeTabTextColor: '#ffffff',
|
|
698
|
-
inactiveTabTextColor: '#71717A'
|
|
701
|
+
inactiveTabTextColor: '#71717A'
|
|
699
702
|
},
|
|
700
703
|
sections: {
|
|
701
704
|
background: '#ffffff',
|
|
@@ -705,13 +708,13 @@ const defaultCustomerPortalTheme = {
|
|
|
705
708
|
emptyTextColor: '#A1A1AA',
|
|
706
709
|
usage: {
|
|
707
710
|
barColor: '#006FEE',
|
|
708
|
-
trackColor: '#E4E4E7'
|
|
711
|
+
trackColor: '#E4E4E7'
|
|
709
712
|
},
|
|
710
713
|
content: {
|
|
711
714
|
background: '#F4F4F5',
|
|
712
715
|
padding: '24px',
|
|
713
716
|
borderColor: '#E4E4E7',
|
|
714
|
-
borderRadius: '8px'
|
|
717
|
+
borderRadius: '8px'
|
|
715
718
|
},
|
|
716
719
|
summaryBalance: {
|
|
717
720
|
background: '#ffffff',
|
|
@@ -720,23 +723,23 @@ const defaultCustomerPortalTheme = {
|
|
|
720
723
|
borderRadius: '8px',
|
|
721
724
|
label: { fontSize: '13px', fontWeight: '500', color: '#71717A' },
|
|
722
725
|
value: { fontSize: '20px', fontWeight: '700', color: '#52525B' },
|
|
723
|
-
unit: { fontSize: '13px', fontWeight: '500', color: '#52525B' }
|
|
726
|
+
unit: { fontSize: '13px', fontWeight: '500', color: '#52525B' }
|
|
724
727
|
},
|
|
725
728
|
header: { fontSize: '16px', fontWeight: '600', color: '#52525B' },
|
|
726
729
|
label: { fontSize: '13px', fontWeight: '500', color: '#71717A' },
|
|
727
|
-
value: { fontSize: '14px', fontWeight: '500', color: '#52525B' }
|
|
730
|
+
value: { fontSize: '14px', fontWeight: '500', color: '#52525B' }
|
|
728
731
|
},
|
|
729
732
|
buttons: {
|
|
730
733
|
primary: {
|
|
731
734
|
backgroundColor: '#3D3D3D',
|
|
732
735
|
border: { color: '#52525B', width: '1px', radius: '8px' },
|
|
733
|
-
typography: { fontSize: '14px', fontWeight: '500', color: '#ffffff' }
|
|
736
|
+
typography: { fontSize: '14px', fontWeight: '500', color: '#ffffff' }
|
|
734
737
|
},
|
|
735
738
|
secondary: {
|
|
736
739
|
backgroundColor: '#E4E4E7',
|
|
737
740
|
border: { color: '#E4E4E7', width: '1px', radius: '8px' },
|
|
738
|
-
typography: { fontSize: '13px', fontWeight: '500', color: '#3F3F46' }
|
|
739
|
-
}
|
|
741
|
+
typography: { fontSize: '13px', fontWeight: '500', color: '#3F3F46' }
|
|
742
|
+
}
|
|
740
743
|
},
|
|
741
744
|
lineItems: {
|
|
742
745
|
parentRow: {
|
|
@@ -744,17 +747,17 @@ const defaultCustomerPortalTheme = {
|
|
|
744
747
|
borderColor: '#E4E4E7',
|
|
745
748
|
typography: {
|
|
746
749
|
label: { color: '#111827' },
|
|
747
|
-
quantity: { color: '#71717A' }
|
|
748
|
-
}
|
|
750
|
+
quantity: { color: '#71717A' }
|
|
751
|
+
}
|
|
749
752
|
},
|
|
750
753
|
childRow: {
|
|
751
754
|
background: '#ffffff',
|
|
752
755
|
borderColor: '#E4E4E7',
|
|
753
756
|
typography: {
|
|
754
757
|
label: { color: '#111827' },
|
|
755
|
-
quantity: { color: '#71717A' }
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
+
quantity: { color: '#71717A' }
|
|
759
|
+
}
|
|
760
|
+
}
|
|
758
761
|
},
|
|
759
762
|
tables: {
|
|
760
763
|
headerBackground: '#E4E4E7',
|
|
@@ -769,8 +772,8 @@ const defaultCustomerPortalTheme = {
|
|
|
769
772
|
fontSize: '14px',
|
|
770
773
|
fontWeight: '400',
|
|
771
774
|
headerFontSize: '14px',
|
|
772
|
-
headerFontWeight: '500'
|
|
773
|
-
}
|
|
775
|
+
headerFontWeight: '500'
|
|
776
|
+
}
|
|
774
777
|
},
|
|
775
778
|
modals: {
|
|
776
779
|
overlayColor: 'rgba(0, 0, 0, 0.4)',
|
|
@@ -787,14 +790,14 @@ const defaultCustomerPortalTheme = {
|
|
|
787
790
|
backgroundColor: 'transparent',
|
|
788
791
|
textColor: '#3F3F46',
|
|
789
792
|
borderColor: '#E4E4E7',
|
|
790
|
-
borderWidth: '1px'
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
+
borderWidth: '1px'
|
|
794
|
+
}
|
|
795
|
+
}
|
|
793
796
|
},
|
|
794
797
|
plans: {
|
|
795
798
|
currentPlanCard: {
|
|
796
799
|
header: { background: '#E4E4E7', textColor: '#111827' },
|
|
797
|
-
gradientColor: '#E4E4E7'
|
|
800
|
+
gradientColor: '#E4E4E7'
|
|
798
801
|
},
|
|
799
802
|
planCards: {
|
|
800
803
|
background: '#ffffff',
|
|
@@ -806,19 +809,25 @@ const defaultCustomerPortalTheme = {
|
|
|
806
809
|
primaryTextColor: '#71717A',
|
|
807
810
|
secondaryTextColor: '#A1A1AA',
|
|
808
811
|
background: 'transparent',
|
|
809
|
-
borderColor: 'transparent'
|
|
810
|
-
}
|
|
812
|
+
borderColor: 'transparent'
|
|
813
|
+
}
|
|
811
814
|
},
|
|
812
815
|
planFeatures: { textColor: '#3F3F46', iconColor: '#0BB02F' },
|
|
813
|
-
planButton: {
|
|
816
|
+
planButton: {
|
|
817
|
+
background: '#3D3D3D',
|
|
818
|
+
textColor: '#ffffff',
|
|
819
|
+
secondaryBackground: '#E4E4E7',
|
|
820
|
+
secondaryTextColor: '#3F3F46',
|
|
821
|
+
textButtonColor: '#2563eb'
|
|
822
|
+
},
|
|
814
823
|
planToggle: {
|
|
815
824
|
background: '#E4E4E7',
|
|
816
825
|
activeBackground: '#1f2937',
|
|
817
826
|
activeText: '#ffffff',
|
|
818
|
-
inactiveText: '#71717A'
|
|
827
|
+
inactiveText: '#71717A'
|
|
819
828
|
},
|
|
820
|
-
planTags: { freeTrialBackground: '#dbeafe', freeTrialText: '#1e40af' }
|
|
821
|
-
}
|
|
829
|
+
planTags: { freeTrialBackground: '#dbeafe', freeTrialText: '#1e40af' }
|
|
830
|
+
}
|
|
822
831
|
};
|
|
823
832
|
|
|
824
833
|
function formatDate(dateString) {
|
|
@@ -874,7 +883,7 @@ function formatPriceAmount(amount) {
|
|
|
874
883
|
function getResetIntervalLabel(interval) {
|
|
875
884
|
const map = {
|
|
876
885
|
daily: 'per day', weekly: 'per week', monthly: 'per month',
|
|
877
|
-
quarterly: 'per quarter', yearly: 'per year', biannually: 'per 6 months'
|
|
886
|
+
quarterly: 'per quarter', yearly: 'per year', biannually: 'per 6 months'
|
|
878
887
|
};
|
|
879
888
|
return map[interval?.toLowerCase()] || interval;
|
|
880
889
|
}
|
|
@@ -911,22 +920,342 @@ const DEFAULT_SECTION_LABELS = {
|
|
|
911
920
|
entitlementUsage: 'Entitlements',
|
|
912
921
|
paymentOverview: 'Payment',
|
|
913
922
|
billingHistory: 'Billing history',
|
|
914
|
-
plan: 'Plans'
|
|
923
|
+
plan: 'Plans'
|
|
915
924
|
};
|
|
916
925
|
function getSectionLabel(sectionsConfig, key) {
|
|
917
926
|
const config = sectionsConfig?.find((s) => s.key === key);
|
|
918
927
|
return config?.label || DEFAULT_SECTION_LABELS[key] || key;
|
|
919
928
|
}
|
|
920
929
|
|
|
921
|
-
class
|
|
922
|
-
|
|
923
|
-
sectionsConfig;
|
|
924
|
-
customerKey = '';
|
|
925
|
-
tenantCheckoutUsername = '';
|
|
930
|
+
class SubscriptionDetailsComponent {
|
|
931
|
+
sub;
|
|
926
932
|
invoicePreview = new EventEmitter();
|
|
927
|
-
|
|
933
|
+
_formatDate(d) {
|
|
934
|
+
return formatDate(d);
|
|
935
|
+
}
|
|
936
|
+
_formatCurrency(amount, currency) {
|
|
937
|
+
return formatCurrency(amount, currency);
|
|
938
|
+
}
|
|
939
|
+
_formatStatus(status) {
|
|
940
|
+
return formatStatus(status);
|
|
941
|
+
}
|
|
942
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: SubscriptionDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
943
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: SubscriptionDetailsComponent, isStandalone: true, selector: "cp-subscription-details", inputs: { sub: "sub" }, outputs: { invoicePreview: "invoicePreview" }, ngImport: i0, template: `
|
|
944
|
+
<!-- Plan details content box -->
|
|
945
|
+
<div data-testid="subscription-content-box"
|
|
946
|
+
class="bg-[var(--cp-section-content-bg,#F4F4F5)] border border-[var(--cp-section-content-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)]"
|
|
947
|
+
[style.padding]="'var(--cp-section-content-padding)'">
|
|
948
|
+
<div class="flex justify-between flex-wrap gap-6">
|
|
949
|
+
<div>
|
|
950
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
951
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
952
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Current plan</span>
|
|
953
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
954
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
955
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
956
|
+
{{ sub.plan_name || '-' }}
|
|
957
|
+
</div>
|
|
958
|
+
</div>
|
|
959
|
+
<div>
|
|
960
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
961
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
962
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Status</span>
|
|
963
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
964
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
965
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
966
|
+
{{ _formatStatus(sub.status) }}
|
|
967
|
+
</div>
|
|
968
|
+
</div>
|
|
969
|
+
<div>
|
|
970
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
971
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
972
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Start date</span>
|
|
973
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
974
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
975
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
976
|
+
{{ _formatDate(sub.starts_at) || '-' }}
|
|
977
|
+
</div>
|
|
978
|
+
</div>
|
|
979
|
+
@if (sub.status === 'active') {
|
|
980
|
+
<div>
|
|
981
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
982
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
983
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Current billing period</span>
|
|
984
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
985
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
986
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
987
|
+
@if (sub.current_billing_period_start && sub.current_billing_period_end) {
|
|
988
|
+
<div class="font-medium">{{ _formatDate(sub.current_billing_period_start) }} - {{ _formatDate(sub.current_billing_period_end) }}</div>
|
|
989
|
+
<div class="mt-1 text-sm opacity-80">(Auto-renew)</div>
|
|
990
|
+
} @else {
|
|
991
|
+
<span>-</span>
|
|
992
|
+
}
|
|
993
|
+
</div>
|
|
994
|
+
</div>
|
|
995
|
+
}
|
|
996
|
+
@if (sub.status === 'trialing' && sub.trial_end_date) {
|
|
997
|
+
<div>
|
|
998
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
999
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1000
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Trial end date</span>
|
|
1001
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1002
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1003
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1004
|
+
{{ _formatDate(sub.trial_end_date) }}
|
|
1005
|
+
</div>
|
|
1006
|
+
</div>
|
|
1007
|
+
<div>
|
|
1008
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1009
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1010
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Trial period</span>
|
|
1011
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1012
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1013
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1014
|
+
{{ _formatDate(sub.starts_at) }} - {{ _formatDate(sub.trial_end_date) }}
|
|
1015
|
+
</div>
|
|
1016
|
+
</div>
|
|
1017
|
+
}
|
|
1018
|
+
@if (sub.status === 'active') {
|
|
1019
|
+
<div>
|
|
1020
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1021
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1022
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">End date</span>
|
|
1023
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1024
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1025
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1026
|
+
{{ sub.ends_at ? _formatDate(sub.ends_at) : '-' }}
|
|
1027
|
+
</div>
|
|
1028
|
+
</div>
|
|
1029
|
+
}
|
|
1030
|
+
</div>
|
|
1031
|
+
</div>
|
|
1032
|
+
|
|
1033
|
+
<!-- Preview invoice link -->
|
|
1034
|
+
@if (sub.upcoming_invoice) {
|
|
1035
|
+
<div class="flex justify-end mt-2">
|
|
1036
|
+
<button type="button"
|
|
1037
|
+
class="text-[var(--cp-link-color,#3b82f6)] underline p-0 text-sm bg-transparent border-none cursor-pointer"
|
|
1038
|
+
(click)="$event.stopPropagation(); invoicePreview.emit(sub.upcoming_invoice!)">
|
|
1039
|
+
Preview invoice
|
|
1040
|
+
</button>
|
|
1041
|
+
</div>
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
<!-- Billing details content box (active only) -->
|
|
1045
|
+
@if (sub.status === 'active') {
|
|
1046
|
+
<div data-testid="subscription-content-box"
|
|
1047
|
+
class="bg-[var(--cp-section-content-bg,#F4F4F5)] border border-[var(--cp-section-content-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] mt-2"
|
|
1048
|
+
[style.padding]="'var(--cp-section-content-padding)'">
|
|
1049
|
+
<div class="flex justify-between flex-wrap gap-6">
|
|
1050
|
+
<div>
|
|
1051
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1052
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1053
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Next billing date</span>
|
|
1054
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1055
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1056
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1057
|
+
{{ sub.renews_at ? _formatDate(sub.renews_at) : '-' }}
|
|
1058
|
+
</div>
|
|
1059
|
+
</div>
|
|
1060
|
+
<div>
|
|
1061
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1062
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1063
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Invoice due</span>
|
|
1064
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1065
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1066
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1067
|
+
{{ sub.renews_at ? _formatDate(sub.renews_at) : '-' }}
|
|
1068
|
+
</div>
|
|
1069
|
+
</div>
|
|
1070
|
+
<div>
|
|
1071
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1072
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1073
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Next estimated bill</span>
|
|
1074
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1075
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1076
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1077
|
+
@if (sub.next_billing_amount) {
|
|
1078
|
+
<div class="font-medium">{{ _formatCurrency(sub.next_billing_amount, sub.currency_code) }}</div>
|
|
1079
|
+
<div class="text-sm opacity-80 mt-0.5">(Monthly)</div>
|
|
1080
|
+
} @else {
|
|
1081
|
+
<span>-</span>
|
|
1082
|
+
}
|
|
1083
|
+
</div>
|
|
1084
|
+
</div>
|
|
1085
|
+
</div>
|
|
1086
|
+
</div>
|
|
1087
|
+
}
|
|
1088
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1089
|
+
}
|
|
1090
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: SubscriptionDetailsComponent, decorators: [{
|
|
1091
|
+
type: Component,
|
|
1092
|
+
args: [{
|
|
1093
|
+
selector: 'cp-subscription-details',
|
|
1094
|
+
standalone: true,
|
|
1095
|
+
imports: [CommonModule],
|
|
1096
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1097
|
+
template: `
|
|
1098
|
+
<!-- Plan details content box -->
|
|
1099
|
+
<div data-testid="subscription-content-box"
|
|
1100
|
+
class="bg-[var(--cp-section-content-bg,#F4F4F5)] border border-[var(--cp-section-content-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)]"
|
|
1101
|
+
[style.padding]="'var(--cp-section-content-padding)'">
|
|
1102
|
+
<div class="flex justify-between flex-wrap gap-6">
|
|
1103
|
+
<div>
|
|
1104
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1105
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1106
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Current plan</span>
|
|
1107
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1108
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1109
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1110
|
+
{{ sub.plan_name || '-' }}
|
|
1111
|
+
</div>
|
|
1112
|
+
</div>
|
|
1113
|
+
<div>
|
|
1114
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1115
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1116
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Status</span>
|
|
1117
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1118
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1119
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1120
|
+
{{ _formatStatus(sub.status) }}
|
|
1121
|
+
</div>
|
|
1122
|
+
</div>
|
|
1123
|
+
<div>
|
|
1124
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1125
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1126
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Start date</span>
|
|
1127
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1128
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1129
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1130
|
+
{{ _formatDate(sub.starts_at) || '-' }}
|
|
1131
|
+
</div>
|
|
1132
|
+
</div>
|
|
1133
|
+
@if (sub.status === 'active') {
|
|
1134
|
+
<div>
|
|
1135
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1136
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1137
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Current billing period</span>
|
|
1138
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1139
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1140
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1141
|
+
@if (sub.current_billing_period_start && sub.current_billing_period_end) {
|
|
1142
|
+
<div class="font-medium">{{ _formatDate(sub.current_billing_period_start) }} - {{ _formatDate(sub.current_billing_period_end) }}</div>
|
|
1143
|
+
<div class="mt-1 text-sm opacity-80">(Auto-renew)</div>
|
|
1144
|
+
} @else {
|
|
1145
|
+
<span>-</span>
|
|
1146
|
+
}
|
|
1147
|
+
</div>
|
|
1148
|
+
</div>
|
|
1149
|
+
}
|
|
1150
|
+
@if (sub.status === 'trialing' && sub.trial_end_date) {
|
|
1151
|
+
<div>
|
|
1152
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1153
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1154
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Trial end date</span>
|
|
1155
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1156
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1157
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1158
|
+
{{ _formatDate(sub.trial_end_date) }}
|
|
1159
|
+
</div>
|
|
1160
|
+
</div>
|
|
1161
|
+
<div>
|
|
1162
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1163
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1164
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Trial period</span>
|
|
1165
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1166
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1167
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1168
|
+
{{ _formatDate(sub.starts_at) }} - {{ _formatDate(sub.trial_end_date) }}
|
|
1169
|
+
</div>
|
|
1170
|
+
</div>
|
|
1171
|
+
}
|
|
1172
|
+
@if (sub.status === 'active') {
|
|
1173
|
+
<div>
|
|
1174
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1175
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1176
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">End date</span>
|
|
1177
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1178
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1179
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1180
|
+
{{ sub.ends_at ? _formatDate(sub.ends_at) : '-' }}
|
|
1181
|
+
</div>
|
|
1182
|
+
</div>
|
|
1183
|
+
}
|
|
1184
|
+
</div>
|
|
1185
|
+
</div>
|
|
1186
|
+
|
|
1187
|
+
<!-- Preview invoice link -->
|
|
1188
|
+
@if (sub.upcoming_invoice) {
|
|
1189
|
+
<div class="flex justify-end mt-2">
|
|
1190
|
+
<button type="button"
|
|
1191
|
+
class="text-[var(--cp-link-color,#3b82f6)] underline p-0 text-sm bg-transparent border-none cursor-pointer"
|
|
1192
|
+
(click)="$event.stopPropagation(); invoicePreview.emit(sub.upcoming_invoice!)">
|
|
1193
|
+
Preview invoice
|
|
1194
|
+
</button>
|
|
1195
|
+
</div>
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
<!-- Billing details content box (active only) -->
|
|
1199
|
+
@if (sub.status === 'active') {
|
|
1200
|
+
<div data-testid="subscription-content-box"
|
|
1201
|
+
class="bg-[var(--cp-section-content-bg,#F4F4F5)] border border-[var(--cp-section-content-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] mt-2"
|
|
1202
|
+
[style.padding]="'var(--cp-section-content-padding)'">
|
|
1203
|
+
<div class="flex justify-between flex-wrap gap-6">
|
|
1204
|
+
<div>
|
|
1205
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1206
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1207
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Next billing date</span>
|
|
1208
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1209
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1210
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1211
|
+
{{ sub.renews_at ? _formatDate(sub.renews_at) : '-' }}
|
|
1212
|
+
</div>
|
|
1213
|
+
</div>
|
|
1214
|
+
<div>
|
|
1215
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1216
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1217
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Invoice due</span>
|
|
1218
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1219
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1220
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1221
|
+
{{ sub.renews_at ? _formatDate(sub.renews_at) : '-' }}
|
|
1222
|
+
</div>
|
|
1223
|
+
</div>
|
|
1224
|
+
<div>
|
|
1225
|
+
<span class="text-[var(--cp-section-label-color)]"
|
|
1226
|
+
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1227
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Next estimated bill</span>
|
|
1228
|
+
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1229
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1230
|
+
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1231
|
+
@if (sub.next_billing_amount) {
|
|
1232
|
+
<div class="font-medium">{{ _formatCurrency(sub.next_billing_amount, sub.currency_code) }}</div>
|
|
1233
|
+
<div class="text-sm opacity-80 mt-0.5">(Monthly)</div>
|
|
1234
|
+
} @else {
|
|
1235
|
+
<span>-</span>
|
|
1236
|
+
}
|
|
1237
|
+
</div>
|
|
1238
|
+
</div>
|
|
1239
|
+
</div>
|
|
1240
|
+
</div>
|
|
1241
|
+
}
|
|
1242
|
+
`
|
|
1243
|
+
}]
|
|
1244
|
+
}], propDecorators: { sub: [{
|
|
1245
|
+
type: Input,
|
|
1246
|
+
args: [{ required: true }]
|
|
1247
|
+
}], invoicePreview: [{
|
|
1248
|
+
type: Output
|
|
1249
|
+
}] } });
|
|
1250
|
+
|
|
1251
|
+
class SubscriptionItemsComponent {
|
|
928
1252
|
expandedAddons = new Set();
|
|
929
|
-
|
|
1253
|
+
items = [];
|
|
1254
|
+
canUpdateQuantities = false;
|
|
1255
|
+
tenantCheckoutUsername = '';
|
|
1256
|
+
customerKey = '';
|
|
1257
|
+
subscriptionId = '';
|
|
1258
|
+
offeringKey = '';
|
|
930
1259
|
toggleAddon(key) {
|
|
931
1260
|
if (this.expandedAddons.has(key)) {
|
|
932
1261
|
this.expandedAddons.delete(key);
|
|
@@ -938,32 +1267,27 @@ class SubscriptionSectionComponent {
|
|
|
938
1267
|
isAddonExpanded(key) {
|
|
939
1268
|
return this.expandedAddons.has(key);
|
|
940
1269
|
}
|
|
941
|
-
openUpdateItems(
|
|
942
|
-
if (!this.tenantCheckoutUsername || !
|
|
1270
|
+
openUpdateItems() {
|
|
1271
|
+
if (!this.tenantCheckoutUsername || !this.subscriptionId || !this.offeringKey)
|
|
943
1272
|
return;
|
|
944
|
-
const updateQtyUrl = `${window.location.origin}/${this.tenantCheckoutUsername}/${
|
|
1273
|
+
const updateQtyUrl = `${window.location.origin}/${this.tenantCheckoutUsername}/${this.offeringKey}/subscriptions/${this.subscriptionId}?customer=${this.customerKey}`;
|
|
945
1274
|
window.open(updateQtyUrl, '_blank', 'noopener,noreferrer');
|
|
946
1275
|
}
|
|
947
|
-
handleManagePlan() {
|
|
948
|
-
this.managePlan.emit(this.subscription);
|
|
949
|
-
}
|
|
950
1276
|
handleAddAddon() {
|
|
951
|
-
|
|
952
|
-
const subscriptionId = this.subscription?.subscription?.id;
|
|
953
|
-
if (!this.tenantCheckoutUsername || !offeringKey || !subscriptionId)
|
|
1277
|
+
if (!this.tenantCheckoutUsername || !this.offeringKey || !this.subscriptionId)
|
|
954
1278
|
return;
|
|
955
1279
|
const webAppUrl = 'https://app.metrifox.com';
|
|
956
|
-
const url = `${webAppUrl}/${this.tenantCheckoutUsername}/${offeringKey}/addons?subscription=${subscriptionId}&manage=addon_add`;
|
|
1280
|
+
const url = `${webAppUrl}/${this.tenantCheckoutUsername}/${this.offeringKey}/addons?subscription=${this.subscriptionId}&manage=addon_add`;
|
|
957
1281
|
window.open(url, '_blank', 'noopener,noreferrer');
|
|
958
1282
|
}
|
|
959
|
-
getPlanLineItems(
|
|
960
|
-
return (items || []).filter((item) => !item.is_addon);
|
|
1283
|
+
getPlanLineItems() {
|
|
1284
|
+
return (this.items || []).filter((item) => !item.is_addon);
|
|
961
1285
|
}
|
|
962
|
-
getAddonLineItems(
|
|
963
|
-
return (items || []).filter((item) => item.is_addon);
|
|
1286
|
+
getAddonLineItems() {
|
|
1287
|
+
return (this.items || []).filter((item) => item.is_addon);
|
|
964
1288
|
}
|
|
965
|
-
getGroupedAddonItems(
|
|
966
|
-
const addonItems = this.getAddonLineItems(
|
|
1289
|
+
getGroupedAddonItems() {
|
|
1290
|
+
const addonItems = this.getAddonLineItems();
|
|
967
1291
|
const groups = new Map();
|
|
968
1292
|
for (const item of addonItems) {
|
|
969
1293
|
const key = item.offering_key || item.name || item.price_option_id;
|
|
@@ -977,666 +1301,427 @@ class SubscriptionSectionComponent {
|
|
|
977
1301
|
return { key, name: baseItem?.name || key, baseItem, children };
|
|
978
1302
|
});
|
|
979
1303
|
}
|
|
980
|
-
getStatusBgClass(status) {
|
|
981
|
-
switch (status?.toLowerCase()) {
|
|
982
|
-
case 'active': return 'bg-green-500';
|
|
983
|
-
case 'trialing': return 'bg-blue-500';
|
|
984
|
-
case 'canceled':
|
|
985
|
-
case 'canceling': return 'bg-red-500';
|
|
986
|
-
case 'past_due':
|
|
987
|
-
case 'unpaid': return 'bg-yellow-500';
|
|
988
|
-
case 'paused': return 'bg-gray-500';
|
|
989
|
-
default: return 'bg-gray-500';
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
_formatDate(d) {
|
|
993
|
-
return formatDate(d);
|
|
994
|
-
}
|
|
995
|
-
_formatCurrency(amount, currency) {
|
|
996
|
-
return formatCurrency(amount, currency);
|
|
997
|
-
}
|
|
998
|
-
_formatStatus(status) {
|
|
999
|
-
return formatStatus(status);
|
|
1000
|
-
}
|
|
1001
1304
|
_capitalize(str) {
|
|
1002
1305
|
return capitalize(str || '');
|
|
1003
1306
|
}
|
|
1004
|
-
|
|
1005
|
-
return
|
|
1006
|
-
}
|
|
1007
|
-
_getSectionLabel(key) {
|
|
1008
|
-
return getSectionLabel(this.sectionsConfig, key);
|
|
1009
|
-
}
|
|
1010
|
-
_getIcon(name) {
|
|
1011
|
-
return getIcon(this.sanitizer, name);
|
|
1307
|
+
_formatCurrency(amount, currency) {
|
|
1308
|
+
return formatCurrency(amount, currency);
|
|
1012
1309
|
}
|
|
1013
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type:
|
|
1014
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type:
|
|
1015
|
-
@if (
|
|
1016
|
-
<div class="
|
|
1017
|
-
|
|
1018
|
-
[style.backgroundColor]="'var(--cp-section-bg)'"
|
|
1019
|
-
[style.borderColor]="'var(--cp-section-border)'"
|
|
1020
|
-
[style.borderRadius]="'var(--cp-section-radius)'"
|
|
1021
|
-
[style.borderWidth]="'1px'"
|
|
1022
|
-
[style.borderStyle]="'solid'">
|
|
1023
|
-
<!-- Header: title + Manage plan -->
|
|
1024
|
-
<div class="flex justify-between items-center mb-4">
|
|
1310
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: SubscriptionItemsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1311
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: SubscriptionItemsComponent, isStandalone: true, selector: "cp-subscription-items", inputs: { items: "items", canUpdateQuantities: "canUpdateQuantities", tenantCheckoutUsername: "tenantCheckoutUsername", customerKey: "customerKey", subscriptionId: "subscriptionId", offeringKey: "offeringKey" }, ngImport: i0, template: `
|
|
1312
|
+
@if (items?.length) {
|
|
1313
|
+
<div class="mt-8">
|
|
1314
|
+
<div class="flex items-center justify-between mb-4">
|
|
1025
1315
|
<span class="text-[var(--cp-section-header-color)]"
|
|
1026
1316
|
[style.fontSize]="'var(--cp-section-header-size)'"
|
|
1027
1317
|
[style.fontWeight]="'var(--cp-section-header-weight)'">
|
|
1028
|
-
|
|
1318
|
+
Subscription items
|
|
1029
1319
|
</span>
|
|
1030
|
-
@if (
|
|
1320
|
+
@if (canUpdateQuantities) {
|
|
1031
1321
|
<button type="button"
|
|
1032
|
-
class="
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
[style.borderWidth]="'var(--cp-btn-primary-border-width, 1px)'"
|
|
1036
|
-
[style.borderStyle]="'solid'"
|
|
1037
|
-
(click)="handleManagePlan()">
|
|
1038
|
-
Manage plan
|
|
1322
|
+
class="text-[var(--cp-link-color,#3b82f6)] underline p-0 font-medium bg-transparent border-none cursor-pointer"
|
|
1323
|
+
(click)="$event.stopPropagation(); openUpdateItems()">
|
|
1324
|
+
Manage item quantities
|
|
1039
1325
|
</button>
|
|
1040
1326
|
}
|
|
1041
1327
|
</div>
|
|
1042
1328
|
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
class="bg-[var(--cp-section-content-bg,#F4F4F5)] border border-[var(--cp-section-content-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)]"
|
|
1329
|
+
<div data-testid="subscription-items-container"
|
|
1330
|
+
class="rounded-[var(--cp-section-content-radius)] overflow-hidden bg-[var(--cp-section-content-bg,#F4F4F5)] border border-[var(--cp-section-content-border,#e4e4e7)]"
|
|
1046
1331
|
[style.padding]="'var(--cp-section-content-padding)'">
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Current plan</span>
|
|
1052
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1053
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1054
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1055
|
-
{{ subscription.subscription.plan_name || '-' }}
|
|
1056
|
-
</div>
|
|
1057
|
-
</div>
|
|
1058
|
-
<div>
|
|
1059
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1060
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1061
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Status</span>
|
|
1062
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1063
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1064
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1065
|
-
{{ _formatStatus(subscription.subscription.status) }}
|
|
1066
|
-
</div>
|
|
1067
|
-
</div>
|
|
1068
|
-
<div>
|
|
1332
|
+
|
|
1333
|
+
<!-- Plan items -->
|
|
1334
|
+
@if (getPlanLineItems().length > 0) {
|
|
1335
|
+
<div class="mb-3 mt-4">
|
|
1069
1336
|
<span class="text-[var(--cp-section-label-color)]"
|
|
1070
1337
|
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1071
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">
|
|
1072
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1073
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1074
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1075
|
-
{{ _formatDate(subscription.subscription.starts_at) || '-' }}
|
|
1076
|
-
</div>
|
|
1338
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Plan</span>
|
|
1077
1339
|
</div>
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
<
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Trial end date</span>
|
|
1100
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1101
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1102
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1103
|
-
{{ _formatDate(subscription.subscription.trial_end_date) }}
|
|
1104
|
-
</div>
|
|
1105
|
-
</div>
|
|
1106
|
-
<div>
|
|
1107
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1108
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1109
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Trial period</span>
|
|
1110
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1111
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1112
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1113
|
-
{{ _formatDate(subscription.subscription.starts_at) }} - {{ _formatDate(subscription.subscription.trial_end_date) }}
|
|
1114
|
-
</div>
|
|
1115
|
-
</div>
|
|
1116
|
-
}
|
|
1117
|
-
@if (subscription.subscription.status === 'active') {
|
|
1118
|
-
<div>
|
|
1119
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1120
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1121
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">End date</span>
|
|
1122
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1123
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1124
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1125
|
-
{{ subscription.subscription.ends_at ? _formatDate(subscription.subscription.ends_at) : '-' }}
|
|
1340
|
+
<div class="space-y-2">
|
|
1341
|
+
@for (item of getPlanLineItems(); track item.price_option_id) {
|
|
1342
|
+
<div class="bg-[var(--cp-subscription-item-bg,white)] border border-[var(--cp-subscription-item-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3 flex items-center justify-between">
|
|
1343
|
+
<div class="flex items-center gap-2">
|
|
1344
|
+
<span class="text-[var(--cp-subscription-item-text)]"
|
|
1345
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1346
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 600)'">
|
|
1347
|
+
{{ _capitalize(item.name) }}
|
|
1348
|
+
</span>
|
|
1349
|
+
@if (item.quantity > 0 && item.source_type !== 'plan') {
|
|
1350
|
+
<span class="text-[var(--cp-subscription-item-quantity,#6b7280)] opacity-75">•</span>
|
|
1351
|
+
<span class="text-[var(--cp-subscription-item-quantity,#6b7280)] font-normal text-sm">
|
|
1352
|
+
{{ item.quantity }} {{ item.name?.toLowerCase() }}
|
|
1353
|
+
</span>
|
|
1354
|
+
}
|
|
1355
|
+
</div>
|
|
1356
|
+
<span class="text-[var(--cp-subscription-item-text)]"
|
|
1357
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1358
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 500)'">
|
|
1359
|
+
{{ _formatCurrency(item.total_amount || item.unit_price, item.currency_code) }}
|
|
1360
|
+
</span>
|
|
1126
1361
|
</div>
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
</div>
|
|
1131
|
-
|
|
1132
|
-
<!-- Preview invoice link -->
|
|
1133
|
-
@if (subscription.subscription.upcoming_invoice) {
|
|
1134
|
-
<div class="flex justify-end mt-2">
|
|
1135
|
-
<button type="button"
|
|
1136
|
-
class="text-[var(--cp-link-color,#3b82f6)] underline p-0 text-sm bg-transparent border-none cursor-pointer"
|
|
1137
|
-
(click)="$event.stopPropagation(); invoicePreview.emit(subscription.subscription.upcoming_invoice)">
|
|
1138
|
-
Preview invoice
|
|
1139
|
-
</button>
|
|
1140
|
-
</div>
|
|
1141
|
-
}
|
|
1362
|
+
}
|
|
1363
|
+
</div>
|
|
1364
|
+
}
|
|
1142
1365
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
[style.padding]="'var(--cp-section-content-padding)'">
|
|
1148
|
-
<div class="flex justify-between flex-wrap gap-6">
|
|
1149
|
-
<div>
|
|
1366
|
+
<!-- Add-on items -->
|
|
1367
|
+
@if (getAddonLineItems().length > 0) {
|
|
1368
|
+
<div class="mt-4">
|
|
1369
|
+
<div class="relative z-[100] flex items-center justify-between mb-3 mt-4">
|
|
1150
1370
|
<span class="text-[var(--cp-section-label-color)]"
|
|
1151
1371
|
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1152
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">
|
|
1153
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1154
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1155
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1156
|
-
{{ subscription.subscription.renews_at ? _formatDate(subscription.subscription.renews_at) : '-' }}
|
|
1157
|
-
</div>
|
|
1158
|
-
</div>
|
|
1159
|
-
<div>
|
|
1160
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1161
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1162
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Invoice due</span>
|
|
1163
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1164
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1165
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1166
|
-
{{ subscription.subscription.renews_at ? _formatDate(subscription.subscription.renews_at) : '-' }}
|
|
1167
|
-
</div>
|
|
1168
|
-
</div>
|
|
1169
|
-
<div>
|
|
1170
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1171
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1172
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Next estimated bill</span>
|
|
1173
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1174
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1175
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1176
|
-
@if (subscription.subscription.next_billing_amount) {
|
|
1177
|
-
<div class="font-medium">{{ _formatCurrency(subscription.subscription.next_billing_amount, subscription.subscription.currency_code) }}</div>
|
|
1178
|
-
<div class="text-sm opacity-80 mt-0.5">(Monthly)</div>
|
|
1179
|
-
} @else {
|
|
1180
|
-
<span>-</span>
|
|
1181
|
-
}
|
|
1182
|
-
</div>
|
|
1183
|
-
</div>
|
|
1184
|
-
</div>
|
|
1185
|
-
</div>
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1188
|
-
<!-- Subscription Line Items -->
|
|
1189
|
-
@if (subscription.subscription.subscription_items?.length) {
|
|
1190
|
-
<div class="mt-8">
|
|
1191
|
-
<div class="flex items-center justify-between mb-4">
|
|
1192
|
-
<span class="text-[var(--cp-section-header-color)]"
|
|
1193
|
-
[style.fontSize]="'var(--cp-section-header-size)'"
|
|
1194
|
-
[style.fontWeight]="'var(--cp-section-header-weight)'">
|
|
1195
|
-
Subscription items
|
|
1196
|
-
</span>
|
|
1197
|
-
@if (subscription.subscription.can_update_quantities) {
|
|
1372
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Add-ons</span>
|
|
1198
1373
|
<button type="button"
|
|
1199
|
-
class="
|
|
1200
|
-
|
|
1201
|
-
|
|
1374
|
+
class="bg-[var(--cp-btn-secondary-bg)] text-[var(--cp-btn-secondary-text)] border-[var(--cp-btn-secondary-border)] rounded-[var(--cp-btn-secondary-radius)] px-5 py-2"
|
|
1375
|
+
[style.fontSize]="'var(--cp-btn-secondary-size)'"
|
|
1376
|
+
[style.fontWeight]="'var(--cp-btn-secondary-weight)'"
|
|
1377
|
+
[style.borderWidth]="'var(--cp-btn-secondary-border-width, 1px)'"
|
|
1378
|
+
[style.borderStyle]="'solid'"
|
|
1379
|
+
(click)="handleAddAddon()">
|
|
1380
|
+
Manage add-on
|
|
1202
1381
|
</button>
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
<!-- Plan items -->
|
|
1211
|
-
@if (getPlanLineItems(subscription.subscription.subscription_items).length > 0) {
|
|
1212
|
-
<div class="mb-3 mt-4">
|
|
1213
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1214
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1215
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Plan</span>
|
|
1216
|
-
</div>
|
|
1217
|
-
<div class="space-y-2">
|
|
1218
|
-
@for (item of getPlanLineItems(subscription.subscription.subscription_items); track item.price_option_id) {
|
|
1219
|
-
<div class="bg-[var(--cp-subscription-item-bg,white)] border border-[var(--cp-subscription-item-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3 flex items-center justify-between">
|
|
1220
|
-
<div class="flex items-center gap-2">
|
|
1221
|
-
<span class="text-[var(--cp-subscription-item-text)]"
|
|
1222
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1223
|
-
[style.fontWeight]="'var(--cp-section-value-weight, 600)'">
|
|
1224
|
-
{{ _capitalize(item.name) }}
|
|
1225
|
-
</span>
|
|
1226
|
-
@if (item.quantity > 0 && item.source_type !== 'plan') {
|
|
1227
|
-
<span class="text-[var(--cp-subscription-item-quantity,#6b7280)] opacity-75">•</span>
|
|
1228
|
-
<span class="text-[var(--cp-subscription-item-quantity,#6b7280)] font-normal text-sm">
|
|
1229
|
-
{{ item.quantity }} {{ item.name?.toLowerCase() }}
|
|
1230
|
-
</span>
|
|
1231
|
-
}
|
|
1232
|
-
</div>
|
|
1382
|
+
</div>
|
|
1383
|
+
<div class="space-y-2">
|
|
1384
|
+
@for (group of getGroupedAddonItems(); track group.key) {
|
|
1385
|
+
<div class="bg-[var(--cp-subscription-item-bg,white)] border border-[var(--cp-subscription-item-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3">
|
|
1386
|
+
<div class="flex justify-between items-center gap-2 w-full"
|
|
1387
|
+
[class.cursor-pointer]="group.children.length > 0"
|
|
1388
|
+
(click)="group.children.length > 0 && toggleAddon(group.key)">
|
|
1233
1389
|
<span class="text-[var(--cp-subscription-item-text)]"
|
|
1234
1390
|
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1235
|
-
[style.fontWeight]="'var(--cp-section-value-weight,
|
|
1236
|
-
{{
|
|
1391
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 600)'">
|
|
1392
|
+
{{ _capitalize(group.name) }}
|
|
1237
1393
|
</span>
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
</div>
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
<!-- Add-on items -->
|
|
1244
|
-
@if (getAddonLineItems(subscription.subscription.subscription_items).length > 0) {
|
|
1245
|
-
<div class="mt-4">
|
|
1246
|
-
<div class="relative z-[100] flex items-center justify-between mb-3 mt-4">
|
|
1247
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1248
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1249
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Add-ons</span>
|
|
1250
|
-
<button type="button"
|
|
1251
|
-
class="bg-[var(--cp-btn-secondary-bg)] text-[var(--cp-btn-secondary-text)] border-[var(--cp-btn-secondary-border)] rounded-[var(--cp-btn-secondary-radius)] px-5 py-2"
|
|
1252
|
-
[style.fontSize]="'var(--cp-btn-secondary-size)'"
|
|
1253
|
-
[style.fontWeight]="'var(--cp-btn-secondary-weight)'"
|
|
1254
|
-
[style.borderWidth]="'var(--cp-btn-secondary-border-width, 1px)'"
|
|
1255
|
-
[style.borderStyle]="'solid'"
|
|
1256
|
-
(click)="handleAddAddon()">
|
|
1257
|
-
Manage add-on
|
|
1258
|
-
</button>
|
|
1259
|
-
</div>
|
|
1260
|
-
<div class="space-y-2">
|
|
1261
|
-
@for (group of getGroupedAddonItems(subscription.subscription.subscription_items); track group.key) {
|
|
1262
|
-
<div class="bg-[var(--cp-subscription-item-bg,white)] border border-[var(--cp-subscription-item-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3">
|
|
1263
|
-
<div class="flex justify-between items-center gap-2 w-full"
|
|
1264
|
-
[class.cursor-pointer]="group.children.length > 0"
|
|
1265
|
-
(click)="group.children.length > 0 && toggleAddon(group.key)">
|
|
1394
|
+
<div class="flex justify-end items-center">
|
|
1395
|
+
@if (group.baseItem) {
|
|
1266
1396
|
<span class="text-[var(--cp-subscription-item-text)]"
|
|
1267
1397
|
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1268
|
-
[style.fontWeight]="'var(--cp-section-value-weight,
|
|
1269
|
-
{{
|
|
1398
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 500)'">
|
|
1399
|
+
{{ _formatCurrency(group.baseItem.total_amount || group.baseItem.unit_price, group.baseItem.currency_code) }}
|
|
1270
1400
|
</span>
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1401
|
+
}
|
|
1402
|
+
@if (group.children.length > 0) {
|
|
1403
|
+
<span class="ml-2 inline-flex transition-transform duration-200"
|
|
1404
|
+
[class.rotate-180]="isAddonExpanded(group.key)"
|
|
1405
|
+
[style.color]="'var(--cp-table-expand-icon-color, #71717a)'">
|
|
1406
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"></path></svg>
|
|
1407
|
+
</span>
|
|
1408
|
+
}
|
|
1409
|
+
</div>
|
|
1410
|
+
</div>
|
|
1411
|
+
@if (isAddonExpanded(group.key) && group.children.length > 0) {
|
|
1412
|
+
<div class="bg-[var(--cp-section-content-bg,#F4F4F5)] space-y-2 p-4 mt-3 rounded-[var(--cp-section-content-radius)]">
|
|
1413
|
+
@for (child of group.children; track child.price_option_id || child.id) {
|
|
1414
|
+
<div class="bg-[var(--cp-subscription-child-bg,white)] border border-[var(--cp-subscription-child-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3 flex items-center justify-between">
|
|
1415
|
+
<div class="flex items-center gap-2">
|
|
1416
|
+
<span class="text-[var(--cp-subscription-child-text)]"
|
|
1274
1417
|
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1275
|
-
[style.fontWeight]="'var(--cp-section-value-weight,
|
|
1276
|
-
{{
|
|
1418
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 600)'">
|
|
1419
|
+
{{ _capitalize(child.name) }}
|
|
1277
1420
|
</span>
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
[innerHTML]="_getIcon('arrowDown')"></span>
|
|
1283
|
-
}
|
|
1284
|
-
</div>
|
|
1285
|
-
</div>
|
|
1286
|
-
@if (isAddonExpanded(group.key) && group.children.length > 0) {
|
|
1287
|
-
<div class="bg-[var(--cp-section-content-bg,#F4F4F5)] space-y-2 p-4 mt-3 rounded-[var(--cp-section-content-radius)]">
|
|
1288
|
-
@for (child of group.children; track child.price_option_id || child.id) {
|
|
1289
|
-
<div class="bg-[var(--cp-subscription-child-bg,white)] border border-[var(--cp-subscription-child-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3 flex items-center justify-between">
|
|
1290
|
-
<div class="flex items-center gap-2">
|
|
1291
|
-
<span class="text-[var(--cp-subscription-child-text)]"
|
|
1292
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1293
|
-
[style.fontWeight]="'var(--cp-section-value-weight, 600)'">
|
|
1294
|
-
{{ _capitalize(child.name) }}
|
|
1295
|
-
</span>
|
|
1296
|
-
@if (child.quantity > 0) {
|
|
1297
|
-
<span class="text-[var(--cp-subscription-child-quantity,#6b7280)] opacity-75">•</span>
|
|
1298
|
-
<span class="text-[var(--cp-subscription-child-quantity,#6b7280)] font-normal text-sm">
|
|
1299
|
-
{{ child.quantity }} {{ child.name?.toLowerCase() }}
|
|
1300
|
-
</span>
|
|
1301
|
-
}
|
|
1302
|
-
</div>
|
|
1303
|
-
<span class="text-[var(--cp-subscription-child-text)]"
|
|
1304
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1305
|
-
[style.fontWeight]="'var(--cp-section-value-weight, 500)'">
|
|
1306
|
-
{{ _formatCurrency(child.total_amount || child.unit_price, child.currency_code) }}
|
|
1421
|
+
@if (child.quantity > 0) {
|
|
1422
|
+
<span class="text-[var(--cp-subscription-child-quantity,#6b7280)] opacity-75">•</span>
|
|
1423
|
+
<span class="text-[var(--cp-subscription-child-quantity,#6b7280)] font-normal text-sm">
|
|
1424
|
+
{{ child.quantity }} {{ child.name?.toLowerCase() }}
|
|
1307
1425
|
</span>
|
|
1308
|
-
|
|
1309
|
-
|
|
1426
|
+
}
|
|
1427
|
+
</div>
|
|
1428
|
+
<span class="text-[var(--cp-subscription-child-text)]"
|
|
1429
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1430
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 500)'">
|
|
1431
|
+
{{ _formatCurrency(child.total_amount || child.unit_price, child.currency_code) }}
|
|
1432
|
+
</span>
|
|
1310
1433
|
</div>
|
|
1311
1434
|
}
|
|
1312
1435
|
</div>
|
|
1313
1436
|
}
|
|
1314
1437
|
</div>
|
|
1315
|
-
|
|
1316
|
-
|
|
1438
|
+
}
|
|
1439
|
+
</div>
|
|
1317
1440
|
</div>
|
|
1318
|
-
|
|
1319
|
-
|
|
1441
|
+
}
|
|
1442
|
+
</div>
|
|
1320
1443
|
</div>
|
|
1321
1444
|
}
|
|
1322
1445
|
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1323
1446
|
}
|
|
1324
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type:
|
|
1447
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: SubscriptionItemsComponent, decorators: [{
|
|
1325
1448
|
type: Component,
|
|
1326
1449
|
args: [{
|
|
1327
|
-
selector: 'cp-subscription-
|
|
1450
|
+
selector: 'cp-subscription-items',
|
|
1328
1451
|
standalone: true,
|
|
1329
1452
|
imports: [CommonModule],
|
|
1330
1453
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1331
1454
|
template: `
|
|
1332
|
-
@if (
|
|
1333
|
-
<div class="
|
|
1334
|
-
|
|
1335
|
-
[style.backgroundColor]="'var(--cp-section-bg)'"
|
|
1336
|
-
[style.borderColor]="'var(--cp-section-border)'"
|
|
1337
|
-
[style.borderRadius]="'var(--cp-section-radius)'"
|
|
1338
|
-
[style.borderWidth]="'1px'"
|
|
1339
|
-
[style.borderStyle]="'solid'">
|
|
1340
|
-
<!-- Header: title + Manage plan -->
|
|
1341
|
-
<div class="flex justify-between items-center mb-4">
|
|
1455
|
+
@if (items?.length) {
|
|
1456
|
+
<div class="mt-8">
|
|
1457
|
+
<div class="flex items-center justify-between mb-4">
|
|
1342
1458
|
<span class="text-[var(--cp-section-header-color)]"
|
|
1343
1459
|
[style.fontSize]="'var(--cp-section-header-size)'"
|
|
1344
1460
|
[style.fontWeight]="'var(--cp-section-header-weight)'">
|
|
1345
|
-
|
|
1461
|
+
Subscription items
|
|
1346
1462
|
</span>
|
|
1347
|
-
@if (
|
|
1463
|
+
@if (canUpdateQuantities) {
|
|
1348
1464
|
<button type="button"
|
|
1349
|
-
class="
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
[style.borderWidth]="'var(--cp-btn-primary-border-width, 1px)'"
|
|
1353
|
-
[style.borderStyle]="'solid'"
|
|
1354
|
-
(click)="handleManagePlan()">
|
|
1355
|
-
Manage plan
|
|
1465
|
+
class="text-[var(--cp-link-color,#3b82f6)] underline p-0 font-medium bg-transparent border-none cursor-pointer"
|
|
1466
|
+
(click)="$event.stopPropagation(); openUpdateItems()">
|
|
1467
|
+
Manage item quantities
|
|
1356
1468
|
</button>
|
|
1357
1469
|
}
|
|
1358
1470
|
</div>
|
|
1359
1471
|
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
class="bg-[var(--cp-section-content-bg,#F4F4F5)] border border-[var(--cp-section-content-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)]"
|
|
1472
|
+
<div data-testid="subscription-items-container"
|
|
1473
|
+
class="rounded-[var(--cp-section-content-radius)] overflow-hidden bg-[var(--cp-section-content-bg,#F4F4F5)] border border-[var(--cp-section-content-border,#e4e4e7)]"
|
|
1363
1474
|
[style.padding]="'var(--cp-section-content-padding)'">
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Current plan</span>
|
|
1369
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1370
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1371
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1372
|
-
{{ subscription.subscription.plan_name || '-' }}
|
|
1373
|
-
</div>
|
|
1374
|
-
</div>
|
|
1375
|
-
<div>
|
|
1376
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1377
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1378
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Status</span>
|
|
1379
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1380
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1381
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1382
|
-
{{ _formatStatus(subscription.subscription.status) }}
|
|
1383
|
-
</div>
|
|
1384
|
-
</div>
|
|
1385
|
-
<div>
|
|
1475
|
+
|
|
1476
|
+
<!-- Plan items -->
|
|
1477
|
+
@if (getPlanLineItems().length > 0) {
|
|
1478
|
+
<div class="mb-3 mt-4">
|
|
1386
1479
|
<span class="text-[var(--cp-section-label-color)]"
|
|
1387
1480
|
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1388
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">
|
|
1389
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1390
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1391
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1392
|
-
{{ _formatDate(subscription.subscription.starts_at) || '-' }}
|
|
1393
|
-
</div>
|
|
1481
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Plan</span>
|
|
1394
1482
|
</div>
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
<
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Trial end date</span>
|
|
1417
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1418
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1419
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1420
|
-
{{ _formatDate(subscription.subscription.trial_end_date) }}
|
|
1421
|
-
</div>
|
|
1422
|
-
</div>
|
|
1423
|
-
<div>
|
|
1424
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1425
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1426
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Trial period</span>
|
|
1427
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1428
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1429
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1430
|
-
{{ _formatDate(subscription.subscription.starts_at) }} - {{ _formatDate(subscription.subscription.trial_end_date) }}
|
|
1431
|
-
</div>
|
|
1432
|
-
</div>
|
|
1433
|
-
}
|
|
1434
|
-
@if (subscription.subscription.status === 'active') {
|
|
1435
|
-
<div>
|
|
1436
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1437
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1438
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">End date</span>
|
|
1439
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1440
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1441
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1442
|
-
{{ subscription.subscription.ends_at ? _formatDate(subscription.subscription.ends_at) : '-' }}
|
|
1483
|
+
<div class="space-y-2">
|
|
1484
|
+
@for (item of getPlanLineItems(); track item.price_option_id) {
|
|
1485
|
+
<div class="bg-[var(--cp-subscription-item-bg,white)] border border-[var(--cp-subscription-item-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3 flex items-center justify-between">
|
|
1486
|
+
<div class="flex items-center gap-2">
|
|
1487
|
+
<span class="text-[var(--cp-subscription-item-text)]"
|
|
1488
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1489
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 600)'">
|
|
1490
|
+
{{ _capitalize(item.name) }}
|
|
1491
|
+
</span>
|
|
1492
|
+
@if (item.quantity > 0 && item.source_type !== 'plan') {
|
|
1493
|
+
<span class="text-[var(--cp-subscription-item-quantity,#6b7280)] opacity-75">•</span>
|
|
1494
|
+
<span class="text-[var(--cp-subscription-item-quantity,#6b7280)] font-normal text-sm">
|
|
1495
|
+
{{ item.quantity }} {{ item.name?.toLowerCase() }}
|
|
1496
|
+
</span>
|
|
1497
|
+
}
|
|
1498
|
+
</div>
|
|
1499
|
+
<span class="text-[var(--cp-subscription-item-text)]"
|
|
1500
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1501
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 500)'">
|
|
1502
|
+
{{ _formatCurrency(item.total_amount || item.unit_price, item.currency_code) }}
|
|
1503
|
+
</span>
|
|
1443
1504
|
</div>
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
</div>
|
|
1448
|
-
|
|
1449
|
-
<!-- Preview invoice link -->
|
|
1450
|
-
@if (subscription.subscription.upcoming_invoice) {
|
|
1451
|
-
<div class="flex justify-end mt-2">
|
|
1452
|
-
<button type="button"
|
|
1453
|
-
class="text-[var(--cp-link-color,#3b82f6)] underline p-0 text-sm bg-transparent border-none cursor-pointer"
|
|
1454
|
-
(click)="$event.stopPropagation(); invoicePreview.emit(subscription.subscription.upcoming_invoice)">
|
|
1455
|
-
Preview invoice
|
|
1456
|
-
</button>
|
|
1457
|
-
</div>
|
|
1458
|
-
}
|
|
1505
|
+
}
|
|
1506
|
+
</div>
|
|
1507
|
+
}
|
|
1459
1508
|
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
[style.padding]="'var(--cp-section-content-padding)'">
|
|
1465
|
-
<div class="flex justify-between flex-wrap gap-6">
|
|
1466
|
-
<div>
|
|
1467
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1468
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1469
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Next billing date</span>
|
|
1470
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1471
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1472
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1473
|
-
{{ subscription.subscription.renews_at ? _formatDate(subscription.subscription.renews_at) : '-' }}
|
|
1474
|
-
</div>
|
|
1475
|
-
</div>
|
|
1476
|
-
<div>
|
|
1477
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1478
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1479
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Invoice due</span>
|
|
1480
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1481
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1482
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1483
|
-
{{ subscription.subscription.renews_at ? _formatDate(subscription.subscription.renews_at) : '-' }}
|
|
1484
|
-
</div>
|
|
1485
|
-
</div>
|
|
1486
|
-
<div>
|
|
1509
|
+
<!-- Add-on items -->
|
|
1510
|
+
@if (getAddonLineItems().length > 0) {
|
|
1511
|
+
<div class="mt-4">
|
|
1512
|
+
<div class="relative z-[100] flex items-center justify-between mb-3 mt-4">
|
|
1487
1513
|
<span class="text-[var(--cp-section-label-color)]"
|
|
1488
1514
|
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1489
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">
|
|
1490
|
-
<div class="text-[var(--cp-section-value-color)] mt-2"
|
|
1491
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1492
|
-
[style.fontWeight]="'var(--cp-section-value-weight)'">
|
|
1493
|
-
@if (subscription.subscription.next_billing_amount) {
|
|
1494
|
-
<div class="font-medium">{{ _formatCurrency(subscription.subscription.next_billing_amount, subscription.subscription.currency_code) }}</div>
|
|
1495
|
-
<div class="text-sm opacity-80 mt-0.5">(Monthly)</div>
|
|
1496
|
-
} @else {
|
|
1497
|
-
<span>-</span>
|
|
1498
|
-
}
|
|
1499
|
-
</div>
|
|
1500
|
-
</div>
|
|
1501
|
-
</div>
|
|
1502
|
-
</div>
|
|
1503
|
-
}
|
|
1504
|
-
|
|
1505
|
-
<!-- Subscription Line Items -->
|
|
1506
|
-
@if (subscription.subscription.subscription_items?.length) {
|
|
1507
|
-
<div class="mt-8">
|
|
1508
|
-
<div class="flex items-center justify-between mb-4">
|
|
1509
|
-
<span class="text-[var(--cp-section-header-color)]"
|
|
1510
|
-
[style.fontSize]="'var(--cp-section-header-size)'"
|
|
1511
|
-
[style.fontWeight]="'var(--cp-section-header-weight)'">
|
|
1512
|
-
Subscription items
|
|
1513
|
-
</span>
|
|
1514
|
-
@if (subscription.subscription.can_update_quantities) {
|
|
1515
|
+
[style.fontWeight]="'var(--cp-section-label-weight)'">Add-ons</span>
|
|
1515
1516
|
<button type="button"
|
|
1516
|
-
class="
|
|
1517
|
-
|
|
1518
|
-
|
|
1517
|
+
class="bg-[var(--cp-btn-secondary-bg)] text-[var(--cp-btn-secondary-text)] border-[var(--cp-btn-secondary-border)] rounded-[var(--cp-btn-secondary-radius)] px-5 py-2"
|
|
1518
|
+
[style.fontSize]="'var(--cp-btn-secondary-size)'"
|
|
1519
|
+
[style.fontWeight]="'var(--cp-btn-secondary-weight)'"
|
|
1520
|
+
[style.borderWidth]="'var(--cp-btn-secondary-border-width, 1px)'"
|
|
1521
|
+
[style.borderStyle]="'solid'"
|
|
1522
|
+
(click)="handleAddAddon()">
|
|
1523
|
+
Manage add-on
|
|
1519
1524
|
</button>
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
<!-- Plan items -->
|
|
1528
|
-
@if (getPlanLineItems(subscription.subscription.subscription_items).length > 0) {
|
|
1529
|
-
<div class="mb-3 mt-4">
|
|
1530
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1531
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1532
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Plan</span>
|
|
1533
|
-
</div>
|
|
1534
|
-
<div class="space-y-2">
|
|
1535
|
-
@for (item of getPlanLineItems(subscription.subscription.subscription_items); track item.price_option_id) {
|
|
1536
|
-
<div class="bg-[var(--cp-subscription-item-bg,white)] border border-[var(--cp-subscription-item-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3 flex items-center justify-between">
|
|
1537
|
-
<div class="flex items-center gap-2">
|
|
1538
|
-
<span class="text-[var(--cp-subscription-item-text)]"
|
|
1539
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1540
|
-
[style.fontWeight]="'var(--cp-section-value-weight, 600)'">
|
|
1541
|
-
{{ _capitalize(item.name) }}
|
|
1542
|
-
</span>
|
|
1543
|
-
@if (item.quantity > 0 && item.source_type !== 'plan') {
|
|
1544
|
-
<span class="text-[var(--cp-subscription-item-quantity,#6b7280)] opacity-75">•</span>
|
|
1545
|
-
<span class="text-[var(--cp-subscription-item-quantity,#6b7280)] font-normal text-sm">
|
|
1546
|
-
{{ item.quantity }} {{ item.name?.toLowerCase() }}
|
|
1547
|
-
</span>
|
|
1548
|
-
}
|
|
1549
|
-
</div>
|
|
1525
|
+
</div>
|
|
1526
|
+
<div class="space-y-2">
|
|
1527
|
+
@for (group of getGroupedAddonItems(); track group.key) {
|
|
1528
|
+
<div class="bg-[var(--cp-subscription-item-bg,white)] border border-[var(--cp-subscription-item-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3">
|
|
1529
|
+
<div class="flex justify-between items-center gap-2 w-full"
|
|
1530
|
+
[class.cursor-pointer]="group.children.length > 0"
|
|
1531
|
+
(click)="group.children.length > 0 && toggleAddon(group.key)">
|
|
1550
1532
|
<span class="text-[var(--cp-subscription-item-text)]"
|
|
1551
1533
|
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1552
|
-
[style.fontWeight]="'var(--cp-section-value-weight,
|
|
1553
|
-
{{
|
|
1534
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 600)'">
|
|
1535
|
+
{{ _capitalize(group.name) }}
|
|
1554
1536
|
</span>
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
</div>
|
|
1558
|
-
}
|
|
1559
|
-
|
|
1560
|
-
<!-- Add-on items -->
|
|
1561
|
-
@if (getAddonLineItems(subscription.subscription.subscription_items).length > 0) {
|
|
1562
|
-
<div class="mt-4">
|
|
1563
|
-
<div class="relative z-[100] flex items-center justify-between mb-3 mt-4">
|
|
1564
|
-
<span class="text-[var(--cp-section-label-color)]"
|
|
1565
|
-
[style.fontSize]="'var(--cp-section-label-size)'"
|
|
1566
|
-
[style.fontWeight]="'var(--cp-section-label-weight)'">Add-ons</span>
|
|
1567
|
-
<button type="button"
|
|
1568
|
-
class="bg-[var(--cp-btn-secondary-bg)] text-[var(--cp-btn-secondary-text)] border-[var(--cp-btn-secondary-border)] rounded-[var(--cp-btn-secondary-radius)] px-5 py-2"
|
|
1569
|
-
[style.fontSize]="'var(--cp-btn-secondary-size)'"
|
|
1570
|
-
[style.fontWeight]="'var(--cp-btn-secondary-weight)'"
|
|
1571
|
-
[style.borderWidth]="'var(--cp-btn-secondary-border-width, 1px)'"
|
|
1572
|
-
[style.borderStyle]="'solid'"
|
|
1573
|
-
(click)="handleAddAddon()">
|
|
1574
|
-
Manage add-on
|
|
1575
|
-
</button>
|
|
1576
|
-
</div>
|
|
1577
|
-
<div class="space-y-2">
|
|
1578
|
-
@for (group of getGroupedAddonItems(subscription.subscription.subscription_items); track group.key) {
|
|
1579
|
-
<div class="bg-[var(--cp-subscription-item-bg,white)] border border-[var(--cp-subscription-item-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3">
|
|
1580
|
-
<div class="flex justify-between items-center gap-2 w-full"
|
|
1581
|
-
[class.cursor-pointer]="group.children.length > 0"
|
|
1582
|
-
(click)="group.children.length > 0 && toggleAddon(group.key)">
|
|
1537
|
+
<div class="flex justify-end items-center">
|
|
1538
|
+
@if (group.baseItem) {
|
|
1583
1539
|
<span class="text-[var(--cp-subscription-item-text)]"
|
|
1584
1540
|
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1585
|
-
[style.fontWeight]="'var(--cp-section-value-weight,
|
|
1586
|
-
{{
|
|
1541
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 500)'">
|
|
1542
|
+
{{ _formatCurrency(group.baseItem.total_amount || group.baseItem.unit_price, group.baseItem.currency_code) }}
|
|
1543
|
+
</span>
|
|
1544
|
+
}
|
|
1545
|
+
@if (group.children.length > 0) {
|
|
1546
|
+
<span class="ml-2 inline-flex transition-transform duration-200"
|
|
1547
|
+
[class.rotate-180]="isAddonExpanded(group.key)"
|
|
1548
|
+
[style.color]="'var(--cp-table-expand-icon-color, #71717a)'">
|
|
1549
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"></path></svg>
|
|
1587
1550
|
</span>
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1551
|
+
}
|
|
1552
|
+
</div>
|
|
1553
|
+
</div>
|
|
1554
|
+
@if (isAddonExpanded(group.key) && group.children.length > 0) {
|
|
1555
|
+
<div class="bg-[var(--cp-section-content-bg,#F4F4F5)] space-y-2 p-4 mt-3 rounded-[var(--cp-section-content-radius)]">
|
|
1556
|
+
@for (child of group.children; track child.price_option_id || child.id) {
|
|
1557
|
+
<div class="bg-[var(--cp-subscription-child-bg,white)] border border-[var(--cp-subscription-child-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3 flex items-center justify-between">
|
|
1558
|
+
<div class="flex items-center gap-2">
|
|
1559
|
+
<span class="text-[var(--cp-subscription-child-text)]"
|
|
1591
1560
|
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1592
|
-
[style.fontWeight]="'var(--cp-section-value-weight,
|
|
1593
|
-
{{
|
|
1561
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 600)'">
|
|
1562
|
+
{{ _capitalize(child.name) }}
|
|
1594
1563
|
</span>
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
[innerHTML]="_getIcon('arrowDown')"></span>
|
|
1600
|
-
}
|
|
1601
|
-
</div>
|
|
1602
|
-
</div>
|
|
1603
|
-
@if (isAddonExpanded(group.key) && group.children.length > 0) {
|
|
1604
|
-
<div class="bg-[var(--cp-section-content-bg,#F4F4F5)] space-y-2 p-4 mt-3 rounded-[var(--cp-section-content-radius)]">
|
|
1605
|
-
@for (child of group.children; track child.price_option_id || child.id) {
|
|
1606
|
-
<div class="bg-[var(--cp-subscription-child-bg,white)] border border-[var(--cp-subscription-child-border,#e4e4e7)] rounded-[var(--cp-section-content-radius)] px-4 py-3 flex items-center justify-between">
|
|
1607
|
-
<div class="flex items-center gap-2">
|
|
1608
|
-
<span class="text-[var(--cp-subscription-child-text)]"
|
|
1609
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1610
|
-
[style.fontWeight]="'var(--cp-section-value-weight, 600)'">
|
|
1611
|
-
{{ _capitalize(child.name) }}
|
|
1612
|
-
</span>
|
|
1613
|
-
@if (child.quantity > 0) {
|
|
1614
|
-
<span class="text-[var(--cp-subscription-child-quantity,#6b7280)] opacity-75">•</span>
|
|
1615
|
-
<span class="text-[var(--cp-subscription-child-quantity,#6b7280)] font-normal text-sm">
|
|
1616
|
-
{{ child.quantity }} {{ child.name?.toLowerCase() }}
|
|
1617
|
-
</span>
|
|
1618
|
-
}
|
|
1619
|
-
</div>
|
|
1620
|
-
<span class="text-[var(--cp-subscription-child-text)]"
|
|
1621
|
-
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1622
|
-
[style.fontWeight]="'var(--cp-section-value-weight, 500)'">
|
|
1623
|
-
{{ _formatCurrency(child.total_amount || child.unit_price, child.currency_code) }}
|
|
1564
|
+
@if (child.quantity > 0) {
|
|
1565
|
+
<span class="text-[var(--cp-subscription-child-quantity,#6b7280)] opacity-75">•</span>
|
|
1566
|
+
<span class="text-[var(--cp-subscription-child-quantity,#6b7280)] font-normal text-sm">
|
|
1567
|
+
{{ child.quantity }} {{ child.name?.toLowerCase() }}
|
|
1624
1568
|
</span>
|
|
1625
|
-
|
|
1626
|
-
|
|
1569
|
+
}
|
|
1570
|
+
</div>
|
|
1571
|
+
<span class="text-[var(--cp-subscription-child-text)]"
|
|
1572
|
+
[style.fontSize]="'var(--cp-section-value-size)'"
|
|
1573
|
+
[style.fontWeight]="'var(--cp-section-value-weight, 500)'">
|
|
1574
|
+
{{ _formatCurrency(child.total_amount || child.unit_price, child.currency_code) }}
|
|
1575
|
+
</span>
|
|
1627
1576
|
</div>
|
|
1628
1577
|
}
|
|
1629
1578
|
</div>
|
|
1630
1579
|
}
|
|
1631
1580
|
</div>
|
|
1632
|
-
|
|
1633
|
-
|
|
1581
|
+
}
|
|
1582
|
+
</div>
|
|
1634
1583
|
</div>
|
|
1635
|
-
|
|
1584
|
+
}
|
|
1585
|
+
</div>
|
|
1586
|
+
</div>
|
|
1587
|
+
}
|
|
1588
|
+
`
|
|
1589
|
+
}]
|
|
1590
|
+
}], propDecorators: { items: [{
|
|
1591
|
+
type: Input
|
|
1592
|
+
}], canUpdateQuantities: [{
|
|
1593
|
+
type: Input
|
|
1594
|
+
}], tenantCheckoutUsername: [{
|
|
1595
|
+
type: Input
|
|
1596
|
+
}], customerKey: [{
|
|
1597
|
+
type: Input
|
|
1598
|
+
}], subscriptionId: [{
|
|
1599
|
+
type: Input
|
|
1600
|
+
}], offeringKey: [{
|
|
1601
|
+
type: Input
|
|
1602
|
+
}] } });
|
|
1603
|
+
|
|
1604
|
+
class SubscriptionSectionComponent {
|
|
1605
|
+
subscription;
|
|
1606
|
+
sectionsConfig;
|
|
1607
|
+
customerKey = '';
|
|
1608
|
+
tenantCheckoutUsername = '';
|
|
1609
|
+
invoicePreview = new EventEmitter();
|
|
1610
|
+
managePlan = new EventEmitter();
|
|
1611
|
+
handleManagePlan() {
|
|
1612
|
+
if (this.subscription) {
|
|
1613
|
+
this.managePlan.emit(this.subscription);
|
|
1636
1614
|
}
|
|
1615
|
+
}
|
|
1616
|
+
_isSectionHidden(key) {
|
|
1617
|
+
return isSectionHidden(this.sectionsConfig, key);
|
|
1618
|
+
}
|
|
1619
|
+
_getSectionLabel(key) {
|
|
1620
|
+
return getSectionLabel(this.sectionsConfig, key);
|
|
1621
|
+
}
|
|
1622
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: SubscriptionSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1623
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: SubscriptionSectionComponent, isStandalone: true, selector: "cp-subscription-section", inputs: { subscription: "subscription", sectionsConfig: "sectionsConfig", customerKey: "customerKey", tenantCheckoutUsername: "tenantCheckoutUsername" }, outputs: { invoicePreview: "invoicePreview", managePlan: "managePlan" }, ngImport: i0, template: `
|
|
1624
|
+
@if (!_isSectionHidden('subscription') && subscription?.subscription) {
|
|
1625
|
+
<div class="w-full"
|
|
1626
|
+
[style.padding]="'var(--cp-section-padding)'"
|
|
1627
|
+
[style.backgroundColor]="'var(--cp-section-bg)'"
|
|
1628
|
+
[style.borderColor]="'var(--cp-section-border)'"
|
|
1629
|
+
[style.borderRadius]="'var(--cp-section-radius)'"
|
|
1630
|
+
[style.borderWidth]="'1px'"
|
|
1631
|
+
[style.borderStyle]="'solid'">
|
|
1632
|
+
<!-- Header: title + Manage plan -->
|
|
1633
|
+
<div class="flex justify-between items-center mb-4">
|
|
1634
|
+
<span class="text-[var(--cp-section-header-color)]"
|
|
1635
|
+
[style.fontSize]="'var(--cp-section-header-size)'"
|
|
1636
|
+
[style.fontWeight]="'var(--cp-section-header-weight)'">
|
|
1637
|
+
{{ _getSectionLabel('subscription') }}
|
|
1638
|
+
</span>
|
|
1639
|
+
@if (subscription.subscription.status !== 'canceled') {
|
|
1640
|
+
<button type="button"
|
|
1641
|
+
class="bg-[var(--cp-btn-primary-bg)] text-[var(--cp-btn-primary-text)] border-[var(--cp-btn-primary-border)] rounded-[var(--cp-btn-primary-radius)] px-5 py-2"
|
|
1642
|
+
[style.fontSize]="'var(--cp-btn-primary-size)'"
|
|
1643
|
+
[style.fontWeight]="'var(--cp-btn-primary-weight)'"
|
|
1644
|
+
[style.borderWidth]="'var(--cp-btn-primary-border-width, 1px)'"
|
|
1645
|
+
[style.borderStyle]="'solid'"
|
|
1646
|
+
(click)="handleManagePlan()">
|
|
1647
|
+
Manage plan
|
|
1648
|
+
</button>
|
|
1649
|
+
}
|
|
1650
|
+
</div>
|
|
1651
|
+
|
|
1652
|
+
<!-- Subscription Details (plan info + billing) -->
|
|
1653
|
+
<cp-subscription-details
|
|
1654
|
+
[sub]="subscription.subscription"
|
|
1655
|
+
(invoicePreview)="invoicePreview.emit($event)">
|
|
1656
|
+
</cp-subscription-details>
|
|
1657
|
+
|
|
1658
|
+
<!-- Subscription Line Items -->
|
|
1659
|
+
<cp-subscription-items
|
|
1660
|
+
[items]="subscription.subscription.subscription_items || []"
|
|
1661
|
+
[canUpdateQuantities]="!!subscription.subscription.can_update_quantities"
|
|
1662
|
+
[tenantCheckoutUsername]="tenantCheckoutUsername"
|
|
1663
|
+
[customerKey]="customerKey"
|
|
1664
|
+
[subscriptionId]="subscription.subscription.id || ''"
|
|
1665
|
+
[offeringKey]="subscription.subscription.offering_key || ''">
|
|
1666
|
+
</cp-subscription-items>
|
|
1667
|
+
</div>
|
|
1668
|
+
}
|
|
1669
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: SubscriptionDetailsComponent, selector: "cp-subscription-details", inputs: ["sub"], outputs: ["invoicePreview"] }, { kind: "component", type: SubscriptionItemsComponent, selector: "cp-subscription-items", inputs: ["items", "canUpdateQuantities", "tenantCheckoutUsername", "customerKey", "subscriptionId", "offeringKey"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1670
|
+
}
|
|
1671
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: SubscriptionSectionComponent, decorators: [{
|
|
1672
|
+
type: Component,
|
|
1673
|
+
args: [{
|
|
1674
|
+
selector: 'cp-subscription-section',
|
|
1675
|
+
standalone: true,
|
|
1676
|
+
imports: [CommonModule, SubscriptionDetailsComponent, SubscriptionItemsComponent],
|
|
1677
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1678
|
+
template: `
|
|
1679
|
+
@if (!_isSectionHidden('subscription') && subscription?.subscription) {
|
|
1680
|
+
<div class="w-full"
|
|
1681
|
+
[style.padding]="'var(--cp-section-padding)'"
|
|
1682
|
+
[style.backgroundColor]="'var(--cp-section-bg)'"
|
|
1683
|
+
[style.borderColor]="'var(--cp-section-border)'"
|
|
1684
|
+
[style.borderRadius]="'var(--cp-section-radius)'"
|
|
1685
|
+
[style.borderWidth]="'1px'"
|
|
1686
|
+
[style.borderStyle]="'solid'">
|
|
1687
|
+
<!-- Header: title + Manage plan -->
|
|
1688
|
+
<div class="flex justify-between items-center mb-4">
|
|
1689
|
+
<span class="text-[var(--cp-section-header-color)]"
|
|
1690
|
+
[style.fontSize]="'var(--cp-section-header-size)'"
|
|
1691
|
+
[style.fontWeight]="'var(--cp-section-header-weight)'">
|
|
1692
|
+
{{ _getSectionLabel('subscription') }}
|
|
1693
|
+
</span>
|
|
1694
|
+
@if (subscription.subscription.status !== 'canceled') {
|
|
1695
|
+
<button type="button"
|
|
1696
|
+
class="bg-[var(--cp-btn-primary-bg)] text-[var(--cp-btn-primary-text)] border-[var(--cp-btn-primary-border)] rounded-[var(--cp-btn-primary-radius)] px-5 py-2"
|
|
1697
|
+
[style.fontSize]="'var(--cp-btn-primary-size)'"
|
|
1698
|
+
[style.fontWeight]="'var(--cp-btn-primary-weight)'"
|
|
1699
|
+
[style.borderWidth]="'var(--cp-btn-primary-border-width, 1px)'"
|
|
1700
|
+
[style.borderStyle]="'solid'"
|
|
1701
|
+
(click)="handleManagePlan()">
|
|
1702
|
+
Manage plan
|
|
1703
|
+
</button>
|
|
1704
|
+
}
|
|
1705
|
+
</div>
|
|
1706
|
+
|
|
1707
|
+
<!-- Subscription Details (plan info + billing) -->
|
|
1708
|
+
<cp-subscription-details
|
|
1709
|
+
[sub]="subscription.subscription"
|
|
1710
|
+
(invoicePreview)="invoicePreview.emit($event)">
|
|
1711
|
+
</cp-subscription-details>
|
|
1712
|
+
|
|
1713
|
+
<!-- Subscription Line Items -->
|
|
1714
|
+
<cp-subscription-items
|
|
1715
|
+
[items]="subscription.subscription.subscription_items || []"
|
|
1716
|
+
[canUpdateQuantities]="!!subscription.subscription.can_update_quantities"
|
|
1717
|
+
[tenantCheckoutUsername]="tenantCheckoutUsername"
|
|
1718
|
+
[customerKey]="customerKey"
|
|
1719
|
+
[subscriptionId]="subscription.subscription.id || ''"
|
|
1720
|
+
[offeringKey]="subscription.subscription.offering_key || ''">
|
|
1721
|
+
</cp-subscription-items>
|
|
1637
1722
|
</div>
|
|
1638
1723
|
}
|
|
1639
|
-
|
|
1724
|
+
`
|
|
1640
1725
|
}]
|
|
1641
1726
|
}], propDecorators: { subscription: [{
|
|
1642
1727
|
type: Input
|
|
@@ -1666,7 +1751,7 @@ class CreditBalanceSectionComponent {
|
|
|
1666
1751
|
walletTabs = [
|
|
1667
1752
|
{ key: 'active', label: 'Active' },
|
|
1668
1753
|
{ key: 'expired', label: 'Expired' },
|
|
1669
|
-
{ key: 'overage', label: 'Overage' }
|
|
1754
|
+
{ key: 'overage', label: 'Overage' }
|
|
1670
1755
|
];
|
|
1671
1756
|
showCreditTransactions = signal(false);
|
|
1672
1757
|
selectedAllocation = signal(null);
|
|
@@ -1725,7 +1810,7 @@ class CreditBalanceSectionComponent {
|
|
|
1725
1810
|
year: 'numeric',
|
|
1726
1811
|
hour: 'numeric',
|
|
1727
1812
|
minute: '2-digit',
|
|
1728
|
-
hour12: true
|
|
1813
|
+
hour12: true
|
|
1729
1814
|
})
|
|
1730
1815
|
.replace(',', '');
|
|
1731
1816
|
}
|
|
@@ -1747,7 +1832,7 @@ class CreditBalanceSectionComponent {
|
|
|
1747
1832
|
return date.toLocaleDateString('en-US', {
|
|
1748
1833
|
month: 'numeric',
|
|
1749
1834
|
day: 'numeric',
|
|
1750
|
-
year: 'numeric'
|
|
1835
|
+
year: 'numeric'
|
|
1751
1836
|
});
|
|
1752
1837
|
}
|
|
1753
1838
|
getAllocationBalance(allocation) {
|
|
@@ -1769,13 +1854,13 @@ class CreditBalanceSectionComponent {
|
|
|
1769
1854
|
.pipe(takeUntil(this.destroy$))
|
|
1770
1855
|
.subscribe({
|
|
1771
1856
|
next: (data) => {
|
|
1772
|
-
this.creditTransactions.set(data
|
|
1857
|
+
this.creditTransactions.set(data || []);
|
|
1773
1858
|
this.creditTransactionsLoading.set(false);
|
|
1774
1859
|
},
|
|
1775
1860
|
error: () => {
|
|
1776
1861
|
this.creditTransactions.set([]);
|
|
1777
1862
|
this.creditTransactionsLoading.set(false);
|
|
1778
|
-
}
|
|
1863
|
+
}
|
|
1779
1864
|
});
|
|
1780
1865
|
}
|
|
1781
1866
|
closeCreditTransactions() {
|
|
@@ -1801,13 +1886,16 @@ class CreditBalanceSectionComponent {
|
|
|
1801
1886
|
getWalletSettingsValidationErrors() {
|
|
1802
1887
|
const errors = [];
|
|
1803
1888
|
if (this.lowBalanceEnabled) {
|
|
1804
|
-
if (!this.walletSettingThreshold?.trim())
|
|
1889
|
+
if (!this.walletSettingThreshold?.trim()) {
|
|
1805
1890
|
errors.push('Set a low balance threshold is required');
|
|
1891
|
+
}
|
|
1806
1892
|
if (this.walletSettingBehaviour === 'auto_top_up') {
|
|
1807
|
-
if (!this.walletSettingTargetBalance?.trim())
|
|
1893
|
+
if (!this.walletSettingTargetBalance?.trim()) {
|
|
1808
1894
|
errors.push('Bring wallet balance back up to is required for auto top-up');
|
|
1809
|
-
|
|
1895
|
+
}
|
|
1896
|
+
if (!this.walletSettingMonthlyLimit?.trim()) {
|
|
1810
1897
|
errors.push('Limit the amount of automatic top up per month is required for auto top-up');
|
|
1898
|
+
}
|
|
1811
1899
|
}
|
|
1812
1900
|
}
|
|
1813
1901
|
return errors;
|
|
@@ -1844,7 +1932,7 @@ class CreditBalanceSectionComponent {
|
|
|
1844
1932
|
error: (err) => {
|
|
1845
1933
|
this.walletSettingsError.set(err?.message || 'Failed to delete settings');
|
|
1846
1934
|
this.walletSettingsSaving.set(false);
|
|
1847
|
-
}
|
|
1935
|
+
}
|
|
1848
1936
|
});
|
|
1849
1937
|
}
|
|
1850
1938
|
else {
|
|
@@ -1861,8 +1949,8 @@ class CreditBalanceSectionComponent {
|
|
|
1861
1949
|
threshold_amount: Number(this.walletSettingThreshold) || 0,
|
|
1862
1950
|
...(this.walletSettingBehaviour === 'auto_top_up' && {
|
|
1863
1951
|
target_balance: Number(this.walletSettingTargetBalance) || 0,
|
|
1864
|
-
monthly_top_up_count_limit: Number(this.walletSettingMonthlyLimit) || 0
|
|
1865
|
-
})
|
|
1952
|
+
monthly_top_up_count_limit: Number(this.walletSettingMonthlyLimit) || 0
|
|
1953
|
+
})
|
|
1866
1954
|
};
|
|
1867
1955
|
this.walletSettingsSaving.set(true);
|
|
1868
1956
|
const editId = this.walletSettingEditId();
|
|
@@ -1878,7 +1966,7 @@ class CreditBalanceSectionComponent {
|
|
|
1878
1966
|
error: (err) => {
|
|
1879
1967
|
this.walletSettingsError.set(err?.message || 'Failed to save settings');
|
|
1880
1968
|
this.walletSettingsSaving.set(false);
|
|
1881
|
-
}
|
|
1969
|
+
}
|
|
1882
1970
|
});
|
|
1883
1971
|
}
|
|
1884
1972
|
onWalletSelectChange(event) {
|
|
@@ -1916,7 +2004,7 @@ class CreditBalanceSectionComponent {
|
|
|
1916
2004
|
error: (err) => {
|
|
1917
2005
|
this.walletSettingsError.set(err?.message || 'Failed to load wallet settings');
|
|
1918
2006
|
this.walletSettingsLoading.set(false);
|
|
1919
|
-
}
|
|
2007
|
+
}
|
|
1920
2008
|
});
|
|
1921
2009
|
}
|
|
1922
2010
|
applyExistingWalletSetting() {
|
|
@@ -2861,7 +2949,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
2861
2949
|
</div>
|
|
2862
2950
|
</div>
|
|
2863
2951
|
}
|
|
2864
|
-
|
|
2952
|
+
`
|
|
2865
2953
|
}]
|
|
2866
2954
|
}], propDecorators: { wallets: [{
|
|
2867
2955
|
type: Input
|
|
@@ -2881,46 +2969,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
2881
2969
|
type: Output
|
|
2882
2970
|
}] } });
|
|
2883
2971
|
|
|
2884
|
-
class
|
|
2972
|
+
class EntitlementSummaryComponent {
|
|
2885
2973
|
sanitizer = inject(DomSanitizer);
|
|
2886
2974
|
entitlementSummary = [];
|
|
2887
|
-
entitlementUsage = [];
|
|
2888
|
-
sectionsConfig;
|
|
2889
|
-
entitlementTab = signal('summary');
|
|
2890
|
-
expandedEntitlements = new Set();
|
|
2891
|
-
Math = Math;
|
|
2892
|
-
_isSectionHidden(key) {
|
|
2893
|
-
return isSectionHidden(this.sectionsConfig, key);
|
|
2894
|
-
}
|
|
2895
|
-
_getSectionLabel(key) {
|
|
2896
|
-
return getSectionLabel(this.sectionsConfig, key);
|
|
2897
|
-
}
|
|
2898
2975
|
_getIcon(name) {
|
|
2899
2976
|
return getIcon(this.sanitizer, name);
|
|
2900
2977
|
}
|
|
2901
2978
|
_capitalize(str) {
|
|
2902
2979
|
return capitalize(str);
|
|
2903
2980
|
}
|
|
2904
|
-
_formatNumber(num) {
|
|
2905
|
-
return formatNumber(num);
|
|
2906
|
-
}
|
|
2907
|
-
changeEntitlementTab(tab) {
|
|
2908
|
-
this.entitlementTab.set(tab);
|
|
2909
|
-
}
|
|
2910
|
-
getMeteredEntitlements() {
|
|
2911
|
-
return (this.entitlementUsage || []).filter((usage) => usage.type !== 'boolean' && usage.feature_type !== 'boolean');
|
|
2912
|
-
}
|
|
2913
2981
|
formatUsageModel(entitlement) {
|
|
2914
2982
|
if (!entitlement.usage_model)
|
|
2915
2983
|
return '';
|
|
2916
|
-
const model = entitlement.usage_model.split('_').join(' ');
|
|
2984
|
+
const model = String(entitlement.usage_model).split('_').join(' ');
|
|
2917
2985
|
let result = capitalize(model);
|
|
2918
2986
|
if (entitlement.feature_type === 'metered') {
|
|
2919
2987
|
if (entitlement.prepaid) {
|
|
2920
2988
|
result += '/ Prepaid';
|
|
2921
2989
|
}
|
|
2922
2990
|
else if (entitlement.price_type) {
|
|
2923
|
-
result += '/ ' + capitalize(entitlement.price_type);
|
|
2991
|
+
result += '/ ' + capitalize(String(entitlement.price_type));
|
|
2924
2992
|
}
|
|
2925
2993
|
}
|
|
2926
2994
|
return result;
|
|
@@ -2933,9 +3001,9 @@ class EntitlementsSectionComponent {
|
|
|
2933
3001
|
return 'Unlimited';
|
|
2934
3002
|
if (allowance === null || allowance === undefined)
|
|
2935
3003
|
return '0';
|
|
2936
|
-
let result = formatNumber(allowance);
|
|
3004
|
+
let result = formatNumber(Number(allowance));
|
|
2937
3005
|
if (entitlement.included_allowance_reset_interval && entitlement.included_allowance_reset_interval !== 'none') {
|
|
2938
|
-
result += ' ' + getResetIntervalLabel(entitlement.included_allowance_reset_interval);
|
|
3006
|
+
result += ' ' + getResetIntervalLabel(String(entitlement.included_allowance_reset_interval));
|
|
2939
3007
|
}
|
|
2940
3008
|
return result;
|
|
2941
3009
|
}
|
|
@@ -2946,17 +3014,17 @@ class EntitlementsSectionComponent {
|
|
|
2946
3014
|
const limit = entitlement.usage_limit ?? 'Unlimited';
|
|
2947
3015
|
if (limit === -1)
|
|
2948
3016
|
return 'Unlimited';
|
|
2949
|
-
let result = typeof limit === 'number' ? formatNumber(limit) : limit;
|
|
3017
|
+
let result = typeof limit === 'number' ? formatNumber(limit) : String(limit);
|
|
2950
3018
|
if (entitlement.usage_limit_reset_interval && entitlement.usage_limit_reset_interval !== 'none') {
|
|
2951
|
-
result += ' ' + getResetIntervalLabel(entitlement.usage_limit_reset_interval);
|
|
3019
|
+
result += ' ' + getResetIntervalLabel(String(entitlement.usage_limit_reset_interval));
|
|
2952
3020
|
}
|
|
2953
3021
|
return result;
|
|
2954
3022
|
}
|
|
2955
3023
|
if (entitlement.purchased_qty !== null && entitlement.purchased_qty !== undefined) {
|
|
2956
|
-
const qty = entitlement.purchased_qty === -1 ? 'Unlimited' : formatNumber(entitlement.purchased_qty);
|
|
3024
|
+
const qty = entitlement.purchased_qty === -1 ? 'Unlimited' : formatNumber(Number(entitlement.purchased_qty));
|
|
2957
3025
|
let interval = '';
|
|
2958
3026
|
if (entitlement.billing_interval && entitlement.billing_interval !== 'none') {
|
|
2959
|
-
interval = ' ' + getResetIntervalLabel(entitlement.billing_interval);
|
|
3027
|
+
interval = ' ' + getResetIntervalLabel(String(entitlement.billing_interval));
|
|
2960
3028
|
}
|
|
2961
3029
|
const softLimit = entitlement.soft_limit_enabled ? ' Soft limits enabled' : '';
|
|
2962
3030
|
return qty + interval + softLimit;
|
|
@@ -2964,15 +3032,192 @@ class EntitlementsSectionComponent {
|
|
|
2964
3032
|
if (entitlement.included_allowance !== null && entitlement.included_allowance !== undefined) {
|
|
2965
3033
|
if (entitlement.included_allowance === -1)
|
|
2966
3034
|
return 'Unlimited';
|
|
2967
|
-
let result = formatNumber(entitlement.included_allowance);
|
|
3035
|
+
let result = formatNumber(Number(entitlement.included_allowance));
|
|
2968
3036
|
if (entitlement.included_allowance_reset_interval && entitlement.included_allowance_reset_interval !== 'none') {
|
|
2969
|
-
result += ' ' + getResetIntervalLabel(entitlement.included_allowance_reset_interval);
|
|
3037
|
+
result += ' ' + getResetIntervalLabel(String(entitlement.included_allowance_reset_interval));
|
|
2970
3038
|
}
|
|
2971
3039
|
return result;
|
|
2972
3040
|
}
|
|
2973
3041
|
return '0';
|
|
2974
3042
|
}
|
|
2975
|
-
|
|
3043
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: EntitlementSummaryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3044
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: EntitlementSummaryComponent, isStandalone: true, selector: "cp-entitlement-summary", inputs: { entitlementSummary: "entitlementSummary" }, ngImport: i0, template: `
|
|
3045
|
+
<div class="overflow-x-auto bg-transparent">
|
|
3046
|
+
@if (entitlementSummary.length > 0) {
|
|
3047
|
+
<table class="min-w-full border-collapse text-left relative">
|
|
3048
|
+
<thead>
|
|
3049
|
+
<tr>
|
|
3050
|
+
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3051
|
+
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3052
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3053
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Feature</th>
|
|
3054
|
+
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3055
|
+
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3056
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3057
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Meter type</th>
|
|
3058
|
+
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3059
|
+
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3060
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3061
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Included allowance</th>
|
|
3062
|
+
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3063
|
+
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3064
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3065
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Usage limits</th>
|
|
3066
|
+
</tr>
|
|
3067
|
+
</thead>
|
|
3068
|
+
<tbody>
|
|
3069
|
+
@for (entitlement of entitlementSummary; track entitlement.id || $index; let rowIdx = $index) {
|
|
3070
|
+
<tr [class]="rowIdx % 2 === 0 ? 'bg-[var(--cp-table-row-even-bg)]' : 'bg-[var(--cp-table-row-odd-bg)]'">
|
|
3071
|
+
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3072
|
+
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3073
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3074
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3075
|
+
<div class="flex flex-col gap-y-1 items-start max-w-[130px]">
|
|
3076
|
+
<span>{{ entitlement.feature_name || '-' }}</span>
|
|
3077
|
+
<span class="text-[var(--cp-table-text)] max-w-[120px] truncate"
|
|
3078
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3079
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ entitlement.feature_key }}</span>
|
|
3080
|
+
</div>
|
|
3081
|
+
</td>
|
|
3082
|
+
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3083
|
+
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3084
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3085
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3086
|
+
<div>
|
|
3087
|
+
<span>{{ _capitalize(entitlement.feature_type) }}</span>
|
|
3088
|
+
@if (entitlement.usage_model) {
|
|
3089
|
+
<span class="block mt-1">{{ formatUsageModel(entitlement) }}</span>
|
|
3090
|
+
}
|
|
3091
|
+
</div>
|
|
3092
|
+
</td>
|
|
3093
|
+
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3094
|
+
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3095
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3096
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3097
|
+
{{ formatIncludedAllowance(entitlement) }}
|
|
3098
|
+
</td>
|
|
3099
|
+
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3100
|
+
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3101
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3102
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3103
|
+
{{ formatUsageLimits(entitlement) }}
|
|
3104
|
+
</td>
|
|
3105
|
+
</tr>
|
|
3106
|
+
}
|
|
3107
|
+
</tbody>
|
|
3108
|
+
</table>
|
|
3109
|
+
} @else {
|
|
3110
|
+
<div class="flex flex-col items-center gap-y-3 py-12">
|
|
3111
|
+
<span [innerHTML]="_getIcon('noteEmpty')"></span>
|
|
3112
|
+
<span class="text-sm text-[var(--cp-section-empty-text)]">No entitlements attached to this subscription</span>
|
|
3113
|
+
</div>
|
|
3114
|
+
}
|
|
3115
|
+
</div>
|
|
3116
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3117
|
+
}
|
|
3118
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: EntitlementSummaryComponent, decorators: [{
|
|
3119
|
+
type: Component,
|
|
3120
|
+
args: [{
|
|
3121
|
+
selector: 'cp-entitlement-summary',
|
|
3122
|
+
standalone: true,
|
|
3123
|
+
imports: [CommonModule],
|
|
3124
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3125
|
+
template: `
|
|
3126
|
+
<div class="overflow-x-auto bg-transparent">
|
|
3127
|
+
@if (entitlementSummary.length > 0) {
|
|
3128
|
+
<table class="min-w-full border-collapse text-left relative">
|
|
3129
|
+
<thead>
|
|
3130
|
+
<tr>
|
|
3131
|
+
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3132
|
+
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3133
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3134
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Feature</th>
|
|
3135
|
+
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3136
|
+
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3137
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3138
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Meter type</th>
|
|
3139
|
+
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3140
|
+
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3141
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3142
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Included allowance</th>
|
|
3143
|
+
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3144
|
+
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3145
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3146
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Usage limits</th>
|
|
3147
|
+
</tr>
|
|
3148
|
+
</thead>
|
|
3149
|
+
<tbody>
|
|
3150
|
+
@for (entitlement of entitlementSummary; track entitlement.id || $index; let rowIdx = $index) {
|
|
3151
|
+
<tr [class]="rowIdx % 2 === 0 ? 'bg-[var(--cp-table-row-even-bg)]' : 'bg-[var(--cp-table-row-odd-bg)]'">
|
|
3152
|
+
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3153
|
+
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3154
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3155
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3156
|
+
<div class="flex flex-col gap-y-1 items-start max-w-[130px]">
|
|
3157
|
+
<span>{{ entitlement.feature_name || '-' }}</span>
|
|
3158
|
+
<span class="text-[var(--cp-table-text)] max-w-[120px] truncate"
|
|
3159
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3160
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ entitlement.feature_key }}</span>
|
|
3161
|
+
</div>
|
|
3162
|
+
</td>
|
|
3163
|
+
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3164
|
+
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3165
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3166
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3167
|
+
<div>
|
|
3168
|
+
<span>{{ _capitalize(entitlement.feature_type) }}</span>
|
|
3169
|
+
@if (entitlement.usage_model) {
|
|
3170
|
+
<span class="block mt-1">{{ formatUsageModel(entitlement) }}</span>
|
|
3171
|
+
}
|
|
3172
|
+
</div>
|
|
3173
|
+
</td>
|
|
3174
|
+
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3175
|
+
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3176
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3177
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3178
|
+
{{ formatIncludedAllowance(entitlement) }}
|
|
3179
|
+
</td>
|
|
3180
|
+
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3181
|
+
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3182
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3183
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3184
|
+
{{ formatUsageLimits(entitlement) }}
|
|
3185
|
+
</td>
|
|
3186
|
+
</tr>
|
|
3187
|
+
}
|
|
3188
|
+
</tbody>
|
|
3189
|
+
</table>
|
|
3190
|
+
} @else {
|
|
3191
|
+
<div class="flex flex-col items-center gap-y-3 py-12">
|
|
3192
|
+
<span [innerHTML]="_getIcon('noteEmpty')"></span>
|
|
3193
|
+
<span class="text-sm text-[var(--cp-section-empty-text)]">No entitlements attached to this subscription</span>
|
|
3194
|
+
</div>
|
|
3195
|
+
}
|
|
3196
|
+
</div>
|
|
3197
|
+
`
|
|
3198
|
+
}]
|
|
3199
|
+
}], propDecorators: { entitlementSummary: [{
|
|
3200
|
+
type: Input
|
|
3201
|
+
}] } });
|
|
3202
|
+
|
|
3203
|
+
class EntitlementUsageComponent {
|
|
3204
|
+
sanitizer = inject(DomSanitizer);
|
|
3205
|
+
expandedEntitlements = new Set();
|
|
3206
|
+
Math = Math;
|
|
3207
|
+
entitlementUsage = [];
|
|
3208
|
+
get meteredEntitlements() {
|
|
3209
|
+
return (this.entitlementUsage || []).filter((usage) => usage.type !== 'boolean');
|
|
3210
|
+
}
|
|
3211
|
+
_getIcon(name) {
|
|
3212
|
+
return getIcon(this.sanitizer, name);
|
|
3213
|
+
}
|
|
3214
|
+
_capitalize(str) {
|
|
3215
|
+
return capitalize(str);
|
|
3216
|
+
}
|
|
3217
|
+
_formatNumber(num) {
|
|
3218
|
+
return formatNumber(num);
|
|
3219
|
+
}
|
|
3220
|
+
toggleExpand(id) {
|
|
2976
3221
|
if (this.expandedEntitlements.has(id)) {
|
|
2977
3222
|
this.expandedEntitlements.delete(id);
|
|
2978
3223
|
}
|
|
@@ -2980,10 +3225,10 @@ class EntitlementsSectionComponent {
|
|
|
2980
3225
|
this.expandedEntitlements.add(id);
|
|
2981
3226
|
}
|
|
2982
3227
|
}
|
|
2983
|
-
|
|
3228
|
+
isExpanded(id) {
|
|
2984
3229
|
return this.expandedEntitlements.has(id);
|
|
2985
3230
|
}
|
|
2986
|
-
|
|
3231
|
+
getUsageBalance(usage) {
|
|
2987
3232
|
const pools = this.getProcessedPools(usage);
|
|
2988
3233
|
const isAnyUnlimited = pools.some((p) => p.isUnlimited);
|
|
2989
3234
|
const totalBalance = pools.filter((p) => !p.isUnlimited).reduce((sum, p) => sum + p.balance, 0);
|
|
@@ -2993,7 +3238,7 @@ class EntitlementsSectionComponent {
|
|
|
2993
3238
|
return formatNumber(Math.abs(totalBalance)) + ' used above limit';
|
|
2994
3239
|
return formatNumber(totalBalance) + ' left';
|
|
2995
3240
|
}
|
|
2996
|
-
|
|
3241
|
+
getUsagePercent(usage) {
|
|
2997
3242
|
const pools = this.getProcessedPools(usage);
|
|
2998
3243
|
const isAnyUnlimited = pools.some((p) => p.isUnlimited);
|
|
2999
3244
|
if (isAnyUnlimited)
|
|
@@ -3004,7 +3249,7 @@ class EntitlementsSectionComponent {
|
|
|
3004
3249
|
return 0;
|
|
3005
3250
|
return Math.min((totalUsed / totalAmount) * 100, 100);
|
|
3006
3251
|
}
|
|
3007
|
-
|
|
3252
|
+
getUsageText(usage) {
|
|
3008
3253
|
const pools = this.getProcessedPools(usage);
|
|
3009
3254
|
const isAnyUnlimited = pools.some((p) => p.isUnlimited);
|
|
3010
3255
|
const totalAmount = pools.filter((p) => !p.isUnlimited).reduce((sum, p) => sum + p.amount, 0);
|
|
@@ -3019,13 +3264,14 @@ class EntitlementsSectionComponent {
|
|
|
3019
3264
|
{ key: 'included_pool', name: 'Included', color: 'gray-400', order: 1 },
|
|
3020
3265
|
{ key: 'purchased_pool', name: 'Purchased', color: 'gray-400', order: 2 },
|
|
3021
3266
|
{ key: 'pay_as_you_go_pool', name: 'Pay as you go', color: 'blue-500', order: 3 },
|
|
3022
|
-
{ key: 'rollover_quantity_pool', name: 'Rollover', color: 'green-500', order: 4 }
|
|
3267
|
+
{ key: 'rollover_quantity_pool', name: 'Rollover', color: 'green-500', order: 4 }
|
|
3023
3268
|
];
|
|
3024
3269
|
for (const config of poolConfigs) {
|
|
3025
|
-
const
|
|
3026
|
-
if (
|
|
3027
|
-
const
|
|
3028
|
-
const
|
|
3270
|
+
const rawPool = usage[config.key];
|
|
3271
|
+
if (rawPool && typeof rawPool === 'object') {
|
|
3272
|
+
const pool = rawPool;
|
|
3273
|
+
const amount = pool.amount === null ? Infinity : parseFloat(String(pool.amount)) || 0;
|
|
3274
|
+
const used = parseFloat(String(pool.used)) || 0;
|
|
3029
3275
|
const balance = amount === Infinity ? Infinity : amount - used;
|
|
3030
3276
|
const isUnlimited = amount === Infinity;
|
|
3031
3277
|
const percent = isUnlimited ? 100 : (amount > 0 ? (used / amount) * 100 : 0);
|
|
@@ -3038,26 +3284,297 @@ class EntitlementsSectionComponent {
|
|
|
3038
3284
|
percent: Math.min(percent, 100),
|
|
3039
3285
|
isUnlimited,
|
|
3040
3286
|
order: config.order,
|
|
3041
|
-
nextResetAt: pool.next_reset_at ? this.formatResetDate(pool.next_reset_at) : null
|
|
3287
|
+
nextResetAt: pool.next_reset_at ? this.formatResetDate(String(pool.next_reset_at)) : null
|
|
3042
3288
|
});
|
|
3043
3289
|
}
|
|
3044
3290
|
}
|
|
3045
|
-
return pools.sort((a, b) => a.order - b.order);
|
|
3291
|
+
return pools.sort((a, b) => a.order - b.order);
|
|
3292
|
+
}
|
|
3293
|
+
formatResetDate(dateStr) {
|
|
3294
|
+
if (!dateStr)
|
|
3295
|
+
return '';
|
|
3296
|
+
const date = new Date(dateStr);
|
|
3297
|
+
return date
|
|
3298
|
+
.toLocaleDateString('en-US', {
|
|
3299
|
+
month: 'short',
|
|
3300
|
+
day: 'numeric',
|
|
3301
|
+
year: 'numeric',
|
|
3302
|
+
hour: 'numeric',
|
|
3303
|
+
minute: '2-digit',
|
|
3304
|
+
hour12: true
|
|
3305
|
+
})
|
|
3306
|
+
.toLowerCase();
|
|
3307
|
+
}
|
|
3308
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: EntitlementUsageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3309
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: EntitlementUsageComponent, isStandalone: true, selector: "cp-entitlement-usage", inputs: { entitlementUsage: "entitlementUsage" }, ngImport: i0, template: `
|
|
3310
|
+
<div class="bg-transparent rounded-2xl px-3 pt-5">
|
|
3311
|
+
@if (meteredEntitlements.length > 0) {
|
|
3312
|
+
<!-- Header -->
|
|
3313
|
+
<div class="grid grid-cols-4 border-b border-[var(--cp-table-border)] gap-x-4 pr-12 bg-[var(--cp-table-header-bg)]"
|
|
3314
|
+
[style.padding]="'var(--cp-table-cell-padding, 0.75rem 1.5rem)'">
|
|
3315
|
+
<div class="text-[var(--cp-table-header-text)]"
|
|
3316
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3317
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Feature</div>
|
|
3318
|
+
<div class="text-[var(--cp-table-header-text)]"
|
|
3319
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3320
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Type</div>
|
|
3321
|
+
<div class="col-span-2 text-[var(--cp-table-header-text)]"
|
|
3322
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3323
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Usage</div>
|
|
3324
|
+
</div>
|
|
3325
|
+
|
|
3326
|
+
<!-- Rows -->
|
|
3327
|
+
@for (usage of meteredEntitlements; track usage.id || $index; let rowIdx = $index) {
|
|
3328
|
+
<div class="border-b border-[var(--cp-table-border)] last:border-0"
|
|
3329
|
+
[class]="rowIdx % 2 === 0 ? 'bg-[var(--cp-table-row-even-bg)]' : 'bg-[var(--cp-table-row-odd-bg)]'"
|
|
3330
|
+
[style.padding]="'var(--cp-table-cell-padding, 1rem 1.5rem)'">
|
|
3331
|
+
<!-- Main Row (Collapsible Trigger) -->
|
|
3332
|
+
<div class="flex items-center cursor-pointer" (click)="toggleExpand(usage.id)">
|
|
3333
|
+
<div class="flex-1 grid grid-cols-4 gap-4 items-center pr-8">
|
|
3334
|
+
<!-- Feature -->
|
|
3335
|
+
<div class="flex flex-col gap-y-1 items-start max-w-[120px] text-balance">
|
|
3336
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3337
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3338
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ usage.feature_name || '-' }}</span>
|
|
3339
|
+
<span class="text-[var(--cp-table-text)] max-w-[120px] truncate"
|
|
3340
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3341
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ usage.feature_key }}</span>
|
|
3342
|
+
</div>
|
|
3343
|
+
|
|
3344
|
+
<!-- Type -->
|
|
3345
|
+
<div>
|
|
3346
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3347
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3348
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ _capitalize(usage.type?.split('_').join(' ') || '') }}</span>
|
|
3349
|
+
</div>
|
|
3350
|
+
|
|
3351
|
+
<!-- Usage -->
|
|
3352
|
+
<div class="col-span-2">
|
|
3353
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3354
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3355
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ getUsageBalance(usage) }}</span>
|
|
3356
|
+
<div class="w-full flex items-center gap-x-2">
|
|
3357
|
+
<div class="w-full max-w-[24rem] h-[6px] my-[6px] bg-[var(--cp-section-usage-bar-track-color,#E4E4E7)] flex items-center justify-start rounded overflow-hidden">
|
|
3358
|
+
<div class="h-[6px] rounded" [style.width.%]="getUsagePercent(usage)" [style.backgroundColor]="'var(--cp-section-usage-bar-color)'"></div>
|
|
3359
|
+
</div>
|
|
3360
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3361
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3362
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ getUsageText(usage) }}</span>
|
|
3363
|
+
</div>
|
|
3364
|
+
</div>
|
|
3365
|
+
</div>
|
|
3366
|
+
|
|
3367
|
+
<!-- Expand Icon -->
|
|
3368
|
+
<div class="transform transition-transform duration-200"
|
|
3369
|
+
[class.rotate-180]="isExpanded(usage.id)"
|
|
3370
|
+
[style.color]="'var(--cp-table-expand-icon-color, #71717a)'">
|
|
3371
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"></path></svg>
|
|
3372
|
+
</div>
|
|
3373
|
+
</div>
|
|
3374
|
+
|
|
3375
|
+
<!-- Expanded Content (Pools) -->
|
|
3376
|
+
@if (isExpanded(usage.id)) {
|
|
3377
|
+
<div class="w-full rounded-lg overflow-hidden flex flex-col items-start justify-start gap-y-0 pt-4">
|
|
3378
|
+
@for (pool of getProcessedPools(usage); track pool.pool) {
|
|
3379
|
+
<div class="w-full flex items-center px-2 py-3 gap-x-12 sm:gap-x-20 md:gap-x-40">
|
|
3380
|
+
<span class="w-20 text-[var(--cp-table-text)]"
|
|
3381
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3382
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ pool.pool }}</span>
|
|
3383
|
+
<div class="flex-1">
|
|
3384
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3385
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3386
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3387
|
+
@if (!pool.isUnlimited) {
|
|
3388
|
+
@if (pool.balance < 0) {
|
|
3389
|
+
{{ _formatNumber(Math.abs(pool.balance)) }} used above limit
|
|
3390
|
+
} @else {
|
|
3391
|
+
{{ _formatNumber(pool.balance) }} left
|
|
3392
|
+
}
|
|
3393
|
+
}
|
|
3394
|
+
</span>
|
|
3395
|
+
<div class="w-full flex items-center gap-x-2">
|
|
3396
|
+
<div class="w-full max-w-[18rem] h-[6px] my-[6px] bg-[var(--cp-section-usage-bar-track-color,#E4E4E7)] flex items-center justify-start rounded overflow-hidden">
|
|
3397
|
+
<div class="h-[6px]" [style.width.%]="pool.percent" [style.backgroundColor]="'var(--cp-section-usage-bar-color)'"></div>
|
|
3398
|
+
</div>
|
|
3399
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3400
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3401
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3402
|
+
@if (pool.isUnlimited) {
|
|
3403
|
+
{{ _formatNumber(pool.used) }}/ Unlimited
|
|
3404
|
+
} @else {
|
|
3405
|
+
{{ _formatNumber(pool.used) }}/{{ _formatNumber(pool.amount) }}
|
|
3406
|
+
}
|
|
3407
|
+
</span>
|
|
3408
|
+
</div>
|
|
3409
|
+
@if (pool.nextResetAt) {
|
|
3410
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3411
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3412
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">resets on {{ pool.nextResetAt }}</span>
|
|
3413
|
+
}
|
|
3414
|
+
</div>
|
|
3415
|
+
</div>
|
|
3416
|
+
}
|
|
3417
|
+
</div>
|
|
3418
|
+
}
|
|
3419
|
+
</div>
|
|
3420
|
+
}
|
|
3421
|
+
} @else {
|
|
3422
|
+
<div class="flex flex-col items-center gap-y-3 py-12">
|
|
3423
|
+
<span [innerHTML]="_getIcon('noteEmpty')"></span>
|
|
3424
|
+
<span class="text-sm text-[var(--cp-section-empty-text)]">No metered entitlements attached to this subscription</span>
|
|
3425
|
+
</div>
|
|
3426
|
+
}
|
|
3427
|
+
</div>
|
|
3428
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3429
|
+
}
|
|
3430
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: EntitlementUsageComponent, decorators: [{
|
|
3431
|
+
type: Component,
|
|
3432
|
+
args: [{
|
|
3433
|
+
selector: 'cp-entitlement-usage',
|
|
3434
|
+
standalone: true,
|
|
3435
|
+
imports: [CommonModule],
|
|
3436
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3437
|
+
template: `
|
|
3438
|
+
<div class="bg-transparent rounded-2xl px-3 pt-5">
|
|
3439
|
+
@if (meteredEntitlements.length > 0) {
|
|
3440
|
+
<!-- Header -->
|
|
3441
|
+
<div class="grid grid-cols-4 border-b border-[var(--cp-table-border)] gap-x-4 pr-12 bg-[var(--cp-table-header-bg)]"
|
|
3442
|
+
[style.padding]="'var(--cp-table-cell-padding, 0.75rem 1.5rem)'">
|
|
3443
|
+
<div class="text-[var(--cp-table-header-text)]"
|
|
3444
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3445
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Feature</div>
|
|
3446
|
+
<div class="text-[var(--cp-table-header-text)]"
|
|
3447
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3448
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Type</div>
|
|
3449
|
+
<div class="col-span-2 text-[var(--cp-table-header-text)]"
|
|
3450
|
+
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3451
|
+
[style.fontWeight]="'var(--cp-table-header-weight)'">Usage</div>
|
|
3452
|
+
</div>
|
|
3453
|
+
|
|
3454
|
+
<!-- Rows -->
|
|
3455
|
+
@for (usage of meteredEntitlements; track usage.id || $index; let rowIdx = $index) {
|
|
3456
|
+
<div class="border-b border-[var(--cp-table-border)] last:border-0"
|
|
3457
|
+
[class]="rowIdx % 2 === 0 ? 'bg-[var(--cp-table-row-even-bg)]' : 'bg-[var(--cp-table-row-odd-bg)]'"
|
|
3458
|
+
[style.padding]="'var(--cp-table-cell-padding, 1rem 1.5rem)'">
|
|
3459
|
+
<!-- Main Row (Collapsible Trigger) -->
|
|
3460
|
+
<div class="flex items-center cursor-pointer" (click)="toggleExpand(usage.id)">
|
|
3461
|
+
<div class="flex-1 grid grid-cols-4 gap-4 items-center pr-8">
|
|
3462
|
+
<!-- Feature -->
|
|
3463
|
+
<div class="flex flex-col gap-y-1 items-start max-w-[120px] text-balance">
|
|
3464
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3465
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3466
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ usage.feature_name || '-' }}</span>
|
|
3467
|
+
<span class="text-[var(--cp-table-text)] max-w-[120px] truncate"
|
|
3468
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3469
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ usage.feature_key }}</span>
|
|
3470
|
+
</div>
|
|
3471
|
+
|
|
3472
|
+
<!-- Type -->
|
|
3473
|
+
<div>
|
|
3474
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3475
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3476
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ _capitalize(usage.type?.split('_').join(' ') || '') }}</span>
|
|
3477
|
+
</div>
|
|
3478
|
+
|
|
3479
|
+
<!-- Usage -->
|
|
3480
|
+
<div class="col-span-2">
|
|
3481
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3482
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3483
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ getUsageBalance(usage) }}</span>
|
|
3484
|
+
<div class="w-full flex items-center gap-x-2">
|
|
3485
|
+
<div class="w-full max-w-[24rem] h-[6px] my-[6px] bg-[var(--cp-section-usage-bar-track-color,#E4E4E7)] flex items-center justify-start rounded overflow-hidden">
|
|
3486
|
+
<div class="h-[6px] rounded" [style.width.%]="getUsagePercent(usage)" [style.backgroundColor]="'var(--cp-section-usage-bar-color)'"></div>
|
|
3487
|
+
</div>
|
|
3488
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3489
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3490
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ getUsageText(usage) }}</span>
|
|
3491
|
+
</div>
|
|
3492
|
+
</div>
|
|
3493
|
+
</div>
|
|
3494
|
+
|
|
3495
|
+
<!-- Expand Icon -->
|
|
3496
|
+
<div class="transform transition-transform duration-200"
|
|
3497
|
+
[class.rotate-180]="isExpanded(usage.id)"
|
|
3498
|
+
[style.color]="'var(--cp-table-expand-icon-color, #71717a)'">
|
|
3499
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"></path></svg>
|
|
3500
|
+
</div>
|
|
3501
|
+
</div>
|
|
3502
|
+
|
|
3503
|
+
<!-- Expanded Content (Pools) -->
|
|
3504
|
+
@if (isExpanded(usage.id)) {
|
|
3505
|
+
<div class="w-full rounded-lg overflow-hidden flex flex-col items-start justify-start gap-y-0 pt-4">
|
|
3506
|
+
@for (pool of getProcessedPools(usage); track pool.pool) {
|
|
3507
|
+
<div class="w-full flex items-center px-2 py-3 gap-x-12 sm:gap-x-20 md:gap-x-40">
|
|
3508
|
+
<span class="w-20 text-[var(--cp-table-text)]"
|
|
3509
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3510
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ pool.pool }}</span>
|
|
3511
|
+
<div class="flex-1">
|
|
3512
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3513
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3514
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3515
|
+
@if (!pool.isUnlimited) {
|
|
3516
|
+
@if (pool.balance < 0) {
|
|
3517
|
+
{{ _formatNumber(Math.abs(pool.balance)) }} used above limit
|
|
3518
|
+
} @else {
|
|
3519
|
+
{{ _formatNumber(pool.balance) }} left
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
</span>
|
|
3523
|
+
<div class="w-full flex items-center gap-x-2">
|
|
3524
|
+
<div class="w-full max-w-[18rem] h-[6px] my-[6px] bg-[var(--cp-section-usage-bar-track-color,#E4E4E7)] flex items-center justify-start rounded overflow-hidden">
|
|
3525
|
+
<div class="h-[6px]" [style.width.%]="pool.percent" [style.backgroundColor]="'var(--cp-section-usage-bar-color)'"></div>
|
|
3526
|
+
</div>
|
|
3527
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3528
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3529
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3530
|
+
@if (pool.isUnlimited) {
|
|
3531
|
+
{{ _formatNumber(pool.used) }}/ Unlimited
|
|
3532
|
+
} @else {
|
|
3533
|
+
{{ _formatNumber(pool.used) }}/{{ _formatNumber(pool.amount) }}
|
|
3534
|
+
}
|
|
3535
|
+
</span>
|
|
3536
|
+
</div>
|
|
3537
|
+
@if (pool.nextResetAt) {
|
|
3538
|
+
<span class="text-[var(--cp-table-text)]"
|
|
3539
|
+
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3540
|
+
[style.fontWeight]="'var(--cp-table-row-weight)'">resets on {{ pool.nextResetAt }}</span>
|
|
3541
|
+
}
|
|
3542
|
+
</div>
|
|
3543
|
+
</div>
|
|
3544
|
+
}
|
|
3545
|
+
</div>
|
|
3546
|
+
}
|
|
3547
|
+
</div>
|
|
3548
|
+
}
|
|
3549
|
+
} @else {
|
|
3550
|
+
<div class="flex flex-col items-center gap-y-3 py-12">
|
|
3551
|
+
<span [innerHTML]="_getIcon('noteEmpty')"></span>
|
|
3552
|
+
<span class="text-sm text-[var(--cp-section-empty-text)]">No metered entitlements attached to this subscription</span>
|
|
3553
|
+
</div>
|
|
3554
|
+
}
|
|
3555
|
+
</div>
|
|
3556
|
+
`
|
|
3557
|
+
}]
|
|
3558
|
+
}], propDecorators: { entitlementUsage: [{
|
|
3559
|
+
type: Input
|
|
3560
|
+
}] } });
|
|
3561
|
+
|
|
3562
|
+
class EntitlementsSectionComponent {
|
|
3563
|
+
entitlementSummary = [];
|
|
3564
|
+
entitlementUsage = [];
|
|
3565
|
+
sectionsConfig;
|
|
3566
|
+
entitlementTab = signal('summary');
|
|
3567
|
+
get hasMeteredEntitlements() {
|
|
3568
|
+
return (this.entitlementUsage || []).some((usage) => usage.type !== 'boolean');
|
|
3046
3569
|
}
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
return
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
year: 'numeric',
|
|
3056
|
-
hour: 'numeric',
|
|
3057
|
-
minute: '2-digit',
|
|
3058
|
-
hour12: true,
|
|
3059
|
-
})
|
|
3060
|
-
.toLowerCase();
|
|
3570
|
+
_isSectionHidden(key) {
|
|
3571
|
+
return isSectionHidden(this.sectionsConfig, key);
|
|
3572
|
+
}
|
|
3573
|
+
_getSectionLabel(key) {
|
|
3574
|
+
return getSectionLabel(this.sectionsConfig, key);
|
|
3575
|
+
}
|
|
3576
|
+
changeEntitlementTab(tab) {
|
|
3577
|
+
this.entitlementTab.set(tab);
|
|
3061
3578
|
}
|
|
3062
3579
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: EntitlementsSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3063
3580
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: EntitlementsSectionComponent, isStandalone: true, selector: "cp-entitlements-section", inputs: { entitlementSummary: "entitlementSummary", entitlementUsage: "entitlementUsage", sectionsConfig: "sectionsConfig" }, ngImport: i0, template: `
|
|
@@ -3089,7 +3606,7 @@ class EntitlementsSectionComponent {
|
|
|
3089
3606
|
(click)="changeEntitlementTab('summary')">
|
|
3090
3607
|
Summary
|
|
3091
3608
|
</button>
|
|
3092
|
-
@if (
|
|
3609
|
+
@if (hasMeteredEntitlements) {
|
|
3093
3610
|
<button
|
|
3094
3611
|
type="button"
|
|
3095
3612
|
class="px-6 py-1.5 rounded-md text-sm font-medium transition-all outline-none"
|
|
@@ -3104,209 +3621,24 @@ class EntitlementsSectionComponent {
|
|
|
3104
3621
|
|
|
3105
3622
|
<!-- Summary Tab Content -->
|
|
3106
3623
|
@if (entitlementTab() === 'summary') {
|
|
3107
|
-
<
|
|
3108
|
-
@if (entitlementSummary.length > 0) {
|
|
3109
|
-
<table class="min-w-full border-collapse text-left relative">
|
|
3110
|
-
<thead>
|
|
3111
|
-
<tr>
|
|
3112
|
-
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3113
|
-
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3114
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3115
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Feature</th>
|
|
3116
|
-
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3117
|
-
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3118
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3119
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Meter type</th>
|
|
3120
|
-
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3121
|
-
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3122
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3123
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Included allowance</th>
|
|
3124
|
-
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3125
|
-
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3126
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3127
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Usage limits</th>
|
|
3128
|
-
</tr>
|
|
3129
|
-
</thead>
|
|
3130
|
-
<tbody>
|
|
3131
|
-
@for (entitlement of entitlementSummary; track entitlement.id || $index; let rowIdx = $index) {
|
|
3132
|
-
<tr [class]="rowIdx % 2 === 0 ? 'bg-[var(--cp-table-row-even-bg)]' : 'bg-[var(--cp-table-row-odd-bg)]'">
|
|
3133
|
-
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3134
|
-
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3135
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3136
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3137
|
-
<div class="flex flex-col gap-y-1 items-start max-w-[130px]">
|
|
3138
|
-
<span>{{ entitlement.feature_name || '-' }}</span>
|
|
3139
|
-
<span class="text-[var(--cp-table-text)] max-w-[120px] truncate"
|
|
3140
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3141
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ entitlement.feature_key }}</span>
|
|
3142
|
-
</div>
|
|
3143
|
-
</td>
|
|
3144
|
-
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3145
|
-
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3146
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3147
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3148
|
-
<div>
|
|
3149
|
-
<span>{{ _capitalize(entitlement.feature_type) }}</span>
|
|
3150
|
-
@if (entitlement.usage_model) {
|
|
3151
|
-
<span class="block mt-1">{{ formatUsageModel(entitlement) }}</span>
|
|
3152
|
-
}
|
|
3153
|
-
</div>
|
|
3154
|
-
</td>
|
|
3155
|
-
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3156
|
-
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3157
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3158
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3159
|
-
{{ formatIncludedAllowance(entitlement) }}
|
|
3160
|
-
</td>
|
|
3161
|
-
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3162
|
-
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3163
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3164
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3165
|
-
{{ formatUsageLimits(entitlement) }}
|
|
3166
|
-
</td>
|
|
3167
|
-
</tr>
|
|
3168
|
-
}
|
|
3169
|
-
</tbody>
|
|
3170
|
-
</table>
|
|
3171
|
-
} @else {
|
|
3172
|
-
<div class="flex flex-col items-center gap-y-3 py-12">
|
|
3173
|
-
<span [innerHTML]="_getIcon('noteEmpty')"></span>
|
|
3174
|
-
<span class="text-sm text-[var(--cp-section-empty-text)]">No entitlements attached to this subscription</span>
|
|
3175
|
-
</div>
|
|
3176
|
-
}
|
|
3177
|
-
</div>
|
|
3624
|
+
<cp-entitlement-summary [entitlementSummary]="entitlementSummary"></cp-entitlement-summary>
|
|
3178
3625
|
}
|
|
3179
3626
|
|
|
3180
3627
|
<!-- Usage Tab Content -->
|
|
3181
3628
|
@if (entitlementTab() === 'usage') {
|
|
3182
|
-
<
|
|
3183
|
-
@if (getMeteredEntitlements().length > 0) {
|
|
3184
|
-
<!-- Header -->
|
|
3185
|
-
<div class="grid grid-cols-4 border-b border-[var(--cp-table-border)] gap-x-4 pr-12 bg-[var(--cp-table-header-bg)]"
|
|
3186
|
-
[style.padding]="'var(--cp-table-cell-padding, 0.75rem 1.5rem)'">
|
|
3187
|
-
<div class="text-[var(--cp-table-header-text)]"
|
|
3188
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3189
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Feature</div>
|
|
3190
|
-
<div class="text-[var(--cp-table-header-text)]"
|
|
3191
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3192
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Type</div>
|
|
3193
|
-
<div class="col-span-2 text-[var(--cp-table-header-text)]"
|
|
3194
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3195
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Usage</div>
|
|
3196
|
-
</div>
|
|
3197
|
-
|
|
3198
|
-
<!-- Rows -->
|
|
3199
|
-
@for (usage of getMeteredEntitlements(); track usage.id || $index; let rowIdx = $index) {
|
|
3200
|
-
<div class="border-b border-[var(--cp-table-border)] last:border-0"
|
|
3201
|
-
[class]="rowIdx % 2 === 0 ? 'bg-[var(--cp-table-row-even-bg)]' : 'bg-[var(--cp-table-row-odd-bg)]'"
|
|
3202
|
-
[style.padding]="'var(--cp-table-cell-padding, 1rem 1.5rem)'">
|
|
3203
|
-
<!-- Main Row (Collapsible Trigger) -->
|
|
3204
|
-
<div class="flex items-center cursor-pointer" (click)="toggleEntitlementExpand(usage.id)">
|
|
3205
|
-
<div class="flex-1 grid grid-cols-4 gap-4 items-center pr-8">
|
|
3206
|
-
<!-- Feature -->
|
|
3207
|
-
<div class="flex flex-col gap-y-1 items-start max-w-[120px] text-balance">
|
|
3208
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3209
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3210
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ usage.feature_name || '-' }}</span>
|
|
3211
|
-
<span class="text-[var(--cp-table-text)] max-w-[120px] truncate"
|
|
3212
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3213
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ usage.feature_key }}</span>
|
|
3214
|
-
</div>
|
|
3215
|
-
|
|
3216
|
-
<!-- Type -->
|
|
3217
|
-
<div>
|
|
3218
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3219
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3220
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ _capitalize(usage.type?.split('_').join(' ') || '') }}</span>
|
|
3221
|
-
</div>
|
|
3222
|
-
|
|
3223
|
-
<!-- Usage -->
|
|
3224
|
-
<div class="col-span-2">
|
|
3225
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3226
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3227
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ getEntitlementUsageBalance(usage) }}</span>
|
|
3228
|
-
<div class="w-full flex items-center gap-x-2">
|
|
3229
|
-
<div class="w-full max-w-[24rem] h-[6px] my-[6px] bg-[var(--cp-section-usage-bar-track-color,#E4E4E7)] flex items-center justify-start rounded overflow-hidden">
|
|
3230
|
-
<div class="h-[6px] rounded" [style.width.%]="getEntitlementUsagePercent(usage)" [style.backgroundColor]="'var(--cp-section-usage-bar-color)'"></div>
|
|
3231
|
-
</div>
|
|
3232
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3233
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3234
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ getEntitlementUsageText(usage) }}</span>
|
|
3235
|
-
</div>
|
|
3236
|
-
</div>
|
|
3237
|
-
</div>
|
|
3238
|
-
|
|
3239
|
-
<!-- Expand Icon -->
|
|
3240
|
-
<div class="transform transition-transform duration-200" [class.rotate-180]="isEntitlementExpanded(usage.id)">
|
|
3241
|
-
<span [innerHTML]="_getIcon('arrowDown')"></span>
|
|
3242
|
-
</div>
|
|
3243
|
-
</div>
|
|
3244
|
-
|
|
3245
|
-
<!-- Expanded Content (Pools) -->
|
|
3246
|
-
@if (isEntitlementExpanded(usage.id)) {
|
|
3247
|
-
<div class="w-full rounded-lg overflow-hidden flex flex-col items-start justify-start gap-y-0 pt-4">
|
|
3248
|
-
@for (pool of getProcessedPools(usage); track pool.pool) {
|
|
3249
|
-
<div class="w-full flex items-center px-2 py-3 gap-x-12 sm:gap-x-20 md:gap-x-40">
|
|
3250
|
-
<span class="w-20 text-[var(--cp-table-text)]"
|
|
3251
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3252
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ pool.pool }}</span>
|
|
3253
|
-
<div class="flex-1">
|
|
3254
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3255
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3256
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3257
|
-
@if (!pool.isUnlimited) {
|
|
3258
|
-
@if (pool.balance < 0) {
|
|
3259
|
-
{{ _formatNumber(Math.abs(pool.balance)) }} used above limit
|
|
3260
|
-
} @else {
|
|
3261
|
-
{{ _formatNumber(pool.balance) }} left
|
|
3262
|
-
}
|
|
3263
|
-
}
|
|
3264
|
-
</span>
|
|
3265
|
-
<div class="w-full flex items-center gap-x-2">
|
|
3266
|
-
<div class="w-full max-w-[18rem] h-[6px] my-[6px] bg-[var(--cp-section-usage-bar-track-color,#E4E4E7)] flex items-center justify-start rounded overflow-hidden">
|
|
3267
|
-
<div class="h-[6px]" [style.width.%]="pool.percent" [style.backgroundColor]="'var(--cp-section-usage-bar-color)'"></div>
|
|
3268
|
-
</div>
|
|
3269
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3270
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3271
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3272
|
-
@if (pool.isUnlimited) {
|
|
3273
|
-
{{ _formatNumber(pool.used) }}/ Unlimited
|
|
3274
|
-
} @else {
|
|
3275
|
-
{{ _formatNumber(pool.used) }}/{{ _formatNumber(pool.amount) }}
|
|
3276
|
-
}
|
|
3277
|
-
</span>
|
|
3278
|
-
</div>
|
|
3279
|
-
@if (pool.nextResetAt) {
|
|
3280
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3281
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3282
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">resets on {{ pool.nextResetAt }}</span>
|
|
3283
|
-
}
|
|
3284
|
-
</div>
|
|
3285
|
-
</div>
|
|
3286
|
-
}
|
|
3287
|
-
</div>
|
|
3288
|
-
}
|
|
3289
|
-
</div>
|
|
3290
|
-
}
|
|
3291
|
-
} @else {
|
|
3292
|
-
<div class="flex flex-col items-center gap-y-3 py-12">
|
|
3293
|
-
<span [innerHTML]="_getIcon('noteEmpty')"></span>
|
|
3294
|
-
<span class="text-sm text-[var(--cp-section-empty-text)]">No metered entitlements attached to this subscription</span>
|
|
3295
|
-
</div>
|
|
3296
|
-
}
|
|
3297
|
-
</div>
|
|
3629
|
+
<cp-entitlement-usage [entitlementUsage]="entitlementUsage"></cp-entitlement-usage>
|
|
3298
3630
|
}
|
|
3299
3631
|
</div>
|
|
3300
3632
|
</div>
|
|
3301
3633
|
}
|
|
3302
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3634
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: EntitlementSummaryComponent, selector: "cp-entitlement-summary", inputs: ["entitlementSummary"] }, { kind: "component", type: EntitlementUsageComponent, selector: "cp-entitlement-usage", inputs: ["entitlementUsage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3303
3635
|
}
|
|
3304
3636
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: EntitlementsSectionComponent, decorators: [{
|
|
3305
3637
|
type: Component,
|
|
3306
3638
|
args: [{
|
|
3307
3639
|
selector: 'cp-entitlements-section',
|
|
3308
3640
|
standalone: true,
|
|
3309
|
-
imports: [CommonModule],
|
|
3641
|
+
imports: [CommonModule, EntitlementSummaryComponent, EntitlementUsageComponent],
|
|
3310
3642
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3311
3643
|
template: `
|
|
3312
3644
|
@if (!_isSectionHidden('entitlementUsage')) {
|
|
@@ -3337,7 +3669,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
3337
3669
|
(click)="changeEntitlementTab('summary')">
|
|
3338
3670
|
Summary
|
|
3339
3671
|
</button>
|
|
3340
|
-
@if (
|
|
3672
|
+
@if (hasMeteredEntitlements) {
|
|
3341
3673
|
<button
|
|
3342
3674
|
type="button"
|
|
3343
3675
|
class="px-6 py-1.5 rounded-md text-sm font-medium transition-all outline-none"
|
|
@@ -3352,202 +3684,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
3352
3684
|
|
|
3353
3685
|
<!-- Summary Tab Content -->
|
|
3354
3686
|
@if (entitlementTab() === 'summary') {
|
|
3355
|
-
<
|
|
3356
|
-
@if (entitlementSummary.length > 0) {
|
|
3357
|
-
<table class="min-w-full border-collapse text-left relative">
|
|
3358
|
-
<thead>
|
|
3359
|
-
<tr>
|
|
3360
|
-
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3361
|
-
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3362
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3363
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Feature</th>
|
|
3364
|
-
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3365
|
-
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3366
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3367
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Meter type</th>
|
|
3368
|
-
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3369
|
-
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3370
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3371
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Included allowance</th>
|
|
3372
|
-
<th class="text-[var(--cp-table-header-text)] bg-[var(--cp-table-header-bg)] border-b border-[var(--cp-table-border)] whitespace-nowrap"
|
|
3373
|
-
[style.padding]="'var(--cp-table-cell-padding, 0.5rem 0.75rem)'"
|
|
3374
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3375
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Usage limits</th>
|
|
3376
|
-
</tr>
|
|
3377
|
-
</thead>
|
|
3378
|
-
<tbody>
|
|
3379
|
-
@for (entitlement of entitlementSummary; track entitlement.id || $index; let rowIdx = $index) {
|
|
3380
|
-
<tr [class]="rowIdx % 2 === 0 ? 'bg-[var(--cp-table-row-even-bg)]' : 'bg-[var(--cp-table-row-odd-bg)]'">
|
|
3381
|
-
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3382
|
-
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3383
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3384
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3385
|
-
<div class="flex flex-col gap-y-1 items-start max-w-[130px]">
|
|
3386
|
-
<span>{{ entitlement.feature_name || '-' }}</span>
|
|
3387
|
-
<span class="text-[var(--cp-table-text)] max-w-[120px] truncate"
|
|
3388
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3389
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ entitlement.feature_key }}</span>
|
|
3390
|
-
</div>
|
|
3391
|
-
</td>
|
|
3392
|
-
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3393
|
-
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3394
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3395
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3396
|
-
<div>
|
|
3397
|
-
<span>{{ _capitalize(entitlement.feature_type) }}</span>
|
|
3398
|
-
@if (entitlement.usage_model) {
|
|
3399
|
-
<span class="block mt-1">{{ formatUsageModel(entitlement) }}</span>
|
|
3400
|
-
}
|
|
3401
|
-
</div>
|
|
3402
|
-
</td>
|
|
3403
|
-
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3404
|
-
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3405
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3406
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3407
|
-
{{ formatIncludedAllowance(entitlement) }}
|
|
3408
|
-
</td>
|
|
3409
|
-
<td class="text-[var(--cp-table-text)] border-y border-[var(--cp-table-border)]"
|
|
3410
|
-
[style.padding]="'var(--cp-table-cell-padding, 1rem 0.75rem)'"
|
|
3411
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3412
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3413
|
-
{{ formatUsageLimits(entitlement) }}
|
|
3414
|
-
</td>
|
|
3415
|
-
</tr>
|
|
3416
|
-
}
|
|
3417
|
-
</tbody>
|
|
3418
|
-
</table>
|
|
3419
|
-
} @else {
|
|
3420
|
-
<div class="flex flex-col items-center gap-y-3 py-12">
|
|
3421
|
-
<span [innerHTML]="_getIcon('noteEmpty')"></span>
|
|
3422
|
-
<span class="text-sm text-[var(--cp-section-empty-text)]">No entitlements attached to this subscription</span>
|
|
3423
|
-
</div>
|
|
3424
|
-
}
|
|
3425
|
-
</div>
|
|
3687
|
+
<cp-entitlement-summary [entitlementSummary]="entitlementSummary"></cp-entitlement-summary>
|
|
3426
3688
|
}
|
|
3427
3689
|
|
|
3428
3690
|
<!-- Usage Tab Content -->
|
|
3429
3691
|
@if (entitlementTab() === 'usage') {
|
|
3430
|
-
<
|
|
3431
|
-
@if (getMeteredEntitlements().length > 0) {
|
|
3432
|
-
<!-- Header -->
|
|
3433
|
-
<div class="grid grid-cols-4 border-b border-[var(--cp-table-border)] gap-x-4 pr-12 bg-[var(--cp-table-header-bg)]"
|
|
3434
|
-
[style.padding]="'var(--cp-table-cell-padding, 0.75rem 1.5rem)'">
|
|
3435
|
-
<div class="text-[var(--cp-table-header-text)]"
|
|
3436
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3437
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Feature</div>
|
|
3438
|
-
<div class="text-[var(--cp-table-header-text)]"
|
|
3439
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3440
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Type</div>
|
|
3441
|
-
<div class="col-span-2 text-[var(--cp-table-header-text)]"
|
|
3442
|
-
[style.fontSize]="'var(--cp-table-header-size)'"
|
|
3443
|
-
[style.fontWeight]="'var(--cp-table-header-weight)'">Usage</div>
|
|
3444
|
-
</div>
|
|
3445
|
-
|
|
3446
|
-
<!-- Rows -->
|
|
3447
|
-
@for (usage of getMeteredEntitlements(); track usage.id || $index; let rowIdx = $index) {
|
|
3448
|
-
<div class="border-b border-[var(--cp-table-border)] last:border-0"
|
|
3449
|
-
[class]="rowIdx % 2 === 0 ? 'bg-[var(--cp-table-row-even-bg)]' : 'bg-[var(--cp-table-row-odd-bg)]'"
|
|
3450
|
-
[style.padding]="'var(--cp-table-cell-padding, 1rem 1.5rem)'">
|
|
3451
|
-
<!-- Main Row (Collapsible Trigger) -->
|
|
3452
|
-
<div class="flex items-center cursor-pointer" (click)="toggleEntitlementExpand(usage.id)">
|
|
3453
|
-
<div class="flex-1 grid grid-cols-4 gap-4 items-center pr-8">
|
|
3454
|
-
<!-- Feature -->
|
|
3455
|
-
<div class="flex flex-col gap-y-1 items-start max-w-[120px] text-balance">
|
|
3456
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3457
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3458
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ usage.feature_name || '-' }}</span>
|
|
3459
|
-
<span class="text-[var(--cp-table-text)] max-w-[120px] truncate"
|
|
3460
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3461
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ usage.feature_key }}</span>
|
|
3462
|
-
</div>
|
|
3463
|
-
|
|
3464
|
-
<!-- Type -->
|
|
3465
|
-
<div>
|
|
3466
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3467
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3468
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ _capitalize(usage.type?.split('_').join(' ') || '') }}</span>
|
|
3469
|
-
</div>
|
|
3470
|
-
|
|
3471
|
-
<!-- Usage -->
|
|
3472
|
-
<div class="col-span-2">
|
|
3473
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3474
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3475
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ getEntitlementUsageBalance(usage) }}</span>
|
|
3476
|
-
<div class="w-full flex items-center gap-x-2">
|
|
3477
|
-
<div class="w-full max-w-[24rem] h-[6px] my-[6px] bg-[var(--cp-section-usage-bar-track-color,#E4E4E7)] flex items-center justify-start rounded overflow-hidden">
|
|
3478
|
-
<div class="h-[6px] rounded" [style.width.%]="getEntitlementUsagePercent(usage)" [style.backgroundColor]="'var(--cp-section-usage-bar-color)'"></div>
|
|
3479
|
-
</div>
|
|
3480
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3481
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3482
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ getEntitlementUsageText(usage) }}</span>
|
|
3483
|
-
</div>
|
|
3484
|
-
</div>
|
|
3485
|
-
</div>
|
|
3486
|
-
|
|
3487
|
-
<!-- Expand Icon -->
|
|
3488
|
-
<div class="transform transition-transform duration-200" [class.rotate-180]="isEntitlementExpanded(usage.id)">
|
|
3489
|
-
<span [innerHTML]="_getIcon('arrowDown')"></span>
|
|
3490
|
-
</div>
|
|
3491
|
-
</div>
|
|
3492
|
-
|
|
3493
|
-
<!-- Expanded Content (Pools) -->
|
|
3494
|
-
@if (isEntitlementExpanded(usage.id)) {
|
|
3495
|
-
<div class="w-full rounded-lg overflow-hidden flex flex-col items-start justify-start gap-y-0 pt-4">
|
|
3496
|
-
@for (pool of getProcessedPools(usage); track pool.pool) {
|
|
3497
|
-
<div class="w-full flex items-center px-2 py-3 gap-x-12 sm:gap-x-20 md:gap-x-40">
|
|
3498
|
-
<span class="w-20 text-[var(--cp-table-text)]"
|
|
3499
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3500
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">{{ pool.pool }}</span>
|
|
3501
|
-
<div class="flex-1">
|
|
3502
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3503
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3504
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3505
|
-
@if (!pool.isUnlimited) {
|
|
3506
|
-
@if (pool.balance < 0) {
|
|
3507
|
-
{{ _formatNumber(Math.abs(pool.balance)) }} used above limit
|
|
3508
|
-
} @else {
|
|
3509
|
-
{{ _formatNumber(pool.balance) }} left
|
|
3510
|
-
}
|
|
3511
|
-
}
|
|
3512
|
-
</span>
|
|
3513
|
-
<div class="w-full flex items-center gap-x-2">
|
|
3514
|
-
<div class="w-full max-w-[18rem] h-[6px] my-[6px] bg-[var(--cp-section-usage-bar-track-color,#E4E4E7)] flex items-center justify-start rounded overflow-hidden">
|
|
3515
|
-
<div class="h-[6px]" [style.width.%]="pool.percent" [style.backgroundColor]="'var(--cp-section-usage-bar-color)'"></div>
|
|
3516
|
-
</div>
|
|
3517
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3518
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3519
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">
|
|
3520
|
-
@if (pool.isUnlimited) {
|
|
3521
|
-
{{ _formatNumber(pool.used) }}/ Unlimited
|
|
3522
|
-
} @else {
|
|
3523
|
-
{{ _formatNumber(pool.used) }}/{{ _formatNumber(pool.amount) }}
|
|
3524
|
-
}
|
|
3525
|
-
</span>
|
|
3526
|
-
</div>
|
|
3527
|
-
@if (pool.nextResetAt) {
|
|
3528
|
-
<span class="text-[var(--cp-table-text)]"
|
|
3529
|
-
[style.fontSize]="'var(--cp-table-row-size)'"
|
|
3530
|
-
[style.fontWeight]="'var(--cp-table-row-weight)'">resets on {{ pool.nextResetAt }}</span>
|
|
3531
|
-
}
|
|
3532
|
-
</div>
|
|
3533
|
-
</div>
|
|
3534
|
-
}
|
|
3535
|
-
</div>
|
|
3536
|
-
}
|
|
3537
|
-
</div>
|
|
3538
|
-
}
|
|
3539
|
-
} @else {
|
|
3540
|
-
<div class="flex flex-col items-center gap-y-3 py-12">
|
|
3541
|
-
<span [innerHTML]="_getIcon('noteEmpty')"></span>
|
|
3542
|
-
<span class="text-sm text-[var(--cp-section-empty-text)]">No metered entitlements attached to this subscription</span>
|
|
3543
|
-
</div>
|
|
3544
|
-
}
|
|
3545
|
-
</div>
|
|
3692
|
+
<cp-entitlement-usage [entitlementUsage]="entitlementUsage"></cp-entitlement-usage>
|
|
3546
3693
|
}
|
|
3547
3694
|
</div>
|
|
3548
3695
|
</div>
|
|
3549
3696
|
}
|
|
3550
|
-
|
|
3697
|
+
`
|
|
3551
3698
|
}]
|
|
3552
3699
|
}], propDecorators: { entitlementSummary: [{
|
|
3553
3700
|
type: Input
|
|
@@ -3738,7 +3885,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
3738
3885
|
</div>
|
|
3739
3886
|
</div>
|
|
3740
3887
|
}
|
|
3741
|
-
|
|
3888
|
+
`
|
|
3742
3889
|
}]
|
|
3743
3890
|
}], propDecorators: { subscription: [{
|
|
3744
3891
|
type: Input
|
|
@@ -3969,7 +4116,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
3969
4116
|
</div>
|
|
3970
4117
|
</div>
|
|
3971
4118
|
}
|
|
3972
|
-
|
|
4119
|
+
`
|
|
3973
4120
|
}]
|
|
3974
4121
|
}], propDecorators: { billingHistory: [{
|
|
3975
4122
|
type: Input
|
|
@@ -4015,7 +4162,7 @@ class PlansSectionComponent {
|
|
|
4015
4162
|
monthly: 'Monthly',
|
|
4016
4163
|
quarterly: 'Quarterly',
|
|
4017
4164
|
biannually: 'Biannually',
|
|
4018
|
-
yearly: 'Yearly'
|
|
4165
|
+
yearly: 'Yearly'
|
|
4019
4166
|
};
|
|
4020
4167
|
return labels[interval] || capitalize(interval);
|
|
4021
4168
|
}
|
|
@@ -4023,36 +4170,40 @@ class PlansSectionComponent {
|
|
|
4023
4170
|
const allPriceOptions = [
|
|
4024
4171
|
...(plan.price_options || []),
|
|
4025
4172
|
...(plan.entitlement_price_options || []),
|
|
4026
|
-
...(plan.credit_attachment_price_options || [])
|
|
4173
|
+
...(plan.credit_attachment_price_options || [])
|
|
4027
4174
|
];
|
|
4028
4175
|
return allPriceOptions.find((po) => po.price?.billing_interval === this.selectedPlanInterval());
|
|
4029
4176
|
}
|
|
4030
4177
|
getPlanPriceInteger(plan) {
|
|
4031
4178
|
const priceOption = this.getPlanPriceOption(plan);
|
|
4032
|
-
|
|
4179
|
+
const price = priceOption?.price;
|
|
4180
|
+
if (!price)
|
|
4033
4181
|
return 'Contact';
|
|
4034
|
-
let amount =
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4182
|
+
let amount = price.price;
|
|
4183
|
+
const tiers = price.tiers;
|
|
4184
|
+
if (tiers && tiers.length > 0) {
|
|
4185
|
+
const tier = tiers[0];
|
|
4186
|
+
amount = (tier.unit_price || tier.package_price || tier.flat_fee || 0);
|
|
4038
4187
|
}
|
|
4039
|
-
const currency =
|
|
4188
|
+
const currency = price.currency || 'USD';
|
|
4040
4189
|
const symbol = getCurrencySymbol(currency);
|
|
4041
|
-
const
|
|
4042
|
-
const amountParts =
|
|
4190
|
+
const formatted = formatPriceAmount(amount);
|
|
4191
|
+
const amountParts = formatted?.split('.');
|
|
4043
4192
|
return `${symbol}${amountParts?.[0] ?? '0'}`;
|
|
4044
4193
|
}
|
|
4045
4194
|
getPlanPriceDecimal(plan) {
|
|
4046
4195
|
const priceOption = this.getPlanPriceOption(plan);
|
|
4047
|
-
|
|
4196
|
+
const price = priceOption?.price;
|
|
4197
|
+
if (!price)
|
|
4048
4198
|
return '00';
|
|
4049
|
-
let amount =
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4199
|
+
let amount = price.price;
|
|
4200
|
+
const tiers = price.tiers;
|
|
4201
|
+
if (tiers && tiers.length > 0) {
|
|
4202
|
+
const tier = tiers[0];
|
|
4203
|
+
amount = (tier.unit_price || tier.package_price || tier.flat_fee || 0);
|
|
4053
4204
|
}
|
|
4054
|
-
const
|
|
4055
|
-
const amountParts =
|
|
4205
|
+
const formatted = formatPriceAmount(amount);
|
|
4206
|
+
const amountParts = formatted?.split('.');
|
|
4056
4207
|
return amountParts && amountParts.length > 1 ? amountParts[1].padEnd(2, '0').slice(0, 2) : '00';
|
|
4057
4208
|
}
|
|
4058
4209
|
getMultiplyNumber(interval, intervalValue) {
|
|
@@ -4063,26 +4214,29 @@ class PlansSectionComponent {
|
|
|
4063
4214
|
monthly: v,
|
|
4064
4215
|
quarterly: 3 * v,
|
|
4065
4216
|
biannually: 6 * v,
|
|
4066
|
-
yearly: 12 * v
|
|
4217
|
+
yearly: 12 * v
|
|
4067
4218
|
};
|
|
4068
4219
|
return map[interval] ?? v;
|
|
4069
4220
|
}
|
|
4070
4221
|
getPlanFixedPriceBilledAmount(plan) {
|
|
4071
4222
|
const priceOption = this.getPlanPriceOption(plan);
|
|
4072
|
-
|
|
4223
|
+
const price = priceOption?.price;
|
|
4224
|
+
if (!price)
|
|
4073
4225
|
return 0;
|
|
4074
|
-
let unitPrice =
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4226
|
+
let unitPrice = price.price;
|
|
4227
|
+
const tiers = price.tiers;
|
|
4228
|
+
if (tiers?.length) {
|
|
4229
|
+
const tier = tiers[0];
|
|
4230
|
+
unitPrice = (tier.unit_price ?? tier.package_price ?? tier.flat_fee ?? 0);
|
|
4078
4231
|
}
|
|
4079
4232
|
const interval = this.selectedPlanInterval();
|
|
4080
|
-
const intervalValue =
|
|
4233
|
+
const intervalValue = price.billing_interval_value ?? 1;
|
|
4081
4234
|
return this.getMultiplyNumber(interval, intervalValue) * (unitPrice ?? 0);
|
|
4082
4235
|
}
|
|
4083
4236
|
getPlanFixedPriceCurrencySymbol(plan) {
|
|
4084
4237
|
const po = this.getPlanPriceOption(plan);
|
|
4085
|
-
|
|
4238
|
+
const price = po?.price;
|
|
4239
|
+
return getCurrencySymbol(price?.currency || 'USD');
|
|
4086
4240
|
}
|
|
4087
4241
|
hasFixedPrice(plan) {
|
|
4088
4242
|
const interval = this.selectedPlanInterval();
|
|
@@ -4098,49 +4252,56 @@ class PlansSectionComponent {
|
|
|
4098
4252
|
const interval = this.selectedPlanInterval();
|
|
4099
4253
|
return [
|
|
4100
4254
|
...(plan.entitlement_price_options || []).filter((po) => po.price?.billing_interval === interval),
|
|
4101
|
-
...(plan.credit_attachment_price_options || []).filter((po) => po.price?.billing_interval === interval)
|
|
4255
|
+
...(plan.credit_attachment_price_options || []).filter((po) => po.price?.billing_interval === interval)
|
|
4102
4256
|
];
|
|
4103
4257
|
}
|
|
4104
4258
|
getDynamicPriceName(priceOption) {
|
|
4105
|
-
|
|
4259
|
+
const price = priceOption?.price;
|
|
4260
|
+
const owner = price?.owner;
|
|
4261
|
+
const feature = owner && 'feature' in owner ? owner.feature : undefined;
|
|
4262
|
+
return price?.name || feature?.name || owner?.name || 'Feature';
|
|
4106
4263
|
}
|
|
4107
4264
|
formatDynamicPrice(priceOption) {
|
|
4108
|
-
|
|
4265
|
+
const price = priceOption?.price;
|
|
4266
|
+
if (!price)
|
|
4109
4267
|
return '';
|
|
4110
|
-
const tiers =
|
|
4268
|
+
const tiers = price.tiers || [];
|
|
4111
4269
|
if (tiers.length === 0)
|
|
4112
4270
|
return '';
|
|
4113
4271
|
const tier = tiers[0];
|
|
4114
|
-
const currency =
|
|
4272
|
+
const currency = price.currency || 'USD';
|
|
4115
4273
|
const symbol = getCurrencySymbol(currency);
|
|
4116
|
-
const amount = tier.unit_price || tier.package_price || tier.flat_fee || 0;
|
|
4274
|
+
const amount = (tier.unit_price || tier.package_price || tier.flat_fee || 0);
|
|
4117
4275
|
const formattedAmount = formatPriceAmount(amount);
|
|
4118
|
-
const owner =
|
|
4119
|
-
const
|
|
4276
|
+
const owner = price.owner;
|
|
4277
|
+
const feature = owner && 'feature' in owner ? owner.feature : undefined;
|
|
4278
|
+
const unitLabel = feature?.unit_singular || owner?.unit_singular || feature?.name || owner?.name || '';
|
|
4120
4279
|
return unitLabel ? `${symbol}${formattedAmount}/${unitLabel}` : `${symbol}${formattedAmount}`;
|
|
4121
4280
|
}
|
|
4122
4281
|
formatDynamicPriceFull(priceOption) {
|
|
4123
|
-
|
|
4282
|
+
const price = priceOption?.price;
|
|
4283
|
+
if (!price)
|
|
4124
4284
|
return '';
|
|
4125
|
-
const tiers =
|
|
4285
|
+
const tiers = price.tiers || [];
|
|
4126
4286
|
if (tiers.length === 0)
|
|
4127
4287
|
return '';
|
|
4128
4288
|
const tier = tiers[0];
|
|
4129
|
-
const currency =
|
|
4289
|
+
const currency = price.currency || 'USD';
|
|
4130
4290
|
const symbol = getCurrencySymbol(currency);
|
|
4131
|
-
const amount = tier.unit_price || tier.package_price || tier.flat_fee || 0;
|
|
4291
|
+
const amount = (tier.unit_price || tier.package_price || tier.flat_fee || 0);
|
|
4132
4292
|
const name = this.getDynamicPriceName(priceOption);
|
|
4133
4293
|
return `${symbol}${amount.toFixed(2)}/${name}`;
|
|
4134
4294
|
}
|
|
4135
4295
|
getDynamicPriceAmountDisplay(priceOption) {
|
|
4136
|
-
|
|
4296
|
+
const price = priceOption?.price;
|
|
4297
|
+
if (!price)
|
|
4137
4298
|
return '';
|
|
4138
|
-
const tiers =
|
|
4299
|
+
const tiers = price.tiers || [];
|
|
4139
4300
|
if (tiers.length === 0)
|
|
4140
4301
|
return '';
|
|
4141
4302
|
const tier = tiers[0];
|
|
4142
|
-
const amount = tier.unit_price || tier.package_price || tier.flat_fee || 0;
|
|
4143
|
-
const currency =
|
|
4303
|
+
const amount = (tier.unit_price || tier.package_price || tier.flat_fee || 0);
|
|
4304
|
+
const currency = price.currency || 'USD';
|
|
4144
4305
|
const symbol = getCurrencySymbol(currency);
|
|
4145
4306
|
return `${symbol}${amount.toFixed(2)}`;
|
|
4146
4307
|
}
|
|
@@ -4148,30 +4309,30 @@ class PlansSectionComponent {
|
|
|
4148
4309
|
const prices = this.getDynamicPrices(plan);
|
|
4149
4310
|
if (prices.length === 0)
|
|
4150
4311
|
return '0';
|
|
4151
|
-
const
|
|
4152
|
-
const tiers =
|
|
4312
|
+
const firstPriceObj = prices[0].price;
|
|
4313
|
+
const tiers = firstPriceObj?.tiers || [];
|
|
4153
4314
|
if (tiers.length === 0)
|
|
4154
4315
|
return '0';
|
|
4155
4316
|
const tier = tiers[0];
|
|
4156
|
-
const amount = tier.unit_price || tier.package_price || tier.flat_fee || 0;
|
|
4157
|
-
const currency =
|
|
4317
|
+
const amount = (tier.unit_price || tier.package_price || tier.flat_fee || 0);
|
|
4318
|
+
const currency = firstPriceObj?.currency || 'USD';
|
|
4158
4319
|
const symbol = getCurrencySymbol(currency);
|
|
4159
|
-
const
|
|
4160
|
-
const amountParts =
|
|
4320
|
+
const formatted = formatPriceAmount(amount);
|
|
4321
|
+
const amountParts = formatted?.split('.');
|
|
4161
4322
|
return `${symbol}${amountParts?.[0] ?? '0'}`;
|
|
4162
4323
|
}
|
|
4163
4324
|
getMainDynamicPriceDecimal(plan) {
|
|
4164
4325
|
const prices = this.getDynamicPrices(plan);
|
|
4165
4326
|
if (prices.length === 0)
|
|
4166
4327
|
return '00';
|
|
4167
|
-
const
|
|
4168
|
-
const tiers =
|
|
4328
|
+
const firstPriceObj = prices[0].price;
|
|
4329
|
+
const tiers = firstPriceObj?.tiers || [];
|
|
4169
4330
|
if (tiers.length === 0)
|
|
4170
4331
|
return '00';
|
|
4171
4332
|
const tier = tiers[0];
|
|
4172
|
-
const amount = tier.unit_price || tier.package_price || tier.flat_fee || 0;
|
|
4173
|
-
const
|
|
4174
|
-
const amountParts =
|
|
4333
|
+
const amount = (tier.unit_price || tier.package_price || tier.flat_fee || 0);
|
|
4334
|
+
const formatted = formatPriceAmount(amount);
|
|
4335
|
+
const amountParts = formatted?.split('.');
|
|
4175
4336
|
return amountParts && amountParts.length > 1 ? amountParts[1].padEnd(2, '0').slice(0, 2) : '00';
|
|
4176
4337
|
}
|
|
4177
4338
|
getMainDynamicPriceUnit(plan) {
|
|
@@ -4289,15 +4450,14 @@ class PlansSectionComponent {
|
|
|
4289
4450
|
<div class="flex gap-x-2 overflow-x-auto whitespace-nowrap px-6 py-4 -mx-4">
|
|
4290
4451
|
@for (plan of plans; track plan.id; let idx = $index) {
|
|
4291
4452
|
<div
|
|
4292
|
-
class="flex flex-col shrink-0 w-[330px]
|
|
4293
|
-
[style.borderRadius]="'var(--pt-card-radius,
|
|
4453
|
+
class="flex flex-col shrink-0 w-[330px]"
|
|
4454
|
+
[style.borderRadius]="plan.is_current_plan ? 'var(--pt-current-sub-card-radius, var(--pt-card-radius, 1rem))' : 'var(--pt-card-radius, 1rem)'"
|
|
4294
4455
|
[style.borderWidth]="'var(--pt-card-border-width, 1px)'"
|
|
4295
4456
|
[style.borderStyle]="'solid'"
|
|
4296
|
-
[style.borderColor]="'var(--pt-card-border)'"
|
|
4457
|
+
[style.borderColor]="'var(--pt-card-border, #e5e7eb)'"
|
|
4297
4458
|
[style.background-color]="plan.is_current_plan ? 'var(--pt-current-sub-card-header-bg)' : 'var(--pt-card-header-bg)'">
|
|
4298
4459
|
<!-- Card Header -->
|
|
4299
|
-
<div class="flex items-center justify-between pl-4 pr-[5px] pt-[6px] pb-[2px]
|
|
4300
|
-
[style.background-color]="plan.is_current_plan ? 'var(--pt-current-sub-card-header-bg)' : 'var(--pt-card-header-bg)'">
|
|
4460
|
+
<div class="flex items-center justify-between pl-4 pr-[5px] pt-[6px] pb-[2px]">
|
|
4301
4461
|
<span
|
|
4302
4462
|
class="text-sm font-medium"
|
|
4303
4463
|
[style.color]="plan.is_current_plan ? 'var(--pt-current-sub-card-header-text)' : 'var(--pt-card-header-text)'">
|
|
@@ -4314,12 +4474,11 @@ class PlansSectionComponent {
|
|
|
4314
4474
|
|
|
4315
4475
|
<!-- Card Body -->
|
|
4316
4476
|
<div
|
|
4317
|
-
class="flex-grow
|
|
4318
|
-
[style.
|
|
4319
|
-
[style.border]="'1px solid var(--pt-card-
|
|
4320
|
-
[style.
|
|
4321
|
-
[
|
|
4322
|
-
[class.border-t-0]="!plan.is_current_plan">
|
|
4477
|
+
class="flex-grow w-full p-2 pb-10"
|
|
4478
|
+
[style.borderRadius]="'calc(' + (plan.is_current_plan ? 'var(--pt-current-sub-card-radius, var(--pt-card-radius, 1rem))' : 'var(--pt-card-radius, 1rem)') + ' - 2px)'"
|
|
4479
|
+
[style.border]="'1px solid ' + (plan.is_current_plan ? 'var(--pt-current-sub-card-header-bg)' : 'var(--pt-card-header-bg)')"
|
|
4480
|
+
[style.background-color]="'var(--pt-card-bg, #ffffff)'"
|
|
4481
|
+
[style.backgroundImage]="plan.is_current_plan ? 'var(--pt-card-gradient)' : undefined">
|
|
4323
4482
|
|
|
4324
4483
|
<!-- Description -->
|
|
4325
4484
|
@if (shouldShowPlanDescription()) {
|
|
@@ -4605,15 +4764,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
4605
4764
|
<div class="flex gap-x-2 overflow-x-auto whitespace-nowrap px-6 py-4 -mx-4">
|
|
4606
4765
|
@for (plan of plans; track plan.id; let idx = $index) {
|
|
4607
4766
|
<div
|
|
4608
|
-
class="flex flex-col shrink-0 w-[330px]
|
|
4609
|
-
[style.borderRadius]="'var(--pt-card-radius,
|
|
4767
|
+
class="flex flex-col shrink-0 w-[330px]"
|
|
4768
|
+
[style.borderRadius]="plan.is_current_plan ? 'var(--pt-current-sub-card-radius, var(--pt-card-radius, 1rem))' : 'var(--pt-card-radius, 1rem)'"
|
|
4610
4769
|
[style.borderWidth]="'var(--pt-card-border-width, 1px)'"
|
|
4611
4770
|
[style.borderStyle]="'solid'"
|
|
4612
|
-
[style.borderColor]="'var(--pt-card-border)'"
|
|
4771
|
+
[style.borderColor]="'var(--pt-card-border, #e5e7eb)'"
|
|
4613
4772
|
[style.background-color]="plan.is_current_plan ? 'var(--pt-current-sub-card-header-bg)' : 'var(--pt-card-header-bg)'">
|
|
4614
4773
|
<!-- Card Header -->
|
|
4615
|
-
<div class="flex items-center justify-between pl-4 pr-[5px] pt-[6px] pb-[2px]
|
|
4616
|
-
[style.background-color]="plan.is_current_plan ? 'var(--pt-current-sub-card-header-bg)' : 'var(--pt-card-header-bg)'">
|
|
4774
|
+
<div class="flex items-center justify-between pl-4 pr-[5px] pt-[6px] pb-[2px]">
|
|
4617
4775
|
<span
|
|
4618
4776
|
class="text-sm font-medium"
|
|
4619
4777
|
[style.color]="plan.is_current_plan ? 'var(--pt-current-sub-card-header-text)' : 'var(--pt-card-header-text)'">
|
|
@@ -4630,12 +4788,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
4630
4788
|
|
|
4631
4789
|
<!-- Card Body -->
|
|
4632
4790
|
<div
|
|
4633
|
-
class="flex-grow
|
|
4634
|
-
[style.
|
|
4635
|
-
[style.border]="'1px solid var(--pt-card-
|
|
4636
|
-
[style.
|
|
4637
|
-
[
|
|
4638
|
-
[class.border-t-0]="!plan.is_current_plan">
|
|
4791
|
+
class="flex-grow w-full p-2 pb-10"
|
|
4792
|
+
[style.borderRadius]="'calc(' + (plan.is_current_plan ? 'var(--pt-current-sub-card-radius, var(--pt-card-radius, 1rem))' : 'var(--pt-card-radius, 1rem)') + ' - 2px)'"
|
|
4793
|
+
[style.border]="'1px solid ' + (plan.is_current_plan ? 'var(--pt-current-sub-card-header-bg)' : 'var(--pt-card-header-bg)')"
|
|
4794
|
+
[style.background-color]="'var(--pt-card-bg, #ffffff)'"
|
|
4795
|
+
[style.backgroundImage]="plan.is_current_plan ? 'var(--pt-card-gradient)' : undefined">
|
|
4639
4796
|
|
|
4640
4797
|
<!-- Description -->
|
|
4641
4798
|
@if (shouldShowPlanDescription()) {
|
|
@@ -4855,7 +5012,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
4855
5012
|
</div>
|
|
4856
5013
|
</div>
|
|
4857
5014
|
}
|
|
4858
|
-
|
|
5015
|
+
`
|
|
4859
5016
|
}]
|
|
4860
5017
|
}], propDecorators: { plans: [{
|
|
4861
5018
|
type: Input
|
|
@@ -4885,7 +5042,7 @@ class InvoicePreviewComponent {
|
|
|
4885
5042
|
return date.toLocaleDateString(undefined, {
|
|
4886
5043
|
month: 'short',
|
|
4887
5044
|
day: 'numeric',
|
|
4888
|
-
year: 'numeric'
|
|
5045
|
+
year: 'numeric'
|
|
4889
5046
|
});
|
|
4890
5047
|
}
|
|
4891
5048
|
formatInvoicePrice(amount) {
|
|
@@ -4906,12 +5063,12 @@ class InvoicePreviewComponent {
|
|
|
4906
5063
|
if (!invoice)
|
|
4907
5064
|
return '$';
|
|
4908
5065
|
const c = invoice.currency;
|
|
4909
|
-
return c?.symbol ??
|
|
5066
|
+
return (c?.symbol ?? '$');
|
|
4910
5067
|
}
|
|
4911
5068
|
getInvoiceSummaryNumber(invoice, ...keys) {
|
|
4912
5069
|
if (!invoice)
|
|
4913
5070
|
return 0;
|
|
4914
|
-
const s = invoice.summary ?? {};
|
|
5071
|
+
const s = (invoice.summary ?? {});
|
|
4915
5072
|
for (const k of keys) {
|
|
4916
5073
|
const v = s[k];
|
|
4917
5074
|
if (v !== undefined && v !== null && v !== '') {
|
|
@@ -4924,51 +5081,45 @@ class InvoicePreviewComponent {
|
|
|
4924
5081
|
getInvoiceLineItems(invoice) {
|
|
4925
5082
|
if (!invoice)
|
|
4926
5083
|
return [];
|
|
4927
|
-
const lineItems = invoice.line_items ??
|
|
4928
|
-
const chargeItems = invoice.charge_items ??
|
|
4929
|
-
const usageItems = invoice.usage_items ??
|
|
4930
|
-
const creditItems = invoice.credit_items ??
|
|
5084
|
+
const lineItems = invoice.line_items ?? [];
|
|
5085
|
+
const chargeItems = invoice.charge_items ?? [];
|
|
5086
|
+
const usageItems = invoice.usage_items ?? [];
|
|
5087
|
+
const creditItems = invoice.credit_items ?? [];
|
|
4931
5088
|
const normalize = (item, itemType) => this.normalizeInvoiceLineItem(item, itemType);
|
|
4932
5089
|
return [
|
|
4933
|
-
...
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
...
|
|
4937
|
-
? chargeItems.map((i) => normalize(i, 'charge_item'))
|
|
4938
|
-
: []),
|
|
4939
|
-
...(Array.isArray(usageItems)
|
|
4940
|
-
? usageItems.map((i) => normalize(i, 'usage_item'))
|
|
4941
|
-
: []),
|
|
4942
|
-
...(Array.isArray(creditItems)
|
|
4943
|
-
? creditItems.map((i) => normalize(i, 'credit_item'))
|
|
4944
|
-
: []),
|
|
5090
|
+
...lineItems.map((i) => normalize(i, 'line_item')),
|
|
5091
|
+
...chargeItems.map((i) => normalize(i, 'charge_item')),
|
|
5092
|
+
...usageItems.map((i) => normalize(i, 'usage_item')),
|
|
5093
|
+
...creditItems.map((i) => normalize(i, 'credit_item'))
|
|
4945
5094
|
];
|
|
4946
5095
|
}
|
|
4947
5096
|
getInvoiceLineItemRangeLabel(raw) {
|
|
4948
|
-
const
|
|
4949
|
-
const
|
|
5097
|
+
const usageTiers = raw['usage_tiers'];
|
|
5098
|
+
const tiers = usageTiers?.['tiers'] ?? raw['tiers'] ?? [];
|
|
5099
|
+
const tier = (Array.isArray(tiers) && tiers.length > 0 ? tiers[0] : null);
|
|
4950
5100
|
if (!tier)
|
|
4951
5101
|
return '';
|
|
4952
|
-
const first = tier
|
|
4953
|
-
const last = tier
|
|
4954
|
-
if (last === -1 || last
|
|
5102
|
+
const first = tier['first_unit'] ?? tier['firstUnit'] ?? 0;
|
|
5103
|
+
const last = tier['last_unit'] ?? tier['lastUnit'] ?? -1;
|
|
5104
|
+
if (last === -1 || last === null || last === undefined)
|
|
4955
5105
|
return `${first} and above`;
|
|
4956
5106
|
return `${first} to ${last}`;
|
|
4957
5107
|
}
|
|
4958
5108
|
normalizeInvoiceLineItem(item, itemType) {
|
|
4959
5109
|
const raw = item || {};
|
|
4960
|
-
const id = raw
|
|
4961
|
-
const name = raw
|
|
4962
|
-
const description = (raw
|
|
4963
|
-
const quantity = Number(raw
|
|
4964
|
-
const totalAmountNum = this.toNumber(raw
|
|
4965
|
-
const amountStr = String(raw
|
|
4966
|
-
const totalAmountStr = String(raw
|
|
4967
|
-
const
|
|
4968
|
-
const
|
|
4969
|
-
const
|
|
5110
|
+
const id = raw['id'] ?? raw['Id'] ?? '';
|
|
5111
|
+
const name = raw['name'] ?? raw['Name'] ?? '';
|
|
5112
|
+
const description = (raw['description'] ?? raw['Description'] ?? '') || this.getInvoiceLineItemRangeLabel(raw);
|
|
5113
|
+
const quantity = Number(raw['quantity'] ?? raw['Quantity'] ?? 0);
|
|
5114
|
+
const totalAmountNum = this.toNumber((raw['total_amount'] ?? raw['totalAmount'] ?? raw['amount'] ?? raw['Amount'] ?? 0));
|
|
5115
|
+
const amountStr = String(raw['amount'] ?? raw['Amount'] ?? raw['total_amount'] ?? raw['totalAmount'] ?? '0');
|
|
5116
|
+
const totalAmountStr = String(raw['total_amount'] ?? raw['totalAmount'] ?? raw['amount'] ?? raw['Amount'] ?? '0');
|
|
5117
|
+
const usageTiers = raw['usage_tiers'];
|
|
5118
|
+
const tiers = usageTiers?.['tiers'] ?? raw['tiers'] ?? [];
|
|
5119
|
+
const firstTier = (Array.isArray(tiers) && tiers.length > 0 ? tiers[0] : null);
|
|
5120
|
+
const tierUnitPrice = firstTier !== null && firstTier !== undefined ? (firstTier['unit_price'] ?? firstTier['unitPrice']) : undefined;
|
|
4970
5121
|
const derivedUnitPrice = quantity > 0 && totalAmountNum > 0 ? totalAmountNum / quantity : undefined;
|
|
4971
|
-
const rawUnitPrice = raw
|
|
5122
|
+
const rawUnitPrice = raw['unit_price'] ?? raw['unitPrice'] ?? tierUnitPrice;
|
|
4972
5123
|
const rawUnitNum = rawUnitPrice !== undefined &&
|
|
4973
5124
|
rawUnitPrice !== null &&
|
|
4974
5125
|
String(rawUnitPrice).trim() !== ''
|
|
@@ -4983,7 +5134,7 @@ class InvoicePreviewComponent {
|
|
|
4983
5134
|
unit_price: String(unitPriceNum),
|
|
4984
5135
|
amount: amountStr,
|
|
4985
5136
|
total_amount: totalAmountStr,
|
|
4986
|
-
itemType
|
|
5137
|
+
itemType
|
|
4987
5138
|
};
|
|
4988
5139
|
}
|
|
4989
5140
|
buildTenantAddress(addr) {
|
|
@@ -4995,41 +5146,29 @@ class InvoicePreviewComponent {
|
|
|
4995
5146
|
addr.city,
|
|
4996
5147
|
addr.state,
|
|
4997
5148
|
addr.postal_code,
|
|
4998
|
-
addr.country
|
|
5149
|
+
addr.country
|
|
4999
5150
|
].filter(Boolean);
|
|
5000
5151
|
return parts.length ? parts.join(', ') : 'No Tenant address provided';
|
|
5001
5152
|
}
|
|
5002
5153
|
buildBilledToAddress(customer) {
|
|
5003
5154
|
if (!customer)
|
|
5004
5155
|
return '-';
|
|
5005
|
-
const billing = customer
|
|
5156
|
+
const billing = customer.billing_address;
|
|
5006
5157
|
if (billing) {
|
|
5007
5158
|
const parts = [
|
|
5008
|
-
billing.
|
|
5009
|
-
billing.
|
|
5159
|
+
billing.address_line_one,
|
|
5160
|
+
billing.address_line_two,
|
|
5010
5161
|
billing.city,
|
|
5011
5162
|
billing.state,
|
|
5012
|
-
billing.
|
|
5013
|
-
billing.country
|
|
5014
|
-
].filter(Boolean);
|
|
5015
|
-
return parts.length ? parts.join(', ') : '-';
|
|
5016
|
-
}
|
|
5017
|
-
const addr = customer?.address;
|
|
5018
|
-
if (addr) {
|
|
5019
|
-
const parts = [
|
|
5020
|
-
addr.line_1,
|
|
5021
|
-
addr.line_2,
|
|
5022
|
-
addr.city,
|
|
5023
|
-
addr.state,
|
|
5024
|
-
addr.postal_code,
|
|
5025
|
-
addr.country,
|
|
5163
|
+
billing.zip_code,
|
|
5164
|
+
billing.country
|
|
5026
5165
|
].filter(Boolean);
|
|
5027
5166
|
return parts.length ? parts.join(', ') : '-';
|
|
5028
5167
|
}
|
|
5029
5168
|
return '-';
|
|
5030
5169
|
}
|
|
5031
5170
|
escapeHtml(s) {
|
|
5032
|
-
if (s
|
|
5171
|
+
if (s === null || s === undefined)
|
|
5033
5172
|
return '';
|
|
5034
5173
|
return String(s)
|
|
5035
5174
|
.replace(/&/g, '&')
|
|
@@ -5072,9 +5211,9 @@ class InvoicePreviewComponent {
|
|
|
5072
5211
|
const paid = fmt(this.getInvoiceSummaryNumber(inv, 'total_amount_paid', 'totalAmountPaid'));
|
|
5073
5212
|
const due = fmt(this.getInvoiceSummaryNumber(inv, 'total_outstanding_amount', 'totalOutstandingAmount'));
|
|
5074
5213
|
const rows = items
|
|
5075
|
-
.map((item) => `<div style="border-top:1px solid #e5e7eb;display:grid;grid-template-columns:minmax(8rem,1fr) auto auto auto auto;gap:1rem;align-items:start;padding:1rem 0.75rem;font-size:13px;color:#374151;"><div><span style="font-weight:500;color:#2563eb;">${this.escapeHtml(item
|
|
5214
|
+
.map((item) => `<div style="border-top:1px solid #e5e7eb;display:grid;grid-template-columns:minmax(8rem,1fr) auto auto auto auto;gap:1rem;align-items:start;padding:1rem 0.75rem;font-size:13px;color:#374151;"><div><span style="font-weight:500;color:#2563eb;">${this.escapeHtml(String(item['name']))}</span>${item['description'] ? `<p style="font-size:12px;color:#6b7280;margin:2px 0 0 0;">${this.escapeHtml(String(item['description']))}</p>` : ''}</div><div>${sym}${fmt(this.toNumber(item['unit_price']))}</div><div>${item['quantity']}</div><div>${sym}${fmt(this.toNumber((item['total_amount'] || item['amount'])))}</div><div>${sym}${fmt(this.toNumber((item['total_amount'] || item['amount'])))}</div></div>`)
|
|
5076
5215
|
.join('');
|
|
5077
|
-
return `<!DOCTYPE html><html><head><meta charset="utf-8"><title>Invoice</title><style>*{box-sizing:border-box;}body{margin:0;padding:0;font-family:ui-sans-serif,system-ui,sans-serif;font-size:16px;color:#111827;line-height:1.5;background:#fff;}</style></head><body><div style="max-width:48rem;margin:0 auto;padding:2rem;"><div style="background:#fff;padding:2rem;border-radius:0.75rem;border-top:4px solid #111827;box-shadow:0 1px 3px 0 rgb(0 0 0/0.1);"><div style="display:flex;justify-content:space-between;align-items:flex-start;"><div style="display:flex;align-items:center;gap:0.75rem;"><strong style="font-size:1.25rem;font-weight:700;color:#111827;">${this.escapeHtml(inv.tenant?.business_name || 'Metrifox Sandbox')}</strong></div><div style="text-align:right;"><div style="font-size:1.25rem;font-weight:700;color:#111827;text-transform:uppercase;">INVOICE</div><div style="font-size:13px;color:#111827;margin-top:2px;">${this.escapeHtml(inv.invoice_number || '-')}</div></div></div><div style="display:grid;grid-template-columns:minmax(8rem,1fr) auto auto auto auto;gap:1rem;background:#e5e7eb;padding:0.5rem 0.75rem;border-radius:0.375rem;font-size:13px;font-weight:500;color:#374151;margin-top:2rem;"><span>Item name</span><span>Price</span><span>Qty</span><span>Subtotal</span><span>Amount</span></div>${rows}<div style="background:#f5f5f5;padding:0.75rem;width:50%;margin-left:auto;margin-top:1.25rem;border-radius:0.25rem;"><div style="display:flex;justify-content:space-between;border-bottom:1px solid #e5e7eb;padding-bottom:0.5rem;"><div><div style="font-size:13px;font-weight:500;color:#111827;">Subtotal</div><div style="font-size:10px;color:#737373;margin:0.5rem 0;">Discount</div><div style="font-size:10px;color:#737373;">Tax</div><div style="font-size:13px;font-weight:500;color:#111827;margin-top:8px;">Grand total</div></div><div style="text-align:right;"><div style="font-size:13px;font-weight:500;color:#1f2937;">${sym}${sub}</div><div style="font-size:10px;color:#737373;margin:0.5rem 0;">${sym}${disc}</div><div style="font-size:10px;color:#737373;">${sym}${tax}</div><div style="font-size:13px;font-weight:500;color:#1f2937;margin-top:8px;">${sym}${grand}</div></div></div><div style="display:flex;justify-content:space-between;padding-top:0.5rem;"><div><div style="font-size:13px;font-weight:500;color:#111827;">Amount paid</div><div style="font-size:13px;font-weight:500;color:#111827;">Amount due</div></div><div style="text-align:right;"><div style="font-size:13px;font-weight:500;color:#1f2937;">${sym}${paid}</div><div style="font-size:16px;font-weight:500;">${sym}${due}</div></div></div></div><div style="border-top:1px solid #d1d5db;padding-top:1rem;margin-top:3rem;text-align:center;font-size:10px;color:#111827;">Powered by MetriFox</div></div></div></body></html>`;
|
|
5216
|
+
return `<!DOCTYPE html><html><head><meta charset="utf-8"><title>Invoice</title><style>*{box-sizing:border-box;}body{margin:0;padding:0;font-family:ui-sans-serif,system-ui,sans-serif;font-size:16px;color:#111827;line-height:1.5;background:#fff;}</style></head><body><div style="max-width:48rem;margin:0 auto;padding:2rem;"><div style="background:#fff;padding:2rem;border-radius:0.75rem;border-top:4px solid #111827;box-shadow:0 1px 3px 0 rgb(0 0 0/0.1);"><div style="display:flex;justify-content:space-between;align-items:flex-start;"><div style="display:flex;align-items:center;gap:0.75rem;"><strong style="font-size:1.25rem;font-weight:700;color:#111827;">${this.escapeHtml(String(inv.tenant?.business_name || 'Metrifox Sandbox'))}</strong></div><div style="text-align:right;"><div style="font-size:1.25rem;font-weight:700;color:#111827;text-transform:uppercase;">INVOICE</div><div style="font-size:13px;color:#111827;margin-top:2px;">${this.escapeHtml(String(inv.invoice_number || '-'))}</div></div></div><div style="display:grid;grid-template-columns:minmax(8rem,1fr) auto auto auto auto;gap:1rem;background:#e5e7eb;padding:0.5rem 0.75rem;border-radius:0.375rem;font-size:13px;font-weight:500;color:#374151;margin-top:2rem;"><span>Item name</span><span>Price</span><span>Qty</span><span>Subtotal</span><span>Amount</span></div>${rows}<div style="background:#f5f5f5;padding:0.75rem;width:50%;margin-left:auto;margin-top:1.25rem;border-radius:0.25rem;"><div style="display:flex;justify-content:space-between;border-bottom:1px solid #e5e7eb;padding-bottom:0.5rem;"><div><div style="font-size:13px;font-weight:500;color:#111827;">Subtotal</div><div style="font-size:10px;color:#737373;margin:0.5rem 0;">Discount</div><div style="font-size:10px;color:#737373;">Tax</div><div style="font-size:13px;font-weight:500;color:#111827;margin-top:8px;">Grand total</div></div><div style="text-align:right;"><div style="font-size:13px;font-weight:500;color:#1f2937;">${sym}${sub}</div><div style="font-size:10px;color:#737373;margin:0.5rem 0;">${sym}${disc}</div><div style="font-size:10px;color:#737373;">${sym}${tax}</div><div style="font-size:13px;font-weight:500;color:#1f2937;margin-top:8px;">${sym}${grand}</div></div></div><div style="display:flex;justify-content:space-between;padding-top:0.5rem;"><div><div style="font-size:13px;font-weight:500;color:#111827;">Amount paid</div><div style="font-size:13px;font-weight:500;color:#111827;">Amount due</div></div><div style="text-align:right;"><div style="font-size:13px;font-weight:500;color:#1f2937;">${sym}${paid}</div><div style="font-size:16px;font-weight:500;">${sym}${due}</div></div></div></div><div style="border-top:1px solid #d1d5db;padding-top:1rem;margin-top:3rem;text-align:center;font-size:10px;color:#111827;">Powered by MetriFox</div></div></div></body></html>`;
|
|
5078
5217
|
}
|
|
5079
5218
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: InvoicePreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5080
5219
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: InvoicePreviewComponent, isStandalone: true, selector: "cp-invoice-preview", inputs: { show: "show", selectedInvoice: "selectedInvoice", invoiceDetails: "invoiceDetails", invoiceDetailsLoading: "invoiceDetailsLoading" }, outputs: { close: "close" }, ngImport: i0, template: `
|
|
@@ -5836,7 +5975,7 @@ class CustomerPortalComponent {
|
|
|
5836
5975
|
const allPriceOptions = [
|
|
5837
5976
|
...(plan.price_options || []),
|
|
5838
5977
|
...(plan.entitlement_price_options || []),
|
|
5839
|
-
...(plan.credit_attachment_price_options || [])
|
|
5978
|
+
...(plan.credit_attachment_price_options || [])
|
|
5840
5979
|
];
|
|
5841
5980
|
allPriceOptions.forEach((po) => {
|
|
5842
5981
|
if (po.price?.billing_interval) {
|
|
@@ -5851,11 +5990,13 @@ class CustomerPortalComponent {
|
|
|
5851
5990
|
const custom = this.themeSignal() ?? MetrifoxService.getTheme()?.customerPortal;
|
|
5852
5991
|
const theme = mergeCustomerPortalTheme(defaultCustomerPortalTheme, custom);
|
|
5853
5992
|
const vars = MetrifoxService.customerPortalThemeToCssVars(theme);
|
|
5993
|
+
const gradientVars = MetrifoxService.getBackgroundImage(theme);
|
|
5854
5994
|
return {
|
|
5855
5995
|
...vars,
|
|
5996
|
+
...gradientVars,
|
|
5856
5997
|
'font-family': 'var(--cp-font-family)',
|
|
5857
5998
|
'background-color': 'var(--cp-bg)',
|
|
5858
|
-
'border-radius': 'var(--cp-radius)'
|
|
5999
|
+
'border-radius': 'var(--cp-radius)'
|
|
5859
6000
|
};
|
|
5860
6001
|
});
|
|
5861
6002
|
ngOnInit() {
|
|
@@ -5898,9 +6039,9 @@ class CustomerPortalComponent {
|
|
|
5898
6039
|
this.error.set(err.message || 'Failed to load customer data');
|
|
5899
6040
|
this.errorOccurred.emit({
|
|
5900
6041
|
message: err.message || 'Failed to load customer data',
|
|
5901
|
-
code: err.status?.toString()
|
|
6042
|
+
code: err.status?.toString()
|
|
5902
6043
|
});
|
|
5903
|
-
}
|
|
6044
|
+
}
|
|
5904
6045
|
});
|
|
5905
6046
|
}
|
|
5906
6047
|
loadAdditionalData() {
|
|
@@ -5911,7 +6052,7 @@ class CustomerPortalComponent {
|
|
|
5911
6052
|
const subscriptionId = firstSubscription?.subscription?.id;
|
|
5912
6053
|
const productKey = firstSubscription?.product_key;
|
|
5913
6054
|
const requests = {
|
|
5914
|
-
wallets: this.metrifoxService.getCustomerWallets(this.customerKey)
|
|
6055
|
+
wallets: this.metrifoxService.getCustomerWallets(this.customerKey)
|
|
5915
6056
|
};
|
|
5916
6057
|
if (subscriptionId) {
|
|
5917
6058
|
requests.history = this.metrifoxService.getBillingHistory(subscriptionId);
|
|
@@ -5955,7 +6096,7 @@ class CustomerPortalComponent {
|
|
|
5955
6096
|
this.isLoadingData = false;
|
|
5956
6097
|
this.loading.set(false);
|
|
5957
6098
|
this.dataLoaded.emit({ customerDetails: details });
|
|
5958
|
-
}
|
|
6099
|
+
}
|
|
5959
6100
|
});
|
|
5960
6101
|
}
|
|
5961
6102
|
loadDataForSubscription(sub) {
|
|
@@ -6006,7 +6147,7 @@ class CustomerPortalComponent {
|
|
|
6006
6147
|
this.entitlementSummary.set([]);
|
|
6007
6148
|
this.entitlementUsage.set([]);
|
|
6008
6149
|
this.productPlans.set(null);
|
|
6009
|
-
}
|
|
6150
|
+
}
|
|
6010
6151
|
});
|
|
6011
6152
|
}
|
|
6012
6153
|
loadCreditAllocations(walletId, tab) {
|
|
@@ -6022,7 +6163,7 @@ class CustomerPortalComponent {
|
|
|
6022
6163
|
error: () => {
|
|
6023
6164
|
this.creditAllocations.set([]);
|
|
6024
6165
|
this.allocationsLoading.set(false);
|
|
6025
|
-
}
|
|
6166
|
+
}
|
|
6026
6167
|
});
|
|
6027
6168
|
}
|
|
6028
6169
|
selectTab(index) {
|
|
@@ -6057,11 +6198,11 @@ class CustomerPortalComponent {
|
|
|
6057
6198
|
if (invoiceId) {
|
|
6058
6199
|
this.metrifoxService.getInvoiceDetails(invoiceId).pipe(takeUntil(this.destroy$)).subscribe({
|
|
6059
6200
|
next: (data) => {
|
|
6060
|
-
const inv = data?.data ?? data;
|
|
6201
|
+
const inv = (data?.data ?? data);
|
|
6061
6202
|
this.invoiceDetails.set(inv);
|
|
6062
6203
|
this.invoiceDetailsLoading.set(false);
|
|
6063
6204
|
},
|
|
6064
|
-
error: () => this.invoiceDetailsLoading.set(false)
|
|
6205
|
+
error: () => this.invoiceDetailsLoading.set(false)
|
|
6065
6206
|
});
|
|
6066
6207
|
}
|
|
6067
6208
|
else {
|
|
@@ -6246,7 +6387,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
6246
6387
|
PaymentSectionComponent,
|
|
6247
6388
|
BillingHistorySectionComponent,
|
|
6248
6389
|
PlansSectionComponent,
|
|
6249
|
-
InvoicePreviewComponent
|
|
6390
|
+
InvoicePreviewComponent
|
|
6250
6391
|
], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
6251
6392
|
<div class="font-sans antialiased" [ngStyle]="cssVars()">
|
|
6252
6393
|
<!-- Error State -->
|
|
@@ -6509,6 +6650,7 @@ var ResetIntervals;
|
|
|
6509
6650
|
ResetIntervals["DAILY"] = "daily";
|
|
6510
6651
|
ResetIntervals["BILLING_PERIOD"] = "billing_period";
|
|
6511
6652
|
ResetIntervals["NEVER"] = "never";
|
|
6653
|
+
ResetIntervals["NONE"] = "none";
|
|
6512
6654
|
})(ResetIntervals || (ResetIntervals = {}));
|
|
6513
6655
|
/**
|
|
6514
6656
|
* Enforcement types
|
|
@@ -6536,6 +6678,7 @@ var BillingTimingTypes;
|
|
|
6536
6678
|
(function (BillingTimingTypes) {
|
|
6537
6679
|
BillingTimingTypes["IN_ADVANCE"] = "in_advance";
|
|
6538
6680
|
BillingTimingTypes["IN_ARREARS"] = "in_arrears";
|
|
6681
|
+
BillingTimingTypes["PAY_AS_YOU_GO"] = "pay_as_you_go";
|
|
6539
6682
|
})(BillingTimingTypes || (BillingTimingTypes = {}));
|
|
6540
6683
|
/**
|
|
6541
6684
|
* Aggregation methods
|
|
@@ -6586,56 +6729,75 @@ var LocalizationSelection;
|
|
|
6586
6729
|
LocalizationSelection["SMART_PRE_FILL"] = "smart_pre_fill";
|
|
6587
6730
|
})(LocalizationSelection || (LocalizationSelection = {}));
|
|
6588
6731
|
|
|
6589
|
-
// Default theme matching React SDK
|
|
6590
6732
|
const defaultPricingTableTheme = {
|
|
6591
6733
|
plans: {
|
|
6592
6734
|
currentPlanCard: {
|
|
6593
|
-
header: {
|
|
6594
|
-
|
|
6735
|
+
header: {
|
|
6736
|
+
background: '#e5e7eb',
|
|
6737
|
+
textColor: '#111827'
|
|
6738
|
+
},
|
|
6739
|
+
gradientColor: '#e5e7eb'
|
|
6595
6740
|
},
|
|
6596
6741
|
planCards: {
|
|
6597
6742
|
background: '#ffffff',
|
|
6598
|
-
border: {
|
|
6599
|
-
|
|
6600
|
-
|
|
6743
|
+
border: {
|
|
6744
|
+
color: '#e5e7eb',
|
|
6745
|
+
width: '1px',
|
|
6746
|
+
radius: '8px'
|
|
6747
|
+
},
|
|
6748
|
+
header: {
|
|
6749
|
+
background: '#e5e7eb',
|
|
6750
|
+
textColor: '#111827'
|
|
6751
|
+
},
|
|
6752
|
+
description: {
|
|
6753
|
+
textColor: '#6b7280',
|
|
6754
|
+
textButtonColor: '#2563eb'
|
|
6755
|
+
},
|
|
6601
6756
|
price: {
|
|
6602
6757
|
amountColor: '#111827',
|
|
6603
|
-
primaryTextColor: '#
|
|
6604
|
-
secondaryTextColor: '#
|
|
6758
|
+
primaryTextColor: '#6b7280',
|
|
6759
|
+
secondaryTextColor: '#9ca3af',
|
|
6605
6760
|
background: 'transparent',
|
|
6606
|
-
borderColor: 'transparent'
|
|
6607
|
-
}
|
|
6761
|
+
borderColor: 'transparent'
|
|
6762
|
+
}
|
|
6763
|
+
},
|
|
6764
|
+
planFeatures: {
|
|
6765
|
+
textColor: '#374151',
|
|
6766
|
+
iconColor: '#0BB02F'
|
|
6608
6767
|
},
|
|
6609
|
-
planFeatures: { textColor: '#3F3F46', iconColor: '#0BB02F' },
|
|
6610
6768
|
planButton: {
|
|
6611
6769
|
background: '#3D3D3D',
|
|
6612
6770
|
textColor: '#ffffff',
|
|
6613
6771
|
secondaryBackground: '#E4E4E7',
|
|
6614
6772
|
secondaryTextColor: '#3F3F46',
|
|
6615
|
-
textButtonColor: '#2563eb'
|
|
6773
|
+
textButtonColor: '#2563eb'
|
|
6616
6774
|
},
|
|
6617
6775
|
planToggle: {
|
|
6618
|
-
background: '#
|
|
6776
|
+
background: '#e5e7eb',
|
|
6619
6777
|
activeBackground: '#1f2937',
|
|
6620
6778
|
activeText: '#ffffff',
|
|
6621
|
-
inactiveText: '#
|
|
6779
|
+
inactiveText: '#6b7280'
|
|
6622
6780
|
},
|
|
6623
|
-
planTags: {
|
|
6781
|
+
planTags: {
|
|
6782
|
+
freeTrialBackground: '#dbeafe',
|
|
6783
|
+
freeTrialText: '#1e40af'
|
|
6784
|
+
}
|
|
6624
6785
|
},
|
|
6625
6786
|
tabs: {
|
|
6626
|
-
inactiveText: '#
|
|
6787
|
+
inactiveText: '#9ca3af',
|
|
6627
6788
|
activeText: '#2563eb',
|
|
6628
6789
|
indicator: '#2563eb',
|
|
6629
|
-
borderColor: '#
|
|
6790
|
+
borderColor: '#9ca3af'
|
|
6630
6791
|
},
|
|
6631
6792
|
checkoutBar: {
|
|
6632
|
-
background: '#
|
|
6633
|
-
borderColor: '#
|
|
6793
|
+
background: '#f9fafb',
|
|
6794
|
+
borderColor: '#e5e7eb',
|
|
6634
6795
|
textColor: '#3F3F46',
|
|
6635
6796
|
buttonBackground: '#2563eb',
|
|
6636
|
-
buttonTextColor: '#ffffff'
|
|
6637
|
-
}
|
|
6797
|
+
buttonTextColor: '#ffffff'
|
|
6798
|
+
}
|
|
6638
6799
|
};
|
|
6800
|
+
|
|
6639
6801
|
function mergePricingTableTheme(defaultTheme, custom) {
|
|
6640
6802
|
if (!custom || typeof custom !== 'object')
|
|
6641
6803
|
return defaultTheme;
|
|
@@ -6659,12 +6821,12 @@ function mergePricingTableTheme(defaultTheme, custom) {
|
|
|
6659
6821
|
}
|
|
6660
6822
|
// SVG Icons
|
|
6661
6823
|
const ICONS = {
|
|
6662
|
-
check:
|
|
6663
|
-
search:
|
|
6664
|
-
close:
|
|
6665
|
-
trash:
|
|
6666
|
-
minus:
|
|
6667
|
-
plus:
|
|
6824
|
+
check: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>',
|
|
6825
|
+
search: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><path d="m21 21-4.3-4.3"></path></svg>',
|
|
6826
|
+
close: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="m15 9-6 6"></path><path d="m9 9 6 6"></path></svg>',
|
|
6827
|
+
trash: '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"></path><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path></svg>',
|
|
6828
|
+
minus: '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path></svg>',
|
|
6829
|
+
plus: '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="M12 5v14"></path></svg>'
|
|
6668
6830
|
};
|
|
6669
6831
|
/**
|
|
6670
6832
|
* Pricing Table Component
|
|
@@ -6689,15 +6851,24 @@ class PricingTableComponent {
|
|
|
6689
6851
|
checkoutUsername;
|
|
6690
6852
|
metrifoxService = inject(MetrifoxService);
|
|
6691
6853
|
sanitizer = inject(DomSanitizer);
|
|
6854
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
6692
6855
|
constructor() { }
|
|
6693
6856
|
/** Product key to load pricing for */
|
|
6694
6857
|
productKey;
|
|
6695
6858
|
/** Show only plans (hide single purchases) */
|
|
6696
|
-
|
|
6859
|
+
plansOnlySignal = signal(false);
|
|
6860
|
+
set plansOnly(value) { this.plansOnlySignal.set(value); }
|
|
6697
6861
|
/** Show only single purchases (hide plans) */
|
|
6698
|
-
|
|
6862
|
+
singlePurchasesOnlySignal = signal(false);
|
|
6863
|
+
set singlePurchasesOnly(value) { this.singlePurchasesOnlySignal.set(value); }
|
|
6699
6864
|
/** Show tab header when both plans and purchases exist */
|
|
6700
|
-
|
|
6865
|
+
showTabHeaderSignal = signal(true);
|
|
6866
|
+
set showTabHeader(value) { this.showTabHeaderSignal.set(value); }
|
|
6867
|
+
/** Optional theme override for this instance */
|
|
6868
|
+
themeSignal = signal(undefined);
|
|
6869
|
+
set theme(value) {
|
|
6870
|
+
this.themeSignal.set(value);
|
|
6871
|
+
}
|
|
6701
6872
|
/** Emitted when a plan is selected */
|
|
6702
6873
|
planSelected = new EventEmitter();
|
|
6703
6874
|
/** Emitted when a single purchase is selected */
|
|
@@ -6715,8 +6886,8 @@ class PricingTableComponent {
|
|
|
6715
6886
|
// Computed
|
|
6716
6887
|
plans = computed(() => this.product()?.plans || []);
|
|
6717
6888
|
singlePurchases = computed(() => this.product()?.single_purchases || []);
|
|
6718
|
-
showPlans = computed(() => this.
|
|
6719
|
-
showSinglePurchases = computed(() => this.
|
|
6889
|
+
showPlans = computed(() => this.plansOnlySignal() || (!this.plansOnlySignal() && !this.singlePurchasesOnlySignal()));
|
|
6890
|
+
showSinglePurchases = computed(() => this.singlePurchasesOnlySignal() || (!this.plansOnlySignal() && !this.singlePurchasesOnlySignal()));
|
|
6720
6891
|
hasBothTypes = computed(() => this.plans().length > 0 && this.singlePurchases().length > 0);
|
|
6721
6892
|
tabOptions = computed(() => {
|
|
6722
6893
|
const options = [];
|
|
@@ -6750,12 +6921,12 @@ class PricingTableComponent {
|
|
|
6750
6921
|
return purchases.filter((p) => p.published_version?.name?.toLowerCase().includes(term));
|
|
6751
6922
|
});
|
|
6752
6923
|
cssVars = computed(() => {
|
|
6753
|
-
const
|
|
6754
|
-
const theme = mergePricingTableTheme(defaultPricingTableTheme,
|
|
6924
|
+
const custom = this.themeSignal() ?? MetrifoxService.getTheme()?.pricingTable;
|
|
6925
|
+
const theme = mergePricingTableTheme(defaultPricingTableTheme, custom);
|
|
6755
6926
|
return {
|
|
6756
6927
|
...MetrifoxService.pricingTableThemeToCssVars(theme),
|
|
6757
6928
|
...MetrifoxService.getBackgroundImage(theme),
|
|
6758
|
-
'font-family': 'var(--pt-font-family, var(--cp-font-family, inherit))'
|
|
6929
|
+
'font-family': 'var(--pt-font-family, var(--cp-font-family, inherit))'
|
|
6759
6930
|
};
|
|
6760
6931
|
});
|
|
6761
6932
|
ngOnInit() {
|
|
@@ -6793,9 +6964,9 @@ class PricingTableComponent {
|
|
|
6793
6964
|
this.error.set(err.message || 'Failed to load pricing');
|
|
6794
6965
|
this.errorOccurred.emit({
|
|
6795
6966
|
message: err.message || 'Failed to load pricing',
|
|
6796
|
-
code: err.status?.toString()
|
|
6967
|
+
code: err.status?.toString()
|
|
6797
6968
|
});
|
|
6798
|
-
}
|
|
6969
|
+
}
|
|
6799
6970
|
});
|
|
6800
6971
|
}
|
|
6801
6972
|
/**
|
|
@@ -6818,7 +6989,7 @@ class PricingTableComponent {
|
|
|
6818
6989
|
this.planSelected.emit({
|
|
6819
6990
|
plan: plan.published_version,
|
|
6820
6991
|
interval: this.selectedInterval(),
|
|
6821
|
-
checkoutUrl
|
|
6992
|
+
checkoutUrl
|
|
6822
6993
|
});
|
|
6823
6994
|
// Open checkout in new tab
|
|
6824
6995
|
window.open(checkoutUrl, '_blank');
|
|
@@ -6830,7 +7001,7 @@ class PricingTableComponent {
|
|
|
6830
7001
|
const checkoutUrl = this.metrifoxService.buildCheckoutUrl(this.checkoutUsername, purchase.offering_key);
|
|
6831
7002
|
this.purchaseSelected.emit({
|
|
6832
7003
|
purchase: purchase.published_version,
|
|
6833
|
-
checkoutUrl
|
|
7004
|
+
checkoutUrl
|
|
6834
7005
|
});
|
|
6835
7006
|
// Open checkout in new tab
|
|
6836
7007
|
window.open(checkoutUrl, '_blank');
|
|
@@ -6891,7 +7062,7 @@ class PricingTableComponent {
|
|
|
6891
7062
|
EUR: '€',
|
|
6892
7063
|
GBP: '£',
|
|
6893
7064
|
JPY: '¥',
|
|
6894
|
-
NGN: '₦'
|
|
7065
|
+
NGN: '₦'
|
|
6895
7066
|
};
|
|
6896
7067
|
return symbols[currency] || currency;
|
|
6897
7068
|
}
|
|
@@ -6934,7 +7105,7 @@ class PricingTableComponent {
|
|
|
6934
7105
|
monthly: 'Monthly',
|
|
6935
7106
|
yearly: 'Yearly',
|
|
6936
7107
|
weekly: 'Weekly',
|
|
6937
|
-
daily: 'Daily'
|
|
7108
|
+
daily: 'Daily'
|
|
6938
7109
|
};
|
|
6939
7110
|
return labels[interval] || interval;
|
|
6940
7111
|
}
|
|
@@ -7015,7 +7186,7 @@ class PricingTableComponent {
|
|
|
7015
7186
|
price: priceOption.price.price,
|
|
7016
7187
|
currency: priceOption.price.currency,
|
|
7017
7188
|
quantity,
|
|
7018
|
-
offering_key: purchase.offering_key
|
|
7189
|
+
offering_key: purchase.offering_key
|
|
7019
7190
|
};
|
|
7020
7191
|
this.cartItems.update((items) => [...items, item]);
|
|
7021
7192
|
}
|
|
@@ -7040,7 +7211,7 @@ class PricingTableComponent {
|
|
|
7040
7211
|
checkoutWindow?.postMessage({
|
|
7041
7212
|
v: 1,
|
|
7042
7213
|
type: 'INIT_CART',
|
|
7043
|
-
payload: dataToSend
|
|
7214
|
+
payload: dataToSend
|
|
7044
7215
|
}, '*');
|
|
7045
7216
|
break;
|
|
7046
7217
|
case 'ACK':
|
|
@@ -7055,7 +7226,7 @@ class PricingTableComponent {
|
|
|
7055
7226
|
}, 5000);
|
|
7056
7227
|
}
|
|
7057
7228
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: PricingTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7058
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: PricingTableComponent, isStandalone: true, selector: "metrifox-pricing-table", inputs: { checkoutUsername: "checkoutUsername", productKey: "productKey", plansOnly: "plansOnly", singlePurchasesOnly: "singlePurchasesOnly", showTabHeader: "showTabHeader" }, outputs: { planSelected: "planSelected", purchaseSelected: "purchaseSelected", errorOccurred: "errorOccurred" }, ngImport: i0, template: `
|
|
7229
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: PricingTableComponent, isStandalone: true, selector: "metrifox-pricing-table", inputs: { checkoutUsername: "checkoutUsername", productKey: "productKey", plansOnly: "plansOnly", singlePurchasesOnly: "singlePurchasesOnly", showTabHeader: "showTabHeader", theme: "theme" }, outputs: { planSelected: "planSelected", purchaseSelected: "purchaseSelected", errorOccurred: "errorOccurred" }, ngImport: i0, template: `
|
|
7059
7230
|
<div class="font-sans antialiased" [ngStyle]="cssVars()">
|
|
7060
7231
|
<!-- Loading State -->
|
|
7061
7232
|
@if (loading()) {
|
|
@@ -7087,7 +7258,7 @@ class PricingTableComponent {
|
|
|
7087
7258
|
<div class="flex justify-center">
|
|
7088
7259
|
<div class="w-full max-w-[1089px] bg-transparent h-full rounded-2xl md:px-6 py-5">
|
|
7089
7260
|
<!-- Tab Header (Listing Tabs) -->
|
|
7090
|
-
@if (
|
|
7261
|
+
@if (showTabHeaderSignal()) {
|
|
7091
7262
|
<div class="w-full flex justify-center border-b border-[var(--pt-tabs-border)] mb-6">
|
|
7092
7263
|
@for (tab of tabOptions(); track tab.value) {
|
|
7093
7264
|
<div
|
|
@@ -7109,31 +7280,36 @@ class PricingTableComponent {
|
|
|
7109
7280
|
<!-- Plans View -->
|
|
7110
7281
|
@if (showPlans() && selectedTab() === 'plan') {
|
|
7111
7282
|
<!-- Interval Toggle (Plan Tabs) -->
|
|
7112
|
-
|
|
7113
|
-
<div class="flex items-center
|
|
7114
|
-
|
|
7115
|
-
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
|
|
7119
|
-
|
|
7120
|
-
|
|
7121
|
-
|
|
7122
|
-
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7283
|
+
<div class="flex items-center mb-4 justify-center">
|
|
7284
|
+
<div class="inline-flex items-center gap-1 bg-[var(--pt-interval-bg)] border border-[var(--pt-interval-border,var(--cp-tabs-border,var(--cp-section-content-border)))] p-1 rounded-lg shadow-sm">
|
|
7285
|
+
@for (interval of intervals(); track interval) {
|
|
7286
|
+
<div
|
|
7287
|
+
class="py-1.5 px-6 rounded-md cursor-pointer transition-all flex items-center justify-center"
|
|
7288
|
+
[class.bg-[var(--pt-interval-active-bg)]]="selectedInterval() === interval"
|
|
7289
|
+
[class.shadow-sm]="selectedInterval() === interval"
|
|
7290
|
+
[class.bg-transparent]="selectedInterval() !== interval"
|
|
7291
|
+
[class.hover:opacity-80]="selectedInterval() !== interval"
|
|
7292
|
+
(click)="selectInterval(interval)">
|
|
7293
|
+
<span
|
|
7294
|
+
class="text-sm font-medium whitespace-nowrap"
|
|
7295
|
+
[class.text-[var(--pt-interval-active-text)]]="selectedInterval() === interval"
|
|
7296
|
+
[class.text-[var(--pt-interval-inactive-text)]]="selectedInterval() !== interval">
|
|
7297
|
+
{{ formatInterval(interval) }}
|
|
7298
|
+
</span>
|
|
7299
|
+
</div>
|
|
7300
|
+
}
|
|
7129
7301
|
</div>
|
|
7130
|
-
|
|
7302
|
+
</div>
|
|
7131
7303
|
|
|
7132
7304
|
<!-- Plan Cards -->
|
|
7133
7305
|
<div class="w-full flex gap-x-4 px-4 justify-start overflow-x-auto flex-nowrap">
|
|
7134
7306
|
@for (plan of plans(); track plan.id) {
|
|
7135
7307
|
<div
|
|
7136
|
-
class="flex flex-col
|
|
7308
|
+
class="flex flex-col shrink-0 w-[330px]"
|
|
7309
|
+
[style.borderWidth]="'var(--pt-card-border-width, 1px)'"
|
|
7310
|
+
[style.borderStyle]="'solid'"
|
|
7311
|
+
[style.borderColor]="'var(--pt-card-border, #e5e7eb)'"
|
|
7312
|
+
[style.borderRadius]="'var(--pt-card-radius, 1rem)'"
|
|
7137
7313
|
[class.bg-[var(--pt-current-sub-card-header-bg)]]="plan.published_version.is_current_plan"
|
|
7138
7314
|
[class.bg-[var(--pt-card-header-bg)]]="!plan.published_version.is_current_plan">
|
|
7139
7315
|
<!-- Card Header -->
|
|
@@ -7157,7 +7333,7 @@ class PricingTableComponent {
|
|
|
7157
7333
|
[class.bg-gradient-to-b]="plan.published_version.is_current_plan"
|
|
7158
7334
|
[class.from-[var(--pt-card-gradient)]]="plan.published_version.is_current_plan"
|
|
7159
7335
|
[class.to-[var(--pt-card-bg)]]="plan.published_version.is_current_plan">
|
|
7160
|
-
|
|
7336
|
+
|
|
7161
7337
|
<!-- Description -->
|
|
7162
7338
|
@if (plan.published_version.description) {
|
|
7163
7339
|
<div class="h-[51px] mt-1 px-2">
|
|
@@ -7200,7 +7376,7 @@ class PricingTableComponent {
|
|
|
7200
7376
|
{{ getButtonText(plan.published_version) }}
|
|
7201
7377
|
</button>
|
|
7202
7378
|
|
|
7203
|
-
<!--
|
|
7379
|
+
<!-- Entitlements -->
|
|
7204
7380
|
@if (plan.published_version.entitlements?.length || plan.published_version.credit_attachments?.length) {
|
|
7205
7381
|
<div class="px-2 mt-4">
|
|
7206
7382
|
<p class="text-sm font-medium text-[var(--pt-feature-text)] mb-3">
|
|
@@ -7263,7 +7439,12 @@ class PricingTableComponent {
|
|
|
7263
7439
|
class="grid gap-4 px-4 lg:grid-cols-3 md:grid-cols-2 grid-cols-1"
|
|
7264
7440
|
[class.pb-[72px]]="cartItems().length > 0">
|
|
7265
7441
|
@for (purchase of filteredSinglePurchases(); track purchase.id) {
|
|
7266
|
-
<div class="flex flex-col bg-[var(--pt-card-header-bg)]
|
|
7442
|
+
<div class="flex flex-col bg-[var(--pt-card-header-bg)] w-full min-h-[187px]"
|
|
7443
|
+
[style.borderWidth]="'var(--pt-card-border-width, 1px)'"
|
|
7444
|
+
[style.borderStyle]="'solid'"
|
|
7445
|
+
[style.borderColor]="'var(--pt-card-border, #e5e7eb)'"
|
|
7446
|
+
[style.borderRadius]="'var(--pt-card-radius, 1rem)'"
|
|
7447
|
+
>
|
|
7267
7448
|
<!-- Card Header -->
|
|
7268
7449
|
<div class="px-4 pt-2 pb-[2px]">
|
|
7269
7450
|
<span class="text-sm font-medium text-[var(--pt-card-header-text)]">
|
|
@@ -7397,7 +7578,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
7397
7578
|
<div class="flex justify-center">
|
|
7398
7579
|
<div class="w-full max-w-[1089px] bg-transparent h-full rounded-2xl md:px-6 py-5">
|
|
7399
7580
|
<!-- Tab Header (Listing Tabs) -->
|
|
7400
|
-
@if (
|
|
7581
|
+
@if (showTabHeaderSignal()) {
|
|
7401
7582
|
<div class="w-full flex justify-center border-b border-[var(--pt-tabs-border)] mb-6">
|
|
7402
7583
|
@for (tab of tabOptions(); track tab.value) {
|
|
7403
7584
|
<div
|
|
@@ -7419,31 +7600,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
7419
7600
|
<!-- Plans View -->
|
|
7420
7601
|
@if (showPlans() && selectedTab() === 'plan') {
|
|
7421
7602
|
<!-- Interval Toggle (Plan Tabs) -->
|
|
7422
|
-
|
|
7423
|
-
<div class="flex items-center
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7603
|
+
<div class="flex items-center mb-4 justify-center">
|
|
7604
|
+
<div class="inline-flex items-center gap-1 bg-[var(--pt-interval-bg)] border border-[var(--pt-interval-border,var(--cp-tabs-border,var(--cp-section-content-border)))] p-1 rounded-lg shadow-sm">
|
|
7605
|
+
@for (interval of intervals(); track interval) {
|
|
7606
|
+
<div
|
|
7607
|
+
class="py-1.5 px-6 rounded-md cursor-pointer transition-all flex items-center justify-center"
|
|
7608
|
+
[class.bg-[var(--pt-interval-active-bg)]]="selectedInterval() === interval"
|
|
7609
|
+
[class.shadow-sm]="selectedInterval() === interval"
|
|
7610
|
+
[class.bg-transparent]="selectedInterval() !== interval"
|
|
7611
|
+
[class.hover:opacity-80]="selectedInterval() !== interval"
|
|
7612
|
+
(click)="selectInterval(interval)">
|
|
7613
|
+
<span
|
|
7614
|
+
class="text-sm font-medium whitespace-nowrap"
|
|
7615
|
+
[class.text-[var(--pt-interval-active-text)]]="selectedInterval() === interval"
|
|
7616
|
+
[class.text-[var(--pt-interval-inactive-text)]]="selectedInterval() !== interval">
|
|
7617
|
+
{{ formatInterval(interval) }}
|
|
7618
|
+
</span>
|
|
7619
|
+
</div>
|
|
7620
|
+
}
|
|
7439
7621
|
</div>
|
|
7440
|
-
|
|
7622
|
+
</div>
|
|
7441
7623
|
|
|
7442
7624
|
<!-- Plan Cards -->
|
|
7443
7625
|
<div class="w-full flex gap-x-4 px-4 justify-start overflow-x-auto flex-nowrap">
|
|
7444
7626
|
@for (plan of plans(); track plan.id) {
|
|
7445
7627
|
<div
|
|
7446
|
-
class="flex flex-col
|
|
7628
|
+
class="flex flex-col shrink-0 w-[330px]"
|
|
7629
|
+
[style.borderWidth]="'var(--pt-card-border-width, 1px)'"
|
|
7630
|
+
[style.borderStyle]="'solid'"
|
|
7631
|
+
[style.borderColor]="'var(--pt-card-border, #e5e7eb)'"
|
|
7632
|
+
[style.borderRadius]="'var(--pt-card-radius, 1rem)'"
|
|
7447
7633
|
[class.bg-[var(--pt-current-sub-card-header-bg)]]="plan.published_version.is_current_plan"
|
|
7448
7634
|
[class.bg-[var(--pt-card-header-bg)]]="!plan.published_version.is_current_plan">
|
|
7449
7635
|
<!-- Card Header -->
|
|
@@ -7467,7 +7653,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
7467
7653
|
[class.bg-gradient-to-b]="plan.published_version.is_current_plan"
|
|
7468
7654
|
[class.from-[var(--pt-card-gradient)]]="plan.published_version.is_current_plan"
|
|
7469
7655
|
[class.to-[var(--pt-card-bg)]]="plan.published_version.is_current_plan">
|
|
7470
|
-
|
|
7656
|
+
|
|
7471
7657
|
<!-- Description -->
|
|
7472
7658
|
@if (plan.published_version.description) {
|
|
7473
7659
|
<div class="h-[51px] mt-1 px-2">
|
|
@@ -7510,7 +7696,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
7510
7696
|
{{ getButtonText(plan.published_version) }}
|
|
7511
7697
|
</button>
|
|
7512
7698
|
|
|
7513
|
-
<!--
|
|
7699
|
+
<!-- Entitlements -->
|
|
7514
7700
|
@if (plan.published_version.entitlements?.length || plan.published_version.credit_attachments?.length) {
|
|
7515
7701
|
<div class="px-2 mt-4">
|
|
7516
7702
|
<p class="text-sm font-medium text-[var(--pt-feature-text)] mb-3">
|
|
@@ -7573,7 +7759,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
7573
7759
|
class="grid gap-4 px-4 lg:grid-cols-3 md:grid-cols-2 grid-cols-1"
|
|
7574
7760
|
[class.pb-[72px]]="cartItems().length > 0">
|
|
7575
7761
|
@for (purchase of filteredSinglePurchases(); track purchase.id) {
|
|
7576
|
-
<div class="flex flex-col bg-[var(--pt-card-header-bg)]
|
|
7762
|
+
<div class="flex flex-col bg-[var(--pt-card-header-bg)] w-full min-h-[187px]"
|
|
7763
|
+
[style.borderWidth]="'var(--pt-card-border-width, 1px)'"
|
|
7764
|
+
[style.borderStyle]="'solid'"
|
|
7765
|
+
[style.borderColor]="'var(--pt-card-border, #e5e7eb)'"
|
|
7766
|
+
[style.borderRadius]="'var(--pt-card-radius, 1rem)'"
|
|
7767
|
+
>
|
|
7577
7768
|
<!-- Card Header -->
|
|
7578
7769
|
<div class="px-4 pt-2 pb-[2px]">
|
|
7579
7770
|
<span class="text-sm font-medium text-[var(--pt-card-header-text)]">
|
|
@@ -7684,6 +7875,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
7684
7875
|
type: Input
|
|
7685
7876
|
}], showTabHeader: [{
|
|
7686
7877
|
type: Input
|
|
7878
|
+
}], theme: [{
|
|
7879
|
+
type: Input
|
|
7687
7880
|
}], planSelected: [{
|
|
7688
7881
|
type: Output
|
|
7689
7882
|
}], purchaseSelected: [{
|
|
@@ -7721,8 +7914,8 @@ class MetrifoxModule {
|
|
|
7721
7914
|
ngModule: MetrifoxModule,
|
|
7722
7915
|
providers: [
|
|
7723
7916
|
provideHttpClient(withInterceptorsFromDi()),
|
|
7724
|
-
MetrifoxService
|
|
7725
|
-
]
|
|
7917
|
+
MetrifoxService
|
|
7918
|
+
]
|
|
7726
7919
|
};
|
|
7727
7920
|
}
|
|
7728
7921
|
/**
|
|
@@ -7731,7 +7924,7 @@ class MetrifoxModule {
|
|
|
7731
7924
|
static forChild() {
|
|
7732
7925
|
return {
|
|
7733
7926
|
ngModule: MetrifoxModule,
|
|
7734
|
-
providers: []
|
|
7927
|
+
providers: []
|
|
7735
7928
|
};
|
|
7736
7929
|
}
|
|
7737
7930
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: MetrifoxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
@@ -7749,12 +7942,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
7749
7942
|
imports: [
|
|
7750
7943
|
CommonModule,
|
|
7751
7944
|
CustomerPortalComponent,
|
|
7752
|
-
PricingTableComponent
|
|
7945
|
+
PricingTableComponent
|
|
7753
7946
|
],
|
|
7754
7947
|
exports: [
|
|
7755
7948
|
CustomerPortalComponent,
|
|
7756
|
-
PricingTableComponent
|
|
7757
|
-
]
|
|
7949
|
+
PricingTableComponent
|
|
7950
|
+
]
|
|
7758
7951
|
}]
|
|
7759
7952
|
}] });
|
|
7760
7953
|
/**
|
|
@@ -7777,7 +7970,7 @@ function provideMetrifox(config) {
|
|
|
7777
7970
|
}
|
|
7778
7971
|
return [
|
|
7779
7972
|
provideHttpClient(),
|
|
7780
|
-
MetrifoxService
|
|
7973
|
+
MetrifoxService
|
|
7781
7974
|
];
|
|
7782
7975
|
}
|
|
7783
7976
|
|