feat(web): add gql archival mutations to notifications sidebar & item

This commit is contained in:
Pujit Mehrotra
2024-10-17 10:47:20 -04:00
parent 1c4506cf50
commit 8fe1e80bbd
5 changed files with 117 additions and 30 deletions

View File

@@ -5,39 +5,54 @@ import {
CheckBadgeIcon,
ExclamationTriangleIcon,
LinkIcon,
} from '@heroicons/vue/24/solid';
import type { NotificationFragmentFragment } from '~/composables/gql/graphql';
} from "@heroicons/vue/24/solid";
import { useMutation } from "@vue/apollo-composable";
import type { NotificationFragmentFragment } from "~/composables/gql/graphql";
import { archiveNotification as archiveMutation } from "./graphql/notification.query";
const props = defineProps<NotificationFragmentFragment>();
const icon = computed<{ component: Component, color: string } | null>(() => {
const icon = computed<{ component: Component; color: string } | null>(() => {
switch (props.importance) {
case 'INFO':
case "INFO":
return {
component: CheckBadgeIcon,
color: 'text-green-500',
color: "text-green-500",
};
case 'WARNING':
case "WARNING":
return {
component: ExclamationTriangleIcon,
color: 'text-yellow-500',
color: "text-yellow-500",
};
case 'ALERT':
case "ALERT":
return {
component: ShieldExclamationIcon,
color: 'text-red-500',
color: "text-red-500",
};
}
return null;
});
const { mutate: archive, loading } = useMutation(archiveMutation, {
variables: { id: props.id },
});
</script>
<template>
<div class="group/item relative w-full py-4 pl-1 flex flex-col gap-2">
<header class="w-full flex flex-row items-baseline justify-between gap-2 -translate-y-1 group-hover/item:font-medium group-focus/item:font-medium">
<h3 class="text-muted-foreground text-[0.875rem] tracking-wide flex flex-row items-baseline gap-2 uppercase">
<header
class="w-full flex flex-row items-baseline justify-between gap-2 -translate-y-1 group-hover/item:font-medium group-focus/item:font-medium"
>
<h3
class="text-muted-foreground text-[0.875rem] tracking-wide flex flex-row items-baseline gap-2 uppercase"
>
<!-- the `translate` compensates for extra space added by the `svg` element when rendered -->
<component :is="icon.component" v-if="icon" class="size-5 shrink-0 translate-y-1.5" :class="icon.color" />
<component
:is="icon.component"
v-if="icon"
class="size-5 shrink-0 translate-y-1.5"
:class="icon.color"
/>
<span>{{ title }}</span>
</h3>
@@ -46,9 +61,13 @@ const icon = computed<{ component: Component, color: string } | null>(() => {
</div>
</header>
<h4 class="group-hover/item:font-medium group-focus/item:font-medium">{{ subject }}</h4>
<h4 class="group-hover/item:font-medium group-focus/item:font-medium">
{{ subject }}
</h4>
<div class="w-full flex flex-row items-center justify-between gap-2 opacity-75 group-hover/item:opacity-100 group-focus/item:opacity-100">
<div
class="w-full flex flex-row items-center justify-between gap-2 opacity-75 group-hover/item:opacity-100 group-focus/item:opacity-100"
>
<p class="text-secondary-foreground">{{ description }}</p>
</div>
@@ -56,22 +75,27 @@ const icon = computed<{ component: Component, color: string } | null>(() => {
<a v-if="link" :href="link">
<Button type="button" variant="outline" size="xs">
<LinkIcon class="size-3 mr-1 text-muted-foreground/80" />
<span class="text-[0.875rem] text-muted-foreground mt-0.5">View</span>
<span class="text-sm text-muted-foreground mt-0.5">View</span>
</Button>
</a>
<TooltipProvider>
<Tooltip>
<TooltipTrigger as-child>
<Button class="relative z-20 rounded" variant="secondary" size="xs">
<ArchiveBoxIcon class="size-3 text-muted-foreground/80 mr-1" />
<span class="text-[0.875rem] text-muted-foreground mt-0.5">Archive</span>
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Archive</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<Tooltip>
<TooltipTrigger as-child>
<Button
:disabled="loading"
class="relative z-20 rounded"
size="xs"
@click="archive"
>
<ArchiveBoxIcon class="size-3 text-muted-foreground/80 mr-1" />
<span class="text-sm text-muted-foreground mt-0.5">Archive</span>
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Archive</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</div>
</template>
</template>

View File

@@ -10,6 +10,7 @@ import {
} from "@/components/shadcn/sheet";
import {
archiveAllNotifications,
getNotifications,
NOTIFICATION_FRAGMENT,
} from "./graphql/notification.query";
@@ -17,7 +18,7 @@ import {
NotificationType,
} from "~/composables/gql/graphql";
import { useFragment } from "~/composables/gql/fragment-masking";
import { useQuery } from "@vue/apollo-composable";
import { useQuery, useMutation } from "@vue/apollo-composable";
// const notifications = ref<NotificationFragmentFragment[]>([]);
// watch(notifications, (newVal) => {
@@ -40,6 +41,8 @@ const notifications = computed(() => {
return useFragment(NOTIFICATION_FRAGMENT, result.value?.notifications.list);
});
const { mutate:archiveAll, loading: archivingAll } = useMutation(archiveAllNotifications);
watch(error, (newVal) => {
console.log("[sidebar error]", newVal);
});
@@ -82,9 +85,11 @@ const { teleportTarget, determineTeleportTarget } = useTeleport();
</TabsList>
<Button
:disabled="archivingAll"
variant="link"
size="sm"
class="text-muted-foreground text-base p-0"
@click="archiveAll"
>
{{ `Archive All` }}
</Button>

View File

@@ -24,3 +24,37 @@ export const getNotifications = graphql(/* GraphQL */ `
}
`);
export const archiveNotification = graphql(/* GraphQL */ `
mutation ArchiveNotification($id: String!) {
archiveNotification(id: $id) {
archive {
info
warning
alert
total
}
unread {
info
warning
alert
total
}
}
}
`);
export const archiveAllNotifications = graphql(/* GraphQL */ `
mutation ArchiveAllNotifications {
archiveAll {
unread {
total
}
archive {
info
warning
alert
total
}
}
}
`);