mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-10-30 14:49:14 +00:00
115 lines
3.1 KiB
TypeScript
115 lines
3.1 KiB
TypeScript
import {useCallback, useEffect, useMemo, useState} from 'react';
|
|
import * as Sentry from '@sentry/react';
|
|
import type {Location} from 'history';
|
|
|
|
import type {Organization} from 'sentry/types';
|
|
import EventView from 'sentry/utils/discover/eventView';
|
|
import {doDiscoverQuery} from 'sentry/utils/discover/genericDiscoverQuery';
|
|
import {decodeScalar} from 'sentry/utils/queryString';
|
|
import {DEFAULT_SORT} from 'sentry/utils/replays/fetchReplayList';
|
|
import useApi from 'sentry/utils/useApi';
|
|
import type {ReplayListLocationQuery} from 'sentry/views/replays/types';
|
|
import {REPLAY_LIST_FIELDS} from 'sentry/views/replays/types';
|
|
|
|
type Options = {
|
|
location: Location;
|
|
organization: Organization;
|
|
replayIdsEventView: EventView;
|
|
};
|
|
|
|
export type EventSpanData = {
|
|
'count()': number;
|
|
replayId: string;
|
|
'span_ops_breakdown.relative': string;
|
|
'spans.browser': null | number;
|
|
'spans.db': null | number;
|
|
'spans.http': null | number;
|
|
'spans.resource': null | number;
|
|
'spans.ui': null | number;
|
|
timestamp: string;
|
|
trace: string;
|
|
'transaction.duration': number;
|
|
};
|
|
|
|
type Return = {
|
|
data: null | {
|
|
events: EventSpanData[];
|
|
replayRecordsEventView: EventView;
|
|
};
|
|
fetchError: any;
|
|
isFetching: boolean;
|
|
pageLinks: null | string;
|
|
};
|
|
|
|
function useReplaysFromTransaction({
|
|
location,
|
|
organization,
|
|
replayIdsEventView,
|
|
}: Options): Return {
|
|
const api = useApi();
|
|
|
|
const [response, setResponse] = useState<{
|
|
events: EventSpanData[];
|
|
pageLinks: null | string;
|
|
replayIds: undefined | string[];
|
|
}>({events: [], pageLinks: null, replayIds: undefined});
|
|
|
|
const [fetchError, setFetchError] = useState<any>();
|
|
|
|
const {cursor} = location.query;
|
|
const fetchReplayIds = useCallback(async () => {
|
|
try {
|
|
const [{data}, _textStatus, resp] = await doDiscoverQuery<{data: EventSpanData[]}>(
|
|
api,
|
|
`/organizations/${organization.slug}/events/`,
|
|
replayIdsEventView.getEventsAPIPayload({
|
|
query: {cursor},
|
|
} as Location<ReplayListLocationQuery>)
|
|
);
|
|
|
|
setResponse({
|
|
pageLinks: resp?.getResponseHeader('Link') ?? '',
|
|
replayIds: data.map(record => String(record.replayId)),
|
|
events: data || [],
|
|
});
|
|
} catch (err) {
|
|
Sentry.captureException(err);
|
|
setFetchError(err);
|
|
}
|
|
}, [api, cursor, organization.slug, replayIdsEventView]);
|
|
|
|
const replayRecordsEventView = useMemo(() => {
|
|
if (!response.replayIds) {
|
|
return null;
|
|
}
|
|
|
|
return EventView.fromSavedQuery({
|
|
id: '',
|
|
name: '',
|
|
version: 2,
|
|
fields: REPLAY_LIST_FIELDS,
|
|
projects: [],
|
|
query: `id:[${String(response.replayIds)}]`,
|
|
orderby: decodeScalar(location.query.sort, DEFAULT_SORT),
|
|
});
|
|
}, [location.query.sort, response.replayIds]);
|
|
|
|
useEffect(() => {
|
|
fetchReplayIds();
|
|
}, [fetchReplayIds]);
|
|
|
|
return {
|
|
data: replayRecordsEventView
|
|
? {
|
|
events: response.events,
|
|
replayRecordsEventView,
|
|
}
|
|
: null,
|
|
fetchError,
|
|
isFetching: !fetchError && !response.replayIds,
|
|
pageLinks: response.pageLinks,
|
|
};
|
|
}
|
|
|
|
export default useReplaysFromTransaction;
|