projectToolbar.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import Access from 'sentry/components/acl/access';
  2. import Feature from 'sentry/components/acl/feature';
  3. import Alert from 'sentry/components/alert';
  4. import {CopyToClipboardButton} from 'sentry/components/copyToClipboardButton';
  5. import Form from 'sentry/components/forms/form';
  6. import JsonForm from 'sentry/components/forms/jsonForm';
  7. import type {JsonFormObject} from 'sentry/components/forms/types';
  8. import {NoAccess} from 'sentry/components/noAccess';
  9. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  10. import {t, tct} from 'sentry/locale';
  11. import type {RouteComponentProps} from 'sentry/types/legacyReactRouter';
  12. import type {Organization} from 'sentry/types/organization';
  13. import type {Project} from 'sentry/types/project';
  14. import {decodeScalar} from 'sentry/utils/queryString';
  15. import {useLocation} from 'sentry/utils/useLocation';
  16. import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
  17. import PermissionAlert from 'sentry/views/settings/project/permissionAlert';
  18. type RouteParams = {
  19. projectId: string;
  20. };
  21. type Props = RouteComponentProps<RouteParams, {}> & {
  22. organization: Organization;
  23. project: Project;
  24. };
  25. function ProjectToolbarSettings({organization, project, params: {projectId}}: Props) {
  26. const location = useLocation();
  27. const domain = decodeScalar(location.query.domain);
  28. const formGroups: JsonFormObject[] = [
  29. {
  30. title: 'Settings',
  31. fields: [
  32. {
  33. name: 'sentry:toolbar_allowed_origins',
  34. type: 'textarea',
  35. rows: 3,
  36. autosize: true,
  37. formatMessageValue: false,
  38. // additional data/props that is related to rendering of form field rather than data
  39. label: t('Allowed Origins'),
  40. help: t(
  41. 'Domain URLs where the dev toolbar can be installed and access your data. Wildcards (*) are supported. Please separate multiple entries with a newline.'
  42. ),
  43. getData: data => ({options: data}),
  44. },
  45. ],
  46. },
  47. ];
  48. return (
  49. <SentryDocumentTitle title={t('Toolbar Settings')} projectSlug={project.slug}>
  50. <SettingsPageHeader title={t('Developer Toolbar')} />
  51. <Feature
  52. features="dev-toolbar-ui"
  53. organization={organization}
  54. renderDisabled={NoAccess}
  55. >
  56. <PermissionAlert project={project} />
  57. {domain && (
  58. <Alert type="info" showIcon>
  59. {tct(
  60. 'To enable the Dev Toolbar, copy and paste your domain into the Allowed Origins text box below: [domain] ',
  61. {domain: <strong>{domain}</strong>}
  62. )}
  63. <CopyToClipboardButton borderless iconSize="xs" size="zero" text={domain} />
  64. </Alert>
  65. )}
  66. <Form
  67. apiMethod="PUT"
  68. apiEndpoint={`/projects/${organization.slug}/${projectId}/`}
  69. initialData={project.options}
  70. saveOnBlur
  71. >
  72. <Access access={['project:write']} project={project}>
  73. {({hasAccess}) => (
  74. <JsonForm
  75. disabled={!hasAccess}
  76. features={new Set(organization.features)}
  77. forms={formGroups}
  78. />
  79. )}
  80. </Access>
  81. </Form>
  82. </Feature>
  83. </SentryDocumentTitle>
  84. );
  85. }
  86. export default ProjectToolbarSettings;