Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ protected override void ConfigureQueryParser(ElasticQueryParserConfiguration con
config
.SetDefaultFields([
"id",
Alias.ReferenceId,
"reference_id",
"source",
"message",
"tags",
Expand Down
10 changes: 10 additions & 0 deletions src/Exceptionless.Core/Utility/RandomEventGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public List<PersistentEvent> Generate(string organizationId, string projectId, i
};

PopulateEvent(ev, i < errorLogCount ? "Error" : null);
if (i % 5 == 0)
{
ev.ReferenceId = GenerateReferenceId();
}

events.Add(ev);
}

Expand Down Expand Up @@ -165,6 +170,11 @@ private void PopulateEvent(Event ev, string? logLevel = null)
: LogMessages.Random();
}

private static string GenerateReferenceId()
{
return Guid.NewGuid().ToString("N").Substring(0, 10);
}

private List<Error>? _randomErrors;
private List<SimpleError>? _randomSimpleErrors;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export async function invalidatePersistentEventQueries(queryClient: QueryClient,

export const queryKeys = {
deleteEvent: (ids: string[] | undefined) => [...queryKeys.type, 'delete', ...(ids ?? [])] as const,
eventsByReference: (referenceId: string | undefined, projectId?: string | undefined, params?: GetEventsByReferenceRequest['params']) =>
[...queryKeys.type, 'by-ref', referenceId, projectId, params] as const,
id: (id: string | undefined) => [...queryKeys.type, id] as const,
organizations: (id: string | undefined) => [...queryKeys.type, 'organizations', id] as const,
organizationsCount: (id: string | undefined, params?: GetOrganizationCountRequest['params']) => [...queryKeys.organizations(id), 'count', params] as const,
Expand Down Expand Up @@ -74,6 +76,21 @@ export interface GetEventRequest {
};
}

export interface GetEventsByReferenceRequest {
params?: {
after?: string;
before?: string;
limit?: number;
mode?: 'summary';
offset?: string;
page?: number;
};
route: {
projectId?: string | undefined;
referenceId: string | undefined;
};
}

export type GetEventsMode = 'stack_frequent' | 'stack_new' | 'stack_recent' | 'stack_users' | 'summary' | null;

export interface GetEventsParams {
Expand Down Expand Up @@ -211,6 +228,31 @@ export function getEventQuery(request: GetEventRequest) {
}));
}

export function getEventsByReferenceQuery(request: GetEventsByReferenceRequest) {
return createQuery<EventSummaryModel<SummaryTemplateKeys>[], ProblemDetails>(() => ({
enabled: () => !!accessToken.current && !!request.route.referenceId,
queryFn: async ({ signal }: { signal: AbortSignal }) => {
const client = useFetchClient();
const path = request.route.projectId
? `projects/${request.route.projectId}/events/by-ref/${encodeURIComponent(request.route.referenceId ?? '')}`
: `events/by-ref/${encodeURIComponent(request.route.referenceId ?? '')}`;
const response = await client.getJSON<EventSummaryModel<SummaryTemplateKeys>[]>(path, {
params: {
...(DEFAULT_OFFSET ? { offset: DEFAULT_OFFSET } : {}),
limit: 20,
mode: 'summary',
page: 1,
...request.params
},
signal
});

return response.data!;
},
queryKey: queryKeys.eventsByReference(request.route.referenceId, request.route.projectId, request.params)
}));
}

export function getEventWithNavigationQuery(request: GetEventRequest) {
const queryClient = useQueryClient();
return createQuery<EventWithNavigation, ProblemDetails>(() => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

let { detailsHref, eventId = $bindable(), filterChanged, onClose, onError }: Props = $props();

const resolvedHref = $derived(detailsHref ?? (eventId ? resolve('/(app)/events/[eventId=objectid]', { eventId }) : '#'));
const resolvedHref = $derived(detailsHref ?? (eventId ? resolve('/(app)/event/[eventId=objectid]', { eventId }) : '#'));

function handleError(problem: ProblemDetails) {
if (onError) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
</strong>
{/if}

<A class="inline" href={resolve('/(app)/events/[eventId=objectid]', { eventId: source.id })}>
<A class="inline" href={resolve('/(app)/event/[eventId=objectid]', { eventId: source.id })}>
{source.data.Message}
</A>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
{#if showType}
<strong>Feature:&nbsp;</strong>
{/if}
<A class="inline" href={resolve('/(app)/events/[eventId=objectid]', { eventId: source.id })}>{source.data.Source}</A>
<A class="inline" href={resolve('/(app)/event/[eventId=objectid]', { eventId: source.id })}>{source.data.Source}</A>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,5 @@
</strong>
{/if}
{#if showType || source.data.Source}:&nbsp;{/if}
<A class="inline" href={resolve('/(app)/events/[eventId=objectid]', { eventId: source.id })}>{source.data.Message}</A>
<A class="inline" href={resolve('/(app)/event/[eventId=objectid]', { eventId: source.id })}>{source.data.Message}</A>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
{#if showType}
<strong>404</strong>:&nbsp;
{/if}
<A class="inline" href={resolve('/(app)/events/[eventId=objectid]', { eventId: source.id })}>{source.data.Source}</A>
<A class="inline" href={resolve('/(app)/event/[eventId=objectid]', { eventId: source.id })}>{source.data.Source}</A>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</strong>:&nbsp;
{/if}

<A class="inline" href={resolve('/(app)/events/[eventId=objectid]', { eventId: source.id })}>
<A class="inline" href={resolve('/(app)/event/[eventId=objectid]', { eventId: source.id })}>
{#if source.data.Name || source.data.Identity || source.data.SessionId}
{source.data.Name || source.data.Identity || source.data.SessionId}
{#if source.data.Name && source.data.Identity}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<div class="line-clamp-2">
<strong><abbr title={source.data.TypeFullName}>{source.data.Type}</abbr>: </strong>
<A class="inline" href={resolve('/(app)/events/[eventId=objectid]', { eventId: source.id })}>{source.data.Message}</A>
<A class="inline" href={resolve('/(app)/event/[eventId=objectid]', { eventId: source.id })}>{source.data.Message}</A>
</div>

{#if source.data.Path}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@
{#if showType || source.data.Source}
:&nbsp;
{/if}
<A class="inline" href={resolve('/(app)/events/[eventId=objectid]', { eventId: source.id })}>{source.data.Message}</A>
<A class="inline" href={resolve('/(app)/event/[eventId=objectid]', { eventId: source.id })}>{source.data.Message}</A>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
</strong>
{/if}

<A class="inline" href={`${resolve('/(app)/events')}?filter=stack:${source.id}`}>
<A class="inline" href={`${resolve('/(app)/event')}?filter=stack:${source.id}`}>
{source.title}
</A>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<strong>Feature</strong>:&nbsp;
{/if}

<A class="inline" href={`${resolve('/(app)/events')}?filter=stack:${source.id}`}>
<A class="inline" href={`${resolve('/(app)/event')}?filter=stack:${source.id}`}>
{source.title}
</A>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<strong>Log source:</strong>&nbsp;
{/if}

<A class="inline" href={`${resolve('/(app)/events')}?filter=stack:${source.id}`}>
<A class="inline" href={`${resolve('/(app)/event')}?filter=stack:${source.id}`}>
{#if source.data?.Source}
<abbr title={source.data.Source}>{source.data.SourceShortName}</abbr>
{:else}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
{#if showType}
<strong>404</strong>:&nbsp;
{/if}
<A class="inline" href={`${resolve('/(app)/events')}?filter=stack:${source.id}`}>
<A class="inline" href={`${resolve('/(app)/event')}?filter=stack:${source.id}`}>
{source.title}
</A>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<strong>Session</strong>:&nbsp;
{/if}

<A class="inline" href={`${resolve('/(app)/events')}?filter=stack:${source.id}`}>
<A class="inline" href={`${resolve('/(app)/event')}?filter=stack:${source.id}`}>
{source.title}
</A>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<abbr title={source.data.TypeFullName}>{source.data.Type}</abbr>:
</strong>

<A class="inline" href={`${resolve('/(app)/events')}?filter=stack:${source.id}`}>{source.title}</A>
<A class="inline" href={`${resolve('/(app)/event')}?filter=stack:${source.id}`}>{source.title}</A>
</div>

{#if source.data.Path}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
:&nbsp;
{/if}

<A class="inline" href={`${resolve('/(app)/events')}?filter=stack:${source.id}`}>
<A class="inline" href={`${resolve('/(app)/event')}?filter=stack:${source.id}`}>
{source.title}
</A>
</div>
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts">
import type { IFilter } from '$comp/faceted-filter';

import { resolve } from '$app/paths';
import CopyToClipboardButton from '$comp/copy-to-clipboard-button.svelte';
import { A, H3 } from '$comp/typography';
import { Button } from '$comp/ui/button';
Expand Down Expand Up @@ -86,7 +87,7 @@
<Table.Head class="w-40 font-semibold whitespace-nowrap">Reference</Table.Head>
<Table.Cell class="w-4 pr-0"><EventsFacetedFilter.ReferenceTrigger changed={filterChanged} value={event.reference_id} /></Table.Cell>
{/if}
<Table.Cell>{event.reference_id}</Table.Cell>
<Table.Cell><A href={resolve('/(app)/event/by-ref/[referenceId]', { referenceId: event.reference_id })}>{event.reference_id}</A></Table.Cell>
</Table.Row>
{/if}
{#each references as reference (reference.id)}
Expand All @@ -98,7 +99,7 @@
<Table.Head class="w-40 font-semibold whitespace-nowrap">{reference.name}</Table.Head>
<Table.Cell class="w-4 pr-0"><EventsFacetedFilter.ReferenceTrigger changed={filterChanged} value={reference.id} /></Table.Cell>
{/if}
<Table.Cell>{reference.id}</Table.Cell>
<Table.Cell><A href={resolve('/(app)/event/by-ref/[referenceId]', { referenceId: reference.id })}>{reference.id}</A></Table.Cell>
</Table.Row>
{/each}
{#if level}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

const sessionId = $derived(getSessionId(event));
const isSessionStart = $derived(event.type === 'session');
const eventsPath = $derived(resolve('/(app)/events'));
const eventsPath = $derived(resolve('/(app)/event'));
const sessionEventsHref = $derived.by(() => {
const filter = getSessionFilter();
if (!filter) {
Expand Down Expand Up @@ -64,7 +64,7 @@
});

function getEventHref(eventId: string): string {
return resolve('/(app)/events/[eventId=objectid]', { eventId });
return resolve('/(app)/event/[eventId=objectid]', { eventId });
}

function getSessionFilter(): SessionFilter | undefined {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { BillingPlan, ChangePlanRequest, ChangePlanResult } from '$lib/gene
import type { QueryClient } from '@tanstack/svelte-query';

import { accessToken } from '$features/auth/index.svelte';
import { queryKeys as userQueryKeys } from '$features/users/api.svelte';
import { type FetchClientResponse, type ProblemDetails, useFetchClient } from '@exceptionless/fetchclient';
import { createMutation, createQuery, useQueryClient } from '@tanstack/svelte-query';

Expand Down Expand Up @@ -408,6 +409,7 @@ export function patchOrganization(request: PatchOrganizationRequest) {

export function postOrganization() {
const queryClient = useQueryClient();
const defaultOrganizationsQueryKey = [...queryKeys.list(undefined), { params: {} }] as const;

return createMutation<ViewOrganization, ProblemDetails, NewOrganization>(() => ({
enabled: () => !!accessToken.current,
Expand All @@ -417,9 +419,25 @@ export function postOrganization() {
return response.data!;
},
mutationKey: queryKeys.postOrganization(),
onSuccess: (organization: ViewOrganization) => {
onSuccess: async (organization: ViewOrganization) => {
queryClient.setQueryData(queryKeys.id(organization.id, 'stats'), organization);
queryClient.setQueryData(queryKeys.id(organization.id, undefined), organization);

queryClient.setQueryData<FetchClientResponse<ViewOrganization[]> | undefined>(defaultOrganizationsQueryKey, (response) => {
if (!response || response.data?.some((existingOrganization) => existingOrganization.id === organization.id)) {
return response;
}

return {
...response,
data: [...(response.data ?? []), organization]
};
});

await Promise.all([
queryClient.invalidateQueries({ queryKey: queryKeys.list(undefined) }),
queryClient.invalidateQueries({ queryKey: userQueryKeys.me() })
]);
}
}));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
let { name, userOrganizations, ...restProps }: Props = $props();

async function stopImpersonating(): Promise<void> {
await goto(resolve('/(app)/stacks'));
await goto(resolve('/(app)/stack'));
organization.current = userOrganizations[0]?.id;
}
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,22 @@ export function postProject() {
return response.data!;
},
mutationKey: queryKeys.postProject(),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: queryKeys.type });
onSuccess: async (project: ViewProject) => {
queryClient.setQueryData(queryKeys.id(project.id), project);

const organizationProjectsQueryKey = [...queryKeys.organization(project.organization_id), { params: undefined }] as const;
queryClient.setQueryData<FetchClientResponse<ViewProject[]> | undefined>(organizationProjectsQueryKey, (response) => {
if (!response || response.data?.some((existingProject) => existingProject.id === project.id)) {
return response;
}

return {
...response,
data: [...(response.data ?? []), project]
};
});

await queryClient.invalidateQueries({ queryKey: queryKeys.type });
}
}));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
{/snippet}
</DropdownMenu.Trigger>
<DropdownMenu.Content align="end">
<DropdownMenu.Item onclick={() => goto(resolve('/(app)/stacks'))}>
<DropdownMenu.Item onclick={() => goto(resolve('/(app)/stack'))}>
<Stacks />
Stacks
</DropdownMenu.Item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function savedViewHref(savedView: SavedViewLink): string {
return `${resolve('/(app)/stream')}?saved=${savedView.id}`;
}

const base = savedView.view_type === 'events' ? resolve('/(app)/events') : resolve('/(app)/stacks');
const base = savedView.view_type === 'events' ? resolve('/(app)/event') : resolve('/(app)/stack');
return `${base}/${savedViewResolvedSlug(savedView)}`;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<Button {...props} variant="ghost" size="icon-sm" onclick={clear}>
<Eraser class="text-muted-foreground size-3.5" />
<Button {...props} variant="ghost" size="icon-sm" onclick={clear} aria-label="Clear filter value">
<Eraser class="text-muted-foreground size-4" />
</Button>
{/snippet}
</Tooltip.Trigger>
Expand All @@ -34,11 +34,11 @@
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<Button {...props} variant="ghost" size="icon-sm" onclick={toggleHidden}>
<Button {...props} variant="ghost" size="icon-sm" onclick={toggleHidden} aria-label={hidden ? 'Show filter' : 'Hide filter'}>
{#if hidden}
<Eye class="text-muted-foreground size-3.5" />
<Eye class="text-muted-foreground size-4" />
{:else}
<EyeOff class="text-muted-foreground size-3.5" />
<EyeOff class="text-muted-foreground size-4" />
{/if}
</Button>
{/snippet}
Expand All @@ -49,8 +49,8 @@
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<Button {...props} variant="ghost" size="icon-sm" onclick={remove}>
<Trash2 class="text-muted-foreground size-3.5" />
<Button {...props} variant="ghost" size="icon-sm" onclick={remove} aria-label="Remove filter">
<Trash2 class="text-muted-foreground size-4" />
</Button>
{/snippet}
</Tooltip.Trigger>
Expand Down
Loading