inlineDocs.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import {Component} from 'react';
  2. import styled from '@emotion/styled';
  3. import * as Sentry from '@sentry/react';
  4. import {loadDocs} from 'sentry/actionCreators/projects';
  5. import {Client} from 'sentry/api';
  6. import ExternalLink from 'sentry/components/links/externalLink';
  7. import LoadingIndicator from 'sentry/components/loadingIndicator';
  8. import {PlatformKey} from 'sentry/data/platformCategories';
  9. import {t, tct} from 'sentry/locale';
  10. import withApi from 'sentry/utils/withApi';
  11. type Props = {
  12. api: Client;
  13. orgSlug: string;
  14. platform: string;
  15. projectSlug: string;
  16. resetCellMeasureCache: () => void;
  17. };
  18. type State = {
  19. html: string | undefined;
  20. link: string | undefined;
  21. loading: boolean;
  22. };
  23. class InlineDocs extends Component<Props, State> {
  24. state: State = {
  25. loading: true,
  26. html: undefined,
  27. link: undefined,
  28. };
  29. componentDidMount() {
  30. this.fetchData();
  31. }
  32. componentDidUpdate(_prevProps: Props, prevState: State) {
  33. if (this.state.loading === false && prevState.loading === true) {
  34. this.props.resetCellMeasureCache();
  35. }
  36. }
  37. fetchData = async () => {
  38. const {platform, api, orgSlug, projectSlug} = this.props;
  39. if (!platform) {
  40. return;
  41. }
  42. this.setState({loading: true});
  43. let tracingPlatform: PlatformKey;
  44. if (platform.startsWith('sentry.python')) {
  45. tracingPlatform = 'python-tracing';
  46. } else if (platform.startsWith('sentry.javascript.node')) {
  47. tracingPlatform = 'node-tracing';
  48. } else if (platform.startsWith('sentry.javascript.react-native')) {
  49. tracingPlatform = 'react-native-tracing';
  50. } else {
  51. this.setState({loading: false});
  52. return;
  53. }
  54. try {
  55. const {html, link} = await loadDocs({
  56. api,
  57. orgSlug,
  58. projectSlug,
  59. platform: tracingPlatform,
  60. });
  61. this.setState({html, link});
  62. } catch (error) {
  63. Sentry.captureException(error);
  64. this.setState({html: undefined, link: undefined});
  65. }
  66. this.setState({loading: false});
  67. };
  68. render() {
  69. const {platform} = this.props;
  70. if (!platform) {
  71. return null;
  72. }
  73. if (this.state.loading) {
  74. return (
  75. <div>
  76. <LoadingIndicator />
  77. </div>
  78. );
  79. }
  80. if (this.state.html) {
  81. return (
  82. <div>
  83. <h4>{t('Requires Manual Instrumentation')}</h4>
  84. <DocumentationWrapper dangerouslySetInnerHTML={{__html: this.state.html}} />
  85. <p>
  86. {tct(
  87. `For in-depth instructions on setting up tracing, view [docLink:our documentation].`,
  88. {
  89. docLink: <a href={this.state.link} />,
  90. }
  91. )}
  92. </p>
  93. </div>
  94. );
  95. }
  96. return (
  97. <div>
  98. <h4>{t('Requires Manual Instrumentation')}</h4>
  99. <p>
  100. {tct(
  101. `To manually instrument certain regions of your code, view [docLink:our documentation].`,
  102. {
  103. docLink: (
  104. <ExternalLink href="https://docs.sentry.io/product/performance/getting-started/" />
  105. ),
  106. }
  107. )}
  108. </p>
  109. </div>
  110. );
  111. }
  112. }
  113. const DocumentationWrapper = styled('div')`
  114. p {
  115. line-height: 1.5;
  116. }
  117. `;
  118. export default withApi(InlineDocs);