feat(ui): show RW permission in DB columns on Users page

pull/5921/head
Pavel Zavora 2022-05-24 19:14:09 +02:00
parent ff229c5a04
commit 7376d1162d
5 changed files with 97 additions and 56 deletions

View File

@ -29,15 +29,17 @@ class FilterBar extends Component {
}) })
return ( return (
<div className="panel-heading"> <div className="panel-heading">
<div className="search-widget" style={{width: '300px'}}> <div>
<input <div className="search-widget" style={{width: '250px'}}>
type="text" <input
className="form-control input-sm" type="text"
placeholder={`Filter ${placeholderText}...`} className="form-control input-sm"
value={this.state.filterText} placeholder={`Filter ${placeholderText}...`}
onChange={this.handleText} value={this.state.filterText}
/> onChange={this.handleText}
<span className="icon search" /> />
<span className="icon search" />
</div>
</div> </div>
<button <button
className="btn btn-sm btn-primary" className="btn btn-sm btn-primary"

View File

@ -5,7 +5,7 @@ import UserRoleDropdown from 'src/admin/components/UserRoleDropdown'
import {USERS_TABLE} from 'src/admin/constants/tableSizing' import {USERS_TABLE} from 'src/admin/constants/tableSizing'
import UserRowEdit from 'src/admin/components/UserRowEdit' import UserRowEdit from 'src/admin/components/UserRowEdit'
import {Database, User, UserPermission} from 'src/types/influxAdmin' import {User, UserPermission} from 'src/types/influxAdmin'
import {Link} from 'react-router' import {Link} from 'react-router'
const ADMIN_STYLES = [ const ADMIN_STYLES = [
@ -19,39 +19,7 @@ const ADMIN_STYLES = [
}, },
] ]
const mapOSSPermission = (allowed: string[]) => {
let retVal = ''
for (const x of allowed) {
if (x === 'WRITE') {
retVal += 'W'
continue
}
if (x === 'READ') {
retVal = 'R' + retVal
continue
}
}
return retVal
}
const OssUserDBPermissions = ({user}: {user: User}) => (
<>
{(user.permissions || [])
.filter(x => x.scope === 'database')
.sort((a, b) => a.name.localeCompare(b.name))
.map(x => (
<React.Fragment key={x.name}>
<span className="permission--db">{x.name}</span>
{':'}
<span className="permission--values">
{mapOSSPermission(x.allowed)}
</span>
</React.Fragment>
))}
</>
)
interface Props { interface Props {
databases: Database[]
user: User user: User
allRoles: any[] allRoles: any[]
allPermissions: string[] allPermissions: string[]
@ -59,6 +27,7 @@ interface Props {
isNew: boolean isNew: boolean
isEditing: boolean isEditing: boolean
page: string page: string
userDBPermissions: Array<Record<string, boolean>>
onCancel: (user: User) => void onCancel: (user: User) => void
onEdit: (User: User, updates: Partial<User>) => void onEdit: (User: User, updates: Partial<User>) => void
onSave: (user: User) => Promise<void> onSave: (user: User) => Promise<void>
@ -74,6 +43,7 @@ const UserRow = ({
isNew, isNew,
isEditing, isEditing,
page, page,
userDBPermissions,
onEdit, onEdit,
onSave, onSave,
onCancel, onCancel,
@ -118,17 +88,34 @@ const UserRow = ({
<span className={adminStyle.style}>{adminStyle.text}</span> <span className={adminStyle.style}>{adminStyle.text}</span>
</td> </td>
)} )}
<td> {hasRoles ? (
{hasRoles ? ( <td>
<UserPermissionsDropdown <UserPermissionsDropdown
user={user} user={user}
allPermissions={allPermissions} allPermissions={allPermissions}
onUpdatePermissions={onUpdatePermissions} onUpdatePermissions={onUpdatePermissions}
/> />
) : ( </td>
<OssUserDBPermissions user={user} /> ) : (
)} userDBPermissions.map((perms, i) => (
</td> <td className="admin-table__dbperm" key={i}>
<span
className={`permission-value ${
perms.READ || perms.Read ? 'granted' : 'denied'
}`}
>
Read
</span>
<span
className={`permission-value ${
perms.WRITE || perms.Write ? 'granted' : 'denied'
}`}
>
Write
</span>
</td>
))
)}
</tr> </tr>
) )
} }

View File

@ -331,7 +331,7 @@ const UserPageContent = ({
<td>{db.name}</td> <td>{db.name}</td>
<td> <td>
{dbPermisssions.map((perm, i) => ( {dbPermisssions.map((perm, i) => (
<span <div
key={i} key={i}
title="Click to change, click Apply Changes to save all changes" title="Click to change, click Apply Changes to save all changes"
data-db={db.name} data-db={db.name}
@ -349,7 +349,7 @@ const UserPageContent = ({
onClick={onPermissionChange} onClick={onPermissionChange}
> >
{perm} {perm}
</span> </div>
))} ))}
</td> </td>
</tr> </tr>

View File

@ -113,6 +113,24 @@ const UsersPage = ({
[source] [source]
) )
const visibleUsers = useMemo(() => users.filter(x => !x.hidden), [users]) const visibleUsers = useMemo(() => users.filter(x => !x.hidden), [users])
const userDBPermissions = useMemo<Array<Array<Record<string, boolean>>>>(
() =>
visibleUsers.map(u => {
const permRecord = u.permissions.reduce((acc, userPerm) => {
if (userPerm.scope === 'database') {
acc[userPerm.name] = userPerm.allowed.reduce<
Record<string, boolean>
>((obj, perm) => {
obj[perm] = true
return obj
}, {})
}
return acc
}, {})
return databases.map(db => permRecord[db.name] || {})
}),
[databases, visibleUsers]
)
return ( return (
<AdminInfluxDBTabbedPage activeTab="users" source={source}> <AdminInfluxDBTabbedPage activeTab="users" source={source}>
<div className="panel panel-solid influxdb-admin"> <div className="panel panel-solid influxdb-admin">
@ -124,26 +142,40 @@ const UsersPage = ({
/> />
<div className="panel-body"> <div className="panel-body">
<FancyScrollbar> <FancyScrollbar>
<table className="table v-center admin-table table-highlight"> <table className="table v-center admin-table table-highlight admin-table--compact">
<thead> <thead>
<tr> <tr>
<th>User</th> <th>User</th>
<th className="admin-table--left-offset"> <th className="admin-table--left-offset">
{hasRoles ? 'Roles' : 'Admin'} {hasRoles ? 'Roles' : 'Admin'}
</th> </th>
<th>Permissions</th>
{visibleUsers.length &&
(hasRoles ? (
<th>Permissions</th>
) : (
databases.map(db => (
<th
className="admin-table__dbheader"
title={`Database ${db.name}`}
key={db.name}
>
{db.name}
</th>
))
))}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{visibleUsers.length ? ( {visibleUsers.length ? (
visibleUsers.map(user => ( visibleUsers.map((user, userIndex) => (
<UserRow <UserRow
key={user.name} key={user.name}
user={user} user={user}
page={`${usersPage}/${encodeURIComponent( page={`${usersPage}/${encodeURIComponent(
user.name || '' user.name || ''
)}`} )}`}
databases={databases} userDBPermissions={userDBPermissions[userIndex]}
allRoles={roles} allRoles={roles}
hasRoles={hasRoles} hasRoles={hasRoles}
onEdit={editUser} onEdit={editUser}
@ -157,7 +189,7 @@ const UsersPage = ({
/> />
)) ))
) : ( ) : (
<EmptyRow tableName={'Users'} colSpan={3} /> <EmptyRow tableName={'Users'} colSpan={2} />
)} )}
</tbody> </tbody>
</table> </table>

View File

@ -25,6 +25,10 @@
span.permission--allowed{ span.permission--allowed{
font-style: italic; font-style: italic;
} }
&.admin-table--compact{
width: auto
}
} }
.admin-table .dropdown-toggle { .admin-table .dropdown-toggle {
@ -60,6 +64,13 @@ table > tbody > tr > td.admin-table--left-offset,
table > thead > tr > th.admin-table--left-offset { table > thead > tr > th.admin-table--left-offset {
padding-left: 15px; padding-left: 15px;
} }
table > thead > tr > th.admin-table__dbheader {
font-weight: 450;
padding: 8px 12px;
}
table > tbody > tr > td.admin-table__dbperm {
min-width: 100px;
}
.admin-table > thead > tr > th.col--sort-asc, .admin-table > thead > tr > th.col--sort-asc,
.admin-table > thead > tr > th.col--sort-desc { .admin-table > thead > tr > th.col--sort-desc {
@ -133,7 +144,7 @@ pre.admin-table--query {
.influxdb-admin--contents{ .influxdb-admin--contents{
height: calc(100%-60px); height: calc(100%-60px);
} }
.permission-value{ div.permission-value{
@include btn-base-styles( @include btn-base-styles(
$g5-pepper, $g5-pepper,
$g6-smoke, $g6-smoke,
@ -171,6 +182,15 @@ pre.admin-table--query {
} }
} }
} }
span.permission-value{
padding: 0 2px;
display: inline-block;
color: $g18-cloud;
&.denied {
font-style: italic;
color: $g5-pepper;
}
}
} }
.influxdb-admin.panel.panel-solid { .influxdb-admin.panel.panel-solid {
border-radius: 0px; border-radius: 0px;