mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-10-30 14:49:14 +00:00
134 lines
4.2 KiB
TypeScript
134 lines
4.2 KiB
TypeScript
import chunk from 'lodash/chunk';
|
|
|
|
import type {NewQuery, Release} from 'sentry/types';
|
|
import type {TableData} from 'sentry/utils/discover/discoverQuery';
|
|
import EventView from 'sentry/utils/discover/eventView';
|
|
import {DiscoverDatasets} from 'sentry/utils/discover/types';
|
|
import type {ApiQueryKey} from 'sentry/utils/queryClient';
|
|
import {useApiQuery, useQueries} from 'sentry/utils/queryClient';
|
|
import {decodeScalar} from 'sentry/utils/queryString';
|
|
import {escapeFilterValue} from 'sentry/utils/tokenizeSearch';
|
|
import useApi from 'sentry/utils/useApi';
|
|
import {useLocation} from 'sentry/utils/useLocation';
|
|
import useOrganization from 'sentry/utils/useOrganization';
|
|
import usePageFilters from 'sentry/utils/usePageFilters';
|
|
|
|
export function useReleases(searchTerm?: string) {
|
|
const organization = useOrganization();
|
|
const location = useLocation();
|
|
const {selection, isReady} = usePageFilters();
|
|
const {environments, projects} = selection;
|
|
const api = useApi();
|
|
|
|
const releaseResults = useApiQuery<Release[]>(
|
|
[
|
|
`/organizations/${organization.slug}/releases/`,
|
|
{
|
|
query: {
|
|
project: projects,
|
|
per_page: 50,
|
|
environment: environments,
|
|
query: searchTerm,
|
|
sort: 'date',
|
|
},
|
|
},
|
|
],
|
|
{staleTime: Infinity, enabled: isReady}
|
|
);
|
|
|
|
const chunks = releaseResults.data?.length ? chunk(releaseResults.data, 10) : [];
|
|
|
|
const releaseMetrics = useQueries({
|
|
queries: chunks.map(releases => {
|
|
const newQuery: NewQuery = {
|
|
name: '',
|
|
fields: ['release', 'count()'],
|
|
query: `transaction.op:ui.load ${escapeFilterValue(
|
|
`release:[${releases.map(r => `"${r.version}"`).join()}]`
|
|
)}`,
|
|
dataset: DiscoverDatasets.METRICS,
|
|
version: 2,
|
|
projects: selection.projects,
|
|
};
|
|
const eventView = EventView.fromNewQueryWithPageFilters(newQuery, selection);
|
|
const queryKey = [
|
|
`/organizations/${organization.slug}/events/`,
|
|
{
|
|
query: {
|
|
...eventView.getEventsAPIPayload(location),
|
|
referrer: 'api.starfish.mobile-release-selector',
|
|
},
|
|
},
|
|
] as ApiQueryKey;
|
|
return {
|
|
queryKey,
|
|
queryFn: () =>
|
|
api.requestPromise(queryKey[0], {
|
|
method: 'GET',
|
|
query: queryKey[1]?.query,
|
|
}) as Promise<TableData>,
|
|
...{staleTime: Infinity, enabled: isReady && !releaseResults.isLoading},
|
|
};
|
|
}),
|
|
});
|
|
|
|
const metricsFetched = releaseMetrics.every(result => result.isFetched);
|
|
|
|
const metricsStats: {[version: string]: {count: number}} = {};
|
|
if (metricsFetched) {
|
|
releaseMetrics.forEach(c =>
|
|
c.data?.data?.forEach(release => {
|
|
metricsStats[release.release] = {count: release['count()'] as number};
|
|
})
|
|
);
|
|
}
|
|
|
|
const releaseStats: {
|
|
dateCreated: string;
|
|
version: string;
|
|
count?: number;
|
|
}[] =
|
|
releaseResults.data?.length && metricsFetched
|
|
? releaseResults.data.flatMap(release => {
|
|
const releaseVersion = release.version;
|
|
const dateCreated = release.dateCreated;
|
|
if (metricsStats[releaseVersion]?.count) {
|
|
return {
|
|
dateCreated,
|
|
version: releaseVersion,
|
|
count: metricsStats[releaseVersion]?.count,
|
|
};
|
|
}
|
|
return [];
|
|
})
|
|
: [];
|
|
|
|
return {
|
|
...releaseResults,
|
|
data: releaseStats,
|
|
isLoading: !metricsFetched || releaseResults.isLoading,
|
|
};
|
|
}
|
|
|
|
export function useReleaseSelection(): {
|
|
isLoading: boolean;
|
|
primaryRelease: string | undefined;
|
|
secondaryRelease: string | undefined;
|
|
} {
|
|
const location = useLocation();
|
|
|
|
const {data: releases, isLoading} = useReleases();
|
|
|
|
// If there are more than 1 release, the first one should be the older one
|
|
const primaryRelease =
|
|
decodeScalar(location.query.primaryRelease) ??
|
|
(releases && releases.length > 1 ? releases?.[1]?.version : releases?.[0]?.version);
|
|
|
|
// If there are more than 1 release, the second one should be the newest one
|
|
const secondaryRelease =
|
|
decodeScalar(location.query.secondaryRelease) ??
|
|
(releases && releases.length > 1 ? releases?.[0]?.version : undefined);
|
|
|
|
return {primaryRelease, secondaryRelease, isLoading};
|
|
}
|