feat(home): toolbar filtre/affichage et modale options d'affichage
- Correction du dropdown toolbar : prop align (left/right) pour éviter le débordement hors écran côté droit - Filtre de collection par statut (all/completed/ongoing) persisté dans userPreferencesStore - toolbarConfig rendu réactif (computed) avec isSelected sur Filter, Sort et View - Modale Options d'affichage par vue (Grille, Overview, Table) avec toggles persistés - Composant ToggleRow réutilisable - Normalisation author → authors dans l'entité Manga (l'API renvoie author string)
This commit is contained in:
parent
214f470e77
commit
e525c9b7bd
37
assets/vue/app/shared/components/ui/ToggleRow.vue
Normal file
37
assets/vue/app/shared/components/ui/ToggleRow.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">{{ label }}</span>
|
||||
<button
|
||||
type="button"
|
||||
role="switch"
|
||||
:aria-checked="value"
|
||||
:class="[
|
||||
value ? 'bg-green-500' : 'bg-gray-300 dark:bg-gray-600',
|
||||
'relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2'
|
||||
]"
|
||||
@click="$emit('update', !value)"
|
||||
>
|
||||
<span
|
||||
:class="[
|
||||
value ? 'translate-x-4' : 'translate-x-0',
|
||||
'pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out'
|
||||
]"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
label: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
defineEmits(['update']);
|
||||
</script>
|
||||
@@ -8,7 +8,7 @@
|
||||
<slot name="center" />
|
||||
|
||||
<!-- Right section -->
|
||||
<ToolbarSection :items="config.rightSection" />
|
||||
<ToolbarSection :items="config.rightSection" align="right" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
</div>
|
||||
|
||||
<MenuItems
|
||||
class="absolute left-0 mt-2 w-max origin-top-left rounded-sm bg-gray-800 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-10">
|
||||
:class="[
|
||||
'absolute mt-2 w-max rounded-sm bg-gray-800 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-10',
|
||||
align === 'right' ? 'right-0 origin-top-right' : 'left-0 origin-top-left'
|
||||
]">
|
||||
<div class="px-1 py-1">
|
||||
<MenuItem v-for="(item, index) in items" :key="index" v-slot="{ active }" :disabled="item.disabled">
|
||||
<button
|
||||
@@ -50,6 +53,11 @@ import ToolbarLabel from './ToolbarLabel.vue';
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
align: {
|
||||
type: String,
|
||||
default: 'left',
|
||||
validator: v => ['left', 'right'].includes(v)
|
||||
},
|
||||
items: {
|
||||
type: Array,
|
||||
required: true,
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
:icon="item.icon"
|
||||
:label="item.label"
|
||||
:active="item.active"
|
||||
:items="item.items" />
|
||||
:items="item.items"
|
||||
:align="align" />
|
||||
<Divider v-else-if="item.type === 'divider'" />
|
||||
<span
|
||||
v-else-if="item.type === 'label'"
|
||||
@@ -43,6 +44,10 @@
|
||||
(item.type === 'dropdown' && Array.isArray(item.items)))
|
||||
);
|
||||
}
|
||||
},
|
||||
align: {
|
||||
type: String,
|
||||
default: 'left'
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user