1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-26 01:17:00 +02:00
unleash.unleash/frontend/src/hooks/useUsersSort.ts
Nuno Góis 004ded8f74 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
2022-05-05 14:53:28 +01:00

126 lines
3.3 KiB
TypeScript

import { IUser } from 'interfaces/user';
import React, { useMemo } from 'react';
import { getBasePath } from 'utils/formatPath';
import { createPersistentGlobalStateHook } from './usePersistentGlobalState';
import useUsers from 'hooks/api/getters/useUsers/useUsers';
import IRole from 'interfaces/role';
export type UsersSortType = 'created' | 'name' | 'role' | 'last-seen';
export interface IUsersSort {
type: UsersSortType;
desc?: boolean;
}
export interface IUsersSortOutput {
sort: IUsersSort;
sorted: IUser[];
setSort: React.Dispatch<React.SetStateAction<IUsersSort>>;
}
export interface IUsersFilterSortOption {
type: UsersSortType;
name: string;
}
// Store the users sort state globally, and in localStorage.
// When changing the format of IUsersSort, change the version as well.
const useUsersSortState = createPersistentGlobalStateHook<IUsersSort>(
`${getBasePath()}:useUsersSort:v1`,
{ type: 'created', desc: false }
);
export const useUsersSort = (users: IUser[]): IUsersSortOutput => {
const [sort, setSort] = useUsersSortState();
const { roles } = useUsers();
const sorted = useMemo(() => {
return sortUsers(users, roles, sort);
}, [users, roles, sort]);
return {
setSort,
sort,
sorted,
};
};
export const createUsersFilterSortOptions = (): IUsersFilterSortOption[] => {
return [
{ type: 'created', name: 'Created' },
{ type: 'name', name: 'Name' },
{ type: 'role', name: 'Role' },
{ type: 'last-seen', name: 'Last seen' },
];
};
const sortAscendingUsers = (
users: IUser[],
roles: IRole[],
sort: IUsersSort
): IUser[] => {
switch (sort.type) {
case 'created':
return sortByCreated(users);
case 'name':
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;
}
};
const sortUsers = (
users: IUser[],
roles: IRole[],
sort: IUsersSort
): IUser[] => {
const sorted = sortAscendingUsers(users, roles, sort);
if (sort.desc) {
return [...sorted].reverse();
}
return sorted;
};
const sortByCreated = (users: Readonly<IUser[]>): IUser[] => {
return [...users].sort((a, b) => a.createdAt.localeCompare(b.createdAt));
};
const sortByName = (users: Readonly<IUser[]>): IUser[] => {
return [...users].sort((a, b) => {
const aName = a.name ?? '';
const bName = b.name ?? '';
return aName.localeCompare(bName);
});
};
const sortByRole = (
users: Readonly<IUser[]>,
roles: Readonly<IRole[]>
): IUser[] => {
return [...users].sort((a, b) =>
getRoleName(a.rootRole, roles).localeCompare(
getRoleName(b.rootRole, roles)
)
);
};
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);
});
};