|
@@ -8,12 +8,19 @@ import {decodeList, decodeScalar} from 'sentry/utils/queryString';
|
|
|
import useLocationQuery from 'sentry/utils/url/useLocationQuery';
|
|
|
|
|
|
interface Props {
|
|
|
+ listHeadTime: number;
|
|
|
organization: Organization;
|
|
|
+ prefetch: boolean;
|
|
|
}
|
|
|
|
|
|
const PER_PAGE = 25;
|
|
|
+const ONE_DAY_MS = intervalToMilliseconds('1d');
|
|
|
|
|
|
-export default function useFeedbackListQueryKey({organization}: Props): ApiQueryKey {
|
|
|
+export default function useFeedbackListQueryKey({
|
|
|
+ listHeadTime,
|
|
|
+ organization,
|
|
|
+ prefetch,
|
|
|
+}: Props): ApiQueryKey | undefined {
|
|
|
const queryView = useLocationQuery({
|
|
|
fields: {
|
|
|
limit: PER_PAGE,
|
|
@@ -38,38 +45,58 @@ export default function useFeedbackListQueryKey({organization}: Props): ApiQuery
|
|
|
// the user wants to see fresher content (like, after the page has been open
|
|
|
// for a while) they can trigger that specifically.
|
|
|
|
|
|
+ // The issues endpoint cannot handle when statsPeroid has a value of "", so
|
|
|
+ // we remove that from the rest and do not use it to query.
|
|
|
const {statsPeriod, ...rest} = queryView;
|
|
|
- const now = Date.now();
|
|
|
- const statsPeriodMs = intervalToMilliseconds(statsPeriod);
|
|
|
- return statsPeriod
|
|
|
- ? {
|
|
|
- ...rest,
|
|
|
- start: new Date(now - statsPeriodMs).toISOString(),
|
|
|
- end: new Date(now).toISOString(),
|
|
|
- }
|
|
|
- : // The issues endpoint cannot handle when statsPeroid has a value of "", so
|
|
|
- // we remove that from the rest and do not use it to query.
|
|
|
- rest;
|
|
|
- }, [queryView]);
|
|
|
+
|
|
|
+ // Usually we want to fetch starting from `now` and looking back in time.
|
|
|
+ // `prefetch` in this case changes the mode: instead of looking back, we want
|
|
|
+ // to look forward for new data, and fetch it before it's time to render.
|
|
|
+ // Note: The ApiQueryKey that we return isn't actually for a full page of
|
|
|
+ // prefetched data, it's just one row actually.
|
|
|
+ if (prefetch) {
|
|
|
+ if (!statsPeriod) {
|
|
|
+ // We shouldn't prefetch if the query uses an absolute date range
|
|
|
+ return undefined;
|
|
|
+ }
|
|
|
+ // Look 1 day into the future, from the time the page is loaded for new
|
|
|
+ // feedbacks to come in.
|
|
|
+ const intervalMS = ONE_DAY_MS;
|
|
|
+ const start = new Date(listHeadTime).toISOString();
|
|
|
+ const end = new Date(listHeadTime + intervalMS).toISOString();
|
|
|
+ return statsPeriod ? {...rest, limit: 1, start, end} : undefined;
|
|
|
+ }
|
|
|
+
|
|
|
+ const intervalMS = intervalToMilliseconds(statsPeriod);
|
|
|
+ const start = new Date(listHeadTime - intervalMS).toISOString();
|
|
|
+ const end = new Date(listHeadTime).toISOString();
|
|
|
+ return statsPeriod ? {...rest, start, end} : rest;
|
|
|
+ }, [listHeadTime, prefetch, queryView]);
|
|
|
|
|
|
return useMemo(() => {
|
|
|
+ if (!queryViewWithStatsPeriod) {
|
|
|
+ return undefined;
|
|
|
+ }
|
|
|
const {mailbox, ...fixedQueryView} = queryViewWithStatsPeriod;
|
|
|
+
|
|
|
return [
|
|
|
`/organizations/${organization.slug}/issues/`,
|
|
|
{
|
|
|
query: {
|
|
|
...fixedQueryView,
|
|
|
collapse: ['inbox'],
|
|
|
- expand: [
|
|
|
- 'owners', // Gives us assignment
|
|
|
- 'stats', // Gives us `firstSeen`
|
|
|
- 'pluginActions', // Gives us plugin actions available
|
|
|
- 'pluginIssues', // Gives us plugin issues available
|
|
|
- ],
|
|
|
+ expand: prefetch
|
|
|
+ ? []
|
|
|
+ : [
|
|
|
+ 'owners', // Gives us assignment
|
|
|
+ 'stats', // Gives us `firstSeen`
|
|
|
+ 'pluginActions', // Gives us plugin actions available
|
|
|
+ 'pluginIssues', // Gives us plugin issues available
|
|
|
+ ],
|
|
|
shortIdLookup: 0,
|
|
|
query: `issue.category:feedback status:${mailbox} ${fixedQueryView.query}`,
|
|
|
},
|
|
|
},
|
|
|
];
|
|
|
- }, [queryViewWithStatsPeriod, organization.slug]);
|
|
|
+ }, [organization.slug, prefetch, queryViewWithStatsPeriod]);
|
|
|
}
|