A29: Design System and Routing UI Drag-and-Drop
This commit is contained in:
parent
d5429da63d
commit
a8c37ca6e3
3 changed files with 492 additions and 1372 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -177,14 +177,48 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- 3. ROUTING VIEW (Main Control Center) -->
|
<!-- 3. ROUTING VIEW (Main Control Center) -->
|
||||||
<section id="view-routing" class="view-pane">
|
|
||||||
<div class="view-header-note">
|
<section id="view-routing" class="view-pane">
|
||||||
Главный центр управления маршрутизацией: перетаскивайте узлы для смены приоритета (Основной → Резерв 1 → Резерв 2), настраивайте рабочие модели и управляйте составом цепочек.
|
<div class="view-header-note" style="display:flex; justify-content: space-between; align-items: center;">
|
||||||
</div>
|
<div>
|
||||||
<div class="routing-pipelines-list" id="routing-pipelines-container">
|
<i class="fa-solid fa-circle-info" style="color:var(--status-warning);"></i>
|
||||||
<!-- Rendered by app.js -->
|
Перетащите аккаунт из правой панели в нужную роль и установите порядок (приоритет) использования.
|
||||||
</div>
|
<br>
|
||||||
</section>
|
Система будет использовать аккаунты сверху вниз по списку при выполнении задач с учётом квот и состояния.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="routing-grid" style="display: flex; gap: 24px; height: calc(100vh - 150px);">
|
||||||
|
<!-- LEFT COLUMN: Roles -->
|
||||||
|
<div class="routing-left-col" id="routing-roles-container" style="flex: 2; overflow-y: auto; padding-right: 8px;">
|
||||||
|
<!-- Rendered by app.js -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- RIGHT COLUMN: Available Accounts -->
|
||||||
|
<div class="routing-right-col" style="flex: 1; display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: var(--radius-md); background-color: var(--surface-muted);">
|
||||||
|
<div style="padding: 16px; border-bottom: 1px solid var(--border-subtle);">
|
||||||
|
<div style="display: flex; justify-content: space-between; margin-bottom: 12px;">
|
||||||
|
<h3 style="font-family: var(--font-title); font-size: 14px; text-transform: uppercase;">Доступные аккаунты</h3>
|
||||||
|
<span id="available-accounts-count" class="text-muted" style="font-size: 12px;">0 аккаунтов</span>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" id="routing-account-search" placeholder="Поиск по аккаунтам, ролям или моделям..." style="width: 100%;">
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; gap: 8px; margin-top: 8px;">
|
||||||
|
<select id="routing-filter-provider" style="flex:1;"><option value="all">Все провайдеры</option></select>
|
||||||
|
<select id="routing-filter-status" style="flex:1;"><option value="all">Все статусы</option></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="available-accounts-list" id="routing-available-container" style="flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 8px;">
|
||||||
|
<!-- Rendered by app.js -->
|
||||||
|
</div>
|
||||||
|
<div style="padding: 16px; text-align: center; font-size: 12px; color: var(--text-muted); border-top: 1px dashed var(--border-subtle);">
|
||||||
|
<i class="fa-solid fa-arrows-up-down-left-right"></i> Перетащите аккаунт в нужную роль или нажмите «+» для добавления
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<!-- 4. ANALYTICS VIEW (P0-1 & P0-5) -->
|
<!-- 4. ANALYTICS VIEW (P0-1 & P0-5) -->
|
||||||
<section id="view-analytics" class="view-pane">
|
<section id="view-analytics" class="view-pane">
|
||||||
|
|
@ -505,5 +539,16 @@
|
||||||
|
|
||||||
<!-- Application Logic -->
|
<!-- Application Logic -->
|
||||||
<script src="app.js"></script>
|
<script src="app.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const theme = urlParams.get('theme');
|
||||||
|
if (theme) {
|
||||||
|
document.body.setAttribute('data-theme', theme);
|
||||||
|
const sel = document.getElementById('theme-selector');
|
||||||
|
if (sel) sel.value = theme;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,7 @@
|
||||||
/* Hermes Hub Web Client — Dark Theme & Cockpit Design System */
|
|
||||||
|
|
||||||
|
/* Theme definitions according to A29 Design System "Крона" */
|
||||||
:root {
|
:root {
|
||||||
--bg-base: #061916;
|
/* Common variables */
|
||||||
--bg-sidebar: #08221E;
|
|
||||||
--bg-header: #071B18;
|
|
||||||
--bg-statusbar: #061512;
|
|
||||||
--bg-modal-backdrop: rgba(2, 11, 9, 0.85);
|
|
||||||
|
|
||||||
--surface: #0B2520;
|
|
||||||
--surface-hover: #12342C;
|
|
||||||
--surface-active: #194535;
|
|
||||||
--surface-selected: #173B2E;
|
|
||||||
--surface-muted: #091E1A;
|
|
||||||
|
|
||||||
--border: #36513B;
|
|
||||||
--border-subtle: #203A2D;
|
|
||||||
--border-accent: #B78525;
|
|
||||||
--border-hover: #537456;
|
|
||||||
|
|
||||||
--text-primary: #F8F0DC;
|
|
||||||
--text-secondary: #D1C7AE;
|
|
||||||
--text-muted: #8FA395;
|
|
||||||
--text-accent: #E0B84E;
|
|
||||||
|
|
||||||
--accent: #C89A2B;
|
|
||||||
--accent-hover: #E0B84E;
|
|
||||||
--accent-pressed: #A9781E;
|
|
||||||
--accent-dim: rgba(200, 154, 43, 0.15);
|
|
||||||
|
|
||||||
--status-healthy: #72C943;
|
--status-healthy: #72C943;
|
||||||
--status-warning: #E1A62B;
|
--status-warning: #E1A62B;
|
||||||
--status-error: #E45C4F;
|
--status-error: #E45C4F;
|
||||||
|
|
@ -44,14 +18,107 @@
|
||||||
--radius-md: 6px;
|
--radius-md: 6px;
|
||||||
--radius-lg: 8px;
|
--radius-lg: 8px;
|
||||||
|
|
||||||
--font-ui: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
|
--font-ui: 'Inter', "Segoe UI", -apple-system, sans-serif;
|
||||||
--font-title: "Cinzel", "Segoe UI", serif, sans-serif;
|
--font-title: "Cinzel", "Cinzel Decorative", "Segoe UI", serif;
|
||||||
--font-mono: "Consolas", "Courier New", monospace;
|
--font-mono: "Consolas", "Courier New", monospace;
|
||||||
|
|
||||||
--header-height: 58px;
|
--header-height: 58px;
|
||||||
--sidebar-width: 230px;
|
--sidebar-width: 230px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Default DARK theme */
|
||||||
|
:root, body[data-theme="dark"] {
|
||||||
|
--bg-base: #101510;
|
||||||
|
--bg-sidebar: #0D120D;
|
||||||
|
--bg-header: #0D120D;
|
||||||
|
--bg-statusbar: #0D120D;
|
||||||
|
--bg-modal-backdrop: rgba(16, 21, 16, 0.85);
|
||||||
|
|
||||||
|
--surface: #1A2A1F;
|
||||||
|
--surface-hover: #2F4A36;
|
||||||
|
--surface-active: #3C5C44;
|
||||||
|
--surface-selected: #28402F;
|
||||||
|
--surface-muted: #152219;
|
||||||
|
|
||||||
|
--border: #36513B;
|
||||||
|
--border-subtle: #203A2D;
|
||||||
|
--border-accent: #CDAA64;
|
||||||
|
--border-hover: #537456;
|
||||||
|
|
||||||
|
--text-primary: #F7F1E3;
|
||||||
|
--text-secondary: #B0B8B2;
|
||||||
|
--text-muted: #8FA395;
|
||||||
|
--text-accent: #CDAA64;
|
||||||
|
|
||||||
|
--accent: #CDAA64;
|
||||||
|
--accent-hover: #E0B84E;
|
||||||
|
--accent-pressed: #A9781E;
|
||||||
|
--accent-dim: rgba(205, 170, 100, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MEDIUM theme (cream cards on green canvas) */
|
||||||
|
body[data-theme="medium"] {
|
||||||
|
--bg-base: #1A2A1F;
|
||||||
|
--bg-sidebar: #152219;
|
||||||
|
--bg-header: #152219;
|
||||||
|
--bg-statusbar: #152219;
|
||||||
|
--bg-modal-backdrop: rgba(26, 42, 31, 0.85);
|
||||||
|
|
||||||
|
--surface: #F7F1E3;
|
||||||
|
--surface-hover: #F0EAD6;
|
||||||
|
--surface-active: #E6DFCB;
|
||||||
|
--surface-selected: #EAE3CF;
|
||||||
|
--surface-muted: #2F4A36;
|
||||||
|
|
||||||
|
--border: #D1C7AE;
|
||||||
|
--border-subtle: #E0D7BF;
|
||||||
|
--border-accent: #CDAA64;
|
||||||
|
--border-hover: #B7A88D;
|
||||||
|
|
||||||
|
--text-primary: #101510;
|
||||||
|
--text-secondary: #2F4A36;
|
||||||
|
--text-muted: #537456;
|
||||||
|
--text-accent: #B78525;
|
||||||
|
|
||||||
|
--accent: #B78525;
|
||||||
|
--accent-hover: #CDAA64;
|
||||||
|
--accent-pressed: #9A6F1D;
|
||||||
|
--accent-dim: rgba(183, 133, 37, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LIGHT theme */
|
||||||
|
body[data-theme="light"] {
|
||||||
|
--bg-base: #F7F1E3;
|
||||||
|
--bg-sidebar: #F0EAD6;
|
||||||
|
--bg-header: #F0EAD6;
|
||||||
|
--bg-statusbar: #E6DFCB;
|
||||||
|
--bg-modal-backdrop: rgba(247, 241, 227, 0.85);
|
||||||
|
|
||||||
|
--surface: #FFFFFF;
|
||||||
|
--surface-hover: #FDFBF7;
|
||||||
|
--surface-active: #F4EEDF;
|
||||||
|
--surface-selected: #FAF7F0;
|
||||||
|
--surface-muted: #F0EAD6;
|
||||||
|
|
||||||
|
--border: #D1C7AE;
|
||||||
|
--border-subtle: #EAE3CF;
|
||||||
|
--border-accent: #CDAA64;
|
||||||
|
--border-hover: #C5BAA1;
|
||||||
|
|
||||||
|
--text-primary: #101510;
|
||||||
|
--text-secondary: #2F4A36;
|
||||||
|
--text-muted: #537456;
|
||||||
|
--text-accent: #B78525;
|
||||||
|
|
||||||
|
--accent: #B78525;
|
||||||
|
--accent-hover: #CDAA64;
|
||||||
|
--accent-pressed: #9A6F1D;
|
||||||
|
--accent-dim: rgba(183, 133, 37, 0.15);
|
||||||
|
}
|
||||||
|
/* Hermes Hub Web Client — Dark Theme & Cockpit Design System */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
@ -1559,20 +1626,114 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Light Theme Override ── */
|
/* ── Light Theme Override ── */
|
||||||
body[data-theme="light"], body.theme-light {
|
|
||||||
--bg-base: #F4F6F8;
|
|
||||||
--bg-sidebar: #E9ECEF;
|
/* Drag and Drop Styles */
|
||||||
--bg-header: #FFFFFF;
|
.draggable-item {
|
||||||
--bg-statusbar: #DEE2E6;
|
cursor: grab;
|
||||||
--surface: #FFFFFF;
|
user-select: none;
|
||||||
--surface-hover: #F1F3F5;
|
}
|
||||||
--surface-active: #E9ECEF;
|
.draggable-item:active {
|
||||||
--surface-selected: #E2E6EA;
|
cursor: grabbing;
|
||||||
--surface-muted: #F8F9FA;
|
}
|
||||||
--border: #CED4DA;
|
.drop-zone {
|
||||||
--border-subtle: #DEE2E6;
|
min-height: 40px;
|
||||||
--border-accent: #B78525;
|
border: 1px dashed var(--border);
|
||||||
--text-primary: #212529;
|
border-radius: var(--radius-sm);
|
||||||
--text-secondary: #495057;
|
display: flex;
|
||||||
--text-muted: #6C757D;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
transition: all 0.2s;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
.drop-zone.drag-over {
|
||||||
|
border-color: var(--accent);
|
||||||
|
background-color: var(--accent-dim);
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
.role-section {
|
||||||
|
background-color: var(--surface);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.role-header {
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-bottom: 1px solid var(--border-subtle);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.role-header h4 {
|
||||||
|
font-family: var(--font-title);
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.role-badge {
|
||||||
|
font-size: 10px;
|
||||||
|
background-color: var(--accent-dim);
|
||||||
|
color: var(--accent);
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: var(--font-ui);
|
||||||
|
}
|
||||||
|
.account-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 24px 20px 200px 120px 120px 150px 80px 80px 24px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-bottom: 1px solid var(--border-subtle);
|
||||||
|
background-color: var(--surface);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.account-row:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.account-row.drag-over {
|
||||||
|
border-top: 2px solid var(--accent);
|
||||||
|
}
|
||||||
|
.drag-handle {
|
||||||
|
color: var(--text-muted);
|
||||||
|
cursor: grab;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.provider-logo-sm {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.available-account-card {
|
||||||
|
background-color: var(--surface);
|
||||||
|
border: 1px solid var(--border-subtle);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
.available-account-card:hover {
|
||||||
|
border-color: var(--border);
|
||||||
|
background-color: var(--surface-hover);
|
||||||
|
}
|
||||||
|
.grid-header {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 24px 20px 200px 120px 120px 150px 80px 80px 24px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 10px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
text-transform: uppercase;
|
||||||
|
border-bottom: 1px solid var(--border-subtle);
|
||||||
|
background-color: var(--surface-muted);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue