From 149cd4a27ffeeed01f3a4884ed07490404db1b23 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Thu, 17 May 2018 12:22:24 -0700 Subject: [PATCH] Refactor InfluxTable and convert to ts --- ui/src/sources/components/ConnectionLink.tsx | 56 ++++ ui/src/sources/components/InfluxTable.js | 247 ------------------ ui/src/sources/components/InfluxTable.tsx | 71 +++++ ui/src/sources/components/InfluxTableHead.tsx | 28 ++ .../sources/components/InfluxTableHeader.tsx | 47 ++++ ui/src/sources/components/InfluxTableRow.tsx | 98 +++++++ .../sources/components/KapacitorDropdown.tsx | 118 +++++++++ ui/src/sources/constants/index.js | 2 - ui/src/sources/constants/index.ts | 5 + ui/src/sources/containers/ManageSources.tsx | 4 +- ui/src/sources/{index.js => index.ts} | 0 11 files changed, 425 insertions(+), 251 deletions(-) create mode 100644 ui/src/sources/components/ConnectionLink.tsx delete mode 100644 ui/src/sources/components/InfluxTable.js create mode 100644 ui/src/sources/components/InfluxTable.tsx create mode 100644 ui/src/sources/components/InfluxTableHead.tsx create mode 100644 ui/src/sources/components/InfluxTableHeader.tsx create mode 100644 ui/src/sources/components/InfluxTableRow.tsx create mode 100644 ui/src/sources/components/KapacitorDropdown.tsx delete mode 100644 ui/src/sources/constants/index.js create mode 100644 ui/src/sources/constants/index.ts rename ui/src/sources/{index.js => index.ts} (100%) diff --git a/ui/src/sources/components/ConnectionLink.tsx b/ui/src/sources/components/ConnectionLink.tsx new file mode 100644 index 0000000000..3d6807e00b --- /dev/null +++ b/ui/src/sources/components/ConnectionLink.tsx @@ -0,0 +1,56 @@ +import React, {PureComponent} from 'react' +import {Link} from 'react-router' +import Authorized, {EDITOR_ROLE} from 'src/auth/Authorized' + +import {Source} from 'src/types' + +interface Props { + source: Source + currentSource: Source +} + +class ConnectionLink extends PureComponent { + public render() { + const {source} = this.props + return ( +
+ {source.name}} + > + + {source.name} + {this.default} + + +
+ ) + } + + private get className(): string { + if (this.isCurrentSource) { + return 'link-success' + } + + return '' + } + + private get default(): string { + const {source} = this.props + if (source.default) { + return ' (Default)' + } + + return '' + } + + private get isCurrentSource(): boolean { + const {source, currentSource} = this.props + return source.id === currentSource.id + } +} + +export default ConnectionLink diff --git a/ui/src/sources/components/InfluxTable.js b/ui/src/sources/components/InfluxTable.js deleted file mode 100644 index 6aa79be845..0000000000 --- a/ui/src/sources/components/InfluxTable.js +++ /dev/null @@ -1,247 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import {Link, withRouter} from 'react-router' -import {connect} from 'react-redux' - -import Authorized, {EDITOR_ROLE} from 'src/auth/Authorized' - -import Dropdown from 'shared/components/Dropdown' -import QuestionMarkTooltip from 'shared/components/QuestionMarkTooltip' -import ConfirmButton from 'shared/components/ConfirmButton' - -const kapacitorDropdown = ( - kapacitors, - source, - router, - setActiveKapacitor, - handleDeleteKapacitor -) => { - if (!kapacitors || kapacitors.length === 0) { - return ( - - - Add Kapacitor Connection - - - ) - } - const kapacitorItems = kapacitors.map(k => { - return { - text: k.name, - resource: `/sources/${source.id}/kapacitors/${k.id}`, - kapacitor: k, - } - }) - - const activeKapacitor = kapacitors.find(k => k.active) - - let selected = '' - if (activeKapacitor) { - selected = activeKapacitor.name - } else { - selected = kapacitorItems[0].text - } - - const unauthorizedDropdown = ( -
{selected}
- ) - - return ( - - { - router.push(`${item.resource}/edit`) - }, - }, - { - icon: 'trash', - text: 'delete', - handler: item => { - handleDeleteKapacitor(item.kapacitor) - }, - confirmable: true, - }, - ]} - selected={selected} - /> - - ) -} - -const InfluxTable = ({ - source, - router, - sources, - location, - setActiveKapacitor, - handleDeleteSource, - handleDeleteKapacitor, - isUsingAuth, - me, -}) => { - return ( -
-
-
-
-

- {isUsingAuth ? ( - - Connections for {me.currentOrganization.name} - - ) : ( - Connections - )} -

- - - Add Connection - - -
-
- - - - - - - - - {sources.map(s => { - return ( - - - - - - - ) - })} - -
- InfluxDB Connection - - Kapacitor Connection{' '} - Kapacitor Connections are
scoped per InfluxDB Connection.
Only one can be active at a time.

' - } - /> -
- {s.id === source.id ? ( -
- Connected -
- ) : ( - - Connect - - )} -
-
- {s.name} - } - > - - {s.name} - {s.default ? ' (Default)' : null} - - -
- {s.url} -
- - - - - {kapacitorDropdown( - s.kapacitors, - s, - router, - setActiveKapacitor, - handleDeleteKapacitor - )} -
-
-
-
-
- ) -} - -const {array, bool, func, shape, string} = PropTypes - -InfluxTable.propTypes = { - handleDeleteSource: func.isRequired, - location: shape({ - pathname: string.isRequired, - }).isRequired, - router: PropTypes.shape({ - push: PropTypes.func.isRequired, - }).isRequired, - source: shape({ - id: string.isRequired, - links: shape({ - proxy: string.isRequired, - self: string.isRequired, - }), - }), - sources: array.isRequired, - setActiveKapacitor: func.isRequired, - handleDeleteKapacitor: func.isRequired, - me: shape({ - currentOrganization: shape({ - id: string.isRequired, - name: string.isRequired, - }), - }), - isUsingAuth: bool, -} - -const mapStateToProps = ({auth: {isUsingAuth, me}}) => ({isUsingAuth, me}) - -export default connect(mapStateToProps)(withRouter(InfluxTable)) diff --git a/ui/src/sources/components/InfluxTable.tsx b/ui/src/sources/components/InfluxTable.tsx new file mode 100644 index 0000000000..09e5499929 --- /dev/null +++ b/ui/src/sources/components/InfluxTable.tsx @@ -0,0 +1,71 @@ +import React, {PureComponent} from 'react' +import {connect} from 'react-redux' + +import {SetActiveKapacitor, DeleteKapacitor} from 'src/shared/actions/sources' + +import InfluxTableHead from 'src/sources/components/InfluxTableHead' +import InfluxTableHeader from 'src/sources/components/InfluxTableHeader' +import InfluxTableRow from 'src/sources/components/InfluxTableRow' + +import {Source, Me} from 'src/types' + +interface Props { + me: Me + source: Source + sources: Source[] + isUsingAuth: boolean + deleteKapacitor: DeleteKapacitor + setActiveKapacitor: SetActiveKapacitor + onDeleteSource: (source: Source) => () => void +} + +class InfluxTable extends PureComponent { + public render() { + const { + source, + sources, + setActiveKapacitor, + onDeleteSource, + deleteKapacitor, + isUsingAuth, + me, + } = this.props + + return ( +
+
+
+ +
+ + + + {sources.map(s => { + return ( + + ) + })} + +
+
+
+
+
+ ) + } +} + +const mapStateToProps = ({auth: {isUsingAuth, me}}) => ({isUsingAuth, me}) + +export default connect(mapStateToProps)(InfluxTable) diff --git a/ui/src/sources/components/InfluxTableHead.tsx b/ui/src/sources/components/InfluxTableHead.tsx new file mode 100644 index 0000000000..7f80b3b03c --- /dev/null +++ b/ui/src/sources/components/InfluxTableHead.tsx @@ -0,0 +1,28 @@ +import React, {SFC, ReactElement} from 'react' + +import QuestionMarkTooltip from 'src/shared/components/QuestionMarkTooltip' + +import {KAPACITOR_TOOLTIP_COPY} from 'src/sources/constants' + +const InfluxTableHead: SFC<{}> = (): ReactElement< + HTMLTableHeaderCellElement +> => { + return ( + + + + InfluxDB Connection + + + Kapacitor Connection + + + + + ) +} + +export default InfluxTableHead diff --git a/ui/src/sources/components/InfluxTableHeader.tsx b/ui/src/sources/components/InfluxTableHeader.tsx new file mode 100644 index 0000000000..ede002de09 --- /dev/null +++ b/ui/src/sources/components/InfluxTableHeader.tsx @@ -0,0 +1,47 @@ +import React, {PureComponent, ReactElement} from 'react' +import {Link} from 'react-router' + +import Authorized, {EDITOR_ROLE} from 'src/auth/Authorized' + +import {Me, Source} from 'src/types' + +interface Props { + me: Me + source: Source + isUsingAuth: boolean +} + +class InfluxTableHeader extends PureComponent { + public render() { + const {source} = this.props + + return ( +
+

{this.title}

+ + + Add Connection + + +
+ ) + } + + private get title(): ReactElement { + const {isUsingAuth, me} = this.props + if (isUsingAuth) { + return ( + + Connections for {me.currentOrganization.name} + + ) + } + + return Connections + } +} + +export default InfluxTableHeader diff --git a/ui/src/sources/components/InfluxTableRow.tsx b/ui/src/sources/components/InfluxTableRow.tsx new file mode 100644 index 0000000000..c0f6a0c748 --- /dev/null +++ b/ui/src/sources/components/InfluxTableRow.tsx @@ -0,0 +1,98 @@ +import React, {PureComponent, ReactElement} from 'react' +import {Link} from 'react-router' + +import * as actions from 'src/shared/actions/sources' + +import Authorized, {EDITOR_ROLE} from 'src/auth/Authorized' +import ConfirmButton from 'src/shared/components/ConfirmButton' +import KapacitorDropdown from 'src/sources/components/KapacitorDropdown' +import ConnectionLink from 'src/sources/components/ConnectionLink' + +import {Source} from 'src/types' + +interface Props { + source: Source + currentSource: Source + onDeleteSource: (source: Source) => void + setActiveKapacitor: actions.SetActiveKapacitor + deleteKapacitor: actions.DeleteKapacitor +} + +class InfluxTableRow extends PureComponent { + public render() { + const { + source, + currentSource, + setActiveKapacitor, + deleteKapacitor, + } = this.props + + return ( + + {this.connectButton} + + + {source.url} + + + + + + + + + + + ) + } + + private handleDeleteSource = (): void => { + this.props.onDeleteSource(this.props.source) + } + + private get connectButton(): ReactElement { + const {source} = this.props + if (this.isCurrentSource) { + return ( +
+ Connected +
+ ) + } + + return ( + + Connect + + ) + } + + private get className(): string { + if (this.isCurrentSource) { + return 'hightlight' + } + + return '' + } + + private get isCurrentSource(): boolean { + const {source, currentSource} = this.props + return source.id === currentSource.id + } +} + +export default InfluxTableRow diff --git a/ui/src/sources/components/KapacitorDropdown.tsx b/ui/src/sources/components/KapacitorDropdown.tsx new file mode 100644 index 0000000000..6451f0acd6 --- /dev/null +++ b/ui/src/sources/components/KapacitorDropdown.tsx @@ -0,0 +1,118 @@ +import React, {PureComponent, ReactElement} from 'react' +import {Link, withRouter, RouteComponentProps} from 'react-router' + +import Dropdown from 'src/shared/components/Dropdown' +import Authorized, {EDITOR_ROLE} from 'src/auth/Authorized' +import {Source, Kapacitor} from 'src/types' +import {SetActiveKapacitor} from 'src/shared/actions/sources' + +interface Props { + source: Source + kapacitors: Kapacitor[] + setActiveKapacitor: SetActiveKapacitor + deleteKapacitor: (Kapacitor: Kapacitor) => void +} + +interface KapacitorItem { + text: string + resource: string + kapacitor: Kapacitor +} + +class KapacitorDropdown extends PureComponent< + Props & RouteComponentProps +> { + public render() { + const {source, router, setActiveKapacitor, deleteKapacitor} = this.props + + if (this.isKapacitorsEmpty) { + return ( + + + Add Kapacitor Connection + + + ) + } + + return ( + + { + router.push(`${item.resource}/edit`) + }, + }, + { + icon: 'trash', + text: 'delete', + handler: item => { + deleteKapacitor(item.kapacitor) + }, + confirmable: true, + }, + ]} + selected={this.selected} + /> + + ) + } + + private get UnauthorizedDropdown(): ReactElement { + return ( +
{this.selected}
+ ) + } + + private get isKapacitorsEmpty(): boolean { + const {kapacitors} = this.props + return !kapacitors || kapacitors.length === 0 + } + + private get kapacitorItems(): KapacitorItem[] { + const {kapacitors, source} = this.props + + return kapacitors.map(k => { + return { + text: k.name, + resource: `/sources/${source.id}/kapacitors/${k.id}`, + kapacitor: k, + } + }) + } + + private get activeKapacitor(): Kapacitor { + return this.props.kapacitors.find(k => k.active) + } + + private get selected(): string { + let selected = '' + if (this.activeKapacitor) { + selected = this.activeKapacitor.name + } else { + selected = this.kapacitorItems[0].text + } + + return selected + } +} + +export default withRouter(KapacitorDropdown) diff --git a/ui/src/sources/constants/index.js b/ui/src/sources/constants/index.js deleted file mode 100644 index d98cdfbd2b..0000000000 --- a/ui/src/sources/constants/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export const REQUIRED_ROLE_COPY = - 'The minimum Role a user must have
in order to access this source.' diff --git a/ui/src/sources/constants/index.ts b/ui/src/sources/constants/index.ts new file mode 100644 index 0000000000..8e2b6e87fa --- /dev/null +++ b/ui/src/sources/constants/index.ts @@ -0,0 +1,5 @@ +export const REQUIRED_ROLE_COPY = + 'The minimum Role a user must have
in order to access this source.' + +export const KAPACITOR_TOOLTIP_COPY = + '

Kapacitor Connections are
scoped per InfluxDB Connection.
Only one can be active at a time.

' diff --git a/ui/src/sources/containers/ManageSources.tsx b/ui/src/sources/containers/ManageSources.tsx index a823c1e6f1..41d42ca564 100644 --- a/ui/src/sources/containers/ManageSources.tsx +++ b/ui/src/sources/containers/ManageSources.tsx @@ -65,8 +65,8 @@ class ManageSources extends PureComponent {

Chronograf Version: {VERSION}

diff --git a/ui/src/sources/index.js b/ui/src/sources/index.ts similarity index 100% rename from ui/src/sources/index.js rename to ui/src/sources/index.ts