Filter library tracks on the server and add track publishing, bulk delete and album types
This commit is contained in:
@@ -1,16 +1,24 @@
|
||||
import type { PageServerLoad, Actions } from './$types';
|
||||
import { fail } from '@sveltejs/kit';
|
||||
import { fail, isActionFailure } from '@sveltejs/kit';
|
||||
import { apiFor } from '$lib/server/api';
|
||||
import { requireUser } from '$lib/server/guards';
|
||||
import { formIds } from '$lib/server/forms/fields';
|
||||
import { formIds, formString } from '$lib/server/forms/fields';
|
||||
import { tagged } from '$lib/server/actions/tagged';
|
||||
import { loadLibraryTracks } from '$lib/server/albums';
|
||||
import { deleteTracks } from '$lib/server/tracks';
|
||||
import { loadLibraryTracks, loadStatusCounts } from '$lib/server/libraryTracks';
|
||||
import { deleteTracks, setTracksPublished } from '$lib/server/tracks';
|
||||
import { parseTrackFilter } from '$lib/data/libraryTracks';
|
||||
|
||||
export const load: PageServerLoad = async ({ locals, url, fetch }) => {
|
||||
const user = requireUser(locals, url);
|
||||
const api = apiFor({ fetch, locals });
|
||||
return { tracks: await loadLibraryTracks(api, user.sub) };
|
||||
const q = url.searchParams.get('q')?.trim() ?? '';
|
||||
const filter = parseTrackFilter(url.searchParams.get('status'));
|
||||
|
||||
const [tracks, counts] = await Promise.all([
|
||||
loadLibraryTracks(api, user.sub, { q, filter }),
|
||||
loadStatusCounts(api, user.sub)
|
||||
]);
|
||||
return { tracks, counts, q, filter };
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
@@ -26,5 +34,15 @@ export const actions: Actions = {
|
||||
? 'No se pudo borrar la canción.'
|
||||
: `No se pudieron borrar ${failed} de ${trackIds.length} canciones.`
|
||||
});
|
||||
}),
|
||||
|
||||
setPublished: tagged('setPublished', async ({ api, form }) => {
|
||||
const trackIds = formIds(form, 'trackIds');
|
||||
if (trackIds.length === 0) return fail(400, { message: 'Falta la canción.' });
|
||||
|
||||
const isPublished = formString(form, 'isPublished') === 'true';
|
||||
const result = await setTracksPublished(api, trackIds, isPublished);
|
||||
if (isActionFailure(result)) return result;
|
||||
return { ...result, isPublished };
|
||||
})
|
||||
};
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
<script lang="ts">
|
||||
import LibraryTracksSection from '$lib/components/music/library/LibraryTracksSection.svelte';
|
||||
import { plural } from '$lib/utils/format';
|
||||
|
||||
let { data, form } = $props();
|
||||
|
||||
const errorMessage = $derived(
|
||||
form && 'message' in form && form.action !== 'saveAlbum' ? form.message : undefined
|
||||
);
|
||||
const published = $derived(
|
||||
form?.action === 'setPublished' ? (form as { skipped?: number; isPublished?: boolean }) : null
|
||||
);
|
||||
const notice = $derived(
|
||||
published?.skipped
|
||||
? `${plural(published.skipped, 'canción', 'canciones')} sin procesar: no se ${published.isPublished ? 'pueden publicar' : 'han despublicado'} todavía.`
|
||||
: undefined
|
||||
);
|
||||
</script>
|
||||
|
||||
<LibraryTracksSection
|
||||
tracks={data.tracks.items}
|
||||
errorMessage={form?.action === 'deleteTracks' ? form.message : undefined}
|
||||
tracks={data.tracks}
|
||||
counts={data.counts}
|
||||
query={data.q}
|
||||
filter={data.filter}
|
||||
{errorMessage}
|
||||
{notice}
|
||||
/>
|
||||
|
||||
@@ -2,8 +2,10 @@ import type { Actions, PageServerLoad } from './$types';
|
||||
import { apiFor, unwrapOrError } from '$lib/server/api';
|
||||
import { requireUser } from '$lib/server/guards';
|
||||
import { toAlbum } from '$lib/server/mappers';
|
||||
import { loadLibraryTracks, trackIdsByAlbum } from '$lib/server/albums';
|
||||
import { albumTrackIds } from '$lib/server/albums';
|
||||
import { loadLibraryTracks } from '$lib/server/libraryTracks';
|
||||
import { removeAlbum, saveAlbum } from '$lib/server/actions/libraryAlbum';
|
||||
import { LIBRARY_PICKER_PAGE_SIZE } from '$lib/config';
|
||||
|
||||
export const load: PageServerLoad = async ({ params, locals, url, fetch }) => {
|
||||
const user = requireUser(locals, url);
|
||||
@@ -11,10 +13,10 @@ export const load: PageServerLoad = async ({ params, locals, url, fetch }) => {
|
||||
const albumResult = await api.GET('/albums/{id}', { params: { path: { id: params.id } } });
|
||||
const album = toAlbum(unwrapOrError(albumResult, 'Álbum no encontrado.', 404));
|
||||
const [tracks, memberIds] = await Promise.all([
|
||||
loadLibraryTracks(api, user.sub),
|
||||
trackIdsByAlbum(api, [album])
|
||||
loadLibraryTracks(api, user.sub, { pageSize: LIBRARY_PICKER_PAGE_SIZE }),
|
||||
albumTrackIds(api, album.id)
|
||||
]);
|
||||
return { album, tracks, memberIds: memberIds[album.id] ?? [] };
|
||||
return { album, tracks, memberIds };
|
||||
};
|
||||
|
||||
export const actions: Actions = { saveAlbum, deleteAlbum: removeAlbum };
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
import { apiFor } from '$lib/server/api';
|
||||
import { requireUser } from '$lib/server/guards';
|
||||
import { loadLibraryTracks } from '$lib/server/albums';
|
||||
import { loadLibraryTracks } from '$lib/server/libraryTracks';
|
||||
import { saveAlbum } from '$lib/server/actions/libraryAlbum';
|
||||
import { LIBRARY_PICKER_PAGE_SIZE } from '$lib/config';
|
||||
|
||||
export const load: PageServerLoad = async ({ locals, url, fetch }) => {
|
||||
const user = requireUser(locals, url);
|
||||
const api = apiFor({ fetch, locals });
|
||||
return { tracks: await loadLibraryTracks(api, user.sub) };
|
||||
return { tracks: await loadLibraryTracks(api, user.sub, { pageSize: LIBRARY_PICKER_PAGE_SIZE }) };
|
||||
};
|
||||
|
||||
export const actions: Actions = { saveAlbum };
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { RequestHandler } from './$types';
|
||||
import { json } from '@sveltejs/kit';
|
||||
import { apiFor } from '$lib/server/api';
|
||||
import { requireUser } from '$lib/server/guards';
|
||||
import { loadLibraryTracks } from '$lib/server/libraryTracks';
|
||||
import { parseTrackFilter } from '$lib/data/libraryTracks';
|
||||
|
||||
export const GET: RequestHandler = async ({ url, locals, fetch }) => {
|
||||
const user = requireUser(locals, url);
|
||||
const api = apiFor({ fetch, locals });
|
||||
const pageNumber = Math.max(1, Number(url.searchParams.get('pageNumber')) || 1);
|
||||
const tracks = await loadLibraryTracks(api, user.sub, {
|
||||
q: url.searchParams.get('q')?.trim() ?? '',
|
||||
filter: parseTrackFilter(url.searchParams.get('status')),
|
||||
pageNumber
|
||||
});
|
||||
return json(tracks);
|
||||
};
|
||||
Reference in New Issue
Block a user