@saasicat/ui-vue 0.2.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.
Files changed (193) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +47 -0
  3. package/dist/index.cjs +3776 -0
  4. package/dist/index.d.cts +2395 -0
  5. package/dist/index.d.ts +2395 -0
  6. package/dist/index.js +3659 -0
  7. package/dist/testing-e2e/admin-pages-suite.cjs +134 -0
  8. package/dist/testing-e2e/admin-pages-suite.d.cts +37 -0
  9. package/dist/testing-e2e/admin-pages-suite.d.ts +37 -0
  10. package/dist/testing-e2e/admin-pages-suite.js +109 -0
  11. package/package.json +87 -0
  12. package/src/action-registry.ts +110 -0
  13. package/src/batch-column-fetcher.ts +152 -0
  14. package/src/boot-loader.ts +60 -0
  15. package/src/components/BundleVersionPublishDialog.vue +359 -0
  16. package/src/components/BusinessTypeVersionEditorDialog.vue +417 -0
  17. package/src/components/BusinessTypeVersionPublishDialog.vue +258 -0
  18. package/src/components/FeatureGate.vue +56 -0
  19. package/src/components/KpiCard.vue +53 -0
  20. package/src/components/KvBlock.vue +36 -0
  21. package/src/components/MarketingPromotionsTab.vue +861 -0
  22. package/src/components/MfaPromptDialog.vue +104 -0
  23. package/src/components/TenantActionConfirmDialog.vue +252 -0
  24. package/src/components/VersionDiffPreview.vue +150 -0
  25. package/src/components/bundle-editor/BundleCreatePanel.vue +681 -0
  26. package/src/components/bundle-editor/BundleFeaturesEditor.vue +215 -0
  27. package/src/components/bundle-editor/BundlePlanCompatPicker.vue +316 -0
  28. package/src/components/bundle-editor/BundleQuotasEditor.vue +219 -0
  29. package/src/components/bundle-editor/BundleStatusBanner.vue +189 -0
  30. package/src/components/bundle-editor/BundleVersionInlineEditor.vue +659 -0
  31. package/src/components/bundle-editor/BundleVersionStrip.vue +207 -0
  32. package/src/components/bundle-editor/bundle-version-status.ts +164 -0
  33. package/src/components/bundle-editor/catalog-i18n.ts +85 -0
  34. package/src/components/dialogs/PilotCreateDialog.vue +780 -0
  35. package/src/components/dialogs/PilotEditDialog.vue +548 -0
  36. package/src/components/dialogs/PromoCodeCreateDialog.vue +737 -0
  37. package/src/components/dialogs/PromoCodeEditDialog.vue +859 -0
  38. package/src/components/dialogs/types.ts +126 -0
  39. package/src/components/plan/PlanCycleToggle.vue +99 -0
  40. package/src/components/plan/PlanGrid.vue +211 -0
  41. package/src/components/plan/PriceSummary.vue +293 -0
  42. package/src/components/plan/PromoCodeInput.vue +192 -0
  43. package/src/components/plan/PublicBundleGrid.vue +287 -0
  44. package/src/components/plan-cockpit/PlanCockpit.vue +993 -0
  45. package/src/components/plan-cockpit/PlanCockpitAuditLog.vue +65 -0
  46. package/src/components/plan-cockpit/PlanCockpitDiffPanel.vue +91 -0
  47. package/src/components/plan-cockpit/PlanCockpitHeader.vue +98 -0
  48. package/src/components/plan-cockpit/PlanCockpitImpactPanel.vue +99 -0
  49. package/src/components/plan-cockpit/PlanCockpitKpis.vue +57 -0
  50. package/src/components/plan-cockpit/PlanCockpitVersions.vue +226 -0
  51. package/src/components/plan-cockpit/types.ts +72 -0
  52. package/src/components/plan-create-dialog/PlanCreateDialog.vue +508 -0
  53. package/src/components/plan-detail/PlanAuditLog.vue +59 -0
  54. package/src/components/plan-detail/PlanDetail.vue +1195 -0
  55. package/src/components/plan-detail/PlanDetailHeader.vue +185 -0
  56. package/src/components/plan-detail/PlanDetailKpis.vue +57 -0
  57. package/src/components/plan-detail/PlanTerminateDialog.vue +76 -0
  58. package/src/components/plan-detail/PlanVersionDiffPanel.vue +149 -0
  59. package/src/components/plan-detail/PlanVersionsPanel.vue +255 -0
  60. package/src/components/plan-detail/types.ts +59 -0
  61. package/src/components/plan-list/PlanList.vue +1067 -0
  62. package/src/components/plan-matrix/PlanMatrix.vue +1113 -0
  63. package/src/components/plan-review/PlanReview.vue +742 -0
  64. package/src/components/plan-version-editor/PlanCatalogPreview.vue +184 -0
  65. package/src/components/plan-version-editor/PlanComponentPool.vue +272 -0
  66. package/src/components/plan-version-editor/PlanVersionBasket.vue +281 -0
  67. package/src/components/plan-version-editor/PlanVersionDiffDialog.vue +84 -0
  68. package/src/components/plan-version-editor/PlanVersionEditor.vue +1728 -0
  69. package/src/components/plan-version-editor/PlanVersionEditorHeader.vue +94 -0
  70. package/src/components/plan-version-editor/types.ts +96 -0
  71. package/src/components/wizard-stepper/WizardStepper.vue +107 -0
  72. package/src/create-admin-routes.ts +68 -0
  73. package/src/create-super-admin-app.ts +345 -0
  74. package/src/entitlement-provider.ts +36 -0
  75. package/src/feature-router-guard.ts +77 -0
  76. package/src/http-json.ts +62 -0
  77. package/src/index.ts +98 -0
  78. package/src/manifest-loader.ts +139 -0
  79. package/src/manifest-store-factory.ts +114 -0
  80. package/src/nav-builder.ts +274 -0
  81. package/src/pages-standard/AdminLayout.vue +411 -0
  82. package/src/pages-standard/AdminManifestErrorPage.vue +79 -0
  83. package/src/pages-standard/AuditPage.vue +223 -0
  84. package/src/pages-standard/BundlesPage.vue +910 -0
  85. package/src/pages-standard/BusinessTypesPage.vue +662 -0
  86. package/src/pages-standard/DashboardPage.vue +595 -0
  87. package/src/pages-standard/DiscoveryPage.vue +663 -0
  88. package/src/pages-standard/EmailHistoryPage.vue +576 -0
  89. package/src/pages-standard/MarketingCatalogPage.vue +1771 -0
  90. package/src/pages-standard/PilotsPage.vue +577 -0
  91. package/src/pages-standard/PlanVersionsPage.vue +216 -0
  92. package/src/pages-standard/PlansPage.vue +1222 -0
  93. package/src/pages-standard/PlatformEmailPage.vue +434 -0
  94. package/src/pages-standard/PromoCodeDetailPage.vue +331 -0
  95. package/src/pages-standard/PromoCodesPage.vue +589 -0
  96. package/src/pages-standard/SubscriptionsPage.vue +159 -0
  97. package/src/pages-standard/SuperAdminLoginPage.vue +299 -0
  98. package/src/pages-standard/SuperAdminSetupWizard.vue +405 -0
  99. package/src/pages-standard/TenantDetailPage.vue +432 -0
  100. package/src/pages-standard/TenantsPage.vue +732 -0
  101. package/src/pages-standard/UsersPage.vue +504 -0
  102. package/src/pages-standard/bundles-page/BundleAccordionList.vue +116 -0
  103. package/src/pages-standard/bundles-page/BundleDetailPanel.vue +193 -0
  104. package/src/pages-standard/bundles-page/BundlesFilterBar.vue +48 -0
  105. package/src/pages-standard/bundles-page/BundlesHeader.vue +67 -0
  106. package/src/pages-standard/bundles-page/BundlesKpis.vue +39 -0
  107. package/src/pages-standard/bundles-page/types.ts +15 -0
  108. package/src/pages-standard/discovery-page/CatalogEntryTransPanel.vue +246 -0
  109. package/src/pages-standard/discovery-page/DiscoveryCapList.vue +171 -0
  110. package/src/pages-standard/discovery-page/DiscoveryFeatureCard.vue +410 -0
  111. package/src/pages-standard/discovery-page/DiscoveryHeader.vue +31 -0
  112. package/src/pages-standard/discovery-page/DiscoveryKpis.vue +47 -0
  113. package/src/pages-standard/discovery-page/DiscoveryMetaBanner.vue +26 -0
  114. package/src/pages-standard/discovery-page/DiscoveryQuotaCard.vue +247 -0
  115. package/src/pages-standard/discovery-page/DiscoveryStatusControl.vue +73 -0
  116. package/src/pages-standard/discovery-page/discovery-ui.ts +166 -0
  117. package/src/pages-standard/email-history.types.ts +48 -0
  118. package/src/pages-standard/marketing-catalog/MarketingCatalogAdmin.vue +448 -0
  119. package/src/pages-standard/marketing-catalog/MarketingCatalogHeader.vue +93 -0
  120. package/src/pages-standard/marketing-catalog/MarketingCatalogPreview.vue +138 -0
  121. package/src/pages-standard/marketing-catalog/MarketingCatalogToolbar.vue +58 -0
  122. package/src/pages-standard/marketing-catalog/types.ts +43 -0
  123. package/src/pages-standard/plan-versions/PlanDiffCard.vue +132 -0
  124. package/src/pages-standard/plan-versions/PlanVersionHeader.vue +293 -0
  125. package/src/pages-standard/plan-versions/PlanVersionStatusBadge.vue +48 -0
  126. package/src/pages-standard/plan-versions/PlanVersionsAudit.vue +307 -0
  127. package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +269 -0
  128. package/src/pages-standard/plan-versions/PlanVersionsKpi.vue +65 -0
  129. package/src/pages-standard/plan-versions/PlanVersionsList.vue +292 -0
  130. package/src/pages-standard/plan-versions/PlanVersionsMatrix.vue +261 -0
  131. package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +300 -0
  132. package/src/pages-standard/plan-versions/VersionDiffPreview.vue +167 -0
  133. package/src/pages-standard/plan-versions/format.ts +53 -0
  134. package/src/pages-standard/plan-versions/types.ts +33 -0
  135. package/src/pages-standard/plans-page/PlanArchiveDialog.vue +50 -0
  136. package/src/pages-standard/plans-page/PlanBundleOverview.vue +147 -0
  137. package/src/pages-standard/plans-page/PlanDiscardDraftDialog.vue +46 -0
  138. package/src/pages-standard/plans-page/PlanPublishDialog.vue +106 -0
  139. package/src/pages-standard/plans-page/PlansPageToast.vue +69 -0
  140. package/src/pages-standard/plans-page/types.ts +18 -0
  141. package/src/pages-standard/platform-email.types.ts +41 -0
  142. package/src/pages-standard/sa-theme.css +223 -0
  143. package/src/pages-standard/tenants/StatusPill.vue +62 -0
  144. package/src/pages-standard/tenants/format.ts +38 -0
  145. package/src/pages-tenant/LimitsRow.vue +67 -0
  146. package/src/pages-tenant/MySubscriptionBundlesPage.vue +604 -0
  147. package/src/pages-tenant/OnboardingConfigurator.vue +417 -0
  148. package/src/pages-tenant/PackageSnapshotPanel.vue +241 -0
  149. package/src/pages-tenant/PendingVersionBanner.vue +126 -0
  150. package/src/pages-tenant/PlanChangeWizard.vue +630 -0
  151. package/src/pages-tenant/TenantPlanSection.vue +729 -0
  152. package/src/pages-tenant/UsageBar.vue +107 -0
  153. package/src/pages-tenant/default-i18n.ts +280 -0
  154. package/src/pages-tenant/tenant-plan-section/BundlePreviewDialog.vue +304 -0
  155. package/src/pages-tenant/tenant-plan-section/TenantBundleStore.vue +323 -0
  156. package/src/pages-tenant/tenant-plan-section/TenantFeatureMatrix.vue +122 -0
  157. package/src/pages-tenant/tenant-plan-section/TenantPlanCardHeader.vue +67 -0
  158. package/src/pages-tenant/tenant-plan-section/TenantUsageGrid.vue +31 -0
  159. package/src/plan-versions-catalog.ts +368 -0
  160. package/src/platform-loaders.ts +68 -0
  161. package/src/project-page-host.ts +108 -0
  162. package/src/testing-e2e/admin-pages-suite.ts +187 -0
  163. package/src/types.ts +58 -0
  164. package/src/use-actions.ts +25 -0
  165. package/src/use-api-list.ts +151 -0
  166. package/src/use-audit-entries.ts +48 -0
  167. package/src/use-batch-columns.ts +59 -0
  168. package/src/use-bulk-publish.ts +150 -0
  169. package/src/use-bundle-versions-map.ts +112 -0
  170. package/src/use-bundles.ts +297 -0
  171. package/src/use-business-types.ts +269 -0
  172. package/src/use-catalog-entries.ts +243 -0
  173. package/src/use-discovery.ts +158 -0
  174. package/src/use-entitlement.ts +87 -0
  175. package/src/use-live-plan-versions.ts +126 -0
  176. package/src/use-manifest.ts +57 -0
  177. package/src/use-marketing-projections.ts +160 -0
  178. package/src/use-nav.ts +33 -0
  179. package/src/use-plan-editor.ts +162 -0
  180. package/src/use-plan-versions.ts +83 -0
  181. package/src/use-plans.ts +375 -0
  182. package/src/use-platform-tenant-actions.ts +286 -0
  183. package/src/use-promotions.ts +126 -0
  184. package/src/use-public-boot.ts +40 -0
  185. package/src/use-subscription-draft.ts +355 -0
  186. package/src/use-super-admin-context.ts +93 -0
  187. package/src/use-tenant-action-flow.ts +238 -0
  188. package/src/use-tenant-billing-catalog.ts +160 -0
  189. package/src/use-tenant-billing.ts +453 -0
  190. package/src/use-tenant-manifest.ts +94 -0
  191. package/src/use-tenant-subscription-bundles.ts +148 -0
  192. package/src/use-tenants.ts +61 -0
  193. package/src/version.ts +10 -0
@@ -0,0 +1,255 @@
1
+ <template>
2
+ <section class="pd-panel">
3
+ <div class="pd-panel-head">
4
+ <div style="min-width: 0">
5
+ <h3 class="pd-panel-title">Versionen</h3>
6
+ <div class="pd-panel-sub">
7
+ Pro Plan max. 1 offene Draft-Version · Publish setzt Vorgänger auf
8
+ <code class="pd-code">supersededAt</code>
9
+ </div>
10
+ </div>
11
+ <div class="pd-panel-head-right">
12
+ <button
13
+ v-if="!draftVersion"
14
+ class="btn btn--sm primary"
15
+ type="button"
16
+ @click="$emit('createDraft')"
17
+ >
18
+ <svg
19
+ width="12"
20
+ height="12"
21
+ viewBox="0 0 24 24"
22
+ fill="none"
23
+ stroke="currentColor"
24
+ stroke-width="2.5"
25
+ >
26
+ <path d="M12 5v14M5 12h14" />
27
+ </svg>
28
+ <span>Draft v{{ nextDraftVersion }}</span>
29
+ </button>
30
+ </div>
31
+ </div>
32
+
33
+ <div v-if="chronological.length > 0" class="pd-timeline">
34
+ <div class="pd-timeline-hint">
35
+ <span aria-hidden="true">
36
+ <svg
37
+ width="12"
38
+ height="12"
39
+ viewBox="0 0 24 24"
40
+ fill="none"
41
+ stroke="currentColor"
42
+ stroke-width="2"
43
+ >
44
+ <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" />
45
+ </svg>
46
+ </span>
47
+ Klicke eine Version, um sie zu wählen
48
+ </div>
49
+ <div class="pd-timeline-bar">
50
+ <div
51
+ v-for="v in chronological"
52
+ :key="v.id"
53
+ :class="[
54
+ 'pd-timeline-seg',
55
+ statusOf(v),
56
+ v.id === selectedId ? 'is-selected' : '',
57
+ ]"
58
+ :style="{ flex: statusOf(v) === 'draft' ? 1.4 : 1 }"
59
+ :title="`v${v.version} wählen (${statusOf(v)})`"
60
+ @click="$emit('update:selectedId', v.id)"
61
+ >
62
+ v{{ v.version }}<template v-if="statusOf(v) === 'draft'"> · draft</template>
63
+ </div>
64
+ </div>
65
+ <div class="pd-timeline-ticks">
66
+ <span v-for="(t, i) in timelineTicks" :key="i">{{ t }}</span>
67
+ </div>
68
+ </div>
69
+
70
+ <div class="pd-versions-tbl">
71
+ <div class="pd-versions-head">
72
+ <div>Version</div>
73
+ <div>Gültig</div>
74
+ <div>Preis</div>
75
+ <div>Auswirkung</div>
76
+ <div>Änderungsnotiz</div>
77
+ <div></div>
78
+ </div>
79
+
80
+ <div
81
+ v-for="v in tableRows"
82
+ :key="v.id"
83
+ :class="[
84
+ 'pd-vrow',
85
+ statusOf(v) === 'draft' ? 'is-draft' : '',
86
+ v.id === selectedId ? 'is-selected' : '',
87
+ ]"
88
+ @click="$emit('update:selectedId', v.id)"
89
+ >
90
+ <div>
91
+ <div class="pd-vcol">
92
+ <span class="pd-v-num">v{{ v.version }}</span>
93
+ <span :class="['chip dot', statusChip(v)]" style="font-size: 10px">
94
+ {{ statusOf(v) }}
95
+ </span>
96
+ </div>
97
+ </div>
98
+ <div>
99
+ <div class="pd-validity">
100
+ <div class="pd-validity-line">
101
+ <span class="pd-validity-date">
102
+ {{ v.validFrom ? v.validFrom.slice(0, 10) : '—' }}
103
+ </span>
104
+ <span class="pd-arrow-inf">→</span>
105
+ <span v-if="v.validUntil" class="pd-validity-date">
106
+ {{ v.validUntil.slice(0, 10) }}
107
+ </span>
108
+ <span v-else class="pd-arrow-inf" style="font-size: 14px">∞</span>
109
+ </div>
110
+ <span class="pd-validity-sub">
111
+ {{
112
+ statusOf(v) === 'draft'
113
+ ? 'geplant'
114
+ : statusOf(v) === 'live'
115
+ ? 'aktiv'
116
+ : 'historisch'
117
+ }}
118
+ </span>
119
+ </div>
120
+ </div>
121
+ <div>
122
+ <div>
123
+ <div class="pd-pricing-m">{{ formatMoney(v.monthlyNet) }} / Mo</div>
124
+ <div class="pd-pricing-y">{{ formatMoney(v.yearlyNet) }} / Jahr</div>
125
+ </div>
126
+ </div>
127
+ <div>
128
+ <div>
129
+ <div class="pd-impact-num">{{ impactByVersion[v.version] ?? 0 }}</div>
130
+ <div class="pd-impact-sub">Mandanten</div>
131
+ </div>
132
+ </div>
133
+ <div>
134
+ <span class="pd-change-note" :title="v.changeNote ?? ''">
135
+ {{ v.changeNote || '—' }}
136
+ </span>
137
+ </div>
138
+ <div class="pd-row-actions" @click.stop>
139
+ <span
140
+ v-if="editabilityOf(v).reason === 'pre-active'"
141
+ class="pd-pre-active-chip"
142
+ :title="
143
+ 'Published, aber noch nicht aktiv — Features, Quotas und ' +
144
+ 'Preis können bis zum Aktivierungsdatum noch korrigiert werden'
145
+ "
146
+ >
147
+ editierbar · noch nicht aktiv
148
+ </span>
149
+ <template v-if="statusOf(v) === 'draft'">
150
+ <button
151
+ class="btn btn--sm primary"
152
+ type="button"
153
+ title="Draft veröffentlichen"
154
+ @click="$emit('publish', v)"
155
+ >
156
+ <svg
157
+ width="12"
158
+ height="12"
159
+ viewBox="0 0 24 24"
160
+ fill="none"
161
+ stroke="currentColor"
162
+ stroke-width="2"
163
+ >
164
+ <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" />
165
+ </svg>
166
+ </button>
167
+ </template>
168
+ <template v-if="editabilityOf(v).editable">
169
+ <button
170
+ class="btn btn--sm"
171
+ type="button"
172
+ :title="
173
+ editabilityOf(v).reason === 'pre-active'
174
+ ? 'Future-Version bearbeiten'
175
+ : 'Draft bearbeiten'
176
+ "
177
+ @click="$emit('editDraft', v)"
178
+ >
179
+ <svg
180
+ width="12"
181
+ height="12"
182
+ viewBox="0 0 24 24"
183
+ fill="none"
184
+ stroke="currentColor"
185
+ stroke-width="2"
186
+ >
187
+ <path
188
+ d="M12 20h9M16.5 3.5a2.12 2.12 0 113 3L7 19l-4 1 1-4 12.5-12.5z"
189
+ />
190
+ </svg>
191
+ </button>
192
+ </template>
193
+ <template v-if="statusOf(v) === 'live'">
194
+ <span
195
+ v-if="v.endsAt"
196
+ class="pd-endsat-badge"
197
+ :title="`Endet am ${formatDate(v.endsAt)}`"
198
+ >
199
+ Endet {{ formatDate(v.endsAt) }}
200
+ </span>
201
+ <button
202
+ class="btn btn--sm"
203
+ type="button"
204
+ :title="v.endsAt ? 'Enddatum ändern' : 'Version terminieren'"
205
+ @click="$emit('openTerminate', v)"
206
+ >
207
+ <svg
208
+ width="12"
209
+ height="12"
210
+ viewBox="0 0 24 24"
211
+ fill="none"
212
+ stroke="currentColor"
213
+ stroke-width="2"
214
+ >
215
+ <rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
216
+ <line x1="16" y1="2" x2="16" y2="6" />
217
+ <line x1="8" y1="2" x2="8" y2="6" />
218
+ <line x1="3" y1="10" x2="21" y2="10" />
219
+ </svg>
220
+ <span>{{ v.endsAt ? 'Enddatum…' : 'Terminieren…' }}</span>
221
+ </button>
222
+ </template>
223
+ </div>
224
+ </div>
225
+ </div>
226
+ </section>
227
+ </template>
228
+
229
+ <script setup lang="ts">
230
+ import type { PlanVersionRow } from '@saasicat/types';
231
+ import type { EditabilityOf, StatusChipOf, StatusOf } from './types.js';
232
+
233
+ defineProps<{
234
+ chronological: PlanVersionRow[];
235
+ tableRows: PlanVersionRow[];
236
+ selectedId: string | null;
237
+ draftVersion: PlanVersionRow | null;
238
+ nextDraftVersion: number;
239
+ timelineTicks: string[];
240
+ impactByVersion: Record<number, number>;
241
+ statusOf: StatusOf;
242
+ statusChip: StatusChipOf;
243
+ editabilityOf: EditabilityOf;
244
+ formatMoney: (raw: string | number) => string;
245
+ formatDate: (iso: string | null | undefined) => string;
246
+ }>();
247
+
248
+ defineEmits<{
249
+ (e: 'update:selectedId', value: string | null): void;
250
+ (e: 'createDraft'): void;
251
+ (e: 'publish', version: PlanVersionRow): void;
252
+ (e: 'editDraft', version: PlanVersionRow): void;
253
+ (e: 'openTerminate', version: PlanVersionRow): void;
254
+ }>();
255
+ </script>
@@ -0,0 +1,59 @@
1
+ import type { PlanVersionRow } from '@saasicat/types';
2
+
3
+ export interface AuditRow {
4
+ id: string;
5
+ createdAt: string;
6
+ action: string;
7
+ entity: string;
8
+ entityId: string;
9
+ changes: Record<string, unknown> | null;
10
+ user?: { email: string; firstName?: string; lastName?: string } | null;
11
+ userEmail?: string | null;
12
+ }
13
+
14
+ export interface DiscoveryQuota {
15
+ quotaKey: string;
16
+ label?: string | null;
17
+ unit?: string | null;
18
+ }
19
+
20
+ export interface BundleEntry {
21
+ bundleKey: string;
22
+ label?: string | null;
23
+ features: string[];
24
+ }
25
+
26
+ export interface FeatureMeta {
27
+ label?: string;
28
+ }
29
+
30
+ export type PlanVersionStatus = 'draft' | 'live' | 'superseded';
31
+
32
+ export interface PlanVersionEditability {
33
+ editable: boolean;
34
+ reason: 'draft' | 'pre-active' | null;
35
+ }
36
+
37
+ export interface PlanVersionDiff {
38
+ featuresAdded: string[];
39
+ featuresRemoved: string[];
40
+ quotasAdded: Array<{ key: string; value: number }>;
41
+ quotasRemoved: Array<{ key: string; value: number }>;
42
+ quotasChanged: Array<{ key: string; from: number; to: number }>;
43
+ priceChanged: boolean;
44
+ }
45
+
46
+ export interface DiffRow {
47
+ id: string;
48
+ kind: 'add' | 'rm' | 'mod';
49
+ sign: string;
50
+ tag: string;
51
+ label: string;
52
+ key: string;
53
+ from?: string;
54
+ to?: string;
55
+ }
56
+
57
+ export type StatusOf = (version: PlanVersionRow) => PlanVersionStatus;
58
+ export type StatusChipOf = (version: PlanVersionRow) => string;
59
+ export type EditabilityOf = (version: PlanVersionRow) => PlanVersionEditability;