feat(ui/variables/rename): add danger zone to rename (#13555)
parent
e5657ca62b
commit
cf8785dc76
|
@ -66,6 +66,9 @@ 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'
|
||||
|
@ -73,7 +76,6 @@ 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()
|
||||
|
@ -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}>
|
||||
|
|
|
@ -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)
|
||||
)
|
|
@ -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)
|
|
@ -1,6 +1,8 @@
|
|||
// Libraries
|
||||
import React, {PureComponent, ChangeEvent, FormEvent} from 'react'
|
||||
import React, {PureComponent, FormEvent} from 'react'
|
||||
import _ from 'lodash'
|
||||
import {connect} from 'react-redux'
|
||||
import {withRouter, WithRouterProps} from 'react-router'
|
||||
|
||||
// Components
|
||||
import {
|
||||
|
@ -14,8 +16,11 @@ import {
|
|||
import {Overlay} from 'src/clockface'
|
||||
import VariableArgumentsEditor from 'src/variables/components/VariableArgumentsEditor'
|
||||
|
||||
// Actions
|
||||
import {updateVariable} from 'src/variables/actions'
|
||||
|
||||
// Utils
|
||||
import {validateVariableName} from 'src/variables/utils/validation'
|
||||
import {extractVariablesList} from 'src/variables/selectors'
|
||||
|
||||
// Constants
|
||||
import {variableItemTypes} from 'src/variables/constants'
|
||||
|
@ -27,14 +32,7 @@ import {
|
|||
ComponentColor,
|
||||
ComponentStatus,
|
||||
} from '@influxdata/clockface'
|
||||
import {VariableArguments} from 'src/types'
|
||||
|
||||
interface Props {
|
||||
variable: Variable
|
||||
variables: Variable[]
|
||||
onCloseOverlay: () => void
|
||||
onUpdateVariable: (variable: Variable) => Promise<void>
|
||||
}
|
||||
import {VariableArguments, AppState} from 'src/types'
|
||||
|
||||
interface State {
|
||||
workingVariable: Variable
|
||||
|
@ -42,107 +40,109 @@ interface State {
|
|||
hasValidArgs: boolean
|
||||
}
|
||||
|
||||
export default class UpdateVariableOverlay extends PureComponent<Props, State> {
|
||||
interface StateProps {
|
||||
variables: Variable[]
|
||||
startVariable: Variable
|
||||
}
|
||||
|
||||
interface DispatchProps {
|
||||
onUpdateVariable: typeof updateVariable
|
||||
}
|
||||
|
||||
type Props = StateProps & DispatchProps & WithRouterProps
|
||||
|
||||
class UpdateVariableOverlay extends PureComponent<Props, State> {
|
||||
public state: State = {
|
||||
workingVariable: this.props.variable,
|
||||
workingVariable: this.props.startVariable,
|
||||
isNameValid: true,
|
||||
hasValidArgs: true,
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {onCloseOverlay} = this.props
|
||||
const {workingVariable} = this.state
|
||||
const {workingVariable, hasValidArgs} = this.state
|
||||
|
||||
return (
|
||||
<Overlay.Container maxWidth={1000}>
|
||||
<Overlay.Heading
|
||||
title="Edit Variable"
|
||||
onDismiss={this.props.onCloseOverlay}
|
||||
/>
|
||||
<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 => (
|
||||
<Overlay visible={true}>
|
||||
<Overlay.Container maxWidth={1000}>
|
||||
<Overlay.Heading title="Edit Variable" onDismiss={this.handleClose} />
|
||||
<Overlay.Body>
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<Grid>
|
||||
<Grid.Row>
|
||||
<Grid.Column widthXS={Columns.Six}>
|
||||
<div className="overlay-flux-editor--spacing">
|
||||
<Form.Element
|
||||
label="Name"
|
||||
helpText="To rename your variable use the rename button. Renaming is not allowed here."
|
||||
>
|
||||
<Input
|
||||
placeholder="Give your variable a name"
|
||||
name="name"
|
||||
autoFocus={true}
|
||||
value={workingVariable.name}
|
||||
onChange={this.handleChangeInput}
|
||||
status={status}
|
||||
status={ComponentStatus.Disabled}
|
||||
/>
|
||||
)}
|
||||
</Form.ValidationElement>
|
||||
</div>
|
||||
</Grid.Column>
|
||||
<Grid.Column widthXS={Columns.Six}>
|
||||
<Form.Element label="Type" required={true}>
|
||||
<Dropdown
|
||||
selectedID={workingVariable.arguments.type}
|
||||
onChange={this.handleChangeType}
|
||||
>
|
||||
{variableItemTypes.map(v => (
|
||||
<Dropdown.Item key={v.type} id={v.type} value={v.type}>
|
||||
{v.label}
|
||||
</Dropdown.Item>
|
||||
))}
|
||||
</Dropdown>
|
||||
</Form.Element>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
<VariableArgumentsEditor
|
||||
onChange={this.handleChangeArgs}
|
||||
onSelectMapDefault={this.handleSelectMapDefault}
|
||||
selected={workingVariable.selected}
|
||||
args={workingVariable.arguments}
|
||||
/>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
<Form.Footer>
|
||||
<Button
|
||||
text="Cancel"
|
||||
color={ComponentColor.Danger}
|
||||
onClick={onCloseOverlay}
|
||||
</Form.Element>
|
||||
</div>
|
||||
</Grid.Column>
|
||||
<Grid.Column widthXS={Columns.Six}>
|
||||
<Form.Element label="Type" required={true}>
|
||||
<Dropdown
|
||||
selectedID={workingVariable.arguments.type}
|
||||
onChange={this.handleChangeType}
|
||||
>
|
||||
{variableItemTypes.map(v => (
|
||||
<Dropdown.Item
|
||||
key={v.type}
|
||||
id={v.type}
|
||||
value={v.type}
|
||||
>
|
||||
{v.label}
|
||||
</Dropdown.Item>
|
||||
))}
|
||||
</Dropdown>
|
||||
</Form.Element>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
<VariableArgumentsEditor
|
||||
onChange={this.handleChangeArgs}
|
||||
onSelectMapDefault={this.handleSelectMapDefault}
|
||||
selected={workingVariable.selected}
|
||||
args={workingVariable.arguments}
|
||||
/>
|
||||
<Button
|
||||
text="Submit"
|
||||
type={ButtonType.Submit}
|
||||
color={ComponentColor.Primary}
|
||||
status={
|
||||
this.isFormValid
|
||||
? ComponentStatus.Default
|
||||
: ComponentStatus.Disabled
|
||||
}
|
||||
/>
|
||||
</Form.Footer>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Overlay.Body>
|
||||
</Overlay.Container>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
<Form.Footer>
|
||||
<Button
|
||||
text="Cancel"
|
||||
color={ComponentColor.Danger}
|
||||
onClick={this.handleClose}
|
||||
/>
|
||||
<Button
|
||||
text="Submit"
|
||||
type={ButtonType.Submit}
|
||||
color={ComponentColor.Primary}
|
||||
status={
|
||||
hasValidArgs
|
||||
? ComponentStatus.Default
|
||||
: ComponentStatus.Disabled
|
||||
}
|
||||
/>
|
||||
</Form.Footer>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Overlay.Body>
|
||||
</Overlay.Container>
|
||||
</Overlay>
|
||||
)
|
||||
}
|
||||
|
||||
private get isFormValid(): boolean {
|
||||
const {hasValidArgs, isNameValid} = this.state
|
||||
|
||||
return hasValidArgs && isNameValid
|
||||
}
|
||||
|
||||
private handleChangeType = (selectedType: string) => {
|
||||
const {isNameValid, workingVariable} = this.state
|
||||
const defaults = {hasValidArgs: false, isNameValid}
|
||||
|
@ -221,27 +221,36 @@ export default class UpdateVariableOverlay extends PureComponent<Props, State> {
|
|||
|
||||
private handleSubmit = (e: FormEvent): void => {
|
||||
e.preventDefault()
|
||||
const {workingVariable} = this.state
|
||||
|
||||
this.props.onUpdateVariable(this.state.workingVariable)
|
||||
this.props.onCloseOverlay()
|
||||
this.props.onUpdateVariable(workingVariable.id, workingVariable)
|
||||
this.handleClose()
|
||||
}
|
||||
|
||||
private handleNameValidation = (name: string) => {
|
||||
const {variables} = this.props
|
||||
const {error} = validateVariableName(name, variables)
|
||||
private handleClose = () => {
|
||||
const {
|
||||
router,
|
||||
params: {orgID},
|
||||
} = this.props
|
||||
|
||||
this.setState({isNameValid: !error})
|
||||
|
||||
return error
|
||||
}
|
||||
|
||||
private handleChangeInput = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value
|
||||
const key = e.target.name
|
||||
const workingVariable = {...this.state.workingVariable, [key]: value}
|
||||
|
||||
this.setState({
|
||||
workingVariable,
|
||||
})
|
||||
router.push(`/orgs/${orgID}/variables`)
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
connect<StateProps, DispatchProps>(
|
||||
mstp,
|
||||
mdtp
|
||||
)(UpdateVariableOverlay)
|
||||
)
|
||||
|
|
|
@ -3,9 +3,8 @@ import React, {PureComponent} from 'react'
|
|||
import memoizeOne from 'memoize-one'
|
||||
|
||||
// Components
|
||||
import {IndexList, Overlay} from 'src/clockface'
|
||||
import {IndexList} from 'src/clockface'
|
||||
import VariableRow from 'src/variables/components/VariableRow'
|
||||
import UpdateVariableOverlay from 'src/variables/components/UpdateVariableOverlay'
|
||||
|
||||
// Types
|
||||
import {IVariable as Variable} from '@influxdata/influx'
|
||||
|
@ -52,13 +51,7 @@ export default class VariableList extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const {
|
||||
emptyState,
|
||||
variables,
|
||||
sortKey,
|
||||
sortDirection,
|
||||
onClickColumn,
|
||||
} = this.props
|
||||
const {emptyState, sortKey, sortDirection, onClickColumn} = this.props
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -77,14 +70,6 @@ export default class VariableList extends PureComponent<Props, State> {
|
|||
{this.rows}
|
||||
</IndexList.Body>
|
||||
</IndexList>
|
||||
<Overlay visible={this.isVariableOverlayVisible}>
|
||||
<UpdateVariableOverlay
|
||||
variable={this.variable}
|
||||
variables={variables}
|
||||
onCloseOverlay={this.handleCloseOverlay}
|
||||
onUpdateVariable={this.handleUpdateVariable}
|
||||
/>
|
||||
</Overlay>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -122,26 +107,10 @@ export default class VariableList extends PureComponent<Props, State> {
|
|||
))
|
||||
}
|
||||
|
||||
private get variable(): Variable {
|
||||
return this.props.variables.find(v => v.id === this.state.variableID)
|
||||
}
|
||||
|
||||
private get isVariableOverlayVisible(): boolean {
|
||||
return this.state.variableOverlayState === OverlayState.Open
|
||||
}
|
||||
|
||||
private handleCloseOverlay = () => {
|
||||
this.setState({variableOverlayState: OverlayState.Closed, variableID: null})
|
||||
}
|
||||
|
||||
private handleStartEdit = (variable: Variable) => {
|
||||
this.setState({
|
||||
variableID: variable.id,
|
||||
variableOverlayState: OverlayState.Open,
|
||||
})
|
||||
}
|
||||
|
||||
private handleUpdateVariable = async (variable: Variable): Promise<void> => {
|
||||
this.props.onUpdateVariable(variable)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
import {withRouter, WithRouterProps} from 'react-router'
|
||||
import {withRouter, WithRouterProps, Link} from 'react-router'
|
||||
|
||||
// Components
|
||||
import {IndexList, Alignment, Context, IconFont} from 'src/clockface'
|
||||
|
@ -11,12 +11,12 @@ import {
|
|||
FlexDirection,
|
||||
AlignItems,
|
||||
ComponentSize,
|
||||
Button,
|
||||
} from '@influxdata/clockface'
|
||||
import InlineLabels from 'src/shared/components/inlineLabels/InlineLabels'
|
||||
|
||||
// Types
|
||||
import {IVariable as Variable, ILabel} from '@influxdata/influx'
|
||||
import EditableName from 'src/shared/components/EditableName'
|
||||
import {AppState} from 'src/types'
|
||||
|
||||
// Selectors
|
||||
|
@ -62,18 +62,23 @@ class VariableRow extends PureComponent<Props & WithRouterProps> {
|
|||
alignItems={AlignItems.FlexStart}
|
||||
stretchToFitWidth={true}
|
||||
>
|
||||
<EditableName
|
||||
onUpdate={this.handleUpdateVariableName}
|
||||
name={variable.name}
|
||||
noNameString="NAME THIS VARIABLE"
|
||||
onEditName={this.handleEditVariable}
|
||||
>
|
||||
{variable.name}
|
||||
</EditableName>
|
||||
<div className="editable-name">
|
||||
<Link to={this.editVariablePath}>
|
||||
<span>{variable.name}</span>
|
||||
</Link>
|
||||
</div>
|
||||
{this.labels}
|
||||
</ComponentSpacer>
|
||||
</IndexList.Cell>
|
||||
<IndexList.Cell alignment={Alignment.Left}>Query</IndexList.Cell>
|
||||
<IndexList.Cell revealOnHover={true} alignment={Alignment.Right}>
|
||||
<Button
|
||||
text="Rename"
|
||||
onClick={this.handleRenameVariable}
|
||||
color={ComponentColor.Danger}
|
||||
size={ComponentSize.ExtraSmall}
|
||||
/>
|
||||
</IndexList.Cell>
|
||||
<IndexList.Cell revealOnHover={true} alignment={Alignment.Right}>
|
||||
<Context>
|
||||
<Context.Menu icon={IconFont.CogThick}>
|
||||
|
@ -97,6 +102,15 @@ class VariableRow extends PureComponent<Props & WithRouterProps> {
|
|||
)
|
||||
}
|
||||
|
||||
private get editVariablePath(): string {
|
||||
const {
|
||||
variable,
|
||||
params: {orgID},
|
||||
} = this.props
|
||||
|
||||
return `/orgs/${orgID}/variables/${variable.id}/edit`
|
||||
}
|
||||
|
||||
private get labels(): JSX.Element {
|
||||
const {variable, labels, onFilterChange} = this.props
|
||||
const collectorLabels = viewableLabels(variable.labels)
|
||||
|
@ -140,17 +154,17 @@ class VariableRow extends PureComponent<Props & WithRouterProps> {
|
|||
variable,
|
||||
params: {orgID},
|
||||
} = this.props
|
||||
router.push(`orgs/${orgID}/variables/${variable.id}/export`)
|
||||
router.push(`/orgs/${orgID}/variables/${variable.id}/export`)
|
||||
}
|
||||
|
||||
private handleUpdateVariableName = async (name: string) => {
|
||||
const {onUpdateVariableName, variable} = this.props
|
||||
private handleRenameVariable = async () => {
|
||||
const {
|
||||
router,
|
||||
variable,
|
||||
params: {orgID},
|
||||
} = this.props
|
||||
|
||||
await onUpdateVariableName({id: variable.id, name})
|
||||
}
|
||||
|
||||
private handleEditVariable = (): void => {
|
||||
this.props.onEditVariable(this.props.variable)
|
||||
router.push(`/orgs/${orgID}/variables/${variable.id}/rename`)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,28 +41,5 @@ exports[`VariableList rendering renders 1`] = `
|
|||
/>
|
||||
</IndexListBody>
|
||||
</IndexList>
|
||||
<Overlay
|
||||
visible={false}
|
||||
>
|
||||
<UpdateVariableOverlay
|
||||
onCloseOverlay={[Function]}
|
||||
onUpdateVariable={[Function]}
|
||||
variables={
|
||||
Array [
|
||||
Object {
|
||||
"arguments": Object {
|
||||
"type": "query",
|
||||
"values": Object {
|
||||
"language": "flux",
|
||||
"query": "1 + 1 ",
|
||||
},
|
||||
},
|
||||
"name": "a little variable",
|
||||
"orgID": "0",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</Overlay>
|
||||
</Fragment>
|
||||
`;
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import {Variable} from '@influxdata/influx'
|
||||
import {
|
||||
TIME_RANGE_START,
|
||||
TIME_RANGE_STOP,
|
||||
WINDOW_PERIOD,
|
||||
} from 'src/variables/constants'
|
||||
|
||||
const reservedVarNames = [TIME_RANGE_START, TIME_RANGE_STOP, WINDOW_PERIOD]
|
||||
|
||||
export const validateVariableName = (
|
||||
varName: string,
|
||||
|
@ -8,11 +15,23 @@ export const validateVariableName = (
|
|||
return {error: 'Variable name cannot be empty'}
|
||||
}
|
||||
|
||||
const matchingName = variables.find(
|
||||
v => v.name.toLocaleLowerCase() === varName.toLocaleLowerCase()
|
||||
const lowerName = varName.toLocaleLowerCase()
|
||||
|
||||
const reservedMatch = reservedVarNames.find(
|
||||
r => r.toLocaleLowerCase() === lowerName
|
||||
)
|
||||
|
||||
if (matchingName) {
|
||||
if (!!reservedMatch) {
|
||||
return {
|
||||
error: `Variable name is reserved: ${reservedMatch}`,
|
||||
}
|
||||
}
|
||||
|
||||
const matchingName = variables.find(
|
||||
v => v.name.toLocaleLowerCase() === lowerName
|
||||
)
|
||||
|
||||
if (!!matchingName) {
|
||||
return {
|
||||
error: `Variable name must be unique`,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue