Merge pull request #13337 from influxdata/reorg-scrapers

refactor(scrapers): move scrapers under orgs
pull/13362/head
Alirie Gray 2019-04-12 10:42:36 -07:00 committed by GitHub
commit cadf065b44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 363 additions and 1057 deletions

View File

@ -2,13 +2,12 @@
import React, {PureComponent} from 'react'
import {withRouter, WithRouterProps} from 'react-router'
import {connect} from 'react-redux'
import _ from 'lodash'
import {get} from 'lodash'
// Components
import UpdateBucketOverlay from 'src/buckets/components/UpdateBucketOverlay'
import BucketRow, {PrettyBucket} from 'src/buckets/components/BucketRow'
import {Overlay, IndexList} from 'src/clockface'
import DataLoaderSwitcher from 'src/dataLoaders/components/DataLoaderSwitcher'
// Actions
import {setBucketInfo} from 'src/dataLoaders/actions/steps'
@ -41,39 +40,21 @@ type Props = OwnProps & StateProps & DispatchProps
interface State {
bucketID: string
bucketOverlayState: OverlayState
dataLoadersOverlayState: OverlayState
}
class BucketList extends PureComponent<Props & WithRouterProps, State> {
constructor(props) {
super(props)
const openDataLoaderOverlay = _.get(
this,
'props.location.query.openDataLoaderOverlay',
false
)
const firstBucketID = _.get(this, 'props.buckets.0.id', null)
const bucketID = openDataLoaderOverlay ? firstBucketID : null
const bucketID = get(this, 'props.buckets.0.id', null)
this.state = {
bucketID,
bucketOverlayState: OverlayState.Closed,
dataLoadersOverlayState: openDataLoaderOverlay
? OverlayState.Open
: OverlayState.Closed,
}
}
public render() {
const {
dataLoaderType,
buckets,
emptyState,
onDeleteBucket,
onFilterChange,
} = this.props
const {bucketID} = this.state
const {buckets, emptyState, onDeleteBucket, onFilterChange} = this.props
return (
<>
@ -104,13 +85,6 @@ class BucketList extends PureComponent<Props & WithRouterProps, State> {
onUpdateBucket={this.handleUpdateBucket}
/>
</Overlay>
<DataLoaderSwitcher
type={dataLoaderType}
visible={this.isDataLoadersWizardVisible}
onCompleteSetup={this.handleDismissDataLoaders}
buckets={buckets}
overrideBucketIDSelection={bucketID}
/>
</>
)
}
@ -129,33 +103,23 @@ class BucketList extends PureComponent<Props & WithRouterProps, State> {
private handleStartAddData = (
bucket: PrettyBucket,
dataLoaderType: DataLoaderType
dataLoaderType: DataLoaderType,
link: string
) => {
this.props.onSetBucketInfo(
const {onSetBucketInfo, onSetDataLoadersType, router} = this.props
onSetBucketInfo(
bucket.organization,
bucket.organizationID,
bucket.name,
bucket.id
)
this.props.onSetDataLoadersType(dataLoaderType)
this.setState({
bucketID: bucket.id,
dataLoadersOverlayState: OverlayState.Open,
})
}
private handleDismissDataLoaders = () => {
this.setState({
bucketID: '',
dataLoadersOverlayState: OverlayState.Closed,
})
}
private get isDataLoadersWizardVisible(): boolean {
const {bucketID, dataLoadersOverlayState} = this.state
return !!bucketID && dataLoadersOverlayState === OverlayState.Open
onSetDataLoadersType(dataLoaderType)
router.push(link)
}
private get isBucketOverlayVisible(): boolean {

View File

@ -30,7 +30,7 @@ interface Props {
bucket: PrettyBucket
onEditBucket: (b: PrettyBucket) => void
onDeleteBucket: (b: PrettyBucket) => void
onAddData: (b: PrettyBucket, d: DataLoaderType) => void
onAddData: (b: PrettyBucket, d: DataLoaderType, l: string) => void
onUpdateBucket: (b: PrettyBucket) => void
onFilterChange: (searchTerm: string) => void
}
@ -101,15 +101,33 @@ class BucketRow extends PureComponent<Props & WithRouterProps> {
}
private handleAddCollector = (): void => {
this.props.onAddData(this.props.bucket, DataLoaderType.Streaming)
const {
params: {orgID},
bucket: {id},
} = this.props
const link = `/orgs/${orgID}/buckets/${id}/telegrafs/new`
this.props.onAddData(this.props.bucket, DataLoaderType.Streaming, link)
}
private handleAddLineProtocol = (): void => {
this.props.onAddData(this.props.bucket, DataLoaderType.LineProtocol)
const {
params: {orgID},
bucket: {id},
} = this.props
const link = `/orgs/${orgID}/buckets/${id}/line-protocols/new`
this.props.onAddData(this.props.bucket, DataLoaderType.LineProtocol, link)
}
private handleAddScraper = (): void => {
this.props.onAddData(this.props.bucket, DataLoaderType.Scraping)
const {
params: {orgID},
bucket: {id},
} = this.props
const link = `/orgs/${orgID}/buckets/${id}/scrapers/new`
this.props.onAddData(this.props.bucket, DataLoaderType.Scraping, link)
}
}

View File

@ -28,27 +28,30 @@ class BucketsIndex extends Component<StateProps> {
const {org} = this.props
return (
<Page titleTag={org.name}>
<OrgHeader />
<Page.Contents fullWidth={false} scrollable={true}>
<div className="col-xs-12">
<Tabs>
<OrganizationNavigation tab="buckets" orgID={org.id} />
<Tabs.TabContents>
<TabbedPageSection
id="org-view-tab--buckets"
url="buckets"
title="Buckets"
>
<GetResources resource={ResourceTypes.Buckets}>
<BucketsTab />
</GetResources>
</TabbedPageSection>
</Tabs.TabContents>
</Tabs>
</div>
</Page.Contents>
</Page>
<>
<Page titleTag={org.name}>
<OrgHeader />
<Page.Contents fullWidth={false} scrollable={true}>
<div className="col-xs-12">
<Tabs>
<OrganizationNavigation tab="buckets" orgID={org.id} />
<Tabs.TabContents>
<TabbedPageSection
id="org-view-tab--buckets"
url="buckets"
title="Buckets"
>
<GetResources resource={ResourceTypes.Buckets}>
<BucketsTab />
{this.props.children}
</GetResources>
</TabbedPageSection>
</Tabs.TabContents>
</Tabs>
</div>
</Page.Contents>
</Page>
</>
)
}
}

View File

@ -8,7 +8,6 @@ import {ErrorHandling} from 'src/shared/decorators/errors'
interface Props {
children: any
visible: boolean
title: string
maxWidth: number
onDismiss: () => void
@ -21,10 +20,10 @@ class WizardOverlay extends PureComponent<Props> {
}
public render() {
const {visible, title, maxWidth, children, onDismiss} = this.props
const {title, maxWidth, children, onDismiss} = this.props
return (
<Overlay visible={visible}>
<Overlay visible={true}>
<Overlay.Container maxWidth={maxWidth}>
<Overlay.Heading title={title} onDismiss={onDismiss} />
<Overlay.Body>

View File

@ -11,7 +11,6 @@ import TabbedPageSection from 'src/shared/components/tabbed_page/TabbedPageSecti
import TabbedPage from 'src/shared/components/tabbed_page/TabbedPage'
import Settings from 'src/me/components/account/Settings'
import Telegrafs from 'src/configuration/components/Telegrafs'
import Scrapers from 'src/configuration/components/Scrapers'
import PageTitleWithOrg from 'src/shared/components/PageTitleWithOrg'
// Decorators
@ -64,13 +63,7 @@ class ConfigurationPage extends Component<Props> {
id="scrapers_tab"
url="scrapers_tab"
title="Scrapers"
>
<GetResources resource={ResourceTypes.Buckets}>
<GetResources resource={ResourceTypes.Scrapers}>
<Scrapers />
</GetResources>
</GetResources>
</TabbedPageSection>
/>
<TabbedPageSection
id="settings_tab"
url="settings_tab"

View File

@ -1,228 +0,0 @@
// Libraries
import _ from 'lodash'
import React, {PureComponent, ChangeEvent} from 'react'
import {connect} from 'react-redux'
// Components
import {Input, Button, EmptyState} from '@influxdata/clockface'
import {Tabs} from 'src/clockface'
import ScraperList from 'src/organizations/components/ScraperList'
import CreateScraperOverlay from 'src/configuration/components/CreateScraperOverlay'
import NoBucketsWarning from 'src/organizations/components/NoBucketsWarning'
import FilterList from 'src/shared/components/Filter'
// Decorators
import {ErrorHandling} from 'src/shared/decorators/errors'
// Types
import {
Bucket,
ScraperTargetRequest,
ScraperTargetResponse,
} from '@influxdata/influx'
import {
IconFont,
InputType,
ComponentSize,
ComponentColor,
ComponentStatus,
} from '@influxdata/clockface'
import {OverlayState} from 'src/types'
import {AppState} from 'src/types'
//Actions
import {createScraper, updateScraper, deleteScraper} from 'src/scrapers/actions'
interface StateProps {
buckets: Bucket[]
scrapers: ScraperTargetResponse[]
}
interface DispatchProps {
createScraper: typeof createScraper
updateScraper: typeof updateScraper
deleteScraper: typeof deleteScraper
}
interface State {
overlayState: OverlayState
searchTerm: string
}
type Props = StateProps & DispatchProps
@ErrorHandling
class Scrapers extends PureComponent<Props, State> {
constructor(props: Props) {
super(props)
this.state = {
overlayState: OverlayState.Closed,
searchTerm: '',
}
}
public render() {
const {searchTerm} = this.state
const {scrapers} = this.props
return (
<>
<Tabs.TabContentsHeader>
<Input
icon={IconFont.Search}
placeholder="Filter scrapers..."
widthPixels={290}
value={searchTerm}
type={InputType.Text}
onChange={this.handleFilterChange}
onBlur={this.handleFilterBlur}
/>
{this.createScraperButton('create-scraper-button-header')}
</Tabs.TabContentsHeader>
<NoBucketsWarning visible={this.hasNoBuckets} resourceName="Scrapers" />
<FilterList<ScraperTargetResponse>
searchTerm={searchTerm}
searchKeys={['name', 'url']}
list={scrapers}
>
{sl => (
<ScraperList
scrapers={sl}
emptyState={this.emptyState}
onDeleteScraper={this.handleDeleteScraper}
onUpdateScraper={this.handleUpdateScraper}
/>
)}
</FilterList>
{this.createScraperOverlay}
</>
)
}
private get hasNoBuckets(): boolean {
const {buckets} = this.props
if (!buckets || !buckets.length) {
return true
}
return false
}
private get createScraperOverlay(): JSX.Element {
const {buckets} = this.props
if (this.hasNoBuckets) {
return
}
return (
<CreateScraperOverlay
visible={this.isOverlayVisible}
buckets={buckets}
onDismiss={this.handleDismissOverlay}
createScraper={this.handleCreateScraper}
/>
)
}
private get isOverlayVisible(): boolean {
return this.state.overlayState === OverlayState.Open
}
private handleShowOverlay = () => {
this.setState({overlayState: OverlayState.Open})
}
private handleDismissOverlay = () => {
this.setState({overlayState: OverlayState.Closed})
}
private handleCreateScraper = async (
scraper: ScraperTargetRequest
): Promise<void> => {
try {
await this.props.createScraper(scraper)
this.handleDismissOverlay()
} catch (e) {}
}
private createScraperButton = (testID: string): JSX.Element => {
let status = ComponentStatus.Default
let titleText = 'Create a new Scraper'
if (this.hasNoBuckets) {
status = ComponentStatus.Disabled
titleText = 'You need at least 1 bucket in order to create a scraper'
}
return (
<Button
text="Create Scraper"
icon={IconFont.Plus}
color={ComponentColor.Primary}
onClick={this.handleShowOverlay}
status={status}
titleText={titleText}
testID={testID}
/>
)
}
private get emptyState(): JSX.Element {
const {searchTerm} = this.state
if (_.isEmpty(searchTerm)) {
return (
<EmptyState size={ComponentSize.Medium}>
<EmptyState.Text
text={`Looks like you don't own any Scrapers , why not create one?`}
highlightWords={['Scrapers']}
/>
{this.createScraperButton('create-scraper-button-empty')}
</EmptyState>
)
}
return (
<EmptyState size={ComponentSize.Medium}>
<EmptyState.Text text="No Scrapers match your query" />
</EmptyState>
)
}
private handleUpdateScraper = async (scraper: ScraperTargetResponse) => {
this.props.updateScraper(scraper)
}
private handleDeleteScraper = async (scraper: ScraperTargetResponse) => {
this.props.deleteScraper(scraper)
}
private handleFilterChange = (e: ChangeEvent<HTMLInputElement>): void => {
this.setState({searchTerm: e.target.value})
}
private handleFilterBlur = (e: ChangeEvent<HTMLInputElement>): void => {
this.setState({searchTerm: e.target.value})
}
}
const mdtp: DispatchProps = {
createScraper,
updateScraper,
deleteScraper,
}
const mstp = ({buckets, scrapers}: AppState): StateProps => {
return {
buckets: buckets.list,
scrapers: scrapers.list,
}
}
export default connect<StateProps, DispatchProps, {}>(
mstp,
mdtp
)(Scrapers)

View File

@ -8,8 +8,6 @@ import {Input, Button, EmptyState, Grid} from '@influxdata/clockface'
import {Tabs} from 'src/clockface'
import CollectorList from 'src/telegrafs/components/CollectorList'
import TelegrafExplainer from 'src/telegrafs/components/TelegrafExplainer'
import TelegrafInstructionsOverlay from 'src/telegrafs/components/TelegrafInstructionsOverlay'
import CollectorsWizard from 'src/dataLoaders/components/collectorsWizard/CollectorsWizard'
import FilterList from 'src/shared/components/Filter'
import NoBucketsWarning from 'src/organizations/components/NoBucketsWarning'
@ -142,12 +140,6 @@ export class Telegrafs extends PureComponent<Props, State> {
</Grid.Column>
</Grid.Row>
</Grid>
{this.telegrafsWizard}
<TelegrafInstructionsOverlay
visible={this.isInstructionsVisible}
collector={this.selectedCollector}
onDismiss={this.handleCloseInstructions}
/>
</>
)
}
@ -162,35 +154,6 @@ export class Telegrafs extends PureComponent<Props, State> {
return false
}
private get telegrafsWizard(): JSX.Element {
const {buckets} = this.props
if (this.hasNoBuckets) {
return
}
return (
<CollectorsWizard
visible={this.isDataLoaderVisible}
onCompleteSetup={this.handleDismissDataLoaders}
startingStep={0}
buckets={buckets}
/>
)
}
private get selectedCollector() {
return this.props.telegrafs.find(c => c.id === this.state.collectorID)
}
private get isDataLoaderVisible(): boolean {
return this.state.dataLoaderOverlay === OverlayState.Open
}
private get isInstructionsVisible(): boolean {
return this.state.instructionsOverlay === OverlayState.Open
}
private handleOpenInstructions = (collectorID: string): void => {
this.setState({
instructionsOverlay: OverlayState.Open,
@ -198,13 +161,6 @@ export class Telegrafs extends PureComponent<Props, State> {
})
}
private handleCloseInstructions = (): void => {
this.setState({
instructionsOverlay: OverlayState.Closed,
collectorID: null,
})
}
private get createButton(): JSX.Element {
let status = ComponentStatus.Default
let titleText = 'Create a new Telegraf Configuration'
@ -240,10 +196,6 @@ export class Telegrafs extends PureComponent<Props, State> {
this.setState({dataLoaderOverlay: OverlayState.Open})
}
private handleDismissDataLoaders = () => {
this.setState({dataLoaderOverlay: OverlayState.Closed})
}
private get emptyState(): JSX.Element {
const {org} = this.props
const {searchTerm} = this.state

View File

@ -1,72 +0,0 @@
// Libraries
import React from 'react'
import {shallow} from 'enzyme'
// Components
import DataLoaderSwitcher from 'src/dataLoaders/components/DataLoaderSwitcher'
import CreateScraperOverlay from 'src/organizations/components/CreateScraperOverlay'
import CollectorsWizard from 'src/dataLoaders/components/collectorsWizard/CollectorsWizard'
import LineProtocolWizard from 'src/dataLoaders/components/lineProtocolWizard/LineProtocolWizard'
// Types
import {DataLoaderType} from 'src/types'
const setup = (override = {}) => {
const props = {
type: DataLoaderType.Empty,
onCompleteSetup: jest.fn(),
visible: true,
buckets: [],
...override,
}
const wrapper = shallow(<DataLoaderSwitcher {...props} />)
return {wrapper}
}
describe('DataLoading.Components.DataLoaderSwitcher', () => {
describe('if type is empty', () => {
it('renders empty div', () => {
const {wrapper} = setup({type: DataLoaderType.Empty})
const emptyDiv = wrapper.find({'data-testid': 'data-loader-empty'})
expect(wrapper.exists()).toBe(true)
expect(emptyDiv.exists()).toBe(true)
})
})
describe('if type is scraping', () => {
it('renders create scraper overlay', () => {
const {wrapper} = setup({type: DataLoaderType.Scraping})
const overlay = wrapper.find(CreateScraperOverlay)
expect(wrapper.exists()).toBe(true)
expect(overlay.exists()).toBe(true)
})
})
describe('if type is streaming', () => {
it('renders collectors wizard', () => {
const {wrapper} = setup({type: DataLoaderType.Streaming})
const wizard = wrapper.find(CollectorsWizard)
expect(wrapper.exists()).toBe(true)
expect(wizard.exists()).toBe(true)
})
})
describe('if type is line protocol', () => {
it('renders line protocol wizard', () => {
const {wrapper} = setup({type: DataLoaderType.LineProtocol})
const wizard = wrapper.find(LineProtocolWizard)
expect(wrapper.exists()).toBe(true)
expect(wizard.exists()).toBe(true)
})
})
})

View File

@ -1,64 +0,0 @@
// Libraries
import React, {PureComponent} from 'react'
import _ from 'lodash'
// Components
import CreateScraperOverlay from 'src/organizations/components/CreateScraperOverlay'
import CollectorsWizard from 'src/dataLoaders/components/collectorsWizard/CollectorsWizard'
import LineProtocolWizard from 'src/dataLoaders/components/lineProtocolWizard/LineProtocolWizard'
// Types
import {DataLoaderType} from 'src/types/dataLoaders'
import {Bucket} from '@influxdata/influx'
interface Props {
type: DataLoaderType
onCompleteSetup: () => void
visible: boolean
buckets: Bucket[]
overrideBucketIDSelection?: string
}
class DataLoaderSwitcher extends PureComponent<Props> {
public render() {
const {
buckets,
type,
visible,
onCompleteSetup,
overrideBucketIDSelection,
} = this.props
switch (type) {
case DataLoaderType.Empty:
return <div data-testid="data-loader-empty" />
case DataLoaderType.Scraping:
return (
<CreateScraperOverlay
visible={visible}
buckets={buckets}
onDismiss={onCompleteSetup}
overrideBucketIDSelection={overrideBucketIDSelection}
/>
)
case DataLoaderType.Streaming:
return (
<CollectorsWizard
visible={visible}
onCompleteSetup={onCompleteSetup}
buckets={buckets}
/>
)
case DataLoaderType.LineProtocol:
return (
<LineProtocolWizard
onCompleteSetup={onCompleteSetup}
visible={visible}
buckets={buckets}
/>
)
}
}
}
export default DataLoaderSwitcher

View File

@ -1,6 +1,7 @@
// Libraries
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
import {withRouter, WithRouterProps} from 'react-router'
import _ from 'lodash'
// Components
@ -39,13 +40,6 @@ export interface CollectorsStepProps {
onExit: () => void
}
interface OwnProps {
onCompleteSetup: () => void
visible: boolean
buckets: Bucket[]
startingStep?: number
}
interface DispatchProps {
notify: (message: Notification | NotificationFunc) => void
onSetBucketInfo: typeof setBucketInfo
@ -60,6 +54,7 @@ interface DispatchProps {
interface StateProps {
links: Links
buckets: Bucket[]
telegrafPlugins: TelegrafPlugin[]
currentStepIndex: number
substep: Substep
@ -67,30 +62,30 @@ interface StateProps {
bucket: string
}
type Props = OwnProps & StateProps & DispatchProps
interface State {
buckets: Bucket[]
}
type Props = StateProps & DispatchProps
@ErrorHandling
class CollectorsWizard extends PureComponent<Props> {
class CollectorsWizard extends PureComponent<Props & WithRouterProps, State> {
constructor(props) {
super(props)
this.state = {
buckets: [],
}
}
public componentDidMount() {
this.handleSetBucketInfo()
this.handleSetStartingValues()
}
public componentDidUpdate(prevProps: Props) {
const hasBecomeVisible = !prevProps.visible && this.props.visible
if (hasBecomeVisible) {
this.handleSetBucketInfo()
this.handleSetStartingValues()
}
this.props.onSetCurrentStepIndex(0)
}
public render() {
const {visible, buckets} = this.props
const {buckets} = this.props
return (
<WizardOverlay
visible={visible}
title="Create a Telegraf Config"
onDismiss={this.handleDismiss}
>
@ -108,20 +103,12 @@ class CollectorsWizard extends PureComponent<Props> {
}
}
private handleSetStartingValues = () => {
const {startingStep} = this.props
const hasStartingStep = startingStep || startingStep === 0
if (hasStartingStep) {
this.props.onSetCurrentStepIndex(startingStep)
}
}
private handleDismiss = () => {
this.props.onCompleteSetup()
this.props.onClearDataLoaders()
this.props.onClearSteps()
const {router, onClearDataLoaders, onClearSteps} = this.props
onClearDataLoaders()
onClearSteps()
router.goBack()
}
private get stepProps(): CollectorsStepProps {
@ -144,6 +131,7 @@ class CollectorsWizard extends PureComponent<Props> {
const mstp = ({
links,
buckets,
dataLoading: {
dataLoaders: {telegrafPlugins},
steps: {currentStep, substep, bucket},
@ -156,6 +144,7 @@ const mstp = ({
substep,
username: name,
bucket,
buckets: buckets.list,
})
const mdtp: DispatchProps = {
@ -170,7 +159,7 @@ const mdtp: DispatchProps = {
onSetPluginConfiguration: setPluginConfiguration,
}
export default connect<StateProps, DispatchProps, OwnProps>(
export default connect<StateProps, DispatchProps, {}>(
mstp,
mdtp
)(CollectorsWizard)
)(withRouter<Props>(CollectorsWizard))

View File

@ -1,6 +1,7 @@
// Libraries
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
import {withRouter, WithRouterProps} from 'react-router'
import _ from 'lodash'
// Components
@ -35,8 +36,6 @@ export interface LineProtocolStepProps {
interface OwnProps {
onCompleteSetup: () => void
visible: boolean
buckets: Bucket[]
startingStep?: number
}
@ -54,35 +53,23 @@ interface StateProps {
currentStepIndex: number
username: string
bucket: string
buckets: Bucket[]
}
type Props = OwnProps & StateProps & DispatchProps
@ErrorHandling
class CollectorsWizard extends PureComponent<Props> {
class LineProtocolWizard extends PureComponent<Props & WithRouterProps> {
public componentDidMount() {
this.handleSetBucketInfo()
this.handleSetStartingValues()
}
public componentDidUpdate(prevProps: Props) {
const hasBecomeVisible = !prevProps.visible && this.props.visible
if (hasBecomeVisible) {
this.handleSetBucketInfo()
this.handleSetStartingValues()
}
}
public render() {
const {visible, buckets} = this.props
const {buckets} = this.props
return (
<WizardOverlay
visible={visible}
title="Add Line Protocol"
onDismiss={this.handleDismiss}
>
<WizardOverlay title="Add Line Protocol" onDismiss={this.handleDismiss}>
<div className="wizard-contents">
<div className="wizard-step--container">
<LineProtocolStepSwitcher
@ -115,9 +102,11 @@ class CollectorsWizard extends PureComponent<Props> {
}
private handleDismiss = () => {
this.props.onCompleteSetup()
this.props.onClearDataLoaders()
this.props.onClearSteps()
const {router, onClearDataLoaders, onClearSteps} = this.props
onClearDataLoaders()
onClearSteps()
router.goBack()
}
private get stepProps(): LineProtocolStepProps {
@ -143,10 +132,12 @@ const mstp = ({
steps: {currentStep, bucket},
},
me: {name},
buckets,
}: AppState): StateProps => ({
currentStepIndex: currentStep,
username: name,
bucket,
buckets: buckets.list,
})
const mdtp: DispatchProps = {
@ -162,4 +153,4 @@ const mdtp: DispatchProps = {
export default connect<StateProps, DispatchProps, OwnProps>(
mstp,
mdtp
)(CollectorsWizard)
)(withRouter<Props>(LineProtocolWizard))

View File

@ -48,17 +48,21 @@ import TelegrafsPage from 'src/telegrafs/containers/TelegrafsPage'
import TemplateImportOverlay from 'src/templates/components/TemplateImportOverlay'
import TemplateExportOverlay from 'src/templates/components/TemplateExportOverlay'
import VariablesIndex from 'src/variables/containers/VariablesIndex'
import OrgScrapersIndex from 'src/organizations/containers/OrgScrapersIndex'
import ScrapersIndex from 'src/scrapers/containers/ScrapersIndex'
import VariableImportOverlay from 'src/variables/components/VariableImportOverlay'
import VariableExportOverlay from 'src/variables/components/VariableExportOverlay'
import SetOrg from 'src/shared/containers/SetOrg'
import RouteToOrg from 'src/shared/containers/RouteToOrg'
import CreateOrgOverlay from 'src/organizations/components/CreateOrgOverlay'
import CreateScraperOverlay from 'src/scrapers/components/CreateScraperOverlay'
import TokensIndex from 'src/authorizations/containers/TokensIndex'
import MembersIndex from 'src/members/containers/MembersIndex'
import LabelsIndex from 'src/labels/containers/LabelsIndex'
import TemplateViewOverlay from 'src/templates/components/TemplateViewOverlay'
import TelegrafConfigOverlay from 'src/telegrafs/components/TelegrafConfigOverlay'
import LineProtocolWizard from 'src/dataLoaders/components/lineProtocolWizard/LineProtocolWizard'
import CollectorsWizard from 'src/dataLoaders/components/collectorsWizard/CollectorsWizard'
import TelegrafInstructionsOverlay from 'src/telegrafs/components/TelegrafInstructionsOverlay'
// Actions
import {disablePresentationMode} from 'src/shared/actions/app'
@ -186,7 +190,20 @@ class Root extends PureComponent {
<Route path="settings">
<IndexRoute component={MembersIndex} />
</Route>
<Route path="buckets" component={BucketsIndex} />
<Route path="buckets" component={BucketsIndex}>
<Route
path=":bucketID/line-protocols/new"
component={LineProtocolWizard}
/>
<Route
path=":bucketID/telegrafs/new"
component={CollectorsWizard}
/>
<Route
path=":bucketID/scrapers/new"
component={CreateScraperOverlay}
/>
</Route>
<Route path="tokens" component={TokensIndex} />
<Route path="members" component={MembersIndex} />
<Route path="telegrafs" component={TelegrafsPage}>
@ -194,6 +211,11 @@ class Root extends PureComponent {
path=":id/view"
component={TelegrafConfigOverlay}
/>
<Route
path=":id/instructions"
component={TelegrafInstructionsOverlay}
/>
<Route path="new" component={CollectorsWizard} />
</Route>
<Route path="templates" component={TemplatesIndex}>
<Route
@ -223,8 +245,13 @@ class Root extends PureComponent {
component={CreateVariableOverlay}
/>
</Route>
<Route path="scrapers" component={OrgScrapersIndex} />
<Route path="labels" component={LabelsIndex} />
<Route path="scrapers" component={ScrapersIndex}>
<Route
path="new"
component={CreateScraperOverlay}
/>
</Route>
</Route>
</Route>
</Route>

View File

@ -1,177 +0,0 @@
// Libraries
import React, {PureComponent, ChangeEvent} from 'react'
import {connect} from 'react-redux'
import _ from 'lodash'
// Components
import {Form, Button} from '@influxdata/clockface'
import {Overlay} from 'src/clockface'
import CreateScraperForm from 'src/organizations/components/CreateScraperForm'
// Actions
import {notify as notifyAction, notify} from 'src/shared/actions/notifications'
import {createScraper} from 'src/organizations/actions/orgView'
// Types
import {Bucket, ScraperTargetRequest} from '@influxdata/influx'
import {ComponentColor, ComponentStatus} from '@influxdata/clockface'
import {
scraperCreateSuccess,
scraperCreateFailed,
} from 'src/shared/copy/v2/notifications'
interface OwnProps {
visible: boolean
buckets: Bucket[]
onDismiss: () => void
overrideBucketIDSelection?: string
}
interface DispatchProps {
notify: typeof notifyAction
onCreateScraper: typeof createScraper
}
type Props = OwnProps & DispatchProps
interface State {
scraper: ScraperTargetRequest
}
class CreateScraperOverlay extends PureComponent<Props, State> {
constructor(props: Props) {
super(props)
const bucketID =
this.props.overrideBucketIDSelection || this.props.buckets[0].id
const orgID = this.props.buckets.find(b => b.id === bucketID).organizationID
this.state = {
scraper: {
name: 'Name this Scraper',
type: ScraperTargetRequest.TypeEnum.Prometheus,
url: `${this.origin}/metrics`,
orgID,
bucketID,
},
}
}
componentDidUpdate(prevProps) {
if (
prevProps.visible === false &&
this.props.visible === true &&
this.props.overrideBucketIDSelection
) {
const bucketID = this.props.overrideBucketIDSelection
const orgID = this.props.buckets.find(b => b.id === bucketID)
.organizationID
const scraper = {
...this.state.scraper,
bucketID,
orgID,
}
this.setState({scraper})
}
}
public render() {
const {scraper} = this.state
const {onDismiss, visible, buckets} = this.props
return (
<Overlay visible={visible}>
<Overlay.Container maxWidth={600}>
<Overlay.Heading title="Create Scraper" onDismiss={onDismiss} />
<Form onSubmit={this.handleSubmit}>
<Overlay.Body>
<h5 className="wizard-step--sub-title">
Scrapers collect data from multiple targets at regular intervals
and to write to a bucket
</h5>
<CreateScraperForm
buckets={buckets}
url={scraper.url}
name={scraper.name}
selectedBucketID={scraper.bucketID}
onInputChange={this.handleInputChange}
onSelectBucket={this.handleSelectBucket}
/>
</Overlay.Body>
<Overlay.Footer>
<Button
text="Cancel"
onClick={onDismiss}
testID="create-scraper--cancel"
/>
<Button
status={this.submitButtonStatus}
text="Create"
onClick={this.handleSubmit}
color={ComponentColor.Success}
testID="create-scraper--submit"
/>
</Overlay.Footer>
</Form>
</Overlay.Container>
</Overlay>
)
}
private handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
const key = e.target.name
const scraper = {...this.state.scraper, [key]: value}
this.setState({
scraper,
})
}
private handleSelectBucket = (bucket: Bucket) => {
const {organizationID, id} = bucket
const scraper = {...this.state.scraper, orgID: organizationID, bucketID: id}
this.setState({scraper})
}
private get submitButtonStatus(): ComponentStatus {
const {scraper} = this.state
if (!scraper.url || !scraper.name || !scraper.bucketID) {
return ComponentStatus.Disabled
}
return ComponentStatus.Default
}
private handleSubmit = async () => {
try {
const {onCreateScraper, onDismiss, notify} = this.props
const {scraper} = this.state
await onCreateScraper(scraper)
onDismiss()
notify(scraperCreateSuccess())
} catch (e) {
console.error(e)
notify(scraperCreateFailed())
}
}
private get origin(): string {
return window.location.origin
}
}
const mdtp: DispatchProps = {
notify: notifyAction,
onCreateScraper: createScraper,
}
export default connect<{}, DispatchProps, OwnProps>(
null,
mdtp
)(CreateScraperOverlay)

View File

@ -1,134 +0,0 @@
// Libraries
import React, {Component} from 'react'
import {withRouter, WithRouterProps} from 'react-router'
import {connect} from 'react-redux'
// Components
import {Page} from 'src/pageLayout'
import {Tabs} from 'src/clockface'
import TabbedPageSection from 'src/shared/components/tabbed_page/TabbedPageSection'
import {SpinnerContainer, TechnoSpinner} from '@influxdata/clockface'
import OrgHeader from 'src/organizations/containers/OrgHeader'
import OrganizationNavigation from 'src/organizations/components/OrganizationNavigation'
import GetOrgResources from 'src/organizations/components/GetOrgResources'
import Scrapers from 'src/organizations/components/Scrapers'
// APIs
import {client} from 'src/utils/api'
// Decorators
import {ErrorHandling} from 'src/shared/decorators/errors'
// Actions
import * as NotificationsActions from 'src/types/actions/notifications'
import * as notifyActions from 'src/shared/actions/notifications'
// Types
import {Organization, ScraperTargetResponse, Bucket} from '@influxdata/influx'
import {AppState} from 'src/types'
const getScrapers = async (
org: Organization
): Promise<ScraperTargetResponse[]> => {
return await client.scrapers.getAll(org.id)
}
const getBuckets = async (org: Organization): Promise<Bucket[]> => {
return client.buckets.getAll(org.id)
}
interface RouterProps {
params: {
orgID: string
}
}
interface DispatchProps {
notify: NotificationsActions.PublishNotificationActionCreator
}
interface StateProps {
org: Organization
}
type Props = WithRouterProps & RouterProps & DispatchProps & StateProps
@ErrorHandling
class OrgScrapersIndex extends Component<Props> {
public render() {
const {org, notify} = this.props
return (
<Page titleTag={org.name}>
<OrgHeader />
<Page.Contents fullWidth={false} scrollable={true}>
<div className="col-xs-12">
<Tabs>
<OrganizationNavigation tab="scrapers" orgID={org.id} />
<Tabs.TabContents>
<TabbedPageSection
id="org-view-tab--scrapers"
url="scrapers"
title="Scrapers"
>
<GetOrgResources<ScraperTargetResponse>
organization={org}
fetcher={getScrapers}
>
{(scrapers, loading, fetch) => {
return (
<SpinnerContainer
loading={loading}
spinnerComponent={<TechnoSpinner />}
>
<GetOrgResources<Bucket>
organization={org}
fetcher={getBuckets}
>
{(buckets, loading) => (
<SpinnerContainer
loading={loading}
spinnerComponent={<TechnoSpinner />}
>
<Scrapers
scrapers={scrapers}
onChange={fetch}
orgName={org.name}
buckets={buckets}
notify={notify}
/>
</SpinnerContainer>
)}
</GetOrgResources>
</SpinnerContainer>
)
}}
</GetOrgResources>
</TabbedPageSection>
</Tabs.TabContents>
</Tabs>
</div>
</Page.Contents>
</Page>
)
}
}
const mstp = (state: AppState, props: Props) => {
const {
orgs: {items},
} = state
const org = items.find(o => o.id === props.params.orgID)
return {
org,
}
}
const mdtp: DispatchProps = {
notify: notifyActions.notify,
}
export default connect<StateProps, DispatchProps, {}>(
mstp,
mdtp
)(withRouter<{}>(OrgScrapersIndex))

View File

@ -1,24 +1,36 @@
// Libraries
import React, {PureComponent, ChangeEvent} from 'react'
import _ from 'lodash'
import {get} from 'lodash'
import {connect} from 'react-redux'
import {withRouter, WithRouterProps} from 'react-router'
// Components
import {Form, Button} from '@influxdata/clockface'
import {Overlay} from 'src/clockface'
import CreateScraperForm from 'src/organizations/components/CreateScraperForm'
import CreateScraperForm from 'src/scrapers/components/CreateScraperForm'
// Actions
import {createScraper} from 'src/scrapers/actions'
// Types
import {Bucket, ScraperTargetRequest} from '@influxdata/influx'
import {ComponentColor, ComponentStatus} from '@influxdata/clockface'
import {AppState} from 'src/types'
interface Props {
interface OwnProps {
visible: boolean
buckets: Bucket[]
onDismiss: () => void
createScraper: (scraper: ScraperTargetRequest) => void
overrideBucketIDSelection?: string
}
interface StateProps {
buckets: Bucket[]
}
interface DispatchProps {
onCreateScraper: typeof createScraper
}
type Props = OwnProps & StateProps & DispatchProps & WithRouterProps
interface State {
scraper: ScraperTargetRequest
}
@ -27,10 +39,12 @@ class CreateScraperOverlay extends PureComponent<Props, State> {
constructor(props: Props) {
super(props)
const bucketID =
this.props.overrideBucketIDSelection || this.props.buckets[0].id
const {
params: {bucketID, orgID},
buckets,
} = this.props
const orgID = this.props.buckets.find(b => b.id === bucketID).organizationID
const firstBucketID = get(buckets, '0.id', '')
this.state = {
scraper: {
@ -38,38 +52,19 @@ class CreateScraperOverlay extends PureComponent<Props, State> {
type: ScraperTargetRequest.TypeEnum.Prometheus,
url: `${this.origin}/metrics`,
orgID,
bucketID,
bucketID: bucketID ? bucketID : firstBucketID,
},
}
}
componentDidUpdate(prevProps) {
if (
prevProps.visible === false &&
this.props.visible === true &&
this.props.overrideBucketIDSelection
) {
const bucketID = this.props.overrideBucketIDSelection
const orgID = this.props.buckets.find(b => b.id === bucketID)
.organizationID
const scraper = {
...this.state.scraper,
bucketID,
orgID,
}
this.setState({scraper})
}
}
public render() {
const {scraper} = this.state
const {onDismiss, visible, buckets} = this.props
const {buckets} = this.props
return (
<Overlay visible={visible}>
<Overlay visible={true}>
<Overlay.Container maxWidth={600}>
<Overlay.Heading title="Create Scraper" onDismiss={onDismiss} />
<Overlay.Heading title="Create Scraper" onDismiss={this.onDismiss} />
<Form onSubmit={this.handleSubmit}>
<Overlay.Body>
<h5 className="wizard-step--sub-title">
@ -88,7 +83,7 @@ class CreateScraperOverlay extends PureComponent<Props, State> {
<Overlay.Footer>
<Button
text="Cancel"
onClick={onDismiss}
onClick={this.onDismiss}
testID="create-scraper--cancel"
/>
<Button
@ -132,16 +127,32 @@ class CreateScraperOverlay extends PureComponent<Props, State> {
return ComponentStatus.Default
}
private handleSubmit = () => {
const {createScraper} = this.props
private handleSubmit = async () => {
const {onCreateScraper} = this.props
const {scraper} = this.state
createScraper(scraper)
onCreateScraper(scraper)
this.onDismiss()
}
private get origin(): string {
return window.location.origin
}
private onDismiss = (): void => {
this.props.router.goBack()
}
}
export default CreateScraperOverlay
const mstp = ({buckets}: AppState): StateProps => ({
buckets: buckets.list,
})
const mdtp: DispatchProps = {
onCreateScraper: createScraper,
}
export default connect<StateProps, DispatchProps, OwnProps>(
mstp,
mdtp
)(withRouter<StateProps & DispatchProps & OwnProps>(CreateScraperOverlay))

View File

@ -3,7 +3,7 @@ import React, {PureComponent} from 'react'
// Components
import {IndexList} from 'src/clockface'
import ScraperRow from 'src/organizations/components/ScraperRow'
import ScraperRow from 'src/scrapers/components/ScraperRow'
// Types
import {ScraperTargetResponse} from '@influxdata/influx'

View File

@ -3,7 +3,7 @@ import React from 'react'
import {shallow} from 'enzyme'
// Components
import ScraperList from 'src/organizations/components/ScraperList'
import ScraperList from 'src/scrapers/components/ScraperList'
// Constants
import {scraperTargets} from 'mocks/dummyData'

View File

@ -1,19 +1,17 @@
// Libraries
import _ from 'lodash'
import React, {PureComponent, ChangeEvent} from 'react'
// APIs
import {client} from 'src/utils/api'
import {withRouter, WithRouterProps} from 'react-router'
import {connect} from 'react-redux'
import _ from 'lodash'
// Components
import {Input, Button, EmptyState} from '@influxdata/clockface'
import {Tabs} from 'src/clockface'
import ScraperList from 'src/organizations/components/ScraperList'
import CreateScraperOverlay from 'src/organizations/components/CreateScraperOverlay'
import ScraperList from 'src/scrapers/components/ScraperList'
import NoBucketsWarning from 'src/organizations/components/NoBucketsWarning'
// Actions
import * as NotificationsActions from 'src/types/actions/notifications'
import {updateScraper, deleteScraper} from 'src/scrapers/actions'
// Decorators
import {ErrorHandling} from 'src/shared/decorators/errors'
@ -27,25 +25,26 @@ import {
ComponentColor,
ComponentStatus,
} from '@influxdata/clockface'
import {OverlayState} from 'src/types'
import {
scraperDeleteSuccess,
scraperDeleteFailed,
scraperUpdateSuccess,
scraperUpdateFailed,
} from 'src/shared/copy/v2/notifications'
import {AppState} from 'src/types'
import FilterList from 'src/shared/components/Filter'
interface Props {
interface StateProps {
scrapers: ScraperTargetResponse[]
onChange: () => void
orgName: string
buckets: Bucket[]
notify: NotificationsActions.PublishNotificationActionCreator
}
interface DispatchProps {
onUpdateScraper: typeof updateScraper
onDeleteScraper: typeof deleteScraper
}
interface OwnProps {
orgName: string
}
type Props = OwnProps & StateProps & DispatchProps & WithRouterProps
interface State {
overlayState: OverlayState
searchTerm: string
}
@ -55,7 +54,6 @@ class Scrapers extends PureComponent<Props, State> {
super(props)
this.state = {
overlayState: OverlayState.Closed,
searchTerm: '',
}
}
@ -93,7 +91,6 @@ class Scrapers extends PureComponent<Props, State> {
/>
)}
</FilterList>
{this.createScraperOverlay}
</>
)
}
@ -108,35 +105,6 @@ class Scrapers extends PureComponent<Props, State> {
return false
}
private get createScraperOverlay(): JSX.Element {
const {buckets} = this.props
if (this.hasNoBuckets) {
return
}
return (
<CreateScraperOverlay
visible={this.isOverlayVisible}
buckets={buckets}
onDismiss={this.handleDismissOverlay}
/>
)
}
private get isOverlayVisible(): boolean {
return this.state.overlayState === OverlayState.Open
}
private handleShowOverlay = () => {
this.setState({overlayState: OverlayState.Open})
}
private handleDismissOverlay = () => {
this.setState({overlayState: OverlayState.Closed})
this.props.onChange()
}
private createScraperButton = (testID: string): JSX.Element => {
let status = ComponentStatus.Default
let titleText = 'Create a new Scraper'
@ -183,27 +151,26 @@ class Scrapers extends PureComponent<Props, State> {
}
private handleUpdateScraper = async (scraper: ScraperTargetResponse) => {
const {onChange, notify} = this.props
try {
await client.scrapers.update(scraper.id, scraper)
onChange()
notify(scraperUpdateSuccess(scraper.name))
} catch (e) {
console.error(e)
notify(scraperUpdateFailed(scraper.name))
}
const {onUpdateScraper} = this.props
onUpdateScraper(scraper)
}
private handleDeleteScraper = async (scraper: ScraperTargetResponse) => {
const {onChange, notify} = this.props
try {
await client.scrapers.delete(scraper.id)
onChange()
notify(scraperDeleteSuccess(scraper.name))
} catch (e) {
notify(scraperDeleteFailed(scraper.name))
console.error(e)
const {onDeleteScraper} = this.props
onDeleteScraper(scraper)
}
private handleShowOverlay = (): void => {
const {
router,
params: {orgID},
} = this.props
if (this.hasNoBuckets) {
return
}
router.push(`/orgs/${orgID}/scrapers/new`)
}
private handleFilterChange = (e: ChangeEvent<HTMLInputElement>): void => {
@ -215,4 +182,17 @@ class Scrapers extends PureComponent<Props, State> {
}
}
export default Scrapers
const mstp = ({scrapers, buckets}: AppState): StateProps => ({
scrapers: scrapers.list,
buckets: buckets.list,
})
const mdtp: DispatchProps = {
onDeleteScraper: deleteScraper,
onUpdateScraper: updateScraper,
}
export default connect<StateProps, DispatchProps, OwnProps>(
mstp,
mdtp
)(withRouter<OwnProps>(Scrapers))

View File

@ -0,0 +1,75 @@
// Libraries
import React, {Component} from 'react'
import {connect} from 'react-redux'
// Components
import {Page} from 'src/pageLayout'
import {Tabs} from 'src/clockface'
import TabbedPageSection from 'src/shared/components/tabbed_page/TabbedPageSection'
import OrgHeader from 'src/organizations/containers/OrgHeader'
import OrganizationNavigation from 'src/organizations/components/OrganizationNavigation'
import GetResources, {
ResourceTypes,
} from 'src/configuration/components/GetResources'
import Scrapers from 'src/scrapers/components/Scrapers'
// Decorators
import {ErrorHandling} from 'src/shared/decorators/errors'
// Types
import {Organization} from '@influxdata/influx'
import {AppState} from 'src/types'
interface StateProps {
org: Organization
}
@ErrorHandling
class ScrapersIndex extends Component<StateProps> {
public render() {
const {org} = this.props
return (
<>
<Page titleTag={org.name}>
<OrgHeader />
<Page.Contents fullWidth={false} scrollable={true}>
<div className="col-xs-12">
<Tabs>
<OrganizationNavigation tab="scrapers" orgID={org.id} />
<Tabs.TabContents>
<TabbedPageSection
id="org-view-tab--scrapers"
url="scrapers"
title="Scrapers"
>
<GetResources resource={ResourceTypes.Scrapers}>
<GetResources resource={ResourceTypes.Buckets}>
<Scrapers orgName={org.name} />
{this.props.children}
</GetResources>
</GetResources>
</TabbedPageSection>
</Tabs.TabContents>
</Tabs>
</div>
</Page.Contents>
</Page>
</>
)
}
}
const mstp = (state: AppState) => {
const {
orgs: {org},
} = state
return {
org,
}
}
export default connect<StateProps, {}, {}>(
mstp,
null
)(ScrapersIndex)

View File

@ -2,20 +2,16 @@
import _ from 'lodash'
import React, {PureComponent, ChangeEvent} from 'react'
import {connect} from 'react-redux'
import {withRouter, WithRouterProps} from 'react-router'
// Components
import {Input, Button, EmptyState, Grid} from '@influxdata/clockface'
import {Tabs} from 'src/clockface'
import CollectorList from 'src/telegrafs/components/CollectorList'
import TelegrafExplainer from 'src/telegrafs/components/TelegrafExplainer'
import TelegrafInstructionsOverlay from 'src/telegrafs/components/TelegrafInstructionsOverlay'
import CollectorsWizard from 'src/dataLoaders/components/collectorsWizard/CollectorsWizard'
import FilterList from 'src/shared/components/Filter'
import NoBucketsWarning from 'src/organizations/components/NoBucketsWarning'
import GetLabels from 'src/configuration/components/GetLabels'
import GetResources, {
ResourceTypes,
} from 'src/configuration/components/GetResources'
// Actions
import {setBucketInfo} from 'src/dataLoaders/actions/steps'
@ -59,7 +55,7 @@ interface DispatchProps {
onDeleteTelegraf: typeof deleteTelegraf
}
type Props = DispatchProps & StateProps
type Props = DispatchProps & StateProps & WithRouterProps
interface State {
dataLoaderOverlay: OverlayState
@ -69,7 +65,7 @@ interface State {
}
@ErrorHandling
export class Collectors extends PureComponent<Props, State> {
class Collectors extends PureComponent<Props, State> {
constructor(props: Props) {
super(props)
@ -135,14 +131,6 @@ export class Collectors extends PureComponent<Props, State> {
</Grid.Column>
</Grid.Row>
</Grid>
{this.collectorsWizard}
<GetResources resource={ResourceTypes.Authorizations}>
<TelegrafInstructionsOverlay
visible={this.isInstructionsVisible}
collector={this.selectedCollector}
onDismiss={this.handleCloseInstructions}
/>
</GetResources>
</>
)
}
@ -157,47 +145,16 @@ export class Collectors extends PureComponent<Props, State> {
return false
}
private get collectorsWizard(): JSX.Element {
const {buckets} = this.props
if (this.hasNoBuckets) {
return
}
return (
<CollectorsWizard
visible={this.isDataLoaderVisible}
onCompleteSetup={this.handleDismissDataLoaders}
startingStep={0}
buckets={buckets}
/>
)
}
private get selectedCollector() {
return this.props.collectors.find(c => c.id === this.state.collectorID)
}
private get isDataLoaderVisible(): boolean {
return this.state.dataLoaderOverlay === OverlayState.Open
}
private get isInstructionsVisible(): boolean {
return this.state.instructionsOverlay === OverlayState.Open
}
private handleOpenInstructions = (collectorID: string): void => {
const {
router,
params: {orgID},
} = this.props
this.setState({
instructionsOverlay: OverlayState.Open,
collectorID,
})
}
private handleCloseInstructions = (): void => {
this.setState({
instructionsOverlay: OverlayState.Closed,
collectorID: null,
})
router.push(`/orgs/${orgID}/telegrafs/${collectorID}/instructions`)
}
private get createButton(): JSX.Element {
@ -223,7 +180,13 @@ export class Collectors extends PureComponent<Props, State> {
}
private handleAddCollector = () => {
const {buckets, onSetBucketInfo, onSetDataLoadersType} = this.props
const {
buckets,
onSetBucketInfo,
onSetDataLoadersType,
router,
params: {orgID},
} = this.props
if (buckets && buckets.length) {
const {organization, organizationID, name, id} = buckets[0]
@ -232,11 +195,7 @@ export class Collectors extends PureComponent<Props, State> {
onSetDataLoadersType(DataLoaderType.Scraping)
this.setState({dataLoaderOverlay: OverlayState.Open})
}
private handleDismissDataLoaders = () => {
this.setState({dataLoaderOverlay: OverlayState.Closed})
router.push(`/orgs/${orgID}/telegrafs/new`)
}
private get emptyState(): JSX.Element {
@ -301,4 +260,4 @@ const mdtp: DispatchProps = {
export default connect<StateProps, DispatchProps>(
mstp,
mdtp
)(Collectors)
)(withRouter<StateProps & DispatchProps>(Collectors))

View File

@ -2,11 +2,15 @@
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
import {get} from 'lodash'
import {withRouter, WithRouterProps} from 'react-router'
// Components
import {ErrorHandling} from 'src/shared/decorators/errors'
import WizardOverlay from 'src/clockface/components/wizard/WizardOverlay'
import TelegrafInstructions from 'src/dataLoaders/components/verifyStep/TelegrafInstructions'
import GetResources, {
ResourceTypes,
} from 'src/configuration/components/GetResources'
// Constants
import {TOKEN_LABEL} from 'src/labels/constants'
@ -15,43 +19,38 @@ import {TOKEN_LABEL} from 'src/labels/constants'
import {AppState} from 'src/types'
import {Telegraf} from '@influxdata/influx'
interface OwnProps {
visible: boolean
onDismiss: () => void
collector?: Telegraf
}
interface StateProps {
username: string
telegrafs: AppState['telegrafs']['list']
tokens: AppState['tokens']['list']
collectors: Telegraf[]
}
type Props = StateProps & OwnProps
@ErrorHandling
export class TelegrafInstructionsOverlay extends PureComponent<Props> {
export class TelegrafInstructionsOverlay extends PureComponent<
StateProps & WithRouterProps
> {
public render() {
const {collector, visible, onDismiss} = this.props
return (
<WizardOverlay
visible={visible}
title="Telegraf Setup Instructions"
onDismiss={onDismiss}
>
<TelegrafInstructions
token={this.token}
configID={get(collector, 'id', '')}
/>
</WizardOverlay>
<GetResources resource={ResourceTypes.Authorizations}>
<WizardOverlay
title="Telegraf Setup Instructions"
onDismiss={this.handleDismiss}
>
<TelegrafInstructions
token={this.token}
configID={get(this.collector, 'id', '')}
/>
</WizardOverlay>
</GetResources>
)
}
private get token(): string {
const {collector, telegrafs, tokens} = this.props
const {telegrafs, tokens} = this.props
const config =
telegrafs.find(t => get(collector, 'id', '') === t.id) || collector
telegrafs.find(t => get(this.collector, 'id', '') === t.id) ||
this.collector
if (!config) {
return 'no config found'
@ -68,15 +67,36 @@ export class TelegrafInstructionsOverlay extends PureComponent<Props> {
return auth.token
}
private get collector() {
const {
params: {id},
collectors,
} = this.props
return collectors.find(c => c.id === id)
}
private handleDismiss = (): void => {
const {
router,
params: {orgID},
} = this.props
this.setState({
collectorID: null,
})
router.push(`/orgs/${orgID}/telegrafs/`)
}
}
const mstp = ({me: {name}, telegrafs, tokens}: AppState): StateProps => ({
username: name,
telegrafs: telegrafs.list,
tokens: tokens.list,
collectors: telegrafs.list,
})
export default connect<StateProps, {}, OwnProps>(
export default connect<StateProps, {}, {}>(
mstp,
null
)(TelegrafInstructionsOverlay)
)(withRouter<StateProps>(TelegrafInstructionsOverlay))

View File

@ -44,6 +44,7 @@ class TelegrafsPage extends PureComponent<StateProps> {
<GetResources resource={ResourceTypes.Buckets}>
<GetResources resource={ResourceTypes.Telegrafs}>
<Collectors />
{this.props.children}
</GetResources>
</GetResources>
</TabbedPageSection>
@ -52,7 +53,6 @@ class TelegrafsPage extends PureComponent<StateProps> {
</div>
</Page.Contents>
</Page>
{this.props.children}
</>
)
}