Card bulk operations, remove expand/collapse, graph color picker fix

- Bulk selection mode: Ctrl+Click or toggle button to enter, Escape to exit
- Shift+Click for range select, bottom toolbar with SVG icon action buttons
- All CardSections wired with bulk actions: Delete everywhere,
  Start/Stop for targets, Enable/Disable for automations
- Remove expand/collapse all buttons (no collapsible sections remain)
- Fix graph node color picker overlay persisting after outside click
- Add Icons section to frontend.md conventions
- Add trash2, listChecks, circleOff icons to icon system
- Backend: processing loop performance improvements (monotonic timestamps,
  deque-based FPS tracking)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 01:21:27 +03:00
parent f4647027d2
commit 122e95545c
18 changed files with 771 additions and 149 deletions

View File

@@ -267,8 +267,9 @@ body.cs-drag-active .card-drag-handle {
opacity: 0 !important;
}
/* Hide drag handles when filter is active */
.cs-filtering .card-drag-handle {
/* Hide drag handles when filter is active or bulk selecting */
.cs-filtering .card-drag-handle,
.cs-selecting .card-drag-handle {
display: none;
}
@@ -1112,3 +1113,146 @@ ul.section-tip li {
.led-preview-layers:hover .led-preview-layer-label {
opacity: 1;
}
/* ── Bulk selection ────────────────────────────────────────── */
/* Toggle button in section header */
.cs-bulk-toggle {
background: none;
border: 1px solid var(--border-color);
color: var(--text-secondary);
font-size: 0.75rem;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border-radius: 4px;
transition: color 0.2s, background 0.2s, border-color 0.2s;
flex-shrink: 0;
line-height: 1;
}
.cs-bulk-toggle:hover {
border-color: var(--primary-color);
color: var(--primary-text-color);
}
.cs-bulk-toggle.active {
background: var(--primary-color);
border-color: var(--primary-color);
color: var(--primary-contrast, #fff);
}
/* Checkbox inside card — hidden unless selecting */
.card-bulk-check {
display: none;
width: 16px;
height: 16px;
cursor: pointer;
accent-color: var(--primary-color);
flex-shrink: 0;
}
.cs-selecting .card-bulk-check {
display: block;
}
/* Selected card highlight */
.cs-selecting .card-selected,
.cs-selecting .card-selected.template-card {
border-color: var(--primary-color);
box-shadow: 0 0 0 1px var(--primary-color), 0 4px 12px color-mix(in srgb, var(--primary-color) 15%, transparent);
}
/* Make cards visually clickable in selection mode */
.cs-selecting .card,
.cs-selecting .template-card {
cursor: pointer;
}
/* Suppress hover lift during selection */
.cs-selecting .card:hover,
.cs-selecting .template-card:hover {
transform: none;
}
/* ── Bulk toolbar ──────────────────────────────────────────── */
#bulk-toolbar {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%) translateY(calc(100% + 30px));
background: var(--card-bg);
border: 1px solid var(--border-color);
border-radius: var(--radius-md, 8px);
padding: 8px 16px;
display: flex;
align-items: center;
gap: 12px;
z-index: 1000;
box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.3);
transition: transform 0.25s ease;
white-space: nowrap;
}
#bulk-toolbar.visible {
transform: translateX(-50%) translateY(0);
}
.bulk-select-all-wrap {
display: flex;
align-items: center;
cursor: pointer;
}
.bulk-select-all-cb {
width: 16px;
height: 16px;
margin: 0;
accent-color: var(--primary-color);
cursor: pointer;
}
.bulk-count {
font-size: 0.85rem;
color: var(--text-secondary);
min-width: 80px;
}
.bulk-actions {
display: flex;
gap: 4px;
}
.bulk-action-btn {
width: 32px;
height: 32px;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
}
.bulk-action-btn .icon {
width: 16px;
height: 16px;
}
.bulk-close {
background: none;
border: none;
color: var(--text-muted);
font-size: 1rem;
cursor: pointer;
padding: 4px;
border-radius: 4px;
transition: color 0.2s;
line-height: 1;
}
.bulk-close:hover {
color: var(--text-color);
}