init
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
<script lang="ts" setup>
|
||||
import {computed} from 'vue'
|
||||
import {useContextMenu} from '@/composables/useContextMenu'
|
||||
|
||||
const {isOpen, position, items, closeContextMenu} = useContextMenu()
|
||||
|
||||
// Cible virtuelle pour positionner Vuetify v-menu à la position X, Y exacte
|
||||
const targetPosition = computed(() => [position.value.x, position.value.y])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-menu
|
||||
v-model="isOpen"
|
||||
:close-on-content-click="true"
|
||||
:target="targetPosition as any"
|
||||
location="bottom start"
|
||||
>
|
||||
<v-list class="py-1" density="compact" min-width="180">
|
||||
<v-list-item
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
:base-color="item.color"
|
||||
:disabled="item.disabled"
|
||||
@click="item.action"
|
||||
>
|
||||
<template v-if="item.icon" #prepend>
|
||||
<v-icon :icon="item.icon" size="small"/>
|
||||
</template>
|
||||
<v-list-item-title>{{ item.label }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</template>
|
||||
@@ -0,0 +1,36 @@
|
||||
import {ref} from 'vue'
|
||||
|
||||
export interface MenuItem {
|
||||
label: string
|
||||
icon?: string
|
||||
color?: string
|
||||
disabled?: boolean
|
||||
action: () => void
|
||||
}
|
||||
|
||||
const isOpen = ref(false)
|
||||
const position = ref({x: 0, y: 0})
|
||||
const items = ref<MenuItem[]>([])
|
||||
|
||||
export function useContextMenu() {
|
||||
function openContextMenu(event: MouseEvent, menuItems: MenuItem[]) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
position.value = {x: event.clientX, y: event.clientY}
|
||||
items.value = menuItems
|
||||
isOpen.value = true
|
||||
}
|
||||
|
||||
function closeContextMenu() {
|
||||
isOpen.value = false
|
||||
}
|
||||
|
||||
return {
|
||||
isOpen,
|
||||
position,
|
||||
items,
|
||||
openContextMenu,
|
||||
closeContextMenu,
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import {storeToRefs} from 'pinia'
|
||||
import {useServerStore} from '@/stores/server'
|
||||
import {ref} from 'vue'
|
||||
import {useRouter} from 'vue-router'
|
||||
import ContextMenu from "@/components/ContextMenu.vue";
|
||||
|
||||
const serverStore = useServerStore()
|
||||
const router = useRouter()
|
||||
@@ -74,7 +75,7 @@ const getServerColor = (str: string): string => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-app>
|
||||
<v-app @contextmenu.prevent>
|
||||
<!--Top bar-->
|
||||
<v-system-bar>
|
||||
|
||||
@@ -127,7 +128,8 @@ const getServerColor = (str: string): string => {
|
||||
|
||||
</v-navigation-drawer>
|
||||
<router-view/>
|
||||
|
||||
<!-- Menu contextuel global -->
|
||||
<ContextMenu/>
|
||||
<v-dialog v-model="showDialog" width="400">
|
||||
<v-card>
|
||||
<v-card-title>Create Server</v-card-title>
|
||||
|
||||
@@ -5,6 +5,7 @@ import {useCategoryStore} from '@/stores/category'
|
||||
import {ref, watch} from 'vue'
|
||||
import {useRoute} from 'vue-router'
|
||||
import CreateChannelDialog from '@/components/channel/CreateChannelDialog.vue'
|
||||
import {type MenuItem, useContextMenu} from '@/composables/useContextMenu'
|
||||
|
||||
const props = defineProps<{
|
||||
serverId: string
|
||||
@@ -16,6 +17,8 @@ const channelStore = useChannelStore()
|
||||
const categoryStore = useCategoryStore()
|
||||
const {channels} = storeToRefs(channelStore)
|
||||
const {categories} = storeToRefs(categoryStore)
|
||||
const {openContextMenu} = useContextMenu()
|
||||
|
||||
|
||||
const loadServerData = async (targetServerId: string) => {
|
||||
if (!targetServerId) return
|
||||
@@ -42,6 +45,37 @@ watch(
|
||||
)
|
||||
|
||||
const showDialog = ref(false)
|
||||
|
||||
// Right click menu
|
||||
async function openEditDialog(channel: any) {
|
||||
console.log("edit dialog clicked")
|
||||
}
|
||||
|
||||
async function deleteChannel(channelId: string) {
|
||||
console.log("delete channel clicked")
|
||||
}
|
||||
|
||||
function onChannelContextMenu(event: MouseEvent, channel: any) {
|
||||
const menuItems: MenuItem[] = [
|
||||
{
|
||||
label: 'Marquer comme lu',
|
||||
icon: 'mdi-check',
|
||||
action: () => console.log('Marqué comme lu', channel.id),
|
||||
},
|
||||
{
|
||||
label: 'Modifier le canal',
|
||||
icon: 'mdi-pencil',
|
||||
action: () => openEditDialog(channel),
|
||||
},
|
||||
{
|
||||
label: 'Supprimer le canal',
|
||||
icon: 'mdi-delete',
|
||||
color: 'error',
|
||||
action: () => deleteChannel(channel.id),
|
||||
},
|
||||
]
|
||||
openContextMenu(event, menuItems);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -69,6 +103,7 @@ const showDialog = ref(false)
|
||||
:title="channel.name"
|
||||
:to="`/server/${serverId}/channel/${channel.id}`"
|
||||
link
|
||||
@contextmenu="onChannelContextMenu($event, channel)"
|
||||
></v-list-item>
|
||||
</v-list>
|
||||
</v-navigation-drawer>
|
||||
|
||||
Reference in New Issue
Block a user