show sidebar view dropdown Ellipsis only on hover of single view.

add toast messages for update, create, delete of view
add confirmation dialog for view deletion
This commit is contained in:
Abhinav Raut
2025-09-10 02:48:48 +05:30
parent dbd4e97f7e
commit 701e5b2580

View File

@@ -38,6 +38,16 @@ import {
DropdownMenuItem, DropdownMenuItem,
DropdownMenuTrigger DropdownMenuTrigger
} from '@/components/ui/dropdown-menu' } from '@/components/ui/dropdown-menu'
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle
} from '@/components/ui/alert-dialog'
import { filterNavItems } from '@/utils/nav-permissions' import { filterNavItems } from '@/utils/nav-permissions'
import { useStorage } from '@vueuse/core' import { useStorage } from '@vueuse/core'
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
@@ -73,8 +83,17 @@ const editView = (view) => {
emit('editView', view) emit('editView', view)
} }
const deleteView = (view) => { const openDeleteConfirmation = (view) => {
emit('deleteView', view) viewToDelete.value = view
isDeleteOpen.value = true
}
const handleDeleteView = () => {
if (viewToDelete.value) {
emit('deleteView', viewToDelete.value)
isDeleteOpen.value = false
viewToDelete.value = null
}
} }
// Navigation methods with conversation retention // Navigation methods with conversation retention
@@ -157,6 +176,13 @@ watch(
const sidebarOpen = useStorage('mainSidebarOpen', true) const sidebarOpen = useStorage('mainSidebarOpen', true)
const teamInboxOpen = useStorage('teamInboxOpen', true) const teamInboxOpen = useStorage('teamInboxOpen', true)
const viewInboxOpen = useStorage('viewInboxOpen', true) const viewInboxOpen = useStorage('viewInboxOpen', true)
// Track which view is being hovered for ellipsis menu visibility
const hoveredViewId = ref(null)
// Track delete confirmation dialog state
const isDeleteOpen = ref(false)
const viewToDelete = ref(null)
</script> </script>
<template> <template>
@@ -472,7 +498,10 @@ const viewInboxOpen = useStorage('viewInboxOpen', true)
<CollapsibleContent> <CollapsibleContent>
<SidebarMenuSub v-for="view in userViews" :key="view.id"> <SidebarMenuSub v-for="view in userViews" :key="view.id">
<SidebarMenuSubItem> <SidebarMenuSubItem
@mouseenter="hoveredViewId = view.id"
@mouseleave="hoveredViewId = null"
>
<SidebarMenuButton <SidebarMenuButton
size="sm" size="sm"
:isActive="route.params.viewID == view.id" :isActive="route.params.viewID == view.id"
@@ -480,16 +509,24 @@ const viewInboxOpen = useStorage('viewInboxOpen', true)
> >
<a href="#" @click.prevent="navigateToViewInbox(view.id)"> <a href="#" @click.prevent="navigateToViewInbox(view.id)">
<span class="break-words w-32 truncate">{{ view.name }}</span> <span class="break-words w-32 truncate">{{ view.name }}</span>
<SidebarMenuAction :showOnHover="true" class="mr-3"> <SidebarMenuAction
@click.stop
:class="[
'mr-3',
'md:opacity-0',
'data-[state=open]:opacity-100',
{ 'md:opacity-100': hoveredViewId === view.id }
]"
>
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild @click.prevent>
<EllipsisVertical /> <EllipsisVertical />
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent> <DropdownMenuContent>
<DropdownMenuItem @click="() => editView(view)"> <DropdownMenuItem @click="() => editView(view)">
<span>{{ t('globals.messages.edit') }}</span> <span>{{ t('globals.messages.edit') }}</span>
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuItem @click="() => deleteView(view)"> <DropdownMenuItem @click="() => openDeleteConfirmation(view)">
<span>{{ t('globals.messages.delete') }}</span> <span>{{ t('globals.messages.delete') }}</span>
</DropdownMenuItem> </DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
@@ -513,4 +550,22 @@ const viewInboxOpen = useStorage('viewInboxOpen', true)
<slot></slot> <slot></slot>
</SidebarInset> </SidebarInset>
</SidebarProvider> </SidebarProvider>
<!-- View Delete Confirmation Dialog -->
<AlertDialog v-model:open="isDeleteOpen">
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{{ t('globals.messages.areYouAbsolutelySure') }}</AlertDialogTitle>
<AlertDialogDescription>
{{ t('globals.messages.deletionConfirmation', { name: t('globals.terms.view') }) }}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>{{ t('globals.messages.cancel') }}</AlertDialogCancel>
<AlertDialogAction @click="handleDeleteView">
{{ t('globals.messages.delete') }}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</template> </template>