From c22a472004ef212c4faf57e70ef6f047f4d975b4 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Mon, 9 Dec 2024 08:12:05 -0600 Subject: [PATCH] WIP - Stack Status --- .../src/lib/features/stacks/api.svelte.ts | 72 ++++++++++- .../components/StackStatusDropdownMenu.svelte | 112 +++++++++++------- 2 files changed, 140 insertions(+), 44 deletions(-) diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/stacks/api.svelte.ts b/src/Exceptionless.Web/ClientApp/src/lib/features/stacks/api.svelte.ts index 90717052e..58a6f7eae 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/stacks/api.svelte.ts +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/stacks/api.svelte.ts @@ -2,9 +2,9 @@ import type { WebSocketMessageValue } from '$features/websockets/models'; import { accessToken } from '$features/auth/index.svelte'; import { type ProblemDetails, useFetchClient } from '@exceptionless/fetchclient'; -import { createQuery, QueryClient, useQueryClient } from '@tanstack/svelte-query'; +import { createMutation, createQuery, QueryClient, useQueryClient } from '@tanstack/svelte-query'; -import type { Stack } from './models'; +import type { Stack, StackStatus } from './models'; // export async function invalidateStackQueries(queryClient: QueryClient, message: WebSocketMessageValue<'StackChanged'>) { @@ -25,6 +25,18 @@ export interface GetStackByIdProps { id: string | undefined; } +export interface UpdateStackFixedStatusProps { + id: string | undefined; +} + +export interface UpdateStackSnoozedStatusProps { + id: string | undefined; +} + +export interface UpdateStackStatusProps { + id: string | undefined; +} + export function getStackByIdQuery(props: GetStackByIdProps) { return createQuery(() => ({ enabled: () => !!accessToken.value && !!props.id, @@ -40,6 +52,62 @@ export function getStackByIdQuery(props: GetStackByIdProps) { })); } +export function mutateStackFixedStatus(props: UpdateStackFixedStatusProps) { + const queryClient = useQueryClient(); + return createMutation(() => ({ + enabled: () => !!accessToken.value && !!props.id, + mutationFn: async (version?: string) => { + const client = useFetchClient(); + const response = await client.postJSON(`stacks/${props.id}/mark-fixed`, { version }); + return response.data!; + }, + mutationKey: queryKeys.id(props.id), + onError: () => { + queryClient.invalidateQueries({ queryKey: queryKeys.id(props.id) }); + }, + onSuccess: (data) => { + queryClient.setQueryData(queryKeys.id(props.id), data); + } + })); +} +export function mutateStackSnoozedStatus(props: UpdateStackSnoozedStatusProps) { + const queryClient = useQueryClient(); + return createMutation(() => ({ + enabled: () => !!accessToken.value && !!props.id, + mutationFn: async (snoozeUntilUtc: Date) => { + const client = useFetchClient(); + const response = await client.postJSON(`stacks/${props.id}/mark-snoozed`, { snoozeUntilUtc }); + return response.data!; + }, + mutationKey: queryKeys.id(props.id), + onError: () => { + queryClient.invalidateQueries({ queryKey: queryKeys.id(props.id) }); + }, + onSuccess: (data) => { + queryClient.setQueryData(queryKeys.id(props.id), data); + } + })); +} + +export function mutateStackStatus(props: UpdateStackStatusProps) { + const queryClient = useQueryClient(); + return createMutation(() => ({ + enabled: () => !!accessToken.value && !!props.id, + mutationFn: async (status: StackStatus) => { + const client = useFetchClient(); + const response = await client.postJSON(`stacks/${props.id}/change-status`, { status }); + return response.data!; + }, + mutationKey: queryKeys.id(props.id), + onError: () => { + queryClient.invalidateQueries({ queryKey: queryKeys.id(props.id) }); + }, + onSuccess: (data) => { + queryClient.setQueryData(queryKeys.id(props.id), data); + } + })); +} + export async function prefetchStack(props: GetStackByIdProps) { if (!accessToken.value) { return; diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/stacks/components/StackStatusDropdownMenu.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/stacks/components/StackStatusDropdownMenu.svelte index f8c41cf70..a600b8aee 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/stacks/components/StackStatusDropdownMenu.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/stacks/components/StackStatusDropdownMenu.svelte @@ -3,14 +3,14 @@ import * as DropdownMenu from '$comp/ui/dropdown-menu'; import ChevronDown from '~icons/mdi/chevron-down'; - import { StackStatus } from '../models'; + import { mutateStackFixedStatus, mutateStackSnoozedStatus, mutateStackStatus } from '../api.svelte'; + import { Stack, StackStatus } from '../models'; interface Props { - id: string; - status: StackStatus; + stack: Stack; } - let { id, status }: Props = $props(); + let { stack }: Props = $props(); type Item = { label: string; value: StackStatus }; const items: Item[] = [ @@ -22,59 +22,86 @@ { label: 'Discarded', value: StackStatus.Discarded } ]; - let selected = $derived((items.find((item) => item.value === status) || items[items.length - 1]) as Item); + let selected = $derived((items.find((item) => item.value === stack?.status) || items[items.length - 1]) as Item); - function updateOpen() { - //stackService.changeStatus(id, "open") + const updateStackFixedStatus = mutateStackFixedStatus({ + get id() { + return stack?.id; + } + }); + + const updateStackSnoozedStatus = mutateStackSnoozedStatus({ + get id() { + return stack?.id; + } + }); + + const updateStackStatus = mutateStackStatus({ + get id() { + return stack?.id; + } + }); + + async function updateOpen() { + if (stack.status === StackStatus.Open) { + return; + } + + await updateStackStatus.mutateAsync(StackStatus.Open); } - function updateFixed() { - // if (vm.stack.status === "fixed") { - // return updateOpen(); - // } - // tackDialogService + async function updateFixed() { + if (stack.status === StackStatus.Fixed) { + return; + } + // .markFixed() // .then(function (version) { // return stackService // .markFixed(vm._stackId, version) // .then(onSuccess, onFailure) // .catch(function (e) {}); + const version = undefined; + await updateStackFixedStatus.mutateAsync(version); } - function updateSnooze(timePeriod?: '6hours' | 'day' | 'month' | 'week') { - console.log(timePeriod, id); - // if (!timePeriod && vm.stack.status === "snoozed") { - // return updateOpen(); - // } - // - // var snoozeUntilUtc = moment(); - // switch (timePeriod) { - // case "6hours": - // snoozeUntilUtc = snoozeUntilUtc.add(6, "hours"); - // break; - // case "day": - // snoozeUntilUtc = snoozeUntilUtc.add(1, "days"); - // break; - // case "week": - // snoozeUntilUtc = snoozeUntilUtc.add(1, "weeks"); - // break; - // case "month": - // default: - // snoozeUntilUtc = snoozeUntilUtc.add(1, "months"); - // break; - // } - // - // return stackService - // .markSnoozed(vm._stackId, snoozeUntilUtc.format("YYYY-MM-DDTHH:mm:ssz")) + async function updateSnooze(timePeriod?: '6hours' | 'day' | 'month' | 'week') { + if (stack.status === StackStatus.Snoozed) { + return; + } + + let snoozeUntilUtc = new Date(); + switch (timePeriod) { + case '6hours': + snoozeUntilUtc.setHours(snoozeUntilUtc.getHours() + 6); + break; + case 'day': + snoozeUntilUtc.setDate(snoozeUntilUtc.getDate() + 1); + break; + case 'week': + snoozeUntilUtc.setDate(snoozeUntilUtc.getDate() + 7); + break; + case 'month': + default: + snoozeUntilUtc.setMonth(snoozeUntilUtc.getMonth() + 1); + break; + } + + await updateStackSnoozedStatus.mutateAsync(snoozeUntilUtc); } - function updateIgnore() { - // var ignored = vm.stack.status === "ignored"; - // return stackService - // .changeStatus(vm._stackId, ignored ? "open" : "ignored") + async function updateIgnore() { + if (stack.status === StackStatus.Ignored) { + return; + } + + await updateStackStatus.mutateAsync(StackStatus.Ignored); } - function updateDiscard() { + async function updateDiscard() { + if (stack.status === StackStatus.Discarded) { + return; + } // if (vm.stack.status === "discarded") { // return updateOpen(); // } @@ -86,6 +113,7 @@ // "All future occurrences will be discarded and will not count against your event limit." // ); //changeStatus(vm._stackId, "discarded") + await updateStackStatus.mutateAsync(StackStatus.Discarded); }