feat(ui): show RW permission in DB columns on Users page
parent
ff229c5a04
commit
7376d1162d
|
@ -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"
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue