step.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import beautify from 'js-beautify';
  4. import {CodeSnippet} from 'sentry/components/codeSnippet';
  5. import {t} from 'sentry/locale';
  6. import {space} from 'sentry/styles/space';
  7. export enum StepType {
  8. INSTALL = 'install',
  9. CONFIGURE = 'configure',
  10. VERIFY = 'verify',
  11. }
  12. export const StepTitle = {
  13. [StepType.INSTALL]: t('Install'),
  14. [StepType.CONFIGURE]: t('Configure SDK'),
  15. [StepType.VERIFY]: t('Verify'),
  16. };
  17. type ConfigurationType = {
  18. /**
  19. * Additional information to be displayed below the code snippet
  20. */
  21. additionalInfo?: React.ReactNode;
  22. /**
  23. * The code snippet to display
  24. */
  25. code?: string;
  26. /**
  27. * Nested configurations provide a convenient way to accommodate diverse layout styles, like the Spring Boot configuration.
  28. */
  29. configurations?: ConfigurationType[];
  30. /**
  31. * A brief description of the configuration
  32. */
  33. description?: React.ReactNode;
  34. /**
  35. * The language of the code to be rendered (python, javascript, etc)
  36. */
  37. language?: string;
  38. };
  39. interface BaseStepProps {
  40. /**
  41. * Additional information to be displayed below the configurations
  42. */
  43. additionalInfo?: React.ReactNode;
  44. configurations?: ConfigurationType[];
  45. /**
  46. * A brief description of the step
  47. */
  48. description?: React.ReactNode;
  49. }
  50. interface StepPropsWithTitle extends BaseStepProps {
  51. title: string;
  52. type?: undefined;
  53. }
  54. interface StepPropsWithoutTitle extends BaseStepProps {
  55. type: StepType;
  56. title?: undefined;
  57. }
  58. export type StepProps = StepPropsWithTitle | StepPropsWithoutTitle;
  59. function getConfiguration({
  60. description,
  61. code,
  62. language,
  63. additionalInfo,
  64. }: ConfigurationType) {
  65. return (
  66. <Configuration>
  67. {description && <Description>{description}</Description>}
  68. {language && code && (
  69. <CodeSnippet dark language={language}>
  70. {language === 'javascript'
  71. ? beautify.js(code, {indent_size: 2, e4x: true})
  72. : beautify.html(code, {indent_size: 2})}
  73. </CodeSnippet>
  74. )}
  75. {additionalInfo && <AdditionalInfo>{additionalInfo}</AdditionalInfo>}
  76. </Configuration>
  77. );
  78. }
  79. export function Step({
  80. title,
  81. type,
  82. configurations,
  83. additionalInfo,
  84. description,
  85. }: StepProps) {
  86. return (
  87. <div>
  88. <h4>{title ?? StepTitle[type]}</h4>
  89. {description && <Description>{description}</Description>}
  90. {!!configurations?.length && (
  91. <Configurations>
  92. {configurations.map((configuration, index) => {
  93. if (configuration.configurations) {
  94. return (
  95. <Fragment key={index}>
  96. {getConfiguration(configuration)}
  97. {configuration.configurations.map(
  98. (nestedConfiguration, nestedConfigurationIndex) => (
  99. <Fragment key={nestedConfigurationIndex}>
  100. {getConfiguration(nestedConfiguration)}
  101. </Fragment>
  102. )
  103. )}
  104. </Fragment>
  105. );
  106. }
  107. return <Fragment key={index}>{getConfiguration(configuration)}</Fragment>;
  108. })}
  109. </Configurations>
  110. )}
  111. {additionalInfo && <GeneralAdditionalInfo>{additionalInfo}</GeneralAdditionalInfo>}
  112. </div>
  113. );
  114. }
  115. const Configuration = styled('div')`
  116. display: flex;
  117. flex-direction: column;
  118. gap: 1rem;
  119. `;
  120. const Configurations = styled(Configuration)`
  121. margin-top: ${space(2)};
  122. `;
  123. const Description = styled(Configuration)``;
  124. const AdditionalInfo = styled(Configuration)``;
  125. const GeneralAdditionalInfo = styled(Configuration)`
  126. margin-top: ${space(2)};
  127. `;