@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 CHANGED
@@ -1 +1 @@
1
- f878eab55ac697e5dea0742e5facb103935abe97b9d67726eba443617bd236fc
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(monthlyNet, yearlyNet, cycle, yearlyFactor) {
889
- if (cycle === "YEARLY") {
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 planNet = planObj ? priceForCycle(planObj.monthlyNet ?? 0, planObj.yearlyNet, cyc, yearlyFactor) : 0;
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.monthlyNet ?? 0, b.yearlyNet, cyc, yearlyFactor);
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 valid = preview;
955
- const value = Number(valid.discount.value);
956
- if (Number.isFinite(value) && value > 0) {
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
- const monthlyTotal = priceForCycle(planObj.monthlyNet ?? 0, planObj.yearlyNet, "MONTHLY", yearlyFactor) * 12;
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: planObj ? {
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
- if (promoState.value.status !== "idle") {
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(monthlyNet, yearlyNet, cycle, yearlyFactor) {
6592
- if (cycle === "YEARLY") {
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 planNet = planObj ? priceForCycle(planObj.monthlyNet ?? 0, planObj.yearlyNet, cyc, yearlyFactor) : 0;
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.monthlyNet ?? 0, b.yearlyNet, cyc, yearlyFactor);
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 valid = preview;
6658
- const value = Number(valid.discount.value);
6659
- if (Number.isFinite(value) && value > 0) {
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
- const monthlyTotal = priceForCycle(planObj.monthlyNet ?? 0, planObj.yearlyNet, "MONTHLY", yearlyFactor) * 12;
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: planObj ? {
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
- if (promoState.value.status !== "idle") {
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, DEFAULT_YEARLY_FACTOR, 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';
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, DEFAULT_YEARLY_FACTOR, 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';
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-HYFHYL73.js";
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,
@@ -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(monthlyNet, yearlyNet, cycle, yearlyFactor) {
5518
- if (cycle === "YEARLY") {
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 planNet = planObj ? priceForCycle(planObj.monthlyNet ?? 0, planObj.yearlyNet, cyc, yearlyFactor) : 0;
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.monthlyNet ?? 0, b.yearlyNet, cyc, yearlyFactor);
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 valid = preview;
5584
- const value = Number(valid.discount.value);
5585
- if (Number.isFinite(value) && value > 0) {
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
- const monthlyTotal = priceForCycle(planObj.monthlyNet ?? 0, planObj.yearlyNet, "MONTHLY", yearlyFactor) * 12;
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: planObj ? {
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
- if (promoState.value.status !== "idle") {
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,
@@ -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
- /** Discount derived from the promo preview (on subtotalNet, not plan-only). */
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, DEFAULT_YEARLY_FACTOR, 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 };
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 };
@@ -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
- /** Discount derived from the promo preview (on subtotalNet, not plan-only). */
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, DEFAULT_YEARLY_FACTOR, 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 };
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-HYFHYL73.js";
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.13",
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.13"
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.13"
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
- /** Discount derived from the promo preview (on subtotalNet, not plan-only). */
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
- yearlyFactor: number,
120
- ): number {
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((b) =>
150
- selectedBundleVersionIds.value.has(b.bundleVersionId),
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
- // Plan
188
- const planNet = planObj
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.monthlyNet ?? 0, b.yearlyNet, cyc, yearlyFactor);
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
- // Derive discount from the promo preview (PERCENT logic is mirrored on the
209
- // frontend; ABSOLUTE is deducted absolutely). The backend recomputes the
210
- // final truth at redeem time — the sidebar shows only the preview value.
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 valid = preview as PromoPreviewValidResponse;
215
- const value = Number(valid.discount.value);
216
- if (Number.isFinite(value) && value > 0) {
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 — yearly. Only meaningful when the catalog
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
- const monthlyTotal =
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: planObj
253
- ? {
254
- key: `plan:${planObj.id}`,
255
- label: planObj.name,
256
- net: planNet,
257
- sublabel: `${planObj.features.length} Basis-Module`,
258
- }
259
- : null,
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
- // Promo restrictions may change — the caller re-runs preview if needed.
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
- if (promoState.value.status !== 'idle') {
303
- promoState.value = { status: 'idle', preview: null, message: '' };
304
- }
307
+ forgetPromoPreview();
305
308
  }
306
309
 
307
310
  function setPromoState(state: PromoState): void {