sdkDocumentation.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import {useEffect, useState} from 'react';
  2. import LoadingError from 'sentry/components/loadingError';
  3. import LoadingIndicator from 'sentry/components/loadingIndicator';
  4. import {OnboardingLayout} from 'sentry/components/onboarding/gettingStartedDoc/onboardingLayout';
  5. import {ConfigType, Docs} from 'sentry/components/onboarding/gettingStartedDoc/types';
  6. import {useSourcePackageRegistries} from 'sentry/components/onboarding/gettingStartedDoc/useSourcePackageRegistries';
  7. import {ProductSolution} from 'sentry/components/onboarding/productSelection';
  8. import type {
  9. Organization,
  10. PlatformIntegration,
  11. PlatformKey,
  12. Project,
  13. ProjectKey,
  14. } from 'sentry/types';
  15. import {useApiQuery} from 'sentry/utils/queryClient';
  16. type SdkDocumentationProps = {
  17. activeProductSelection: ProductSolution[];
  18. organization: Organization;
  19. platform: PlatformIntegration;
  20. projectId: Project['id'];
  21. projectSlug: Project['slug'];
  22. configType?: ConfigType;
  23. newOrg?: boolean;
  24. };
  25. export type ModuleProps = {
  26. dsn: string;
  27. projectSlug: Project['slug'];
  28. activeProductSelection?: ProductSolution[];
  29. hideHeader?: boolean;
  30. newOrg?: boolean;
  31. organization?: Organization;
  32. platformKey?: PlatformKey;
  33. projectId?: Project['id'];
  34. sourcePackageRegistries?: ReturnType<typeof useSourcePackageRegistries>;
  35. };
  36. function isFunctionalComponent(obj: any): obj is React.ComponentType<ModuleProps> {
  37. // As we only use function components in the docs this should suffice
  38. return typeof obj === 'function';
  39. }
  40. // Loads the component containing the documentation for the specified platform
  41. export function SdkDocumentation({
  42. platform,
  43. projectSlug,
  44. activeProductSelection,
  45. newOrg,
  46. organization,
  47. projectId,
  48. configType,
  49. }: SdkDocumentationProps) {
  50. const sourcePackageRegistries = useSourcePackageRegistries(organization);
  51. const [module, setModule] = useState<null | {
  52. default: Docs<any> | React.ComponentType<ModuleProps>;
  53. }>(null);
  54. // TODO: This will be removed once we no longer rely on sentry-docs to load platform icons
  55. const platformPath =
  56. platform?.type === 'framework'
  57. ? platform.language === 'minidump'
  58. ? `minidump/minidump`
  59. : platform?.id === 'native-qt'
  60. ? `native/native-qt`
  61. : platform?.id === 'android'
  62. ? `android/android`
  63. : platform?.id === 'ionic'
  64. ? `ionic/ionic`
  65. : platform?.id === 'unity'
  66. ? `unity/unity`
  67. : platform?.id === 'unreal'
  68. ? `unreal/unreal`
  69. : platform?.id === 'capacitor'
  70. ? `capacitor/capacitor`
  71. : platform?.id === 'flutter'
  72. ? `flutter/flutter`
  73. : platform?.id === 'dart'
  74. ? `dart/dart`
  75. : platform?.id.replace(`${platform.language}-`, `${platform.language}/`)
  76. : platform?.id === 'python-celery'
  77. ? `python/celery`
  78. : platform?.id === 'python-rq'
  79. ? `python/rq`
  80. : platform?.id === 'python-pymongo'
  81. ? `python/mongo`
  82. : `${platform?.language}/${platform?.id}`;
  83. const {
  84. data: projectKeys,
  85. isError: projectKeysIsError,
  86. isLoading: projectKeysIsLoading,
  87. refetch: refetchProjectKeys,
  88. } = useApiQuery<ProjectKey[]>([`/projects/${organization.slug}/${projectSlug}/keys/`], {
  89. staleTime: Infinity,
  90. });
  91. useEffect(() => {
  92. async function getGettingStartedDoc() {
  93. const mod = await import(
  94. /* webpackExclude: /.spec/ */
  95. `sentry/gettingStartedDocs/${platformPath}`
  96. );
  97. setModule(mod);
  98. }
  99. getGettingStartedDoc();
  100. return () => {
  101. setModule(null);
  102. };
  103. }, [platformPath]);
  104. if (!module || projectKeysIsLoading) {
  105. return <LoadingIndicator />;
  106. }
  107. if (projectKeysIsError) {
  108. return <LoadingError onRetry={refetchProjectKeys} />;
  109. }
  110. const {default: docs} = module;
  111. if (isFunctionalComponent(docs)) {
  112. const GettingStartedDoc = docs;
  113. return (
  114. <GettingStartedDoc
  115. dsn={projectKeys[0].dsn.public}
  116. activeProductSelection={activeProductSelection}
  117. newOrg={newOrg}
  118. platformKey={platform.id}
  119. organization={organization}
  120. projectId={projectId}
  121. projectSlug={projectSlug}
  122. sourcePackageRegistries={sourcePackageRegistries}
  123. />
  124. );
  125. }
  126. return (
  127. <OnboardingLayout
  128. docsConfig={docs}
  129. dsn={projectKeys[0].dsn.public}
  130. activeProductSelection={activeProductSelection}
  131. newOrg={newOrg}
  132. platformKey={platform.id}
  133. projectId={projectId}
  134. projectSlug={projectSlug}
  135. configType={configType}
  136. />
  137. );
  138. }