mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
feat: add last seen col to admin users list (#949)
* feat: add last seen col to admin users list * fix: header hover effect, duplicate title from TimeAgo * fix: use YMD format, never logged * fix: small tooltip change * refactor: adapt to review suggestions
This commit is contained in:
parent
1772997d28
commit
004ded8f74
@ -16,12 +16,16 @@ export const useStyles = makeStyles()(theme => ({
|
||||
fontWeight: 'normal',
|
||||
border: 0,
|
||||
'&:first-of-type': {
|
||||
borderTopLeftRadius: '8px',
|
||||
borderBottomLeftRadius: '8px',
|
||||
'&, & > button': {
|
||||
borderTopLeftRadius: theme.spacing(1),
|
||||
borderBottomLeftRadius: theme.spacing(1),
|
||||
},
|
||||
},
|
||||
'&:last-of-type': {
|
||||
borderTopRightRadius: '8px',
|
||||
borderBottomRightRadius: '8px',
|
||||
'&, & > button': {
|
||||
borderTopRightRadius: theme.spacing(1),
|
||||
borderBottomRightRadius: theme.spacing(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -18,6 +18,7 @@ import { ILocationSettings } from 'hooks/useLocationSettings';
|
||||
import { formatDateYMD } from 'utils/formatDate';
|
||||
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
||||
import { useStyles } from './UserListItem.styles';
|
||||
import TimeAgo from 'react-timeago';
|
||||
|
||||
interface IUserListItemProps {
|
||||
user: IUser;
|
||||
@ -40,6 +41,20 @@ const UserListItem = ({
|
||||
const navigate = useNavigate();
|
||||
const { classes: styles } = useStyles();
|
||||
|
||||
const renderTimeAgo = (date: string) => (
|
||||
<Tooltip
|
||||
title={`Last seen on: ${formatDateYMD(
|
||||
date,
|
||||
locationSettings.locale
|
||||
)}`}
|
||||
arrow
|
||||
>
|
||||
<Typography noWrap variant="body2" data-loading>
|
||||
<TimeAgo date={new Date(date)} live={false} title={''} />
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
return (
|
||||
<TableRow key={user.id} className={styles.tableRow}>
|
||||
<TableCell className={styles.hideSM}>
|
||||
@ -77,6 +92,17 @@ const UserListItem = ({
|
||||
{renderRole(user.rootRole)}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell className={styles.hideXS}>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(user.seenAt)}
|
||||
show={() => renderTimeAgo(user.seenAt!)}
|
||||
elseShow={
|
||||
<Typography noWrap variant="body2" data-loading>
|
||||
Never logged
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<ConditionallyRender
|
||||
condition={hasAccess(ADMIN)}
|
||||
show={
|
||||
|
@ -186,6 +186,17 @@ const UsersList = ({ search }: IUsersListProps) => {
|
||||
>
|
||||
Role
|
||||
</TableCellSortable>
|
||||
<TableCellSortable
|
||||
className={classnames(
|
||||
styles.hideXS,
|
||||
styles.shrinkTableCell
|
||||
)}
|
||||
name="last-seen"
|
||||
sort={sort}
|
||||
setSort={setSort}
|
||||
>
|
||||
Last seen
|
||||
</TableCellSortable>
|
||||
<TableCell align="center">
|
||||
{hasAccess(ADMIN) ? 'Actions' : ''}
|
||||
</TableCell>
|
||||
|
@ -3,7 +3,6 @@ import { makeStyles } from 'tss-react/mui';
|
||||
export const useStyles = makeStyles()(theme => ({
|
||||
tableCellHeaderSortable: {
|
||||
padding: 0,
|
||||
position: 'relative',
|
||||
cursor: 'pointer',
|
||||
'& > svg': {
|
||||
fontSize: 18,
|
||||
|
@ -5,7 +5,7 @@ import { createPersistentGlobalStateHook } from './usePersistentGlobalState';
|
||||
import useUsers from 'hooks/api/getters/useUsers/useUsers';
|
||||
import IRole from 'interfaces/role';
|
||||
|
||||
export type UsersSortType = 'created' | 'name' | 'role';
|
||||
export type UsersSortType = 'created' | 'name' | 'role' | 'last-seen';
|
||||
|
||||
export interface IUsersSort {
|
||||
type: UsersSortType;
|
||||
@ -50,6 +50,7 @@ export const createUsersFilterSortOptions = (): IUsersFilterSortOption[] => {
|
||||
{ type: 'created', name: 'Created' },
|
||||
{ type: 'name', name: 'Name' },
|
||||
{ type: 'role', name: 'Role' },
|
||||
{ type: 'last-seen', name: 'Last seen' },
|
||||
];
|
||||
};
|
||||
|
||||
@ -65,6 +66,8 @@ const sortAscendingUsers = (
|
||||
return sortByName(users);
|
||||
case 'role':
|
||||
return sortByRole(users, roles);
|
||||
case 'last-seen':
|
||||
return sortByLastSeen(users);
|
||||
default:
|
||||
console.error(`Unknown feature sort type: ${sort.type}`);
|
||||
return users;
|
||||
@ -112,3 +115,11 @@ const getRoleName = (roleId: number, roles: Readonly<IRole[]>) => {
|
||||
const role = roles.find((role: IRole) => role.id === roleId);
|
||||
return role ? role.name : '';
|
||||
};
|
||||
|
||||
const sortByLastSeen = (users: Readonly<IUser[]>): IUser[] => {
|
||||
return [...users].sort((a, b) => {
|
||||
const aSeenAt = a.seenAt ?? '';
|
||||
const bSeenAt = b.seenAt ?? '';
|
||||
return bSeenAt.localeCompare(aSeenAt);
|
||||
});
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user