mirror of
https://github.com/azaion/ui.git
synced 2026-06-21 13:51:11 +00:00
434854bf3c
- Design system: v2 CSS variables (surface-0/1/2, border-hair, accent-amber/cyan/red/green/blue)
and utility classes (.btn, .inp, .pill, .chip, .bracket, .panel, .seg, .swatch,
.type-sq, .grid-bg, .ibtn, .checkbox, .tab); v1 az-* names aliased to v2 vars
so other pages still render. Google Fonts (IBM Plex Sans + JetBrains Mono)
loaded via <link> in index.html <head> to avoid FOUT.
- Header rebuilt to v2: amber wordmark + // divider, amber-bordered flight pill
with cyan live dot, tab-style nav with amber underline on active, LINK status
pill, cog + sign-out icon buttons.
- AdminPage rewritten to 3-column layout (340 / flex / 280):
- Detection Classes: search + ADD button, table with #/Name/Hex/Ops columns,
name-only inline edit with ringed swatch, sibling-row error alert.
- AI Recognition Engine + GPS Device Link panels with corner-bracket borders,
number steppers, segmented protocol control, dashed telemetry footers.
Hooks (useAiSettings, useGpsSettings) seed factory defaults so the UI is
interactive when GET fails (no backend).
- Default Aircrafts: P/C/F type chips, isDefault star toggle, + ADD AIRCRAFT
modal with model/type/resolution/maxMinutes/default fields.
- Co-located components: Modal (backdrop + ESC + body-scroll-lock),
NumberStepper (▲▼ with clamp on click but not on typing), ClassEditRow.
- Types: Aircraft extended with FixedWing + optional resolution/maxMinutes;
new AiRecognitionSettings/Telemetry, GpsDeviceSettings/Telemetry, GpsProtocol.
- Endpoints: /api/admin/ai-settings, /api/admin/gps-settings (+ /ping, /reconnect).
POST /api/flights/aircrafts (plural REST collection).
- MSW: stateful admin-settings handler with resetAdminSettingsSeed() wired into
tests/setup.ts. Aircraft seed expanded to 6 entries matching the mockup.
- i18n: full admin.{classes,aiEngine,gpsDevice,aircrafts} key sets in en+ua;
nav.dataset shortened to "Dataset"; obsolete users-management keys removed.
- Tests: new AdminPage AI/GPS/aircraft test suites; admin_class_edit selectors
updated for the name-only inline editor and the modal-based add flow.
88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
import { http } from 'msw'
|
|
import { jsonResponse, noContent } from '../helpers'
|
|
import type {
|
|
AiRecognitionSettings,
|
|
AiRecognitionTelemetry,
|
|
GpsDeviceSettings,
|
|
GpsDeviceTelemetry,
|
|
} from '../../../src/types'
|
|
|
|
// Stateful MSW handlers for AI Recognition + GPS Device Link settings.
|
|
// Seed mutates on PATCH so PING / RECONNECT / APPLY round-trips persist
|
|
// within a session. `resetAdminSettingsSeed()` is invoked per-test from
|
|
// tests/setup.ts so test isolation is preserved.
|
|
|
|
const DEFAULT_AI_SETTINGS: AiRecognitionSettings = {
|
|
framesToRecognize: 4,
|
|
minSecondsBetween: 2,
|
|
minConfidence: 25,
|
|
}
|
|
|
|
const DEFAULT_AI_TELEMETRY: AiRecognitionTelemetry = {
|
|
model: 'YOLOV8-X',
|
|
checkpoint: 'CKPT-241',
|
|
lastRunAt: '2026-05-18T11:43:09Z',
|
|
frames: 14228,
|
|
avgConfidence: 71.4,
|
|
}
|
|
|
|
const DEFAULT_GPS_SETTINGS: GpsDeviceSettings = {
|
|
address: '192.168.1.100',
|
|
port: 9001,
|
|
protocol: 'NMEA',
|
|
}
|
|
|
|
const DEFAULT_GPS_TELEMETRY: GpsDeviceTelemetry = {
|
|
socket: 'UDP/192.168.1.100:9001',
|
|
connected: true,
|
|
fix: '3D',
|
|
satellites: 11,
|
|
hdop: 0.82,
|
|
lastPacketMs: 12,
|
|
}
|
|
|
|
let aiSettings: AiRecognitionSettings = { ...DEFAULT_AI_SETTINGS }
|
|
let aiTelemetry: AiRecognitionTelemetry = { ...DEFAULT_AI_TELEMETRY }
|
|
let gpsSettings: GpsDeviceSettings = { ...DEFAULT_GPS_SETTINGS }
|
|
let gpsTelemetry: GpsDeviceTelemetry = { ...DEFAULT_GPS_TELEMETRY }
|
|
|
|
export function resetAdminSettingsSeed() {
|
|
aiSettings = { ...DEFAULT_AI_SETTINGS }
|
|
aiTelemetry = { ...DEFAULT_AI_TELEMETRY }
|
|
gpsSettings = { ...DEFAULT_GPS_SETTINGS }
|
|
gpsTelemetry = { ...DEFAULT_GPS_TELEMETRY }
|
|
}
|
|
|
|
export const adminSettingsHandlers = [
|
|
http.get('/api/admin/ai-settings', () =>
|
|
jsonResponse({ settings: aiSettings, telemetry: aiTelemetry }),
|
|
),
|
|
|
|
http.patch('/api/admin/ai-settings', async ({ request }) => {
|
|
const body = (await request.json().catch(() => ({}))) as Partial<AiRecognitionSettings>
|
|
aiSettings = { ...aiSettings, ...body }
|
|
return jsonResponse({ settings: aiSettings, telemetry: aiTelemetry })
|
|
}),
|
|
|
|
http.get('/api/admin/gps-settings', () =>
|
|
jsonResponse({ settings: gpsSettings, telemetry: gpsTelemetry }),
|
|
),
|
|
|
|
http.patch('/api/admin/gps-settings', async ({ request }) => {
|
|
const body = (await request.json().catch(() => ({}))) as Partial<GpsDeviceSettings>
|
|
gpsSettings = { ...gpsSettings, ...body }
|
|
gpsTelemetry = {
|
|
...gpsTelemetry,
|
|
socket: `UDP/${gpsSettings.address}:${gpsSettings.port}`,
|
|
}
|
|
return jsonResponse({ settings: gpsSettings, telemetry: gpsTelemetry })
|
|
}),
|
|
|
|
http.post('/api/admin/gps-settings/ping', () => noContent()),
|
|
|
|
http.post('/api/admin/gps-settings/reconnect', () => {
|
|
gpsTelemetry = { ...gpsTelemetry, connected: true, lastPacketMs: 0 }
|
|
return jsonResponse({ settings: gpsSettings, telemetry: gpsTelemetry })
|
|
}),
|
|
]
|