import {useCallback} from 'react'; import {addErrorMessage, addLoadingMessage} from 'sentry/actionCreators/indicator'; import CheckboxField from 'sentry/components/forms/fields/checkboxField'; import SelectField from 'sentry/components/forms/fields/selectField'; import TextField from 'sentry/components/forms/fields/textField'; import Form from 'sentry/components/forms/form'; import type {OnSubmitCallback} from 'sentry/components/forms/types'; import NarrowLayout from 'sentry/components/narrowLayout'; import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; import {t, tct} from 'sentry/locale'; import ConfigStore from 'sentry/stores/configStore'; import type {OrganizationSummary} from 'sentry/types'; import {getRegionChoices, shouldDisplayRegions} from 'sentry/utils/regions'; import useApi from 'sentry/utils/useApi'; import {normalizeUrl} from 'sentry/utils/withDomainRequired'; export const DATA_STORAGE_DOCS_LINK = 'https://docs.sentry.io/product/accounts/choose-your-data-center'; function removeDataStorageLocationFromFormData( formData: Record ): Record { const shallowFormDataClone = {...formData}; delete shallowFormDataClone.dataStorageLocation; return shallowFormDataClone; } function OrganizationCreate() { const termsUrl = ConfigStore.get('termsUrl'); const privacyUrl = ConfigStore.get('privacyUrl'); const isSelfHosted = ConfigStore.get('isSelfHosted'); const relocationUrl = normalizeUrl(`/relocation/`); const regionChoices = getRegionChoices(); const client = useApi(); // This is a trimmed down version of the logic in ApiForm. It validates the // form data prior to submitting the request, and overrides the request host // with the selected region's URL if one is provided. const submitOrganizationCreate: OnSubmitCallback = useCallback( (data, onSubmitSuccess, onSubmitError, _event, formModel) => { if (!formModel.validateForm()) { return; } const regionUrl = data.dataStorageLocation; addLoadingMessage(t('Creating Organization\u2026')); formModel.setFormSaving(); client.request('/organizations/', { method: 'POST', data: removeDataStorageLocationFromFormData(data), host: regionUrl, success: onSubmitSuccess, error: onSubmitError, }); }, [client] ); return (

{t('Create a New Organization')}

{t( "Organizations represent the top level in your hierarchy. You'll be able to bundle a collection of teams within an organization as well as give organization-wide permissions to users." )}

{ const hasCustomerDomain = createdOrg?.features.includes('customer-domains'); let nextUrl = normalizeUrl( `/organizations/${createdOrg.slug}/projects/new/`, {forceCustomerDomain: hasCustomerDomain} ); if (hasCustomerDomain) { nextUrl = `${createdOrg.links.organizationUrl}${nextUrl}`; } // redirect to project creation *(BYPASS REACT ROUTER AND FORCE PAGE REFRESH TO GRAB CSRF TOKEN)* // browserHistory.pushState(null, `/organizations/${data.slug}/projects/new/`); window.location.assign(nextUrl); }} onSubmitError={error => { addErrorMessage( error.responseJSON?.detail ?? t('Unable to create organization.') ); }} requireChanges > {shouldDisplayRegions() && ( } )} choices={regionChoices} inline={false} stacked required /> )} {termsUrl && privacyUrl && ( , privacyLink: , } )} inline={false} stacked required /> )} {!isSelfHosted && ConfigStore.get('features').has('relocation:enabled') && ( )}
); } export default OrganizationCreate;