- Implemented HTML pages for datasets, models, training, testing, and results. - Created API endpoints for managing repositories, results, tests, and training sessions. - Added functionality for streaming training progress via Server-Sent Events (SSE). - Introduced a Dockerfile for the ML runner with necessary dependencies. - Developed an SDK for user code execution within the runner container. - Enhanced CSS styles for improved UI layout and navigation. - Established a layout template for consistent HTML structure across pages. - Added JavaScript for dynamic interactions on the models page. - Implemented WebSocket handling for real-time communication with kiosk devices and controllers. - Implemented model registration and management API at /api/models - Added Gitea proxy API for repository interactions at /api/repos - Created results API for listing and comparing training results at /api/results - Developed training management API for enqueueing and retrieving training jobs at /api/trainings - Introduced SSE endpoint for live training progress updates - Added HTML pages for models, datasets, and training management - Created a Dockerfile for the ML runner with necessary dependencies - Developed SDK for user code execution within the runner container - Enhanced CSS styles for improved UI/UX - Implemented WebSocket communication for real-time device and controller interactions in the kiosk system
147 lines
3.2 KiB
CSS
147 lines
3.2 KiB
CSS
.ml-nav {
|
|
display: flex;
|
|
gap: 16px;
|
|
align-items: center;
|
|
}
|
|
.ml-nav a {
|
|
text-decoration: none;
|
|
color: var(--text-secondary);
|
|
font-weight: 600;
|
|
padding: 8px 12px;
|
|
border-radius: var(--radius-md);
|
|
transition: all 0.2s ease;
|
|
}
|
|
.ml-nav a:hover { background: var(--accent-light); color: var(--accent-color); }
|
|
.ml-nav a.active { background: var(--accent-light); color: var(--accent-color); }
|
|
|
|
.container {
|
|
max-width: 1200px;
|
|
margin: 24px auto;
|
|
padding: 0 24px;
|
|
}
|
|
|
|
.page-head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 20px;
|
|
}
|
|
.page-head h2 { font-size: 1.5rem; }
|
|
|
|
.list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
.list .item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 12px 16px;
|
|
border: 1px solid var(--header-border);
|
|
border-radius: var(--radius-lg);
|
|
background: #fff;
|
|
transition: box-shadow 0.12s ease;
|
|
}
|
|
.list .item:hover { box-shadow: var(--shadow-md); }
|
|
.list .meta { color: var(--text-secondary); font-size: 0.85rem; }
|
|
|
|
.form-row {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 12px;
|
|
align-items: flex-end;
|
|
margin-bottom: 20px;
|
|
}
|
|
.form-row label {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
font-size: 0.85rem;
|
|
color: var(--text-secondary);
|
|
}
|
|
.form-row input, .form-row select, .form-row textarea {
|
|
padding: 8px 12px;
|
|
border: 1px solid var(--header-border);
|
|
border-radius: var(--radius-md);
|
|
font-family: inherit;
|
|
}
|
|
|
|
.hidden { display: none !important; }
|
|
|
|
.queue-info {
|
|
font-size: 0.9rem;
|
|
color: var(--text-secondary);
|
|
padding: 6px 12px;
|
|
background: var(--accent-light);
|
|
border-radius: var(--radius-md);
|
|
}
|
|
|
|
.charts {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 16px;
|
|
margin: 16px 0;
|
|
}
|
|
|
|
.logs {
|
|
background: #0f172a;
|
|
color: #cbd5e1;
|
|
padding: 12px;
|
|
border-radius: var(--radius-md);
|
|
font-family: ui-monospace, monospace;
|
|
font-size: 0.8rem;
|
|
max-height: 320px;
|
|
overflow: auto;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
.detail {
|
|
border: 1px solid var(--header-border);
|
|
border-radius: var(--radius-lg);
|
|
padding: 16px;
|
|
margin-top: 16px;
|
|
background: #fff;
|
|
position: relative;
|
|
}
|
|
.detail #btn-close-detail {
|
|
position: absolute;
|
|
top: 8px;
|
|
right: 8px;
|
|
padding: 4px 10px;
|
|
}
|
|
|
|
dialog {
|
|
border: 1px solid var(--header-border);
|
|
border-radius: var(--radius-lg);
|
|
padding: 24px;
|
|
width: min(500px, 90vw);
|
|
}
|
|
dialog form { display: flex; flex-direction: column; gap: 12px; }
|
|
dialog label { display: flex; flex-direction: column; gap: 4px; font-size: 0.85rem; }
|
|
dialog menu { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; padding: 0; }
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin-top: 12px;
|
|
}
|
|
th, td { padding: 8px 12px; border-bottom: 1px solid var(--header-border); text-align: left; font-size: 0.9rem; }
|
|
|
|
code {
|
|
font-family: ui-monospace, monospace;
|
|
background: #f1f5f9;
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
font-size: 0.85em;
|
|
}
|
|
|
|
pre {
|
|
background: #f8fafc;
|
|
padding: 12px;
|
|
border-radius: var(--radius-md);
|
|
overflow: auto;
|
|
font-family: ui-monospace, monospace;
|
|
font-size: 0.8rem;
|
|
}
|