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,
|
ChevronUpIcon,
|
||||||
MagnifyingGlassIcon
|
MagnifyingGlassIcon
|
||||||
} from '@heroicons/vue/24/outline';
|
} from '@heroicons/vue/24/outline';
|
||||||
import { ref } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import { useMangaStore } from '../../application/store/mangaStore';
|
import { useMangaStore } from '../../application/store/mangaStore';
|
||||||
import MangaChapterList from './MangaChapterList.vue';
|
import MangaChapterList from './MangaChapterList.vue';
|
||||||
|
|
||||||
@@ -106,13 +106,21 @@ import MangaChapterList from './MangaChapterList.vue';
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['toggle']);
|
||||||
|
|
||||||
const store = useMangaStore();
|
const store = useMangaStore();
|
||||||
const isOpen = ref(props.isOpen);
|
const isOpen = ref(props.isOpen);
|
||||||
const isSearching = ref(false);
|
const isSearching = ref(false);
|
||||||
const isDownloading = ref(false);
|
const isDownloading = ref(false);
|
||||||
|
|
||||||
|
// Synchroniser l'état local avec la prop
|
||||||
|
watch(() => props.isOpen, (newValue) => {
|
||||||
|
isOpen.value = newValue;
|
||||||
|
});
|
||||||
|
|
||||||
const toggleVolume = () => {
|
const toggleVolume = () => {
|
||||||
isOpen.value = !isOpen.value;
|
isOpen.value = !isOpen.value;
|
||||||
|
emit('toggle', props.volume.number);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSearch = async () => {
|
const handleSearch = async () => {
|
||||||
|
|||||||
@@ -6,11 +6,13 @@
|
|||||||
:volume="volume"
|
:volume="volume"
|
||||||
:mangaSlug="mangaSlug"
|
:mangaSlug="mangaSlug"
|
||||||
:mangaId="mangaId"
|
:mangaId="mangaId"
|
||||||
:isOpen="index === 0" />
|
:isOpen="expandedVolumes.has(volume.number)"
|
||||||
|
@toggle="handleVolumeToggle" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
import MangaVolume from './MangaVolume.vue';
|
import MangaVolume from './MangaVolume.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -25,6 +27,69 @@
|
|||||||
mangaId: {
|
mangaId: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true
|
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>
|
</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">
|
<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.' }}
|
{{ errorVolumes.message || 'Une erreur est survenue lors du chargement des volumes.' }}
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
<!-- Modale des sources préférées -->
|
<!-- Modale des sources préférées -->
|
||||||
@@ -80,8 +86,8 @@
|
|||||||
BookmarkIcon,
|
BookmarkIcon,
|
||||||
BookmarkSlashIcon,
|
BookmarkSlashIcon,
|
||||||
ChevronDoubleDownIcon,
|
ChevronDoubleDownIcon,
|
||||||
|
ChevronDoubleUpIcon,
|
||||||
Cog6ToothIcon,
|
Cog6ToothIcon,
|
||||||
DocumentArrowDownIcon,
|
|
||||||
PencilSquareIcon,
|
PencilSquareIcon,
|
||||||
TrashIcon,
|
TrashIcon,
|
||||||
WrenchIcon
|
WrenchIcon
|
||||||
@@ -118,6 +124,10 @@ import { useMangaStore } from '../../application/store/mangaStore';
|
|||||||
const isSavingChapters = ref(false);
|
const isSavingChapters = ref(false);
|
||||||
const chaptersError = ref(null);
|
const chaptersError = ref(null);
|
||||||
|
|
||||||
|
// État d'expansion des volumes
|
||||||
|
const isAllExpanded = ref(false);
|
||||||
|
const volumeListRef = ref(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: currentManga,
|
data: currentManga,
|
||||||
isLoading: isLoadingDetails,
|
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(() => ({
|
const toolbarConfig = computed(() => ({
|
||||||
leftSection: [
|
leftSection: [
|
||||||
{
|
{
|
||||||
@@ -286,12 +307,6 @@ import { useMangaStore } from '../../application/store/mangaStore';
|
|||||||
type: 'button',
|
type: 'button',
|
||||||
onClick: openManageChaptersModal
|
onClick: openManageChaptersModal
|
||||||
},
|
},
|
||||||
{
|
|
||||||
icon: DocumentArrowDownIcon,
|
|
||||||
label: 'Manage cbz',
|
|
||||||
type: 'button',
|
|
||||||
onClick: () => console.log('Manage cbz')
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
icon: Cog6ToothIcon,
|
icon: Cog6ToothIcon,
|
||||||
label: 'Preferred Sources',
|
label: 'Preferred Sources',
|
||||||
@@ -322,10 +337,11 @@ import { useMangaStore } from '../../application/store/mangaStore';
|
|||||||
onClick: () => console.log('Delete')
|
onClick: () => console.log('Delete')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: ChevronDoubleDownIcon,
|
icon: isAllExpanded.value ? ChevronDoubleUpIcon : ChevronDoubleDownIcon,
|
||||||
label: 'Expand all',
|
label: isAllExpanded.value ? 'Collapse all' : 'Expand all',
|
||||||
type: 'button',
|
type: 'button',
|
||||||
onClick: () => console.log('Expand all')
|
onClick: handleExpandAll,
|
||||||
|
variant: isAllExpanded.value ? 'active' : 'default'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}));
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user