Files
HartOMat/frontend/src/api/dashboard.ts
T
Hartmut f0dd952f63 feat: material alias seeds expansion, bulk product delete, dashboard stats widgets
- Material alias seeds: 95 → 855 aliases covering German variants, DIN standards,
  Werkstoffnummern, industry terms, English equivalents, polymer abbreviations
- Batch product delete/deactivate endpoint (POST /products/batch-delete)
- Multi-select UI on Products page with floating action bar
- Dashboard: RenderThroughput + MaterialCoverage widgets
- Dashboard stats endpoint (GET /admin/dashboard-stats)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 12:45:41 +01:00

119 lines
2.8 KiB
TypeScript

import api from './client'
export type WidgetType =
| 'ProductionStats'
| 'QueueStatus'
| 'RecentRenders'
| 'CostOverview'
| 'WorkerStatus'
| 'KPISummary'
| 'OrderThroughput'
| 'RevenueChart'
| 'ItemStatus'
| 'ProcessingTimes'
| 'RenderTimeByOutputType'
| 'OutputTypeUsage'
| 'TopProducts'
| 'OrdersByUser'
| 'RenderBackendStats'
| 'RenderThroughput'
| 'MaterialCoverage'
export interface WidgetPosition {
col: number
row: number
w: number
h: number
}
export interface WidgetConfig {
widget_type: WidgetType
position: WidgetPosition
config?: Record<string, unknown>
}
interface DashboardConfigResponse {
widgets: WidgetConfig[]
}
export async function getDashboardConfig(): Promise<WidgetConfig[]> {
const { data } = await api.get<DashboardConfigResponse>('/dashboard/config')
return data.widgets
}
export async function updateDashboardConfig(
widgets: WidgetConfig[]
): Promise<WidgetConfig[]> {
const { data } = await api.put<DashboardConfigResponse>('/dashboard/config', {
widgets,
})
return data.widgets
}
export async function getTenantDefaultDashboard(): Promise<WidgetConfig[]> {
const { data } = await api.get<DashboardConfigResponse>(
'/dashboard/tenant-default'
)
return data.widgets
}
export async function updateTenantDefaultDashboard(
widgets: WidgetConfig[]
): Promise<WidgetConfig[]> {
const { data } = await api.put<DashboardConfigResponse>(
'/dashboard/tenant-default',
{ widgets }
)
return data.widgets
}
// ── Dashboard Stats ──────────────────────────────────────────────────────────
export interface RenderThroughputStats {
completed_today: number
completed_this_week: number
completed_this_month: number
failed_today: number
failed_this_week: number
failed_this_month: number
avg_render_time_s: number | null
median_render_time_s: number | null
}
export interface MaterialCoverageStats {
total_unique_materials: number
mapped_materials: number
unmapped_materials: number
coverage_pct: number
library_material_count: number
alias_count: number
}
export interface ProductStatsOverview {
total_products: number
with_step_files: number
without_step_files: number
step_coverage_pct: number
}
export interface OrderStatusBreakdown {
draft: number
submitted: number
processing: number
completed: number
rejected: number
total: number
}
export interface DashboardStats {
render_throughput: RenderThroughputStats
material_coverage: MaterialCoverageStats
product_stats: ProductStatsOverview
order_status: OrderStatusBreakdown
}
export async function getDashboardStats(): Promise<DashboardStats> {
const { data } = await api.get<DashboardStats>('/admin/dashboard-stats')
return data
}