datePageFilter.tsx 3.4 KB

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