veza/apps/web/src/features/tracks
senke 8f93b0ce37 feat(web): update all features, stories, e2e tests, and auth interceptor
Update auth, playlists, tracks, search, profile, dashboard, player,
settings, and social features. Add e2e audit specs for all major pages.
Update ESLint config, vitest config, and route configuration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 19:16:36 +02:00
..
__tests__ incus deployement fully implemented, Makefile updated and make fmt ran 2026-01-13 19:47:57 +01:00
api feat(v0.10.1): Track edit form - tags/genres (Phase 4.4) 2026-03-09 10:00:07 +01:00
components feat(web): update all features, stories, e2e tests, and auth interceptor 2026-03-31 19:16:36 +02:00
docs incus deployement fully implemented, Makefile updated and make fmt ran 2026-01-13 19:47:57 +01:00
errors state-ownership: delete unused optimisticStoreUpdates.ts file 2026-01-15 19:26:53 +01:00
hooks chore: enable noUncheckedIndexedAccess, isolate ghost MSW handlers, document go-clamd tech debt 2026-02-12 23:12:35 +01:00
pages feat(web): update all features, stories, e2e tests, and auth interceptor 2026-03-31 19:16:36 +02:00
services test: fix and improve unit tests across multiple features 2026-03-25 23:34:42 +01:00
types feat(v0.10.1): Track edit form - tags/genres (Phase 4.4) 2026-03-09 10:00:07 +01:00
index.ts api-contracts: replace ApiError interface with Zod-inferred type 2026-01-15 17:03:35 +01:00
README.md refonte: backend-api go first; phase 1 2025-12-12 21:34:34 -05:00
types.test.ts refonte: backend-api go first; phase 1 2025-12-12 21:34:34 -05:00
types.ts Phase 2 stabilisation: code mort, Modal→Dialog, feature flags, tests, router split, Rust legacy 2026-02-14 17:23:32 +01:00

Feature: Tracks

Cette feature fournit tous les composants et hooks nécessaires pour afficher et gérer des listes de pistes musicales.

Architecture

Composants

TrackListContainer

Composant principal qui assemble tous les sous-composants pour créer une interface complète de gestion de listes de pistes.

Utilisation :

import { TrackListContainer } from '@/features/tracks';

<TrackListContainer
  showFilters={true}
  showSort={true}
  showViewToggle={true}
  showPagination={true}
  availableGenres={['Rock', 'Pop', 'Jazz']}
  availableArtists={['Artist 1', 'Artist 2']}
  onTrackPlay={(track) => console.log('Play:', track)}
  onTrackLike={(track) => console.log('Like:', track)}
/>;

Props principales :

  • showFilters : Afficher les filtres (défaut: true)
  • showSort : Afficher les options de tri (défaut: true)
  • showViewToggle : Afficher le toggle liste/grille (défaut: true)
  • showPagination : Afficher la pagination (défaut: true)
  • useService : Utiliser le service API pour charger les données (défaut: true)
  • persistFilters : Persister les filtres dans localStorage (défaut: false)
  • persistSort : Persister le tri dans localStorage (défaut: false)
  • syncUrlParams : Synchroniser avec les paramètres URL (défaut: false)

TrackList

Affiche une liste de pistes en format liste (table) avec colonnes, actions et sélection.

TrackGrid

Affiche une grille de pistes avec layout responsive et options de densité.

TrackFilters

Composant de filtrage avec recherche, genre, artiste, année, durée.

TrackSort

Composant de tri avec sélection du champ et ordre (asc/desc).

ViewToggle

Toggle pour basculer entre vue liste et vue grille.

TrackListPagination

Composant de pagination avec navigation et informations.

TrackListEmpty

Affiche des états vides : aucun track, aucun résultat, erreur.

Hooks

useTrackList

Hook principal pour gérer l'état d'une liste de pistes avec tri, filtrage, pagination.

Utilisation :

import { useTrackList } from '@/features/tracks';

const trackList = useTrackList({
  useService: true,
  autoLoad: true,
  persistFilters: true,
  persistSort: true,
});

// Accéder aux données
trackList.filteredTracks; // Tracks filtrés et triés
trackList.isLoading; // État de chargement
trackList.error; // Erreur éventuelle

// Actions
trackList.setFilterOptions({ genre: 'Rock' });
trackList.setSortField('title');
trackList.setPage(2);

Services

trackListService

Service pour interagir avec l'API de listes de pistes.

Fonctions principales :

  • getTracks(options) : Récupérer les pistes avec pagination, filtres, tri
  • getTrackById(id) : Récupérer une piste par ID
  • getTracksByArtist(artist) : Récupérer les pistes d'un artiste

Exemples d'utilisation

Liste simple

import { TrackListContainer } from '@/features/tracks';

function MyTracksPage() {
  return (
    <TrackListContainer
      showFilters={false}
      showSort={true}
      showViewToggle={true}
    />
  );
}

Liste avec filtres personnalisés

import { TrackListContainer } from '@/features/tracks';

function FilteredTracksPage() {
  const genres = ['Rock', 'Pop', 'Jazz'];
  const artists = ['Artist 1', 'Artist 2'];

  return (
    <TrackListContainer
      showFilters={true}
      availableGenres={genres}
      availableArtists={artists}
      persistFilters={true}
      syncUrlParams={true}
    />
  );
}

Liste avec sélection

import { TrackListContainer } from '@/features/tracks';

function SelectableTracksPage() {
  const handleSelectedPlay = (trackIds: number[]) => {
    console.log('Play selected tracks:', trackIds);
  };

  return (
    <TrackListContainer
      showSelection={true}
      onSelectedPlay={handleSelectedPlay}
      onSelectedDelete={(ids) => console.log('Delete:', ids)}
      onSelectedLike={(ids) => console.log('Like:', ids)}
    />
  );
}

Liste avec callbacks personnalisés

import { TrackListContainer } from '@/features/tracks';
import { usePlayer } from '@/features/player';

function InteractiveTracksPage() {
  const player = usePlayer();

  const handleTrackPlay = (track) => {
    player.play(track);
  };

  const handleTrackLike = (track) => {
    // Appel API pour liker
    likeTrack(track.id);
  };

  const isLiked = (trackId: number) => {
    return likedTracks.includes(trackId);
  };

  const isPlaying = (trackId: number) => {
    return player.currentTrack?.id === trackId && player.isPlaying;
  };

  return (
    <TrackListContainer
      onTrackPlay={handleTrackPlay}
      onTrackLike={handleTrackLike}
      isLiked={isLiked}
      isPlaying={isPlaying}
      currentPlayingId={player.currentTrack?.id}
    />
  );
}

Persistance

localStorage

Les préférences peuvent être persistées dans localStorage :

  • Filtres : trackList_filters
  • Tri : trackList_sort
  • Mode d'affichage : trackList_viewMode
  • Densité de grille : trackList_gridDensity

URL Parameters

Les filtres et le tri peuvent être synchronisés avec les paramètres URL :

  • ?genre=Rock&artist=Artist1&sortField=title&sortOrder=asc

Tests

Tous les composants incluent des tests unitaires avec coverage ≥ 80%.

Exécuter les tests :

npm test -- features/tracks

Accessibilité

Tous les composants respectent les standards d'accessibilité :

  • Attributs ARIA appropriés
  • Navigation au clavier
  • Support des lecteurs d'écran
  • Contraste de couleurs conforme WCAG

Performance

  • Lazy loading des composants
  • Mémoïsation des calculs coûteux
  • Debouncing des recherches
  • Pagination côté serveur pour les grandes listes