Merge pull request #13249 from influxdata/feat/create-org-bucket
feat(ui): Create new bucket when creating new orgpull/13254/head
commit
11578e5221
|
@ -13,9 +13,12 @@ import {defaultTemplates} from 'src/templates/constants/'
|
||||||
import {
|
import {
|
||||||
orgCreateSuccess,
|
orgCreateSuccess,
|
||||||
orgCreateFailed,
|
orgCreateFailed,
|
||||||
|
bucketCreateSuccess,
|
||||||
|
bucketCreateFailed,
|
||||||
} from 'src/shared/copy/v2/notifications'
|
} from 'src/shared/copy/v2/notifications'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
import {Bucket} from '@influxdata/influx'
|
||||||
import {Organization, RemoteDataState} from 'src/types'
|
import {Organization, RemoteDataState} from 'src/types'
|
||||||
import {PublishNotificationAction} from 'src/types/actions/notifications'
|
import {PublishNotificationAction} from 'src/types/actions/notifications'
|
||||||
|
|
||||||
|
@ -135,6 +138,41 @@ export const getOrganizations = () => async (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const createOrgWithBucket = (
|
||||||
|
org: Organization,
|
||||||
|
bucket: Bucket
|
||||||
|
) => async (
|
||||||
|
dispatch: Dispatch<Actions | RouterAction | PublishNotificationAction>
|
||||||
|
) => {
|
||||||
|
let createdOrg: Organization
|
||||||
|
|
||||||
|
try {
|
||||||
|
createdOrg = await client.organizations.create(org)
|
||||||
|
await client.templates.create({
|
||||||
|
...defaultTemplates.systemTemplate(),
|
||||||
|
orgID: createdOrg.id,
|
||||||
|
})
|
||||||
|
dispatch(notify(orgCreateSuccess()))
|
||||||
|
|
||||||
|
dispatch(addOrg(createdOrg))
|
||||||
|
dispatch(push(`/orgs/${createdOrg.id}`))
|
||||||
|
|
||||||
|
await client.buckets.create({
|
||||||
|
...bucket,
|
||||||
|
organizationID: createdOrg.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
dispatch(notify(bucketCreateSuccess()))
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
|
||||||
|
if (!createdOrg) {
|
||||||
|
dispatch(notify(orgCreateFailed()))
|
||||||
|
}
|
||||||
|
dispatch(notify(bucketCreateFailed()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const createOrg = (org: Organization) => async (
|
export const createOrg = (org: Organization) => async (
|
||||||
dispatch: Dispatch<Actions | RouterAction | PublishNotificationAction>
|
dispatch: Dispatch<Actions | RouterAction | PublishNotificationAction>
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {Form, Input, Button} from '@influxdata/clockface'
|
||||||
import {Overlay} from 'src/clockface'
|
import {Overlay} from 'src/clockface'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {Organization} from '@influxdata/influx'
|
import {Organization, Bucket} from '@influxdata/influx'
|
||||||
import {
|
import {
|
||||||
ButtonType,
|
ButtonType,
|
||||||
ComponentColor,
|
ComponentColor,
|
||||||
|
@ -18,20 +18,23 @@ import {
|
||||||
} from '@influxdata/clockface'
|
} from '@influxdata/clockface'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {createOrg} from 'src/organizations/actions/orgs'
|
import {createOrgWithBucket} from 'src/organizations/actions/orgs'
|
||||||
|
|
||||||
interface OwnProps {}
|
interface OwnProps {}
|
||||||
|
|
||||||
interface DispatchProps {
|
interface DispatchProps {
|
||||||
createOrg: typeof createOrg
|
createOrgWithBucket: typeof createOrgWithBucket
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = OwnProps & DispatchProps & WithRouterProps
|
type Props = OwnProps & DispatchProps & WithRouterProps
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
org: Organization
|
org: Organization
|
||||||
nameInputStatus: ComponentStatus
|
bucket: Bucket
|
||||||
errorMessage: string
|
orgNameInputStatus: ComponentStatus
|
||||||
|
bucketNameInputStatus: ComponentStatus
|
||||||
|
orgErrorMessage: string
|
||||||
|
bucketErrorMessage: string
|
||||||
}
|
}
|
||||||
|
|
||||||
class CreateOrgOverlay extends PureComponent<Props, State> {
|
class CreateOrgOverlay extends PureComponent<Props, State> {
|
||||||
|
@ -39,13 +42,23 @@ class CreateOrgOverlay extends PureComponent<Props, State> {
|
||||||
super(props)
|
super(props)
|
||||||
this.state = {
|
this.state = {
|
||||||
org: {name: ''},
|
org: {name: ''},
|
||||||
nameInputStatus: ComponentStatus.Default,
|
bucket: {name: '', retentionRules: []},
|
||||||
errorMessage: '',
|
orgNameInputStatus: ComponentStatus.Default,
|
||||||
|
bucketNameInputStatus: ComponentStatus.Default,
|
||||||
|
orgErrorMessage: '',
|
||||||
|
bucketErrorMessage: '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {org, nameInputStatus, errorMessage} = this.state
|
const {
|
||||||
|
org,
|
||||||
|
orgNameInputStatus,
|
||||||
|
orgErrorMessage,
|
||||||
|
bucket,
|
||||||
|
bucketNameInputStatus,
|
||||||
|
bucketErrorMessage,
|
||||||
|
} = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Overlay visible={true}>
|
<Overlay visible={true}>
|
||||||
|
@ -56,14 +69,31 @@ class CreateOrgOverlay extends PureComponent<Props, State> {
|
||||||
/>
|
/>
|
||||||
<Form onSubmit={this.handleCreateOrg}>
|
<Form onSubmit={this.handleCreateOrg}>
|
||||||
<Overlay.Body>
|
<Overlay.Body>
|
||||||
<Form.Element label="Name" errorMessage={errorMessage}>
|
<Form.Element
|
||||||
|
label="Organization Name"
|
||||||
|
errorMessage={orgErrorMessage}
|
||||||
|
>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Give your organization a name"
|
placeholder="Give your organization a name"
|
||||||
name="name"
|
name="name"
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
value={org.name}
|
value={org.name}
|
||||||
onChange={this.handleChangeInput}
|
onChange={this.handleChangeOrgInput}
|
||||||
status={nameInputStatus}
|
status={orgNameInputStatus}
|
||||||
|
testID="create-org-name-input"
|
||||||
|
/>
|
||||||
|
</Form.Element>
|
||||||
|
<Form.Element
|
||||||
|
label="Bucket Name"
|
||||||
|
errorMessage={bucketErrorMessage}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
placeholder="Give your bucket a name"
|
||||||
|
name="name"
|
||||||
|
autoFocus={false}
|
||||||
|
value={bucket.name}
|
||||||
|
onChange={this.handleChangeBucketInput}
|
||||||
|
status={bucketNameInputStatus}
|
||||||
testID="create-org-name-input"
|
testID="create-org-name-input"
|
||||||
/>
|
/>
|
||||||
</Form.Element>
|
</Form.Element>
|
||||||
|
@ -85,9 +115,9 @@ class CreateOrgOverlay extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private get submitButtonStatus(): ComponentStatus {
|
private get submitButtonStatus(): ComponentStatus {
|
||||||
const {org} = this.state
|
const {org, bucket} = this.state
|
||||||
|
|
||||||
if (org.name) {
|
if (org.name && bucket.name) {
|
||||||
return ComponentStatus.Default
|
return ComponentStatus.Default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,17 +125,17 @@ class CreateOrgOverlay extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleCreateOrg = async () => {
|
private handleCreateOrg = async () => {
|
||||||
const {org} = this.state
|
const {org, bucket} = this.state
|
||||||
const {createOrg} = this.props
|
const {createOrgWithBucket} = this.props
|
||||||
|
|
||||||
await createOrg(org)
|
await createOrgWithBucket(org, bucket)
|
||||||
}
|
}
|
||||||
|
|
||||||
private closeModal = () => {
|
private closeModal = () => {
|
||||||
this.props.router.goBack()
|
this.props.router.goBack()
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleChangeInput = (e: ChangeEvent<HTMLInputElement>) => {
|
private handleChangeOrgInput = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
const value = e.target.value
|
const value = e.target.value
|
||||||
const key = e.target.name
|
const key = e.target.name
|
||||||
const org = {...this.state.org, [key]: value}
|
const org = {...this.state.org, [key]: value}
|
||||||
|
@ -113,24 +143,44 @@ class CreateOrgOverlay extends PureComponent<Props, State> {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return this.setState({
|
return this.setState({
|
||||||
org,
|
org,
|
||||||
nameInputStatus: ComponentStatus.Error,
|
orgNameInputStatus: ComponentStatus.Error,
|
||||||
errorMessage: this.randomErrorMessage(key),
|
orgErrorMessage: this.randomErrorMessage(key, 'organization'),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
org,
|
org,
|
||||||
nameInputStatus: ComponentStatus.Valid,
|
orgNameInputStatus: ComponentStatus.Valid,
|
||||||
errorMessage: '',
|
orgErrorMessage: '',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private randomErrorMessage = (key: string): string => {
|
private handleChangeBucketInput = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const value = e.target.value
|
||||||
|
const key = e.target.name
|
||||||
|
const bucket = {...this.state.bucket, [key]: value}
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
return this.setState({
|
||||||
|
bucket,
|
||||||
|
bucketNameInputStatus: ComponentStatus.Error,
|
||||||
|
bucketErrorMessage: this.randomErrorMessage(key, 'bucket'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
bucket,
|
||||||
|
bucketNameInputStatus: ComponentStatus.Valid,
|
||||||
|
bucketErrorMessage: '',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private randomErrorMessage = (key: string, resource: string): string => {
|
||||||
const messages = [
|
const messages = [
|
||||||
`Imagine that! An organization without a ${key}`,
|
`Imagine that! ${_.startCase(resource)} without a ${key}`,
|
||||||
`An organization needs a ${key}`,
|
`${_.startCase(resource)} needs a ${key}`,
|
||||||
`You're not getting far without a ${key}`,
|
`You're not getting far without a ${key}`,
|
||||||
`The organization formerly known as...`,
|
`The ${resource} formerly known as...`,
|
||||||
`Pick a ${key}, any ${key}`,
|
`Pick a ${key}, any ${key}`,
|
||||||
`Any ${key} will do`,
|
`Any ${key} will do`,
|
||||||
]
|
]
|
||||||
|
@ -140,7 +190,7 @@ class CreateOrgOverlay extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mdtp = {
|
const mdtp = {
|
||||||
createOrg,
|
createOrgWithBucket,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(
|
export default withRouter(
|
||||||
|
|
Loading…
Reference in New Issue