feat: ajout de la gestion de l'expansion des volumes dans les composants MangaVolume et MangaVolumeList. Intégration de la synchronisation de l'état d'expansion avec les props, ainsi que des méthodes pour étendre ou réduire tous les volumes. Amélioration de l'interface utilisateur pour une navigation plus fluide entre les volumes.
This commit is contained in:
parent
330a0fac34
commit
7f9d583c94
@@ -83,7 +83,7 @@
|
||||
ChevronUpIcon,
|
||||
MagnifyingGlassIcon
|
||||
} from '@heroicons/vue/24/outline';
|
||||
import { ref } from 'vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import { useMangaStore } from '../../application/store/mangaStore';
|
||||
import MangaChapterList from './MangaChapterList.vue';
|
||||
|
||||
@@ -106,13 +106,21 @@ import MangaChapterList from './MangaChapterList.vue';
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['toggle']);
|
||||
|
||||
const store = useMangaStore();
|
||||
const isOpen = ref(props.isOpen);
|
||||
const isSearching = ref(false);
|
||||
const isDownloading = ref(false);
|
||||
|
||||
// Synchroniser l'état local avec la prop
|
||||
watch(() => props.isOpen, (newValue) => {
|
||||
isOpen.value = newValue;
|
||||
});
|
||||
|
||||
const toggleVolume = () => {
|
||||
isOpen.value = !isOpen.value;
|
||||
emit('toggle', props.volume.number);
|
||||
};
|
||||
|
||||
const handleSearch = async () => {
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
:volume="volume"
|
||||
:mangaSlug="mangaSlug"
|
||||
:mangaId="mangaId"
|
||||
:isOpen="index === 0" />
|
||||
:isOpen="expandedVolumes.has(volume.number)"
|
||||
@toggle="handleVolumeToggle" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue';
|
||||
import MangaVolume from './MangaVolume.vue';
|
||||
|
||||
const props = defineProps({
|
||||
@@ -25,6 +27,69 @@
|
||||
mangaId: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
expandAll: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:expandAll']);
|
||||
|
||||
// Set pour stocker les numéros de volumes ouverts
|
||||
const expandedVolumes = ref(new Set());
|
||||
|
||||
// Initialiser avec le premier volume ouvert par défaut
|
||||
watch(() => props.volumes, (newVolumes) => {
|
||||
if (newVolumes.length > 0 && expandedVolumes.value.size === 0) {
|
||||
// Ouvrir le premier volume (volume 00) par défaut
|
||||
expandedVolumes.value.add(newVolumes[0].number);
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
// Gérer l'expansion de tous les volumes
|
||||
watch(() => props.expandAll, (shouldExpand) => {
|
||||
if (shouldExpand) {
|
||||
// Ouvrir tous les volumes
|
||||
props.volumes.forEach(volume => {
|
||||
expandedVolumes.value.add(volume.number);
|
||||
});
|
||||
} else {
|
||||
// Fermer tous les volumes (y compris le volume 00)
|
||||
expandedVolumes.value.clear();
|
||||
}
|
||||
});
|
||||
|
||||
const handleVolumeToggle = (volumeNumber) => {
|
||||
if (expandedVolumes.value.has(volumeNumber)) {
|
||||
expandedVolumes.value.delete(volumeNumber);
|
||||
} else {
|
||||
expandedVolumes.value.add(volumeNumber);
|
||||
}
|
||||
|
||||
// Émettre l'état d'expansion
|
||||
const allExpanded = props.volumes.length > 0 &&
|
||||
props.volumes.every(volume => expandedVolumes.value.has(volume.number));
|
||||
emit('update:expandAll', allExpanded);
|
||||
};
|
||||
|
||||
// Méthode publique pour contrôler l'expansion
|
||||
const expandAllVolumes = () => {
|
||||
props.volumes.forEach(volume => {
|
||||
expandedVolumes.value.add(volume.number);
|
||||
});
|
||||
emit('update:expandAll', true);
|
||||
};
|
||||
|
||||
const collapseAllVolumes = () => {
|
||||
expandedVolumes.value.clear();
|
||||
// Ne plus garder le premier volume ouvert, tous les volumes sont fermés
|
||||
emit('update:expandAll', false);
|
||||
};
|
||||
|
||||
// Exposer les méthodes pour le composant parent
|
||||
defineExpose({
|
||||
expandAllVolumes,
|
||||
collapseAllVolumes
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -27,7 +27,13 @@
|
||||
<div v-else-if="errorVolumes" class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
|
||||
{{ errorVolumes.message || 'Une erreur est survenue lors du chargement des volumes.' }}
|
||||
</div>
|
||||
<MangaVolumeList v-else :volumes="volumes" :manga-slug="currentManga.slug" :manga-id="mangaId" />
|
||||
<MangaVolumeList
|
||||
v-else
|
||||
ref="volumeListRef"
|
||||
:volumes="volumes"
|
||||
:manga-slug="currentManga.slug"
|
||||
:manga-id="mangaId"
|
||||
v-model:expand-all="isAllExpanded" />
|
||||
</div>
|
||||
|
||||
<!-- Modale des sources préférées -->
|
||||
@@ -80,8 +86,8 @@
|
||||
BookmarkIcon,
|
||||
BookmarkSlashIcon,
|
||||
ChevronDoubleDownIcon,
|
||||
ChevronDoubleUpIcon,
|
||||
Cog6ToothIcon,
|
||||
DocumentArrowDownIcon,
|
||||
PencilSquareIcon,
|
||||
TrashIcon,
|
||||
WrenchIcon
|
||||
@@ -118,6 +124,10 @@ import { useMangaStore } from '../../application/store/mangaStore';
|
||||
const isSavingChapters = ref(false);
|
||||
const chaptersError = ref(null);
|
||||
|
||||
// État d'expansion des volumes
|
||||
const isAllExpanded = ref(false);
|
||||
const volumeListRef = ref(null);
|
||||
|
||||
const {
|
||||
data: currentManga,
|
||||
isLoading: isLoadingDetails,
|
||||
@@ -270,6 +280,17 @@ import { useMangaStore } from '../../application/store/mangaStore';
|
||||
}
|
||||
};
|
||||
|
||||
// Fonction pour étendre/réduire tous les volumes
|
||||
const handleExpandAll = () => {
|
||||
if (!volumeListRef.value) return;
|
||||
|
||||
if (isAllExpanded.value) {
|
||||
volumeListRef.value.collapseAllVolumes();
|
||||
} else {
|
||||
volumeListRef.value.expandAllVolumes();
|
||||
}
|
||||
};
|
||||
|
||||
const toolbarConfig = computed(() => ({
|
||||
leftSection: [
|
||||
{
|
||||
@@ -286,12 +307,6 @@ import { useMangaStore } from '../../application/store/mangaStore';
|
||||
type: 'button',
|
||||
onClick: openManageChaptersModal
|
||||
},
|
||||
{
|
||||
icon: DocumentArrowDownIcon,
|
||||
label: 'Manage cbz',
|
||||
type: 'button',
|
||||
onClick: () => console.log('Manage cbz')
|
||||
},
|
||||
{
|
||||
icon: Cog6ToothIcon,
|
||||
label: 'Preferred Sources',
|
||||
@@ -322,10 +337,11 @@ import { useMangaStore } from '../../application/store/mangaStore';
|
||||
onClick: () => console.log('Delete')
|
||||
},
|
||||
{
|
||||
icon: ChevronDoubleDownIcon,
|
||||
label: 'Expand all',
|
||||
icon: isAllExpanded.value ? ChevronDoubleUpIcon : ChevronDoubleDownIcon,
|
||||
label: isAllExpanded.value ? 'Collapse all' : 'Expand all',
|
||||
type: 'button',
|
||||
onClick: () => console.log('Expand all')
|
||||
onClick: handleExpandAll,
|
||||
variant: isAllExpanded.value ? 'active' : 'default'
|
||||
}
|
||||
]
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user