commit
74044ee63d
|
@ -15,24 +15,13 @@ 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'
|
||||
import {Links} from 'src/types/auth'
|
||||
|
||||
interface CurrentOrganization {
|
||||
name: string
|
||||
id: string
|
||||
}
|
||||
|
||||
interface ExternalLink {
|
||||
name: string
|
||||
url: string
|
||||
}
|
||||
interface ExternalLinks {
|
||||
custom: ExternalLink[]
|
||||
}
|
||||
interface Links {
|
||||
me: string
|
||||
external: ExternalLinks
|
||||
}
|
||||
|
||||
interface Props {
|
||||
organization: Organization
|
||||
currentOrganization: CurrentOrganization
|
||||
|
|
|
@ -9,7 +9,7 @@ import {ErrorHandling} from 'src/shared/decorators/errors'
|
|||
|
||||
import AllUsersTable from 'src/admin/components/chronograf/AllUsersTable'
|
||||
import {
|
||||
AuthLinks,
|
||||
Links,
|
||||
Organization,
|
||||
Role,
|
||||
User,
|
||||
|
@ -19,7 +19,7 @@ import {
|
|||
|
||||
interface Props {
|
||||
notify: (message: Notification | NotificationFunc) => void
|
||||
links: AuthLinks
|
||||
links: Links
|
||||
meID: string
|
||||
users: User[]
|
||||
organizations: Organization[]
|
||||
|
|
|
@ -6,7 +6,7 @@ import {errorThrown} from 'src/shared/actions/errors'
|
|||
|
||||
import {linksLink} from 'src/shared/constants'
|
||||
|
||||
import {AuthLinks} from 'src/types/auth'
|
||||
import {Links} from 'src/types/auth'
|
||||
|
||||
export enum ActionTypes {
|
||||
LinksGetRequested = 'LINKS_GET_REQUESTED',
|
||||
|
@ -23,11 +23,9 @@ const linksGetRequested = (): LinksGetRequestedAction => ({
|
|||
|
||||
export interface LinksGetCompletedAction {
|
||||
type: ActionTypes.LinksGetCompleted
|
||||
payload: {links: AuthLinks}
|
||||
payload: {links: Links}
|
||||
}
|
||||
export const linksGetCompleted = (
|
||||
links: AuthLinks
|
||||
): LinksGetCompletedAction => ({
|
||||
export const linksGetCompleted = (links: Links): LinksGetCompletedAction => ({
|
||||
type: ActionTypes.LinksGetCompleted,
|
||||
payload: {links},
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {AuthMe, AuthLink} from 'src/types/auth'
|
||||
import {Me, AuthLink} from 'src/types/auth'
|
||||
import {getMeRole} from 'src/shared/reducers/helpers/auth'
|
||||
import {getDeep} from 'src/utils/wrappers'
|
||||
|
||||
|
@ -6,7 +6,7 @@ import {ActionTypes} from 'src/shared/actions/auth'
|
|||
|
||||
interface State {
|
||||
links: AuthLink[] | null
|
||||
me: AuthMe | null
|
||||
me: Me | null
|
||||
isMeLoading: boolean
|
||||
isAuthLoading: boolean
|
||||
logoutLink: string | null
|
||||
|
@ -32,7 +32,7 @@ export const initialState = getInitialState()
|
|||
|
||||
const meGetCompleted = (
|
||||
state: State,
|
||||
{me}: {me: AuthMe},
|
||||
{me}: {me: Me},
|
||||
isUsingAuth: boolean
|
||||
): State => {
|
||||
let newMe = me
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import _ from 'lodash'
|
||||
|
||||
import {SUPERADMIN_ROLE, MEMBER_ROLE} from 'src/auth/Authorized'
|
||||
import {AuthMe} from 'src/types/auth'
|
||||
import {Me} from 'src/types/auth'
|
||||
|
||||
export const getMeRole = (me: AuthMe): string => {
|
||||
export const getMeRole = (me: Me): string => {
|
||||
const currentRoleOrg = me.roles.find(
|
||||
role => me.currentOrganization.id === role.organization
|
||||
)
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
// Libraries
|
||||
import classnames from 'classnames'
|
||||
import React, {PureComponent} from 'react'
|
||||
import {withRouter, WithRouterProps} from 'react-router'
|
||||
|
||||
// Types
|
||||
import {Me, Role} from 'src/types'
|
||||
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
interface OrgID {
|
||||
organization: string
|
||||
}
|
||||
|
||||
interface Props {
|
||||
me: Me
|
||||
role: Role
|
||||
meLink: string
|
||||
onMeChangeOrg: (meLink: string, orgID: OrgID) => void
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
class OrgLink extends PureComponent<Props & WithRouterProps> {
|
||||
public render() {
|
||||
const {role} = this.props
|
||||
|
||||
return (
|
||||
<span className={this.className} onClick={this.handleChangeOrganization}>
|
||||
{this.orgName} <strong>({role.name})</strong>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
private get orgName(): string {
|
||||
const {me, role} = this.props
|
||||
const org = me.organizations.find(o => o.id === role.organization)
|
||||
|
||||
if (!org) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return org.name
|
||||
}
|
||||
|
||||
private get isCurrentOrg(): boolean {
|
||||
const {me, role} = this.props
|
||||
return me.currentOrganization.id === role.organization
|
||||
}
|
||||
|
||||
private get className(): string {
|
||||
return classnames('sidebar-menu--item', {
|
||||
active: this.isCurrentOrg,
|
||||
})
|
||||
}
|
||||
|
||||
private handleChangeOrganization = async () => {
|
||||
const {router, meLink, onMeChangeOrg, role} = this.props
|
||||
try {
|
||||
await onMeChangeOrg(meLink, {organization: role.organization})
|
||||
router.push('')
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter<Props>(OrgLink)
|
|
@ -1,158 +0,0 @@
|
|||
import React, {Component} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
import {withRouter} from 'react-router'
|
||||
|
||||
import classnames from 'classnames'
|
||||
|
||||
import FancyScrollbar from 'shared/components/FancyScrollbar'
|
||||
|
||||
import {meChangeOrganizationAsync} from 'shared/actions/auth'
|
||||
|
||||
import {SUPERADMIN_ROLE} from 'src/auth/Authorized'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
@ErrorHandling
|
||||
class UserNavBlock extends Component {
|
||||
handleChangeCurrentOrganization = organizationID => async () => {
|
||||
const {router, links, meChangeOrganization} = this.props
|
||||
await meChangeOrganization(links.me, {organization: organizationID})
|
||||
router.push('')
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
logoutLink,
|
||||
links: {
|
||||
external: {custom: customLinks},
|
||||
},
|
||||
me,
|
||||
me: {currentOrganization, organizations, roles},
|
||||
me: {role},
|
||||
} = this.props
|
||||
|
||||
const isSuperAdmin = role === SUPERADMIN_ROLE
|
||||
|
||||
return (
|
||||
<div className="sidebar--item">
|
||||
<div className="sidebar--square">
|
||||
<div className="sidebar--icon icon user-outline" />
|
||||
{isSuperAdmin ? (
|
||||
<span className="sidebar--icon sidebar--icon__superadmin icon crown2" />
|
||||
) : null}
|
||||
</div>
|
||||
<div className="sidebar-menu sidebar-menu--user-nav">
|
||||
{customLinks ? (
|
||||
<div className="sidebar-menu--section sidebar-menu--section__custom-links">
|
||||
Custom Links
|
||||
</div>
|
||||
) : null}
|
||||
{customLinks
|
||||
? customLinks.map((link, i) => (
|
||||
<a
|
||||
key={i}
|
||||
className="sidebar-menu--item sidebar-menu--item__link-name"
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
>
|
||||
{link.name}
|
||||
</a>
|
||||
))
|
||||
: null}
|
||||
<div className="sidebar-menu--section sidebar-menu--section__switch-orgs">
|
||||
Switch Organizations
|
||||
</div>
|
||||
<FancyScrollbar
|
||||
className="sidebar-menu--scrollbar"
|
||||
autoHeight={true}
|
||||
maxHeight={100}
|
||||
autoHide={false}
|
||||
>
|
||||
{roles.map((r, i) => {
|
||||
const isLinkCurrentOrg = currentOrganization.id === r.organization
|
||||
return (
|
||||
<span
|
||||
key={i}
|
||||
className={classnames({
|
||||
'sidebar-menu--item': true,
|
||||
active: isLinkCurrentOrg,
|
||||
})}
|
||||
onClick={this.handleChangeCurrentOrganization(r.organization)}
|
||||
>
|
||||
{organizations.find(o => o.id === r.organization).name}{' '}
|
||||
<strong>({r.name})</strong>
|
||||
</span>
|
||||
)
|
||||
})}
|
||||
</FancyScrollbar>
|
||||
<div className="sidebar-menu--section sidebar-menu--section__account">
|
||||
Account
|
||||
</div>
|
||||
<div className="sidebar-menu--provider">
|
||||
<div>
|
||||
{me.scheme} / {me.provider}
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
className="sidebar-menu--item sidebar-menu--item__logout"
|
||||
href={logoutLink}
|
||||
>
|
||||
Log out
|
||||
</a>
|
||||
<div className="sidebar-menu--heading sidebar--no-hover">
|
||||
{me.name}
|
||||
</div>
|
||||
<div className="sidebar-menu--triangle" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const {arrayOf, func, shape, string} = PropTypes
|
||||
|
||||
UserNavBlock.propTypes = {
|
||||
router: shape({
|
||||
push: func.isRequired,
|
||||
}).isRequired,
|
||||
links: shape({
|
||||
me: string,
|
||||
external: shape({
|
||||
custom: arrayOf(
|
||||
shape({
|
||||
name: string.isRequired,
|
||||
url: string.isRequired,
|
||||
})
|
||||
),
|
||||
}),
|
||||
}),
|
||||
logoutLink: string.isRequired,
|
||||
me: shape({
|
||||
currentOrganization: shape({
|
||||
id: string.isRequired,
|
||||
name: string.isRequired,
|
||||
}),
|
||||
name: string,
|
||||
organizations: arrayOf(
|
||||
shape({
|
||||
id: string.isRequired,
|
||||
name: string.isRequired,
|
||||
})
|
||||
),
|
||||
roles: arrayOf(
|
||||
shape({
|
||||
id: string,
|
||||
name: string,
|
||||
})
|
||||
),
|
||||
role: string,
|
||||
}).isRequired,
|
||||
meChangeOrganization: func.isRequired,
|
||||
}
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
meChangeOrganization: bindActionCreators(meChangeOrganizationAsync, dispatch),
|
||||
})
|
||||
|
||||
export default connect(null, mapDispatchToProps)(withRouter(UserNavBlock))
|
|
@ -0,0 +1,117 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
|
||||
// Components
|
||||
import OrgLink from 'src/side_nav/components/OrgLink'
|
||||
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
||||
|
||||
// Actions
|
||||
import {meChangeOrganizationAsync} from 'src/shared/actions/auth'
|
||||
|
||||
// Constants
|
||||
import {SUPERADMIN_ROLE} from 'src/auth/Authorized'
|
||||
|
||||
// Types
|
||||
import {Me} from 'src/types'
|
||||
import {Links, ExternalLink} from 'src/types/auth'
|
||||
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
interface OrgID {
|
||||
organization: string
|
||||
}
|
||||
|
||||
interface Props {
|
||||
me: Me
|
||||
links: Links
|
||||
logoutLink: string
|
||||
meChangeOrg: (meLink: string, orgID: OrgID) => void
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
class UserNavBlock extends PureComponent<Props> {
|
||||
public render() {
|
||||
const {logoutLink, me, links, meChangeOrg} = this.props
|
||||
|
||||
return (
|
||||
<div className="sidebar--item">
|
||||
<div className="sidebar--square">
|
||||
<div className="sidebar--icon icon user-outline" />
|
||||
{this.isSuperAdmin && (
|
||||
<span className="sidebar--icon sidebar--icon__superadmin icon crown2" />
|
||||
)}
|
||||
</div>
|
||||
<div className="sidebar-menu sidebar-menu--user-nav">
|
||||
{!!this.customLinks && (
|
||||
<div className="sidebar-menu--section sidebar-menu--section__custom-links">
|
||||
Custom Links
|
||||
</div>
|
||||
)}
|
||||
{!!this.customLinks &&
|
||||
this.customLinks.map((link, i) => (
|
||||
<a
|
||||
key={i}
|
||||
className="sidebar-menu--item sidebar-menu--item__link-name"
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
>
|
||||
{link.name}
|
||||
</a>
|
||||
))}
|
||||
<div className="sidebar-menu--section sidebar-menu--section__switch-orgs">
|
||||
Switch Organizations
|
||||
</div>
|
||||
<FancyScrollbar
|
||||
className="sidebar-menu--scrollbar"
|
||||
autoHeight={true}
|
||||
maxHeight={100}
|
||||
autoHide={false}
|
||||
>
|
||||
{me.roles.map((r, i) => (
|
||||
<OrgLink
|
||||
onMeChangeOrg={meChangeOrg}
|
||||
meLink={links.me}
|
||||
key={i}
|
||||
me={me}
|
||||
role={r}
|
||||
/>
|
||||
))}
|
||||
</FancyScrollbar>
|
||||
<div className="sidebar-menu--section sidebar-menu--section__account">
|
||||
Account
|
||||
</div>
|
||||
<div className="sidebar-menu--provider">
|
||||
<div>
|
||||
{me.scheme} / {me.provider}
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
className="sidebar-menu--item sidebar-menu--item__logout"
|
||||
href={logoutLink}
|
||||
>
|
||||
Log out
|
||||
</a>
|
||||
<div className="sidebar-menu--heading sidebar--no-hover">
|
||||
{me.name}
|
||||
</div>
|
||||
<div className="sidebar-menu--triangle" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private get customLinks(): ExternalLink[] {
|
||||
return this.props.links.external.custom
|
||||
}
|
||||
|
||||
private get isSuperAdmin(): boolean {
|
||||
return this.props.me.role === SUPERADMIN_ROLE
|
||||
}
|
||||
}
|
||||
|
||||
const mdtp = {
|
||||
meChangeOrg: meChangeOrganizationAsync,
|
||||
}
|
||||
|
||||
export default connect(null, mdtp)(UserNavBlock)
|
|
@ -6,7 +6,12 @@ import _ from 'lodash'
|
|||
import {insecureSkipVerifyText} from 'src/shared/copy/tooltipText'
|
||||
|
||||
import {SUPERADMIN_ROLE} from 'src/auth/Authorized'
|
||||
import {Source, Me} from 'src/types'
|
||||
import {Source, Role, Organization} from 'src/types'
|
||||
|
||||
interface Me {
|
||||
role: Role
|
||||
currentOrganization: Organization
|
||||
}
|
||||
|
||||
interface Props {
|
||||
me: Me
|
||||
|
@ -33,7 +38,7 @@ export class SourceForm extends PureComponent<Props> {
|
|||
} = this.props
|
||||
return (
|
||||
<div className="panel-body">
|
||||
{isUsingAuth && isInitialSource && this.authIndicatior}
|
||||
{isUsingAuth && isInitialSource && this.authIndicator}
|
||||
<form onSubmit={onSubmit}>
|
||||
<div className="form-group col-xs-12 col-sm-6">
|
||||
<label htmlFor="connect-string">Connection String</label>
|
||||
|
@ -167,7 +172,7 @@ export class SourceForm extends PureComponent<Props> {
|
|||
)
|
||||
}
|
||||
|
||||
private get authIndicatior(): JSX.Element {
|
||||
private get authIndicator(): JSX.Element {
|
||||
const {me} = this.props
|
||||
return (
|
||||
<div className="text-center">
|
||||
|
|
|
@ -8,27 +8,14 @@ export interface Organization {
|
|||
}
|
||||
|
||||
export interface Me {
|
||||
role: Role
|
||||
currentOrganization?: Organization
|
||||
}
|
||||
|
||||
export interface AuthMe {
|
||||
id?: string
|
||||
role: string
|
||||
name: string
|
||||
provider: string
|
||||
scheme: string
|
||||
superAdmin: boolean
|
||||
logoutLink: string
|
||||
role: string
|
||||
scheme: string
|
||||
provider: string
|
||||
name: string
|
||||
roles: Role[]
|
||||
links: {
|
||||
self: string
|
||||
}
|
||||
organizations?: Organization[]
|
||||
currentOrganization?: Organization
|
||||
isUsingAuth: boolean
|
||||
isMeLoading: boolean
|
||||
isAuthLoading: boolean
|
||||
organizations: Organization[]
|
||||
}
|
||||
|
||||
export enum InfluxDBPermissions {
|
||||
|
@ -79,7 +66,7 @@ export interface User {
|
|||
superAdmin: boolean
|
||||
}
|
||||
|
||||
export interface Auth {
|
||||
export interface AuthLink {
|
||||
callback: string
|
||||
label: string
|
||||
login: string
|
||||
|
@ -92,15 +79,13 @@ export interface AuthConfig {
|
|||
self: string
|
||||
}
|
||||
|
||||
export interface AuthLinks {
|
||||
export interface Links {
|
||||
allUsers: string
|
||||
auth: Auth[]
|
||||
auth: AuthLink[]
|
||||
config: AuthConfig
|
||||
dashboards: string
|
||||
environment: string
|
||||
external: {
|
||||
statusFeed?: string
|
||||
}
|
||||
external: ExternalLinks
|
||||
layouts: string
|
||||
logout: string
|
||||
mappings: string
|
||||
|
@ -110,10 +95,12 @@ export interface AuthLinks {
|
|||
users: string
|
||||
}
|
||||
|
||||
export interface AuthLink {
|
||||
export interface ExternalLink {
|
||||
name: string
|
||||
label: string
|
||||
login: string
|
||||
logout: string
|
||||
callback: string
|
||||
url: string
|
||||
}
|
||||
|
||||
interface ExternalLinks {
|
||||
statusFeed?: string
|
||||
custom?: ExternalLink[]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {LayoutCell, LayoutQuery} from './layouts'
|
||||
import {Service, NewService} from './services'
|
||||
import {AuthLinks, Organization, Role, Permission, User, Me} from './auth'
|
||||
import {Links, Organization, Role, Permission, User, Me} from './auth'
|
||||
import {Cell, CellQuery, Legend, Axes, Dashboard, CellType} from './dashboards'
|
||||
import {
|
||||
Template,
|
||||
|
@ -54,7 +54,7 @@ import {WriteDataMode} from './dataExplorer'
|
|||
|
||||
export {
|
||||
Me,
|
||||
AuthLinks,
|
||||
Links,
|
||||
Role,
|
||||
User,
|
||||
Organization,
|
||||
|
|
Loading…
Reference in New Issue