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.

DocLink.tsx 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2022 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 React from 'react';
  21. import { Link } from 'react-router';
  22. import withAppStateContext from '../../app/components/app-state/withAppStateContext';
  23. import DetachIcon from '../../components/icons/DetachIcon';
  24. import { isSonarCloud } from '../../helpers/system';
  25. import { AppState } from '../../types/appstate';
  26. interface OwnProps {
  27. appState: AppState;
  28. customProps?: {
  29. [k: string]: any;
  30. };
  31. }
  32. type Props = OwnProps & React.AnchorHTMLAttributes<HTMLAnchorElement>;
  33. const SONARCLOUD_LINK = '/#sonarcloud#/';
  34. const SONARQUBE_LINK = '/#sonarqube#/';
  35. const SONARQUBE_ADMIN_LINK = '/#sonarqube-admin#/';
  36. export class DocLink extends React.PureComponent<Props> {
  37. handleClickOnAnchor = (event: React.MouseEvent<HTMLAnchorElement>) => {
  38. const { customProps, href = '#' } = this.props;
  39. if (customProps && customProps.onAnchorClick) {
  40. customProps.onAnchorClick(href, event);
  41. }
  42. };
  43. render() {
  44. const { appState, children, href, customProps, ...other } = this.props;
  45. if (href && href.startsWith('#')) {
  46. return (
  47. <a href="#" onClick={this.handleClickOnAnchor}>
  48. {children}
  49. </a>
  50. );
  51. }
  52. if (href && href.startsWith('/')) {
  53. if (href.startsWith(SONARCLOUD_LINK)) {
  54. return <SonarCloudLink url={href}>{children}</SonarCloudLink>;
  55. } else if (href.startsWith(SONARQUBE_LINK)) {
  56. return <SonarQubeLink url={href}>{children}</SonarQubeLink>;
  57. } else if (href.startsWith(SONARQUBE_ADMIN_LINK)) {
  58. return (
  59. <SonarQubeAdminLink canAdmin={appState.canAdmin} url={href}>
  60. {children}
  61. </SonarQubeAdminLink>
  62. );
  63. }
  64. const url = '/documentation' + href;
  65. return (
  66. <Link to={url} {...other}>
  67. {children}
  68. </Link>
  69. );
  70. }
  71. return (
  72. <>
  73. <a href={href} rel="noopener noreferrer" target="_blank" {...other}>
  74. {children}
  75. </a>
  76. <DetachIcon
  77. className="text-muted little-spacer-left little-spacer-right text-baseline"
  78. size={12}
  79. />
  80. </>
  81. );
  82. }
  83. }
  84. export default withAppStateContext(DocLink);
  85. interface SonarCloudLinkProps {
  86. children: React.ReactNode;
  87. url: string;
  88. }
  89. function SonarCloudLink({ children, url }: SonarCloudLinkProps) {
  90. if (!isSonarCloud()) {
  91. return <>{children}</>;
  92. }
  93. const to = `/${url.substr(SONARCLOUD_LINK.length)}`;
  94. return <Link to={to}>{children}</Link>;
  95. }
  96. interface SonarQubeLinkProps {
  97. children: React.ReactNode;
  98. url: string;
  99. }
  100. function SonarQubeLink({ children, url }: SonarQubeLinkProps) {
  101. if (isSonarCloud()) {
  102. return <>{children}</>;
  103. }
  104. const to = `/${url.substr(SONARQUBE_LINK.length)}`;
  105. return (
  106. <Link target="_blank" to={to}>
  107. {children}
  108. </Link>
  109. );
  110. }
  111. interface SonarQubeAdminLinkProps {
  112. canAdmin?: boolean;
  113. children: React.ReactNode;
  114. url: string;
  115. }
  116. function SonarQubeAdminLink({ canAdmin, children, url }: SonarQubeAdminLinkProps) {
  117. if (isSonarCloud() || !canAdmin) {
  118. return <>{children}</>;
  119. }
  120. const to = `/${url.substr(SONARQUBE_ADMIN_LINK.length)}`;
  121. return (
  122. <Link target="_blank" to={to}>
  123. {children}
  124. </Link>
  125. );
  126. }