Merge pull request #5956 from influxdata/5953/keep_tabs_in_detail_pages
feat(ui): Add InfluxDB admin tabs to user/role detail pagepull/5965/head
commit
38ee6bbad9
|
@ -10,6 +10,7 @@
|
|||
1. [#5927](https://github.com/influxdata/chronograf/pull/5927): Show effective permissions on Users page.
|
||||
1. [#5929](https://github.com/influxdata/chronograf/pull/5926): Add refresh button to InfluxDB Users/Roles/Databases page.
|
||||
1. [#5940](https://github.com/influxdata/chronograf/pull/5940): Support InfluxDB behind proxy under subpath.
|
||||
1. [#5956](https://github.com/influxdata/chronograf/pull/5956): Add InfluxDB admin tabs to user/role detail page.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
|
|
|
@ -107,7 +107,8 @@ describe('InfluxDB', () => {
|
|||
.contains('Create')
|
||||
.should('not.be.disabled')
|
||||
.click({force: true})
|
||||
cy.getByTestID('exit--button').click({force: true})
|
||||
cy.url().should('match', new RegExp(`${influxDB.user.name}$`))
|
||||
cy.get('.subsection--tab.active').click({force: true})
|
||||
cy.getByTestID(`user-row--${influxDB.user.name}`).should('exist')
|
||||
cy.getByTestID('user-filter--input').type('Non existing user')
|
||||
cy.getByTestID(`user-row--${influxDB.user.name}`).should('not.exist')
|
||||
|
@ -133,6 +134,12 @@ describe('InfluxDB', () => {
|
|||
})
|
||||
|
||||
cy.getByTestID('apply-changes--button').click({force: true})
|
||||
cy.url().should('match', /users$/)
|
||||
cy.getByTestID(`user-row--${influxDB.user.name}`)
|
||||
.should('exist')
|
||||
.within(() => {
|
||||
cy.get('a').contains(influxDB.user.name).click({force: true})
|
||||
})
|
||||
cy.getByTestID(`${influxDB.db.name}-permissions--row`).within(() => {
|
||||
influxDB.user.db[0].permissions.forEach((permission: any) => {
|
||||
cy.getByTestID(
|
||||
|
@ -149,7 +156,7 @@ describe('InfluxDB', () => {
|
|||
cy.getByTestID('change-password--button').click({force: true})
|
||||
cy.getByTestID('new-password--input').type(influxDB.user.password)
|
||||
cy.getByTestID('confirm').click({force: true})
|
||||
cy.getByTestID('exit--button').click({force: true})
|
||||
cy.get('.subsection--tab.active').click({force: true})
|
||||
cy.getByTestID(`user-row--${influxDB.user.name}`).within(() => {
|
||||
cy.getByTestID('permissions--values').within(() => {
|
||||
cy.getByTestID('read-permission').should('have.class', 'granted')
|
||||
|
@ -176,7 +183,8 @@ describe('InfluxDB', () => {
|
|||
.contains('Create')
|
||||
.should('not.be.disabled')
|
||||
.click({force: true})
|
||||
cy.getByTestID('exit--button').click({force: true})
|
||||
cy.url().should('match', new RegExp(`${influxDB.user.name}$`))
|
||||
cy.get('.subsection--tab.active').click({force: true})
|
||||
cy.get('.dropdown--selected').click({force: true})
|
||||
cy.getByTestID('dropdown-menu').within(() => {
|
||||
cy.getByTestID('dropdown--item')
|
||||
|
@ -202,11 +210,17 @@ describe('InfluxDB', () => {
|
|||
'value-changed'
|
||||
)
|
||||
cy.getByTestID('apply-changes--button').click({force: true})
|
||||
cy.url().should('match', new RegExp(`users$`))
|
||||
cy.getByTestID(`user-row--${influxDB.user.name}`)
|
||||
.should('exist')
|
||||
.within(() => {
|
||||
cy.get('a').contains(influxDB.user.name).click({force: true})
|
||||
})
|
||||
cy.getByTestID(`role-${influxDB.role.name}--button`).should(
|
||||
'not.have.class',
|
||||
'value-changed'
|
||||
)
|
||||
cy.getByTestID('exit--button').click({force: true})
|
||||
cy.get('.subsection--tab.active').click({force: true})
|
||||
cy.getByTestID('roles-granted').within(() => {
|
||||
cy.get('.role-value').contains(influxDB.role.name).should('exist')
|
||||
})
|
||||
|
@ -236,7 +250,8 @@ describe('InfluxDB', () => {
|
|||
cy.getByTestID('form--create-role--button')
|
||||
.should('not.be.disabled')
|
||||
.click()
|
||||
cy.getByTestID('exit--button').click({force: true})
|
||||
cy.url().should('match', new RegExp(`${influxDB.role.name}$`))
|
||||
cy.get('.subsection--tab.active').click({force: true})
|
||||
cy.getByTestID(`role-${influxDB.role.name}--row`)
|
||||
.should('exist')
|
||||
.within(() => {
|
||||
|
@ -260,6 +275,10 @@ describe('InfluxDB', () => {
|
|||
})
|
||||
|
||||
cy.getByTestID('apply-changes--button').click({force: true})
|
||||
cy.url().should('match',new RegExp(`roles$`))
|
||||
cy.getByTestID(`role-${influxDB.role.name}--row`).within(() => {
|
||||
cy.get('a').contains(influxDB.role.name).click({force: true})
|
||||
})
|
||||
|
||||
cy.getByTestID(`${influxDB.db.name}-db-perm--row`).within(() => {
|
||||
influxDB.role.permissions.forEach((perm: any) => {
|
||||
|
@ -270,7 +289,8 @@ describe('InfluxDB', () => {
|
|||
})
|
||||
})
|
||||
|
||||
cy.getByTestID('exit--button').click({force: true})
|
||||
cy.get('.subsection--tab.active').click({force: true})
|
||||
cy.url().should('match',new RegExp(`roles$`))
|
||||
cy.getByTestID('wizard-bucket-selected').click({force: true})
|
||||
cy.getByTestID('dropdown-menu').within(() => {
|
||||
cy.getByTestID('dropdown--item')
|
||||
|
@ -296,7 +316,7 @@ describe('InfluxDB', () => {
|
|||
cy.getByTestID('show-users--toggle').click()
|
||||
cy.getByTestID('admin-table--head').within(() => {
|
||||
cy.get('th').contains('Users').should('exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -410,11 +410,13 @@ export const updateRoleUsersAsync = (role, users) => async dispatch => {
|
|||
const {data} = await updateRoleAJAX(role.links.self, {users})
|
||||
dispatch(notify(notifyRoleUsersUpdated()))
|
||||
dispatch(syncRole(role, data))
|
||||
return true
|
||||
} catch (error) {
|
||||
dispatch(
|
||||
errorThrown(error, notifyRoleUsersUpdateFailed(error.data.message))
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export const updateRolePermissionsAsync = (
|
||||
|
@ -425,11 +427,13 @@ export const updateRolePermissionsAsync = (
|
|||
const {data} = await updateRoleAJAX(role.links.self, {permissions})
|
||||
dispatch(notify(notifyRolePermissionsUpdated()))
|
||||
dispatch(syncRole(role, data))
|
||||
return true
|
||||
} catch (error) {
|
||||
dispatch(
|
||||
errorThrown(error, notifyRolePermissionsUpdateFailed(error.data.message))
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export const updateUserPermissionsAsync = (
|
||||
|
@ -440,6 +444,7 @@ export const updateUserPermissionsAsync = (
|
|||
const {data} = await updateUserAJAX(user.links.self, {permissions})
|
||||
dispatch(notify(notifyDBUserPermissionsUpdated()))
|
||||
dispatch(syncUser(user, data))
|
||||
return true
|
||||
} catch (error) {
|
||||
dispatch(
|
||||
errorThrown(
|
||||
|
@ -455,11 +460,13 @@ export const updateUserRolesAsync = (user, roles) => async dispatch => {
|
|||
const {data} = await updateUserAJAX(user.links.self, {roles})
|
||||
dispatch(notify(notifyDBUserRolesUpdated()))
|
||||
dispatch(syncUser(user, data))
|
||||
return true
|
||||
} catch (error) {
|
||||
dispatch(
|
||||
errorThrown(error, notifyDBUserRolesUpdateFailed(error.data.message))
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export const updateUserPasswordAsync = (user, password) => async dispatch => {
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
Form,
|
||||
OverlayContainer,
|
||||
OverlayHeading,
|
||||
OverlayTechnology,
|
||||
} from 'src/reusable_ui'
|
||||
|
||||
const minLen = 3
|
||||
export function validateRoleName(name: string): boolean {
|
||||
return name?.length >= minLen
|
||||
}
|
||||
|
||||
interface Props {
|
||||
onCancel: () => void
|
||||
onOK: () => void
|
||||
visible: boolean
|
||||
}
|
||||
const ConfirmDiscardDialog = ({visible, onOK, onCancel}: Props) => {
|
||||
return (
|
||||
<OverlayTechnology visible={visible}>
|
||||
<OverlayContainer maxWidth={400}>
|
||||
<OverlayHeading title="Discard unsaved changes?" />
|
||||
<div
|
||||
className="overlay--body"
|
||||
style={{minHeight: '100px', padding: '0px'}}
|
||||
>
|
||||
<form>
|
||||
<Form>
|
||||
{[
|
||||
<Form.Footer key={1}>
|
||||
<div className="form-group text-center col-xs-12">
|
||||
<button
|
||||
className="btn btn-sm btn-warning"
|
||||
type="button"
|
||||
onClick={onOK}
|
||||
data-test="confirm--ok--button"
|
||||
>
|
||||
OK
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-sm btn-default"
|
||||
onClick={onCancel}
|
||||
type="button"
|
||||
data-test="confirm--cancel--button"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</Form.Footer>,
|
||||
]}
|
||||
</Form>
|
||||
</form>
|
||||
</div>
|
||||
</OverlayContainer>
|
||||
</OverlayTechnology>
|
||||
)
|
||||
}
|
||||
|
||||
export default ConfirmDiscardDialog
|
|
@ -2,12 +2,14 @@ import React from 'react'
|
|||
import {useMemo} from 'react'
|
||||
import SubSections from 'src/shared/components/SubSections'
|
||||
import {Source, SourceAuthenticationMethod} from 'src/types'
|
||||
import {PageSection} from 'src/types/shared'
|
||||
import {WrapToPage} from './AdminInfluxDBScopedPage'
|
||||
|
||||
interface Props {
|
||||
source: Source
|
||||
activeTab: 'databases' | 'users' | 'roles' | 'queries'
|
||||
children: JSX.Element | JSX.Element[]
|
||||
onTabChange?: (section: PageSection, url: string) => void
|
||||
}
|
||||
export function hasRoleManagement(source: Source) {
|
||||
return !!source?.links?.roles
|
||||
|
@ -16,7 +18,12 @@ export function isConnectedToLDAP(source: Source) {
|
|||
return source.authentication === SourceAuthenticationMethod.LDAP
|
||||
}
|
||||
|
||||
const AdminInfluxDBTabbedPage = ({source, activeTab, children}: Props) => {
|
||||
export const AdminTabs = ({
|
||||
source,
|
||||
activeTab,
|
||||
children,
|
||||
onTabChange,
|
||||
}: Props) => {
|
||||
const sections = useMemo(() => {
|
||||
const hasRoles = hasRoleManagement(source)
|
||||
const isLDAP = isConnectedToLDAP(source)
|
||||
|
@ -43,17 +50,34 @@ const AdminInfluxDBTabbedPage = ({source, activeTab, children}: Props) => {
|
|||
},
|
||||
]
|
||||
}, [source])
|
||||
return (
|
||||
<SubSections
|
||||
parentUrl="admin-influxdb"
|
||||
sourceID={source.id}
|
||||
activeSection={activeTab}
|
||||
sections={sections}
|
||||
position="top"
|
||||
onTabChange={onTabChange}
|
||||
>
|
||||
{children}
|
||||
</SubSections>
|
||||
)
|
||||
}
|
||||
const AdminInfluxDBTabbedPage = ({
|
||||
source,
|
||||
activeTab,
|
||||
children,
|
||||
onTabChange,
|
||||
}: Props) => {
|
||||
return (
|
||||
<WrapToPage hideRefresh={activeTab === 'queries'}>
|
||||
<SubSections
|
||||
parentUrl="admin-influxdb"
|
||||
sourceID={source.id}
|
||||
activeSection={activeTab}
|
||||
sections={sections}
|
||||
position="top"
|
||||
<AdminTabs
|
||||
source={source}
|
||||
activeTab={activeTab}
|
||||
onTabChange={onTabChange}
|
||||
>
|
||||
{children}
|
||||
</SubSections>
|
||||
</AdminTabs>
|
||||
</WrapToPage>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,11 @@ import {connect, ResolveThunks} from 'react-redux'
|
|||
import {withSource} from 'src/CheckSources'
|
||||
import {Source} from 'src/types'
|
||||
import {Database, User, UserPermission, UserRole} from 'src/types/influxAdmin'
|
||||
import {hasRoleManagement, isConnectedToLDAP} from './AdminInfluxDBTabbedPage'
|
||||
import {
|
||||
AdminTabs,
|
||||
hasRoleManagement,
|
||||
isConnectedToLDAP,
|
||||
} from './AdminInfluxDBTabbedPage'
|
||||
import {withRouter, WithRouterProps} from 'react-router'
|
||||
import {useMemo} from 'react'
|
||||
import ConfirmButton from 'src/shared/components/ConfirmButton'
|
||||
|
@ -22,6 +26,7 @@ import {
|
|||
computePermissionsChange,
|
||||
toUserPermissions,
|
||||
} from '../../util/permissions'
|
||||
import ConfirmDiscardDialog from 'src/admin/components/influxdb/ConfirmDiscardDialog'
|
||||
|
||||
const FAKE_ROLE: UserRole = {
|
||||
name: '',
|
||||
|
@ -148,7 +153,7 @@ const RolePage = ({
|
|||
const changePermissions = useMemo(
|
||||
() => async () => {
|
||||
if (Object.entries(changedPermissions).length === 0) {
|
||||
return
|
||||
return true
|
||||
}
|
||||
setRunning(true)
|
||||
try {
|
||||
|
@ -157,7 +162,7 @@ const RolePage = ({
|
|||
roleDBPermissions,
|
||||
changedPermissions
|
||||
)
|
||||
await updatePermissionsAsync(role, permissions)
|
||||
return await updatePermissionsAsync(role, permissions)
|
||||
} finally {
|
||||
setRunning(false)
|
||||
}
|
||||
|
@ -201,7 +206,7 @@ const RolePage = ({
|
|||
const changeUsers = useMemo(
|
||||
() => async () => {
|
||||
if (Object.entries(changedUsersRecord).length === 0) {
|
||||
return
|
||||
return true
|
||||
}
|
||||
setRunning(true)
|
||||
try {
|
||||
|
@ -216,7 +221,7 @@ const RolePage = ({
|
|||
}
|
||||
return acc
|
||||
}, [])
|
||||
await updateUsersAsync(role, newUsers)
|
||||
return await updateUsersAsync(role, newUsers)
|
||||
} finally {
|
||||
setRunning(false)
|
||||
}
|
||||
|
@ -228,13 +233,14 @@ const RolePage = ({
|
|||
permissionsChanged,
|
||||
usersChanged,
|
||||
])
|
||||
const changeData = useCallback(async () => {
|
||||
await changeUsers()
|
||||
await changePermissions()
|
||||
}, [changePermissions, changeUsers])
|
||||
const exitHandler = useCallback(() => {
|
||||
router.push(`/sources/${sourceID}/admin-influxdb/roles`)
|
||||
}, [router, source])
|
||||
const changeData = useCallback(async () => {
|
||||
if ((await changeUsers()) && (await changePermissions())) {
|
||||
exitHandler()
|
||||
}
|
||||
}, [changePermissions, changeUsers, exitHandler])
|
||||
const databaseNames = useMemo<string[]>(
|
||||
() =>
|
||||
databases.reduce(
|
||||
|
@ -246,6 +252,25 @@ const RolePage = ({
|
|||
),
|
||||
[databases]
|
||||
)
|
||||
|
||||
const [exitUrl, setExitUrl] = useState('')
|
||||
const onTabChange = useCallback(
|
||||
(_section, url) => {
|
||||
if (dataChanged) {
|
||||
setExitUrl(url)
|
||||
return
|
||||
}
|
||||
router.push(url)
|
||||
},
|
||||
[router, dataChanged]
|
||||
)
|
||||
const onExitCancel = useCallback(() => {
|
||||
setExitUrl('')
|
||||
}, [])
|
||||
const onExitConfirm = useCallback(() => {
|
||||
router.push(exitUrl)
|
||||
}, [router, exitUrl])
|
||||
|
||||
const body =
|
||||
role === FAKE_ROLE ? (
|
||||
<div className="container-fluid">
|
||||
|
@ -375,7 +400,7 @@ const RolePage = ({
|
|||
<Page className="influxdb-admin">
|
||||
<Page.Header fullWidth={true}>
|
||||
<Page.Header.Left>
|
||||
<Page.Title title="Manage Role" />
|
||||
<Page.Title title="InfluxDB Role" />
|
||||
</Page.Header.Left>
|
||||
<Page.Header.Right showSourceIndicator={true}>
|
||||
{dataChanged ? (
|
||||
|
@ -402,7 +427,16 @@ const RolePage = ({
|
|||
)}
|
||||
</Page.Header.Right>
|
||||
</Page.Header>
|
||||
<div className="influxdb-admin--contents">{body}</div>
|
||||
<div className="influxdb-admin--contents">
|
||||
<AdminTabs activeTab="roles" source={source} onTabChange={onTabChange}>
|
||||
<ConfirmDiscardDialog
|
||||
onOK={onExitConfirm}
|
||||
onCancel={onExitCancel}
|
||||
visible={!!exitUrl}
|
||||
/>
|
||||
{body}
|
||||
</AdminTabs>
|
||||
</div>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,11 @@ import {connect, ResolveThunks} from 'react-redux'
|
|||
import {withSource} from 'src/CheckSources'
|
||||
import {Source} from 'src/types'
|
||||
import {Database, User, UserPermission, UserRole} from 'src/types/influxAdmin'
|
||||
import {hasRoleManagement, isConnectedToLDAP} from './AdminInfluxDBTabbedPage'
|
||||
import {
|
||||
AdminTabs,
|
||||
hasRoleManagement,
|
||||
isConnectedToLDAP,
|
||||
} from './AdminInfluxDBTabbedPage'
|
||||
import {withRouter, WithRouterProps} from 'react-router'
|
||||
import {useMemo} from 'react'
|
||||
import ConfirmButton from 'src/shared/components/ConfirmButton'
|
||||
|
@ -24,6 +28,7 @@ import {
|
|||
computePermissionsChange,
|
||||
toUserPermissions,
|
||||
} from '../../util/permissions'
|
||||
import ConfirmDiscardDialog from 'src/admin/components/influxdb/ConfirmDiscardDialog'
|
||||
|
||||
const FAKE_USER: User = {
|
||||
name: '',
|
||||
|
@ -179,7 +184,7 @@ const UserPage = ({
|
|||
const changePermissions = useMemo(
|
||||
() => async () => {
|
||||
if (Object.entries(changedPermissions).length === 0) {
|
||||
return
|
||||
return true
|
||||
}
|
||||
setRunning(true)
|
||||
try {
|
||||
|
@ -189,7 +194,7 @@ const UserPage = ({
|
|||
changedPermissions,
|
||||
isEnterprise ? [] : user.permissions.filter(x => x.scope === 'all')
|
||||
)
|
||||
await updatePermissionsAsync(user, permissions)
|
||||
return await updatePermissionsAsync(user, permissions)
|
||||
} finally {
|
||||
setRunning(false)
|
||||
}
|
||||
|
@ -236,7 +241,7 @@ const UserPage = ({
|
|||
const changeRoles = useMemo(
|
||||
() => async () => {
|
||||
if (Object.entries(changedRolesRecord).length === 0) {
|
||||
return
|
||||
return true
|
||||
}
|
||||
setRunning(true)
|
||||
try {
|
||||
|
@ -251,7 +256,7 @@ const UserPage = ({
|
|||
}
|
||||
return acc
|
||||
}, [])
|
||||
await updateRolesAsync(user, newRoles)
|
||||
return await updateRolesAsync(user, newRoles)
|
||||
} finally {
|
||||
setRunning(false)
|
||||
}
|
||||
|
@ -263,13 +268,14 @@ const UserPage = ({
|
|||
permissionsChanged,
|
||||
rolesChanged,
|
||||
])
|
||||
const changeData = useCallback(async () => {
|
||||
await changeRoles()
|
||||
await changePermissions()
|
||||
}, [changePermissions, changeRoles])
|
||||
const exitHandler = useCallback(() => {
|
||||
router.push(`/sources/${sourceID}/admin-influxdb/users`)
|
||||
}, [router, source])
|
||||
const changeData = useCallback(async () => {
|
||||
if ((await changeRoles()) && (await changePermissions())) {
|
||||
exitHandler()
|
||||
}
|
||||
}, [changePermissions, changeRoles, exitHandler])
|
||||
const databaseNames = useMemo<string[]>(
|
||||
() =>
|
||||
databases.reduce(
|
||||
|
@ -281,6 +287,24 @@ const UserPage = ({
|
|||
),
|
||||
[isEnterprise, databases]
|
||||
)
|
||||
|
||||
const [exitUrl, setExitUrl] = useState('')
|
||||
const onTabChange = useCallback(
|
||||
(_section, url) => {
|
||||
if (dataChanged) {
|
||||
setExitUrl(url)
|
||||
return
|
||||
}
|
||||
router.push(url)
|
||||
},
|
||||
[router, dataChanged]
|
||||
)
|
||||
const onExitCancel = useCallback(() => {
|
||||
setExitUrl('')
|
||||
}, [])
|
||||
const onExitConfirm = useCallback(() => {
|
||||
router.push(exitUrl)
|
||||
}, [router, exitUrl])
|
||||
const body =
|
||||
user === FAKE_USER ? (
|
||||
<div className="container-fluid">
|
||||
|
@ -480,7 +504,7 @@ const UserPage = ({
|
|||
<Page className="influxdb-admin">
|
||||
<Page.Header fullWidth={true}>
|
||||
<Page.Header.Left>
|
||||
<Page.Title title="Manage User" />
|
||||
<Page.Title title="InfluxDB User" />
|
||||
</Page.Header.Left>
|
||||
<Page.Header.Right showSourceIndicator={true}>
|
||||
{dataChanged ? (
|
||||
|
@ -489,7 +513,7 @@ const UserPage = ({
|
|||
confirmText="Discard unsaved changes?"
|
||||
confirmAction={exitHandler}
|
||||
position="left"
|
||||
testId="exit--button"
|
||||
testId="discard-changes--exit--button"
|
||||
/>
|
||||
) : (
|
||||
<Button text="Exit" onClick={exitHandler} testId="exit--button" />
|
||||
|
@ -507,7 +531,16 @@ const UserPage = ({
|
|||
)}
|
||||
</Page.Header.Right>
|
||||
</Page.Header>
|
||||
<div className="influxdb-admin--contents">{body}</div>
|
||||
<div className="influxdb-admin--contents">
|
||||
<AdminTabs activeTab="users" source={source} onTabChange={onTabChange}>
|
||||
<ConfirmDiscardDialog
|
||||
onOK={onExitConfirm}
|
||||
onCancel={onExitCancel}
|
||||
visible={!!exitUrl}
|
||||
/>
|
||||
{body}
|
||||
</AdminTabs>
|
||||
</div>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ $overlay-min-height: 150px;
|
|||
@extend %overlay-styles;
|
||||
z-index: 1;
|
||||
opacity: 0;
|
||||
transition: opacity 0.25s ease;
|
||||
// transition: opacity 1.25s ease; // some defect in Chrome causes to randomly go to opacity 1 (ConfirmDiscardDialog)
|
||||
@include gradient-diag-down($c-pool,$c-comet);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ interface Props extends WithRouterProps {
|
|||
parentUrl: string
|
||||
children?: ReactNode
|
||||
position?: 'left' | 'top'
|
||||
onTabChange?: (section: PageSection, url: string) => void
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
|
@ -55,7 +56,7 @@ class SubSections extends Component<Props> {
|
|||
<SubSectionsTab
|
||||
key={i}
|
||||
section={section}
|
||||
handleClick={this.handleTabClick(section.url)}
|
||||
handleClick={this.handleTabClick(section)}
|
||||
activeSection={activeSection}
|
||||
/>
|
||||
)
|
||||
|
@ -75,9 +76,14 @@ class SubSections extends Component<Props> {
|
|||
return found?.component || children || <NotFound />
|
||||
}
|
||||
|
||||
public handleTabClick = (url: string) => () => {
|
||||
const {router, sourceID, parentUrl} = this.props
|
||||
router.push(`/sources/${sourceID}/${parentUrl}/${url}`)
|
||||
public handleTabClick = (section: PageSection) => () => {
|
||||
const {router, sourceID, parentUrl, onTabChange} = this.props
|
||||
const url = `/sources/${sourceID}/${parentUrl}/${section.url}`
|
||||
if (onTabChange) {
|
||||
onTabChange(section, url)
|
||||
return
|
||||
}
|
||||
router.push(url)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ pre.admin-table--query {
|
|||
height: calc(100vh - 150px);
|
||||
min-height: 10px;
|
||||
&.influxdb-admin--detail{
|
||||
height: calc(100vh - 120px);
|
||||
height: calc(100vh - 150px);
|
||||
padding: 10px 0 0;
|
||||
background-color: $g1-raven;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue