grafana/public/app/features/users/UsersTable.tsx
Alexander Zobnin a7e721e987
Access control: Make Admin/Users UI working with the permissions (#33176)
* API: authorize admin/users views

* Render admin/users components based on user's permissions

* Add LDAP permissions (required by admin/user page)

* Extend default admin role by LDAP permissions

* Show/hide LDAP debug views

* Render LDAP debug page if user has access

* Authorize LDAP debug view

* fix permissions definitions

* Add LDAP page permissions

* remove ambiguous permissions check

* Hide logout buttons in sessions table

* Add org/users permissions

* Use org permissions for managing user roles in orgs

* Apply permissions to org/users

* Apply suggestions from review

* Fix tests

* remove scopes from the frontend

* Tweaks according to review

* Handle /invites endpoints
2021-04-22 13:19:41 +03:00

90 lines
2.9 KiB
TypeScript

import React, { FC, useState } from 'react';
import { AccessControlAction, OrgUser } from 'app/types';
import { OrgRolePicker } from '../admin/OrgRolePicker';
import { Button, ConfirmModal } from '@grafana/ui';
import { OrgRole } from '@grafana/data';
import { contextSrv } from 'app/core/core';
export interface Props {
users: OrgUser[];
onRoleChange: (role: OrgRole, user: OrgUser) => void;
onRemoveUser: (user: OrgUser) => void;
}
const UsersTable: FC<Props> = (props) => {
const { users, onRoleChange, onRemoveUser } = props;
const canUpdateRole = contextSrv.hasPermission(AccessControlAction.OrgUsersRoleUpdate);
const canRemoveFromOrg = contextSrv.hasPermission(AccessControlAction.OrgUsersRemove);
const [showRemoveModal, setShowRemoveModal] = useState<string | boolean>(false);
return (
<table className="filter-table form-inline">
<thead>
<tr>
<th />
<th>Login</th>
<th>Email</th>
<th>Name</th>
<th>Seen</th>
<th>Role</th>
<th style={{ width: '34px' }} />
</tr>
</thead>
<tbody>
{users.map((user, index) => {
return (
<tr key={`${user.userId}-${index}`}>
<td className="width-2 text-center">
<img className="filter-table__avatar" src={user.avatarUrl} />
</td>
<td className="max-width-6">
<span className="ellipsis" title={user.login}>
{user.login}
</span>
</td>
<td className="max-width-5">
<span className="ellipsis" title={user.email}>
{user.email}
</span>
</td>
<td className="max-width-5">
<span className="ellipsis" title={user.name}>
{user.name}
</span>
</td>
<td className="width-1">{user.lastSeenAtAge}</td>
<td className="width-8">
<OrgRolePicker
value={user.role}
disabled={!canUpdateRole}
onChange={(newRole) => onRoleChange(newRole, user)}
/>
</td>
{canRemoveFromOrg && (
<td>
<Button size="sm" variant="destructive" onClick={() => setShowRemoveModal(user.login)} icon="times" />
<ConfirmModal
body={`Are you sure you want to delete user ${user.login}?`}
confirmText="Delete"
title="Delete"
onDismiss={() => setShowRemoveModal(false)}
isOpen={user.login === showRemoveModal}
onConfirm={() => {
onRemoveUser(user);
}}
/>
</td>
)}
</tr>
);
})}
</tbody>
</table>
);
};
export default UsersTable;