|
@@ -1,75 +1,54 @@
|
|
|
-import {useState} from 'react';
|
|
|
+import {useCallback} from 'react';
|
|
|
|
|
|
import {addErrorMessage} from 'sentry/actionCreators/indicator';
|
|
|
-import ApiForm from 'sentry/components/forms/apiForm';
|
|
|
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 {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 {OrganizationSummary} from 'sentry/types';
|
|
|
+import {
|
|
|
+ getRegionChoices,
|
|
|
+ shouldDisplayRegions,
|
|
|
+} from 'sentry/utils/regions';
|
|
|
+import useApi from 'sentry/utils/useApi';
|
|
|
import {normalizeUrl} from 'sentry/utils/withDomainRequired';
|
|
|
|
|
|
-enum RegionDisplayName {
|
|
|
- US = '๐บ๐ธ United States of America (US)',
|
|
|
- DE = '๐ช๐บ European Union (EU)',
|
|
|
-}
|
|
|
-
|
|
|
-function getRegionChoices(): [string, string][] {
|
|
|
- const regions = ConfigStore.get('regions') ?? [];
|
|
|
-
|
|
|
- return regions.map(({name, url}) => {
|
|
|
- const regionName = name.toUpperCase();
|
|
|
- if (RegionDisplayName[regionName]) {
|
|
|
- return [url, RegionDisplayName[regionName]];
|
|
|
- }
|
|
|
-
|
|
|
- return [url, name];
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-function getDefaultRegionChoice(
|
|
|
- regionChoices: [string, string][]
|
|
|
-): [string, string] | undefined {
|
|
|
- if (!shouldDisplayRegions()) {
|
|
|
- return undefined;
|
|
|
- }
|
|
|
-
|
|
|
- const usRegion = regionChoices.find(
|
|
|
- ([_, regionName]) => regionName === RegionDisplayName.US
|
|
|
- );
|
|
|
-
|
|
|
- if (usRegion) {
|
|
|
- return usRegion;
|
|
|
- }
|
|
|
-
|
|
|
- return regionChoices[0];
|
|
|
-}
|
|
|
-
|
|
|
-function shouldDisplayRegions(): boolean {
|
|
|
- const regionCount = (ConfigStore.get('regions') ?? []).length;
|
|
|
- return (
|
|
|
- ConfigStore.get('features').has('organizations:multi-region-selector') &&
|
|
|
- regionCount > 1
|
|
|
- );
|
|
|
-}
|
|
|
-
|
|
|
-function removeRegionFromRequestForm(formData: Record<string, any>) {
|
|
|
- const shallowFormDataCopy = {...formData};
|
|
|
-
|
|
|
- delete shallowFormDataCopy.region;
|
|
|
- return shallowFormDataCopy;
|
|
|
+function removeDataStorageLocationFromFormData(
|
|
|
+ formData: Record<string, any>
|
|
|
+): Record<string, any> {
|
|
|
+ const shallowFormDataClone = {...formData};
|
|
|
+ delete shallowFormDataClone.dataStorageLocation;
|
|
|
+ return shallowFormDataClone;
|
|
|
}
|
|
|
|
|
|
function OrganizationCreate() {
|
|
|
const termsUrl = ConfigStore.get('termsUrl');
|
|
|
const privacyUrl = ConfigStore.get('privacyUrl');
|
|
|
const regionChoices = getRegionChoices();
|
|
|
- const [regionUrl, setRegion] = useState<string | undefined>(
|
|
|
- getDefaultRegionChoice(regionChoices)?.[0]
|
|
|
- );
|
|
|
+ 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;
|
|
|
+
|
|
|
+ client.request("/organizations/", {
|
|
|
+ method:"POST",
|
|
|
+ data: removeDataStorageLocationFromFormData(data),
|
|
|
+ host: regionUrl,
|
|
|
+ success: onSubmitSuccess,
|
|
|
+ error: onSubmitError
|
|
|
+ });
|
|
|
+ }, [client]);
|
|
|
|
|
|
return (
|
|
|
<SentryDocumentTitle title={t('Create Organization')}>
|
|
@@ -81,13 +60,12 @@ function OrganizationCreate() {
|
|
|
)}
|
|
|
</p>
|
|
|
|
|
|
- <ApiForm
|
|
|
+ <Form
|
|
|
initialData={{defaultTeam: true}}
|
|
|
submitLabel={t('Create Organization')}
|
|
|
apiEndpoint="/organizations/"
|
|
|
apiMethod="POST"
|
|
|
- hostOverride={regionUrl}
|
|
|
- onSubmit={removeRegionFromRequestForm}
|
|
|
+ onSubmit={submitOrganizationCreate}
|
|
|
onSubmitSuccess={(createdOrg: OrganizationSummary) => {
|
|
|
const hasCustomerDomain = createdOrg?.features.includes('customer-domains');
|
|
|
let nextUrl = normalizeUrl(
|
|
@@ -118,14 +96,12 @@ function OrganizationCreate() {
|
|
|
stacked
|
|
|
required
|
|
|
/>
|
|
|
- {shouldDisplayRegions() && (
|
|
|
+ {shouldDisplayRegions() && (
|
|
|
<SelectField
|
|
|
- name="region"
|
|
|
- label="Data Storage"
|
|
|
+ name="dataStorageLocation"
|
|
|
+ label="Data Storage Location"
|
|
|
help="Where will this organization reside?"
|
|
|
- defaultValue={getDefaultRegionChoice(regionChoices)?.[0]}
|
|
|
choices={regionChoices}
|
|
|
- onChange={setRegion}
|
|
|
inline={false}
|
|
|
stacked
|
|
|
required
|
|
@@ -146,7 +122,7 @@ function OrganizationCreate() {
|
|
|
required
|
|
|
/>
|
|
|
)}
|
|
|
- </ApiForm>
|
|
|
+ </Form>
|
|
|
</NarrowLayout>
|
|
|
</SentryDocumentTitle>
|
|
|
);
|