From 6b0e4e5539cdd20a53b3750f25ad211fe76d183b Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Tue, 31 Mar 2026 23:11:17 +0300 Subject: [PATCH] feat(processed-audio-sources): phase 8 - frontend design consistency review Fix audio source modal error class (modal-error), use Modal.showError(), reorder audio source card description, remove redundant APT filter count badge, clean up unused imports in audio-sources.ts. --- plans/processed-audio-sources/PLAN.md | 4 +-- .../phase-8-frontend-design-review.md | 26 +++++++++---------- .../js/features/audio-processing-templates.ts | 3 --- .../static/js/features/audio-sources.ts | 14 +++------- .../static/js/features/streams.ts | 4 +-- .../templates/modals/audio-source-editor.html | 2 +- 6 files changed, 22 insertions(+), 31 deletions(-) diff --git a/plans/processed-audio-sources/PLAN.md b/plans/processed-audio-sources/PLAN.md index 1b859ce..c91a522 100644 --- a/plans/processed-audio-sources/PLAN.md +++ b/plans/processed-audio-sources/PLAN.md @@ -33,7 +33,7 @@ Clean-slate approach: no data migration for old source types. - [ ] Phase 5: Frontend — Audio Processing Templates [domain: frontend] → [subplan](./phase-5-frontend-templates.md) - [ ] Phase 6: Frontend — Source Types [domain: frontend] → [subplan](./phase-6-frontend-source-types.md) - [ ] Phase 7: Testing & Polish [domain: backend] → [subplan](./phase-7-testing-polish.md) -- [ ] Phase 8: Frontend Design Consistency Review [domain: frontend] → [subplan](./phase-8-frontend-design-review.md) +- [x] Phase 8: Frontend Design Consistency Review [domain: frontend] → [subplan](./phase-8-frontend-design-review.md) ## Phase Progress Log @@ -46,7 +46,7 @@ Clean-slate approach: no data migration for old source types. | Phase 5: Frontend — Audio Processing Templates | frontend | ✅ Done | ✅ | ⏭️ | ✅ | | Phase 6: Frontend — Source Types | frontend | ✅ Done | ✅ | ⏭️ | ✅ | | Phase 7: Testing & Polish | backend | ✅ Done | — | ✅ | ✅ | -| Phase 8: Frontend Design Review | frontend | ⬜ Not Started | ⬜ | ⬜ | ⬜ | +| Phase 8: Frontend Design Review | frontend | ✅ Done | ✅ | ✅ | ⬜ | ## Final Review - [ ] Comprehensive code review diff --git a/plans/processed-audio-sources/phase-8-frontend-design-review.md b/plans/processed-audio-sources/phase-8-frontend-design-review.md index 33d8dd1..51aa83f 100644 --- a/plans/processed-audio-sources/phase-8-frontend-design-review.md +++ b/plans/processed-audio-sources/phase-8-frontend-design-review.md @@ -1,6 +1,6 @@ # Phase 8: Frontend Design Consistency Review -**Status:** ⬜ Not Started +**Status:** ✅ Done **Parent plan:** [PLAN.md](./PLAN.md) **Domain:** frontend @@ -9,31 +9,31 @@ Review all new frontend UI created in Phases 5-6 for visual consistency, design ## Tasks -- [ ] Task 1: Review Audio Processing Templates section for design consistency +- [x] Task 1: Review Audio Processing Templates section for design consistency - Card layout, spacing, typography alignment with existing sections - Filter editor modal — controls alignment, visual hierarchy, grouping - Responsive behavior at different viewport widths -- [ ] Task 2: Review Processed Audio Source cards for design consistency +- [x] Task 2: Review Processed Audio Source cards for design consistency - Card style matches existing source cards (capture, picture, value sources) - EntitySelect pickers are visually consistent - Type badges/icons are clear and distinguishable -- [ ] Task 3: Review Capture Audio Source card (relabeled) +- [x] Task 3: Review Capture Audio Source card (relabeled) - Label/icon updates look correct - No visual regressions from the rename -- [ ] Task 4: Review source type picker/creation flow +- [x] Task 4: Review source type picker/creation flow - Type selector is clear and accessible - Transition between types is smooth - Empty states handled properly -- [ ] Task 5: Review real-time audio preview UI +- [x] Task 5: Review real-time audio preview UI - Spectrum visualization looks polished - Source picker and controls are well-placed - Loading/error states -- [ ] Task 6: Fix all design issues found in Tasks 1-5 +- [x] Task 6: Fix all design issues found in Tasks 1-5 - CSS adjustments for spacing, alignment, typography - Icon/color consistency - Dark mode compatibility (if applicable) - Hover/focus/active states on interactive elements -- [ ] Task 7: Cross-browser spot-check (if applicable) +- [x] Task 7: Cross-browser spot-check (if applicable) ## Files to Modify/Create - `static/css/dashboard.css` — **modify** — design fixes @@ -55,11 +55,11 @@ Review all new frontend UI created in Phases 5-6 for visual consistency, design - The project uses vanilla CSS (no framework) — fixes must use the existing stylesheet approach ## Review Checklist -- [ ] All tasks completed -- [ ] Code follows project conventions -- [ ] No unintended side effects -- [ ] Build passes -- [ ] Tests pass (new + existing) +- [x] All tasks completed +- [x] Code follows project conventions +- [x] No unintended side effects +- [x] Build passes +- [x] Tests pass (new + existing) ## Handoff to Next Phase diff --git a/server/src/wled_controller/static/js/features/audio-processing-templates.ts b/server/src/wled_controller/static/js/features/audio-processing-templates.ts index d15a7b2..48cc1e3 100644 --- a/server/src/wled_controller/static/js/features/audio-processing-templates.ts +++ b/server/src/wled_controller/static/js/features/audio-processing-templates.ts @@ -290,9 +290,6 @@ export function createAudioProcessingTemplateCard(tmpl: any): string {
${ICON_AUDIO_TEMPLATE} ${escapeHtml(tmpl.name)}
${tmpl.description ? `
${escapeHtml(tmpl.description)}
` : ''} -
- ${ICON_AUDIO_TEMPLATE} ${tmpl.filters ? tmpl.filters.length : 0} ${t('audio_processing.filters_label')} -
${filterChainHtml} ${renderTagChips(tmpl.tags)}`, actions: ` diff --git a/server/src/wled_controller/static/js/features/audio-sources.ts b/server/src/wled_controller/static/js/features/audio-sources.ts index 284c65a..832d0a4 100644 --- a/server/src/wled_controller/static/js/features/audio-sources.ts +++ b/server/src/wled_controller/static/js/features/audio-sources.ts @@ -13,13 +13,11 @@ import { _cachedAudioSources, _cachedAudioTemplates, _cachedAudioProcessingTemplates, audioProcessingTemplatesCache, apiKey, audioSourcesCache } from '../core/state.ts'; import { API_BASE, fetchWithAuth, escapeHtml } from '../core/api.ts'; import { t } from '../core/i18n.ts'; -import { showToast, showConfirm, lockBody, unlockBody } from '../core/ui.ts'; +import { showToast, showConfirm } from '../core/ui.ts'; import { Modal } from '../core/modal.ts'; import { ICON_MUSIC, getAudioSourceIcon, ICON_AUDIO_TEMPLATE, ICON_AUDIO_INPUT, ICON_AUDIO_LOOPBACK } from '../core/icons.ts'; import { EntitySelect } from '../core/entity-palette.ts'; -import { IconSelect } from '../core/icon-select.ts'; import { TagInput } from '../core/tag-input.ts'; -import * as P from '../core/icon-paths.ts'; import { loadPictureSources } from './streams.ts'; let _audioSourceTagsInput: TagInput | null = null; @@ -53,8 +51,6 @@ let _asDeviceEntitySelect: EntitySelect | null = null; let _asParentEntitySelect: EntitySelect | null = null; let _asProcessingTemplateEntitySelect: EntitySelect | null = null; -const _svg = (d: string): string => `${d}`; - // ── Auto-name generation ────────────────────────────────────── let _asNameManuallyEdited = false; @@ -158,11 +154,9 @@ export async function saveAudioSource() { const name = (document.getElementById('audio-source-name') as HTMLInputElement).value.trim(); const sourceType = (document.getElementById('audio-source-type') as HTMLSelectElement).value; const description = (document.getElementById('audio-source-description') as HTMLInputElement).value.trim() || null; - const errorEl = document.getElementById('audio-source-error') as HTMLElement; if (!name) { - errorEl.textContent = t('audio_source.error.name_required'); - errorEl.style.display = ''; + audioSourceModal.showError(t('audio_source.error.name_required')); return; } @@ -196,8 +190,8 @@ export async function saveAudioSource() { audioSourcesCache.invalidate(); await loadPictureSources(); } catch (e: any) { - errorEl.textContent = e.message; - errorEl.style.display = ''; + if (e.isAuth) return; + audioSourceModal.showError(e.message); } } diff --git a/server/src/wled_controller/static/js/features/streams.ts b/server/src/wled_controller/static/js/features/streams.ts index 2c9f12f..58ab2cf 100644 --- a/server/src/wled_controller/static/js/features/streams.ts +++ b/server/src/wled_controller/static/js/features/streams.ts @@ -711,9 +711,9 @@ function renderPictureSourcesList(streams: any) {
${icon} ${escapeHtml(src.name)}
+ ${src.description ? `
${escapeHtml(src.description)}
` : ''}
${propsHtml}
- ${renderTagChips(src.tags)} - ${src.description ? `
${escapeHtml(src.description)}
` : ''}`, + ${renderTagChips(src.tags)}`, actions: ` diff --git a/server/src/wled_controller/templates/modals/audio-source-editor.html b/server/src/wled_controller/templates/modals/audio-source-editor.html index 9529c97..ddb9926 100644 --- a/server/src/wled_controller/templates/modals/audio-source-editor.html +++ b/server/src/wled_controller/templates/modals/audio-source-editor.html @@ -9,7 +9,7 @@
- +