Remove unused SourcePage
parent
c647798c3d
commit
5596254e6a
|
@ -35,7 +35,7 @@ import {
|
|||
TickscriptPage,
|
||||
} from 'src/kapacitor'
|
||||
import {AdminChronografPage, AdminInfluxDBPage} from 'src/admin'
|
||||
import {SourcePage, ManageSources, OnboardingWizard} from 'src/sources'
|
||||
import {ManageSources, OnboardingWizard} from 'src/sources'
|
||||
|
||||
import {CheckServices, FluxConnectionPage} from 'src/flux'
|
||||
import NotFound from 'src/shared/components/NotFound'
|
||||
|
@ -166,8 +166,6 @@ class Root extends PureComponent<{}, State> {
|
|||
/>
|
||||
<Route path="admin-influxdb/:tab" component={AdminInfluxDBPage} />
|
||||
<Route path="manage-sources" component={ManageSources} />
|
||||
<Route path="manage-sources/new" component={SourcePage} />
|
||||
<Route path="manage-sources/:id/edit" component={SourcePage} />
|
||||
<Route path="delorean" component={CheckServices} />
|
||||
</Route>
|
||||
</Route>
|
||||
|
|
|
@ -1,229 +0,0 @@
|
|||
import React, {PureComponent, FocusEvent, MouseEvent, ChangeEvent} from 'react'
|
||||
import classnames from 'classnames'
|
||||
import {connect} from 'react-redux'
|
||||
import _ from 'lodash'
|
||||
|
||||
import {insecureSkipVerifyText} from 'src/shared/copy/tooltipText'
|
||||
|
||||
import {SUPERADMIN_ROLE} from 'src/auth/Authorized'
|
||||
import {Source, Role, Organization} from 'src/types'
|
||||
|
||||
interface Me {
|
||||
role: Role
|
||||
currentOrganization: Organization
|
||||
}
|
||||
|
||||
interface Props {
|
||||
me: Me
|
||||
source: Partial<Source>
|
||||
editMode: boolean
|
||||
isUsingAuth: boolean
|
||||
gotoPurgatory: () => void
|
||||
isInitialSource: boolean
|
||||
onSubmit: (e: MouseEvent<HTMLFormElement>) => void
|
||||
onInputChange: (e: ChangeEvent<HTMLInputElement>) => void
|
||||
onBlurSourceURL: (e: FocusEvent<HTMLInputElement>) => void
|
||||
}
|
||||
|
||||
export class SourceForm extends PureComponent<Props> {
|
||||
public render() {
|
||||
const {
|
||||
source,
|
||||
onSubmit,
|
||||
isUsingAuth,
|
||||
onInputChange,
|
||||
gotoPurgatory,
|
||||
onBlurSourceURL,
|
||||
isInitialSource,
|
||||
} = this.props
|
||||
return (
|
||||
<div className="panel-body">
|
||||
{isUsingAuth && isInitialSource && this.authIndicator}
|
||||
<form onSubmit={onSubmit}>
|
||||
<div className="form-group col-xs-12 col-sm-6">
|
||||
<label htmlFor="connect-string">Connection String</label>
|
||||
<input
|
||||
type="text"
|
||||
name="url"
|
||||
className="form-control"
|
||||
id="connect-string"
|
||||
placeholder="Address of InfluxDB"
|
||||
onChange={onInputChange}
|
||||
value={source.url}
|
||||
onBlur={onBlurSourceURL}
|
||||
required={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group col-xs-12 col-sm-6">
|
||||
<label htmlFor="name">Name</label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
className="form-control"
|
||||
id="name"
|
||||
placeholder="Name this source"
|
||||
onChange={onInputChange}
|
||||
value={source.name}
|
||||
required={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group col-xs-12 col-sm-6">
|
||||
<label htmlFor="username">Username</label>
|
||||
<input
|
||||
type="text"
|
||||
name="username"
|
||||
className="form-control"
|
||||
id="username"
|
||||
onChange={onInputChange}
|
||||
value={source.username}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group col-xs-12 col-sm-6">
|
||||
<label htmlFor="password">Password</label>
|
||||
<input
|
||||
type="password"
|
||||
name="password"
|
||||
className="form-control"
|
||||
id="password"
|
||||
onChange={onInputChange}
|
||||
value={source.password}
|
||||
/>
|
||||
</div>
|
||||
{this.isEnterprise && (
|
||||
<div className="form-group col-xs-12">
|
||||
<label htmlFor="meta-url">Meta Service Connection URL</label>
|
||||
<input
|
||||
type="text"
|
||||
name="metaUrl"
|
||||
className="form-control"
|
||||
id="meta-url"
|
||||
placeholder="http://localhost:8091"
|
||||
onChange={onInputChange}
|
||||
value={source.metaUrl}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="form-group col-xs-12 col-sm-6">
|
||||
<label htmlFor="telegraf">Telegraf Database</label>
|
||||
<input
|
||||
type="text"
|
||||
name="telegraf"
|
||||
className="form-control"
|
||||
id="telegraf"
|
||||
onChange={onInputChange}
|
||||
value={source.telegraf}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group col-xs-12 col-sm-6">
|
||||
<label htmlFor="defaultRP">Default Retention Policy</label>
|
||||
<input
|
||||
type="text"
|
||||
name="defaultRP"
|
||||
className="form-control"
|
||||
id="defaultRP"
|
||||
onChange={onInputChange}
|
||||
value={source.defaultRP}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group col-xs-12">
|
||||
<div className="form-control-static">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="defaultConnectionCheckbox"
|
||||
name="default"
|
||||
checked={source.default}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
<label htmlFor="defaultConnectionCheckbox">
|
||||
Make this the default connection
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{this.isHTTPS && (
|
||||
<div className="form-group col-xs-12">
|
||||
<div className="form-control-static">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="insecureSkipVerifyCheckbox"
|
||||
name="insecureSkipVerify"
|
||||
checked={source.insecureSkipVerify}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
<label htmlFor="insecureSkipVerifyCheckbox">Unsafe SSL</label>
|
||||
</div>
|
||||
<label className="form-helper">{insecureSkipVerifyText}</label>
|
||||
</div>
|
||||
)}
|
||||
<div className="form-group form-group-submit text-center col-xs-12 col-sm-6 col-sm-offset-3">
|
||||
<button className={this.submitClass} type="submit">
|
||||
<span className={this.submitIconClass} />
|
||||
{this.submitText}
|
||||
</button>
|
||||
|
||||
<br />
|
||||
{isUsingAuth && (
|
||||
<button className="btn btn-link btn-sm" onClick={gotoPurgatory}>
|
||||
<span className="icon shuffle" /> Switch Orgs
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private get authIndicator(): JSX.Element {
|
||||
const {me} = this.props
|
||||
return (
|
||||
<div className="text-center">
|
||||
{me.role.name === SUPERADMIN_ROLE ? (
|
||||
<h3>
|
||||
<strong>{me.currentOrganization.name}</strong> has no connections
|
||||
</h3>
|
||||
) : (
|
||||
<h3>
|
||||
<strong>{me.currentOrganization.name}</strong> has no connections
|
||||
available to <em>{me.role}s</em>
|
||||
</h3>
|
||||
)}
|
||||
<h6>Add a Connection below:</h6>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private get submitText(): string {
|
||||
const {editMode} = this.props
|
||||
if (editMode) {
|
||||
return 'Save Changes'
|
||||
}
|
||||
|
||||
return 'Add Connection'
|
||||
}
|
||||
|
||||
private get submitIconClass(): string {
|
||||
const {editMode} = this.props
|
||||
return `icon ${editMode ? 'checkmark' : 'plus'}`
|
||||
}
|
||||
|
||||
private get submitClass(): string {
|
||||
const {editMode} = this.props
|
||||
return classnames('btn btn-block', {
|
||||
'btn-primary': editMode,
|
||||
'btn-success': !editMode,
|
||||
})
|
||||
}
|
||||
|
||||
private get isEnterprise(): boolean {
|
||||
const {source} = this.props
|
||||
return _.get(source, 'type', '').includes('enterprise')
|
||||
}
|
||||
|
||||
private get isHTTPS(): boolean {
|
||||
const {source} = this.props
|
||||
return _.get(source, 'url', '').startsWith('https')
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = ({auth: {isUsingAuth, me}}) => ({isUsingAuth, me})
|
||||
|
||||
export default connect(mapStateToProps)(SourceForm)
|
|
@ -1,267 +0,0 @@
|
|||
import React, {PureComponent, MouseEvent, ChangeEvent} from 'react'
|
||||
import {withRouter, WithRouterProps} from 'react-router'
|
||||
import _ from 'lodash'
|
||||
import {getSource} from 'src/shared/apis'
|
||||
import {createSource, updateSource} from 'src/shared/apis'
|
||||
import {
|
||||
addSource as addSourceAction,
|
||||
updateSource as updateSourceAction,
|
||||
AddSource,
|
||||
UpdateSource,
|
||||
} from 'src/shared/actions/sources'
|
||||
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
||||
import {connect} from 'react-redux'
|
||||
|
||||
import Notifications from 'src/shared/components/Notifications'
|
||||
import SourceForm from 'src/sources/components/SourceForm'
|
||||
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
||||
import PageHeader from 'src/reusable_ui/components/page_layout/PageHeader'
|
||||
import {DEFAULT_SOURCE} from 'src/shared/constants'
|
||||
|
||||
const INITIAL_PATH = '/sources/new'
|
||||
|
||||
import {
|
||||
notifySourceUdpated,
|
||||
notifySourceUdpateFailed,
|
||||
notifySourceCreationFailed,
|
||||
notifyErrorConnectingToSource,
|
||||
notifySourceCreationSucceeded,
|
||||
} from 'src/shared/copy/notifications'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
import * as SourcesModels from 'src/types/sources'
|
||||
import * as NotificationsActions from 'src/types/actions/notifications'
|
||||
|
||||
interface Props extends WithRouterProps {
|
||||
notify: NotificationsActions.PublishNotificationActionCreator
|
||||
addSource: AddSource
|
||||
updateSource: UpdateSource
|
||||
}
|
||||
|
||||
interface State {
|
||||
isCreated: boolean
|
||||
isLoading: boolean
|
||||
source: Partial<SourcesModels.Source>
|
||||
editMode: boolean
|
||||
isInitialSource: boolean
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
class SourcePage extends PureComponent<Props, State> {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
isLoading: true,
|
||||
isCreated: false,
|
||||
source: DEFAULT_SOURCE,
|
||||
editMode: props.params.id !== undefined,
|
||||
isInitialSource: props.router.location.pathname === INITIAL_PATH,
|
||||
}
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const {editMode} = this.state
|
||||
const {params, notify} = this.props
|
||||
|
||||
if (!editMode) {
|
||||
return this.setState({isLoading: false})
|
||||
}
|
||||
|
||||
try {
|
||||
const source = await getSource(params.id)
|
||||
this.setState({
|
||||
source: {...DEFAULT_SOURCE, ...source},
|
||||
isLoading: false,
|
||||
})
|
||||
} catch (error) {
|
||||
notify(notifyErrorConnectingToSource(this.parseError(error)))
|
||||
this.setState({isLoading: false})
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {isLoading, source, editMode, isInitialSource} = this.state
|
||||
|
||||
if (isLoading) {
|
||||
return <div className="page-spinner" />
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`${isInitialSource ? '' : 'page'}`}>
|
||||
<Notifications />
|
||||
<PageHeader titleText={this.pageTitle} />
|
||||
<FancyScrollbar className="page-contents">
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-md-8 col-md-offset-2">
|
||||
<div className="panel">
|
||||
<SourceForm
|
||||
source={source}
|
||||
editMode={editMode}
|
||||
onInputChange={this.handleInputChange}
|
||||
onSubmit={this.handleSubmit}
|
||||
onBlurSourceURL={this.handleBlurSourceURL}
|
||||
isInitialSource={isInitialSource}
|
||||
gotoPurgatory={this.gotoPurgatory}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FancyScrollbar>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private handleSubmit = (e: MouseEvent<HTMLFormElement>): void => {
|
||||
e.preventDefault()
|
||||
const {isCreated, editMode} = this.state
|
||||
const isNewSource = !editMode
|
||||
if (!isCreated && isNewSource) {
|
||||
return this.setState(this.normalizeSource, this.createSource)
|
||||
}
|
||||
this.setState(this.normalizeSource, this.updateSource)
|
||||
}
|
||||
|
||||
private gotoPurgatory = (): void => {
|
||||
const {router} = this.props
|
||||
router.push('/purgatory')
|
||||
}
|
||||
|
||||
private normalizeSource({source}) {
|
||||
const url = source.url.trim()
|
||||
if (source.url.startsWith('http')) {
|
||||
return {source: {...source, url}}
|
||||
}
|
||||
return {source: {...source, url: `http://${url}`}}
|
||||
}
|
||||
|
||||
private createSourceOnBlur = async () => {
|
||||
const {source} = this.state
|
||||
// if there is a type on source it has already been created
|
||||
if (source.type) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const sourceFromServer = await createSource(source)
|
||||
this.props.addSource(sourceFromServer)
|
||||
this.setState({
|
||||
source: {...DEFAULT_SOURCE, ...sourceFromServer},
|
||||
isCreated: true,
|
||||
})
|
||||
} catch (err) {
|
||||
// dont want to flash this until they submit
|
||||
const error = this.parseError(err)
|
||||
console.error('Error creating InfluxDB connection: ', error)
|
||||
}
|
||||
}
|
||||
|
||||
private createSource = async () => {
|
||||
const {source} = this.state
|
||||
const {notify} = this.props
|
||||
try {
|
||||
const sourceFromServer = await createSource(source)
|
||||
this.props.addSource(sourceFromServer)
|
||||
this.redirect(sourceFromServer)
|
||||
notify(notifySourceCreationSucceeded(source.name))
|
||||
} catch (err) {
|
||||
// dont want to flash this until they submit
|
||||
notify(notifySourceCreationFailed(source.name, this.parseError(err)))
|
||||
}
|
||||
}
|
||||
|
||||
private updateSource = async () => {
|
||||
const {source} = this.state
|
||||
const {notify} = this.props
|
||||
try {
|
||||
const sourceFromServer = await updateSource(source)
|
||||
this.props.updateSource(sourceFromServer)
|
||||
this.redirect(sourceFromServer)
|
||||
notify(notifySourceUdpated(source.name))
|
||||
} catch (error) {
|
||||
notify(notifySourceUdpateFailed(source.name, this.parseError(error)))
|
||||
}
|
||||
}
|
||||
|
||||
private redirect = source => {
|
||||
const {isInitialSource} = this.state
|
||||
const {params, router} = this.props
|
||||
|
||||
if (isInitialSource) {
|
||||
return this.redirectToApp(source)
|
||||
}
|
||||
|
||||
router.push(`/sources/${params.sourceID}/manage-sources`)
|
||||
}
|
||||
|
||||
private parseError = (error): string => {
|
||||
return _.get(error, ['data', 'message'], error)
|
||||
}
|
||||
|
||||
private redirectToApp = source => {
|
||||
const {location, router} = this.props
|
||||
const {redirectPath} = location.query
|
||||
|
||||
if (!redirectPath) {
|
||||
return router.push(`/sources/${source.id}/hosts`)
|
||||
}
|
||||
|
||||
const fixedPath = redirectPath.replace(
|
||||
/\/sources\/[^/]*/,
|
||||
`/sources/${source.id}`
|
||||
)
|
||||
return router.push(fixedPath)
|
||||
}
|
||||
|
||||
private handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
let val = e.target.value
|
||||
const name = e.target.name
|
||||
|
||||
if (e.target.type === 'checkbox') {
|
||||
val = e.target.checked as any
|
||||
}
|
||||
|
||||
this.setState(prevState => {
|
||||
const source = {
|
||||
...prevState.source,
|
||||
[name]: val,
|
||||
}
|
||||
|
||||
return {...prevState, source}
|
||||
})
|
||||
}
|
||||
|
||||
private handleBlurSourceURL = () => {
|
||||
const {source, editMode} = this.state
|
||||
if (editMode) {
|
||||
this.setState(this.normalizeSource)
|
||||
return
|
||||
}
|
||||
|
||||
if (!source.url) {
|
||||
return
|
||||
}
|
||||
|
||||
this.setState(this.normalizeSource, this.createSourceOnBlur)
|
||||
}
|
||||
|
||||
private get pageTitle(): string {
|
||||
const {editMode} = this.state
|
||||
|
||||
if (editMode) {
|
||||
return 'Configure InfluxDB Connection'
|
||||
}
|
||||
|
||||
return 'Add a New InfluxDB Connection'
|
||||
}
|
||||
}
|
||||
|
||||
const mdtp = {
|
||||
notify: notifyAction,
|
||||
addSource: addSourceAction,
|
||||
updateSource: updateSourceAction,
|
||||
}
|
||||
|
||||
export default connect(null, mdtp)(withRouter(SourcePage))
|
|
@ -1,4 +1,3 @@
|
|||
import SourcePage from './containers/SourcePage'
|
||||
import ManageSources from './containers/ManageSources'
|
||||
import OnboardingWizard from './containers/OnboardingWizard'
|
||||
export {SourcePage, ManageSources, OnboardingWizard}
|
||||
export {ManageSources, OnboardingWizard}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
import React from 'react'
|
||||
import {shallow} from 'enzyme'
|
||||
|
||||
import {SourceForm} from 'src/sources/components/SourceForm'
|
||||
import {me} from 'test/resources'
|
||||
import {source} from 'test/fixtures/index'
|
||||
|
||||
const setup = (override = {}) => {
|
||||
const noop = () => {}
|
||||
const props = {
|
||||
source,
|
||||
editMode: false,
|
||||
onSubmit: noop,
|
||||
onInputChange: noop,
|
||||
onBlurSourceURL: noop,
|
||||
isUsingAuth: false,
|
||||
gotoPurgatory: noop,
|
||||
isInitialSource: false,
|
||||
me,
|
||||
...override,
|
||||
}
|
||||
|
||||
const wrapper = shallow(<SourceForm {...props} />)
|
||||
return {wrapper, props}
|
||||
}
|
||||
|
||||
describe('Sources.Components.SourceForm', () => {
|
||||
describe('rendering', () => {
|
||||
it('renders default retention policy field', () => {
|
||||
const {wrapper} = setup()
|
||||
const inputs = wrapper.find('input')
|
||||
const defaultRP = inputs.find({id: 'defaultRP'})
|
||||
|
||||
expect(defaultRP.exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue