useFeedbackListQueryKey.tsx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import {useMemo} from 'react';
  2. import decodeMailbox from 'sentry/components/feedback/decodeMailbox';
  3. import type {Organization} from 'sentry/types';
  4. import {intervalToMilliseconds} from 'sentry/utils/dates';
  5. import type {ApiQueryKey} from 'sentry/utils/queryClient';
  6. import {decodeList, decodeScalar} from 'sentry/utils/queryString';
  7. import useLocationQuery from 'sentry/utils/url/useLocationQuery';
  8. interface Props {
  9. organization: Organization;
  10. }
  11. const PER_PAGE = 5;
  12. export default function useFeedbackListQueryKey({organization}: Props): ApiQueryKey {
  13. const queryView = useLocationQuery({
  14. fields: {
  15. limit: PER_PAGE,
  16. queryReferrer: 'feedback_list_page',
  17. end: decodeScalar,
  18. environment: decodeList,
  19. field: decodeList,
  20. project: decodeList,
  21. query: decodeScalar,
  22. start: decodeScalar,
  23. statsPeriod: decodeScalar,
  24. utc: decodeScalar,
  25. mailbox: decodeMailbox,
  26. },
  27. });
  28. const fixedQueryView = useMemo(() => {
  29. // We don't want to use `statsPeriod` directly, because that will mean the
  30. // start time of our infinite list will change, shifting the index/page
  31. // where items appear if we invalidate the cache and refetch specific pages.
  32. // So we'll convert statsPeriod into start/end time here, and use that. When
  33. // the user wants to see fresher content (like, after the page has been open
  34. // for a while) they can trigger that specifically.
  35. const {statsPeriod, ...rest} = queryView;
  36. const now = Date.now();
  37. const statsPeriodMs = intervalToMilliseconds(statsPeriod);
  38. return statsPeriod
  39. ? {
  40. ...rest,
  41. start: new Date(now - statsPeriodMs).toISOString(),
  42. end: new Date(now).toISOString(),
  43. }
  44. : // The issues endpoint cannot handle when statsPeroid has a value of "", so
  45. // we remove that from the rest and do not use it to query.
  46. rest;
  47. }, [queryView]);
  48. return [
  49. `/organizations/${organization.slug}/issues/`,
  50. {
  51. query: {
  52. ...fixedQueryView,
  53. collapse: ['inbox'],
  54. expand: [
  55. 'owners', // Gives us assignment
  56. 'stats', // Gives us `firstSeen`
  57. ],
  58. shortIdLookup: 0,
  59. query: `issue.category:feedback status:${fixedQueryView.mailbox} ${fixedQueryView.query}`,
  60. },
  61. },
  62. ];
  63. }