Skip to content

Commit

Permalink
feat(ui/variables/rename): add danger zone to rename (#13555)
Browse files Browse the repository at this point in the history
  • Loading branch information
OfTheDelmer authored Apr 22, 2019
1 parent e5657ca commit cf8785d
Show file tree
Hide file tree
Showing 8 changed files with 391 additions and 186 deletions.
12 changes: 11 additions & 1 deletion ui/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,16 @@ import AddMembersOverlay from 'src/members/components/AddMembersOverlay'
import OrgProfilePage from 'src/organizations/containers/OrgProfilePage'
import RenameOrgOverlay from 'src/organizations/components/RenameOrgOverlay'
import UpdateBucketOverlay from 'src/buckets/components/UpdateBucketOverlay'
import RenameBucketOverlay from 'src/buckets/components/RenameBucketOverlay'
import RenameVariableOverlay from 'src/variables/components/RenameVariableOverlay'
import UpdateVariableOverlay from 'src/variables/components/UpdateVariableOverlay'

// Actions
import {disablePresentationMode} from 'src/shared/actions/app'

// Styles
import 'src/style/chronograf.scss'
import '@influxdata/clockface/dist/index.css'
import RenameBucketOverlay from './buckets/components/RenameBucketOverlay'

const rootNode = getRootNode()
const basepath = getBasepath()
Expand Down Expand Up @@ -256,6 +258,14 @@ class Root extends PureComponent {
path="new"
component={CreateVariableOverlay}
/>
<Route
path=":id/rename"
component={RenameVariableOverlay}
/>
<Route
path=":id/edit"
component={UpdateVariableOverlay}
/>
</Route>
<Route path="labels" component={LabelsIndex} />
<Route path="scrapers" component={ScrapersIndex}>
Expand Down
159 changes: 159 additions & 0 deletions ui/src/variables/components/RenameVariableForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// Libraries
import React, {PureComponent, ChangeEvent, FormEvent} from 'react'
import _ from 'lodash'
import {connect} from 'react-redux'
import {withRouter, WithRouterProps} from 'react-router'

// Components
import {Form, Input, Button, Grid, Columns} from '@influxdata/clockface'
import {Overlay} from 'src/clockface'

// Utils
import {validateVariableName} from 'src/variables/utils/validation'
import {extractVariablesList} from 'src/variables/selectors'

// Actions
import {updateVariable} from 'src/variables/actions'

// Types
import {AppState} from 'src/types'
import {IVariable as Variable} from '@influxdata/influx'
import {
ButtonType,
ComponentColor,
ComponentStatus,
} from '@influxdata/clockface'

interface OwnProps {
onClose: () => void
}

interface State {
workingVariable: Variable
isNameValid: boolean
}

interface StateProps {
variables: Variable[]
startVariable: Variable
}

interface DispatchProps {
onUpdateVariable: typeof updateVariable
}

type Props = StateProps & OwnProps & DispatchProps & WithRouterProps

class RenameVariableOverlayForm extends PureComponent<Props, State> {
public state: State = {
workingVariable: this.props.startVariable,
isNameValid: true,
}

public render() {
const {onClose} = this.props
const {workingVariable, isNameValid} = this.state

return (
<Overlay.Container maxWidth={1000}>
<Overlay.Heading title="Rename Variable" onDismiss={onClose} />
<Overlay.Body>
<Form onSubmit={this.handleSubmit}>
<Grid>
<Grid.Row>
<Grid.Column widthXS={Columns.Six}>
<div className="overlay-flux-editor--spacing">
<Form.ValidationElement
label="Name"
value={workingVariable.name}
required={true}
validationFunc={this.handleNameValidation}
>
{status => (
<Input
placeholder="Rename your variable"
name="name"
autoFocus={true}
value={workingVariable.name}
onChange={this.handleChangeInput}
status={status}
/>
)}
</Form.ValidationElement>
</div>
</Grid.Column>
</Grid.Row>
<Grid.Row>
<Grid.Column>
<Form.Footer>
<Button
text="Cancel"
color={ComponentColor.Danger}
onClick={onClose}
/>
<Button
text="Submit"
type={ButtonType.Submit}
color={ComponentColor.Primary}
status={
isNameValid
? ComponentStatus.Default
: ComponentStatus.Disabled
}
/>
</Form.Footer>
</Grid.Column>
</Grid.Row>
</Grid>
</Form>
</Overlay.Body>
</Overlay.Container>
)
}

private handleSubmit = (e: FormEvent): void => {
const {workingVariable} = this.state

e.preventDefault()

this.props.onUpdateVariable(workingVariable.id, workingVariable)
this.props.onClose()
}

private handleNameValidation = (name: string) => {
const {variables} = this.props
const {error} = validateVariableName(name, variables)

this.setState({isNameValid: !error})

return error
}

private handleChangeInput = (e: ChangeEvent<HTMLInputElement>) => {
const name = e.target.value

const workingVariable = {...this.state.workingVariable, name}

this.setState({
workingVariable,
})
}
}

const mstp = (state: AppState, {params: {id}}: Props): StateProps => {
const variables = extractVariablesList(state)
const startVariable = variables.find(v => v.id === id)

return {variables, startVariable}
}

const mdtp: DispatchProps = {
onUpdateVariable: updateVariable,
}

export default withRouter<OwnProps>(
connect<StateProps, DispatchProps, OwnProps>(
mstp,
mdtp
)(RenameVariableOverlayForm)
)
48 changes: 48 additions & 0 deletions ui/src/variables/components/RenameVariableOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Libraries
import React, {PureComponent} from 'react'
import {withRouter, WithRouterProps} from 'react-router'

import _ from 'lodash'

// Components
import DangerConfirmationOverlay from 'src/shared/components/dangerConfirmation/DangerConfirmationOverlay'
import RenameVariableForm from 'src/variables/components/RenameVariableForm'

// Decorators
import {ErrorHandling} from 'src/shared/decorators/errors'

@ErrorHandling
class RenameVariableOverlay extends PureComponent<WithRouterProps> {
public render() {
return (
<DangerConfirmationOverlay
title="Rename Variable"
message={this.message}
effectedItems={this.effectedItems}
onClose={this.handleClose}
confirmButtonText="I understand, let's rename my Variable"
>
<RenameVariableForm onClose={this.handleClose} />
</DangerConfirmationOverlay>
)
}

private get message(): string {
return 'Updating the name of a Variable can have unintended consequences. Anything that references this Variable by name will stop working including:'
}

private get effectedItems(): string[] {
return ['Queries', 'Dashboards', 'Telegraf Configurations', 'Templates']
}

private handleClose = () => {
const {
router,
params: {orgID},
} = this.props

router.push(`/orgs/${orgID}/variables`)
}
}

export default withRouter(RenameVariableOverlay)
Loading

0 comments on commit cf8785d

Please sign in to comment.