@saasicat/ui-vue 1.0.0-rc.13 → 1.0.0-rc.14
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/.build-stamp +1 -1
- package/dist/{chunk-HYFHYL73.js → chunk-ADKRZZDZ.js} +24 -32
- package/dist/index.cjs +24 -33
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -3
- package/dist/vue/index.cjs +24 -33
- package/dist/vue/index.d.cts +11 -5
- package/dist/vue/index.d.ts +11 -5
- package/dist/vue/index.js +1 -3
- package/package.json +3 -3
- package/src/vue/use-subscription-draft.ts +63 -60
package/dist/.build-stamp
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
92a69f127a3ffaf9c29fb0fbe90a6580bf95af61b32757843279254ffc81c7e7
|
|
@@ -878,21 +878,16 @@ import { computed as computed4, ref as ref13 } from "vue";
|
|
|
878
878
|
import {
|
|
879
879
|
selectChargeableBundles
|
|
880
880
|
} from "@saasicat/core";
|
|
881
|
-
var DEFAULT_YEARLY_FACTOR = 10;
|
|
882
881
|
function unwrap(source) {
|
|
883
882
|
if (source && typeof source === "object" && "value" in source) {
|
|
884
883
|
return source.value;
|
|
885
884
|
}
|
|
886
885
|
return source;
|
|
887
886
|
}
|
|
888
|
-
function priceForCycle(
|
|
889
|
-
|
|
890
|
-
return yearlyNet != null ? yearlyNet : monthlyNet * yearlyFactor;
|
|
891
|
-
}
|
|
892
|
-
return monthlyNet;
|
|
887
|
+
function priceForCycle(item, cycle) {
|
|
888
|
+
return cycle === "YEARLY" ? item.yearlyNet : item.monthlyNet;
|
|
893
889
|
}
|
|
894
890
|
function useSubscriptionDraft(options) {
|
|
895
|
-
const yearlyFactor = options.yearlyFactor ?? DEFAULT_YEARLY_FACTOR;
|
|
896
891
|
const plansRef = computed4(() => unwrap(options.plans) ?? []);
|
|
897
892
|
const subscriptionBundlesRef = computed4(
|
|
898
893
|
() => unwrap(options.subscriptionBundles ?? null) ?? []
|
|
@@ -910,7 +905,7 @@ function useSubscriptionDraft(options) {
|
|
|
910
905
|
});
|
|
911
906
|
const selectedBundles = computed4(
|
|
912
907
|
() => subscriptionBundlesRef.value.filter(
|
|
913
|
-
(b) => selectedBundleVersionIds.value.has(b.bundleVersionId)
|
|
908
|
+
(b) => selectedBundleVersionIds.value.has(b.bundleVersionId) && priceForCycle(b, cycle.value) !== null
|
|
914
909
|
)
|
|
915
910
|
);
|
|
916
911
|
const chargeableBundles = computed4(() => {
|
|
@@ -935,11 +930,12 @@ function useSubscriptionDraft(options) {
|
|
|
935
930
|
const pricing = computed4(() => {
|
|
936
931
|
const cyc = cycle.value;
|
|
937
932
|
const planObj = selectedPlan.value;
|
|
938
|
-
const
|
|
933
|
+
const planPrice = planObj ? priceForCycle(planObj, cyc) : null;
|
|
934
|
+
const planNet = planPrice ?? 0;
|
|
939
935
|
const bundleItems = [];
|
|
940
936
|
let bundlesNet = 0;
|
|
941
937
|
for (const b of chargeableBundles.value) {
|
|
942
|
-
const net = priceForCycle(b
|
|
938
|
+
const net = priceForCycle(b, cyc) ?? 0;
|
|
943
939
|
bundlesNet += net;
|
|
944
940
|
bundleItems.push({
|
|
945
941
|
key: `subscription-bundle:${b.bundleVersionId}`,
|
|
@@ -951,30 +947,19 @@ function useSubscriptionDraft(options) {
|
|
|
951
947
|
let discountNet = 0;
|
|
952
948
|
const preview = promoState.value.preview;
|
|
953
949
|
if (preview && preview.valid && promoState.value.status === "valid") {
|
|
954
|
-
const
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
if (valid.discount.valueType === "PERCENT") {
|
|
958
|
-
discountNet = subtotalNet * value / 100;
|
|
959
|
-
} else {
|
|
960
|
-
discountNet = Math.min(value, subtotalNet);
|
|
961
|
-
}
|
|
950
|
+
const amount = Number(preview.price.discountNet);
|
|
951
|
+
if (Number.isFinite(amount) && amount > 0) {
|
|
952
|
+
discountNet = Math.min(amount, planNet);
|
|
962
953
|
}
|
|
963
954
|
}
|
|
964
955
|
const totalNet = Math.max(0, subtotalNet - discountNet);
|
|
965
956
|
let yearSavings = 0;
|
|
966
|
-
if (planObj) {
|
|
967
|
-
|
|
968
|
-
const yearlyTotal = priceForCycle(
|
|
969
|
-
planObj.monthlyNet ?? 0,
|
|
970
|
-
planObj.yearlyNet,
|
|
971
|
-
"YEARLY",
|
|
972
|
-
yearlyFactor
|
|
973
|
-
);
|
|
974
|
-
yearSavings = Math.max(0, monthlyTotal - yearlyTotal);
|
|
957
|
+
if (planObj && planObj.monthlyNet !== null && planObj.yearlyNet !== null) {
|
|
958
|
+
yearSavings = Math.max(0, planObj.monthlyNet * 12 - planObj.yearlyNet);
|
|
975
959
|
}
|
|
976
960
|
return {
|
|
977
961
|
cycle: cyc,
|
|
962
|
+
planPriced: planPrice !== null,
|
|
978
963
|
planNet,
|
|
979
964
|
bundlesNet,
|
|
980
965
|
subtotalNet,
|
|
@@ -982,7 +967,9 @@ function useSubscriptionDraft(options) {
|
|
|
982
967
|
totalNet,
|
|
983
968
|
yearSavings,
|
|
984
969
|
breakdown: {
|
|
985
|
-
plan:
|
|
970
|
+
// A plan not sold in the cycle has no line: 0.00 beside its name
|
|
971
|
+
// would read as a price.
|
|
972
|
+
plan: planObj && planPrice !== null ? {
|
|
986
973
|
key: `plan:${planObj.id}`,
|
|
987
974
|
label: planObj.name,
|
|
988
975
|
net: planNet,
|
|
@@ -995,9 +982,15 @@ function useSubscriptionDraft(options) {
|
|
|
995
982
|
const isDirty = computed4(() => {
|
|
996
983
|
return selectedBundleVersionIds.value.size > 0 || promoState.value.status === "valid";
|
|
997
984
|
});
|
|
985
|
+
function forgetPromoPreview() {
|
|
986
|
+
if (promoState.value.status !== "idle") {
|
|
987
|
+
promoState.value = { status: "idle", preview: null, message: "" };
|
|
988
|
+
}
|
|
989
|
+
}
|
|
998
990
|
function setPlan(planId) {
|
|
999
991
|
if (plan.value === planId) return;
|
|
1000
992
|
plan.value = planId;
|
|
993
|
+
forgetPromoPreview();
|
|
1001
994
|
const compatibleBundleVersions = /* @__PURE__ */ new Set();
|
|
1002
995
|
for (const bundle of subscriptionBundlesRef.value) {
|
|
1003
996
|
if (bundle.compatiblePlanKeys.length === 0 || bundle.compatiblePlanKeys.includes(planId)) {
|
|
@@ -1009,7 +1002,9 @@ function useSubscriptionDraft(options) {
|
|
|
1009
1002
|
);
|
|
1010
1003
|
}
|
|
1011
1004
|
function setCycle(c) {
|
|
1005
|
+
if (cycle.value === c) return;
|
|
1012
1006
|
cycle.value = c;
|
|
1007
|
+
forgetPromoPreview();
|
|
1013
1008
|
}
|
|
1014
1009
|
function toggleSubscriptionBundle(bundleVersionId) {
|
|
1015
1010
|
const next = new Set(selectedBundleVersionIds.value);
|
|
@@ -1019,9 +1014,7 @@ function useSubscriptionDraft(options) {
|
|
|
1019
1014
|
}
|
|
1020
1015
|
function setPromoCode(code) {
|
|
1021
1016
|
promoCode.value = code.toUpperCase();
|
|
1022
|
-
|
|
1023
|
-
promoState.value = { status: "idle", preview: null, message: "" };
|
|
1024
|
-
}
|
|
1017
|
+
forgetPromoPreview();
|
|
1025
1018
|
}
|
|
1026
1019
|
function setPromoState(state) {
|
|
1027
1020
|
promoState.value = state;
|
|
@@ -3102,7 +3095,6 @@ export {
|
|
|
3102
3095
|
buildFeatureRouterGuard,
|
|
3103
3096
|
useTenantBillingCatalog,
|
|
3104
3097
|
useTenantBilling,
|
|
3105
|
-
DEFAULT_YEARLY_FACTOR,
|
|
3106
3098
|
useSubscriptionDraft,
|
|
3107
3099
|
useBulkPublish,
|
|
3108
3100
|
PlannedOnlyFeatureError,
|
package/dist/index.cjs
CHANGED
|
@@ -36,7 +36,6 @@ __export(src_exports, {
|
|
|
36
36
|
DEFAULT_ROWS_PER_PAGE: () => DEFAULT_ROWS_PER_PAGE,
|
|
37
37
|
DEFAULT_SA_LOCALE: () => DEFAULT_SA_LOCALE,
|
|
38
38
|
DEFAULT_STANDARD_PAGE_ROUTES: () => DEFAULT_STANDARD_PAGE_ROUTES,
|
|
39
|
-
DEFAULT_YEARLY_FACTOR: () => DEFAULT_YEARLY_FACTOR,
|
|
40
39
|
DiscoveryLoadError: () => DiscoveryLoadError,
|
|
41
40
|
ENTITLEMENT_INJECTION_KEY: () => ENTITLEMENT_INJECTION_KEY,
|
|
42
41
|
HttpJsonError: () => HttpJsonError,
|
|
@@ -6581,21 +6580,16 @@ function useTenantBilling(options = {}) {
|
|
|
6581
6580
|
// src/vue/use-subscription-draft.ts
|
|
6582
6581
|
var import_vue19 = require("vue");
|
|
6583
6582
|
var import_core4 = require("@saasicat/core");
|
|
6584
|
-
var DEFAULT_YEARLY_FACTOR = 10;
|
|
6585
6583
|
function unwrap(source) {
|
|
6586
6584
|
if (source && typeof source === "object" && "value" in source) {
|
|
6587
6585
|
return source.value;
|
|
6588
6586
|
}
|
|
6589
6587
|
return source;
|
|
6590
6588
|
}
|
|
6591
|
-
function priceForCycle(
|
|
6592
|
-
|
|
6593
|
-
return yearlyNet != null ? yearlyNet : monthlyNet * yearlyFactor;
|
|
6594
|
-
}
|
|
6595
|
-
return monthlyNet;
|
|
6589
|
+
function priceForCycle(item, cycle) {
|
|
6590
|
+
return cycle === "YEARLY" ? item.yearlyNet : item.monthlyNet;
|
|
6596
6591
|
}
|
|
6597
6592
|
function useSubscriptionDraft(options) {
|
|
6598
|
-
const yearlyFactor = options.yearlyFactor ?? DEFAULT_YEARLY_FACTOR;
|
|
6599
6593
|
const plansRef = (0, import_vue19.computed)(() => unwrap(options.plans) ?? []);
|
|
6600
6594
|
const subscriptionBundlesRef = (0, import_vue19.computed)(
|
|
6601
6595
|
() => unwrap(options.subscriptionBundles ?? null) ?? []
|
|
@@ -6613,7 +6607,7 @@ function useSubscriptionDraft(options) {
|
|
|
6613
6607
|
});
|
|
6614
6608
|
const selectedBundles = (0, import_vue19.computed)(
|
|
6615
6609
|
() => subscriptionBundlesRef.value.filter(
|
|
6616
|
-
(b) => selectedBundleVersionIds.value.has(b.bundleVersionId)
|
|
6610
|
+
(b) => selectedBundleVersionIds.value.has(b.bundleVersionId) && priceForCycle(b, cycle.value) !== null
|
|
6617
6611
|
)
|
|
6618
6612
|
);
|
|
6619
6613
|
const chargeableBundles = (0, import_vue19.computed)(() => {
|
|
@@ -6638,11 +6632,12 @@ function useSubscriptionDraft(options) {
|
|
|
6638
6632
|
const pricing = (0, import_vue19.computed)(() => {
|
|
6639
6633
|
const cyc = cycle.value;
|
|
6640
6634
|
const planObj = selectedPlan.value;
|
|
6641
|
-
const
|
|
6635
|
+
const planPrice = planObj ? priceForCycle(planObj, cyc) : null;
|
|
6636
|
+
const planNet = planPrice ?? 0;
|
|
6642
6637
|
const bundleItems = [];
|
|
6643
6638
|
let bundlesNet = 0;
|
|
6644
6639
|
for (const b of chargeableBundles.value) {
|
|
6645
|
-
const net = priceForCycle(b
|
|
6640
|
+
const net = priceForCycle(b, cyc) ?? 0;
|
|
6646
6641
|
bundlesNet += net;
|
|
6647
6642
|
bundleItems.push({
|
|
6648
6643
|
key: `subscription-bundle:${b.bundleVersionId}`,
|
|
@@ -6654,30 +6649,19 @@ function useSubscriptionDraft(options) {
|
|
|
6654
6649
|
let discountNet = 0;
|
|
6655
6650
|
const preview = promoState.value.preview;
|
|
6656
6651
|
if (preview && preview.valid && promoState.value.status === "valid") {
|
|
6657
|
-
const
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
if (valid.discount.valueType === "PERCENT") {
|
|
6661
|
-
discountNet = subtotalNet * value / 100;
|
|
6662
|
-
} else {
|
|
6663
|
-
discountNet = Math.min(value, subtotalNet);
|
|
6664
|
-
}
|
|
6652
|
+
const amount = Number(preview.price.discountNet);
|
|
6653
|
+
if (Number.isFinite(amount) && amount > 0) {
|
|
6654
|
+
discountNet = Math.min(amount, planNet);
|
|
6665
6655
|
}
|
|
6666
6656
|
}
|
|
6667
6657
|
const totalNet = Math.max(0, subtotalNet - discountNet);
|
|
6668
6658
|
let yearSavings = 0;
|
|
6669
|
-
if (planObj) {
|
|
6670
|
-
|
|
6671
|
-
const yearlyTotal = priceForCycle(
|
|
6672
|
-
planObj.monthlyNet ?? 0,
|
|
6673
|
-
planObj.yearlyNet,
|
|
6674
|
-
"YEARLY",
|
|
6675
|
-
yearlyFactor
|
|
6676
|
-
);
|
|
6677
|
-
yearSavings = Math.max(0, monthlyTotal - yearlyTotal);
|
|
6659
|
+
if (planObj && planObj.monthlyNet !== null && planObj.yearlyNet !== null) {
|
|
6660
|
+
yearSavings = Math.max(0, planObj.monthlyNet * 12 - planObj.yearlyNet);
|
|
6678
6661
|
}
|
|
6679
6662
|
return {
|
|
6680
6663
|
cycle: cyc,
|
|
6664
|
+
planPriced: planPrice !== null,
|
|
6681
6665
|
planNet,
|
|
6682
6666
|
bundlesNet,
|
|
6683
6667
|
subtotalNet,
|
|
@@ -6685,7 +6669,9 @@ function useSubscriptionDraft(options) {
|
|
|
6685
6669
|
totalNet,
|
|
6686
6670
|
yearSavings,
|
|
6687
6671
|
breakdown: {
|
|
6688
|
-
plan:
|
|
6672
|
+
// A plan not sold in the cycle has no line: 0.00 beside its name
|
|
6673
|
+
// would read as a price.
|
|
6674
|
+
plan: planObj && planPrice !== null ? {
|
|
6689
6675
|
key: `plan:${planObj.id}`,
|
|
6690
6676
|
label: planObj.name,
|
|
6691
6677
|
net: planNet,
|
|
@@ -6698,9 +6684,15 @@ function useSubscriptionDraft(options) {
|
|
|
6698
6684
|
const isDirty = (0, import_vue19.computed)(() => {
|
|
6699
6685
|
return selectedBundleVersionIds.value.size > 0 || promoState.value.status === "valid";
|
|
6700
6686
|
});
|
|
6687
|
+
function forgetPromoPreview() {
|
|
6688
|
+
if (promoState.value.status !== "idle") {
|
|
6689
|
+
promoState.value = { status: "idle", preview: null, message: "" };
|
|
6690
|
+
}
|
|
6691
|
+
}
|
|
6701
6692
|
function setPlan(planId) {
|
|
6702
6693
|
if (plan.value === planId) return;
|
|
6703
6694
|
plan.value = planId;
|
|
6695
|
+
forgetPromoPreview();
|
|
6704
6696
|
const compatibleBundleVersions = /* @__PURE__ */ new Set();
|
|
6705
6697
|
for (const bundle of subscriptionBundlesRef.value) {
|
|
6706
6698
|
if (bundle.compatiblePlanKeys.length === 0 || bundle.compatiblePlanKeys.includes(planId)) {
|
|
@@ -6712,7 +6704,9 @@ function useSubscriptionDraft(options) {
|
|
|
6712
6704
|
);
|
|
6713
6705
|
}
|
|
6714
6706
|
function setCycle(c) {
|
|
6707
|
+
if (cycle.value === c) return;
|
|
6715
6708
|
cycle.value = c;
|
|
6709
|
+
forgetPromoPreview();
|
|
6716
6710
|
}
|
|
6717
6711
|
function toggleSubscriptionBundle(bundleVersionId) {
|
|
6718
6712
|
const next = new Set(selectedBundleVersionIds.value);
|
|
@@ -6722,9 +6716,7 @@ function useSubscriptionDraft(options) {
|
|
|
6722
6716
|
}
|
|
6723
6717
|
function setPromoCode(code) {
|
|
6724
6718
|
promoCode.value = code.toUpperCase();
|
|
6725
|
-
|
|
6726
|
-
promoState.value = { status: "idle", preview: null, message: "" };
|
|
6727
|
-
}
|
|
6719
|
+
forgetPromoPreview();
|
|
6728
6720
|
}
|
|
6729
6721
|
function setPromoState(state) {
|
|
6730
6722
|
promoState.value = state;
|
|
@@ -8841,7 +8833,6 @@ function buildQuotaRegistry(quotaCatalog, locale) {
|
|
|
8841
8833
|
DEFAULT_ROWS_PER_PAGE,
|
|
8842
8834
|
DEFAULT_SA_LOCALE,
|
|
8843
8835
|
DEFAULT_STANDARD_PAGE_ROUTES,
|
|
8844
|
-
DEFAULT_YEARLY_FACTOR,
|
|
8845
8836
|
DiscoveryLoadError,
|
|
8846
8837
|
ENTITLEMENT_INJECTION_KEY,
|
|
8847
8838
|
HttpJsonError,
|
package/dist/index.d.cts
CHANGED
|
@@ -2,7 +2,7 @@ export { ADMIN_UI_VERSION, AdminPromoListFilter, AdminPromoListRow, AdminResourc
|
|
|
2
2
|
export { A as ActionDefNotInManifestError, a as ActionHandler, b as ActionRegistry, c as AppliedSettingsView, d as AuditListFilter, B as Bound, D as DEFAULT_SA_LOCALE, e as DiscoveryRead, E as EmailHistoryDetail, f as EmailHistoryFilter, g as EmailHistoryListResult, h as EmailHistoryResendResult, i as EmailHistoryRow, j as EmailHistoryStatus, H as HttpClient, k as HttpResponse, K as KpiReading, l as KvStore, L as LIST_FIRST_PAGE, m as LIST_PAGE_SIZE_DEFAULT, n as LIST_PAGE_SIZE_MAX, o as LIST_PAGINATION_PARAMS, p as ListFilterOf, q as ListOp, r as ListQuery, M as MarketingProjectionsFilter, s as MessageTree, t as MissingHandlerError, P as PartialMessages, u as PilotCreatePayload, v as PilotCreateResult, w as PilotEditPayload, x as PilotEditResult, y as PilotRow, z as PlatformEmailProvider, C as PlatformEmailTestInput, F as PlatformEmailTestResult, G as PlatformEmailWriteInput, I as PlatformResources, J as PromoCodesFilter, N as PromoDetail, O as PublishBundleVersionOptions, Q as PublishPlanVersionOptions, R as ResolvedAction, S as ResourceContext, T as ResourceDef, U as ResourceListPage, V as ResourceOp, W as ResourceOps, X as SA_INTL_LOCALES, Y as SA_LOCALES, Z as SA_LOCALE_LABELS, _ as SA_MESSAGES, $ as SaBuiltinLocale, a0 as SaCatalog, a1 as SaCatalogOptions, a2 as SaLocale, a3 as SaLocaleDefinition, a4 as SaLocaleOption, a5 as SaMessages, a6 as SaMessagesOverrides, a7 as SettingsChangeView, a8 as SettingsDifferenceView, a9 as TenantsListFilter, aa as TranslationOf, ab as auditResource, ac as bindResource, ad as bundleVersionsResource, ae as bundlesResource, af as clampListPage, ag as clampListPageSize, ah as createSaCatalog, ai as dashboardResource, aj as defaultHttpClient, ak as defaultKvStore, al as defineListOp, am as defineMessages, an as defineResource, ao as discoveryResource, ap as filterQueryString, aq as isSaBuiltinLocale, ar as isSentInQuery, as as listUrl, at as marketingResource, au as mergeMessages, av as planVersionsResource, aw as plansResource, ax as platformResources, ay as promoCodesResource, az as readListPage, aA as resolveMessages, aB as settingsResource, aC as tenantsResource } from './catalog-DUdy_YZB.cjs';
|
|
3
3
|
export { A as AdminError, a as AdminErrorInit, B as BatchColumnData, b as BatchColumnDriftError, c as BatchColumnFetcher, d as BatchColumnFetcherOptions, e as BatchColumnRow, f as BatchColumnValue, g as BootLoadError, h as BootLoader, i as BootLoaderOptions, j as BuildRouteEntry, C as CachedManifestEntry, D as DEFAULT_STANDARD_PAGE_ROUTES, M as ManifestLoadError, k as ManifestLoader, l as ManifestLoaderOptions, N as NavBuilderOptions, P as ParamStyle, S as SidebarItem, m as SidebarSection, n as adminErrorMessage, o as buildRoutes, p as buildSidebar, q as defaultSectionOrder, r as httpStatusOf, s as isAdminError, t as isAxiosNoResponseError, u as isEmptyResponse, v as isPlatformError, w as isTransportFailure, x as markEmptyResponse, y as markPlatformError, z as markTransportFailure, E as readErrorCode, F as readErrorDetail, G as resolveExtension, H as toAdminError } from './batch-column-fetcher-DmoujOET.cjs';
|
|
4
4
|
export { A as ActionsMap, C as CreateResourceRegistryOptions, E as ExtensionLoader, a as ExtensionsMap, I as InstallPlugin, O as OpOverride, R as ResourceMap, b as ResourceOverride, c as ResourceOverrides, d as ResourceRegistry, S as SA_COLOR_SCHEMES, e as SA_LOCALE_STORAGE_KEY, f as SA_THEME_KEY, g as SA_THEME_STORAGE_KEY, h as SUPER_ADMIN_ACTIONS_KEY, i as SUPER_ADMIN_BRAND_KEY, j as SUPER_ADMIN_CONFIRM_KEY, k as SUPER_ADMIN_ENDPOINTS_KEY, l as SUPER_ADMIN_EXTENSIONS_KEY, m as SUPER_ADMIN_HTTP_KEY, n as SUPER_ADMIN_I18N_KEY, o as SUPER_ADMIN_LOGIN_ADAPTER_KEY, p as SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY, q as SUPER_ADMIN_MANIFEST_KEY, r as SUPER_ADMIN_NOTIFY_KEY, s as SUPER_ADMIN_RESOURCES_KEY, t as SaColorScheme, u as SaResolvedScheme, v as SaTheme, w as SaThemeOptions, x as SuperAdminAuthGuardOptions, y as SuperAdminBrand, z as SuperAdminEndpoints, B as SuperAdminGuardOptions, D as SuperAdminI18n, F as SuperAdminI18nOptions, G as SuperAdminLoginAdapter, H as SuperAdminLoginResult, J as SuperAdminManifestGuardOptions, U as UiConfirm, K as UiConfirmPrompt, L as UiConfirmRequest, M as UiConfirmResult, N as UiConfirmTone, P as UiNotify, Q as UiNotifyKind, T as UiNotifyOptions, V as bindSaThemeAttribute, W as buildNavigationGuard, X as createResourceRegistry, Y as createSaTheme, Z as createSuperAdminI18n, _ as useResource, $ as useSaMessages, a0 as useSaTheme, a1 as useSuperAdminI18n } from './resource-registry-CYmBGVPK.cjs';
|
|
5
|
-
export { ALL_ROWS, ApiListResponse, AppliedSettingsResource, AppliedSettingsState, AsyncAction, AsyncActionResult, AsyncData, AsyncList, BillingCycleStr, BulkItemKind, BulkItemStatus, BulkPublishItem, BundleAddPreviewShape, BundleBookingOptions, BundleCancelPreviewShape, BundlePreviewIssueShape, BundlePreviewShape, BundlePreviewSnapshotShape, BundlesApiError, CancellationResultShape, CatalogBundle, CatalogEntriesApiError, CatalogPlan, ConfirmDialogState, CreateAdminRoutesOptions, CreateManifestStoreOptions, CreatePlatformLoadersOptions, DEFAULT_LOGIN_PATH, DEFAULT_ROWS_PER_PAGE,
|
|
5
|
+
export { ALL_ROWS, ApiListResponse, AppliedSettingsResource, AppliedSettingsState, AsyncAction, AsyncActionResult, AsyncData, AsyncList, BillingCycleStr, BulkItemKind, BulkItemStatus, BulkPublishItem, BundleAddPreviewShape, BundleBookingOptions, BundleCancelPreviewShape, BundlePreviewIssueShape, BundlePreviewShape, BundlePreviewSnapshotShape, BundlesApiError, CancellationResultShape, CatalogBundle, CatalogEntriesApiError, CatalogPlan, ConfirmDialogState, CreateAdminRoutesOptions, CreateManifestStoreOptions, CreatePlatformLoadersOptions, DEFAULT_LOGIN_PATH, DEFAULT_ROWS_PER_PAGE, Dialog, DiscoveryLoadError, DraftPricing, ENTITLEMENT_INJECTION_KEY, EntitlementSnapshotShape, FeatureRouterGuardOptions, FeatureRowMarkers, ListOpNames, ListResourceKey, ManifestStoreActions, ManifestStoreDefinition, ManifestStoreState, MarketingProjectionsApiError, MfaDialogState, MfaOutcome, MfaPrompt, PAGE_SIZE_OPTIONS, PLAN_WIZARD_KEY, PROMO_STATUS_TONE, PackageSnapshotShape, PillTone, PlanChangePreviewIssueShape, PlanChangePreviewShape, PlanDraftEditing, PlanDraftForm, PlanSnapshotShape, PlanWizardState, PlannedOnlyFeatureError, PlansApiError, PlatformLoaders, PlatformTenantActionRow, PlatformTenantActionTone, PlatformTenantActionsOptions, PlatformTenantActionsResult, PriceLineItem, ProjectPageHost, PromoState, PromoStatus, PromotionsApiError, RedundantFeatureHintShape, ResolvedBundlePrice, ResolvedTenantAction, RowOf, RowReorder, SERVER_PAGE_SIZE_OPTIONS, StepStatus, Steps, SubscriptionBundleShape, SubscriptionDraft, TenantActionFlowProviders, TenantActionInput, TenantManifestNavItem, TenantManifestShape, TenantRowLike, TenantSubscriptionBundlesApiError, UsageSnapshotShape, UseActionsResult, UseApiListOptions, UseApiListResult, UseAsyncActionOptions, UseAsyncDataOptions, UseAuditEntriesOptions, UseAuditEntriesResult, UseBatchColumnsResult, UseBulkPublishOptions, UseBulkPublishResult, UseBundleVersionsMapOptions, UseBundleVersionsMapResult, UseBundleVersionsOptions, UseBundleVersionsResult, UseBundlesOptions, UseBundlesResult, UseCatalogEntriesOptions, UseCatalogEntriesResult, UseDialogOptions, UseDiscoveryOptions, UseDiscoveryResult, UseEntitlementOptions, UseEntitlementResult, UseLivePlanVersionsOptions, UseLivePlanVersionsResult, UseManifestResult, UseMarketingProjectionsOptions, UseMarketingProjectionsResult, UseNavResult, UsePaginationResult, UsePlanEditorOptions, UsePlanEditorResult, UsePlanVersionsOptions, UsePlanVersionsResult, UsePlansOptions, UsePlansResult, UsePromotionsOptions, UsePromotionsResult, UsePublicBootResult, UseResourceListOptions, UseSignOutOptions, UseStepsOptions, UseSubscriptionDraftOptions, UseTenantActionFlowResult, UseTenantBillingCatalogOptions, UseTenantBillingCatalogResult, UseTenantBillingOptions, UseTenantBillingResult, UseTenantManifestOptions, UseTenantManifestResult, UseTenantSubscriptionBundlesOptions, UseTenantSubscriptionBundlesResult, UseTenantsOptions, UseTenantsResult, buildFeatureRouterGuard, createAdminRoutes, createManifestStore, createPlatformLoaders, createProjectPageHostRoute, defaultIconForActionKey, defaultToneForActionKey, findLatestLive, promoStatusTone, provideEntitlement, providePlanWizard, resolveSuperAdminEndpoints, useActions, useApiList, useAppliedSettings, useAsyncAction, useAsyncData, useAuditEntries, useBatchColumns, useBulkPublish, useBundleVersions, useBundleVersionsMap, useBundles, useCatalogEntries, useDialog, useDiscovery, useEntitlement, useInjectedEntitlement, useLivePlanVersions, useManifest, useMarketingProjections, useMfaPrompt, useNav, usePagination, usePlanEditor, usePlanVersions, usePlanWizard, usePlans, usePlatformTenantActions, usePromotions, usePublicBoot, useResourceList, useRowReorder, useSignOut, useSteps, useSubscriptionDraft, useSuperAdminActions, useSuperAdminBrand, useSuperAdminEndpoints, useSuperAdminExtensions, useSuperAdminHttp, useSuperAdminLoginAdapter, useSuperAdminManifest, useTenantActionFlow, useTenantBilling, useTenantBillingCatalog, useTenantManifest, useTenantSubscriptionBundles, useTenants } from './vue/index.cjs';
|
|
6
6
|
import { FeatureCatalogEntryRow, QuotaCatalogEntryRow } from '@saasicat/core';
|
|
7
7
|
import 'vue';
|
|
8
8
|
import 'vue-router';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { ADMIN_UI_VERSION, AdminPromoListFilter, AdminPromoListRow, AdminResourc
|
|
|
2
2
|
export { A as ActionDefNotInManifestError, a as ActionHandler, b as ActionRegistry, c as AppliedSettingsView, d as AuditListFilter, B as Bound, D as DEFAULT_SA_LOCALE, e as DiscoveryRead, E as EmailHistoryDetail, f as EmailHistoryFilter, g as EmailHistoryListResult, h as EmailHistoryResendResult, i as EmailHistoryRow, j as EmailHistoryStatus, H as HttpClient, k as HttpResponse, K as KpiReading, l as KvStore, L as LIST_FIRST_PAGE, m as LIST_PAGE_SIZE_DEFAULT, n as LIST_PAGE_SIZE_MAX, o as LIST_PAGINATION_PARAMS, p as ListFilterOf, q as ListOp, r as ListQuery, M as MarketingProjectionsFilter, s as MessageTree, t as MissingHandlerError, P as PartialMessages, u as PilotCreatePayload, v as PilotCreateResult, w as PilotEditPayload, x as PilotEditResult, y as PilotRow, z as PlatformEmailProvider, C as PlatformEmailTestInput, F as PlatformEmailTestResult, G as PlatformEmailWriteInput, I as PlatformResources, J as PromoCodesFilter, N as PromoDetail, O as PublishBundleVersionOptions, Q as PublishPlanVersionOptions, R as ResolvedAction, S as ResourceContext, T as ResourceDef, U as ResourceListPage, V as ResourceOp, W as ResourceOps, X as SA_INTL_LOCALES, Y as SA_LOCALES, Z as SA_LOCALE_LABELS, _ as SA_MESSAGES, $ as SaBuiltinLocale, a0 as SaCatalog, a1 as SaCatalogOptions, a2 as SaLocale, a3 as SaLocaleDefinition, a4 as SaLocaleOption, a5 as SaMessages, a6 as SaMessagesOverrides, a7 as SettingsChangeView, a8 as SettingsDifferenceView, a9 as TenantsListFilter, aa as TranslationOf, ab as auditResource, ac as bindResource, ad as bundleVersionsResource, ae as bundlesResource, af as clampListPage, ag as clampListPageSize, ah as createSaCatalog, ai as dashboardResource, aj as defaultHttpClient, ak as defaultKvStore, al as defineListOp, am as defineMessages, an as defineResource, ao as discoveryResource, ap as filterQueryString, aq as isSaBuiltinLocale, ar as isSentInQuery, as as listUrl, at as marketingResource, au as mergeMessages, av as planVersionsResource, aw as plansResource, ax as platformResources, ay as promoCodesResource, az as readListPage, aA as resolveMessages, aB as settingsResource, aC as tenantsResource } from './catalog-DUdy_YZB.js';
|
|
3
3
|
export { A as AdminError, a as AdminErrorInit, B as BatchColumnData, b as BatchColumnDriftError, c as BatchColumnFetcher, d as BatchColumnFetcherOptions, e as BatchColumnRow, f as BatchColumnValue, g as BootLoadError, h as BootLoader, i as BootLoaderOptions, j as BuildRouteEntry, C as CachedManifestEntry, D as DEFAULT_STANDARD_PAGE_ROUTES, M as ManifestLoadError, k as ManifestLoader, l as ManifestLoaderOptions, N as NavBuilderOptions, P as ParamStyle, S as SidebarItem, m as SidebarSection, n as adminErrorMessage, o as buildRoutes, p as buildSidebar, q as defaultSectionOrder, r as httpStatusOf, s as isAdminError, t as isAxiosNoResponseError, u as isEmptyResponse, v as isPlatformError, w as isTransportFailure, x as markEmptyResponse, y as markPlatformError, z as markTransportFailure, E as readErrorCode, F as readErrorDetail, G as resolveExtension, H as toAdminError } from './batch-column-fetcher-CFnqFxQU.js';
|
|
4
4
|
export { A as ActionsMap, C as CreateResourceRegistryOptions, E as ExtensionLoader, a as ExtensionsMap, I as InstallPlugin, O as OpOverride, R as ResourceMap, b as ResourceOverride, c as ResourceOverrides, d as ResourceRegistry, S as SA_COLOR_SCHEMES, e as SA_LOCALE_STORAGE_KEY, f as SA_THEME_KEY, g as SA_THEME_STORAGE_KEY, h as SUPER_ADMIN_ACTIONS_KEY, i as SUPER_ADMIN_BRAND_KEY, j as SUPER_ADMIN_CONFIRM_KEY, k as SUPER_ADMIN_ENDPOINTS_KEY, l as SUPER_ADMIN_EXTENSIONS_KEY, m as SUPER_ADMIN_HTTP_KEY, n as SUPER_ADMIN_I18N_KEY, o as SUPER_ADMIN_LOGIN_ADAPTER_KEY, p as SUPER_ADMIN_MANIFEST_CLEAR_CACHE_KEY, q as SUPER_ADMIN_MANIFEST_KEY, r as SUPER_ADMIN_NOTIFY_KEY, s as SUPER_ADMIN_RESOURCES_KEY, t as SaColorScheme, u as SaResolvedScheme, v as SaTheme, w as SaThemeOptions, x as SuperAdminAuthGuardOptions, y as SuperAdminBrand, z as SuperAdminEndpoints, B as SuperAdminGuardOptions, D as SuperAdminI18n, F as SuperAdminI18nOptions, G as SuperAdminLoginAdapter, H as SuperAdminLoginResult, J as SuperAdminManifestGuardOptions, U as UiConfirm, K as UiConfirmPrompt, L as UiConfirmRequest, M as UiConfirmResult, N as UiConfirmTone, P as UiNotify, Q as UiNotifyKind, T as UiNotifyOptions, V as bindSaThemeAttribute, W as buildNavigationGuard, X as createResourceRegistry, Y as createSaTheme, Z as createSuperAdminI18n, _ as useResource, $ as useSaMessages, a0 as useSaTheme, a1 as useSuperAdminI18n } from './resource-registry-bG2PxbM0.js';
|
|
5
|
-
export { ALL_ROWS, ApiListResponse, AppliedSettingsResource, AppliedSettingsState, AsyncAction, AsyncActionResult, AsyncData, AsyncList, BillingCycleStr, BulkItemKind, BulkItemStatus, BulkPublishItem, BundleAddPreviewShape, BundleBookingOptions, BundleCancelPreviewShape, BundlePreviewIssueShape, BundlePreviewShape, BundlePreviewSnapshotShape, BundlesApiError, CancellationResultShape, CatalogBundle, CatalogEntriesApiError, CatalogPlan, ConfirmDialogState, CreateAdminRoutesOptions, CreateManifestStoreOptions, CreatePlatformLoadersOptions, DEFAULT_LOGIN_PATH, DEFAULT_ROWS_PER_PAGE,
|
|
5
|
+
export { ALL_ROWS, ApiListResponse, AppliedSettingsResource, AppliedSettingsState, AsyncAction, AsyncActionResult, AsyncData, AsyncList, BillingCycleStr, BulkItemKind, BulkItemStatus, BulkPublishItem, BundleAddPreviewShape, BundleBookingOptions, BundleCancelPreviewShape, BundlePreviewIssueShape, BundlePreviewShape, BundlePreviewSnapshotShape, BundlesApiError, CancellationResultShape, CatalogBundle, CatalogEntriesApiError, CatalogPlan, ConfirmDialogState, CreateAdminRoutesOptions, CreateManifestStoreOptions, CreatePlatformLoadersOptions, DEFAULT_LOGIN_PATH, DEFAULT_ROWS_PER_PAGE, Dialog, DiscoveryLoadError, DraftPricing, ENTITLEMENT_INJECTION_KEY, EntitlementSnapshotShape, FeatureRouterGuardOptions, FeatureRowMarkers, ListOpNames, ListResourceKey, ManifestStoreActions, ManifestStoreDefinition, ManifestStoreState, MarketingProjectionsApiError, MfaDialogState, MfaOutcome, MfaPrompt, PAGE_SIZE_OPTIONS, PLAN_WIZARD_KEY, PROMO_STATUS_TONE, PackageSnapshotShape, PillTone, PlanChangePreviewIssueShape, PlanChangePreviewShape, PlanDraftEditing, PlanDraftForm, PlanSnapshotShape, PlanWizardState, PlannedOnlyFeatureError, PlansApiError, PlatformLoaders, PlatformTenantActionRow, PlatformTenantActionTone, PlatformTenantActionsOptions, PlatformTenantActionsResult, PriceLineItem, ProjectPageHost, PromoState, PromoStatus, PromotionsApiError, RedundantFeatureHintShape, ResolvedBundlePrice, ResolvedTenantAction, RowOf, RowReorder, SERVER_PAGE_SIZE_OPTIONS, StepStatus, Steps, SubscriptionBundleShape, SubscriptionDraft, TenantActionFlowProviders, TenantActionInput, TenantManifestNavItem, TenantManifestShape, TenantRowLike, TenantSubscriptionBundlesApiError, UsageSnapshotShape, UseActionsResult, UseApiListOptions, UseApiListResult, UseAsyncActionOptions, UseAsyncDataOptions, UseAuditEntriesOptions, UseAuditEntriesResult, UseBatchColumnsResult, UseBulkPublishOptions, UseBulkPublishResult, UseBundleVersionsMapOptions, UseBundleVersionsMapResult, UseBundleVersionsOptions, UseBundleVersionsResult, UseBundlesOptions, UseBundlesResult, UseCatalogEntriesOptions, UseCatalogEntriesResult, UseDialogOptions, UseDiscoveryOptions, UseDiscoveryResult, UseEntitlementOptions, UseEntitlementResult, UseLivePlanVersionsOptions, UseLivePlanVersionsResult, UseManifestResult, UseMarketingProjectionsOptions, UseMarketingProjectionsResult, UseNavResult, UsePaginationResult, UsePlanEditorOptions, UsePlanEditorResult, UsePlanVersionsOptions, UsePlanVersionsResult, UsePlansOptions, UsePlansResult, UsePromotionsOptions, UsePromotionsResult, UsePublicBootResult, UseResourceListOptions, UseSignOutOptions, UseStepsOptions, UseSubscriptionDraftOptions, UseTenantActionFlowResult, UseTenantBillingCatalogOptions, UseTenantBillingCatalogResult, UseTenantBillingOptions, UseTenantBillingResult, UseTenantManifestOptions, UseTenantManifestResult, UseTenantSubscriptionBundlesOptions, UseTenantSubscriptionBundlesResult, UseTenantsOptions, UseTenantsResult, buildFeatureRouterGuard, createAdminRoutes, createManifestStore, createPlatformLoaders, createProjectPageHostRoute, defaultIconForActionKey, defaultToneForActionKey, findLatestLive, promoStatusTone, provideEntitlement, providePlanWizard, resolveSuperAdminEndpoints, useActions, useApiList, useAppliedSettings, useAsyncAction, useAsyncData, useAuditEntries, useBatchColumns, useBulkPublish, useBundleVersions, useBundleVersionsMap, useBundles, useCatalogEntries, useDialog, useDiscovery, useEntitlement, useInjectedEntitlement, useLivePlanVersions, useManifest, useMarketingProjections, useMfaPrompt, useNav, usePagination, usePlanEditor, usePlanVersions, usePlanWizard, usePlans, usePlatformTenantActions, usePromotions, usePublicBoot, useResourceList, useRowReorder, useSignOut, useSteps, useSubscriptionDraft, useSuperAdminActions, useSuperAdminBrand, useSuperAdminEndpoints, useSuperAdminExtensions, useSuperAdminHttp, useSuperAdminLoginAdapter, useSuperAdminManifest, useTenantActionFlow, useTenantBilling, useTenantBillingCatalog, useTenantManifest, useTenantSubscriptionBundles, useTenants } from './vue/index.js';
|
|
6
6
|
import { FeatureCatalogEntryRow, QuotaCatalogEntryRow } from '@saasicat/core';
|
|
7
7
|
import 'vue';
|
|
8
8
|
import 'vue-router';
|
package/dist/index.js
CHANGED
|
@@ -30,7 +30,6 @@ import {
|
|
|
30
30
|
CatalogEntriesApiError,
|
|
31
31
|
DEFAULT_LOGIN_PATH,
|
|
32
32
|
DEFAULT_ROWS_PER_PAGE,
|
|
33
|
-
DEFAULT_YEARLY_FACTOR,
|
|
34
33
|
DiscoveryLoadError,
|
|
35
34
|
ENTITLEMENT_INJECTION_KEY,
|
|
36
35
|
MarketingProjectionsApiError,
|
|
@@ -100,7 +99,7 @@ import {
|
|
|
100
99
|
useTenantManifest,
|
|
101
100
|
useTenantSubscriptionBundles,
|
|
102
101
|
useTenants
|
|
103
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-ADKRZZDZ.js";
|
|
104
103
|
import {
|
|
105
104
|
ActionDefNotInManifestError,
|
|
106
105
|
ActionRegistry,
|
|
@@ -268,7 +267,6 @@ export {
|
|
|
268
267
|
DEFAULT_ROWS_PER_PAGE,
|
|
269
268
|
DEFAULT_SA_LOCALE,
|
|
270
269
|
DEFAULT_STANDARD_PAGE_ROUTES,
|
|
271
|
-
DEFAULT_YEARLY_FACTOR,
|
|
272
270
|
DiscoveryLoadError,
|
|
273
271
|
ENTITLEMENT_INJECTION_KEY,
|
|
274
272
|
HttpJsonError,
|
package/dist/vue/index.cjs
CHANGED
|
@@ -25,7 +25,6 @@ __export(vue_exports, {
|
|
|
25
25
|
CatalogEntriesApiError: () => CatalogEntriesApiError,
|
|
26
26
|
DEFAULT_LOGIN_PATH: () => DEFAULT_LOGIN_PATH,
|
|
27
27
|
DEFAULT_ROWS_PER_PAGE: () => DEFAULT_ROWS_PER_PAGE,
|
|
28
|
-
DEFAULT_YEARLY_FACTOR: () => DEFAULT_YEARLY_FACTOR,
|
|
29
28
|
DiscoveryLoadError: () => DiscoveryLoadError,
|
|
30
29
|
ENTITLEMENT_INJECTION_KEY: () => ENTITLEMENT_INJECTION_KEY,
|
|
31
30
|
MarketingProjectionsApiError: () => MarketingProjectionsApiError,
|
|
@@ -5507,21 +5506,16 @@ function useTenantBilling(options = {}) {
|
|
|
5507
5506
|
// src/vue/use-subscription-draft.ts
|
|
5508
5507
|
var import_vue19 = require("vue");
|
|
5509
5508
|
var import_core3 = require("@saasicat/core");
|
|
5510
|
-
var DEFAULT_YEARLY_FACTOR = 10;
|
|
5511
5509
|
function unwrap(source) {
|
|
5512
5510
|
if (source && typeof source === "object" && "value" in source) {
|
|
5513
5511
|
return source.value;
|
|
5514
5512
|
}
|
|
5515
5513
|
return source;
|
|
5516
5514
|
}
|
|
5517
|
-
function priceForCycle(
|
|
5518
|
-
|
|
5519
|
-
return yearlyNet != null ? yearlyNet : monthlyNet * yearlyFactor;
|
|
5520
|
-
}
|
|
5521
|
-
return monthlyNet;
|
|
5515
|
+
function priceForCycle(item, cycle) {
|
|
5516
|
+
return cycle === "YEARLY" ? item.yearlyNet : item.monthlyNet;
|
|
5522
5517
|
}
|
|
5523
5518
|
function useSubscriptionDraft(options) {
|
|
5524
|
-
const yearlyFactor = options.yearlyFactor ?? DEFAULT_YEARLY_FACTOR;
|
|
5525
5519
|
const plansRef = (0, import_vue19.computed)(() => unwrap(options.plans) ?? []);
|
|
5526
5520
|
const subscriptionBundlesRef = (0, import_vue19.computed)(
|
|
5527
5521
|
() => unwrap(options.subscriptionBundles ?? null) ?? []
|
|
@@ -5539,7 +5533,7 @@ function useSubscriptionDraft(options) {
|
|
|
5539
5533
|
});
|
|
5540
5534
|
const selectedBundles = (0, import_vue19.computed)(
|
|
5541
5535
|
() => subscriptionBundlesRef.value.filter(
|
|
5542
|
-
(b) => selectedBundleVersionIds.value.has(b.bundleVersionId)
|
|
5536
|
+
(b) => selectedBundleVersionIds.value.has(b.bundleVersionId) && priceForCycle(b, cycle.value) !== null
|
|
5543
5537
|
)
|
|
5544
5538
|
);
|
|
5545
5539
|
const chargeableBundles = (0, import_vue19.computed)(() => {
|
|
@@ -5564,11 +5558,12 @@ function useSubscriptionDraft(options) {
|
|
|
5564
5558
|
const pricing = (0, import_vue19.computed)(() => {
|
|
5565
5559
|
const cyc = cycle.value;
|
|
5566
5560
|
const planObj = selectedPlan.value;
|
|
5567
|
-
const
|
|
5561
|
+
const planPrice = planObj ? priceForCycle(planObj, cyc) : null;
|
|
5562
|
+
const planNet = planPrice ?? 0;
|
|
5568
5563
|
const bundleItems = [];
|
|
5569
5564
|
let bundlesNet = 0;
|
|
5570
5565
|
for (const b of chargeableBundles.value) {
|
|
5571
|
-
const net = priceForCycle(b
|
|
5566
|
+
const net = priceForCycle(b, cyc) ?? 0;
|
|
5572
5567
|
bundlesNet += net;
|
|
5573
5568
|
bundleItems.push({
|
|
5574
5569
|
key: `subscription-bundle:${b.bundleVersionId}`,
|
|
@@ -5580,30 +5575,19 @@ function useSubscriptionDraft(options) {
|
|
|
5580
5575
|
let discountNet = 0;
|
|
5581
5576
|
const preview = promoState.value.preview;
|
|
5582
5577
|
if (preview && preview.valid && promoState.value.status === "valid") {
|
|
5583
|
-
const
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
if (valid.discount.valueType === "PERCENT") {
|
|
5587
|
-
discountNet = subtotalNet * value / 100;
|
|
5588
|
-
} else {
|
|
5589
|
-
discountNet = Math.min(value, subtotalNet);
|
|
5590
|
-
}
|
|
5578
|
+
const amount = Number(preview.price.discountNet);
|
|
5579
|
+
if (Number.isFinite(amount) && amount > 0) {
|
|
5580
|
+
discountNet = Math.min(amount, planNet);
|
|
5591
5581
|
}
|
|
5592
5582
|
}
|
|
5593
5583
|
const totalNet = Math.max(0, subtotalNet - discountNet);
|
|
5594
5584
|
let yearSavings = 0;
|
|
5595
|
-
if (planObj) {
|
|
5596
|
-
|
|
5597
|
-
const yearlyTotal = priceForCycle(
|
|
5598
|
-
planObj.monthlyNet ?? 0,
|
|
5599
|
-
planObj.yearlyNet,
|
|
5600
|
-
"YEARLY",
|
|
5601
|
-
yearlyFactor
|
|
5602
|
-
);
|
|
5603
|
-
yearSavings = Math.max(0, monthlyTotal - yearlyTotal);
|
|
5585
|
+
if (planObj && planObj.monthlyNet !== null && planObj.yearlyNet !== null) {
|
|
5586
|
+
yearSavings = Math.max(0, planObj.monthlyNet * 12 - planObj.yearlyNet);
|
|
5604
5587
|
}
|
|
5605
5588
|
return {
|
|
5606
5589
|
cycle: cyc,
|
|
5590
|
+
planPriced: planPrice !== null,
|
|
5607
5591
|
planNet,
|
|
5608
5592
|
bundlesNet,
|
|
5609
5593
|
subtotalNet,
|
|
@@ -5611,7 +5595,9 @@ function useSubscriptionDraft(options) {
|
|
|
5611
5595
|
totalNet,
|
|
5612
5596
|
yearSavings,
|
|
5613
5597
|
breakdown: {
|
|
5614
|
-
plan:
|
|
5598
|
+
// A plan not sold in the cycle has no line: 0.00 beside its name
|
|
5599
|
+
// would read as a price.
|
|
5600
|
+
plan: planObj && planPrice !== null ? {
|
|
5615
5601
|
key: `plan:${planObj.id}`,
|
|
5616
5602
|
label: planObj.name,
|
|
5617
5603
|
net: planNet,
|
|
@@ -5624,9 +5610,15 @@ function useSubscriptionDraft(options) {
|
|
|
5624
5610
|
const isDirty = (0, import_vue19.computed)(() => {
|
|
5625
5611
|
return selectedBundleVersionIds.value.size > 0 || promoState.value.status === "valid";
|
|
5626
5612
|
});
|
|
5613
|
+
function forgetPromoPreview() {
|
|
5614
|
+
if (promoState.value.status !== "idle") {
|
|
5615
|
+
promoState.value = { status: "idle", preview: null, message: "" };
|
|
5616
|
+
}
|
|
5617
|
+
}
|
|
5627
5618
|
function setPlan(planId) {
|
|
5628
5619
|
if (plan.value === planId) return;
|
|
5629
5620
|
plan.value = planId;
|
|
5621
|
+
forgetPromoPreview();
|
|
5630
5622
|
const compatibleBundleVersions = /* @__PURE__ */ new Set();
|
|
5631
5623
|
for (const bundle of subscriptionBundlesRef.value) {
|
|
5632
5624
|
if (bundle.compatiblePlanKeys.length === 0 || bundle.compatiblePlanKeys.includes(planId)) {
|
|
@@ -5638,7 +5630,9 @@ function useSubscriptionDraft(options) {
|
|
|
5638
5630
|
);
|
|
5639
5631
|
}
|
|
5640
5632
|
function setCycle(c) {
|
|
5633
|
+
if (cycle.value === c) return;
|
|
5641
5634
|
cycle.value = c;
|
|
5635
|
+
forgetPromoPreview();
|
|
5642
5636
|
}
|
|
5643
5637
|
function toggleSubscriptionBundle(bundleVersionId) {
|
|
5644
5638
|
const next = new Set(selectedBundleVersionIds.value);
|
|
@@ -5648,9 +5642,7 @@ function useSubscriptionDraft(options) {
|
|
|
5648
5642
|
}
|
|
5649
5643
|
function setPromoCode(code) {
|
|
5650
5644
|
promoCode.value = code.toUpperCase();
|
|
5651
|
-
|
|
5652
|
-
promoState.value = { status: "idle", preview: null, message: "" };
|
|
5653
|
-
}
|
|
5645
|
+
forgetPromoPreview();
|
|
5654
5646
|
}
|
|
5655
5647
|
function setPromoState(state) {
|
|
5656
5648
|
promoState.value = state;
|
|
@@ -8188,7 +8180,6 @@ function createManifestStore(options) {
|
|
|
8188
8180
|
CatalogEntriesApiError,
|
|
8189
8181
|
DEFAULT_LOGIN_PATH,
|
|
8190
8182
|
DEFAULT_ROWS_PER_PAGE,
|
|
8191
|
-
DEFAULT_YEARLY_FACTOR,
|
|
8192
8183
|
DiscoveryLoadError,
|
|
8193
8184
|
ENTITLEMENT_INJECTION_KEY,
|
|
8194
8185
|
MarketingProjectionsApiError,
|
package/dist/vue/index.d.cts
CHANGED
|
@@ -886,7 +886,6 @@ interface UseTenantBillingResult {
|
|
|
886
886
|
}
|
|
887
887
|
declare function useTenantBilling(options?: UseTenantBillingOptions): UseTenantBillingResult;
|
|
888
888
|
|
|
889
|
-
declare const DEFAULT_YEARLY_FACTOR = 10;
|
|
890
889
|
type PromoStatus = 'idle' | 'checking' | 'valid' | 'invalid' | 'restricted';
|
|
891
890
|
interface PromoState {
|
|
892
891
|
status: PromoStatus;
|
|
@@ -901,8 +900,6 @@ interface UseSubscriptionDraftOptions {
|
|
|
901
900
|
initialPlan?: string | null;
|
|
902
901
|
initialCycle?: BillingCycleStr;
|
|
903
902
|
initialBundleVersionIds?: ReadonlyArray<string>;
|
|
904
|
-
/** Override for the `yearlyNet` fallback if the catalog provides no yearlyNet. */
|
|
905
|
-
yearlyFactor?: number;
|
|
906
903
|
}
|
|
907
904
|
interface PriceLineItem {
|
|
908
905
|
/** Stable key for UI `v-for`. */
|
|
@@ -915,13 +912,22 @@ interface PriceLineItem {
|
|
|
915
912
|
}
|
|
916
913
|
interface DraftPricing {
|
|
917
914
|
cycle: BillingCycleStr;
|
|
915
|
+
/**
|
|
916
|
+
* Whether the selected plan carries a price for the cycle. A plan without
|
|
917
|
+
* one is not sold in it — a plan without a yearly price is a monthly plan —
|
|
918
|
+
* so `planNet` is 0 and there is nothing to submit.
|
|
919
|
+
*/
|
|
920
|
+
planPriced: boolean;
|
|
918
921
|
/** Plan base without bundles. */
|
|
919
922
|
planNet: number;
|
|
920
923
|
/** Sum of all selected catalog bundles. */
|
|
921
924
|
bundlesNet: number;
|
|
922
925
|
/** Plan + Bundles. */
|
|
923
926
|
subtotalNet: number;
|
|
924
|
-
/**
|
|
927
|
+
/**
|
|
928
|
+
* The promo preview's discount in net. A code discounts the plan price, not
|
|
929
|
+
* the bundles, so it never exceeds `planNet`.
|
|
930
|
+
*/
|
|
925
931
|
discountNet: number;
|
|
926
932
|
/** subtotalNet - discountNet. */
|
|
927
933
|
totalNet: number;
|
|
@@ -1979,4 +1985,4 @@ type ManifestStoreDefinition = StoreDefinition<string, ManifestStoreState, Recor
|
|
|
1979
1985
|
*/
|
|
1980
1986
|
declare function createManifestStore(options: CreateManifestStoreOptions): ManifestStoreDefinition;
|
|
1981
1987
|
|
|
1982
|
-
export { ALL_ROWS, ActionsMap, type ApiListResponse, type AppliedSettingsResource, type AppliedSettingsState, type AsyncAction, type AsyncActionResult, type AsyncData, type AsyncList, type BillingCycleStr, type BulkItemKind, type BulkItemStatus, type BulkPublishItem, type BundleAddPreviewShape, type BundleBookingOptions, type BundleCancelPreviewShape, type BundlePreviewIssueShape, type BundlePreviewShape, type BundlePreviewSnapshotShape, BundlesApiError, type CancellationResultShape, type CatalogBundle, CatalogEntriesApiError, type CatalogPlan, type ConfirmDialogState, type CreateAdminRoutesOptions, type CreateManifestStoreOptions, type CreatePlatformLoadersOptions, DEFAULT_LOGIN_PATH, DEFAULT_ROWS_PER_PAGE,
|
|
1988
|
+
export { ALL_ROWS, ActionsMap, type ApiListResponse, type AppliedSettingsResource, type AppliedSettingsState, type AsyncAction, type AsyncActionResult, type AsyncData, type AsyncList, type BillingCycleStr, type BulkItemKind, type BulkItemStatus, type BulkPublishItem, type BundleAddPreviewShape, type BundleBookingOptions, type BundleCancelPreviewShape, type BundlePreviewIssueShape, type BundlePreviewShape, type BundlePreviewSnapshotShape, BundlesApiError, type CancellationResultShape, type CatalogBundle, CatalogEntriesApiError, type CatalogPlan, type ConfirmDialogState, type CreateAdminRoutesOptions, type CreateManifestStoreOptions, type CreatePlatformLoadersOptions, DEFAULT_LOGIN_PATH, DEFAULT_ROWS_PER_PAGE, type Dialog, DiscoveryLoadError, type DraftPricing, ENTITLEMENT_INJECTION_KEY, type EntitlementSnapshotShape, ExtensionsMap, type FeatureRouterGuardOptions, type FeatureRowMarkers, type ListOpNames, type ListResourceKey, type ManifestStoreActions, type ManifestStoreDefinition, type ManifestStoreState, MarketingProjectionsApiError, type MfaDialogState, type MfaOutcome, type MfaPrompt, PAGE_SIZE_OPTIONS, PLAN_WIZARD_KEY, PROMO_STATUS_TONE, type PackageSnapshotShape, type PillTone, type PlanChangePreviewIssueShape, type PlanChangePreviewShape, type PlanDraftEditing, type PlanDraftForm, type PlanSnapshotShape, type PlanWizardState, PlannedOnlyFeatureError, PlansApiError, type PlatformLoaders, type PlatformTenantActionRow, type PlatformTenantActionTone, type PlatformTenantActionsOptions, type PlatformTenantActionsResult, type PriceLineItem, ProjectPageHost, type PromoState, type PromoStatus, PromotionsApiError, type RedundantFeatureHintShape, type ResolvedBundlePrice, type ResolvedTenantAction, ResourceMap, ResourceOverride, type RowOf, type RowReorder, SERVER_PAGE_SIZE_OPTIONS, type StepStatus, type Steps, type SubscriptionBundleShape, type SubscriptionDraft, SuperAdminBrand, SuperAdminEndpoints, SuperAdminLoginAdapter, type TenantActionFlowProviders, type TenantActionInput, type TenantManifestNavItem, type TenantManifestShape, type TenantRowLike, TenantSubscriptionBundlesApiError, UiNotify, type UsageSnapshotShape, type UseActionsResult, type UseApiListOptions, type UseApiListResult, type UseAsyncActionOptions, type UseAsyncDataOptions, type UseAuditEntriesOptions, type UseAuditEntriesResult, type UseBatchColumnsResult, type UseBulkPublishOptions, type UseBulkPublishResult, type UseBundleVersionsMapOptions, type UseBundleVersionsMapResult, type UseBundleVersionsOptions, type UseBundleVersionsResult, type UseBundlesOptions, type UseBundlesResult, type UseCatalogEntriesOptions, type UseCatalogEntriesResult, type UseDialogOptions, type UseDiscoveryOptions, type UseDiscoveryResult, type UseEntitlementOptions, type UseEntitlementResult, type UseLivePlanVersionsOptions, type UseLivePlanVersionsResult, type UseManifestResult, type UseMarketingProjectionsOptions, type UseMarketingProjectionsResult, type UseNavResult, type UsePaginationResult, type UsePlanEditorOptions, type UsePlanEditorResult, type UsePlanVersionsOptions, type UsePlanVersionsResult, type UsePlansOptions, type UsePlansResult, type UsePromotionsOptions, type UsePromotionsResult, type UsePublicBootResult, type UseResourceListOptions, type UseSignOutOptions, type UseStepsOptions, type UseSubscriptionDraftOptions, type UseTenantActionFlowResult, type UseTenantBillingCatalogOptions, type UseTenantBillingCatalogResult, type UseTenantBillingOptions, type UseTenantBillingResult, type UseTenantManifestOptions, type UseTenantManifestResult, type UseTenantSubscriptionBundlesOptions, type UseTenantSubscriptionBundlesResult, type UseTenantsOptions, type UseTenantsResult, buildFeatureRouterGuard, createAdminRoutes, createManifestStore, createPlatformLoaders, createProjectPageHostRoute, defaultIconForActionKey, defaultToneForActionKey, findLatestLive, promoStatusTone, provideEntitlement, providePlanWizard, resolveSuperAdminEndpoints, useActions, useApiList, useAppliedSettings, useAsyncAction, useAsyncData, useAuditEntries, useBatchColumns, useBulkPublish, useBundleVersions, useBundleVersionsMap, useBundles, useCatalogEntries, useDialog, useDiscovery, useEntitlement, useInjectedEntitlement, useLivePlanVersions, useManifest, useMarketingProjections, useMfaPrompt, useNav, usePagination, usePlanEditor, usePlanVersions, usePlanWizard, usePlans, usePlatformTenantActions, usePromotions, usePublicBoot, useResourceList, useRowReorder, useSignOut, useSteps, useSubscriptionDraft, useSuperAdminActions, useSuperAdminBrand, useSuperAdminEndpoints, useSuperAdminExtensions, useSuperAdminHttp, useSuperAdminLoginAdapter, useSuperAdminManifest, useTenantActionFlow, useTenantBilling, useTenantBillingCatalog, useTenantManifest, useTenantSubscriptionBundles, useTenants };
|
package/dist/vue/index.d.ts
CHANGED
|
@@ -886,7 +886,6 @@ interface UseTenantBillingResult {
|
|
|
886
886
|
}
|
|
887
887
|
declare function useTenantBilling(options?: UseTenantBillingOptions): UseTenantBillingResult;
|
|
888
888
|
|
|
889
|
-
declare const DEFAULT_YEARLY_FACTOR = 10;
|
|
890
889
|
type PromoStatus = 'idle' | 'checking' | 'valid' | 'invalid' | 'restricted';
|
|
891
890
|
interface PromoState {
|
|
892
891
|
status: PromoStatus;
|
|
@@ -901,8 +900,6 @@ interface UseSubscriptionDraftOptions {
|
|
|
901
900
|
initialPlan?: string | null;
|
|
902
901
|
initialCycle?: BillingCycleStr;
|
|
903
902
|
initialBundleVersionIds?: ReadonlyArray<string>;
|
|
904
|
-
/** Override for the `yearlyNet` fallback if the catalog provides no yearlyNet. */
|
|
905
|
-
yearlyFactor?: number;
|
|
906
903
|
}
|
|
907
904
|
interface PriceLineItem {
|
|
908
905
|
/** Stable key for UI `v-for`. */
|
|
@@ -915,13 +912,22 @@ interface PriceLineItem {
|
|
|
915
912
|
}
|
|
916
913
|
interface DraftPricing {
|
|
917
914
|
cycle: BillingCycleStr;
|
|
915
|
+
/**
|
|
916
|
+
* Whether the selected plan carries a price for the cycle. A plan without
|
|
917
|
+
* one is not sold in it — a plan without a yearly price is a monthly plan —
|
|
918
|
+
* so `planNet` is 0 and there is nothing to submit.
|
|
919
|
+
*/
|
|
920
|
+
planPriced: boolean;
|
|
918
921
|
/** Plan base without bundles. */
|
|
919
922
|
planNet: number;
|
|
920
923
|
/** Sum of all selected catalog bundles. */
|
|
921
924
|
bundlesNet: number;
|
|
922
925
|
/** Plan + Bundles. */
|
|
923
926
|
subtotalNet: number;
|
|
924
|
-
/**
|
|
927
|
+
/**
|
|
928
|
+
* The promo preview's discount in net. A code discounts the plan price, not
|
|
929
|
+
* the bundles, so it never exceeds `planNet`.
|
|
930
|
+
*/
|
|
925
931
|
discountNet: number;
|
|
926
932
|
/** subtotalNet - discountNet. */
|
|
927
933
|
totalNet: number;
|
|
@@ -1979,4 +1985,4 @@ type ManifestStoreDefinition = StoreDefinition<string, ManifestStoreState, Recor
|
|
|
1979
1985
|
*/
|
|
1980
1986
|
declare function createManifestStore(options: CreateManifestStoreOptions): ManifestStoreDefinition;
|
|
1981
1987
|
|
|
1982
|
-
export { ALL_ROWS, ActionsMap, type ApiListResponse, type AppliedSettingsResource, type AppliedSettingsState, type AsyncAction, type AsyncActionResult, type AsyncData, type AsyncList, type BillingCycleStr, type BulkItemKind, type BulkItemStatus, type BulkPublishItem, type BundleAddPreviewShape, type BundleBookingOptions, type BundleCancelPreviewShape, type BundlePreviewIssueShape, type BundlePreviewShape, type BundlePreviewSnapshotShape, BundlesApiError, type CancellationResultShape, type CatalogBundle, CatalogEntriesApiError, type CatalogPlan, type ConfirmDialogState, type CreateAdminRoutesOptions, type CreateManifestStoreOptions, type CreatePlatformLoadersOptions, DEFAULT_LOGIN_PATH, DEFAULT_ROWS_PER_PAGE,
|
|
1988
|
+
export { ALL_ROWS, ActionsMap, type ApiListResponse, type AppliedSettingsResource, type AppliedSettingsState, type AsyncAction, type AsyncActionResult, type AsyncData, type AsyncList, type BillingCycleStr, type BulkItemKind, type BulkItemStatus, type BulkPublishItem, type BundleAddPreviewShape, type BundleBookingOptions, type BundleCancelPreviewShape, type BundlePreviewIssueShape, type BundlePreviewShape, type BundlePreviewSnapshotShape, BundlesApiError, type CancellationResultShape, type CatalogBundle, CatalogEntriesApiError, type CatalogPlan, type ConfirmDialogState, type CreateAdminRoutesOptions, type CreateManifestStoreOptions, type CreatePlatformLoadersOptions, DEFAULT_LOGIN_PATH, DEFAULT_ROWS_PER_PAGE, type Dialog, DiscoveryLoadError, type DraftPricing, ENTITLEMENT_INJECTION_KEY, type EntitlementSnapshotShape, ExtensionsMap, type FeatureRouterGuardOptions, type FeatureRowMarkers, type ListOpNames, type ListResourceKey, type ManifestStoreActions, type ManifestStoreDefinition, type ManifestStoreState, MarketingProjectionsApiError, type MfaDialogState, type MfaOutcome, type MfaPrompt, PAGE_SIZE_OPTIONS, PLAN_WIZARD_KEY, PROMO_STATUS_TONE, type PackageSnapshotShape, type PillTone, type PlanChangePreviewIssueShape, type PlanChangePreviewShape, type PlanDraftEditing, type PlanDraftForm, type PlanSnapshotShape, type PlanWizardState, PlannedOnlyFeatureError, PlansApiError, type PlatformLoaders, type PlatformTenantActionRow, type PlatformTenantActionTone, type PlatformTenantActionsOptions, type PlatformTenantActionsResult, type PriceLineItem, ProjectPageHost, type PromoState, type PromoStatus, PromotionsApiError, type RedundantFeatureHintShape, type ResolvedBundlePrice, type ResolvedTenantAction, ResourceMap, ResourceOverride, type RowOf, type RowReorder, SERVER_PAGE_SIZE_OPTIONS, type StepStatus, type Steps, type SubscriptionBundleShape, type SubscriptionDraft, SuperAdminBrand, SuperAdminEndpoints, SuperAdminLoginAdapter, type TenantActionFlowProviders, type TenantActionInput, type TenantManifestNavItem, type TenantManifestShape, type TenantRowLike, TenantSubscriptionBundlesApiError, UiNotify, type UsageSnapshotShape, type UseActionsResult, type UseApiListOptions, type UseApiListResult, type UseAsyncActionOptions, type UseAsyncDataOptions, type UseAuditEntriesOptions, type UseAuditEntriesResult, type UseBatchColumnsResult, type UseBulkPublishOptions, type UseBulkPublishResult, type UseBundleVersionsMapOptions, type UseBundleVersionsMapResult, type UseBundleVersionsOptions, type UseBundleVersionsResult, type UseBundlesOptions, type UseBundlesResult, type UseCatalogEntriesOptions, type UseCatalogEntriesResult, type UseDialogOptions, type UseDiscoveryOptions, type UseDiscoveryResult, type UseEntitlementOptions, type UseEntitlementResult, type UseLivePlanVersionsOptions, type UseLivePlanVersionsResult, type UseManifestResult, type UseMarketingProjectionsOptions, type UseMarketingProjectionsResult, type UseNavResult, type UsePaginationResult, type UsePlanEditorOptions, type UsePlanEditorResult, type UsePlanVersionsOptions, type UsePlanVersionsResult, type UsePlansOptions, type UsePlansResult, type UsePromotionsOptions, type UsePromotionsResult, type UsePublicBootResult, type UseResourceListOptions, type UseSignOutOptions, type UseStepsOptions, type UseSubscriptionDraftOptions, type UseTenantActionFlowResult, type UseTenantBillingCatalogOptions, type UseTenantBillingCatalogResult, type UseTenantBillingOptions, type UseTenantBillingResult, type UseTenantManifestOptions, type UseTenantManifestResult, type UseTenantSubscriptionBundlesOptions, type UseTenantSubscriptionBundlesResult, type UseTenantsOptions, type UseTenantsResult, buildFeatureRouterGuard, createAdminRoutes, createManifestStore, createPlatformLoaders, createProjectPageHostRoute, defaultIconForActionKey, defaultToneForActionKey, findLatestLive, promoStatusTone, provideEntitlement, providePlanWizard, resolveSuperAdminEndpoints, useActions, useApiList, useAppliedSettings, useAsyncAction, useAsyncData, useAuditEntries, useBatchColumns, useBulkPublish, useBundleVersions, useBundleVersionsMap, useBundles, useCatalogEntries, useDialog, useDiscovery, useEntitlement, useInjectedEntitlement, useLivePlanVersions, useManifest, useMarketingProjections, useMfaPrompt, useNav, usePagination, usePlanEditor, usePlanVersions, usePlanWizard, usePlans, usePlatformTenantActions, usePromotions, usePublicBoot, useResourceList, useRowReorder, useSignOut, useSteps, useSubscriptionDraft, useSuperAdminActions, useSuperAdminBrand, useSuperAdminEndpoints, useSuperAdminExtensions, useSuperAdminHttp, useSuperAdminLoginAdapter, useSuperAdminManifest, useTenantActionFlow, useTenantBilling, useTenantBillingCatalog, useTenantManifest, useTenantSubscriptionBundles, useTenants };
|
package/dist/vue/index.js
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
CatalogEntriesApiError,
|
|
5
5
|
DEFAULT_LOGIN_PATH,
|
|
6
6
|
DEFAULT_ROWS_PER_PAGE,
|
|
7
|
-
DEFAULT_YEARLY_FACTOR,
|
|
8
7
|
DiscoveryLoadError,
|
|
9
8
|
ENTITLEMENT_INJECTION_KEY,
|
|
10
9
|
MarketingProjectionsApiError,
|
|
@@ -74,7 +73,7 @@ import {
|
|
|
74
73
|
useTenantManifest,
|
|
75
74
|
useTenantSubscriptionBundles,
|
|
76
75
|
useTenants
|
|
77
|
-
} from "../chunk-
|
|
76
|
+
} from "../chunk-ADKRZZDZ.js";
|
|
78
77
|
import "../chunk-MPVQBEM6.js";
|
|
79
78
|
import {
|
|
80
79
|
SA_COLOR_SCHEMES,
|
|
@@ -112,7 +111,6 @@ export {
|
|
|
112
111
|
CatalogEntriesApiError,
|
|
113
112
|
DEFAULT_LOGIN_PATH,
|
|
114
113
|
DEFAULT_ROWS_PER_PAGE,
|
|
115
|
-
DEFAULT_YEARLY_FACTOR,
|
|
116
114
|
DiscoveryLoadError,
|
|
117
115
|
ENTITLEMENT_INJECTION_KEY,
|
|
118
116
|
MarketingProjectionsApiError,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saasicat/ui-vue",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.14",
|
|
4
4
|
"description": "Vue 3 components, resource clients and composables for the SuperAdmin UI shell. Provides boot and manifest loaders, navigation, actions and standard pages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
],
|
|
92
92
|
"dependencies": {
|
|
93
93
|
"quasar": "^2.24.0",
|
|
94
|
-
"@saasicat/core": "^1.0.0-rc.
|
|
94
|
+
"@saasicat/core": "^1.0.0-rc.14"
|
|
95
95
|
},
|
|
96
96
|
"peerDependencies": {
|
|
97
97
|
"pinia": "^2.0.0 || ^3.0.0",
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
"vue": "^3.5.0",
|
|
125
125
|
"vue-router": "^5.0.0",
|
|
126
126
|
"vue-tsc": "^3.3.3",
|
|
127
|
-
"@saasicat/ui-vue-tenant": "1.0.0-rc.
|
|
127
|
+
"@saasicat/ui-vue-tenant": "1.0.0-rc.14"
|
|
128
128
|
},
|
|
129
129
|
"license": "PolyForm-Shield-1.0.0",
|
|
130
130
|
"author": "Taci Uelker",
|
|
@@ -21,11 +21,6 @@ import {
|
|
|
21
21
|
type PublicMarketingBundle,
|
|
22
22
|
} from '@saasicat/core';
|
|
23
23
|
|
|
24
|
-
// For yearly payment, the mockup applies 10x the monthly price (= 2 months free).
|
|
25
|
-
// If the catalog already provides a `yearlyNet`, that one is used;
|
|
26
|
-
// if it is missing, the composable falls back to `monthly * 10`.
|
|
27
|
-
export const DEFAULT_YEARLY_FACTOR = 10;
|
|
28
|
-
|
|
29
24
|
export type PromoStatus = 'idle' | 'checking' | 'valid' | 'invalid' | 'restricted';
|
|
30
25
|
|
|
31
26
|
export interface PromoState {
|
|
@@ -43,8 +38,6 @@ export interface UseSubscriptionDraftOptions {
|
|
|
43
38
|
initialPlan?: string | null;
|
|
44
39
|
initialCycle?: BillingCycleStr;
|
|
45
40
|
initialBundleVersionIds?: ReadonlyArray<string>;
|
|
46
|
-
/** Override for the `yearlyNet` fallback if the catalog provides no yearlyNet. */
|
|
47
|
-
yearlyFactor?: number;
|
|
48
41
|
}
|
|
49
42
|
|
|
50
43
|
export interface PriceLineItem {
|
|
@@ -59,13 +52,22 @@ export interface PriceLineItem {
|
|
|
59
52
|
|
|
60
53
|
export interface DraftPricing {
|
|
61
54
|
cycle: BillingCycleStr;
|
|
55
|
+
/**
|
|
56
|
+
* Whether the selected plan carries a price for the cycle. A plan without
|
|
57
|
+
* one is not sold in it — a plan without a yearly price is a monthly plan —
|
|
58
|
+
* so `planNet` is 0 and there is nothing to submit.
|
|
59
|
+
*/
|
|
60
|
+
planPriced: boolean;
|
|
62
61
|
/** Plan base without bundles. */
|
|
63
62
|
planNet: number;
|
|
64
63
|
/** Sum of all selected catalog bundles. */
|
|
65
64
|
bundlesNet: number;
|
|
66
65
|
/** Plan + Bundles. */
|
|
67
66
|
subtotalNet: number;
|
|
68
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* The promo preview's discount in net. A code discounts the plan price, not
|
|
69
|
+
* the bundles, so it never exceeds `planNet`.
|
|
70
|
+
*/
|
|
69
71
|
discountNet: number;
|
|
70
72
|
/** subtotalNet - discountNet. */
|
|
71
73
|
totalNet: number;
|
|
@@ -112,21 +114,20 @@ function unwrap<T>(source: Ref<T> | ComputedRef<T> | T): T {
|
|
|
112
114
|
return source as T;
|
|
113
115
|
}
|
|
114
116
|
|
|
117
|
+
/**
|
|
118
|
+
* The price the catalogue carries for the cycle, or `null` when it carries none.
|
|
119
|
+
*
|
|
120
|
+
* Never derived from the other cycle: a yearly price is what the operator set
|
|
121
|
+
* for a year, and the offer and the contract charge that figure or refuse.
|
|
122
|
+
*/
|
|
115
123
|
function priceForCycle(
|
|
116
|
-
monthlyNet: number,
|
|
117
|
-
yearlyNet: number | null | undefined,
|
|
124
|
+
item: { monthlyNet: number | null; yearlyNet: number | null },
|
|
118
125
|
cycle: BillingCycleStr,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (cycle === 'YEARLY') {
|
|
122
|
-
return yearlyNet != null ? yearlyNet : monthlyNet * yearlyFactor;
|
|
123
|
-
}
|
|
124
|
-
return monthlyNet;
|
|
126
|
+
): number | null {
|
|
127
|
+
return cycle === 'YEARLY' ? item.yearlyNet : item.monthlyNet;
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
export function useSubscriptionDraft(options: UseSubscriptionDraftOptions): SubscriptionDraft {
|
|
128
|
-
const yearlyFactor = options.yearlyFactor ?? DEFAULT_YEARLY_FACTOR;
|
|
129
|
-
|
|
130
131
|
const plansRef = computed<CatalogPlan[]>(() => unwrap(options.plans) ?? []);
|
|
131
132
|
const subscriptionBundlesRef = computed<PublicMarketingBundle[]>(
|
|
132
133
|
() => unwrap(options.subscriptionBundles ?? null) ?? [],
|
|
@@ -145,9 +146,14 @@ export function useSubscriptionDraft(options: UseSubscriptionDraftOptions): Subs
|
|
|
145
146
|
return plansRef.value.find((p) => p.id === plan.value) ?? null;
|
|
146
147
|
});
|
|
147
148
|
|
|
149
|
+
// A selected bundle without a price for the cycle is not sold in it, so it
|
|
150
|
+
// is neither charged nor sent, and covers nothing. It stays selected, so
|
|
151
|
+
// switching back to the cycle it is priced for books it again.
|
|
148
152
|
const selectedBundles = computed<PublicMarketingBundle[]>(() =>
|
|
149
|
-
subscriptionBundlesRef.value.filter(
|
|
150
|
-
|
|
153
|
+
subscriptionBundlesRef.value.filter(
|
|
154
|
+
(b) =>
|
|
155
|
+
selectedBundleVersionIds.value.has(b.bundleVersionId) &&
|
|
156
|
+
priceForCycle(b, cycle.value) !== null,
|
|
151
157
|
),
|
|
152
158
|
);
|
|
153
159
|
|
|
@@ -184,17 +190,15 @@ export function useSubscriptionDraft(options: UseSubscriptionDraftOptions): Subs
|
|
|
184
190
|
const cyc = cycle.value;
|
|
185
191
|
const planObj = selectedPlan.value;
|
|
186
192
|
|
|
187
|
-
|
|
188
|
-
const planNet =
|
|
189
|
-
? priceForCycle(planObj.monthlyNet ?? 0, planObj.yearlyNet, cyc, yearlyFactor)
|
|
190
|
-
: 0;
|
|
193
|
+
const planPrice = planObj ? priceForCycle(planObj, cyc) : null;
|
|
194
|
+
const planNet = planPrice ?? 0;
|
|
191
195
|
|
|
192
196
|
// Independently bookable catalog bundles from the public marketing catalog.
|
|
193
197
|
// Redundant (fully covered) bundles are excluded here.
|
|
194
198
|
const bundleItems: PriceLineItem[] = [];
|
|
195
199
|
let bundlesNet = 0;
|
|
196
200
|
for (const b of chargeableBundles.value) {
|
|
197
|
-
const net = priceForCycle(b
|
|
201
|
+
const net = priceForCycle(b, cyc) ?? 0;
|
|
198
202
|
bundlesNet += net;
|
|
199
203
|
bundleItems.push({
|
|
200
204
|
key: `subscription-bundle:${b.bundleVersionId}`,
|
|
@@ -205,43 +209,32 @@ export function useSubscriptionDraft(options: UseSubscriptionDraftOptions): Subs
|
|
|
205
209
|
|
|
206
210
|
const subtotalNet = planNet + bundlesNet;
|
|
207
211
|
|
|
208
|
-
//
|
|
209
|
-
//
|
|
210
|
-
//
|
|
212
|
+
// The discount is the one the server previewed. The promo module reckons
|
|
213
|
+
// it on the plan price in gross, and only the server knows the VAT rate
|
|
214
|
+
// that turns it into the net figure this summary adds up. A preview
|
|
215
|
+
// answers for one plan and cycle, which is why changing either sets the
|
|
216
|
+
// promo state back to idle for the caller to ask again.
|
|
211
217
|
let discountNet = 0;
|
|
212
218
|
const preview = promoState.value.preview;
|
|
213
219
|
if (preview && preview.valid && promoState.value.status === 'valid') {
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (valid.discount.valueType === 'PERCENT') {
|
|
218
|
-
discountNet = (subtotalNet * value) / 100;
|
|
219
|
-
} else {
|
|
220
|
-
discountNet = Math.min(value, subtotalNet);
|
|
221
|
-
}
|
|
220
|
+
const amount = Number((preview as PromoPreviewValidResponse).price.discountNet);
|
|
221
|
+
if (Number.isFinite(amount) && amount > 0) {
|
|
222
|
+
discountNet = Math.min(amount, planNet);
|
|
222
223
|
}
|
|
223
224
|
}
|
|
224
225
|
|
|
225
226
|
const totalNet = Math.max(0, subtotalNet - discountNet);
|
|
226
227
|
|
|
227
|
-
// yearSavings: 12 × monthly
|
|
228
|
+
// yearSavings: 12 × monthly − yearly. Only meaningful when the catalog
|
|
228
229
|
// knows both prices; otherwise 0.
|
|
229
230
|
let yearSavings = 0;
|
|
230
|
-
if (planObj) {
|
|
231
|
-
|
|
232
|
-
priceForCycle(planObj.monthlyNet ?? 0, planObj.yearlyNet, 'MONTHLY', yearlyFactor) *
|
|
233
|
-
12;
|
|
234
|
-
const yearlyTotal = priceForCycle(
|
|
235
|
-
planObj.monthlyNet ?? 0,
|
|
236
|
-
planObj.yearlyNet,
|
|
237
|
-
'YEARLY',
|
|
238
|
-
yearlyFactor,
|
|
239
|
-
);
|
|
240
|
-
yearSavings = Math.max(0, monthlyTotal - yearlyTotal);
|
|
231
|
+
if (planObj && planObj.monthlyNet !== null && planObj.yearlyNet !== null) {
|
|
232
|
+
yearSavings = Math.max(0, planObj.monthlyNet * 12 - planObj.yearlyNet);
|
|
241
233
|
}
|
|
242
234
|
|
|
243
235
|
return {
|
|
244
236
|
cycle: cyc,
|
|
237
|
+
planPriced: planPrice !== null,
|
|
245
238
|
planNet,
|
|
246
239
|
bundlesNet,
|
|
247
240
|
subtotalNet,
|
|
@@ -249,14 +242,17 @@ export function useSubscriptionDraft(options: UseSubscriptionDraftOptions): Subs
|
|
|
249
242
|
totalNet,
|
|
250
243
|
yearSavings,
|
|
251
244
|
breakdown: {
|
|
252
|
-
plan:
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
245
|
+
// A plan not sold in the cycle has no line: 0.00 beside its name
|
|
246
|
+
// would read as a price.
|
|
247
|
+
plan:
|
|
248
|
+
planObj && planPrice !== null
|
|
249
|
+
? {
|
|
250
|
+
key: `plan:${planObj.id}`,
|
|
251
|
+
label: planObj.name,
|
|
252
|
+
net: planNet,
|
|
253
|
+
sublabel: `${planObj.features.length} Basis-Module`,
|
|
254
|
+
}
|
|
255
|
+
: null,
|
|
260
256
|
bundles: bundleItems,
|
|
261
257
|
},
|
|
262
258
|
};
|
|
@@ -266,9 +262,17 @@ export function useSubscriptionDraft(options: UseSubscriptionDraftOptions): Subs
|
|
|
266
262
|
return selectedBundleVersionIds.value.size > 0 || promoState.value.status === 'valid';
|
|
267
263
|
});
|
|
268
264
|
|
|
265
|
+
// A promo preview answers for the plan and cycle it was asked about.
|
|
266
|
+
function forgetPromoPreview(): void {
|
|
267
|
+
if (promoState.value.status !== 'idle') {
|
|
268
|
+
promoState.value = { status: 'idle', preview: null, message: '' };
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
269
272
|
function setPlan(planId: string): void {
|
|
270
273
|
if (plan.value === planId) return;
|
|
271
274
|
plan.value = planId;
|
|
275
|
+
forgetPromoPreview();
|
|
272
276
|
// Reduce the bundle selection to those compatible with the new plan.
|
|
273
277
|
const compatibleBundleVersions = new Set<string>();
|
|
274
278
|
for (const bundle of subscriptionBundlesRef.value) {
|
|
@@ -285,8 +289,9 @@ export function useSubscriptionDraft(options: UseSubscriptionDraftOptions): Subs
|
|
|
285
289
|
}
|
|
286
290
|
|
|
287
291
|
function setCycle(c: BillingCycleStr): void {
|
|
292
|
+
if (cycle.value === c) return;
|
|
288
293
|
cycle.value = c;
|
|
289
|
-
|
|
294
|
+
forgetPromoPreview();
|
|
290
295
|
}
|
|
291
296
|
|
|
292
297
|
function toggleSubscriptionBundle(bundleVersionId: string): void {
|
|
@@ -299,9 +304,7 @@ export function useSubscriptionDraft(options: UseSubscriptionDraftOptions): Subs
|
|
|
299
304
|
function setPromoCode(code: string): void {
|
|
300
305
|
promoCode.value = code.toUpperCase();
|
|
301
306
|
// Reset status — the caller re-validates via preview().
|
|
302
|
-
|
|
303
|
-
promoState.value = { status: 'idle', preview: null, message: '' };
|
|
304
|
-
}
|
|
307
|
+
forgetPromoPreview();
|
|
305
308
|
}
|
|
306
309
|
|
|
307
310
|
function setPromoState(state: PromoState): void {
|