datePageFilter.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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 PageFilterPinButton from 'sentry/components/organizations/pageFilters/pageFilterPinButton';
  6. import TimeRangeSelector, {
  7. ChangeData,
  8. } from 'sentry/components/organizations/timeRangeSelector';
  9. import PageTimeRangeSelector from 'sentry/components/pageTimeRangeSelector';
  10. import {IconCalendar} from 'sentry/icons';
  11. import PageFiltersStore from 'sentry/stores/pageFiltersStore';
  12. import {useLegacyStore} from 'sentry/stores/useLegacyStore';
  13. import space from 'sentry/styles/space';
  14. import useOrganization from 'sentry/utils/useOrganization';
  15. type Props = Omit<
  16. React.ComponentProps<typeof TimeRangeSelector>,
  17. 'organization' | 'start' | 'end' | 'utc' | 'relative' | 'onUpdate'
  18. > & {
  19. router: WithRouterProps['router'];
  20. /**
  21. * Reset these URL params when we fire actions (custom routing only)
  22. */
  23. resetParamsOnChange?: string[];
  24. };
  25. function DatePageFilter({router, resetParamsOnChange, ...props}: Props) {
  26. const {selection, desyncedFilters} = useLegacyStore(PageFiltersStore);
  27. const organization = useOrganization();
  28. const {start, end, period, utc} = selection.datetime;
  29. const handleUpdate = (timePeriodUpdate: ChangeData) => {
  30. const {relative, ...startEndUtc} = timePeriodUpdate;
  31. const newTimePeriod = {
  32. period: relative,
  33. ...startEndUtc,
  34. };
  35. updateDateTime(newTimePeriod, router, {save: true, resetParams: resetParamsOnChange});
  36. };
  37. const customDropdownButton = ({getActorProps, isOpen}) => {
  38. let label;
  39. if (start && end) {
  40. const startString = start.toLocaleString('default', {
  41. month: 'short',
  42. day: 'numeric',
  43. });
  44. const endString = end.toLocaleString('default', {month: 'short', day: 'numeric'});
  45. label = `${startString} - ${endString}`;
  46. } else {
  47. label = period?.toUpperCase();
  48. }
  49. return (
  50. <PageFilterDropdownButton
  51. isOpen={isOpen}
  52. icon={<IconCalendar />}
  53. highlighted={desyncedFilters.has('datetime')}
  54. {...getActorProps()}
  55. >
  56. <DropdownTitle>
  57. <TitleContainer>{label}</TitleContainer>
  58. </DropdownTitle>
  59. </PageFilterDropdownButton>
  60. );
  61. };
  62. return (
  63. <DateSelectorContainer>
  64. <StyledPageTimeRangeSelector
  65. organization={organization}
  66. start={start}
  67. end={end}
  68. relative={period}
  69. utc={utc}
  70. onUpdate={handleUpdate}
  71. label={<IconCalendar color="textColor" />}
  72. customDropdownButton={customDropdownButton}
  73. {...props}
  74. />
  75. <PageFilterPinButton size="zero" filter="datetime" />
  76. </DateSelectorContainer>
  77. );
  78. }
  79. const DateSelectorContainer = styled('div')`
  80. display: grid;
  81. gap: ${space(1)};
  82. align-items: center;
  83. grid-auto-flow: column;
  84. grid-auto-columns: max-content;
  85. `;
  86. const StyledPageTimeRangeSelector = styled(PageTimeRangeSelector)`
  87. height: 40px;
  88. font-weight: 600;
  89. background: ${p => p.theme.background};
  90. border: none;
  91. box-shadow: none;
  92. `;
  93. const TitleContainer = styled('div')`
  94. overflow: hidden;
  95. white-space: nowrap;
  96. text-overflow: ellipsis;
  97. flex: 1 1 0%;
  98. `;
  99. const DropdownTitle = styled('div')`
  100. display: flex;
  101. overflow: hidden;
  102. align-items: center;
  103. flex: 1;
  104. `;
  105. export default withRouter(DatePageFilter);