Merge pull request #5944 from influxdata/5942/influxdb_admin_filter_redux
feat(ui/admin): remember state of influxdb users/roles filterspull/5949/head
commit
cbbd0ea829
|
@ -289,10 +289,14 @@ describe('InfluxDB', () => {
|
|||
cy.get('th').contains('Users').should('exist')
|
||||
})
|
||||
|
||||
cy.getByTestID('hide-users--toggle').click()
|
||||
cy.getByTestID('show-users--toggle').click()
|
||||
cy.getByTestID('admin-table--head').within(() => {
|
||||
cy.get('th').contains('Users').should('not.exist')
|
||||
})
|
||||
cy.getByTestID('show-users--toggle').click()
|
||||
cy.getByTestID('admin-table--head').within(() => {
|
||||
cy.get('th').contains('Users').should('exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -473,3 +473,18 @@ export const updateUserPasswordAsync = (user, password) => async dispatch => {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const changeSelectedDBs = (selectedDBs /* : string[] */) => ({
|
||||
type: 'INFLUXDB_CHANGE_SELECTED_DBS',
|
||||
payload: {
|
||||
selectedDBs,
|
||||
},
|
||||
})
|
||||
|
||||
export const changeShowUsers = () => ({
|
||||
type: 'INFLUXDB_CHANGE_SHOW_USERS',
|
||||
})
|
||||
|
||||
export const changeShowRoles = () => ({
|
||||
type: 'INFLUXDB_CHANGE_SHOW_ROLES',
|
||||
})
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import React from 'react'
|
||||
import {connect, ResolveThunks} from 'react-redux'
|
||||
import {changeSelectedDBs} from 'src/admin/actions/influxdb'
|
||||
import {MultiSelectDropdown} from 'src/reusable_ui'
|
||||
import {Database} from 'src/types/influxAdmin'
|
||||
|
||||
interface ConnectedProps {
|
||||
databases: Database[]
|
||||
selectedDBs: string[]
|
||||
}
|
||||
const mapStateToProps = ({adminInfluxDB: {databases, selectedDBs}}) => ({
|
||||
databases,
|
||||
selectedDBs,
|
||||
})
|
||||
const mapDispatchToProps = {
|
||||
setSelectedDBs: changeSelectedDBs,
|
||||
}
|
||||
type ReduxDispatchProps = ResolveThunks<typeof mapDispatchToProps>
|
||||
type Props = ConnectedProps & ReduxDispatchProps
|
||||
const MultiDBSelector = ({databases, selectedDBs, setSelectedDBs}: Props) => {
|
||||
return (
|
||||
<div className="db-selector">
|
||||
<MultiSelectDropdown
|
||||
onChange={setSelectedDBs}
|
||||
selectedIDs={selectedDBs}
|
||||
emptyText="<no database>"
|
||||
>
|
||||
{databases.reduce(
|
||||
(acc, db) => {
|
||||
acc.push(
|
||||
<MultiSelectDropdown.Item
|
||||
key={db.name}
|
||||
id={db.name}
|
||||
value={{id: db.name}}
|
||||
>
|
||||
{db.name}
|
||||
</MultiSelectDropdown.Item>
|
||||
)
|
||||
return acc
|
||||
},
|
||||
[
|
||||
<MultiSelectDropdown.Item id="*" key="*" value={{id: '*'}}>
|
||||
All Databases
|
||||
</MultiSelectDropdown.Item>,
|
||||
<MultiSelectDropdown.Divider id="" key="" />,
|
||||
]
|
||||
)}
|
||||
</MultiSelectDropdown>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(MultiDBSelector)
|
|
@ -142,7 +142,7 @@ const RolePage = ({
|
|||
)
|
||||
)
|
||||
},
|
||||
[roleDBPermissions, changedPermissions, setChangedPermissions]
|
||||
[roleDBPermissions, changedPermissions]
|
||||
)
|
||||
const permissionsChanged = !!Object.keys(changedPermissions).length
|
||||
const changePermissions = useMemo(
|
||||
|
|
|
@ -6,6 +6,7 @@ import {Source, NotificationAction} from 'src/types'
|
|||
import {UserRole, User, Database} from 'src/types/influxAdmin'
|
||||
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
||||
import {
|
||||
changeShowUsers,
|
||||
createRoleAsync,
|
||||
filterRoles as filterRolesAction,
|
||||
} from 'src/admin/actions/influxdb'
|
||||
|
@ -21,14 +22,14 @@ import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
|||
import NoEntities from 'src/admin/components/influxdb/NoEntities'
|
||||
import RoleRow from 'src/admin/components/RoleRow'
|
||||
import {useCallback} from 'react'
|
||||
import allOrParticularSelection from '../../util/allOrParticularSelection'
|
||||
import {computeEntitiesDBPermissions} from '../../util/computeEffectiveDBPermissions'
|
||||
import useDebounce from 'src/utils/useDebounce'
|
||||
import useChangeEffect from 'src/utils/useChangeEffect'
|
||||
import {ComponentSize, MultiSelectDropdown, SlideToggle} from 'src/reusable_ui'
|
||||
import {ComponentSize, SlideToggle} from 'src/reusable_ui'
|
||||
import CreateRoleDialog, {
|
||||
validateRoleName,
|
||||
} from 'src/admin/components/influxdb/CreateRoleDialog'
|
||||
import MultiDBSelector from 'src/admin/components/influxdb/MultiDBSelector'
|
||||
|
||||
const validateRole = (
|
||||
role: Pick<UserRole, 'name'>,
|
||||
|
@ -41,16 +42,22 @@ const validateRole = (
|
|||
return true
|
||||
}
|
||||
|
||||
const mapStateToProps = ({adminInfluxDB: {databases, users, roles}}) => ({
|
||||
const mapStateToProps = ({
|
||||
adminInfluxDB: {databases, users, roles, selectedDBs, showUsers, rolesFilter},
|
||||
}) => ({
|
||||
databases,
|
||||
users,
|
||||
roles,
|
||||
selectedDBs,
|
||||
showUsers,
|
||||
rolesFilter,
|
||||
})
|
||||
|
||||
const mapDispatchToProps = {
|
||||
filterRoles: filterRolesAction,
|
||||
createRole: createRoleAsync,
|
||||
notify: notifyAction,
|
||||
toggleShowUsers: changeShowUsers,
|
||||
}
|
||||
|
||||
interface OwnProps {
|
||||
|
@ -60,6 +67,9 @@ interface ConnectedProps {
|
|||
databases: Database[]
|
||||
users: User[]
|
||||
roles: UserRole[]
|
||||
selectedDBs: string[]
|
||||
showUsers: boolean
|
||||
rolesFilter: string
|
||||
}
|
||||
|
||||
type ReduxDispatchProps = ResolveThunks<typeof mapDispatchToProps>
|
||||
|
@ -71,30 +81,26 @@ const RolesPage = ({
|
|||
users,
|
||||
roles,
|
||||
databases,
|
||||
selectedDBs,
|
||||
showUsers,
|
||||
rolesFilter,
|
||||
router,
|
||||
filterRoles,
|
||||
createRole,
|
||||
toggleShowUsers,
|
||||
notify,
|
||||
}: Props) => {
|
||||
const rolesPage = useMemo(
|
||||
() => `/sources/${source.id}/admin-influxdb/roles`,
|
||||
[source]
|
||||
)
|
||||
// filter databases
|
||||
const [selectedDBs, setSelectedDBs] = useState<string[]>(['*'])
|
||||
// database columns
|
||||
const visibleDBNames = useMemo<string[]>(() => {
|
||||
if (selectedDBs.includes('*')) {
|
||||
return databases.map(db => db.name)
|
||||
}
|
||||
return selectedDBs
|
||||
}, [databases, selectedDBs])
|
||||
const changeSelectedDBs = useCallback(
|
||||
(newDBs: string[]) =>
|
||||
setSelectedDBs((oldDBs: string[]) => {
|
||||
return allOrParticularSelection(oldDBs, newDBs)
|
||||
}),
|
||||
[setSelectedDBs]
|
||||
)
|
||||
|
||||
// effective permissions
|
||||
const visibleRoles = useMemo(() => roles.filter(x => !x.hidden), [roles])
|
||||
|
@ -103,23 +109,14 @@ const RolesPage = ({
|
|||
[visibleDBNames, visibleRoles]
|
||||
)
|
||||
|
||||
// filter users
|
||||
const [filterText, setFilterText] = useState('')
|
||||
const changeFilterText = useCallback(e => setFilterText(e.target.value), [
|
||||
setFilterText,
|
||||
])
|
||||
// filter roles
|
||||
const [filterText, setFilterText] = useState(rolesFilter)
|
||||
const changeFilterText = useCallback(e => setFilterText(e.target.value), [])
|
||||
const debouncedFilterText = useDebounce(filterText, 200)
|
||||
useChangeEffect(() => {
|
||||
filterRoles(debouncedFilterText)
|
||||
}, [debouncedFilterText])
|
||||
|
||||
// hide users
|
||||
const [showUsers, setShowUsers] = useState(true)
|
||||
const changeHideUsers = useCallback(() => setShowUsers(!showUsers), [
|
||||
showUsers,
|
||||
setShowUsers,
|
||||
])
|
||||
|
||||
const [createVisible, setCreateVisible] = useState(false)
|
||||
const createNew = useCallback(
|
||||
async (role: {name: string}) => {
|
||||
|
@ -159,40 +156,13 @@ const RolesPage = ({
|
|||
/>
|
||||
<span className="icon search" />
|
||||
</div>
|
||||
<div className="db-selector">
|
||||
<MultiSelectDropdown
|
||||
onChange={changeSelectedDBs}
|
||||
selectedIDs={selectedDBs}
|
||||
emptyText="<no database>"
|
||||
>
|
||||
{databases.reduce(
|
||||
(acc, db) => {
|
||||
acc.push(
|
||||
<MultiSelectDropdown.Item
|
||||
key={db.name}
|
||||
id={db.name}
|
||||
value={{id: db.name}}
|
||||
>
|
||||
{db.name}
|
||||
</MultiSelectDropdown.Item>
|
||||
)
|
||||
return acc
|
||||
},
|
||||
[
|
||||
<MultiSelectDropdown.Item id="*" key="*" value={{id: '*'}}>
|
||||
All Databases
|
||||
</MultiSelectDropdown.Item>,
|
||||
<MultiSelectDropdown.Divider id="" key="" />,
|
||||
]
|
||||
)}
|
||||
</MultiSelectDropdown>
|
||||
</div>
|
||||
<MultiDBSelector />
|
||||
<div className="hide-roles-toggle">
|
||||
<SlideToggle
|
||||
active={showUsers}
|
||||
onChange={changeHideUsers}
|
||||
onChange={toggleShowUsers}
|
||||
size={ComponentSize.ExtraSmall}
|
||||
entity="users"
|
||||
dataTest="show-users--toggle"
|
||||
/>
|
||||
Show Users
|
||||
</div>
|
||||
|
|
|
@ -173,7 +173,7 @@ const UserPage = ({
|
|||
)
|
||||
)
|
||||
},
|
||||
[userDBPermissions, changedPermissions, setChangedPermissions]
|
||||
[userDBPermissions, changedPermissions]
|
||||
)
|
||||
const permissionsChanged = !!Object.keys(changedPermissions).length
|
||||
const changePermissions = useMemo(
|
||||
|
|
|
@ -5,6 +5,7 @@ import {Source, NotificationAction} from 'src/types'
|
|||
import {UserRole, User, Database} from 'src/types/influxAdmin'
|
||||
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
||||
import {
|
||||
changeShowRoles,
|
||||
createUserAsync,
|
||||
filterUsers as filterUsersAction,
|
||||
} from 'src/admin/actions/influxdb'
|
||||
|
@ -22,15 +23,14 @@ import NoEntities from 'src/admin/components/influxdb/NoEntities'
|
|||
import UserRow from 'src/admin/components/UserRow'
|
||||
import useDebounce from 'src/utils/useDebounce'
|
||||
import useChangeEffect from 'src/utils/useChangeEffect'
|
||||
import MultiSelectDropdown from 'src/reusable_ui/components/dropdowns/MultiSelectDropdown'
|
||||
import {ComponentSize, SlideToggle} from 'src/reusable_ui'
|
||||
import {computeEffectiveUserDBPermissions} from '../../util/computeEffectiveDBPermissions'
|
||||
import allOrParticularSelection from '../../util/allOrParticularSelection'
|
||||
import CreateUserDialog, {
|
||||
validatePassword,
|
||||
validateUserName,
|
||||
} from '../../components/influxdb/CreateUserDialog'
|
||||
import {withRouter, WithRouterProps} from 'react-router'
|
||||
import MultiDBSelector from 'src/admin/components/influxdb/MultiDBSelector'
|
||||
|
||||
const validateUser = (
|
||||
user: Pick<User, 'name' | 'password'>,
|
||||
|
@ -47,15 +47,21 @@ const validateUser = (
|
|||
return true
|
||||
}
|
||||
|
||||
const mapStateToProps = ({adminInfluxDB: {databases, users, roles}}) => ({
|
||||
const mapStateToProps = ({
|
||||
adminInfluxDB: {databases, users, roles, selectedDBs, showRoles, usersFilter},
|
||||
}) => ({
|
||||
databases,
|
||||
users,
|
||||
roles,
|
||||
selectedDBs,
|
||||
showRoles,
|
||||
usersFilter,
|
||||
})
|
||||
|
||||
const mapDispatchToProps = {
|
||||
filterUsers: filterUsersAction,
|
||||
createUser: createUserAsync,
|
||||
toggleShowRoles: changeShowRoles,
|
||||
notify: notifyAction,
|
||||
}
|
||||
|
||||
|
@ -66,6 +72,9 @@ interface ConnectedProps {
|
|||
databases: Database[]
|
||||
users: User[]
|
||||
roles: UserRole[]
|
||||
selectedDBs: string[]
|
||||
showRoles: boolean
|
||||
usersFilter: string
|
||||
}
|
||||
|
||||
type ReduxDispatchProps = ResolveThunks<typeof mapDispatchToProps>
|
||||
|
@ -77,9 +86,13 @@ const UsersPage = ({
|
|||
databases,
|
||||
users,
|
||||
roles,
|
||||
selectedDBs,
|
||||
showRoles,
|
||||
usersFilter,
|
||||
notify,
|
||||
createUser,
|
||||
filterUsers,
|
||||
toggleShowRoles,
|
||||
}: Props) => {
|
||||
const [isEnterprise, usersPage] = useMemo(
|
||||
() => [
|
||||
|
@ -88,21 +101,13 @@ const UsersPage = ({
|
|||
],
|
||||
[source]
|
||||
)
|
||||
// filter databases
|
||||
const [selectedDBs, setSelectedDBs] = useState<string[]>(['*'])
|
||||
// database columns
|
||||
const visibleDBNames = useMemo<string[]>(() => {
|
||||
if (selectedDBs.includes('*')) {
|
||||
return databases.map(db => db.name)
|
||||
}
|
||||
return selectedDBs
|
||||
}, [databases, selectedDBs])
|
||||
const changeSelectedDBs = useCallback(
|
||||
(newDBs: string[]) =>
|
||||
setSelectedDBs((oldDBs: string[]) => {
|
||||
return allOrParticularSelection(oldDBs, newDBs)
|
||||
}),
|
||||
[setSelectedDBs]
|
||||
)
|
||||
|
||||
// effective permissions
|
||||
const visibleUsers = useMemo(() => users.filter(x => !x.hidden), [users])
|
||||
|
@ -113,22 +118,13 @@ const UsersPage = ({
|
|||
)
|
||||
|
||||
// filter users
|
||||
const [filterText, setFilterText] = useState('')
|
||||
const changeFilterText = useCallback(e => setFilterText(e.target.value), [
|
||||
setFilterText,
|
||||
])
|
||||
const [filterText, setFilterText] = useState(usersFilter)
|
||||
const changeFilterText = useCallback(e => setFilterText(e.target.value), [])
|
||||
const debouncedFilterText = useDebounce(filterText, 200)
|
||||
useChangeEffect(() => {
|
||||
filterUsers(debouncedFilterText)
|
||||
}, [debouncedFilterText])
|
||||
|
||||
// hide role
|
||||
const [showRoles, setShowRoles] = useState(true)
|
||||
const changeHideRoles = useCallback(() => setShowRoles(!showRoles), [
|
||||
showRoles,
|
||||
setShowRoles,
|
||||
])
|
||||
|
||||
const [createVisible, setCreateVisible] = useState(false)
|
||||
const createNew = useCallback(
|
||||
async (user: {name: string; password: string}) => {
|
||||
|
@ -169,39 +165,12 @@ const UsersPage = ({
|
|||
/>
|
||||
<span className="icon search" />
|
||||
</div>
|
||||
<div className="db-selector" data-test="db-selector">
|
||||
<MultiSelectDropdown
|
||||
onChange={changeSelectedDBs}
|
||||
selectedIDs={selectedDBs}
|
||||
emptyText="<no database>"
|
||||
>
|
||||
{databases.reduce(
|
||||
(acc, db) => {
|
||||
acc.push(
|
||||
<MultiSelectDropdown.Item
|
||||
key={db.name}
|
||||
id={db.name}
|
||||
value={{id: db.name}}
|
||||
>
|
||||
{db.name}
|
||||
</MultiSelectDropdown.Item>
|
||||
)
|
||||
return acc
|
||||
},
|
||||
[
|
||||
<MultiSelectDropdown.Item id="*" key="*" value={{id: '*'}}>
|
||||
All Databases
|
||||
</MultiSelectDropdown.Item>,
|
||||
<MultiSelectDropdown.Divider id="" key="" />,
|
||||
]
|
||||
)}
|
||||
</MultiSelectDropdown>
|
||||
</div>
|
||||
<MultiDBSelector />
|
||||
{isEnterprise && (
|
||||
<div className="hide-roles-toggle">
|
||||
<SlideToggle
|
||||
active={showRoles}
|
||||
onChange={changeHideRoles}
|
||||
onChange={toggleShowRoles}
|
||||
size={ComponentSize.ExtraSmall}
|
||||
/>
|
||||
Show Roles
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
changeNamedCollection,
|
||||
computeNamedChanges,
|
||||
} from '../util/changeNamedCollection'
|
||||
import allOrParticularSelection from '../util/allOrParticularSelection'
|
||||
|
||||
const querySorters = {
|
||||
'+time'(queries) {
|
||||
|
@ -37,8 +38,7 @@ const identity = x => x
|
|||
function sortQueries(queries, queriesSort) {
|
||||
return (querySorters[queriesSort] || identity)(queries)
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
export const initialState = {
|
||||
users: [],
|
||||
roles: [],
|
||||
permissions: [],
|
||||
|
@ -46,16 +46,21 @@ const initialState = {
|
|||
queriesSort: '-time',
|
||||
queryIDToKill: null,
|
||||
databases: [],
|
||||
selectedDBs: ['*'],
|
||||
showUsers: true,
|
||||
showRoles: true,
|
||||
usersFilter: '',
|
||||
rolesFilter: '',
|
||||
}
|
||||
|
||||
const adminInfluxDB = (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case 'INFLUXDB_LOAD_USERS': {
|
||||
return {...state, ...action.payload}
|
||||
return {...state, ...action.payload, usersFilter: ''}
|
||||
}
|
||||
|
||||
case 'INFLUXDB_LOAD_ROLES': {
|
||||
return {...state, ...action.payload}
|
||||
return {...state, ...action.payload, rolesFilter: ''}
|
||||
}
|
||||
|
||||
case 'INFLUXDB_LOAD_PERMISSIONS': {
|
||||
|
@ -63,7 +68,9 @@ const adminInfluxDB = (state = initialState, action) => {
|
|||
}
|
||||
|
||||
case 'INFLUXDB_LOAD_DATABASES': {
|
||||
return {...state, ...action.payload}
|
||||
const databases = action.payload.databases
|
||||
const selectedDBs = initialState.selectedDBs
|
||||
return {...state, databases, selectedDBs}
|
||||
}
|
||||
|
||||
case 'INFLUXDB_ADD_DATABASE': {
|
||||
|
@ -333,7 +340,7 @@ const adminInfluxDB = (state = initialState, action) => {
|
|||
return u
|
||||
}),
|
||||
}
|
||||
return {...state, ...newState}
|
||||
return {...state, ...newState, usersFilter: text}
|
||||
}
|
||||
|
||||
case 'INFLUXDB_FILTER_ROLES': {
|
||||
|
@ -344,7 +351,7 @@ const adminInfluxDB = (state = initialState, action) => {
|
|||
return r
|
||||
}),
|
||||
}
|
||||
return {...state, ...newState}
|
||||
return {...state, ...newState, rolesFilter: text}
|
||||
}
|
||||
|
||||
case 'INFLUXDB_KILL_QUERY': {
|
||||
|
@ -359,6 +366,18 @@ const adminInfluxDB = (state = initialState, action) => {
|
|||
case 'INFLUXDB_SET_QUERY_TO_KILL': {
|
||||
return {...state, ...action.payload}
|
||||
}
|
||||
case 'INFLUXDB_CHANGE_SELECTED_DBS': {
|
||||
const newDBs = action.payload.selectedDBs
|
||||
const oldDBs = state.selectedDBs || ['*']
|
||||
const selectedDBs = allOrParticularSelection(oldDBs, newDBs)
|
||||
return {...state, selectedDBs}
|
||||
}
|
||||
case 'INFLUXDB_CHANGE_SHOW_USERS': {
|
||||
return {...state, showUsers: !state.showUsers}
|
||||
}
|
||||
case 'INFLUXDB_CHANGE_SHOW_ROLES': {
|
||||
return {...state, showRoles: !state.showRoles}
|
||||
}
|
||||
}
|
||||
|
||||
return state
|
||||
|
|
|
@ -10,6 +10,7 @@ import {defaultTableData} from 'src/logs/constants'
|
|||
import {VERSION, GIT_SHA} from 'src/shared/constants'
|
||||
|
||||
import {LocalStorage} from 'src/types/localStorage'
|
||||
import {initialState as adminInfluxDBInitialState} from './admin/reducers/influxdb'
|
||||
|
||||
export const loadLocalStorage = (
|
||||
errorsQueue: any[]
|
||||
|
@ -39,7 +40,7 @@ export const loadLocalStorage = (
|
|||
|
||||
delete state.VERSION
|
||||
delete state.GIT_SHA
|
||||
|
||||
state.adminInfluxDB = {...adminInfluxDBInitialState, ...state.adminInfluxDB}
|
||||
return state
|
||||
} catch (error) {
|
||||
console.error(notifyLoadLocalSettingsFailed(error).message)
|
||||
|
@ -55,6 +56,7 @@ export const saveToLocalStorage = ({
|
|||
dashTimeV1: {ranges, refreshes},
|
||||
logs,
|
||||
script,
|
||||
adminInfluxDB: {showUsers, showRoles},
|
||||
}: LocalStorage): void => {
|
||||
try {
|
||||
const dashTimeV1 = {
|
||||
|
@ -104,6 +106,7 @@ export const saveToLocalStorage = ({
|
|||
},
|
||||
tableTime: minimalLogs.tableTime || {},
|
||||
},
|
||||
adminInfluxDB: {showRoles, showUsers},
|
||||
})
|
||||
)
|
||||
} catch (err) {
|
||||
|
|
|
@ -14,7 +14,7 @@ interface Props {
|
|||
color?: ComponentColor
|
||||
disabled?: boolean
|
||||
tooltipText?: string
|
||||
entity?: string
|
||||
dataTest?: string
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
|
@ -27,14 +27,14 @@ class SlideToggle extends Component<Props> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const {tooltipText} = this.props
|
||||
const {tooltipText, dataTest} = this.props
|
||||
|
||||
return (
|
||||
<div
|
||||
className={this.className}
|
||||
onClick={this.handleClick}
|
||||
title={tooltipText}
|
||||
data-test={this.dataTest}
|
||||
data-test={dataTest}
|
||||
>
|
||||
<div className="slide-toggle--knob" />
|
||||
</div>
|
||||
|
@ -59,12 +59,6 @@ class SlideToggle extends Component<Props> {
|
|||
{active, disabled}
|
||||
)
|
||||
}
|
||||
|
||||
private get dataTest(): string {
|
||||
const {active, entity} = this.props
|
||||
|
||||
return active ? `hide-${entity}--toggle` : `show-${entity}--toggle`
|
||||
}
|
||||
}
|
||||
|
||||
export default SlideToggle
|
||||
|
|
|
@ -10,6 +10,10 @@ export interface LocalStorage {
|
|||
logs: LogsState
|
||||
telegrafSystemInterval: string
|
||||
hostPageDisabled: boolean
|
||||
adminInfluxDB: {
|
||||
showUsers: boolean
|
||||
showRoles: boolean
|
||||
}
|
||||
}
|
||||
|
||||
export type VERSION = string
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
syncRole,
|
||||
editDatabase,
|
||||
editRetentionPolicyRequested,
|
||||
loadUsers,
|
||||
loadRoles,
|
||||
loadPermissions,
|
||||
deleteRole,
|
||||
|
@ -19,6 +20,10 @@ import {
|
|||
removeDatabaseDeleteCode,
|
||||
loadQueries,
|
||||
setQueriesSort,
|
||||
loadDatabases,
|
||||
changeSelectedDBs,
|
||||
changeShowUsers,
|
||||
changeShowRoles,
|
||||
} from 'src/admin/actions/influxdb'
|
||||
|
||||
import {NEW_DEFAULT_DATABASE, NEW_EMPTY_RP} from 'src/admin/constants'
|
||||
|
@ -137,6 +142,17 @@ describe('Admin.InfluxDB.Reducers', () => {
|
|||
state = {databases: [db1, db2]}
|
||||
})
|
||||
|
||||
it('can load databases', () => {
|
||||
const {databases, selectedDBs} = reducer(
|
||||
undefined,
|
||||
loadDatabases([{name: 'db1'}])
|
||||
)
|
||||
expect({databases, selectedDBs}).toEqual({
|
||||
databases: [{name: 'db1'}],
|
||||
selectedDBs: ['*'],
|
||||
})
|
||||
})
|
||||
|
||||
it('can add a database', () => {
|
||||
const actual = reducer(state, addDatabase())
|
||||
const expected = [{...NEW_DEFAULT_DATABASE, isEditing: true}, db1, db2]
|
||||
|
@ -209,7 +225,15 @@ describe('Admin.InfluxDB.Reducers', () => {
|
|||
expect(actual.databases).toEqual(expected)
|
||||
})
|
||||
})
|
||||
it('it can load users', () => {
|
||||
const {users: d, usersFilter} = reducer(state, loadUsers({users}))
|
||||
const expected = {
|
||||
users,
|
||||
usersFilter: '',
|
||||
}
|
||||
|
||||
expect({users: d, usersFilter}).toEqual(expected)
|
||||
})
|
||||
it('it can sync a stale user', () => {
|
||||
const staleUser = {...u1, roles: []}
|
||||
state = {users: [u2, staleUser], roles: []}
|
||||
|
@ -315,13 +339,14 @@ describe('Admin.InfluxDB.Reducers', () => {
|
|||
expect(actual.users).toEqual(expected.users)
|
||||
})
|
||||
|
||||
it('it can load the roles', () => {
|
||||
const actual = reducer(state, loadRoles({roles}))
|
||||
it('it can load roles', () => {
|
||||
const {roles: d, rolesFilter} = reducer(state, loadRoles({roles}))
|
||||
const expected = {
|
||||
roles,
|
||||
rolesFilter: '',
|
||||
}
|
||||
|
||||
expect(actual.roles).toEqual(expected.roles)
|
||||
expect({roles: d, rolesFilter}).toEqual(expected)
|
||||
})
|
||||
|
||||
it('it can delete a non-existing role', () => {
|
||||
|
@ -382,15 +407,16 @@ describe('Admin.InfluxDB.Reducers', () => {
|
|||
|
||||
const text = 'x'
|
||||
|
||||
const actual = reducer(state, filterRoles(text))
|
||||
const {roles: d, rolesFilter} = reducer(state, filterRoles(text))
|
||||
const expected = {
|
||||
roles: [
|
||||
{...r1, hidden: false},
|
||||
{...r2, hidden: true},
|
||||
],
|
||||
rolesFilter: text,
|
||||
}
|
||||
|
||||
expect(actual.roles).toEqual(expected.roles)
|
||||
expect({roles: d, rolesFilter}).toEqual(expected)
|
||||
})
|
||||
|
||||
it('can filter users w/ "zero" text', () => {
|
||||
|
@ -400,15 +426,16 @@ describe('Admin.InfluxDB.Reducers', () => {
|
|||
|
||||
const text = 'zero'
|
||||
|
||||
const actual = reducer(state, filterUsers(text))
|
||||
const {users: d, usersFilter} = reducer(state, filterUsers(text))
|
||||
const expected = {
|
||||
users: [
|
||||
{...u1, hidden: true},
|
||||
{...u2, hidden: false},
|
||||
],
|
||||
usersFilter: text,
|
||||
}
|
||||
|
||||
expect(actual.users).toEqual(expected.users)
|
||||
expect({users: d, usersFilter}).toEqual(expected)
|
||||
})
|
||||
|
||||
// Permissions
|
||||
|
@ -488,4 +515,56 @@ describe('Admin.InfluxDB.Reducers', () => {
|
|||
expect(actual.queries[2].id).toEqual(1)
|
||||
})
|
||||
})
|
||||
describe('filters', () => {
|
||||
it('can change selected DBS', () => {
|
||||
const testPairs = [
|
||||
{
|
||||
prev: undefined,
|
||||
change: ['db1'],
|
||||
next: ['db1'],
|
||||
},
|
||||
{
|
||||
prev: [],
|
||||
change: ['db1'],
|
||||
next: ['db1'],
|
||||
},
|
||||
{
|
||||
prev: ['db1'],
|
||||
change: ['db1', '*'],
|
||||
next: ['*'],
|
||||
},
|
||||
{
|
||||
prev: ['*'],
|
||||
change: ['db1', '*'],
|
||||
next: ['db1'],
|
||||
},
|
||||
{
|
||||
prev: ['db1'],
|
||||
change: [],
|
||||
next: [],
|
||||
},
|
||||
]
|
||||
testPairs.forEach(({prev, change, next}) => {
|
||||
const {selectedDBs} = reducer(
|
||||
{selectedDBs: prev},
|
||||
changeSelectedDBs(change)
|
||||
)
|
||||
expect(selectedDBs).toEqual(next)
|
||||
})
|
||||
})
|
||||
it('can change showUsers flag', () => {
|
||||
const vals = [undefined, true, false]
|
||||
vals.forEach(prev => {
|
||||
const {showUsers} = reducer({showUsers: prev}, changeShowUsers())
|
||||
expect(showUsers).toEqual(!prev)
|
||||
})
|
||||
})
|
||||
it('can change showRoles flag', () => {
|
||||
const vals = [undefined, true, false]
|
||||
vals.forEach(prev => {
|
||||
const {showRoles} = reducer({showRoles: prev}, changeShowRoles())
|
||||
expect(showRoles).toEqual(!prev)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue