179 lines
4.7 KiB
TypeScript
179 lines
4.7 KiB
TypeScript
import { baseApi } from "@/store/api/baseApi";
|
|
import { User } from "@/store/models/User.model";
|
|
import { RiskEnum } from "@/constants/riskEnum";
|
|
import { TableSortDirection } from "@/constants/tableSortDirectionEnum";
|
|
|
|
export type UsersQueryParams = {
|
|
page?: number;
|
|
limit?: number;
|
|
search?: string;
|
|
risks?: RiskEnum[];
|
|
sortBy?: "name" | "email" | "title" | "role" | "risk";
|
|
sortDir?: TableSortDirection;
|
|
roleType?: "user" | "admin";
|
|
};
|
|
|
|
export type PaginatedUsers = {
|
|
items: User[];
|
|
total: number;
|
|
page: number;
|
|
limit: number;
|
|
};
|
|
|
|
export type UserLoginLog = {
|
|
id: string;
|
|
name: string;
|
|
email: string;
|
|
lastLoginAt: string | Date;
|
|
activity: string;
|
|
status?: "SUCCESS" | "FAILURE";
|
|
failureReason?:
|
|
| "MISSING_CREDENTIALS"
|
|
| "INVALID_CREDENTIALS"
|
|
| "WRONG_PASSWORD"
|
|
| "ACCOUNT_LOCKED"
|
|
| "NOT_ACTIVATED"
|
|
| "NOT_ALLOWED"
|
|
| "UNKNOWN"
|
|
| null;
|
|
};
|
|
|
|
const normalizeSortDir = (dir?: TableSortDirection) => {
|
|
return dir
|
|
? dir === TableSortDirection.DESCENDING
|
|
? "desc"
|
|
: "asc"
|
|
: undefined;
|
|
};
|
|
|
|
const buildUserParams = (params?: UsersQueryParams) => {
|
|
if (!params) return {};
|
|
|
|
const { page, limit, search, risks, sortBy, sortDir, roleType } = params;
|
|
|
|
return {
|
|
...(page !== undefined && { page }),
|
|
...(limit !== undefined && { limit }),
|
|
...(search && { search }),
|
|
...(risks?.length && { risks: risks.join(",") }),
|
|
...(sortBy && { sortBy }),
|
|
...(sortDir && { sortDir: normalizeSortDir(sortDir) }),
|
|
...(roleType && { roleType }),
|
|
};
|
|
};
|
|
|
|
const buildLogParams = (params?: {
|
|
page?: number;
|
|
limit?: number;
|
|
search?: string;
|
|
}) => {
|
|
if (!params) return {};
|
|
|
|
const { page, limit, search } = params;
|
|
|
|
return {
|
|
...(page !== undefined && { page }),
|
|
...(limit !== undefined && { limit }),
|
|
...(search && { search }),
|
|
};
|
|
};
|
|
|
|
export const usersApi = baseApi.injectEndpoints({
|
|
overrideExisting: true,
|
|
endpoints: (builder) => ({
|
|
getUserLogs: builder.query<
|
|
{ items: UserLoginLog[]; total: number; page: number; limit: number },
|
|
{ page?: number; limit?: number; search?: string } | undefined
|
|
>({
|
|
query: (params) => ({
|
|
url: "/users/logs",
|
|
params: buildLogParams(params),
|
|
}),
|
|
providesTags: ["UserLogs"],
|
|
}),
|
|
|
|
getUserLogsById: builder.query<
|
|
{ items: UserLoginLog[]; total: number; page: number; limit: number },
|
|
{ userId: string; page?: number; limit?: number }
|
|
>({
|
|
query: ({ userId, page, limit }) => ({
|
|
url: `/users/${userId}/logs`,
|
|
params: {
|
|
...(page !== undefined && { page }),
|
|
...(limit !== undefined && { limit }),
|
|
},
|
|
}),
|
|
providesTags: (_res, _err, { userId }) => [
|
|
"UserLogs",
|
|
{ type: "UserLogs", id: userId } as any,
|
|
],
|
|
}),
|
|
|
|
getUsers: builder.query<PaginatedUsers, UsersQueryParams | undefined>({
|
|
query: (params) => ({ url: "/users", params: buildUserParams(params) }),
|
|
providesTags: (result) => [
|
|
"Users",
|
|
...(result?.items ?? []).map(
|
|
({ id }) => ({ type: "Users", id } as const)
|
|
),
|
|
],
|
|
}),
|
|
|
|
getUserById: builder.query<User, string>({
|
|
query: (id) => `/users/${id}`,
|
|
providesTags: (_res, _err, id) => [{ type: "Users", id }],
|
|
}),
|
|
|
|
deleteUser: builder.mutation<void, string>({
|
|
query: (id) => ({ url: `/users/${id}`, method: "DELETE" }),
|
|
invalidatesTags: ["Users"],
|
|
}),
|
|
|
|
deleteUsers: builder.mutation<void, string[]>({
|
|
query: (ids) => ({ url: "/users", method: "DELETE", body: { ids } }),
|
|
invalidatesTags: ["Users"],
|
|
}),
|
|
|
|
lockUser: builder.mutation<void, string>({
|
|
query: (id) => ({ url: `/users/${id}/lock`, method: "PUT" }),
|
|
invalidatesTags: ["Users"],
|
|
}),
|
|
|
|
updateUser: builder.mutation<User, Partial<User>>({
|
|
query: (user) => ({
|
|
url: `/users/${user.id}`,
|
|
method: "PUT",
|
|
body: user,
|
|
}),
|
|
invalidatesTags: (_res, _err, { id }) => [
|
|
"Users",
|
|
{ type: "Users", id },
|
|
"Todos",
|
|
],
|
|
}),
|
|
|
|
createUser: builder.mutation<User, Partial<User>>({
|
|
query: (user) => ({ url: "/users", method: "POST", body: user }),
|
|
invalidatesTags: ["Users"],
|
|
}),
|
|
|
|
resendInvitation: builder.mutation<{ message: string }, string>({
|
|
query: (id) => ({ url: `/users/${id}/invite`, method: "POST" }),
|
|
invalidatesTags: (_res, _err, id) => ["Users", { type: "Users", id }],
|
|
}),
|
|
}),
|
|
});
|
|
|
|
export const {
|
|
useGetUserLogsQuery,
|
|
useGetUserLogsByIdQuery,
|
|
useGetUsersQuery,
|
|
useGetUserByIdQuery,
|
|
useDeleteUserMutation,
|
|
useDeleteUsersMutation,
|
|
useLockUserMutation,
|
|
useUpdateUserMutation,
|
|
useCreateUserMutation,
|
|
useResendInvitationMutation,
|
|
} = usersApi;
|