@littlebearapps/platform-admin-sdk 2.1.0 → 2.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 (115) hide show
  1. package/README.md +2 -5
  2. package/dist/templates.d.ts +1 -1
  3. package/dist/templates.js +121 -3
  4. package/package.json +1 -1
  5. package/templates/full/dashboard/src/components/notifications/NotificationDropdown.tsx +130 -0
  6. package/templates/full/dashboard/src/components/notifications/NotificationItem.tsx +264 -0
  7. package/templates/full/dashboard/src/components/patterns/PatternInfoButton.tsx +60 -0
  8. package/templates/full/dashboard/src/components/reports/FeatureUsageReport.tsx +339 -0
  9. package/templates/full/dashboard/src/components/search/SearchResultGroup.tsx +46 -0
  10. package/templates/full/dashboard/src/components/search/SearchResultItem.tsx +212 -0
  11. package/templates/full/dashboard/src/pages/api/patterns/[id]/approve.ts +49 -0
  12. package/templates/full/dashboard/src/pages/api/patterns/[id]/reject.ts +50 -0
  13. package/templates/full/dashboard/src/pages/api/reports/digests/stats.ts +38 -0
  14. package/templates/full/dashboard/src/pages/api/reports/digests.ts +39 -0
  15. package/templates/full/dashboard/src/pages/api/search/reindex/[type].ts +56 -0
  16. package/templates/full/dashboard/src/pages/api/test-reports/[id].ts +102 -0
  17. package/templates/full/dashboard/src/pages/feedback.astro +365 -0
  18. package/templates/full/dashboard/src/pages/kiosk.astro +206 -0
  19. package/templates/full/dashboard/src/pages/map.astro +561 -0
  20. package/templates/full/dashboard/src/pages/revenue.astro +72 -0
  21. package/templates/full/dashboard/src/pages/tests.astro +431 -0
  22. package/templates/full/scripts/ops/audit-cost-anomaly.ts +430 -0
  23. package/templates/full/scripts/ops/verify-account-total.ts +256 -0
  24. package/templates/full/tests/integration/feedback-schema.test.ts +361 -0
  25. package/templates/full/tests/integration/r2-archive.test.ts +108 -0
  26. package/templates/shared/.github/workflows/dependabot-automerge.yml +41 -0
  27. package/templates/shared/.github/workflows/validate-controls.yml +27 -0
  28. package/templates/shared/dashboard/src/components/Breadcrumbs.astro +101 -0
  29. package/templates/shared/dashboard/src/components/EmptyState.astro +46 -0
  30. package/templates/shared/dashboard/src/components/ErrorBoundary.astro +79 -0
  31. package/templates/shared/dashboard/src/components/LoadingSkeleton.astro +105 -0
  32. package/templates/shared/dashboard/src/components/PageShell.astro +72 -0
  33. package/templates/shared/dashboard/src/components/SkipLinks.astro +22 -0
  34. package/templates/shared/dashboard/src/components/Toast.astro +170 -0
  35. package/templates/shared/dashboard/src/components/ToastContainer.astro +156 -0
  36. package/templates/shared/dashboard/src/components/costs/ProviderCostsGrid.tsx +401 -0
  37. package/templates/shared/dashboard/src/components/costs/index.ts +4 -0
  38. package/templates/shared/dashboard/src/components/overview/AlertBanner.tsx +94 -0
  39. package/templates/shared/dashboard/src/components/overview/index.ts +9 -0
  40. package/templates/shared/dashboard/src/components/resources/CostChart.tsx +170 -0
  41. package/templates/shared/dashboard/src/components/resources/ProviderCard.tsx +272 -0
  42. package/templates/shared/dashboard/src/components/resources/ProviderDetail.tsx +293 -0
  43. package/templates/shared/dashboard/src/components/settings/SettingsCard.astro +102 -0
  44. package/templates/shared/dashboard/src/components/usage/AllowanceGauge.astro +170 -0
  45. package/templates/shared/dashboard/src/components/usage/AnomalyAlerts.astro +633 -0
  46. package/templates/shared/dashboard/src/components/usage/BillingCycleCountdown.astro +192 -0
  47. package/templates/shared/dashboard/src/components/usage/BurnRateHero.astro +539 -0
  48. package/templates/shared/dashboard/src/components/usage/CircuitBreakerEventLog.astro +542 -0
  49. package/templates/shared/dashboard/src/components/usage/CircuitBreakerPanel.tsx +292 -0
  50. package/templates/shared/dashboard/src/components/usage/CircuitBreakerStatus.astro +669 -0
  51. package/templates/shared/dashboard/src/components/usage/CompactThresholdBanner.astro +531 -0
  52. package/templates/shared/dashboard/src/components/usage/ComparisonModeSelector.astro +651 -0
  53. package/templates/shared/dashboard/src/components/usage/CostBreakdownChart.astro +381 -0
  54. package/templates/shared/dashboard/src/components/usage/CostBreakdownTable.astro +210 -0
  55. package/templates/shared/dashboard/src/components/usage/CostDataTable.astro +0 -0
  56. package/templates/shared/dashboard/src/components/usage/CostDonutChart.astro +311 -0
  57. package/templates/shared/dashboard/src/components/usage/DailyCostChart.astro +632 -0
  58. package/templates/shared/dashboard/src/components/usage/ExportButton.astro +114 -0
  59. package/templates/shared/dashboard/src/components/usage/FeatureBudgetsTable.astro +872 -0
  60. package/templates/shared/dashboard/src/components/usage/FilterBar.astro +190 -0
  61. package/templates/shared/dashboard/src/components/usage/FilterToggles.astro +175 -0
  62. package/templates/shared/dashboard/src/components/usage/GitHubUsageCard.astro +537 -0
  63. package/templates/shared/dashboard/src/components/usage/OverageCostCard.astro +212 -0
  64. package/templates/shared/dashboard/src/components/usage/PlanUtilizationCard.astro +193 -0
  65. package/templates/shared/dashboard/src/components/usage/ProjectCard.astro +640 -0
  66. package/templates/shared/dashboard/src/components/usage/ProjectCardsGrid.astro +272 -0
  67. package/templates/shared/dashboard/src/components/usage/ResourceSearch.astro +279 -0
  68. package/templates/shared/dashboard/src/components/usage/ServiceUtilizationList.astro +604 -0
  69. package/templates/shared/dashboard/src/components/usage/SparklineCard.astro +399 -0
  70. package/templates/shared/dashboard/src/components/usage/StatsHero.astro +600 -0
  71. package/templates/shared/dashboard/src/components/usage/TableFilters.astro +1033 -0
  72. package/templates/shared/dashboard/src/components/usage/ThresholdAlert.astro +271 -0
  73. package/templates/shared/dashboard/src/components/usage/ThresholdSettings.astro +618 -0
  74. package/templates/shared/dashboard/src/components/usage/TopSpenderCard.astro +170 -0
  75. package/templates/shared/dashboard/src/components/usage/UnifiedResourceTable.astro +1737 -0
  76. package/templates/shared/dashboard/src/components/usage/UsageCard.astro +135 -0
  77. package/templates/shared/dashboard/src/components/usage/UsageHealthBanner.astro +387 -0
  78. package/templates/shared/dashboard/src/components/usage/UtilizationBar.astro +159 -0
  79. package/templates/shared/dashboard/src/components/usage/WorkersBreakdownTable.astro +659 -0
  80. package/templates/shared/dashboard/src/components/usage/daily/CostChart.astro +461 -0
  81. package/templates/shared/dashboard/src/components/usage/daily/CostTable.astro +946 -0
  82. package/templates/shared/dashboard/src/components/usage/daily/DailyOverview.astro +1079 -0
  83. package/templates/shared/dashboard/src/components/usage/design-tokens.ts +187 -0
  84. package/templates/shared/dashboard/src/components/usage/filters/InlineDateRange.astro +285 -0
  85. package/templates/shared/dashboard/src/components/usage/filters/PeriodButtons.astro +157 -0
  86. package/templates/shared/dashboard/src/components/usage/filters/ProjectSelect.astro +284 -0
  87. package/templates/shared/dashboard/src/components/usage/scripts/ai-tab-controller.ts +419 -0
  88. package/templates/shared/dashboard/src/components/usage/scripts/constants.ts +60 -0
  89. package/templates/shared/dashboard/src/components/usage/scripts/formatters.ts +62 -0
  90. package/templates/shared/dashboard/src/components/usage/scripts/overview-controller.ts +1633 -0
  91. package/templates/shared/dashboard/src/components/usage/scripts/resource-table-builder.ts +294 -0
  92. package/templates/shared/dashboard/src/components/usage/scripts/tabs-filters-controller.ts +464 -0
  93. package/templates/shared/dashboard/src/components/usage/state/index.ts +55 -0
  94. package/templates/shared/dashboard/src/components/usage/state/usageActions.ts +439 -0
  95. package/templates/shared/dashboard/src/components/usage/state/usageStore.ts +376 -0
  96. package/templates/shared/dashboard/src/components/usage/types.ts +283 -0
  97. package/templates/shared/dashboard/src/components/usage/usage-colors.ts +292 -0
  98. package/templates/shared/dashboard/src/pages/api/usage/ai-models.ts +235 -0
  99. package/templates/shared/dashboard/src/pages/api/usage/billing-context.ts +296 -0
  100. package/templates/shared/scripts/test-telemetry-flow.ts +464 -0
  101. package/templates/shared/tests/e2e/usage-export.test.ts +784 -0
  102. package/templates/shared/tests/e2e/usage-mobile.test.ts +531 -0
  103. package/templates/standard/dashboard/src/components/errors/PriorityBadge.astro +27 -0
  104. package/templates/standard/dashboard/src/components/infrastructure/HealthchecksStatus.tsx +293 -0
  105. package/templates/standard/dashboard/src/components/infrastructure/InfrastructureTabs.tsx +268 -0
  106. package/templates/standard/dashboard/src/pages/analytics.astro +64 -0
  107. package/templates/standard/dashboard/src/pages/api/infrastructure/alerts.ts +85 -0
  108. package/templates/standard/dashboard/src/pages/api/infrastructure/healthchecks/[id]/flips.ts +110 -0
  109. package/templates/standard/dashboard/src/pages/api/infrastructure/healthchecks.ts +101 -0
  110. package/templates/standard/dashboard/src/pages/api/infrastructure/uptime/[id]/response-times.ts +121 -0
  111. package/templates/standard/dashboard/src/pages/api/infrastructure/uptime.ts +89 -0
  112. package/templates/standard/dashboard/src/pages/api/test/service-auth.ts +178 -0
  113. package/templates/standard/tests/integration/connectors.test.ts +241 -0
  114. package/templates/standard/tests/integration/github-monitor.test.ts +143 -0
  115. package/templates/standard/tests/integration/ingestion.test.ts +211 -0
@@ -0,0 +1,311 @@
1
+ ---
2
+ /**
3
+ * CostDonutChart Component
4
+ *
5
+ * Visual donut chart showing cost breakdown by resource type.
6
+ * Uses Chart.js for rendering with center text showing total.
7
+ */
8
+
9
+ export interface CostItem {
10
+ label: string;
11
+ amount: number;
12
+ colour: string;
13
+ }
14
+
15
+ interface Props {
16
+ items: CostItem[];
17
+ totalCost: number;
18
+ currency?: string;
19
+ title?: string;
20
+ trend?: 'up' | 'down' | 'stable';
21
+ percentChange?: number;
22
+ chartId: string;
23
+ }
24
+
25
+ const {
26
+ items,
27
+ totalCost,
28
+ currency = '$',
29
+ title = 'Cost Breakdown',
30
+ trend = 'stable',
31
+ percentChange = 0,
32
+ chartId,
33
+ } = Astro.props;
34
+
35
+ // Trend colours (for costs, down is good)
36
+ const trendColour = trend === 'stable' ? '#6B7280' : trend === 'up' ? '#EF4444' : '#10B981';
37
+ const trendArrow = trend === 'up' ? '↑' : trend === 'down' ? '↓' : '→';
38
+
39
+ // Format currency amount
40
+ function formatCurrency(amount: number): string {
41
+ if (amount >= 1000) {
42
+ return `${currency}${(amount / 1000).toFixed(1)}K`;
43
+ }
44
+ return `${currency}${amount.toFixed(2)}`;
45
+ }
46
+
47
+ // Prepare chart data for client-side
48
+ const chartData = {
49
+ labels: items.map((item) => item.label),
50
+ amounts: items.map((item) => item.amount),
51
+ colours: items.map((item) => item.colour),
52
+ totalFormatted: formatCurrency(totalCost),
53
+ };
54
+ ---
55
+
56
+ <div class="cost-donut-container">
57
+ <div class="chart-header">
58
+ <h3 class="chart-title">{title}</h3>
59
+ {
60
+ trend !== 'stable' && (
61
+ <div
62
+ class="trend-badge"
63
+ style={`color: ${trendColour}; background-color: ${trendColour}15;`}
64
+ >
65
+ <span class="trend-arrow">{trendArrow}</span>
66
+ <span class="trend-value">{Math.abs(percentChange).toFixed(1)}%</span>
67
+ </div>
68
+ )
69
+ }
70
+ </div>
71
+
72
+ <div class="chart-content">
73
+ <div class="chart-wrapper">
74
+ <canvas
75
+ id={`donut-${chartId}`}
76
+ class="donut-canvas"
77
+ aria-label={`${title}: ${formatCurrency(totalCost)}`}></canvas>
78
+ <div class="center-text">
79
+ <span class="total-value">{formatCurrency(totalCost)}</span>
80
+ <span class="total-label">Total</span>
81
+ </div>
82
+ </div>
83
+
84
+ <div class="legend">
85
+ {
86
+ items.map((item) => (
87
+ <div class="legend-item">
88
+ <span class="legend-colour" style={`background-color: ${item.colour};`} />
89
+ <span class="legend-label">{item.label}</span>
90
+ <span class="legend-value">{formatCurrency(item.amount)}</span>
91
+ </div>
92
+ ))
93
+ }
94
+ </div>
95
+ </div>
96
+ </div>
97
+
98
+ <style>
99
+ .cost-donut-container {
100
+ background-color: white;
101
+ border: 1px solid #e5e7eb;
102
+ border-radius: 0.5rem;
103
+ padding: 1rem;
104
+ }
105
+
106
+ :global(.dark) .cost-donut-container {
107
+ background-color: #1f2937;
108
+ border-color: #374151;
109
+ }
110
+
111
+ .chart-header {
112
+ display: flex;
113
+ align-items: center;
114
+ justify-content: space-between;
115
+ margin-bottom: 1rem;
116
+ }
117
+
118
+ .chart-title {
119
+ font-size: 0.875rem;
120
+ font-weight: 600;
121
+ color: #374151;
122
+ margin: 0;
123
+ }
124
+
125
+ :global(.dark) .chart-title {
126
+ color: #d1d5db;
127
+ }
128
+
129
+ .trend-badge {
130
+ display: inline-flex;
131
+ align-items: center;
132
+ gap: 0.25rem;
133
+ padding: 0.125rem 0.375rem;
134
+ border-radius: 9999px;
135
+ font-size: 0.625rem;
136
+ font-weight: 600;
137
+ }
138
+
139
+ .trend-arrow {
140
+ font-size: 0.75rem;
141
+ }
142
+
143
+ .chart-content {
144
+ display: flex;
145
+ align-items: center;
146
+ gap: 1rem;
147
+ }
148
+
149
+ .chart-wrapper {
150
+ position: relative;
151
+ width: 120px;
152
+ height: 120px;
153
+ flex-shrink: 0;
154
+ }
155
+
156
+ .donut-canvas {
157
+ width: 100% !important;
158
+ height: 100% !important;
159
+ }
160
+
161
+ .center-text {
162
+ position: absolute;
163
+ top: 50%;
164
+ left: 50%;
165
+ transform: translate(-50%, -50%);
166
+ text-align: center;
167
+ pointer-events: none;
168
+ }
169
+
170
+ .total-value {
171
+ display: block;
172
+ font-size: 1rem;
173
+ font-weight: 700;
174
+ color: #1f2937;
175
+ line-height: 1;
176
+ }
177
+
178
+ :global(.dark) .total-value {
179
+ color: #f9fafb;
180
+ }
181
+
182
+ .total-label {
183
+ font-size: 0.625rem;
184
+ color: #6b7280;
185
+ text-transform: uppercase;
186
+ letter-spacing: 0.05em;
187
+ }
188
+
189
+ :global(.dark) .total-label {
190
+ color: #9ca3af;
191
+ }
192
+
193
+ .legend {
194
+ flex: 1;
195
+ display: flex;
196
+ flex-direction: column;
197
+ gap: 0.375rem;
198
+ min-width: 0;
199
+ }
200
+
201
+ .legend-item {
202
+ display: flex;
203
+ align-items: center;
204
+ gap: 0.5rem;
205
+ font-size: 0.75rem;
206
+ }
207
+
208
+ .legend-colour {
209
+ width: 10px;
210
+ height: 10px;
211
+ border-radius: 2px;
212
+ flex-shrink: 0;
213
+ }
214
+
215
+ .legend-label {
216
+ flex: 1;
217
+ color: #6b7280;
218
+ white-space: nowrap;
219
+ overflow: hidden;
220
+ text-overflow: ellipsis;
221
+ }
222
+
223
+ :global(.dark) .legend-label {
224
+ color: #9ca3af;
225
+ }
226
+
227
+ .legend-value {
228
+ font-weight: 600;
229
+ color: #374151;
230
+ font-family: monospace;
231
+ font-size: 0.6875rem;
232
+ }
233
+
234
+ :global(.dark) .legend-value {
235
+ color: #d1d5db;
236
+ }
237
+
238
+ @media (max-width: 480px) {
239
+ .chart-content {
240
+ flex-direction: column;
241
+ }
242
+
243
+ .chart-wrapper {
244
+ width: 100px;
245
+ height: 100px;
246
+ }
247
+
248
+ .legend {
249
+ width: 100%;
250
+ }
251
+ }
252
+ </style>
253
+
254
+ <script define:vars={{ chartData, chartId }}>
255
+ document.addEventListener('DOMContentLoaded', async () => {
256
+ try {
257
+ const { Chart, registerables } = await import('chart.js');
258
+ Chart.register(...registerables);
259
+
260
+ const canvas = document.getElementById(`donut-${chartId}`);
261
+ if (!canvas) return;
262
+
263
+ const ctx = canvas.getContext('2d');
264
+ if (!ctx) return;
265
+
266
+ new Chart(ctx, {
267
+ type: 'doughnut',
268
+ data: {
269
+ labels: chartData.labels,
270
+ datasets: [
271
+ {
272
+ data: chartData.amounts,
273
+ backgroundColor: chartData.colours,
274
+ borderColor: 'transparent',
275
+ borderWidth: 0,
276
+ hoverOffset: 4,
277
+ },
278
+ ],
279
+ },
280
+ options: {
281
+ responsive: true,
282
+ maintainAspectRatio: true,
283
+ cutout: '65%',
284
+ plugins: {
285
+ legend: {
286
+ display: false,
287
+ },
288
+ tooltip: {
289
+ enabled: true,
290
+ backgroundColor: '#1f2937',
291
+ titleFont: { size: 11 },
292
+ bodyFont: { size: 11 },
293
+ padding: 8,
294
+ displayColors: true,
295
+ callbacks: {
296
+ label: (context) => {
297
+ const value = context.raw;
298
+ const total = chartData.amounts.reduce((a, b) => a + b, 0);
299
+ const percentage = total > 0 ? ((value / total) * 100).toFixed(1) : 0;
300
+ return ` $${value.toFixed(2)} (${percentage}%)`;
301
+ },
302
+ },
303
+ },
304
+ },
305
+ },
306
+ });
307
+ } catch (e) {
308
+ console.error('Failed to render donut chart:', e);
309
+ }
310
+ });
311
+ </script>