@saasicat/ui-vue 0.4.0 → 0.6.0
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/README.md +64 -4
- package/dist/chunk-A3W2N26K.js +714 -0
- package/dist/chunk-QZOSDCNP.js +98 -0
- package/dist/chunk-X5SQ5HMB.js +3231 -0
- package/dist/client/index.cjs +3988 -0
- package/dist/client/index.d.cts +321 -0
- package/dist/client/index.d.ts +321 -0
- package/dist/client/index.js +70 -0
- package/dist/index.cjs +4446 -1249
- package/dist/index.d.cts +297 -888
- package/dist/index.d.ts +297 -888
- package/dist/index.js +609 -1348
- package/dist/messages-7b0P8W75.d.cts +1652 -0
- package/dist/messages-7b0P8W75.d.ts +1652 -0
- package/dist/quasar/index.cjs +3340 -0
- package/dist/quasar/index.d.cts +95 -0
- package/dist/quasar/index.d.ts +95 -0
- package/dist/quasar/index.js +96 -0
- package/dist/testing-e2e/admin-pages-suite.cjs +14 -11
- package/dist/testing-e2e/admin-pages-suite.js +14 -11
- package/dist/use-super-admin-i18n-B3v3-SWZ.d.ts +210 -0
- package/dist/use-super-admin-i18n-DMktRVEt.d.cts +210 -0
- package/package.json +23 -3
- package/src/{action-registry.ts → client/action-registry.ts} +4 -4
- package/src/{batch-column-fetcher.ts → client/batch-column-fetcher.ts} +4 -4
- package/src/{boot-loader.ts → client/boot-loader.ts} +3 -3
- package/src/client/i18n/currency.ts +42 -0
- package/src/client/i18n/define.ts +59 -0
- package/src/client/i18n/format.ts +12 -0
- package/src/client/i18n/index.ts +14 -0
- package/src/client/i18n/locale.ts +15 -0
- package/src/client/i18n/messages/audit.ts +42 -0
- package/src/client/i18n/messages/bundles.ts +459 -0
- package/src/client/i18n/messages/common.ts +147 -0
- package/src/client/i18n/messages/dashboard.ts +16 -0
- package/src/client/i18n/messages/discovery.ts +229 -0
- package/src/client/i18n/messages/email.ts +125 -0
- package/src/client/i18n/messages/marketing.ts +270 -0
- package/src/client/i18n/messages/nav.ts +72 -0
- package/src/client/i18n/messages/pilots.ts +192 -0
- package/src/client/i18n/messages/plan-detail.ts +266 -0
- package/src/client/i18n/messages/plan-editor.ts +177 -0
- package/src/client/i18n/messages/plan-versions.ts +251 -0
- package/src/client/i18n/messages/plans.ts +503 -0
- package/src/client/i18n/messages/promos.ts +202 -0
- package/src/client/i18n/messages/shell.ts +145 -0
- package/src/client/i18n/messages/tenants.ts +104 -0
- package/src/client/i18n/messages/users.ts +78 -0
- package/src/client/i18n/messages.ts +84 -0
- package/src/client/index.ts +27 -0
- package/src/{manifest-loader.ts → client/manifest-loader.ts} +4 -4
- package/src/{nav-builder.ts → client/nav-builder.ts} +44 -51
- package/src/{plan-versions-catalog.ts → client/plan-versions-catalog.ts} +42 -30
- package/src/components/BundleVersionPublishDialog.vue +35 -24
- package/src/components/FeatureGate.vue +1 -1
- package/src/components/MarketingPromotionsTab.vue +112 -59
- package/src/components/MfaPromptDialog.vue +11 -11
- package/src/components/TenantActionConfirmDialog.vue +19 -17
- package/src/components/VersionDiffPreview.vue +72 -43
- package/src/components/bundle-editor/BundleCreatePanel.vue +76 -63
- package/src/components/bundle-editor/BundleFeaturesEditor.vue +13 -6
- package/src/components/bundle-editor/BundlePlanCompatPicker.vue +19 -14
- package/src/components/bundle-editor/BundleQuotasEditor.vue +7 -4
- package/src/components/bundle-editor/BundleStatusBanner.vue +36 -19
- package/src/components/bundle-editor/BundleVersionInlineEditor.vue +51 -35
- package/src/components/bundle-editor/BundleVersionStrip.vue +24 -12
- package/src/components/bundle-editor/bundle-version-status.ts +29 -29
- package/src/components/dialogs/PilotCreateDialog.vue +58 -63
- package/src/components/dialogs/PilotEditDialog.vue +40 -34
- package/src/components/dialogs/PromoCodeCreateDialog.vue +89 -63
- package/src/components/dialogs/PromoCodeEditDialog.vue +98 -66
- package/src/components/dialogs/types.ts +3 -13
- package/src/components/plan/PlanCycleToggle.vue +21 -10
- package/src/components/plan/PlanGrid.vue +2 -2
- package/src/components/plan/PriceSummary.vue +1 -1
- package/src/components/plan/PromoCodeInput.vue +1 -1
- package/src/components/plan/PublicBundleGrid.vue +1 -1
- package/src/components/plan-cockpit/PlanCockpit.vue +34 -15
- package/src/components/plan-cockpit/PlanCockpitAuditLog.vue +13 -6
- package/src/components/plan-cockpit/PlanCockpitDiffPanel.vue +18 -9
- package/src/components/plan-cockpit/PlanCockpitHeader.vue +9 -6
- package/src/components/plan-cockpit/PlanCockpitImpactPanel.vue +24 -11
- package/src/components/plan-cockpit/PlanCockpitKpis.vue +28 -17
- package/src/components/plan-cockpit/PlanCockpitVersions.vue +50 -25
- package/src/components/plan-create-dialog/PlanCreateDialog.vue +45 -35
- package/src/components/plan-detail/PlanAuditLog.vue +11 -6
- package/src/components/plan-detail/PlanDetail.vue +21 -23
- package/src/components/plan-detail/PlanDetailHeader.vue +20 -11
- package/src/components/plan-detail/PlanDetailKpis.vue +30 -17
- package/src/components/plan-detail/PlanTerminateDialog.vue +22 -9
- package/src/components/plan-detail/PlanVersionDiffPanel.vue +61 -27
- package/src/components/plan-detail/PlanVersionsPanel.vue +71 -36
- package/src/components/plan-list/PlanList.vue +99 -57
- package/src/components/plan-matrix/PlanMatrix.vue +85 -38
- package/src/components/plan-review/PlanReview.vue +105 -80
- package/src/components/plan-version-editor/PlanCatalogPreview.vue +43 -20
- package/src/components/plan-version-editor/PlanComponentPool.vue +15 -7
- package/src/components/plan-version-editor/PlanVersionBasket.vue +45 -24
- package/src/components/plan-version-editor/PlanVersionDiffDialog.vue +8 -7
- package/src/components/plan-version-editor/PlanVersionEditor.vue +74 -40
- package/src/components/plan-version-editor/PlanVersionEditorHeader.vue +24 -12
- package/src/index.ts +82 -79
- package/src/pages-standard/AdminLayout.vue +43 -18
- package/src/pages-standard/AdminManifestErrorPage.vue +10 -10
- package/src/pages-standard/AuditPage.vue +58 -19
- package/src/pages-standard/BundlesPage.vue +29 -18
- package/src/pages-standard/DashboardPage.vue +31 -17
- package/src/pages-standard/DiscoveryPage.vue +40 -28
- package/src/pages-standard/EmailHistoryPage.vue +98 -69
- package/src/pages-standard/MarketingCatalogPage.vue +40 -21
- package/src/pages-standard/PilotsPage.vue +64 -52
- package/src/pages-standard/PlanVersionsPage.vue +9 -5
- package/src/pages-standard/PlansPage.vue +91 -59
- package/src/pages-standard/PlatformEmailPage.vue +120 -53
- package/src/pages-standard/PromoCodeDetailPage.vue +66 -63
- package/src/pages-standard/PromoCodesPage.vue +51 -54
- package/src/pages-standard/SubscriptionsPage.vue +14 -9
- package/src/pages-standard/SuperAdminLoginPage.vue +19 -16
- package/src/pages-standard/SuperAdminSetupWizard.vue +53 -49
- package/src/pages-standard/TenantDetailPage.vue +54 -40
- package/src/pages-standard/TenantsPage.vue +57 -44
- package/src/pages-standard/UsersPage.vue +70 -52
- package/src/pages-standard/bundles-page/BundleAccordionList.vue +20 -8
- package/src/pages-standard/bundles-page/BundleDetailPanel.vue +28 -18
- package/src/pages-standard/bundles-page/BundlesFilterBar.vue +4 -1
- package/src/pages-standard/bundles-page/BundlesHeader.vue +9 -8
- package/src/pages-standard/bundles-page/BundlesKpis.vue +29 -11
- package/src/pages-standard/discovery-page/CatalogEntryTransPanel.vue +20 -8
- package/src/pages-standard/discovery-page/DiscoveryCapList.vue +5 -3
- package/src/pages-standard/discovery-page/DiscoveryFeatureCard.vue +43 -24
- package/src/pages-standard/discovery-page/DiscoveryHeader.vue +7 -4
- package/src/pages-standard/discovery-page/DiscoveryKpis.vue +28 -15
- package/src/pages-standard/discovery-page/DiscoveryQuotaCard.vue +20 -10
- package/src/pages-standard/discovery-page/DiscoveryStatusControl.vue +9 -6
- package/src/pages-standard/discovery-page/discovery-ui.ts +40 -52
- package/src/pages-standard/marketing-catalog/MarketingCatalogAdmin.vue +81 -49
- package/src/pages-standard/marketing-catalog/MarketingCatalogHeader.vue +13 -10
- package/src/pages-standard/marketing-catalog/MarketingCatalogPreview.vue +24 -20
- package/src/pages-standard/marketing-catalog/MarketingCatalogToolbar.vue +6 -3
- package/src/pages-standard/plan-versions/PlanDiffCard.vue +16 -6
- package/src/pages-standard/plan-versions/PlanVersionHeader.vue +42 -26
- package/src/pages-standard/plan-versions/PlanVersionsAudit.vue +46 -27
- package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +8 -6
- package/src/pages-standard/plan-versions/PlanVersionsList.vue +40 -17
- package/src/pages-standard/plan-versions/PlanVersionsMatrix.vue +1 -1
- package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +25 -13
- package/src/pages-standard/plan-versions/format.ts +33 -17
- package/src/pages-standard/plans-page/PlanArchiveDialog.vue +12 -8
- package/src/pages-standard/plans-page/PlanBundleOverview.vue +15 -6
- package/src/pages-standard/plans-page/PlanDiscardDraftDialog.vue +18 -7
- package/src/pages-standard/plans-page/PlanPublishDialog.vue +23 -12
- package/src/pages-standard/tenants/format.ts +3 -2
- package/src/pages-tenant/MySubscriptionBundlesPage.vue +73 -38
- package/src/pages-tenant/OnboardingConfigurator.vue +3 -3
- package/src/pages-tenant/PackageSnapshotPanel.vue +1 -1
- package/src/pages-tenant/PlanChangeWizard.vue +10 -6
- package/src/pages-tenant/TenantPlanSection.vue +20 -16
- package/src/pages-tenant/default-i18n.ts +217 -1
- package/src/pages-tenant/tenant-plan-section/BundlePreviewDialog.vue +9 -7
- package/src/pages-tenant/tenant-plan-section/TenantBundleStore.vue +11 -12
- package/src/pages-tenant/tenant-plan-section/TenantFeatureMatrix.vue +4 -1
- package/src/pages-tenant/tenant-plan-section/TenantPlanCardHeader.vue +1 -1
- package/src/pages-tenant/tenant-plan-section/TenantUsageGrid.vue +1 -1
- package/src/quasar/create-super-admin-app.ts +192 -0
- package/src/quasar/index.ts +11 -0
- package/src/quasar/notify.ts +30 -0
- package/src/testing-e2e/admin-pages-suite.ts +14 -11
- package/src/{manifest-store-factory.ts → vue/manifest-store-factory.ts} +1 -1
- package/src/{platform-loaders.ts → vue/platform-loaders.ts} +4 -4
- package/src/{project-page-host.ts → vue/project-page-host.ts} +6 -4
- package/src/{create-super-admin-app.ts → vue/super-admin-context.ts} +20 -139
- package/src/vue/ui-notify.ts +30 -0
- package/src/{use-actions.ts → vue/use-actions.ts} +1 -1
- package/src/{use-api-list.ts → vue/use-api-list.ts} +1 -1
- package/src/{use-audit-entries.ts → vue/use-audit-entries.ts} +3 -3
- package/src/{use-batch-columns.ts → vue/use-batch-columns.ts} +1 -1
- package/src/{use-bulk-publish.ts → vue/use-bulk-publish.ts} +7 -5
- package/src/{use-bundle-versions-map.ts → vue/use-bundle-versions-map.ts} +7 -5
- package/src/{use-bundles.ts → vue/use-bundles.ts} +14 -14
- package/src/{use-catalog-entries.ts → vue/use-catalog-entries.ts} +14 -11
- package/src/{use-discovery.ts → vue/use-discovery.ts} +9 -6
- package/src/{use-entitlement.ts → vue/use-entitlement.ts} +4 -4
- package/src/{use-live-plan-versions.ts → vue/use-live-plan-versions.ts} +5 -5
- package/src/{use-manifest.ts → vue/use-manifest.ts} +1 -1
- package/src/{use-marketing-projections.ts → vue/use-marketing-projections.ts} +10 -7
- package/src/{use-nav.ts → vue/use-nav.ts} +9 -3
- package/src/{use-plan-editor.ts → vue/use-plan-editor.ts} +2 -2
- package/src/{use-plan-versions.ts → vue/use-plan-versions.ts} +3 -3
- package/src/{use-plans.ts → vue/use-plans.ts} +13 -13
- package/src/{use-platform-tenant-actions.ts → vue/use-platform-tenant-actions.ts} +9 -6
- package/src/{use-promotions.ts → vue/use-promotions.ts} +10 -11
- package/src/{use-public-boot.ts → vue/use-public-boot.ts} +1 -1
- package/src/{use-subscription-draft.ts → vue/use-subscription-draft.ts} +2 -3
- package/src/{use-super-admin-context.ts → vue/use-super-admin-context.ts} +5 -5
- package/src/vue/use-super-admin-i18n.ts +82 -0
- package/src/{use-tenant-action-flow.ts → vue/use-tenant-action-flow.ts} +12 -7
- package/src/{use-tenant-billing-catalog.ts → vue/use-tenant-billing-catalog.ts} +2 -2
- package/src/{use-tenant-billing.ts → vue/use-tenant-billing.ts} +2 -2
- package/src/{use-tenant-manifest.ts → vue/use-tenant-manifest.ts} +2 -4
- package/src/{use-tenant-subscription-bundles.ts → vue/use-tenant-subscription-bundles.ts} +5 -5
- package/src/{use-tenants.ts → vue/use-tenants.ts} +3 -3
- package/dist/testing-e2e/admin-pages-suite.d.cts +0 -37
- package/dist/testing-e2e/admin-pages-suite.d.ts +0 -37
- package/src/components/BusinessTypeVersionEditorDialog.vue +0 -417
- package/src/components/BusinessTypeVersionPublishDialog.vue +0 -258
- package/src/pages-standard/BusinessTypesPage.vue +0 -662
- package/src/pages-standard/plan-versions/VersionDiffPreview.vue +0 -167
- package/src/use-business-types.ts +0 -269
- /package/src/{http-json.ts → client/http-json.ts} +0 -0
- /package/src/{types.ts → client/types.ts} +0 -0
- /package/src/{version.ts → client/version.ts} +0 -0
- /package/src/{create-admin-routes.ts → vue/create-admin-routes.ts} +0 -0
- /package/src/{entitlement-provider.ts → vue/entitlement-provider.ts} +0 -0
- /package/src/{feature-router-guard.ts → vue/feature-router-guard.ts} +0 -0
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
import { defineMessages } from '../define.js';
|
|
2
|
+
|
|
3
|
+
export const plansMessages = defineMessages(
|
|
4
|
+
{
|
|
5
|
+
// PlansPage — shell of the plan area: loading state, toasts and the
|
|
6
|
+
// error texts of the draft/publish/archive/discard actions.
|
|
7
|
+
page: {
|
|
8
|
+
loading: 'Pläne werden geladen…',
|
|
9
|
+
toastPlanCreated: 'Plan {planKey} angelegt — jetzt die erste Version zusammenstellen.',
|
|
10
|
+
toastDraftSaved: 'Draft v{version} von {planKey} gespeichert.',
|
|
11
|
+
toastPlanPublished:
|
|
12
|
+
'Plan {planKey} wurde als v{version} veröffentlicht — sichtbar im Katalog.',
|
|
13
|
+
toastPlanDeleted: 'Plan {planKey} komplett aus der DB gelöscht.',
|
|
14
|
+
toastDraftDiscarded:
|
|
15
|
+
'Draft v{version} von {planKey} verworfen — Live-Version unverändert.',
|
|
16
|
+
toastVersionTerminated: 'v{version} terminiert.',
|
|
17
|
+
errorSessionExpiredSave:
|
|
18
|
+
'Sitzung abgelaufen — bitte neu anmelden und erneut speichern.',
|
|
19
|
+
errorStrictMode: 'Strict-Mode-Check: {details}',
|
|
20
|
+
errorStrictModeFallback: 'Drift gegen den Discovery-Snapshot.',
|
|
21
|
+
errorDraftRegression:
|
|
22
|
+
'Diese Version ist regressiv (Feature entfernt / Quota gesenkt / Preis erhöht). Publish erfordert Force-Regressive — beim Speichern als Draft sollte das nicht auftreten.',
|
|
23
|
+
errorSaveFailedHttp: 'Speichern fehlgeschlagen (HTTP {status}).',
|
|
24
|
+
errorSaveFailedDetail: 'Speichern fehlgeschlagen: {message}',
|
|
25
|
+
errorSaveFailedConsole: 'Speichern fehlgeschlagen — Details siehe Browser-Konsole.',
|
|
26
|
+
errorPlanHasPublishedVersions:
|
|
27
|
+
'Plan hat published Versionen — kann nicht gelöscht werden (Vertragsschutz P1).',
|
|
28
|
+
errorPlanHasDrafts:
|
|
29
|
+
'Plan hat noch einen offenen Draft — bitte erst über das Mülleimer-Icon verwerfen.',
|
|
30
|
+
errorHardDeleteNotImplemented:
|
|
31
|
+
'Backend unterstützt Hard-Delete noch nicht — API-Server neu bauen + starten.',
|
|
32
|
+
errorPlanAlreadyRemoved: 'Plan wurde bereits entfernt (404). Liste wird neu geladen.',
|
|
33
|
+
errorOperationFailedHttp: 'Vorgang fehlgeschlagen (HTTP {status}).',
|
|
34
|
+
errorOperationFailedDetail:
|
|
35
|
+
'Vorgang fehlgeschlagen: {message}. Details siehe Browser-Konsole.',
|
|
36
|
+
errorVersionAlreadyPublished:
|
|
37
|
+
'Diese Version ist bereits published und kann nicht verworfen werden.',
|
|
38
|
+
errorDiscardNotImplemented:
|
|
39
|
+
'Backend unterstützt das Verwerfen noch nicht — bitte API-Server neu bauen + starten.',
|
|
40
|
+
errorDraftAlreadyRemoved:
|
|
41
|
+
'Draft wurde bereits entfernt (404) — Liste wird gleich neu geladen.',
|
|
42
|
+
errorDiscardFailedHttp: 'Verwerfen fehlgeschlagen (HTTP {status}).',
|
|
43
|
+
errorDiscardFailedDetail:
|
|
44
|
+
'Verwerfen fehlgeschlagen: {message}. Details siehe Browser-Konsole (oft: API-Server alt gebaut oder CORS blockiert DELETE).',
|
|
45
|
+
errorSessionExpiredPublish:
|
|
46
|
+
'Sitzung abgelaufen — bitte neu anmelden und erneut versuchen.',
|
|
47
|
+
errorPublishRegression:
|
|
48
|
+
'Diese Version ist regressiv. Aktiviere "Force-Publish", wenn der Schritt absichtlich ist.',
|
|
49
|
+
errorValidFromRequired:
|
|
50
|
+
'Beim Publish muss "Gültig ab" gesetzt sein. Bitte den Draft öffnen und das Datum eintragen.',
|
|
51
|
+
errorValidFromNotAfterPrevious:
|
|
52
|
+
'"Gültig ab" muss strikt nach dem "Gültig ab" der Vorgänger-Version liegen. Bitte ein späteres Datum wählen.',
|
|
53
|
+
errorZeroPrice:
|
|
54
|
+
'Diese Version hat Preis 0,00 (Schutz gegen Seed-Platzhalter). Aktiviere "Preis 0,00 bewusst zulassen", wenn das ein gewollter kostenloser Sondervertrag ist.',
|
|
55
|
+
errorPublishFailedHttp: 'Publish fehlgeschlagen (HTTP {status})',
|
|
56
|
+
},
|
|
57
|
+
// Field labels of the regression report the publish endpoint returns.
|
|
58
|
+
regressionFields: {
|
|
59
|
+
monthlyNet: 'Preis (monatlich, netto)',
|
|
60
|
+
yearlyNet: 'Preis (jährlich, netto)',
|
|
61
|
+
featuresRemoved: 'Entfernte Features',
|
|
62
|
+
featuresAdded: 'Hinzugefügte Features',
|
|
63
|
+
quotasLowered: 'Gesenkte Quotas',
|
|
64
|
+
quotasRaised: 'Erhöhte Quotas',
|
|
65
|
+
bundlesRemoved: 'Entfernte Bundles',
|
|
66
|
+
bundlesAdded: 'Hinzugefügte Bundles',
|
|
67
|
+
},
|
|
68
|
+
// PlanList — default plan overview with one row per plan.
|
|
69
|
+
list: {
|
|
70
|
+
title: 'Alle Pläne',
|
|
71
|
+
summary:
|
|
72
|
+
'{plans} Pläne · {live} live · {drafts} offene Drafts · {tenants} Mandanten zugeordnet',
|
|
73
|
+
matrixView: 'Matrix-Ansicht',
|
|
74
|
+
newPlan: 'Neuer Plan',
|
|
75
|
+
searchPlaceholder: 'Plan suchen…',
|
|
76
|
+
sortedBy: 'Sortiert nach: Order',
|
|
77
|
+
columnPlan: 'Plan',
|
|
78
|
+
columnVersion: 'Version',
|
|
79
|
+
columnPrice: 'Preis',
|
|
80
|
+
columnTenants: 'Mandanten',
|
|
81
|
+
emptyNoPlans: 'Noch keine Pläne — über „Neuer Plan" oben rechts den ersten anlegen.',
|
|
82
|
+
emptyNoMatch: 'Keine Pläne entsprechen der Suche „{query}".',
|
|
83
|
+
badgeNew: 'NEU',
|
|
84
|
+
chipLive: 'live',
|
|
85
|
+
chipPrivate: 'privat',
|
|
86
|
+
chipNoLive: 'keine live',
|
|
87
|
+
chipScheduled: 'geplant',
|
|
88
|
+
chipDraft: 'Draft',
|
|
89
|
+
validFrom: 'ab {date}',
|
|
90
|
+
since: 'seit',
|
|
91
|
+
from: 'ab',
|
|
92
|
+
until: 'bis',
|
|
93
|
+
priceFree: 'Kostenlos',
|
|
94
|
+
perMonthShort: '/ Mo',
|
|
95
|
+
perYearShort: '/ Jahr',
|
|
96
|
+
tenantCount: '{count} Mandanten',
|
|
97
|
+
noChangeNote: 'keine Change-Note',
|
|
98
|
+
actionDeleteBlocked:
|
|
99
|
+
'Plan hat published Versionen — kann nicht gelöscht werden (Vertragsschutz P1)',
|
|
100
|
+
actionDeletePlan: 'Plan komplett löschen',
|
|
101
|
+
actionClonePlan: 'Plan klonen',
|
|
102
|
+
actionNewVersion: 'Neue Version anlegen',
|
|
103
|
+
actionOpenPlan: 'Plan öffnen',
|
|
104
|
+
actionDiscardDraft: 'Draft v{version} verwerfen',
|
|
105
|
+
actionEditDraft: 'Draft bearbeiten',
|
|
106
|
+
actionOpenInCockpit: 'Im Cockpit öffnen',
|
|
107
|
+
},
|
|
108
|
+
// PlanMatrix — all plans side by side, components as rows.
|
|
109
|
+
matrix: {
|
|
110
|
+
title: 'Pläne · Matrix-Vergleich',
|
|
111
|
+
summary:
|
|
112
|
+
'Alle Pläne nebeneinander · {plans} Pläne · {features} Features · {quotas} Quotas · {bundles} Bundles',
|
|
113
|
+
catalogPreview: 'Catalog-Vorschau',
|
|
114
|
+
createPlan: 'Plan anlegen',
|
|
115
|
+
createPlanSub: 'oder Klon erstellen',
|
|
116
|
+
componentColumn: 'Komponente',
|
|
117
|
+
chipLiveVersion: 'v{version} live',
|
|
118
|
+
chipNoLive: 'keine live',
|
|
119
|
+
chipDraftVersion: 'v{version} Entwurf',
|
|
120
|
+
priceFree: 'Kostenlos',
|
|
121
|
+
perMonthShort: '/ Mo',
|
|
122
|
+
perYearShort: '/J',
|
|
123
|
+
priceDraftMarker: '(Entwurf)',
|
|
124
|
+
noPrices: 'noch keine Preise',
|
|
125
|
+
tenantCount: '{count} Mandanten',
|
|
126
|
+
validFrom: 'ab {date}',
|
|
127
|
+
inCatalog: 'im Katalog',
|
|
128
|
+
private: 'privat',
|
|
129
|
+
clonePlan: 'Plan klonen',
|
|
130
|
+
groupQuotas: 'Quotas',
|
|
131
|
+
groupFeatures: 'Features',
|
|
132
|
+
groupBundles: 'Bundles',
|
|
133
|
+
baseBadge: 'Basis · immer enthalten',
|
|
134
|
+
legendIncluded: 'enthalten',
|
|
135
|
+
legendNotIncluded: 'nicht enthalten',
|
|
136
|
+
legendLoading: 'lade Versionen…',
|
|
137
|
+
},
|
|
138
|
+
// PlanReview — wizard step 3: read-only check before publishing.
|
|
139
|
+
review: {
|
|
140
|
+
title: 'Review & Publish',
|
|
141
|
+
subtitleLead: 'Letzte Prüfung, bevor',
|
|
142
|
+
subtitleTail: 'live geht.',
|
|
143
|
+
saving: 'Wird gespeichert…',
|
|
144
|
+
saveAsDraft: 'Als Draft speichern',
|
|
145
|
+
publishBlocked: 'Publish-Checkliste noch nicht vollständig',
|
|
146
|
+
publishing: 'Wird veröffentlicht…',
|
|
147
|
+
publishVersion: 'Publish v{version}',
|
|
148
|
+
cardMasterData: 'Stammdaten',
|
|
149
|
+
labelPlanKey: 'Plan-Key',
|
|
150
|
+
labelDisplayName: 'Anzeigename',
|
|
151
|
+
missing: 'fehlt',
|
|
152
|
+
cardPricing: 'Version v{version} · Pricing & Sichtbarkeit',
|
|
153
|
+
labelValidFrom: 'Gültig ab',
|
|
154
|
+
labelValidUntil: 'Gültig bis',
|
|
155
|
+
missingRequiredOnPublish: 'fehlt — beim Publish Pflicht',
|
|
156
|
+
unlimited: '∞ unbegrenzt',
|
|
157
|
+
labelMonthlyPrice: 'Preis monatlich',
|
|
158
|
+
labelYearlyPrice: 'Preis jährlich',
|
|
159
|
+
labelPublicCatalog: 'Public-Catalog',
|
|
160
|
+
visibleInCatalog: 'Im Catalog sichtbar',
|
|
161
|
+
hiddenFromCatalog: 'Ausgeblendet',
|
|
162
|
+
priceFree: 'Kostenlos',
|
|
163
|
+
cardComponents: 'Komponenten · {total} insgesamt',
|
|
164
|
+
componentQuotas: 'Quotas · {count}',
|
|
165
|
+
componentFeatures: 'Features · {count}',
|
|
166
|
+
componentBundles: 'Bundles · {count}',
|
|
167
|
+
componentEmpty: 'keine',
|
|
168
|
+
cardChangeNote: 'Change-Note',
|
|
169
|
+
changeNoteHint: 'Wird im Audit-Log gespeichert und mit der Versions-History angezeigt.',
|
|
170
|
+
changeNoteMissing:
|
|
171
|
+
'Keine Change-Note — im Editor nachtragen (Pflicht beim Publish, Vertragsschutz\u00A0P3).',
|
|
172
|
+
cardChecklist: 'Publish-Checkliste',
|
|
173
|
+
checkPlanKey: 'Plan-Key vergeben',
|
|
174
|
+
checkDisplayName: 'Anzeigename vorhanden',
|
|
175
|
+
checkQuota: 'Mindestens 1 Quota zugewiesen',
|
|
176
|
+
checkFeature: 'Mindestens 1 Feature zugewiesen',
|
|
177
|
+
checkValidFrom: '„Gültig ab" gesetzt (Pflicht beim Publish)',
|
|
178
|
+
checkValidFromAfterPredecessor: '„Gültig ab" liegt nach Vorgänger v{version}',
|
|
179
|
+
checkValidFromAfterPrevious: '„Gültig ab" liegt nach der Vorgänger-Version',
|
|
180
|
+
checkChangeNote: 'Change-Note vorhanden (Vertragsschutz P3)',
|
|
181
|
+
cardRegression: 'Vertragsschutz P3 — Regression',
|
|
182
|
+
regressionHint:
|
|
183
|
+
'Wenn diese Version regressiv ist (Feature entfernt, Quota gesenkt, Preis erhöht), blockiert das Backend den Publish. Mit Force-Publish wird die Regression bewusst freigegeben und löst die Notification-Welle aus.',
|
|
184
|
+
forceRegressive: 'Force-Publish auch bei Regression',
|
|
185
|
+
cardZeroPrice: 'Preis 0,00',
|
|
186
|
+
zeroPriceHint:
|
|
187
|
+
'Standardmäßig blockt das Backend einen Publish mit Preis 0,00 (Schutz gegen Seed-Platzhalter). Für bewusst kostenlose Sonderverträge hier freigeben.',
|
|
188
|
+
allowZeroPrice: 'Preis 0,00 bewusst zulassen',
|
|
189
|
+
cardTenantImpact: 'Tenant-Impact bei Publish',
|
|
190
|
+
impactNone:
|
|
191
|
+
'Aktuell sind keine Mandanten betroffen. Sobald die Version live ist, können Mandanten den Plan im Catalog buchen.',
|
|
192
|
+
impactSome:
|
|
193
|
+
'{count} Mandant(en) auf der aktuellen Live-Version bleiben per Bestandsschutz (P1) auf ihrer Version — neue Buchungen laufen auf v{version}.',
|
|
194
|
+
},
|
|
195
|
+
// PlanCreateDialog — step 1 of the "new plan" flow.
|
|
196
|
+
createDialog: {
|
|
197
|
+
title: 'Neuen Plan anlegen',
|
|
198
|
+
subtitle:
|
|
199
|
+
'Plan-Stamm anlegen. Im nächsten Schritt weist du Features, Quotas und Bundles zu.',
|
|
200
|
+
labelPlanKey: 'Plan-Key',
|
|
201
|
+
placeholderPlanKey: 'z. B. SCALE',
|
|
202
|
+
hintPlanKey: 'Großbuchstaben + Unterstriche · API-stabil, nicht änderbar nach Publish',
|
|
203
|
+
labelDisplayName: 'Anzeigename',
|
|
204
|
+
placeholderDisplayName: 'z. B. Scale',
|
|
205
|
+
hintDisplayName: 'Wie der Plan im Catalog erscheint',
|
|
206
|
+
placeholderDescription: 'Was bekommt der Kunde mit diesem Plan?',
|
|
207
|
+
labelBasis: 'Basis für die erste Version',
|
|
208
|
+
emptyPlan: 'Leerer Plan',
|
|
209
|
+
emptyPlanHint: 'Im Editor alles selbst zusammenstellen',
|
|
210
|
+
cloneOf: 'Klon von {label}',
|
|
211
|
+
counts: '{features} Features · {quotas} Quotas · {bundles} Bundles',
|
|
212
|
+
errorKeyFormat: 'Muss mit Buchstabe beginnen, nur A–Z, 0–9, _.',
|
|
213
|
+
errorKeyExists: '„{key}" existiert bereits.',
|
|
214
|
+
submitting: 'Wird angelegt…',
|
|
215
|
+
submit: 'Weiter · Komponenten',
|
|
216
|
+
},
|
|
217
|
+
// PlanPublishDialog — publish confirmation from the plan cockpit.
|
|
218
|
+
publishDialog: {
|
|
219
|
+
title: 'Version publishen?',
|
|
220
|
+
bodyLead: 'Plan',
|
|
221
|
+
bodyTail: ', Draft v{version}.',
|
|
222
|
+
supersededNoteLead: 'Eine ggf. zuvor live Version wird auf',
|
|
223
|
+
supersededNoteTail:
|
|
224
|
+
'gesetzt (Vertragsschutz P1: Bestand-Subscriptions bleiben auf der alten Version bis zum nächsten Renewal).',
|
|
225
|
+
forceRegressive:
|
|
226
|
+
'Force-Publish auch bei Regression (Feature entfernt / Quota gesenkt / Preis erhöht)',
|
|
227
|
+
allowZeroPrice: 'Preis 0,00 bewusst zulassen (kostenloser Sondervertrag)',
|
|
228
|
+
regressiveChanges: 'Regressive Änderungen:',
|
|
229
|
+
confirm: 'Publish',
|
|
230
|
+
},
|
|
231
|
+
// PlanArchiveDialog — hard delete of a plan without published versions.
|
|
232
|
+
archiveDialog: {
|
|
233
|
+
title: 'Plan komplett löschen?',
|
|
234
|
+
bodyLead: 'Plan',
|
|
235
|
+
bodyVerb: 'wird',
|
|
236
|
+
bodyEmphasis: 'unwiderruflich aus der DB entfernt',
|
|
237
|
+
bodyTail:
|
|
238
|
+
'. Da der Plan keine published Version hat, sind keine Subscriptions betroffen.',
|
|
239
|
+
contractProtectionNote:
|
|
240
|
+
'Vertragsschutz P1: Pläne mit jemals veröffentlichten Versionen können nicht gelöscht werden — das Backend würde 422 antworten.',
|
|
241
|
+
},
|
|
242
|
+
// PlanDiscardDraftDialog — discard an open draft version.
|
|
243
|
+
discardDialog: {
|
|
244
|
+
title: 'Draft verwerfen?',
|
|
245
|
+
bodyLead: 'Draft v{version} von',
|
|
246
|
+
bodyTail: 'wird unwiderruflich gelöscht. Published Versions bleiben unverändert.',
|
|
247
|
+
},
|
|
248
|
+
// PlanBundleOverview — bundle cards below the plan list.
|
|
249
|
+
bundleOverview: {
|
|
250
|
+
title: 'Bundles',
|
|
251
|
+
empty: 'Keine Bundles vorhanden.',
|
|
252
|
+
contains: 'Enthält',
|
|
253
|
+
compatibleWith: 'Kompatibel mit',
|
|
254
|
+
allPlans: 'Alle Pläne',
|
|
255
|
+
},
|
|
256
|
+
// PlanCycleToggle — monthly/yearly switch (labels come from `common`).
|
|
257
|
+
cycle: {
|
|
258
|
+
ariaLabel: 'Abrechnungszyklus',
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
page: {
|
|
263
|
+
loading: 'Loading plans…',
|
|
264
|
+
toastPlanCreated: 'Plan {planKey} created — now assemble the first version.',
|
|
265
|
+
toastDraftSaved: 'Draft v{version} of {planKey} saved.',
|
|
266
|
+
toastPlanPublished:
|
|
267
|
+
'Plan {planKey} was published as v{version} — visible in the catalog.',
|
|
268
|
+
toastPlanDeleted: 'Plan {planKey} completely removed from the database.',
|
|
269
|
+
toastDraftDiscarded:
|
|
270
|
+
'Draft v{version} of {planKey} discarded — live version unchanged.',
|
|
271
|
+
toastVersionTerminated: 'v{version} terminated.',
|
|
272
|
+
errorSessionExpiredSave: 'Session expired — please sign in again and save once more.',
|
|
273
|
+
errorStrictMode: 'Strict mode check: {details}',
|
|
274
|
+
errorStrictModeFallback: 'Drift against the discovery snapshot.',
|
|
275
|
+
errorDraftRegression:
|
|
276
|
+
'This version is regressive (feature removed / quota lowered / price increased). Publishing requires force-regressive — this should not happen when saving as a draft.',
|
|
277
|
+
errorSaveFailedHttp: 'Failed to save (HTTP {status}).',
|
|
278
|
+
errorSaveFailedDetail: 'Failed to save: {message}',
|
|
279
|
+
errorSaveFailedConsole: 'Failed to save — see the browser console for details.',
|
|
280
|
+
errorPlanHasPublishedVersions:
|
|
281
|
+
'Plan has published versions — it cannot be deleted (contract protection P1).',
|
|
282
|
+
errorPlanHasDrafts:
|
|
283
|
+
'Plan still has an open draft — please discard it first via the trash icon.',
|
|
284
|
+
errorHardDeleteNotImplemented:
|
|
285
|
+
'The backend does not support hard delete yet — rebuild and restart the API server.',
|
|
286
|
+
errorPlanAlreadyRemoved: 'Plan has already been removed (404). Reloading the list.',
|
|
287
|
+
errorOperationFailedHttp: 'Operation failed (HTTP {status}).',
|
|
288
|
+
errorOperationFailedDetail:
|
|
289
|
+
'Operation failed: {message}. See the browser console for details.',
|
|
290
|
+
errorVersionAlreadyPublished:
|
|
291
|
+
'This version is already published and cannot be discarded.',
|
|
292
|
+
errorDiscardNotImplemented:
|
|
293
|
+
'The backend does not support discarding yet — please rebuild and restart the API server.',
|
|
294
|
+
errorDraftAlreadyRemoved:
|
|
295
|
+
'Draft has already been removed (404) — the list is about to reload.',
|
|
296
|
+
errorDiscardFailedHttp: 'Failed to discard (HTTP {status}).',
|
|
297
|
+
errorDiscardFailedDetail:
|
|
298
|
+
'Failed to discard: {message}. See the browser console for details (often: stale API server build or CORS blocking DELETE).',
|
|
299
|
+
errorSessionExpiredPublish: 'Session expired — please sign in again and retry.',
|
|
300
|
+
errorPublishRegression:
|
|
301
|
+
'This version is regressive. Enable "force publish" if the step is intentional.',
|
|
302
|
+
errorValidFromRequired:
|
|
303
|
+
'"Effective as of" must be set when publishing. Please open the draft and enter the date.',
|
|
304
|
+
errorValidFromNotAfterPrevious:
|
|
305
|
+
'"Effective as of" must be strictly after the "effective as of" of the previous version. Please pick a later date.',
|
|
306
|
+
errorZeroPrice:
|
|
307
|
+
'This version has a price of 0.00 (protection against seed placeholders). Enable "deliberately allow price 0.00" if this is an intentional free special contract.',
|
|
308
|
+
errorPublishFailedHttp: 'Publishing failed (HTTP {status})',
|
|
309
|
+
},
|
|
310
|
+
regressionFields: {
|
|
311
|
+
monthlyNet: 'Price (monthly, net)',
|
|
312
|
+
yearlyNet: 'Price (yearly, net)',
|
|
313
|
+
featuresRemoved: 'Removed features',
|
|
314
|
+
featuresAdded: 'Added features',
|
|
315
|
+
quotasLowered: 'Lowered quotas',
|
|
316
|
+
quotasRaised: 'Raised quotas',
|
|
317
|
+
bundlesRemoved: 'Removed bundles',
|
|
318
|
+
bundlesAdded: 'Added bundles',
|
|
319
|
+
},
|
|
320
|
+
list: {
|
|
321
|
+
title: 'All plans',
|
|
322
|
+
summary:
|
|
323
|
+
'{plans} plans · {live} live · {drafts} open drafts · {tenants} tenants assigned',
|
|
324
|
+
matrixView: 'Matrix view',
|
|
325
|
+
newPlan: 'New plan',
|
|
326
|
+
searchPlaceholder: 'Search plan…',
|
|
327
|
+
sortedBy: 'Sorted by: order',
|
|
328
|
+
columnPlan: 'Plan',
|
|
329
|
+
columnVersion: 'Version',
|
|
330
|
+
columnPrice: 'Price',
|
|
331
|
+
columnTenants: 'Tenants',
|
|
332
|
+
emptyNoPlans: 'No plans yet — create the first one via "New plan" in the top right.',
|
|
333
|
+
emptyNoMatch: 'No plans match the search "{query}".',
|
|
334
|
+
badgeNew: 'NEW',
|
|
335
|
+
chipLive: 'live',
|
|
336
|
+
chipPrivate: 'private',
|
|
337
|
+
chipNoLive: 'no live version',
|
|
338
|
+
chipScheduled: 'scheduled',
|
|
339
|
+
chipDraft: 'Draft',
|
|
340
|
+
validFrom: 'from {date}',
|
|
341
|
+
since: 'since',
|
|
342
|
+
from: 'from',
|
|
343
|
+
until: 'until',
|
|
344
|
+
priceFree: 'Free',
|
|
345
|
+
perMonthShort: '/ mo',
|
|
346
|
+
perYearShort: '/ yr',
|
|
347
|
+
tenantCount: '{count} tenants',
|
|
348
|
+
noChangeNote: 'no change note',
|
|
349
|
+
actionDeleteBlocked:
|
|
350
|
+
'Plan has published versions — it cannot be deleted (contract protection P1)',
|
|
351
|
+
actionDeletePlan: 'Delete plan completely',
|
|
352
|
+
actionClonePlan: 'Clone plan',
|
|
353
|
+
actionNewVersion: 'Create new version',
|
|
354
|
+
actionOpenPlan: 'Open plan',
|
|
355
|
+
actionDiscardDraft: 'Discard draft v{version}',
|
|
356
|
+
actionEditDraft: 'Edit draft',
|
|
357
|
+
actionOpenInCockpit: 'Open in cockpit',
|
|
358
|
+
},
|
|
359
|
+
matrix: {
|
|
360
|
+
title: 'Plans · matrix comparison',
|
|
361
|
+
summary:
|
|
362
|
+
'All plans side by side · {plans} plans · {features} features · {quotas} quotas · {bundles} bundles',
|
|
363
|
+
catalogPreview: 'Catalog preview',
|
|
364
|
+
createPlan: 'Create plan',
|
|
365
|
+
createPlanSub: 'or create a clone',
|
|
366
|
+
componentColumn: 'Component',
|
|
367
|
+
chipLiveVersion: 'v{version} live',
|
|
368
|
+
chipNoLive: 'no live version',
|
|
369
|
+
chipDraftVersion: 'v{version} draft',
|
|
370
|
+
priceFree: 'Free',
|
|
371
|
+
perMonthShort: '/ mo',
|
|
372
|
+
perYearShort: '/yr',
|
|
373
|
+
priceDraftMarker: '(draft)',
|
|
374
|
+
noPrices: 'no prices yet',
|
|
375
|
+
tenantCount: '{count} tenants',
|
|
376
|
+
validFrom: 'from {date}',
|
|
377
|
+
inCatalog: 'in catalog',
|
|
378
|
+
private: 'private',
|
|
379
|
+
clonePlan: 'Clone plan',
|
|
380
|
+
groupQuotas: 'Quotas',
|
|
381
|
+
groupFeatures: 'Features',
|
|
382
|
+
groupBundles: 'Bundles',
|
|
383
|
+
baseBadge: 'Base · always included',
|
|
384
|
+
legendIncluded: 'included',
|
|
385
|
+
legendNotIncluded: 'not included',
|
|
386
|
+
legendLoading: 'loading versions…',
|
|
387
|
+
},
|
|
388
|
+
review: {
|
|
389
|
+
title: 'Review & publish',
|
|
390
|
+
subtitleLead: 'Final check before',
|
|
391
|
+
subtitleTail: 'goes live.',
|
|
392
|
+
saving: 'Saving…',
|
|
393
|
+
saveAsDraft: 'Save as draft',
|
|
394
|
+
publishBlocked: 'Publish checklist is not complete yet',
|
|
395
|
+
publishing: 'Publishing…',
|
|
396
|
+
publishVersion: 'Publish v{version}',
|
|
397
|
+
cardMasterData: 'Master data',
|
|
398
|
+
labelPlanKey: 'Plan key',
|
|
399
|
+
labelDisplayName: 'Display name',
|
|
400
|
+
missing: 'missing',
|
|
401
|
+
cardPricing: 'Version v{version} · pricing & visibility',
|
|
402
|
+
labelValidFrom: 'Effective as of',
|
|
403
|
+
labelValidUntil: 'Valid until',
|
|
404
|
+
missingRequiredOnPublish: 'missing — required when publishing',
|
|
405
|
+
unlimited: '∞ unlimited',
|
|
406
|
+
labelMonthlyPrice: 'Monthly price',
|
|
407
|
+
labelYearlyPrice: 'Yearly price',
|
|
408
|
+
labelPublicCatalog: 'Public catalog',
|
|
409
|
+
visibleInCatalog: 'Visible in catalog',
|
|
410
|
+
hiddenFromCatalog: 'Hidden',
|
|
411
|
+
priceFree: 'Free',
|
|
412
|
+
cardComponents: 'Components · {total} in total',
|
|
413
|
+
componentQuotas: 'Quotas · {count}',
|
|
414
|
+
componentFeatures: 'Features · {count}',
|
|
415
|
+
componentBundles: 'Bundles · {count}',
|
|
416
|
+
componentEmpty: 'none',
|
|
417
|
+
cardChangeNote: 'Change note',
|
|
418
|
+
changeNoteHint: 'Stored in the audit log and shown with the version history.',
|
|
419
|
+
changeNoteMissing:
|
|
420
|
+
'No change note — add it in the editor (required when publishing, contract protection\u00A0P3).',
|
|
421
|
+
cardChecklist: 'Publish checklist',
|
|
422
|
+
checkPlanKey: 'Plan key assigned',
|
|
423
|
+
checkDisplayName: 'Display name present',
|
|
424
|
+
checkQuota: 'At least 1 quota assigned',
|
|
425
|
+
checkFeature: 'At least 1 feature assigned',
|
|
426
|
+
checkValidFrom: '"Effective as of" set (required when publishing)',
|
|
427
|
+
checkValidFromAfterPredecessor: '"Effective as of" is after predecessor v{version}',
|
|
428
|
+
checkValidFromAfterPrevious: '"Effective as of" is after the previous version',
|
|
429
|
+
checkChangeNote: 'Change note present (contract protection P3)',
|
|
430
|
+
cardRegression: 'Contract protection P3 — regression',
|
|
431
|
+
regressionHint:
|
|
432
|
+
'If this version is regressive (feature removed, quota lowered, price increased), the backend blocks the publish. Force publish deliberately releases the regression and triggers the notification wave.',
|
|
433
|
+
forceRegressive: 'Force publish even on regression',
|
|
434
|
+
cardZeroPrice: 'Price 0.00',
|
|
435
|
+
zeroPriceHint:
|
|
436
|
+
'By default the backend blocks a publish with price 0.00 (protection against seed placeholders). Release it here for deliberately free special contracts.',
|
|
437
|
+
allowZeroPrice: 'Deliberately allow price 0.00',
|
|
438
|
+
cardTenantImpact: 'Tenant impact on publish',
|
|
439
|
+
impactNone:
|
|
440
|
+
'No tenants are affected right now. Once the version is live, tenants can book the plan from the catalog.',
|
|
441
|
+
impactSome:
|
|
442
|
+
'{count} tenant(s) on the current live version stay on their version under grandfathering (P1) — new bookings run on v{version}.',
|
|
443
|
+
},
|
|
444
|
+
createDialog: {
|
|
445
|
+
title: 'Create new plan',
|
|
446
|
+
subtitle:
|
|
447
|
+
'Create the plan master record. In the next step you assign features, quotas and bundles.',
|
|
448
|
+
labelPlanKey: 'Plan key',
|
|
449
|
+
placeholderPlanKey: 'e.g. SCALE',
|
|
450
|
+
hintPlanKey: 'Uppercase + underscores · API-stable, not changeable after publishing',
|
|
451
|
+
labelDisplayName: 'Display name',
|
|
452
|
+
placeholderDisplayName: 'e.g. Scale',
|
|
453
|
+
hintDisplayName: 'How the plan appears in the catalog',
|
|
454
|
+
placeholderDescription: 'What does the customer get with this plan?',
|
|
455
|
+
labelBasis: 'Basis for the first version',
|
|
456
|
+
emptyPlan: 'Empty plan',
|
|
457
|
+
emptyPlanHint: 'Assemble everything yourself in the editor',
|
|
458
|
+
cloneOf: 'Clone of {label}',
|
|
459
|
+
counts: '{features} features · {quotas} quotas · {bundles} bundles',
|
|
460
|
+
errorKeyFormat: 'Must start with a letter, only A–Z, 0–9, _.',
|
|
461
|
+
errorKeyExists: '"{key}" already exists.',
|
|
462
|
+
submitting: 'Creating…',
|
|
463
|
+
submit: 'Next · components',
|
|
464
|
+
},
|
|
465
|
+
publishDialog: {
|
|
466
|
+
title: 'Publish version?',
|
|
467
|
+
bodyLead: 'Plan',
|
|
468
|
+
bodyTail: ', draft v{version}.',
|
|
469
|
+
supersededNoteLead: 'A previously live version, if any, is set to',
|
|
470
|
+
supersededNoteTail:
|
|
471
|
+
'(contract protection P1: existing subscriptions stay on the old version until the next renewal).',
|
|
472
|
+
forceRegressive:
|
|
473
|
+
'Force publish even on regression (feature removed / quota lowered / price increased)',
|
|
474
|
+
allowZeroPrice: 'Deliberately allow price 0.00 (free special contract)',
|
|
475
|
+
regressiveChanges: 'Regressive changes:',
|
|
476
|
+
confirm: 'Publish',
|
|
477
|
+
},
|
|
478
|
+
archiveDialog: {
|
|
479
|
+
title: 'Delete plan completely?',
|
|
480
|
+
bodyLead: 'Plan',
|
|
481
|
+
bodyVerb: 'will be',
|
|
482
|
+
bodyEmphasis: 'permanently removed from the database',
|
|
483
|
+
bodyTail: '. Since the plan has no published version, no subscriptions are affected.',
|
|
484
|
+
contractProtectionNote:
|
|
485
|
+
'Contract protection P1: plans with ever-published versions cannot be deleted — the backend would respond with 422.',
|
|
486
|
+
},
|
|
487
|
+
discardDialog: {
|
|
488
|
+
title: 'Discard draft?',
|
|
489
|
+
bodyLead: 'Draft v{version} of',
|
|
490
|
+
bodyTail: 'will be permanently deleted. Published versions remain unchanged.',
|
|
491
|
+
},
|
|
492
|
+
bundleOverview: {
|
|
493
|
+
title: 'Bundles',
|
|
494
|
+
empty: 'No bundles available.',
|
|
495
|
+
contains: 'Contains',
|
|
496
|
+
compatibleWith: 'Compatible with',
|
|
497
|
+
allPlans: 'All plans',
|
|
498
|
+
},
|
|
499
|
+
cycle: {
|
|
500
|
+
ariaLabel: 'Billing cycle',
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
);
|