datePageFilter.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import {withRouter, WithRouterProps} from 'react-router';
  2. import styled from '@emotion/styled';
  3. import {updateDateTime} from 'sentry/actionCreators/pageFilters';
  4. import PageFilterDropdownButton from 'sentry/components/organizations/pageFilters/pageFilterDropdownButton';
  5. import PageFilterPinIndicator from 'sentry/components/organizations/pageFilters/pageFilterPinIndicator';
  6. import TimeRangeSelector, {
  7. ChangeData,
  8. } from 'sentry/components/organizations/timeRangeSelector';
  9. import {IconCalendar} from 'sentry/icons';
  10. import PageFiltersStore from 'sentry/stores/pageFiltersStore';
  11. import {useLegacyStore} from 'sentry/stores/useLegacyStore';
  12. import space from 'sentry/styles/space';
  13. import useOrganization from 'sentry/utils/useOrganization';
  14. type Props = Omit<
  15. React.ComponentProps<typeof TimeRangeSelector>,
  16. 'organization' | 'start' | 'end' | 'utc' | 'relative' | 'onUpdate'
  17. > &
  18. WithRouterProps & {
  19. /**
  20. * Reset these URL params when we fire actions (custom routing only)
  21. */
  22. resetParamsOnChange?: string[];
  23. };
  24. function DatePageFilter({router, resetParamsOnChange, ...props}: Props) {
  25. const {selection, desyncedFilters} = useLegacyStore(PageFiltersStore);
  26. const organization = useOrganization();
  27. const {start, end, period, utc} = selection.datetime;
  28. const handleUpdate = (timePeriodUpdate: ChangeData) => {
  29. const {relative, ...startEndUtc} = timePeriodUpdate;
  30. const newTimePeriod = {
  31. period: relative,
  32. ...startEndUtc,
  33. };
  34. updateDateTime(newTimePeriod, router, {save: true, resetParams: resetParamsOnChange});
  35. };
  36. const customDropdownButton = ({getActorProps, isOpen}) => {
  37. let label;
  38. if (start && end) {
  39. const startString = start.toLocaleString('default', {
  40. month: 'short',
  41. day: 'numeric',
  42. });
  43. const endString = end.toLocaleString('default', {month: 'short', day: 'numeric'});
  44. label = `${startString} - ${endString}`;
  45. } else {
  46. label = period?.toUpperCase();
  47. }
  48. return (
  49. <PageFilterDropdownButton
  50. detached
  51. hideBottomBorder={false}
  52. isOpen={isOpen}
  53. highlighted={desyncedFilters.has('datetime')}
  54. data-test-id="page-filter-timerange-selector"
  55. {...getActorProps()}
  56. >
  57. <DropdownTitle>
  58. <PageFilterPinIndicator filter="datetime">
  59. <IconCalendar />
  60. </PageFilterPinIndicator>
  61. <TitleContainer>{label}</TitleContainer>
  62. </DropdownTitle>
  63. </PageFilterDropdownButton>
  64. );
  65. };
  66. return (
  67. <TimeRangeSelector
  68. organization={organization}
  69. start={start}
  70. end={end}
  71. relative={period}
  72. utc={utc}
  73. onUpdate={handleUpdate}
  74. customDropdownButton={customDropdownButton}
  75. showPin
  76. detached
  77. {...props}
  78. />
  79. );
  80. }
  81. const TitleContainer = styled('div')`
  82. overflow: hidden;
  83. white-space: nowrap;
  84. text-overflow: ellipsis;
  85. flex: 1 1 0%;
  86. margin-left: ${space(1)};
  87. text-align: left;
  88. `;
  89. const DropdownTitle = styled('div')`
  90. display: flex;
  91. align-items: center;
  92. flex: 1;
  93. `;
  94. export default withRouter(DatePageFilter);