mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-07 14:56:06 +02:00
add destructive variant to alert dialogs for destructive actions
This commit is contained in:
@@ -287,7 +287,8 @@ export function useAvatarDialogCommands(
|
|||||||
title: t('confirm.title'),
|
title: t('confirm.title'),
|
||||||
description: t('confirm.command_question', {
|
description: t('confirm.command_question', {
|
||||||
command: t('dialog.avatar.actions.block')
|
command: t('dialog.avatar.actions.block')
|
||||||
})
|
}),
|
||||||
|
destructive: true
|
||||||
}),
|
}),
|
||||||
handler: (id) => {
|
handler: (id) => {
|
||||||
avatarModerationRequest
|
avatarModerationRequest
|
||||||
@@ -369,7 +370,8 @@ export function useAvatarDialogCommands(
|
|||||||
title: t('confirm.title'),
|
title: t('confirm.title'),
|
||||||
description: t('confirm.command_question', {
|
description: t('confirm.command_question', {
|
||||||
command: t('dialog.avatar.actions.delete')
|
command: t('dialog.avatar.actions.delete')
|
||||||
})
|
}),
|
||||||
|
destructive: true
|
||||||
}),
|
}),
|
||||||
handler: (id) => {
|
handler: (id) => {
|
||||||
avatarRequest
|
avatarRequest
|
||||||
@@ -399,7 +401,8 @@ export function useAvatarDialogCommands(
|
|||||||
title: t('confirm.title'),
|
title: t('confirm.title'),
|
||||||
description: t('confirm.command_question', {
|
description: t('confirm.command_question', {
|
||||||
command: t('dialog.avatar.actions.delete_impostor')
|
command: t('dialog.avatar.actions.delete_impostor')
|
||||||
})
|
}),
|
||||||
|
destructive: true
|
||||||
}),
|
}),
|
||||||
handler: (id) => {
|
handler: (id) => {
|
||||||
avatarRequest
|
avatarRequest
|
||||||
@@ -432,7 +435,8 @@ export function useAvatarDialogCommands(
|
|||||||
title: t('confirm.title'),
|
title: t('confirm.title'),
|
||||||
description: t('confirm.command_question', {
|
description: t('confirm.command_question', {
|
||||||
command: t('dialog.avatar.actions.regenerate_impostor')
|
command: t('dialog.avatar.actions.regenerate_impostor')
|
||||||
})
|
}),
|
||||||
|
destructive: true
|
||||||
}),
|
}),
|
||||||
handler: (id) => {
|
handler: (id) => {
|
||||||
avatarRequest
|
avatarRequest
|
||||||
|
|||||||
@@ -770,7 +770,8 @@
|
|||||||
const dashboardId = String(dashboardKey || '').replace(DASHBOARD_NAV_KEY_PREFIX, '');
|
const dashboardId = String(dashboardKey || '').replace(DASHBOARD_NAV_KEY_PREFIX, '');
|
||||||
const { ok } = await modalStore.confirm({
|
const { ok } = await modalStore.confirm({
|
||||||
title: t('dashboard.confirmations.delete_title'),
|
title: t('dashboard.confirmations.delete_title'),
|
||||||
description: t('dashboard.confirmations.delete_description')
|
description: t('dashboard.confirmations.delete_description'),
|
||||||
|
destructive: true
|
||||||
});
|
});
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -561,7 +561,8 @@
|
|||||||
modalStore
|
modalStore
|
||||||
.confirm({
|
.confirm({
|
||||||
description: t('confirm.delete_post'),
|
description: t('confirm.delete_post'),
|
||||||
title: t('confirm.title')
|
title: t('confirm.title'),
|
||||||
|
destructive: true
|
||||||
})
|
})
|
||||||
.then(({ ok }) => {
|
.then(({ ok }) => {
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
|
|||||||
@@ -84,7 +84,8 @@ export function useGroupDialogCommands(
|
|||||||
'Block Group': {
|
'Block Group': {
|
||||||
confirm: () => ({
|
confirm: () => ({
|
||||||
title: t('confirm.title'),
|
title: t('confirm.title'),
|
||||||
description: t('confirm.block_group')
|
description: t('confirm.block_group'),
|
||||||
|
destructive: true
|
||||||
}),
|
}),
|
||||||
handler: (id) => {
|
handler: (id) => {
|
||||||
groupRequest.blockGroup({ groupId: id }).then((args) => {
|
groupRequest.blockGroup({ groupId: id }).then((args) => {
|
||||||
|
|||||||
@@ -486,7 +486,8 @@ export function useUserDialogCommands(
|
|||||||
title: t('confirm.title'),
|
title: t('confirm.title'),
|
||||||
description: t('confirm.command_question', {
|
description: t('confirm.command_question', {
|
||||||
command: t('dialog.user.actions.moderation_block')
|
command: t('dialog.user.actions.moderation_block')
|
||||||
})
|
}),
|
||||||
|
destructive: true
|
||||||
}),
|
}),
|
||||||
handler: async (userId) => {
|
handler: async (userId) => {
|
||||||
const args =
|
const args =
|
||||||
@@ -518,7 +519,8 @@ export function useUserDialogCommands(
|
|||||||
title: t('confirm.title'),
|
title: t('confirm.title'),
|
||||||
description: t('confirm.command_question', {
|
description: t('confirm.command_question', {
|
||||||
command: t('dialog.user.actions.moderation_mute')
|
command: t('dialog.user.actions.moderation_mute')
|
||||||
})
|
}),
|
||||||
|
destructive: true
|
||||||
}),
|
}),
|
||||||
handler: async (userId) => {
|
handler: async (userId) => {
|
||||||
const args =
|
const args =
|
||||||
@@ -554,7 +556,8 @@ export function useUserDialogCommands(
|
|||||||
command: t(
|
command: t(
|
||||||
'dialog.user.actions.moderation_disable_avatar_interaction'
|
'dialog.user.actions.moderation_disable_avatar_interaction'
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
|
destructive: true
|
||||||
}),
|
}),
|
||||||
handler: async (userId) => {
|
handler: async (userId) => {
|
||||||
const args =
|
const args =
|
||||||
@@ -590,7 +593,8 @@ export function useUserDialogCommands(
|
|||||||
command: t(
|
command: t(
|
||||||
'dialog.user.actions.moderation_disable_chatbox'
|
'dialog.user.actions.moderation_disable_chatbox'
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
|
destructive: true
|
||||||
}),
|
}),
|
||||||
handler: async (userId) => {
|
handler: async (userId) => {
|
||||||
const args =
|
const args =
|
||||||
@@ -622,7 +626,8 @@ export function useUserDialogCommands(
|
|||||||
title: t('confirm.title'),
|
title: t('confirm.title'),
|
||||||
description: t('confirm.command_question', {
|
description: t('confirm.command_question', {
|
||||||
command: t('dialog.user.actions.unfriend')
|
command: t('dialog.user.actions.unfriend')
|
||||||
})
|
}),
|
||||||
|
destructive: true
|
||||||
}),
|
}),
|
||||||
handler: async (userId) => {
|
handler: async (userId) => {
|
||||||
const args = await friendRequest.deleteFriend(
|
const args = await friendRequest.deleteFriend(
|
||||||
|
|||||||
@@ -528,7 +528,8 @@ export function useWorldDialogCommands(
|
|||||||
title: t('confirm.title'),
|
title: t('confirm.title'),
|
||||||
description: t('confirm.command_question', {
|
description: t('confirm.command_question', {
|
||||||
command: t('dialog.world.actions.delete')
|
command: t('dialog.world.actions.delete')
|
||||||
})
|
}),
|
||||||
|
destructive: true
|
||||||
}),
|
}),
|
||||||
handler: (id) => {
|
handler: (id) => {
|
||||||
worldRequest.deleteWorld({ worldId: id }).then((args) => {
|
worldRequest.deleteWorld({ worldId: id }).then((args) => {
|
||||||
|
|||||||
@@ -50,11 +50,11 @@
|
|||||||
</ContextMenuTrigger>
|
</ContextMenuTrigger>
|
||||||
<ContextMenuContent>
|
<ContextMenuContent>
|
||||||
<ContextMenuItem
|
<ContextMenuItem
|
||||||
:disabled="!hasNotifications"
|
v-if="hasNotifications"
|
||||||
@click="clearAllNotifications">
|
@click="clearAllNotifications">
|
||||||
{{ t('nav_menu.mark_all_read') }}
|
{{ t('nav_menu.mark_all_read') }}
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
<ContextMenuSeparator />
|
<ContextMenuSeparator v-if="hasNotifications" />
|
||||||
<template v-if="isDashboardItem(item)">
|
<template v-if="isDashboardItem(item)">
|
||||||
<ContextMenuItem @click="handleEditDashboard(item)">
|
<ContextMenuItem @click="handleEditDashboard(item)">
|
||||||
{{ t('nav_menu.edit_dashboard') }}
|
{{ t('nav_menu.edit_dashboard') }}
|
||||||
@@ -101,10 +101,10 @@
|
|||||||
</SidebarContent>
|
</SidebarContent>
|
||||||
</ContextMenuTrigger>
|
</ContextMenuTrigger>
|
||||||
<ContextMenuContent>
|
<ContextMenuContent>
|
||||||
<ContextMenuItem :disabled="!hasNotifications" @click="clearAllNotifications">
|
<ContextMenuItem v-if="hasNotifications" @click="clearAllNotifications">
|
||||||
{{ t('nav_menu.mark_all_read') }}
|
{{ t('nav_menu.mark_all_read') }}
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
<ContextMenuSeparator />
|
<ContextMenuSeparator v-if="hasNotifications" />
|
||||||
<ContextMenuItem @click="handleQuickCreateDashboard">
|
<ContextMenuItem @click="handleQuickCreateDashboard">
|
||||||
{{ t('dashboard.new_dashboard') }}
|
{{ t('dashboard.new_dashboard') }}
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
@@ -361,7 +361,8 @@
|
|||||||
}
|
}
|
||||||
const { ok } = await modalStore.confirm({
|
const { ok } = await modalStore.confirm({
|
||||||
title: t('dashboard.confirmations.delete_title'),
|
title: t('dashboard.confirmations.delete_title'),
|
||||||
description: t('dashboard.confirmations.delete_description')
|
description: t('dashboard.confirmations.delete_description'),
|
||||||
|
destructive: true
|
||||||
});
|
});
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -94,11 +94,11 @@
|
|||||||
</ContextMenuTrigger>
|
</ContextMenuTrigger>
|
||||||
<ContextMenuContent>
|
<ContextMenuContent>
|
||||||
<ContextMenuItem
|
<ContextMenuItem
|
||||||
:disabled="!hasNotifications"
|
v-if="hasNotifications"
|
||||||
@click="emit('clear-notifications')">
|
@click="emit('clear-notifications')">
|
||||||
{{ t('nav_menu.mark_all_read') }}
|
{{ t('nav_menu.mark_all_read') }}
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
<ContextMenuSeparator />
|
<ContextMenuSeparator v-if="hasNotifications" />
|
||||||
<template v-if="isDashboardItem(entry)">
|
<template v-if="isDashboardItem(entry)">
|
||||||
<ContextMenuItem @click="emit('edit-dashboard', entry)">
|
<ContextMenuItem @click="emit('edit-dashboard', entry)">
|
||||||
{{ t('nav_menu.edit_dashboard') }}
|
{{ t('nav_menu.edit_dashboard') }}
|
||||||
@@ -126,10 +126,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</ContextMenuTrigger>
|
</ContextMenuTrigger>
|
||||||
<ContextMenuContent>
|
<ContextMenuContent>
|
||||||
<ContextMenuItem :disabled="!hasNotifications" @click="emit('clear-notifications')">
|
<ContextMenuItem v-if="hasNotifications" @click="emit('clear-notifications')">
|
||||||
{{ t('nav_menu.mark_all_read') }}
|
{{ t('nav_menu.mark_all_read') }}
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
<ContextMenuSeparator />
|
<ContextMenuSeparator v-if="hasNotifications" />
|
||||||
<ContextMenuItem @click="emit('create-dashboard')">
|
<ContextMenuItem @click="emit('create-dashboard')">
|
||||||
{{ t('dashboard.new_dashboard') }}
|
{{ t('dashboard.new_dashboard') }}
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
|
|||||||
@@ -7,14 +7,15 @@
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
asChild: { type: Boolean, required: false },
|
asChild: { type: Boolean, required: false },
|
||||||
as: { type: null, required: false },
|
as: { type: null, required: false },
|
||||||
|
variant: { type: String, required: false },
|
||||||
class: { type: null, required: false }
|
class: { type: null, required: false }
|
||||||
});
|
});
|
||||||
|
|
||||||
const delegatedProps = reactiveOmit(props, 'class');
|
const delegatedProps = reactiveOmit(props, 'class', 'variant');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<AlertDialogAction v-bind="delegatedProps" :class="cn(buttonVariants(), props.class)">
|
<AlertDialogAction v-bind="delegatedProps" :class="cn(buttonVariants({ variant: props.variant }), props.class)">
|
||||||
<slot />
|
<slot />
|
||||||
</AlertDialogAction>
|
</AlertDialogAction>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
const modalStore = useModalStore();
|
const modalStore = useModalStore();
|
||||||
|
|
||||||
const { alertOpen, alertMode, alertTitle, alertDescription, alertOkText, alertCancelText, alertDismissible } =
|
const { alertOpen, alertMode, alertTitle, alertDescription, alertOkText, alertCancelText, alertDismissible, alertDestructive } =
|
||||||
storeToRefs(modalStore);
|
storeToRefs(modalStore);
|
||||||
|
|
||||||
function onEscapeKeyDown(event) {
|
function onEscapeKeyDown(event) {
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
{{ alertCancelText }}
|
{{ alertCancelText }}
|
||||||
</AlertDialogCancel>
|
</AlertDialogCancel>
|
||||||
|
|
||||||
<AlertDialogAction @click="modalStore.handleOk">
|
<AlertDialogAction :variant="alertDestructive ? 'destructive' : undefined" @click="modalStore.handleOk">
|
||||||
{{ alertOkText }}
|
{{ alertOkText }}
|
||||||
</AlertDialogAction>
|
</AlertDialogAction>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
|
|||||||
@@ -232,7 +232,8 @@ export function promptClearAvatarHistory() {
|
|||||||
modalStore
|
modalStore
|
||||||
.confirm({
|
.confirm({
|
||||||
description: t('confirm.clear_avatar_history'),
|
description: t('confirm.clear_avatar_history'),
|
||||||
title: 'Confirm'
|
title: t('confirm.title'),
|
||||||
|
destructive: true
|
||||||
})
|
})
|
||||||
.then(({ ok }) => {
|
.then(({ ok }) => {
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
@@ -472,7 +473,7 @@ export function selectAvatarWithConfirmation(id) {
|
|||||||
modalStore
|
modalStore
|
||||||
.confirm({
|
.confirm({
|
||||||
description: t('confirm.select_avatar'),
|
description: t('confirm.select_avatar'),
|
||||||
title: 'Confirm'
|
title: t('confirm.title')
|
||||||
})
|
})
|
||||||
.then(({ ok }) => {
|
.then(({ ok }) => {
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
|
|||||||
@@ -746,7 +746,8 @@ export function leaveGroupPrompt(groupId) {
|
|||||||
modalStore
|
modalStore
|
||||||
.confirm({
|
.confirm({
|
||||||
description: t('confirm.leave_group'),
|
description: t('confirm.leave_group'),
|
||||||
title: t('confirm.title')
|
title: t('confirm.title'),
|
||||||
|
destructive: true
|
||||||
})
|
})
|
||||||
.then(({ ok }) => {
|
.then(({ ok }) => {
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
|
|||||||
@@ -187,7 +187,8 @@
|
|||||||
"tab_group": "Group",
|
"tab_group": "Group",
|
||||||
"tab_other": "Other",
|
"tab_other": "Other",
|
||||||
"past_notifications": "Last 24 hours",
|
"past_notifications": "Last 24 hours",
|
||||||
"no_new_notifications": "No new notifications in the past 24 hours"
|
"no_new_notifications": "No new notifications in the past 24 hours",
|
||||||
|
"no_unseen_notifications": "No unread notifications"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"view": {
|
"view": {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { useI18n } from 'vue-i18n';
|
|||||||
* @property {string=} confirmText
|
* @property {string=} confirmText
|
||||||
* @property {string=} cancelText
|
* @property {string=} cancelText
|
||||||
* @property {boolean=} dismissible // true: allow esc/outside, false: block
|
* @property {boolean=} dismissible // true: allow esc/outside, false: block
|
||||||
|
* @property {boolean=} destructive // true: use destructive variant for confirm button
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,6 +24,7 @@ import { useI18n } from 'vue-i18n';
|
|||||||
* @property {string} description
|
* @property {string} description
|
||||||
* @property {string=} confirmText
|
* @property {string=} confirmText
|
||||||
* @property {boolean=} dismissible
|
* @property {boolean=} dismissible
|
||||||
|
* @property {boolean=} destructive // true: use destructive variant for confirm button
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,6 +67,7 @@ export const useModalStore = defineStore('Modal', () => {
|
|||||||
const alertOkText = ref('');
|
const alertOkText = ref('');
|
||||||
const alertCancelText = ref('');
|
const alertCancelText = ref('');
|
||||||
const alertDismissible = ref(true);
|
const alertDismissible = ref(true);
|
||||||
|
const alertDestructive = ref(false);
|
||||||
|
|
||||||
const promptOpen = ref(false);
|
const promptOpen = ref(false);
|
||||||
const promptTitle = ref('');
|
const promptTitle = ref('');
|
||||||
@@ -155,6 +158,7 @@ export const useModalStore = defineStore('Modal', () => {
|
|||||||
alertTitle.value = options.title;
|
alertTitle.value = options.title;
|
||||||
alertDescription.value = options.description;
|
alertDescription.value = options.description;
|
||||||
alertDismissible.value = options.dismissible !== false;
|
alertDismissible.value = options.dismissible !== false;
|
||||||
|
alertDestructive.value = options.destructive === true;
|
||||||
|
|
||||||
if (mode === 'alert') {
|
if (mode === 'alert') {
|
||||||
alertOkText.value =
|
alertOkText.value =
|
||||||
@@ -381,6 +385,7 @@ export const useModalStore = defineStore('Modal', () => {
|
|||||||
alertOkText,
|
alertOkText,
|
||||||
alertCancelText,
|
alertCancelText,
|
||||||
alertDismissible,
|
alertDismissible,
|
||||||
|
alertDestructive,
|
||||||
promptOpen,
|
promptOpen,
|
||||||
promptTitle,
|
promptTitle,
|
||||||
promptDescription,
|
promptDescription,
|
||||||
|
|||||||
@@ -212,7 +212,8 @@
|
|||||||
const handleDelete = async () => {
|
const handleDelete = async () => {
|
||||||
const { ok } = await modalStore.confirm({
|
const { ok } = await modalStore.confirm({
|
||||||
title: t('dashboard.confirmations.delete_title'),
|
title: t('dashboard.confirmations.delete_title'),
|
||||||
description: t('dashboard.confirmations.delete_description')
|
description: t('dashboard.confirmations.delete_description'),
|
||||||
|
destructive: true
|
||||||
});
|
});
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -880,7 +880,8 @@
|
|||||||
invalidIdsText,
|
invalidIdsText,
|
||||||
title: t('view.favorite.avatars.confirm_delete_invalid'),
|
title: t('view.favorite.avatars.confirm_delete_invalid'),
|
||||||
confirmText: t('confirm.confirm_button'),
|
confirmText: t('confirm.confirm_button'),
|
||||||
cancelText: t('view.favorite.avatars.copy_removed_ids')
|
cancelText: t('view.favorite.avatars.copy_removed_ids'),
|
||||||
|
destructive: true
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!confirmDeleteResult.ok) {
|
if (!confirmDeleteResult.ok) {
|
||||||
@@ -1000,7 +1001,8 @@
|
|||||||
modalStore
|
modalStore
|
||||||
.confirm({
|
.confirm({
|
||||||
description: t('confirm.clear_group'),
|
description: t('confirm.clear_group'),
|
||||||
title: t('confirm.title')
|
title: t('confirm.title'),
|
||||||
|
destructive: true
|
||||||
})
|
})
|
||||||
.then(({ ok }) => {
|
.then(({ ok }) => {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
@@ -1050,7 +1052,8 @@
|
|||||||
modalStore
|
modalStore
|
||||||
.confirm({
|
.confirm({
|
||||||
description: t('confirm.delete_group', { name: group }),
|
description: t('confirm.delete_group', { name: group }),
|
||||||
title: t('confirm.title')
|
title: t('confirm.title'),
|
||||||
|
destructive: true
|
||||||
})
|
})
|
||||||
.then(({ ok }) => {
|
.then(({ ok }) => {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
@@ -1223,9 +1226,9 @@
|
|||||||
const total = selectedFavoriteAvatars.value.length;
|
const total = selectedFavoriteAvatars.value.length;
|
||||||
modalStore
|
modalStore
|
||||||
.confirm({
|
.confirm({
|
||||||
description: `Are you sure you want to unfavorite ${total} favorites?
|
description: t('confirm.bulk_unfavorite', { count: total }),
|
||||||
This action cannot be undone.`,
|
title: t('confirm.bulk_unfavorite_title', { count: total }),
|
||||||
title: `Delete ${total} favorites?`
|
destructive: true
|
||||||
})
|
})
|
||||||
.then(({ ok }) => {
|
.then(({ ok }) => {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<RefreshCw v-else />
|
<RefreshCw v-else />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
<ContextMenu>
|
<ContextMenu v-if="hasUnseenNotifications">
|
||||||
<ContextMenuTrigger as-child>
|
<ContextMenuTrigger as-child>
|
||||||
<TooltipWrapper side="bottom" :content="t('side_panel.notification_center.title')">
|
<TooltipWrapper side="bottom" :content="t('side_panel.notification_center.title')">
|
||||||
<Button
|
<Button
|
||||||
@@ -36,17 +36,26 @@
|
|||||||
@click="isNotificationCenterOpen = !isNotificationCenterOpen">
|
@click="isNotificationCenterOpen = !isNotificationCenterOpen">
|
||||||
<Bell />
|
<Bell />
|
||||||
<span
|
<span
|
||||||
v-if="hasUnseenNotifications"
|
|
||||||
class="absolute top-1 right-1.25 size-1.5 rounded-full bg-red-500" />
|
class="absolute top-1 right-1.25 size-1.5 rounded-full bg-red-500" />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
</ContextMenuTrigger>
|
</ContextMenuTrigger>
|
||||||
<ContextMenuContent>
|
<ContextMenuContent>
|
||||||
<ContextMenuItem :disabled="!hasUnseenNotifications" @click="markNotificationsRead">
|
<ContextMenuItem @click="markNotificationsRead">
|
||||||
{{ t('nav_menu.mark_all_read') }}
|
{{ t('nav_menu.mark_all_read') }}
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
</ContextMenuContent>
|
</ContextMenuContent>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
|
<TooltipWrapper v-else side="bottom" :content="t('side_panel.notification_center.title')">
|
||||||
|
<Button
|
||||||
|
class="rounded-full relative"
|
||||||
|
variant="ghost"
|
||||||
|
size="icon-sm"
|
||||||
|
@click="isNotificationCenterOpen = !isNotificationCenterOpen"
|
||||||
|
@contextmenu.prevent="toast.info(t('side_panel.notification_center.no_unseen_notifications'))">
|
||||||
|
<Bell />
|
||||||
|
</Button>
|
||||||
|
</TooltipWrapper>
|
||||||
<Popover v-model:open="isSettingsPopoverOpen">
|
<Popover v-model:open="isSettingsPopoverOpen">
|
||||||
<PopoverTrigger as-child>
|
<PopoverTrigger as-child>
|
||||||
<Button class="rounded-full" variant="ghost" size="icon-sm">
|
<Button class="rounded-full" variant="ghost" size="icon-sm">
|
||||||
@@ -246,6 +255,7 @@
|
|||||||
SelectValue
|
SelectValue
|
||||||
} from '@/components/ui/select';
|
} from '@/components/ui/select';
|
||||||
import { Bell, RefreshCw, Search, Settings } from 'lucide-vue-next';
|
import { Bell, RefreshCw, Search, Settings } from 'lucide-vue-next';
|
||||||
|
import { toast } from 'vue-sonner';
|
||||||
import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from '@/components/ui/context-menu';
|
import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from '@/components/ui/context-menu';
|
||||||
import { Field, FieldContent, FieldLabel } from '@/components/ui/field';
|
import { Field, FieldContent, FieldLabel } from '@/components/ui/field';
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
||||||
|
|||||||
Reference in New Issue
Block a user