From 92f21bd23772ea74cec5fda2a8f7a58c664b6fb4 Mon Sep 17 00:00:00 2001 From: 4gray Date: Sat, 25 Apr 2026 22:11:31 +0200 Subject: [PATCH] feat(workspace): enhance dashboard and sources components with playlist management and UI improvements Entire-Checkpoint: c6e522b4276c --- .../workspace-dashboard-rails.component.html | 11 +- .../workspace-dashboard-rails.component.scss | 18 +++ .../workspace-dashboard-rails.component.ts | 13 ++- ...space-shell-context-sidebar.component.html | 2 +- ...rkspace-shell-context-sidebar.component.ts | 1 + .../workspace-shell-header.component.html | 108 ++++++++---------- .../workspace-shell-header.component.scss | 22 ++-- .../workspace-shell-header.component.ts | 1 + .../services/workspace-shell.facade.ts | 36 ++++++ .../workspace-shell.component.html | 9 +- .../workspace-shell.component.ts | 6 + .../workspace-sources.component.html | 73 ++++++------ .../workspace-sources.component.scss | 15 +++ .../workspace-sources.component.ts | 9 +- 14 files changed, 209 insertions(+), 115 deletions(-) diff --git a/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.html b/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.html index 1c933a146..054be0621 100644 --- a/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.html +++ b/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.html @@ -1,4 +1,8 @@ -
+
@if (!ready()) { @@ -34,8 +38,9 @@ } } @else if (!hasPlaylists()) { } @else { @if (hero(); as item) { diff --git a/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.scss b/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.scss index 352935db4..0e25da815 100644 --- a/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.scss +++ b/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.scss @@ -5,6 +5,14 @@ min-height: 100%; } +:host(.rails-page-host--empty) { + padding: 0; + height: 100%; + min-height: 100%; + display: flex; + overflow: hidden; +} + .rails-page { max-width: 1440px; margin: 0 auto; @@ -14,6 +22,16 @@ min-width: 0; } +.rails-page--empty { + flex: 1; + max-width: none; + margin: 0; + gap: 0; + min-height: 0; + height: 100%; + overflow: hidden; +} + // ── Hero ──────────────────────────────────────────────────────────────────── // Netflix/Apple TV-style hero: blurred poster backdrop + vignette + sharp 2:3 // poster card + text block. Mirrors content-hero fallback (no dedicated diff --git a/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.ts b/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.ts index 1146a9590..abb12ce69 100644 --- a/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.ts +++ b/libs/workspace/dashboard/feature/src/lib/rails/workspace-dashboard-rails.component.ts @@ -18,7 +18,10 @@ import { PlaylistInfoComponent, } from '@iptvnator/playlist/shared/ui'; import { PlaylistRefreshActionService } from '@iptvnator/playlist/shared/util'; -import { WORKSPACE_SHELL_ACTIONS } from '@iptvnator/workspace/shell/util'; +import { + WORKSPACE_SHELL_ACTIONS, + WorkspacePlaylistType, +} from '@iptvnator/workspace/shell/util'; import { DialogService } from 'components'; import { PlaylistActions } from 'm3u-state'; import { DatabaseService } from 'services'; @@ -214,6 +217,9 @@ function isXtreamAccountPlaylist( templateUrl: './workspace-dashboard-rails.component.html', styleUrl: './workspace-dashboard-rails.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, + host: { + '[class.rails-page-host--empty]': 'ready() && !hasPlaylists()', + }, }) export class WorkspaceDashboardRailsComponent { readonly data = inject(DashboardDataService); @@ -231,6 +237,7 @@ export class WorkspaceDashboardRailsComponent { readonly hasPlaylists = computed(() => this.data.playlists().length > 0); readonly ready = this.data.dashboardReady; readonly xtreamPlaylistCount = this.data.xtreamPlaylistCount; + readonly isElectron = !!window.electron; readonly skeletonSlots = SKELETON_CARDS_PER_RAIL; readonly skeletonRails = SKELETON_RAILS; @@ -321,8 +328,8 @@ export class WorkspaceDashboardRailsComponent { }); } - onAddPlaylist(): void { - this.shellActions.openAddPlaylistDialog(); + onAddPlaylist(type?: WorkspacePlaylistType): void { + this.shellActions.openAddPlaylistDialog(type); } markHeroImageFailed(url: string): void { diff --git a/libs/workspace/shell/feature/src/lib/workspace-shell/components/workspace-shell-context-sidebar/workspace-shell-context-sidebar.component.html b/libs/workspace/shell/feature/src/lib/workspace-shell/components/workspace-shell-context-sidebar/workspace-shell-context-sidebar.component.html index 8fbe856e1..eb2745632 100644 --- a/libs/workspace/shell/feature/src/lib/workspace-shell/components/workspace-shell-context-sidebar/workspace-shell-context-sidebar.component.html +++ b/libs/workspace/shell/feature/src/lib/workspace-shell/components/workspace-shell-context-sidebar/workspace-shell-context-sidebar.component.html @@ -1,4 +1,4 @@ -@if (variant() === 'sources') { +@if (variant() === 'sources' && hasPlaylists()) {