You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ActionsDropdown.tsx 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2021 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import * as classNames from 'classnames';
  21. import { LocationDescriptor } from 'history';
  22. import * as React from 'react';
  23. import { Link } from 'react-router';
  24. import { translate } from '../../helpers/l10n';
  25. import DropdownIcon from '../icons/DropdownIcon';
  26. import SettingsIcon from '../icons/SettingsIcon';
  27. import { PopupPlacement } from '../ui/popups';
  28. import { Button } from './buttons';
  29. import { ClipboardBase } from './clipboard';
  30. import Dropdown from './Dropdown';
  31. import Tooltip from './Tooltip';
  32. export interface ActionsDropdownProps {
  33. className?: string;
  34. children: React.ReactNode;
  35. onOpen?: () => void;
  36. overlayPlacement?: PopupPlacement;
  37. small?: boolean;
  38. toggleClassName?: string;
  39. }
  40. export default function ActionsDropdown(props: ActionsDropdownProps) {
  41. const { children, className, overlayPlacement, small, toggleClassName } = props;
  42. return (
  43. <Dropdown
  44. className={className}
  45. onOpen={props.onOpen}
  46. overlay={<ul className="menu">{children}</ul>}
  47. overlayPlacement={overlayPlacement}>
  48. <Button
  49. className={classNames('dropdown-toggle', toggleClassName, {
  50. 'button-small': small,
  51. })}>
  52. <SettingsIcon size={small ? 12 : 14} />
  53. <DropdownIcon className="little-spacer-left" />
  54. </Button>
  55. </Dropdown>
  56. );
  57. }
  58. interface ItemProps {
  59. className?: string;
  60. children: React.ReactNode;
  61. /** used to pass a string to copy to clipboard */
  62. copyValue?: string;
  63. destructive?: boolean;
  64. /** used to pass a name of downloaded file */
  65. download?: string;
  66. id?: string;
  67. onClick?: () => void;
  68. to?: LocationDescriptor;
  69. }
  70. export class ActionsDropdownItem extends React.PureComponent<ItemProps> {
  71. handleClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
  72. event.preventDefault();
  73. event.currentTarget.blur();
  74. if (this.props.onClick) {
  75. this.props.onClick();
  76. }
  77. };
  78. render() {
  79. const className = classNames(this.props.className, { 'text-danger': this.props.destructive });
  80. if (this.props.download && typeof this.props.to === 'string') {
  81. return (
  82. <li>
  83. <a
  84. className={className}
  85. download={this.props.download}
  86. href={this.props.to}
  87. id={this.props.id}>
  88. {this.props.children}
  89. </a>
  90. </li>
  91. );
  92. }
  93. if (this.props.to) {
  94. return (
  95. <li>
  96. <Link className={className} id={this.props.id} to={this.props.to}>
  97. {this.props.children}
  98. </Link>
  99. </li>
  100. );
  101. }
  102. if (this.props.copyValue) {
  103. return (
  104. <ClipboardBase>
  105. {({ setCopyButton, copySuccess }) => (
  106. <Tooltip overlay={translate('copied_action')} visible={copySuccess}>
  107. <li data-clipboard-text={this.props.copyValue} ref={setCopyButton}>
  108. <a className={className} href="#" id={this.props.id} onClick={this.handleClick}>
  109. {this.props.children}
  110. </a>
  111. </li>
  112. </Tooltip>
  113. )}
  114. </ClipboardBase>
  115. );
  116. }
  117. return (
  118. <li>
  119. <a className={className} href="#" id={this.props.id} onClick={this.handleClick}>
  120. {this.props.children}
  121. </a>
  122. </li>
  123. );
  124. }
  125. }
  126. export function ActionsDropdownDivider() {
  127. return <li className="divider" />;
  128. }