@saasicat/ui-vue 1.0.0-rc.2 → 1.0.0-rc.21

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.
Files changed (309) hide show
  1. package/README.md +84 -19
  2. package/dist/.build-stamp +1 -1
  3. package/dist/assets/material-icons/material-icons.css +31 -0
  4. package/dist/assets/material-icons/web-font/flUhRq6tzZclQEJ-Vdg-IuiaDsNa.woff +0 -0
  5. package/dist/assets/material-icons/web-font/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2 +0 -0
  6. package/dist/assets/quasar.css +11696 -0
  7. package/dist/assets/ui-vue.css +6923 -0
  8. package/dist/auth/SuperAdminLoginPage.js +213 -0
  9. package/dist/auth/SuperAdminSetupWizard.js +5 -0
  10. package/dist/{batch-column-fetcher-VwjOxerL.d.ts → batch-column-fetcher-DQ89o95K.d.cts} +5 -5
  11. package/dist/{batch-column-fetcher-Dk9X92db.d.cts → batch-column-fetcher-Sr48UWEX.d.ts} +5 -5
  12. package/dist/{catalog-C5VKGbxk.d.cts → catalog-0eZwciPW.d.cts} +125 -86
  13. package/dist/{catalog-C5VKGbxk.d.ts → catalog-0eZwciPW.d.ts} +125 -86
  14. package/dist/{chunk-L7HPDVHV.js → chunk-47HDYN35.js} +86 -7
  15. package/dist/{chunk-A7JICGQ5.js → chunk-7CHT2ATN.js} +16 -3
  16. package/dist/{chunk-P4EJF43F.js → chunk-CZIVA536.js} +358 -300
  17. package/dist/{chunk-6X6AGH66.js → chunk-RFJ4UGOE.js} +7 -4
  18. package/dist/chunk-U7LNAX6T.js +35 -0
  19. package/dist/{chunk-4CJBABLZ.js → chunk-VLGEOPZH.js} +685 -196
  20. package/dist/chunks/AdminAccordion.vue_vue_type_script_setup_true_lang-DOwlTV5_.js +175 -0
  21. package/dist/chunks/AdminBanner.vue_vue_type_script_setup_true_lang-D27JEaak.js +83 -0
  22. package/dist/chunks/AdminBody.vue_vue_type_script_setup_true_lang-DxcVRzXE.js +41 -0
  23. package/dist/chunks/AdminDialog.vue_vue_type_script_setup_true_lang-CpxfSrx-.js +138 -0
  24. package/dist/chunks/AdminEmptyState.vue_vue_type_script_setup_true_lang-jaYkgNbE.js +48 -0
  25. package/dist/chunks/AdminErrorBanner.vue_vue_type_script_setup_true_lang-t-5uqt82.js +50 -0
  26. package/dist/chunks/AdminField.vue_vue_type_script_setup_true_lang-CtPByt2w.js +63 -0
  27. package/dist/chunks/AdminFieldGrid.vue_vue_type_script_setup_true_lang-BxuyHtBU.js +21 -0
  28. package/dist/chunks/AdminFilters.vue_vue_type_script_setup_true_lang-DSnzAlwj.js +18 -0
  29. package/dist/chunks/AdminFormDialog.vue_vue_type_script_setup_true_lang-BpWshaWv.js +84 -0
  30. package/dist/chunks/AdminHero.vue_vue_type_script_setup_true_lang-CoaRxXLF.js +46 -0
  31. package/dist/chunks/AdminKpi.vue_vue_type_script_setup_true_lang-CgCcGGmY.js +79 -0
  32. package/dist/chunks/AdminPage.vue_vue_type_script_setup_true_lang-L7St_zOY.js +15 -0
  33. package/dist/chunks/AdminPaginator.vue_vue_type_script_setup_true_lang-Cv8EEBGP.js +157 -0
  34. package/dist/chunks/AdminRefreshBtn.vue_vue_type_script_setup_true_lang-Bxk5GWOB.js +41 -0
  35. package/dist/chunks/AdminSection.vue_vue_type_script_setup_true_lang-DpjApOU-.js +62 -0
  36. package/dist/chunks/AdminStatistics.vue_vue_type_script_setup_true_lang-DwHeeYCX.js +32 -0
  37. package/dist/chunks/AdminStatusPill.vue_vue_type_script_setup_true_lang-09G3rCxN.js +32 -0
  38. package/dist/chunks/AdminTable.vue_vue_type_script_setup_true_lang-BzAusc-r.js +2007 -0
  39. package/dist/chunks/ClosePopup-iyFHWknU.js +48 -0
  40. package/dist/chunks/PromoCodeEditDialog.vue_vue_type_script_setup_true_lang-NiW-Ky7H.js +639 -0
  41. package/dist/chunks/QBadge-B8LYhEVv.js +43 -0
  42. package/dist/chunks/QBtn-CSVcAwrE.js +770 -0
  43. package/dist/chunks/QCard-g0Hwqx6i.js +30 -0
  44. package/dist/chunks/QCardSection-FvPMZdQ4.js +22 -0
  45. package/dist/chunks/QCheckbox-BwxH7EyE.js +63 -0
  46. package/dist/chunks/QDialog-CcwVEueo.js +331 -0
  47. package/dist/chunks/QIcon-DaxYRLz0.js +195 -0
  48. package/dist/chunks/QInput-SRRCebo8.js +1663 -0
  49. package/dist/chunks/QItem-DunhGoPO.js +127 -0
  50. package/dist/chunks/QList-D3jMUITp.js +37 -0
  51. package/dist/chunks/QMenu-BFP-qtEm.js +831 -0
  52. package/dist/chunks/QSelect-jOvICNCy.js +1885 -0
  53. package/dist/chunks/QSeparator-CrLemO5z.js +60 -0
  54. package/dist/chunks/QSpinner-DblEBRSQ.js +57 -0
  55. package/dist/chunks/QToggle-BBogOutP.js +40 -0
  56. package/dist/chunks/QTooltip-Ch_r2hMZ.js +320 -0
  57. package/dist/chunks/SuperAdminSetupWizard-UO4j4Eyu.js +465 -0
  58. package/dist/chunks/TenantActionConfirmDialog-DU11RlmB.js +201 -0
  59. package/dist/chunks/_plugin-vue_export-helper-1tPrXgE0.js +10 -0
  60. package/dist/chunks/catalog-i18n-tKlkm6-2.js +32 -0
  61. package/dist/chunks/create-Ck-e8kVF.js +42 -0
  62. package/dist/chunks/detached-fullscreen-DuM-R9uv.js +488 -0
  63. package/dist/chunks/focus-manager-Cc4uTjsQ.js +301 -0
  64. package/dist/chunks/format-BIQKj_qk.js +23 -0
  65. package/dist/chunks/is-DNOHJAOK.js +269 -0
  66. package/dist/chunks/plan-area-context-RiY4rHni.js +20 -0
  67. package/dist/chunks/private.use-form-BdJSI6of.js +30 -0
  68. package/dist/chunks/render-DSsuXum_.js +32 -0
  69. package/dist/chunks/symbols-Cy0ehVpr.js +67 -0
  70. package/dist/chunks/touch-B8tpYG34.js +162 -0
  71. package/dist/chunks/use-checkbox-CBtmpkdc.js +221 -0
  72. package/dist/chunks/use-dark-VmDF1SYZ.js +14 -0
  73. package/dist/chunks/use-hydration-PO-eh3w4.js +14 -0
  74. package/dist/chunks/use-prevent-scroll-B9A_pIzH.js +156 -0
  75. package/dist/chunks/use-render-cache-Bj5SbY5v.js +22 -0
  76. package/dist/chunks/use-size-C7KmPm4L.js +23 -0
  77. package/dist/chunks/vm-Dl-TBfKC.js +182 -0
  78. package/dist/client/index.cjs +488 -306
  79. package/dist/client/index.d.cts +107 -7
  80. package/dist/client/index.d.ts +107 -7
  81. package/dist/client/index.js +25 -3
  82. package/dist/index.cjs +1226 -536
  83. package/dist/index.d.cts +5 -5
  84. package/dist/index.d.ts +5 -5
  85. package/dist/index.js +53 -7
  86. package/dist/layouts/AdminLayout.js +1711 -0
  87. package/dist/pages/AdminManifestErrorPage.js +99 -0
  88. package/dist/pages/AuditPage.js +244 -0
  89. package/dist/pages/BundlesPage.js +2883 -0
  90. package/dist/pages/DashboardPage.js +299 -0
  91. package/dist/pages/DiscoveryPage.js +2563 -0
  92. package/dist/pages/EmailHistoryPage.js +509 -0
  93. package/dist/pages/MarketingCatalogPage.js +2095 -0
  94. package/dist/pages/PilotsPage.js +1197 -0
  95. package/dist/pages/PlanReviewPage.js +563 -0
  96. package/dist/pages/PlanVersionEditorPage.js +1626 -0
  97. package/dist/pages/PlansPage.js +6164 -0
  98. package/dist/pages/PlatformEmailPage.js +455 -0
  99. package/dist/pages/PromoCodeDetailPage.js +240 -0
  100. package/dist/pages/PromoCodesPage.js +567 -0
  101. package/dist/pages/SettingsPage.js +216 -0
  102. package/dist/pages/SubscriptionsPage.js +113 -0
  103. package/dist/pages/TenantDetailPage.js +393 -0
  104. package/dist/pages/TenantsPage.js +430 -0
  105. package/dist/pages/UsersPage.js +386 -0
  106. package/dist/pages/index.js +75 -0
  107. package/dist/quasar/index.cjs +388 -297
  108. package/dist/quasar/index.d.cts +13 -3
  109. package/dist/quasar/index.d.ts +13 -3
  110. package/dist/quasar/index.js +10 -6
  111. package/dist/{resource-registry-CrHUvVx6.d.cts → resource-registry-GAxu2kn6.d.ts} +32 -18
  112. package/dist/{resource-registry-Cw_c0F11.d.ts → resource-registry-zfCLvEgx.d.cts} +32 -18
  113. package/dist/testing/admin-pages-suite.cjs +4 -1
  114. package/dist/testing/admin-pages-suite.d.cts +10 -1
  115. package/dist/testing/admin-pages-suite.d.ts +10 -1
  116. package/dist/testing/admin-pages-suite.js +3 -1
  117. package/dist/testing/mount-with-quasar.cjs +65 -0
  118. package/dist/testing/mount-with-quasar.d.cts +7 -0
  119. package/dist/testing/mount-with-quasar.d.ts +7 -0
  120. package/dist/testing/mount-with-quasar.js +63 -0
  121. package/dist/ui/data/AdminKpi.js +4 -0
  122. package/dist/ui/data/AdminPaginator.js +4 -0
  123. package/dist/ui/data/AdminRowActions.js +37 -0
  124. package/dist/ui/data/AdminStatistics.js +4 -0
  125. package/dist/ui/data/AdminStatusPill.js +4 -0
  126. package/dist/ui/data/AdminTable.js +4 -0
  127. package/dist/ui/data/KvBlock.js +24 -0
  128. package/dist/ui/entitlement/FeatureGate.js +25 -0
  129. package/dist/ui/feedback/AdminBanner.js +4 -0
  130. package/dist/ui/feedback/AdminEmptyState.js +4 -0
  131. package/dist/ui/feedback/AdminErrorBanner.js +4 -0
  132. package/dist/ui/feedback/AdminRefreshBtn.js +4 -0
  133. package/dist/ui/overlay/AdminConfirmDialog.js +112 -0
  134. package/dist/ui/overlay/AdminDialog.js +4 -0
  135. package/dist/ui/overlay/AdminFormDialog.js +4 -0
  136. package/dist/ui/overlay/MfaPromptDialog.js +131 -0
  137. package/dist/ui/page/AdminAccordion.js +4 -0
  138. package/dist/ui/page/AdminBody.js +4 -0
  139. package/dist/ui/page/AdminField.js +4 -0
  140. package/dist/ui/page/AdminFieldGrid.js +4 -0
  141. package/dist/ui/page/AdminFilters.js +4 -0
  142. package/dist/ui/page/AdminHero.js +4 -0
  143. package/dist/ui/page/AdminPage.js +4 -0
  144. package/dist/ui/page/AdminSection.js +4 -0
  145. package/dist/ui/page/AdminToolbar.js +35 -0
  146. package/dist/ui/page/LocaleSwitcher.js +90 -0
  147. package/dist/ui/page/ThemeSwitcher.js +95 -0
  148. package/dist/ui/page/WizardStepper.js +55 -0
  149. package/dist/vue/index.cjs +1135 -524
  150. package/dist/vue/index.d.cts +520 -44
  151. package/dist/vue/index.d.ts +520 -44
  152. package/dist/vue/index.js +30 -6
  153. package/package.json +30 -15
  154. package/src/auth/SuperAdminLoginPage.vue +16 -16
  155. package/src/auth/SuperAdminSetupWizard.vue +33 -28
  156. package/src/client/admin-resource-client.ts +23 -8
  157. package/src/client/billing-area.ts +14 -0
  158. package/src/client/brand-bridge.ts +98 -0
  159. package/src/client/http/axios-http-client.ts +4 -3
  160. package/src/client/http-json.ts +16 -3
  161. package/src/client/i18n/messages/audit.ts +1 -0
  162. package/src/client/i18n/messages/bundles.ts +17 -4
  163. package/src/client/i18n/messages/common.ts +1 -0
  164. package/src/client/i18n/messages/dashboard.ts +1 -0
  165. package/src/client/i18n/messages/discovery.ts +10 -19
  166. package/src/client/i18n/messages/email.ts +1 -0
  167. package/src/client/i18n/messages/errors.ts +1 -0
  168. package/src/client/i18n/messages/marketing.ts +7 -2
  169. package/src/client/i18n/messages/nav.ts +3 -0
  170. package/src/client/i18n/messages/pilots.ts +1 -0
  171. package/src/client/i18n/messages/plan-detail.ts +1 -0
  172. package/src/client/i18n/messages/plan-editor.ts +1 -0
  173. package/src/client/i18n/messages/plan-versions.ts +3 -4
  174. package/src/client/i18n/messages/plans.ts +9 -4
  175. package/src/client/i18n/messages/promos.ts +3 -0
  176. package/src/client/i18n/messages/settings.ts +75 -0
  177. package/src/client/i18n/messages/shell.ts +1 -0
  178. package/src/client/i18n/messages/tenants.ts +1 -0
  179. package/src/client/i18n/messages/users.ts +1 -0
  180. package/src/client/i18n/messages.ts +3 -0
  181. package/src/client/index.ts +10 -0
  182. package/src/client/mfa-header.ts +14 -0
  183. package/src/client/nav-builder.ts +7 -4
  184. package/src/client/reorder-priorities.ts +76 -0
  185. package/src/client/resources/bundles.resource.ts +24 -38
  186. package/src/client/resources/catalog.resource.ts +91 -113
  187. package/src/client/resources/define-resource.ts +2 -75
  188. package/src/client/resources/index.ts +3 -0
  189. package/src/client/resources/marketing.resource.ts +77 -80
  190. package/src/client/resources/pilots.resource.ts +1 -11
  191. package/src/client/resources/plans.resource.ts +47 -64
  192. package/src/client/resources/platform-email.resource.ts +1 -11
  193. package/src/client/resources/promotions.resource.ts +18 -25
  194. package/src/client/resources/settings.resource.ts +68 -0
  195. package/src/client/resources/tenants.resource.ts +10 -4
  196. package/src/client/resources/users.resource.ts +3 -2
  197. package/src/client/settings-view.ts +50 -0
  198. package/src/client/version-change-fields.ts +17 -0
  199. package/src/features/bundle/BundleVersionInlineEditor.vue +112 -155
  200. package/src/features/bundle/BundleVersionPublishDialog.vue +34 -16
  201. package/src/features/bundle/BundleVersionStrip.vue +25 -31
  202. package/src/features/bundle/VersionDiffPreview.vue +21 -15
  203. package/src/features/bundle/internal/BundleCreatePanel.vue +65 -119
  204. package/src/features/bundle/internal/BundleFeaturesEditor.vue +18 -31
  205. package/src/features/bundle/internal/BundlePlanCompatPicker.vue +23 -29
  206. package/src/features/bundle/internal/BundleQuotasEditor.vue +20 -41
  207. package/src/features/bundle/internal/BundleStatusBanner.vue +16 -70
  208. package/src/features/marketing/MarketingPromotionsTab.vue +155 -122
  209. package/src/features/plan/PlanCreateDialog.vue +49 -129
  210. package/src/features/plan/PlanDetail.vue +57 -76
  211. package/src/features/plan/PlanList.vue +81 -156
  212. package/src/features/plan/PlanMatrix.vue +89 -158
  213. package/src/features/plan/PlanReview.vue +62 -80
  214. package/src/features/plan/PlanVersionEditor.vue +134 -238
  215. package/src/features/plan/internal/PlanCatalogPreview.vue +22 -68
  216. package/src/features/plan/internal/PlanComponentPool.vue +18 -88
  217. package/src/features/plan/internal/PlanTitleEdit.vue +12 -9
  218. package/src/features/plan/internal/PlanVersionBasket.vue +65 -89
  219. package/src/features/plan/internal/PlanVersionEditorHeader.vue +16 -20
  220. package/src/features/plan/internal/PlanVersionsPanel.vue +29 -75
  221. package/src/features/tenant/TenantActionConfirmDialog.vue +4 -4
  222. package/src/index.ts +9 -0
  223. package/src/internal/bundles-page/BundleAccordionList.vue +32 -2
  224. package/src/internal/bundles-page/BundleDetailPanel.vue +37 -21
  225. package/src/internal/bundles-page/BundlesToolbar.vue +9 -5
  226. package/src/internal/dialogs/PilotCreateDialog.vue +65 -104
  227. package/src/internal/dialogs/PilotEditDialog.vue +22 -23
  228. package/src/internal/dialogs/PromoCodeCreateDialog.vue +27 -23
  229. package/src/internal/dialogs/PromoCodeDialogFields.vue +203 -252
  230. package/src/internal/dialogs/PromoCodeEditDialog.vue +52 -48
  231. package/src/internal/dialogs/pilot-dialog.css +16 -111
  232. package/src/internal/discovery-page/CatalogEntryTransPanel.vue +18 -18
  233. package/src/internal/discovery-page/DiscoveryCapList.vue +20 -20
  234. package/src/internal/discovery-page/DiscoveryFeatureCard.vue +20 -20
  235. package/src/internal/discovery-page/DiscoveryQuotaCard.vue +10 -10
  236. package/src/internal/discovery-page/DiscoveryStatusControl.vue +1 -1
  237. package/src/internal/marketing-catalog-page/MarketingCatalogAdmin.vue +660 -0
  238. package/src/internal/{marketing-catalog → marketing-catalog-page}/MarketingCatalogHeader.vue +21 -16
  239. package/src/internal/{marketing-catalog → marketing-catalog-page}/MarketingCatalogPreview.vue +26 -13
  240. package/src/internal/{marketing-catalog → marketing-catalog-page}/MarketingCatalogToolbar.vue +14 -10
  241. package/src/internal/plan-versions/PlanDiffCard.vue +15 -15
  242. package/src/internal/plan-versions/PlanVersionsDiff.vue +11 -11
  243. package/src/internal/plan-versions/PlanVersionsTimeline.vue +35 -31
  244. package/src/internal/plans-page/PlanBundleOverview.vue +8 -8
  245. package/src/internal/plans-page/PlanPublishDialog.vue +2 -2
  246. package/src/internal/tenant-detail/TenantUsage.vue +3 -3
  247. package/src/internal/tenant-detail/types.ts +2 -2
  248. package/src/layouts/AdminLayout.vue +22 -22
  249. package/src/pages/AdminManifestErrorPage.vue +7 -7
  250. package/src/pages/AuditPage.vue +2 -2
  251. package/src/pages/BundlesPage.vue +81 -89
  252. package/src/pages/DashboardPage.vue +106 -97
  253. package/src/pages/DiscoveryPage.vue +22 -28
  254. package/src/pages/EmailHistoryPage.vue +26 -34
  255. package/src/pages/MarketingCatalogPage.vue +289 -281
  256. package/src/pages/PilotsPage.vue +22 -35
  257. package/src/pages/PlanVersionEditorPage.vue +1 -1
  258. package/src/pages/PlansPage.vue +181 -107
  259. package/src/pages/PlatformEmailPage.vue +33 -41
  260. package/src/pages/PromoCodeDetailPage.vue +12 -18
  261. package/src/pages/PromoCodesPage.vue +36 -14
  262. package/src/pages/SettingsPage.vue +226 -0
  263. package/src/pages/TenantDetailPage.vue +28 -53
  264. package/src/pages/TenantsPage.vue +7 -7
  265. package/src/pages/UsersPage.vue +7 -20
  266. package/src/pages/index.ts +3 -1
  267. package/src/quasar/create-super-admin-app.ts +13 -2
  268. package/src/quasar/dark-bridge.ts +8 -4
  269. package/src/quasar/index.ts +11 -0
  270. package/src/testing/admin-pages-suite.ts +11 -1
  271. package/src/testing/mount-with-quasar.ts +73 -0
  272. package/src/ui/data/AdminPaginator.vue +30 -20
  273. package/src/ui/data/KvBlock.vue +4 -4
  274. package/src/ui/entitlement/FeatureGate.vue +2 -2
  275. package/src/ui/feedback/AdminRefreshBtn.vue +10 -7
  276. package/src/ui/overlay/MfaPromptDialog.vue +5 -6
  277. package/src/ui/page/AdminAccordion.vue +27 -10
  278. package/src/ui/page/WizardStepper.vue +7 -18
  279. package/src/ui/theme/base.css +31 -0
  280. package/src/ui/theme/components/accordion.css +9 -9
  281. package/src/ui/theme/components/button.css +10 -68
  282. package/src/ui/theme/components/card.css +0 -8
  283. package/src/ui/theme/components/paginator.css +14 -28
  284. package/src/ui/theme/tokens.semantic.dark.css +13 -0
  285. package/src/ui/theme/tokens.semantic.light.css +39 -0
  286. package/src/vue/index.ts +9 -0
  287. package/src/vue/platform-loaders.ts +1 -3
  288. package/src/vue/resource-registry.ts +0 -8
  289. package/src/vue/super-admin-context.ts +14 -15
  290. package/src/vue/use-applied-settings.ts +79 -0
  291. package/src/vue/use-bulk-publish.ts +2 -5
  292. package/src/vue/use-bundles.ts +6 -10
  293. package/src/vue/use-catalog-entries.ts +9 -16
  294. package/src/vue/use-dialog.ts +221 -0
  295. package/src/vue/use-marketing-projections.ts +5 -6
  296. package/src/vue/use-mfa-prompt.ts +61 -11
  297. package/src/vue/use-plans.ts +28 -21
  298. package/src/vue/use-promotions.ts +1 -7
  299. package/src/vue/use-row-reorder.ts +109 -0
  300. package/src/vue/use-sa-theme.ts +31 -0
  301. package/src/vue/use-steps.ts +109 -0
  302. package/src/vue/use-subscription-draft.ts +63 -60
  303. package/src/vue/use-tenant-billing-details.ts +119 -0
  304. package/src/vue/use-tenant-billing.ts +250 -33
  305. package/src/vue/use-tenant-payment-method.ts +112 -0
  306. package/src/vue/use-tenant-subscription-bundles.ts +8 -0
  307. package/src/internal/marketing-catalog/MarketingCatalogAdmin.vue +0 -553
  308. package/src/internal/plans-page/PlansPageToast.vue +0 -69
  309. /package/src/internal/{marketing-catalog → marketing-catalog-page}/types.ts +0 -0
@@ -0,0 +1,563 @@
1
+ import { defineComponent, ref, computed, openBlock, createElementBlock, createVNode, unref, withCtx, createTextVNode, toDisplayString, createElementVNode, createCommentVNode, Fragment, renderList, normalizeClass, createBlock } from "vue";
2
+ import { useRouter } from "vue-router";
3
+ import { Q as QBtn } from "../chunks/QBtn-CSVcAwrE.js";
4
+ import { Q as QIcon } from "../chunks/QIcon-DaxYRLz0.js";
5
+ import { Q as QCheckbox } from "../chunks/QCheckbox-BwxH7EyE.js";
6
+ import { useSaMessages, useSuperAdminI18n, formatMessage, formatCurrency, usePlanWizard } from "@saasicat/ui-vue";
7
+ import { _ as _sfc_main$3 } from "../chunks/AdminBody.vue_vue_type_script_setup_true_lang-DxcVRzXE.js";
8
+ import { _ as _sfc_main$2 } from "../chunks/AdminHero.vue_vue_type_script_setup_true_lang-CoaRxXLF.js";
9
+ import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
10
+ import { _ as _sfc_main$4 } from "../chunks/AdminEmptyState.vue_vue_type_script_setup_true_lang-jaYkgNbE.js";
11
+ import { u as usePlanArea } from "../chunks/plan-area-context-RiY4rHni.js";
12
+ const _hoisted_1 = { class: "pr" };
13
+ const _hoisted_2 = { class: "pr-mono" };
14
+ const _hoisted_3 = {
15
+ key: 0,
16
+ class: "pr-banner"
17
+ };
18
+ const _hoisted_4 = { class: "pr-grid" };
19
+ const _hoisted_5 = { class: "pr-col" };
20
+ const _hoisted_6 = { class: "pr-card" };
21
+ const _hoisted_7 = { class: "pr-card-title" };
22
+ const _hoisted_8 = { class: "pr-row" };
23
+ const _hoisted_9 = { class: "pr-label" };
24
+ const _hoisted_10 = { class: "pr-val pr-mono" };
25
+ const _hoisted_11 = { class: "pr-row" };
26
+ const _hoisted_12 = { class: "pr-label" };
27
+ const _hoisted_13 = { class: "pr-val" };
28
+ const _hoisted_14 = { class: "pr-row" };
29
+ const _hoisted_15 = { class: "pr-label" };
30
+ const _hoisted_16 = { class: "pr-val" };
31
+ const _hoisted_17 = {
32
+ key: 1,
33
+ class: "pr-missing"
34
+ };
35
+ const _hoisted_18 = { class: "pr-card" };
36
+ const _hoisted_19 = { class: "pr-card-title" };
37
+ const _hoisted_20 = { class: "pr-row" };
38
+ const _hoisted_21 = { class: "pr-label" };
39
+ const _hoisted_22 = { class: "pr-val" };
40
+ const _hoisted_23 = {
41
+ key: 1,
42
+ class: "pr-missing"
43
+ };
44
+ const _hoisted_24 = { class: "pr-row" };
45
+ const _hoisted_25 = { class: "pr-label" };
46
+ const _hoisted_26 = { class: "pr-val" };
47
+ const _hoisted_27 = {
48
+ key: 1,
49
+ class: "pr-inf"
50
+ };
51
+ const _hoisted_28 = { class: "pr-row" };
52
+ const _hoisted_29 = { class: "pr-label" };
53
+ const _hoisted_30 = { class: "pr-val" };
54
+ const _hoisted_31 = {
55
+ key: 1,
56
+ class: "pr-missing"
57
+ };
58
+ const _hoisted_32 = { class: "pr-row" };
59
+ const _hoisted_33 = { class: "pr-label" };
60
+ const _hoisted_34 = { class: "pr-val" };
61
+ const _hoisted_35 = { class: "pr-row" };
62
+ const _hoisted_36 = { class: "pr-label" };
63
+ const _hoisted_37 = { class: "pr-val" };
64
+ const _hoisted_38 = {
65
+ key: 0,
66
+ class: "pr-chip pr-chip--live"
67
+ };
68
+ const _hoisted_39 = {
69
+ key: 1,
70
+ class: "pr-chip pr-chip--muted"
71
+ };
72
+ const _hoisted_40 = { class: "pr-card" };
73
+ const _hoisted_41 = { class: "pr-card-title" };
74
+ const _hoisted_42 = { class: "pr-components" };
75
+ const _hoisted_43 = { class: "pr-comp-col" };
76
+ const _hoisted_44 = { class: "pr-comp-head pr-comp-head--quota" };
77
+ const _hoisted_45 = {
78
+ key: 0,
79
+ class: "pr-comp-empty"
80
+ };
81
+ const _hoisted_46 = { class: "pr-comp-col" };
82
+ const _hoisted_47 = { class: "pr-comp-head pr-comp-head--feature" };
83
+ const _hoisted_48 = {
84
+ key: 0,
85
+ class: "pr-comp-empty"
86
+ };
87
+ const _hoisted_49 = { class: "pr-comp-col" };
88
+ const _hoisted_50 = { class: "pr-comp-head pr-comp-head--bundle" };
89
+ const _hoisted_51 = {
90
+ key: 0,
91
+ class: "pr-comp-empty"
92
+ };
93
+ const _hoisted_52 = { class: "pr-col" };
94
+ const _hoisted_53 = { class: "pr-card" };
95
+ const _hoisted_54 = { class: "pr-card-title" };
96
+ const _hoisted_55 = { class: "pr-card-hint" };
97
+ const _hoisted_56 = {
98
+ key: 0,
99
+ class: "pr-note"
100
+ };
101
+ const _hoisted_57 = {
102
+ key: 1,
103
+ class: "pr-note pr-note--missing"
104
+ };
105
+ const _hoisted_58 = { class: "pr-card" };
106
+ const _hoisted_59 = { class: "pr-card-title" };
107
+ const _hoisted_60 = { class: "pr-checks" };
108
+ const _hoisted_61 = { class: "pr-check-mark" };
109
+ const _hoisted_62 = {
110
+ key: 0,
111
+ class: "pr-card pr-card--regress"
112
+ };
113
+ const _hoisted_63 = { class: "pr-card-title" };
114
+ const _hoisted_64 = { class: "pr-card-hint" };
115
+ const _hoisted_65 = { class: "pr-toggle" };
116
+ const _hoisted_66 = { class: "pr-card" };
117
+ const _hoisted_67 = { class: "pr-card-title" };
118
+ const _hoisted_68 = { class: "pr-card-hint" };
119
+ const _hoisted_69 = { class: "pr-toggle" };
120
+ const _hoisted_70 = { class: "pr-card pr-card--impact" };
121
+ const _hoisted_71 = { class: "pr-card-title" };
122
+ const _hoisted_72 = { class: "pr-impact" };
123
+ const _hoisted_73 = { class: "pr-impact-num" };
124
+ const _hoisted_74 = { class: "pr-impact-text" };
125
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
126
+ __name: "PlanReview",
127
+ props: {
128
+ plan: {},
129
+ version: {},
130
+ predecessor: { default: null },
131
+ availableQuotas: { default: () => [] },
132
+ availableBundles: { default: () => [] },
133
+ featureRegistry: { default: () => ({}) },
134
+ tenantImpactCount: { default: 0 },
135
+ saving: { type: Boolean, default: false },
136
+ publishing: { type: Boolean, default: false },
137
+ publishError: { default: null }
138
+ },
139
+ emits: ["back", "saveAndExit", "publish"],
140
+ setup(__props, { emit: __emit }) {
141
+ const props = __props;
142
+ const emit = __emit;
143
+ const msg = useSaMessages("plans");
144
+ const { locale } = useSuperAdminI18n();
145
+ const common = useSaMessages("common");
146
+ const forceRegressive = ref(false);
147
+ const allowZeroPrice = ref(false);
148
+ const publishLabel = computed(
149
+ () => formatMessage(msg.value.review.publishVersion, { version: props.version.version })
150
+ );
151
+ const pricingCardTitle = computed(
152
+ () => formatMessage(msg.value.review.cardPricing, { version: props.version.version })
153
+ );
154
+ function quotasOf(v) {
155
+ if (v.quotas && Object.keys(v.quotas).length > 0) return v.quotas;
156
+ const legacy = {};
157
+ if (typeof v.maxUsers === "number") legacy.users = v.maxUsers;
158
+ if (typeof v.maxVehicles === "number") legacy.vehicles = v.maxVehicles;
159
+ if (typeof v.maxStorageGb === "number") legacy.storageGb = v.maxStorageGb;
160
+ return legacy;
161
+ }
162
+ const quotaList = computed(
163
+ () => Object.entries(quotasOf(props.version)).sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => {
164
+ const def = props.availableQuotas.find((q) => q.quotaKey === key);
165
+ return { key, value, label: def?.label || key, unit: def?.unit || "" };
166
+ })
167
+ );
168
+ const featureList = computed(
169
+ () => [...props.version.features].sort().map((key) => ({
170
+ key,
171
+ label: props.featureRegistry[key]?.label ?? key
172
+ }))
173
+ );
174
+ const bundleList = computed(
175
+ () => [...props.version.bundles ?? []].sort().map((key) => {
176
+ const def = props.availableBundles.find((b) => b.bundleKey === key);
177
+ return { key, label: def?.label || key };
178
+ })
179
+ );
180
+ const componentTotal = computed(
181
+ () => quotaList.value.length + featureList.value.length + bundleList.value.length
182
+ );
183
+ const componentsCardTitle = computed(
184
+ () => formatMessage(msg.value.review.cardComponents, { total: componentTotal.value })
185
+ );
186
+ const quotaSectionTitle = computed(
187
+ () => formatMessage(msg.value.review.componentQuotas, { count: quotaList.value.length })
188
+ );
189
+ const featureSectionTitle = computed(
190
+ () => formatMessage(msg.value.review.componentFeatures, { count: featureList.value.length })
191
+ );
192
+ const bundleSectionTitle = computed(
193
+ () => formatMessage(msg.value.review.componentBundles, { count: bundleList.value.length })
194
+ );
195
+ const impactText = computed(
196
+ () => props.tenantImpactCount === 0 ? msg.value.review.impactNone : formatMessage(msg.value.review.impactSome, {
197
+ count: props.tenantImpactCount,
198
+ version: props.version.version
199
+ })
200
+ );
201
+ const hasMonthly = computed(() => {
202
+ const n = Number(props.version.monthlyNet);
203
+ return props.version.monthlyNet !== "" && Number.isFinite(n) && n >= 0;
204
+ });
205
+ const validFromAfterPredecessor = computed(() => {
206
+ const prev = props.predecessor;
207
+ if (!prev?.validFrom || !props.version.validFrom) return true;
208
+ return props.version.validFrom.slice(0, 10) > prev.validFrom.slice(0, 10);
209
+ });
210
+ function formatMoney(raw) {
211
+ const num = typeof raw === "string" ? Number(raw) : raw;
212
+ if (!Number.isFinite(num)) return String(raw);
213
+ if (num === 0) return msg.value.review.priceFree;
214
+ return formatCurrency(num, locale.value);
215
+ }
216
+ const checks = computed(() => [
217
+ { id: "key", label: msg.value.review.checkPlanKey, ok: Boolean(props.plan.planKey) },
218
+ { id: "label", label: msg.value.review.checkDisplayName, ok: Boolean(props.plan.label) },
219
+ {
220
+ id: "quota",
221
+ label: msg.value.review.checkQuota,
222
+ ok: quotaList.value.length > 0
223
+ },
224
+ {
225
+ id: "feature",
226
+ label: msg.value.review.checkFeature,
227
+ ok: featureList.value.length > 0
228
+ },
229
+ {
230
+ id: "validFrom",
231
+ label: msg.value.review.checkValidFrom,
232
+ ok: Boolean(props.version.validFrom)
233
+ },
234
+ {
235
+ id: "validFromOrder",
236
+ label: props.predecessor ? formatMessage(msg.value.review.checkValidFromAfterPredecessor, {
237
+ version: props.predecessor.version
238
+ }) : msg.value.review.checkValidFromAfterPrevious,
239
+ ok: validFromAfterPredecessor.value
240
+ },
241
+ {
242
+ id: "changeNote",
243
+ label: msg.value.review.checkChangeNote,
244
+ ok: Boolean(props.version.changeNote && props.version.changeNote.trim())
245
+ }
246
+ ]);
247
+ const canPublish = computed(() => checks.value.every((c) => c.ok));
248
+ function onPublish() {
249
+ if (!canPublish.value || props.publishing || props.saving) return;
250
+ emit("publish", {
251
+ forceRegressive: forceRegressive.value,
252
+ allowZeroPrice: allowZeroPrice.value
253
+ });
254
+ }
255
+ return (_ctx, _cache) => {
256
+ return openBlock(), createElementBlock("div", _hoisted_1, [
257
+ createVNode(_sfc_main$2, {
258
+ title: unref(msg).review.title
259
+ }, {
260
+ subtitle: withCtx(() => [
261
+ createTextVNode(toDisplayString(unref(msg).review.subtitleLead) + " ", 1),
262
+ createElementVNode("code", _hoisted_2, toDisplayString(__props.plan.planKey) + "@v" + toDisplayString(__props.version.version), 1),
263
+ createTextVNode(" " + toDisplayString(unref(msg).review.subtitleTail), 1)
264
+ ]),
265
+ actions: withCtx(() => [
266
+ createVNode(QBtn, {
267
+ flat: "",
268
+ "no-caps": "",
269
+ icon: "arrow_back",
270
+ label: unref(common).back,
271
+ disable: __props.publishing || __props.saving,
272
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("back"))
273
+ }, null, 8, ["label", "disable"]),
274
+ createVNode(QBtn, {
275
+ flat: "",
276
+ "no-caps": "",
277
+ label: __props.saving ? unref(msg).review.saving : unref(msg).review.saveAsDraft,
278
+ disable: __props.publishing || __props.saving,
279
+ onClick: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("saveAndExit"))
280
+ }, null, 8, ["label", "disable"]),
281
+ createVNode(QBtn, {
282
+ unelevated: "",
283
+ "no-caps": "",
284
+ color: "primary",
285
+ icon: "bolt",
286
+ label: __props.publishing ? unref(msg).review.publishing : publishLabel.value,
287
+ disable: !canPublish.value || __props.publishing || __props.saving,
288
+ title: canPublish.value ? void 0 : unref(msg).review.publishBlocked,
289
+ onClick: onPublish
290
+ }, null, 8, ["label", "disable", "title"])
291
+ ]),
292
+ _: 1
293
+ }, 8, ["title"]),
294
+ createVNode(_sfc_main$3, null, {
295
+ default: withCtx(() => [
296
+ __props.publishError ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(__props.publishError), 1)) : createCommentVNode("", true),
297
+ createElementVNode("div", _hoisted_4, [
298
+ createElementVNode("div", _hoisted_5, [
299
+ createElementVNode("div", _hoisted_6, [
300
+ createElementVNode("h3", _hoisted_7, toDisplayString(unref(msg).review.cardMasterData), 1),
301
+ createElementVNode("div", _hoisted_8, [
302
+ createElementVNode("div", _hoisted_9, toDisplayString(unref(msg).review.labelPlanKey), 1),
303
+ createElementVNode("div", _hoisted_10, toDisplayString(__props.plan.planKey), 1)
304
+ ]),
305
+ createElementVNode("div", _hoisted_11, [
306
+ createElementVNode("div", _hoisted_12, toDisplayString(unref(msg).review.labelDisplayName), 1),
307
+ createElementVNode("div", _hoisted_13, toDisplayString(__props.plan.label), 1)
308
+ ]),
309
+ createElementVNode("div", _hoisted_14, [
310
+ createElementVNode("div", _hoisted_15, toDisplayString(unref(common).description), 1),
311
+ createElementVNode("div", _hoisted_16, [
312
+ __props.plan.description ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
313
+ createTextVNode(toDisplayString(__props.plan.description), 1)
314
+ ], 64)) : (openBlock(), createElementBlock("i", _hoisted_17, toDisplayString(unref(msg).review.missing), 1))
315
+ ])
316
+ ])
317
+ ]),
318
+ createElementVNode("div", _hoisted_18, [
319
+ createElementVNode("h3", _hoisted_19, toDisplayString(pricingCardTitle.value), 1),
320
+ createElementVNode("div", _hoisted_20, [
321
+ createElementVNode("div", _hoisted_21, toDisplayString(unref(msg).review.labelValidFrom), 1),
322
+ createElementVNode("div", _hoisted_22, [
323
+ __props.version.validFrom ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
324
+ createTextVNode(toDisplayString(__props.version.validFrom.slice(0, 10)), 1)
325
+ ], 64)) : (openBlock(), createElementBlock("i", _hoisted_23, toDisplayString(unref(msg).review.missingRequiredOnPublish), 1))
326
+ ])
327
+ ]),
328
+ createElementVNode("div", _hoisted_24, [
329
+ createElementVNode("div", _hoisted_25, toDisplayString(unref(msg).review.labelValidUntil), 1),
330
+ createElementVNode("div", _hoisted_26, [
331
+ __props.version.validUntil ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
332
+ createTextVNode(toDisplayString(__props.version.validUntil.slice(0, 10)), 1)
333
+ ], 64)) : (openBlock(), createElementBlock("span", _hoisted_27, toDisplayString(unref(msg).review.unlimited), 1))
334
+ ])
335
+ ]),
336
+ createElementVNode("div", _hoisted_28, [
337
+ createElementVNode("div", _hoisted_29, toDisplayString(unref(msg).review.labelMonthlyPrice), 1),
338
+ createElementVNode("div", _hoisted_30, [
339
+ hasMonthly.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
340
+ createTextVNode(toDisplayString(formatMoney(__props.version.monthlyNet)), 1)
341
+ ], 64)) : (openBlock(), createElementBlock("i", _hoisted_31, toDisplayString(unref(msg).review.missing), 1))
342
+ ])
343
+ ]),
344
+ createElementVNode("div", _hoisted_32, [
345
+ createElementVNode("div", _hoisted_33, toDisplayString(unref(msg).review.labelYearlyPrice), 1),
346
+ createElementVNode("div", _hoisted_34, toDisplayString(formatMoney(__props.version.yearlyNet)), 1)
347
+ ]),
348
+ createElementVNode("div", _hoisted_35, [
349
+ createElementVNode("div", _hoisted_36, toDisplayString(unref(msg).review.labelPublicCatalog), 1),
350
+ createElementVNode("div", _hoisted_37, [
351
+ __props.version.marketed ? (openBlock(), createElementBlock("span", _hoisted_38, toDisplayString(unref(msg).review.visibleInCatalog), 1)) : (openBlock(), createElementBlock("span", _hoisted_39, toDisplayString(unref(msg).review.hiddenFromCatalog), 1))
352
+ ])
353
+ ])
354
+ ]),
355
+ createElementVNode("div", _hoisted_40, [
356
+ createElementVNode("h3", _hoisted_41, toDisplayString(componentsCardTitle.value), 1),
357
+ createElementVNode("div", _hoisted_42, [
358
+ createElementVNode("div", _hoisted_43, [
359
+ createElementVNode("div", _hoisted_44, toDisplayString(quotaSectionTitle.value), 1),
360
+ (openBlock(true), createElementBlock(Fragment, null, renderList(quotaList.value, (q) => {
361
+ return openBlock(), createElementBlock("div", {
362
+ key: q.key,
363
+ class: "pr-comp-item"
364
+ }, [
365
+ createElementVNode("span", null, toDisplayString(q.label), 1),
366
+ createElementVNode("b", null, toDisplayString(q.value) + toDisplayString(q.unit ? " " + q.unit : ""), 1)
367
+ ]);
368
+ }), 128)),
369
+ quotaList.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_45, toDisplayString(unref(msg).review.componentEmpty), 1)) : createCommentVNode("", true)
370
+ ]),
371
+ createElementVNode("div", _hoisted_46, [
372
+ createElementVNode("div", _hoisted_47, toDisplayString(featureSectionTitle.value), 1),
373
+ (openBlock(true), createElementBlock(Fragment, null, renderList(featureList.value, (f) => {
374
+ return openBlock(), createElementBlock("div", {
375
+ key: f.key,
376
+ class: "pr-comp-item"
377
+ }, [
378
+ createElementVNode("span", null, toDisplayString(f.label), 1)
379
+ ]);
380
+ }), 128)),
381
+ featureList.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_48, toDisplayString(unref(msg).review.componentEmpty), 1)) : createCommentVNode("", true)
382
+ ]),
383
+ createElementVNode("div", _hoisted_49, [
384
+ createElementVNode("div", _hoisted_50, toDisplayString(bundleSectionTitle.value), 1),
385
+ (openBlock(true), createElementBlock(Fragment, null, renderList(bundleList.value, (b) => {
386
+ return openBlock(), createElementBlock("div", {
387
+ key: b.key,
388
+ class: "pr-comp-item"
389
+ }, [
390
+ createElementVNode("span", null, toDisplayString(b.label), 1)
391
+ ]);
392
+ }), 128)),
393
+ bundleList.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_51, toDisplayString(unref(msg).review.componentEmpty), 1)) : createCommentVNode("", true)
394
+ ])
395
+ ])
396
+ ])
397
+ ]),
398
+ createElementVNode("div", _hoisted_52, [
399
+ createElementVNode("div", _hoisted_53, [
400
+ createElementVNode("h3", _hoisted_54, [
401
+ createTextVNode(toDisplayString(unref(msg).review.cardChangeNote) + " ", 1),
402
+ _cache[4] || (_cache[4] = createElementVNode("span", { class: "pr-req" }, "*", -1))
403
+ ]),
404
+ createElementVNode("p", _hoisted_55, toDisplayString(unref(msg).review.changeNoteHint), 1),
405
+ __props.version.changeNote ? (openBlock(), createElementBlock("div", _hoisted_56, toDisplayString(__props.version.changeNote), 1)) : (openBlock(), createElementBlock("div", _hoisted_57, toDisplayString(unref(msg).review.changeNoteMissing), 1))
406
+ ]),
407
+ createElementVNode("div", _hoisted_58, [
408
+ createElementVNode("h3", _hoisted_59, toDisplayString(unref(msg).review.cardChecklist), 1),
409
+ createElementVNode("div", _hoisted_60, [
410
+ (openBlock(true), createElementBlock(Fragment, null, renderList(checks.value, (c) => {
411
+ return openBlock(), createElementBlock("div", {
412
+ key: c.id,
413
+ class: normalizeClass(["pr-check", c.ok ? "pr-check--ok" : "pr-check--warn"])
414
+ }, [
415
+ createElementVNode("span", _hoisted_61, [
416
+ c.ok ? (openBlock(), createBlock(QIcon, {
417
+ key: 0,
418
+ name: "check",
419
+ size: "11px"
420
+ })) : (openBlock(), createBlock(QIcon, {
421
+ key: 1,
422
+ name: "warning",
423
+ size: "11px"
424
+ }))
425
+ ]),
426
+ createElementVNode("span", null, toDisplayString(c.label), 1)
427
+ ], 2);
428
+ }), 128))
429
+ ])
430
+ ]),
431
+ __props.predecessor ? (openBlock(), createElementBlock("div", _hoisted_62, [
432
+ createElementVNode("h3", _hoisted_63, toDisplayString(unref(msg).review.cardRegression), 1),
433
+ createElementVNode("p", _hoisted_64, toDisplayString(unref(msg).review.regressionHint), 1),
434
+ createElementVNode("label", _hoisted_65, [
435
+ createVNode(QCheckbox, {
436
+ modelValue: forceRegressive.value,
437
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => forceRegressive.value = $event),
438
+ dense: "",
439
+ label: unref(msg).review.forceRegressive
440
+ }, null, 8, ["modelValue", "label"])
441
+ ])
442
+ ])) : createCommentVNode("", true),
443
+ createElementVNode("div", _hoisted_66, [
444
+ createElementVNode("h3", _hoisted_67, toDisplayString(unref(msg).review.cardZeroPrice), 1),
445
+ createElementVNode("p", _hoisted_68, toDisplayString(unref(msg).review.zeroPriceHint), 1),
446
+ createElementVNode("label", _hoisted_69, [
447
+ createVNode(QCheckbox, {
448
+ modelValue: allowZeroPrice.value,
449
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => allowZeroPrice.value = $event),
450
+ dense: "",
451
+ label: unref(msg).review.allowZeroPrice
452
+ }, null, 8, ["modelValue", "label"])
453
+ ])
454
+ ]),
455
+ createElementVNode("div", _hoisted_70, [
456
+ createElementVNode("h3", _hoisted_71, toDisplayString(unref(msg).review.cardTenantImpact), 1),
457
+ createElementVNode("div", _hoisted_72, [
458
+ createElementVNode("div", _hoisted_73, toDisplayString(__props.tenantImpactCount), 1),
459
+ createElementVNode("div", _hoisted_74, toDisplayString(impactText.value), 1)
460
+ ])
461
+ ])
462
+ ])
463
+ ])
464
+ ]),
465
+ _: 1
466
+ })
467
+ ]);
468
+ };
469
+ }
470
+ });
471
+ const PlanReview = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-6dd38900"]]);
472
+ const _sfc_main = /* @__PURE__ */ defineComponent({
473
+ __name: "PlanReviewPage",
474
+ setup(__props) {
475
+ const router = useRouter();
476
+ const area = usePlanArea();
477
+ const wizard = usePlanWizard();
478
+ const msg = useSaMessages("plans");
479
+ const reviewVersion = computed(() => {
480
+ const form = wizard.editing.value?.initialForm;
481
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
482
+ return {
483
+ id: wizard.editing.value?.editingId ?? "",
484
+ planId: area.plan.value?.planKey ?? "",
485
+ version: form?.version ?? 1,
486
+ baseVersionId: null,
487
+ features: [...form?.features ?? []],
488
+ bundles: [...form?.bundles ?? []],
489
+ quotas: { ...form?.quotas ?? {} },
490
+ monthlyNet: form?.monthlyNet ?? "0.00",
491
+ yearlyNet: form?.yearlyNet ?? "0.00",
492
+ marketed: form?.marketed ?? true,
493
+ publishedAt: null,
494
+ supersededAt: null,
495
+ publishedChanges: null,
496
+ changeNote: form?.changeNote ?? "",
497
+ nonRegressive: true,
498
+ validFrom: form?.validFrom ?? null,
499
+ validUntil: form?.validUntil ?? null,
500
+ createdByUserId: null,
501
+ publishedByUserId: null,
502
+ createdAt: nowIso,
503
+ updatedAt: nowIso
504
+ };
505
+ });
506
+ const predecessor = computed(() => {
507
+ const live = area.versions.value.filter(
508
+ (v) => v.publishedAt !== null && v.supersededAt === null
509
+ );
510
+ if (live.length === 0) return null;
511
+ return live.reduce((a, b) => a.version > b.version ? a : b);
512
+ });
513
+ function onBack() {
514
+ void router.push("/admin/plans/version/edit");
515
+ }
516
+ async function onSaveAndExit() {
517
+ const form = wizard.editing.value?.initialForm;
518
+ if (!form) return;
519
+ const saved = await area.saveDraft({ ...form }, wizard.editing.value?.editingId ?? null);
520
+ if (!saved) return;
521
+ leaveWizard();
522
+ }
523
+ async function onPublish(payload) {
524
+ const form = wizard.editing.value?.initialForm;
525
+ if (!form) return;
526
+ const published = await area.publishDraft(
527
+ { ...form },
528
+ wizard.editing.value?.editingId ?? null,
529
+ payload
530
+ );
531
+ if (!published) return;
532
+ leaveWizard();
533
+ }
534
+ function leaveWizard() {
535
+ wizard.reset();
536
+ void router.push("/admin/plans");
537
+ }
538
+ return (_ctx, _cache) => {
539
+ return unref(area).plan.value && unref(wizard).editing.value ? (openBlock(), createBlock(PlanReview, {
540
+ key: 0,
541
+ plan: unref(area).plan.value,
542
+ version: reviewVersion.value,
543
+ predecessor: predecessor.value,
544
+ "available-quotas": unref(area).availableQuotas.value,
545
+ "available-bundles": unref(area).availableBundles.value,
546
+ "feature-registry": unref(area).featureRegistry.value,
547
+ "tenant-impact-count": unref(area).tenantCounts.value[unref(area).plan.value.planKey] ?? 0,
548
+ saving: unref(area).saving.value,
549
+ publishing: unref(area).publishing.value,
550
+ "publish-error": unref(area).saveError.value,
551
+ onBack,
552
+ onSaveAndExit,
553
+ onPublish
554
+ }, null, 8, ["plan", "version", "predecessor", "available-quotas", "available-bundles", "feature-registry", "tenant-impact-count", "saving", "publishing", "publish-error"])) : (openBlock(), createBlock(_sfc_main$4, {
555
+ key: 1,
556
+ title: unref(msg).list.emptyNoPlans
557
+ }, null, 8, ["title"]));
558
+ };
559
+ }
560
+ });
561
+ export {
562
+ _sfc_main as default
563
+ };