feat: ajout d'une modale de gestion des chapitres, permettant la création, l'édition et le déplacement de chapitres. Mise à jour de l'API pour gérer les modifications en lot des chapitres, ainsi que l'intégration de tests pour valider cette nouvelle fonctionnalité. Amélioration de l'interface utilisateur pour une gestion plus fluide des chapitres.

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-07-23 14:25:17 +02:00
parent 00d63dffeb
commit 551db0bf77
19 changed files with 2566 additions and 3 deletions

View File

@@ -50,6 +50,18 @@
@close="closeEditModal"
@save="saveMangaEdit"
/>
<!-- Modale de gestion des chapitres -->
<ManageChaptersModal
:is-open="isManageChaptersModalOpen"
:manga="currentManga"
:chapters="mangaStore.mangaChapters[mangaId]?.items || []"
:is-loading="mangaStore.loadingChapters"
:is-saving="isSavingChapters"
:error="chaptersError"
@close="closeManageChaptersModal"
@save="saveChaptersChanges"
/>
</div>
<div v-else-if="isLoadingDetails" class="flex justify-center items-center h-64">
@@ -84,7 +96,8 @@ import { useMangaPreferredSources } from '../composables/useMangaPreferredSource
import { useMangaRefresh } from '../composables/useMangaRefresh';
import { useMangaVolumes } from '../composables/useMangaVolumes';
import MangaEditModal from '../components/MangaEditModal.vue';
import ManageChaptersModal from '../components/ManageChaptersModal.vue';
import MangaEditModal from '../components/MangaEditModal.vue';
import MangaHeader from '../components/MangaHeader.vue';
import MangaPreferredSourcesModal from '../components/MangaPreferredSourcesModal.vue';
import MangaVolumeList from '../components/MangaVolumeList.vue';
@@ -101,6 +114,9 @@ import { useMangaStore } from '../../application/store/mangaStore';
// État de la modale
const isPreferredSourcesModalOpen = ref(false);
const isManageChaptersModalOpen = ref(false);
const isSavingChapters = ref(false);
const chaptersError = ref(null);
const {
data: currentManga,
@@ -167,6 +183,15 @@ import { useMangaStore } from '../../application/store/mangaStore';
isPreferredSourcesModalOpen.value = false;
};
const openManageChaptersModal = () => {
isManageChaptersModalOpen.value = true;
};
const closeManageChaptersModal = () => {
isManageChaptersModalOpen.value = false;
chaptersError.value = null;
};
const savePreferredSources = async (sourceIds) => {
try {
await saveSourcesOrder(sourceIds);
@@ -185,6 +210,39 @@ import { useMangaStore } from '../../application/store/mangaStore';
}
};
// Fonction pour sauvegarder les changements des chapitres
const saveChaptersChanges = async (chaptersData) => {
if (!mangaId.value) return;
isSavingChapters.value = true;
chaptersError.value = null;
try {
const response = await fetch('/api/chapters/batch-edit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
chapters: chaptersData
})
});
if (!response.ok) {
throw new Error('Erreur lors de la sauvegarde des chapitres');
}
// Recharger les chapitres et les volumes
await mangaStore.loadChapters(mangaId.value);
closeManageChaptersModal();
} catch (error) {
chaptersError.value = error.message;
console.error('Erreur lors de la sauvegarde des chapitres:', error);
} finally {
isSavingChapters.value = false;
}
};
// Fonction pour le refresh des métadonnées
const handleRefreshMetadata = async () => {
if (!mangaId.value) return;
@@ -224,9 +282,9 @@ import { useMangaStore } from '../../application/store/mangaStore';
},
{
icon: PencilSquareIcon,
label: 'Rename chapters',
label: 'Manage chapters',
type: 'button',
onClick: () => console.log('Rename chapters')
onClick: openManageChaptersModal
},
{
icon: DocumentArrowDownIcon,