repositorySwitcher.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import {createRef, Fragment, PureComponent} from 'react';
  2. import {InjectedRouter} from 'react-router';
  3. import styled from '@emotion/styled';
  4. import {Location} from 'history';
  5. import DropdownControl, {DropdownItem} from 'app/components/dropdownControl';
  6. import {t} from 'app/locale';
  7. import overflowEllipsis from 'app/styles/overflowEllipsis';
  8. import space from 'app/styles/space';
  9. import {Repository} from 'app/types';
  10. type Props = {
  11. repositories: Array<Repository>;
  12. router: InjectedRouter;
  13. location: Location;
  14. activeRepository?: Repository;
  15. };
  16. type State = {
  17. dropdownButtonWidth?: number;
  18. };
  19. class RepositorySwitcher extends PureComponent<Props, State> {
  20. state: State = {};
  21. componentDidMount() {
  22. this.setButtonDropDownWidth();
  23. }
  24. setButtonDropDownWidth() {
  25. const dropdownButtonWidth = this.dropdownButton?.current?.offsetWidth;
  26. if (dropdownButtonWidth) {
  27. this.setState({dropdownButtonWidth});
  28. }
  29. }
  30. dropdownButton = createRef<HTMLButtonElement>();
  31. handleRepoFilterChange = (activeRepo: string) => {
  32. const {router, location} = this.props;
  33. router.push({
  34. ...location,
  35. query: {...location.query, cursor: undefined, activeRepo},
  36. });
  37. };
  38. render() {
  39. const {activeRepository, repositories} = this.props;
  40. const {dropdownButtonWidth} = this.state;
  41. const activeRepo = activeRepository?.name;
  42. return (
  43. <StyledDropdownControl
  44. minMenuWidth={dropdownButtonWidth}
  45. label={
  46. <Fragment>
  47. <FilterText>{`${t('Filter')}:`}</FilterText>
  48. {activeRepo}
  49. </Fragment>
  50. }
  51. buttonProps={{forwardRef: this.dropdownButton}}
  52. >
  53. {repositories
  54. .map(repo => repo.name)
  55. .map(repoName => (
  56. <DropdownItem
  57. key={repoName}
  58. onSelect={this.handleRepoFilterChange}
  59. eventKey={repoName}
  60. isActive={repoName === activeRepo}
  61. >
  62. <RepoLabel>{repoName}</RepoLabel>
  63. </DropdownItem>
  64. ))}
  65. </StyledDropdownControl>
  66. );
  67. }
  68. }
  69. export default RepositorySwitcher;
  70. const StyledDropdownControl = styled(DropdownControl)<{
  71. minMenuWidth: State['dropdownButtonWidth'];
  72. }>`
  73. margin-bottom: ${space(1)};
  74. > *:nth-child(2) {
  75. right: auto;
  76. width: auto;
  77. ${p => p.minMenuWidth && `min-width: calc(${p.minMenuWidth}px + 10px);`}
  78. border-radius: ${p => p.theme.borderRadius};
  79. border-top-left-radius: 0px;
  80. border: 1px solid ${p => p.theme.button.default.border};
  81. top: calc(100% - 1px);
  82. }
  83. `;
  84. const FilterText = styled('em')`
  85. font-style: normal;
  86. color: ${p => p.theme.gray300};
  87. margin-right: ${space(0.5)};
  88. `;
  89. const RepoLabel = styled('div')`
  90. ${overflowEllipsis}
  91. `;