feat: route user to no orgs page (#16208)
* feat: route user to no orgs page * style: no orgs page * fix: eslint * fix: prettierpull/16228/head
parent
7b81ebaf4e
commit
3cca6be000
|
@ -0,0 +1,21 @@
|
|||
describe('Orgs', () => {
|
||||
beforeEach(() => {
|
||||
cy.flush()
|
||||
})
|
||||
|
||||
describe('when there is a user with no orgs', () => {
|
||||
beforeEach(() => {
|
||||
cy.signin().then(({body}) => {
|
||||
cy.deleteOrg(body.org.id)
|
||||
})
|
||||
|
||||
cy.visit('/')
|
||||
})
|
||||
|
||||
it('forwards the user to the No Orgs Page', () => {
|
||||
cy.url().should('contain', 'no-org')
|
||||
cy.contains('Sign In').click()
|
||||
cy.url().should('contain', 'signin')
|
||||
})
|
||||
})
|
||||
})
|
|
@ -8,6 +8,7 @@ import {
|
|||
createCell,
|
||||
createOrg,
|
||||
createSource,
|
||||
deleteOrg,
|
||||
flush,
|
||||
getByTestID,
|
||||
getByInputName,
|
||||
|
@ -48,6 +49,7 @@ declare global {
|
|||
createDashWithViewAndVar: typeof createDashWithViewAndVar
|
||||
createView: typeof createView
|
||||
createOrg: typeof createOrg
|
||||
deleteOrg: typeof deleteOrg
|
||||
flush: typeof flush
|
||||
getByTestID: typeof getByTestID
|
||||
getByInputName: typeof getByInputName
|
||||
|
|
|
@ -123,6 +123,13 @@ export const createOrg = (): Cypress.Chainable<Cypress.Response> => {
|
|||
})
|
||||
}
|
||||
|
||||
export const deleteOrg = (id: string): Cypress.Chainable<Cypress.Response> => {
|
||||
return cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/v2/orgs/${id}`,
|
||||
})
|
||||
}
|
||||
|
||||
export const createBucket = (
|
||||
orgID?: string,
|
||||
organization?: string,
|
||||
|
@ -452,6 +459,7 @@ Cypress.Commands.add('createView', createView)
|
|||
|
||||
// orgs
|
||||
Cypress.Commands.add('createOrg', createOrg)
|
||||
Cypress.Commands.add('deleteOrg', deleteOrg)
|
||||
|
||||
// buckets
|
||||
Cypress.Commands.add('createBucket', createBucket)
|
||||
|
|
|
@ -88,6 +88,7 @@ import NewRuleOverlay from 'src/alerting/components/notifications/NewRuleOverlay
|
|||
import EditRuleOverlay from 'src/alerting/components/notifications/EditRuleOverlay'
|
||||
import NewEndpointOverlay from 'src/alerting/components/endpoints/NewEndpointOverlay'
|
||||
import EditEndpointOverlay from 'src/alerting/components/endpoints/EditEndpointOverlay'
|
||||
import NoOrgsPage from 'src/organizations/containers/NoOrgsPage'
|
||||
|
||||
// Overlays
|
||||
import OverlayHandler, {
|
||||
|
@ -196,6 +197,7 @@ class Root extends PureComponent {
|
|||
<Route component={GetMe}>
|
||||
<Route component={GetOrganizations}>
|
||||
<Route path="/">
|
||||
<Route path="no-orgs" component={NoOrgsPage} />
|
||||
<IndexRoute component={RouteToOrg} />
|
||||
<Route path="orgs" component={App}>
|
||||
<Route path="new" component={CreateOrgOverlay} />
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// Libraries
|
||||
import React, {FC} from 'react'
|
||||
import {FunnelPage, Button, ComponentColor} from '@influxdata/clockface'
|
||||
import {withRouter, WithRouterProps} from 'react-router'
|
||||
import {connect} from 'react-redux'
|
||||
|
||||
// Types
|
||||
import {AppState} from 'src/types'
|
||||
|
||||
interface DispatchProps {
|
||||
me: AppState['me']
|
||||
}
|
||||
|
||||
type Props = DispatchProps & WithRouterProps
|
||||
|
||||
const NoOrgsPage: FC<Props> = ({router, me}) => {
|
||||
const handleClick = () => {
|
||||
router.push('/signin')
|
||||
}
|
||||
|
||||
return (
|
||||
<FunnelPage>
|
||||
<div className="cf-funnel-page--logo" data-testid="funnel-page--logo">
|
||||
<img
|
||||
src="https://influxdata.github.io/branding/img/downloads/influxdata-logo--full--white-alpha.png"
|
||||
width="170"
|
||||
/>
|
||||
</div>
|
||||
<h1 className="cf-funnel-page--title">Whoops!</h1>
|
||||
<p className="cf-funnel-page--subtitle">
|
||||
You don't belong to an organization.
|
||||
<br />
|
||||
Add user <strong>{`"${me.name}"`}</strong> to an organization to
|
||||
continue
|
||||
</p>
|
||||
<Button
|
||||
text="Sign In"
|
||||
color={ComponentColor.Primary}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
</FunnelPage>
|
||||
)
|
||||
}
|
||||
|
||||
const mstp = ({me}: AppState) => {
|
||||
return {me}
|
||||
}
|
||||
|
||||
export default connect(mstp)(withRouter(NoOrgsPage))
|
|
@ -6,8 +6,6 @@ import {WithRouterProps} from 'react-router'
|
|||
// Types
|
||||
import {AppState, Organization} from 'src/types'
|
||||
|
||||
// Decorators
|
||||
|
||||
interface StateProps {
|
||||
orgs: Organization[]
|
||||
org: {id?: string}
|
||||
|
@ -19,6 +17,11 @@ class RouteToOrg extends PureComponent<Props> {
|
|||
public componentDidMount() {
|
||||
const {orgs, router, org} = this.props
|
||||
|
||||
if (!orgs || !orgs.length) {
|
||||
router.push(`/no-orgs`)
|
||||
return
|
||||
}
|
||||
|
||||
// org from local storage
|
||||
if (org && org.id) {
|
||||
router.push(`/orgs/${org.id}`)
|
||||
|
|
Loading…
Reference in New Issue