Convert admin components to have proper error handling

pull/10616/head
Brandon Farmer 2018-04-17 10:53:13 -07:00
parent 217c60ec31
commit 278a532401
36 changed files with 108 additions and 8 deletions

View File

@ -8,10 +8,14 @@
],
"presets": ["env", "react", "stage-0"],
"env": {
"development": {
"plugins": ["transform-decorators-legacy"]
},
"production": {
"plugins": [
"transform-react-remove-prop-types"
"transform-react-remove-prop-types",
"transform-decorators-legacy"
]
},
}
}
}

View File

@ -12,8 +12,7 @@
"build": "yarn run clean && webpack --config ./webpack/prod.config.js",
"build:dev": "webpack --config ./webpack/dev.config.js",
"build:vendor": "webpack --config webpack/vendor.config.js",
"start":
"yarn run clean && yarn run build:vendor && webpack --watch --config ./webpack/dev.config.js --progress",
"start": "yarn run clean && yarn run build:vendor && webpack --watch --config ./webpack/dev.config.js --progress",
"start:fast": "webpack --watch --config ./webpack/dev.config.js",
"start:hmr": "webpack-dev-server --open --config ./webpack/dev.config.js",
"lint": "esw src/",
@ -23,8 +22,7 @@
"clean": "rm -rf ./build/*",
"eslint:fix": "eslint src --fix",
"tslint:fix": "tslint --fix -c ./tslint.json '{src,test}/**/*.ts?(x)'",
"prettier":
"prettier --single-quote --trailing-comma es5 --bracket-spacing false --semi false --write \"{src,spec}/**/*.js\"",
"prettier": "prettier --single-quote --trailing-comma es5 --bracket-spacing false --semi false --write \"{src,spec}/**/*.js\"",
"lint:fix": "yarn run prettier && yarn run eslint:fix && yarn run tslint:fix",
"eslint-check": "eslint --print-config .eslintrc | eslint-config-prettier-check"
},

View File

@ -3,7 +3,9 @@ import PropTypes from 'prop-types'
import OnClickOutside from 'shared/components/OnClickOutside'
import ConfirmOrCancel from 'shared/components/ConfirmOrCancel'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class ChangePassRow extends Component {
constructor(props) {
super(props)

View File

@ -11,7 +11,9 @@ import {formatRPDuration} from 'utils/formatting'
import ConfirmButton from 'shared/components/ConfirmButton'
import {DATABASE_TABLE} from 'src/admin/constants/tableSizing'
import {notifyRetentionPolicyCantHaveEmptyFields} from 'shared/copy/notifications'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class DatabaseRow extends Component {
constructor(props) {
super(props)

View File

@ -1,6 +1,8 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class FilterBar extends Component {
constructor(props) {
super(props)

View File

@ -2,7 +2,9 @@ import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {ROLES_TABLE} from 'src/admin/constants/tableSizing'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class RoleEditingRow extends Component {
constructor(props) {
super(props)

View File

@ -2,7 +2,9 @@ import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {USERS_TABLE} from 'src/admin/constants/tableSizing'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class UserEditName extends Component {
constructor(props) {
super(props)

View File

@ -2,7 +2,9 @@ import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {USERS_TABLE} from 'src/admin/constants/tableSizing'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class UserNewPassword extends Component {
handleKeyPress = user => {
return e => {

View File

@ -6,6 +6,7 @@ import MultiSelectDropdown from 'src/shared/components/MultiSelectDropdown'
import {USERS_TABLE} from 'src/admin/constants/tableSizing'
import {User} from 'src/types/influxAdmin'
import {ErrorHandling} from 'src/shared/decorators/errors'
interface Props {
user: User
@ -13,6 +14,7 @@ interface Props {
onUpdatePermissions: (user: User, permissions: any[]) => void
}
@ErrorHandling
class UserPermissionsDropdown extends PureComponent<Props> {
public render() {
return (

View File

@ -7,6 +7,7 @@ import MultiSelectDropdown from 'src/shared/components/MultiSelectDropdown'
import {USERS_TABLE} from 'src/admin/constants/tableSizing'
import {User, UserRole} from 'src/types/influxAdmin'
import {ErrorHandling} from 'src/shared/decorators/errors'
interface Props {
user: User
@ -14,6 +15,7 @@ interface Props {
onUpdateRoles: (user: User, roles: UserRole[]) => void
}
@ErrorHandling
class UserRoleDropdown extends PureComponent<Props> {
public render() {
const {allRoles} = this.props

View File

@ -8,6 +8,7 @@ import {USERS_TABLE} from 'src/admin/constants/tableSizing'
import UserRowEdit from 'src/admin/components/UserRowEdit'
import {User} from 'src/types/influxAdmin'
import {ErrorHandling} from 'src/shared/decorators/errors'
interface UserRowProps {
user: User
@ -25,6 +26,7 @@ interface UserRowProps {
onUpdatePassword: (user: User, password: string) => void
}
@ErrorHandling
class UserRow extends PureComponent<UserRowProps> {
public render() {
const {

View File

@ -8,6 +8,8 @@ import AllUsersTableRowNew from 'src/admin/components/chronograf/AllUsersTableRo
import AllUsersTableRow from 'src/admin/components/chronograf/AllUsersTableRow'
import {ALL_USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
import {ErrorHandling} from 'src/shared/decorators/errors'
const {
colOrganizations,
colProvider,
@ -21,6 +23,7 @@ import {
notifyChronografUserRemovedFromOrg,
} from 'shared/copy/notifications'
@ErrorHandling
class AllUsersTable extends Component {
constructor(props) {
super(props)

View File

@ -6,6 +6,7 @@ import SlideToggle from 'src/shared/components/SlideToggle'
import ConfirmButton from 'src/shared/components/ConfirmButton'
import {ALL_USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
import {ErrorHandling} from 'src/shared/decorators/errors'
const {
colOrganizations,
@ -44,6 +45,7 @@ interface Props {
organizations: Organization[]
}
@ErrorHandling
export default class AllUsersTableRow extends PureComponent<Props> {
public render() {
const {

View File

@ -5,6 +5,7 @@ import {bindActionCreators} from 'redux'
import {notify as notifyAction} from 'shared/actions/notifications'
import Dropdown from 'shared/components/Dropdown'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {notifyChronografUserMissingNameAndProvider} from 'shared/copy/notifications'
import {ALL_USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
@ -19,6 +20,7 @@ const {
const nullOrganization = {id: undefined, name: 'None'}
const nullRole = {name: '*', organization: undefined}
@ErrorHandling
class AllUsersTableRowNew extends Component {
constructor(props) {
super(props)

View File

@ -6,7 +6,9 @@ import _ from 'lodash'
import OrganizationsTableRow from 'src/admin/components/chronograf/OrganizationsTableRow'
import OrganizationsTableRowNew from 'src/admin/components/chronograf/OrganizationsTableRowNew'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class OrganizationsTable extends Component {
constructor(props) {
super(props)

View File

@ -11,6 +11,7 @@ import InputClickToEdit from 'src/shared/components/InputClickToEdit'
import {meChangeOrganizationAsync} from 'src/shared/actions/auth'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {DEFAULT_ORG_ID} from 'src/admin/constants/chronografAdmin'
import {USER_ROLES} from 'src/admin/constants/chronografAdmin'
import {Organization} from 'src/types'
@ -43,6 +44,7 @@ interface Props {
router: InjectedRouter
}
@ErrorHandling
class OrganizationsTableRow extends PureComponent<Props, {}> {
public shouldComponentUpdate(nextProps) {
return !_.isEqual(this.props, nextProps)

View File

@ -6,7 +6,9 @@ import Dropdown from 'shared/components/Dropdown'
import {USER_ROLES} from 'src/admin/constants/chronografAdmin'
import {MEMBER_ROLE} from 'src/auth/Authorized'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class OrganizationsTableRowNew extends Component {
constructor(props) {
super(props)

View File

@ -4,7 +4,9 @@ import PropTypes from 'prop-types'
import uuid from 'uuid'
import ProvidersTableRow from 'src/admin/components/chronograf/ProvidersTableRow'
import ProvidersTableRowNew from 'src/admin/components/chronograf/ProvidersTableRowNew'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class ProvidersTable extends Component {
constructor(props) {
super(props)

View File

@ -6,7 +6,9 @@ import Dropdown from 'shared/components/Dropdown'
import InputClickToEdit from 'shared/components/InputClickToEdit'
import {DEFAULT_MAPPING_ID} from 'src/admin/constants/chronografAdmin'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class ProvidersTableRow extends Component {
constructor(props) {
super(props)

View File

@ -3,6 +3,7 @@ import React, {PureComponent} from 'react'
import ConfirmOrCancel from 'src/shared/components/ConfirmOrCancel'
import Dropdown from 'src/shared/components/Dropdown'
import InputClickToEdit from 'src/shared/components/InputClickToEdit'
import {ErrorHandling} from 'src/shared/decorators/errors'
interface Organization {
id: string
@ -28,6 +29,7 @@ interface State {
organizationId: string
}
@ErrorHandling
class ProvidersTableRowNew extends PureComponent<Props, State> {
constructor(props) {
super(props)

View File

@ -9,7 +9,9 @@ import UsersTableRowNew from 'src/admin/components/chronograf/UsersTableRowNew'
import UsersTableRow from 'src/admin/components/chronograf/UsersTableRow'
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class UsersTable extends Component {
constructor(props) {
super(props)

View File

@ -1,6 +1,8 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class UsersTableHeader extends Component {
constructor(props) {
super(props)

View File

@ -3,6 +3,7 @@ import React, {PureComponent} from 'react'
import Dropdown from 'src/shared/components/Dropdown'
import ConfirmButton from 'src/shared/components/ConfirmButton'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {USER_ROLES} from 'src/admin/constants/chronografAdmin'
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
import {User, Role} from 'src/types'
@ -25,6 +26,7 @@ interface Props {
meID: string
}
@ErrorHandling
class UsersTableRow extends PureComponent<Props> {
public render() {
const {user, onChangeUserRole} = this.props

View File

@ -7,10 +7,12 @@ import {notify as notifyAction} from 'shared/actions/notifications'
import Dropdown from 'shared/components/Dropdown'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {notifyChronografUserMissingNameAndProvider} from 'shared/copy/notifications'
import {USERS_TABLE} from 'src/admin/constants/chronografTableSizing'
import {USER_ROLES} from 'src/admin/constants/chronografAdmin'
@ErrorHandling
class UsersTableRowNew extends Component {
constructor(props) {
super(props)

View File

@ -28,6 +28,7 @@ import {
import AdminTabs from 'src/admin/components/AdminTabs'
import SourceIndicator from 'shared/components/SourceIndicator'
import FancyScrollbar from 'shared/components/FancyScrollbar'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {notify as notifyAction} from 'shared/actions/notifications'
@ -46,6 +47,7 @@ const isValidRole = role => {
return role.name.length >= minLen
}
@ErrorHandling
class AdminInfluxDBPage extends Component {
constructor(props) {
super(props)

View File

@ -8,6 +8,7 @@ import DatabaseManager from 'src/admin/components/DatabaseManager'
import * as adminActionCreators from 'src/admin/actions/influxdb'
import {notify as notifyAction} from 'shared/actions/notifications'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {
notifyDatabaseDeleteConfirmationRequired,
@ -15,6 +16,7 @@ import {
notifyDatabaseNameInvalid,
} from 'shared/copy/notifications'
@ErrorHandling
class DatabaseManagerPage extends Component {
constructor(props) {
super(props)

View File

@ -7,7 +7,9 @@ import * as adminChronografActionCreators from 'src/admin/actions/chronograf'
import {notify as notifyAction} from 'shared/actions/notifications'
import ProvidersTable from 'src/admin/components/chronograf/ProvidersTable'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class ProvidersPage extends Component {
constructor(props) {
super(props)

View File

@ -13,6 +13,7 @@ import showDatabasesParser from 'shared/parsing/showDatabases'
import showQueriesParser from 'shared/parsing/showQueries'
import {TIMES} from 'src/admin/constants'
import {notifyQueriesError} from 'shared/copy/notifications'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {
loadQueries as loadQueriesAction,
@ -22,6 +23,7 @@ import {
import {notify as notifyAction} from 'shared/actions/notifications'
@ErrorHandling
class QueriesPage extends Component {
componentDidMount() {
this.updateQueries()

View File

@ -5,6 +5,7 @@ import {bindActionCreators} from 'redux'
import * as adminChronografActionCreators from 'src/admin/actions/chronograf'
import * as configActionCreators from 'src/shared/actions/config'
import {notify as notifyAction} from 'src/shared/actions/notifications'
import {ErrorHandling} from 'src/shared/decorators/errors'
import AllUsersTable from 'src/admin/components/chronograf/AllUsersTable'
import {AuthLinks, Organization, Role, User} from 'src/types'
@ -38,6 +39,7 @@ interface State {
isLoading: boolean
}
@ErrorHandling
export class AllUsersPage extends PureComponent<Props, State> {
constructor(props) {
super(props)

View File

@ -5,9 +5,11 @@ import {bindActionCreators} from 'redux'
import * as adminChronografActionCreators from 'src/admin/actions/chronograf'
import {getMeAsync} from 'shared/actions/auth'
import {ErrorHandling} from 'src/shared/decorators/errors'
import OrganizationsTable from 'src/admin/components/chronograf/OrganizationsTable'
@ErrorHandling
class OrganizationsPage extends Component {
componentDidMount() {
const {links, actionsAdmin: {loadOrganizationsAsync}} = this.props

View File

@ -5,9 +5,11 @@ import {bindActionCreators} from 'redux'
import * as adminChronografActionCreators from 'src/admin/actions/chronograf'
import {notify as notifyAction} from 'shared/actions/notifications'
import {ErrorHandling} from 'src/shared/decorators/errors'
import UsersTable from 'src/admin/components/chronograf/UsersTable'
@ErrorHandling
class UsersPage extends PureComponent {
constructor(props) {
super(props)

View File

@ -3,6 +3,7 @@ import React, {PureComponent} from 'react'
import QueryEditor from './QueryEditor'
import SchemaExplorer from 'src/shared/components/SchemaExplorer'
import {Source, Query} from 'src/types'
import {ErrorHandling} from 'src/shared/decorators/errors'
const rawTextBinder = (links, id, action) => text =>
action(links.queries, id, text)
@ -15,6 +16,7 @@ interface Props {
initialGroupByTime: string
}
@ErrorHandling
class QueryMaker extends PureComponent<Props> {
public render() {
const {

View File

@ -1,6 +1,7 @@
import React, {PureComponent, SFC} from 'react'
import {Link} from 'react-router'
import _ from 'lodash'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {AlertRule, Source} from 'src/types'
@ -65,6 +66,7 @@ const KapacitorRulesTable: SFC<KapacitorRulesTableProps> = ({
</table>
)
@ErrorHandling
export class RuleRow extends PureComponent<RuleRowProps> {
constructor(props) {
super(props)

View File

@ -7,6 +7,8 @@ import {MultiGrid, ColumnSizer} from 'react-virtualized'
import moment from 'moment'
import {reduce} from 'fast.js'
const {arrayOf, bool, shape, string, func} = PropTypes
import {
timeSeriesToTableGraph,
processTableData,
@ -26,7 +28,9 @@ import {
import {generateThresholdsListHexs} from 'shared/constants/colorOperations'
import {colorsStringSchema} from 'shared/schemas'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ErrorHandling
class TableGraph extends Component {
constructor(props) {
super(props)
@ -387,8 +391,6 @@ class TableGraph extends Component {
}
}
const {arrayOf, bool, shape, string, func} = PropTypes
TableGraph.propTypes = {
data: arrayOf(shape()),
tableOptions: shape({

View File

@ -0,0 +1,32 @@
import React from 'react'
export function ErrorHandling<
P,
S,
T extends {new (...args: any[]): React.Component<P, S>}
>(constructor: T) {
class Wrapped extends constructor {
private error: boolean = false
public componentDidCatch(error, info) {
console.error(error)
console.error(info)
this.error = true
this.forceUpdate()
}
public render() {
if (this.error) {
return (
<p className="error">
A Chronograf error has occurred. Please report the issue
<a href="https://github.com/influxdata/chronograf/issues">here</a>
</p>
)
}
return super.render()
}
}
return Wrapped
}

View File

@ -117,6 +117,7 @@ module.exports = {
loader: 'babel-loader',
options: {
presets: ['env', 'react', 'stage-0'],
plugins: ['transform-decorators-legacy'],
cacheDirectory: true, // use a cache directory to speed up compilation
},
},