c0e55752a3
Turned the inline dependency-count badges on each admin row into
focusable, keyboard-accessible buttons that open a drill-in modal
listing the actual rows behind the count.
Backend (artifacts/api-server/src/routes):
- apps.ts: GET /admin/apps/:id/dependents/{groups,restrictions,opens}
- services.ts: GET /admin/services/:id/dependents/orders
- users.ts: GET /admin/users/:id/dependents/{notes,orders,conversations,messages}
All paginated (limit default 50, max 200; offset) returning
{items, totalCount, limit, offset, nextOffset}. Restrictions joins
the role names that include each required permission.
OpenAPI:
- Added 8 path operations + 16 schemas (Item + Page) and re-ran
`pnpm --filter @workspace/api-spec run codegen`.
Frontend (artifacts/tx-os/src/pages/admin.tsx):
- New DependencyDrillIn component reuses DrillInShell (Escape +
backdrop close, RTL/LTR safe) and the existing LoadMoreSection
pagination pattern from AppOpensDrillIn.
- Each count part in Apps, Services, and Users panels is now a
<button> with a unique data-testid (e.g. app-counts-groups-213,
user-counts-messages-5) and an aria-label that reads
"View {count}".
- AdminPage owns dependencyTarget state for Apps/Services counts;
UsersPanel owns its own (it already encapsulates user list).
Translations:
- Added admin.dependents.* (titles, subtitles, empty/error/load
labels, conversation/order/message helper strings, order status
enum) to en.json and ar.json.
Verification: - tx-os typecheck clean; api-server has only the pre-existing
executive-meetings.ts errors (untouched).
- e2e tested via runTest: login as admin, opened Apps panel,
drilled into groups + opens (Load more grew 50→100), drilled into
Tea orders, drilled into user 5 conversations and messages,
switched to Arabic/RTL and re-opened the Groups drill-in to
confirm Arabic rendering with no raw i18n keys.
Replit-Task-Id: fe96a05b-325f-4e1f-901b-3a2235fb24b5
8425 lines
227 KiB
TypeScript
8425 lines
227 KiB
TypeScript
/**
|
|
* Generated by orval v8.5.3 🍺
|
|
* Do not edit manually.
|
|
* Api
|
|
* Tx OS API specification
|
|
* OpenAPI spec version: 0.1.0
|
|
*/
|
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
import type {
|
|
MutationFunction,
|
|
QueryFunction,
|
|
QueryKey,
|
|
UseMutationOptions,
|
|
UseMutationResult,
|
|
UseQueryOptions,
|
|
UseQueryResult,
|
|
} from "@tanstack/react-query";
|
|
|
|
import type {
|
|
AddAppPermissionBody,
|
|
AddParticipantsBody,
|
|
AddUserRoleBody,
|
|
AdminAppOpensByApp,
|
|
AdminAppOpensByUser,
|
|
AdminResetLinkResponse,
|
|
AdminStats,
|
|
App,
|
|
AppDeletionConflict,
|
|
AppDependentGroupsPage,
|
|
AppDependentOpensPage,
|
|
AppDependentRestrictionsPage,
|
|
AppPermissionLink,
|
|
AppPermissionsImpact,
|
|
AppPermissionsImpactBody,
|
|
AppSettings,
|
|
AuditLogList,
|
|
AuthUser,
|
|
ConversationWithDetails,
|
|
CreateAppBody,
|
|
CreateConversationBody,
|
|
CreateGroupBody,
|
|
CreateRoleBody,
|
|
CreateServiceBody,
|
|
CreateServiceOrderBody,
|
|
CreateUserBody,
|
|
DeleteAppParams,
|
|
DeleteGroupParams,
|
|
DeleteServiceParams,
|
|
DeleteUserParams,
|
|
ErrorResponse,
|
|
ExportAuditLogsCsvParams,
|
|
ForgotPasswordBody,
|
|
ForgotPasswordResponse,
|
|
GetAdminAppDependentGroupsParams,
|
|
GetAdminAppDependentOpensParams,
|
|
GetAdminAppDependentRestrictionsParams,
|
|
GetAdminAppOpensByAppParams,
|
|
GetAdminAppOpensByUserParams,
|
|
GetAdminServiceDependentOrdersParams,
|
|
GetAdminStatsParams,
|
|
GetAdminUserDependentConversationsParams,
|
|
GetAdminUserDependentMessagesParams,
|
|
GetAdminUserDependentNotesParams,
|
|
GetAdminUserDependentOrdersParams,
|
|
GetAppPermissionAuditParams,
|
|
GetGroupPermissionAuditParams,
|
|
GetRolePermissionAuditParams,
|
|
GetUserPermissionAuditParams,
|
|
Group,
|
|
GroupDeletionConflict,
|
|
GroupDetail,
|
|
HealthStatus,
|
|
HomeStats,
|
|
LeaveConversationBody,
|
|
ListAuditLogsParams,
|
|
ListGroupsParams,
|
|
ListUsersParams,
|
|
LoginBody,
|
|
MessageWithSender,
|
|
Notification,
|
|
Permission,
|
|
PermissionAuditList,
|
|
RegisterBody,
|
|
ReplaceRolePermissionsBody,
|
|
RequestUploadUrlBody,
|
|
RequestUploadUrlResponse,
|
|
ResetPasswordBody,
|
|
Role,
|
|
RoleDeletionConflict,
|
|
RolePermissionAuditList,
|
|
RolePermissionsImpact,
|
|
RolePermissionsImpactBody,
|
|
RoleUsage,
|
|
SendMessageBody,
|
|
Service,
|
|
ServiceCategory,
|
|
ServiceDeletionConflict,
|
|
ServiceDependentOrdersPage,
|
|
ServiceOrder,
|
|
SuccessResponse,
|
|
UpdateAppBody,
|
|
UpdateAppSettingsBody,
|
|
UpdateClockHour12Body,
|
|
UpdateClockStyleBody,
|
|
UpdateConversationBody,
|
|
UpdateConversationStateBody,
|
|
UpdateGroupBody,
|
|
UpdateLanguageBody,
|
|
UpdateMyAppOrderBody,
|
|
UpdateRoleBody,
|
|
UpdateServiceBody,
|
|
UpdateServiceOrderStatusBody,
|
|
UpdateUserBody,
|
|
UserDeletionConflict,
|
|
UserDependentConversationsPage,
|
|
UserDependentMessagesPage,
|
|
UserDependentNotesPage,
|
|
UserDependentOrdersPage,
|
|
UserProfile,
|
|
VerifyResetTokenBody,
|
|
VerifyResetTokenResponse,
|
|
} from "./api.schemas";
|
|
|
|
import { customFetch } from "../custom-fetch";
|
|
import type { ErrorType, BodyType } from "../custom-fetch";
|
|
|
|
type AwaitedInput<T> = PromiseLike<T> | T;
|
|
|
|
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
|
|
|
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
|
|
|
/**
|
|
* @summary Health check
|
|
*/
|
|
export const getHealthCheckUrl = () => {
|
|
return `/api/healthz`;
|
|
};
|
|
|
|
export const healthCheck = async (
|
|
options?: RequestInit,
|
|
): Promise<HealthStatus> => {
|
|
return customFetch<HealthStatus>(getHealthCheckUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getHealthCheckQueryKey = () => {
|
|
return [`/api/healthz`] as const;
|
|
};
|
|
|
|
export const getHealthCheckQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof healthCheck>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof healthCheck>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getHealthCheckQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof healthCheck>>> = ({
|
|
signal,
|
|
}) => healthCheck({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof healthCheck>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type HealthCheckQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof healthCheck>>
|
|
>;
|
|
export type HealthCheckQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Health check
|
|
*/
|
|
|
|
export function useHealthCheck<
|
|
TData = Awaited<ReturnType<typeof healthCheck>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof healthCheck>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getHealthCheckQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Register a new user
|
|
*/
|
|
export const getRegisterUrl = () => {
|
|
return `/api/auth/register`;
|
|
};
|
|
|
|
export const register = async (
|
|
registerBody: RegisterBody,
|
|
options?: RequestInit,
|
|
): Promise<AuthUser> => {
|
|
return customFetch<AuthUser>(getRegisterUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(registerBody),
|
|
});
|
|
};
|
|
|
|
export const getRegisterMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof register>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof register>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["register"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof register>>,
|
|
{ data: BodyType<RegisterBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return register(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type RegisterMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof register>>
|
|
>;
|
|
export type RegisterMutationBody = BodyType<RegisterBody>;
|
|
export type RegisterMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Register a new user
|
|
*/
|
|
export const useRegister = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof register>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof register>>,
|
|
TError,
|
|
{ data: BodyType<RegisterBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getRegisterMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Login
|
|
*/
|
|
export const getLoginUrl = () => {
|
|
return `/api/auth/login`;
|
|
};
|
|
|
|
export const login = async (
|
|
loginBody: LoginBody,
|
|
options?: RequestInit,
|
|
): Promise<AuthUser> => {
|
|
return customFetch<AuthUser>(getLoginUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(loginBody),
|
|
});
|
|
};
|
|
|
|
export const getLoginMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof login>>,
|
|
TError,
|
|
{ data: BodyType<LoginBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof login>>,
|
|
TError,
|
|
{ data: BodyType<LoginBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["login"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof login>>,
|
|
{ data: BodyType<LoginBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return login(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type LoginMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof login>>
|
|
>;
|
|
export type LoginMutationBody = BodyType<LoginBody>;
|
|
export type LoginMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Login
|
|
*/
|
|
export const useLogin = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof login>>,
|
|
TError,
|
|
{ data: BodyType<LoginBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof login>>,
|
|
TError,
|
|
{ data: BodyType<LoginBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getLoginMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Logout
|
|
*/
|
|
export const getLogoutUrl = () => {
|
|
return `/api/auth/logout`;
|
|
};
|
|
|
|
export const logout = async (
|
|
options?: RequestInit,
|
|
): Promise<SuccessResponse> => {
|
|
return customFetch<SuccessResponse>(getLogoutUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
});
|
|
};
|
|
|
|
export const getLogoutMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof logout>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof logout>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["logout"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof logout>>,
|
|
void
|
|
> = () => {
|
|
return logout(requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type LogoutMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof logout>>
|
|
>;
|
|
|
|
export type LogoutMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Logout
|
|
*/
|
|
export const useLogout = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof logout>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof logout>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
> => {
|
|
return useMutation(getLogoutMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Request a password reset link
|
|
*/
|
|
export const getForgotPasswordUrl = () => {
|
|
return `/api/auth/forgot-password`;
|
|
};
|
|
|
|
export const forgotPassword = async (
|
|
forgotPasswordBody: ForgotPasswordBody,
|
|
options?: RequestInit,
|
|
): Promise<ForgotPasswordResponse> => {
|
|
return customFetch<ForgotPasswordResponse>(getForgotPasswordUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(forgotPasswordBody),
|
|
});
|
|
};
|
|
|
|
export const getForgotPasswordMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof forgotPassword>>,
|
|
TError,
|
|
{ data: BodyType<ForgotPasswordBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof forgotPassword>>,
|
|
TError,
|
|
{ data: BodyType<ForgotPasswordBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["forgotPassword"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof forgotPassword>>,
|
|
{ data: BodyType<ForgotPasswordBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return forgotPassword(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type ForgotPasswordMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof forgotPassword>>
|
|
>;
|
|
export type ForgotPasswordMutationBody = BodyType<ForgotPasswordBody>;
|
|
export type ForgotPasswordMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Request a password reset link
|
|
*/
|
|
export const useForgotPassword = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof forgotPassword>>,
|
|
TError,
|
|
{ data: BodyType<ForgotPasswordBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof forgotPassword>>,
|
|
TError,
|
|
{ data: BodyType<ForgotPasswordBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getForgotPasswordMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Set a new password using a reset token
|
|
*/
|
|
export const getResetPasswordUrl = () => {
|
|
return `/api/auth/reset-password`;
|
|
};
|
|
|
|
export const resetPassword = async (
|
|
resetPasswordBody: ResetPasswordBody,
|
|
options?: RequestInit,
|
|
): Promise<SuccessResponse> => {
|
|
return customFetch<SuccessResponse>(getResetPasswordUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(resetPasswordBody),
|
|
});
|
|
};
|
|
|
|
export const getResetPasswordMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof resetPassword>>,
|
|
TError,
|
|
{ data: BodyType<ResetPasswordBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof resetPassword>>,
|
|
TError,
|
|
{ data: BodyType<ResetPasswordBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["resetPassword"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof resetPassword>>,
|
|
{ data: BodyType<ResetPasswordBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return resetPassword(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type ResetPasswordMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof resetPassword>>
|
|
>;
|
|
export type ResetPasswordMutationBody = BodyType<ResetPasswordBody>;
|
|
export type ResetPasswordMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Set a new password using a reset token
|
|
*/
|
|
export const useResetPassword = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof resetPassword>>,
|
|
TError,
|
|
{ data: BodyType<ResetPasswordBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof resetPassword>>,
|
|
TError,
|
|
{ data: BodyType<ResetPasswordBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getResetPasswordMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Check whether a reset token is valid
|
|
*/
|
|
export const getVerifyResetTokenUrl = () => {
|
|
return `/api/auth/reset-password/verify`;
|
|
};
|
|
|
|
export const verifyResetToken = async (
|
|
verifyResetTokenBody: VerifyResetTokenBody,
|
|
options?: RequestInit,
|
|
): Promise<VerifyResetTokenResponse> => {
|
|
return customFetch<VerifyResetTokenResponse>(getVerifyResetTokenUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(verifyResetTokenBody),
|
|
});
|
|
};
|
|
|
|
export const getVerifyResetTokenMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof verifyResetToken>>,
|
|
TError,
|
|
{ data: BodyType<VerifyResetTokenBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof verifyResetToken>>,
|
|
TError,
|
|
{ data: BodyType<VerifyResetTokenBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["verifyResetToken"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof verifyResetToken>>,
|
|
{ data: BodyType<VerifyResetTokenBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return verifyResetToken(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type VerifyResetTokenMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof verifyResetToken>>
|
|
>;
|
|
export type VerifyResetTokenMutationBody = BodyType<VerifyResetTokenBody>;
|
|
export type VerifyResetTokenMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Check whether a reset token is valid
|
|
*/
|
|
export const useVerifyResetToken = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof verifyResetToken>>,
|
|
TError,
|
|
{ data: BodyType<VerifyResetTokenBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof verifyResetToken>>,
|
|
TError,
|
|
{ data: BodyType<VerifyResetTokenBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getVerifyResetTokenMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Admin generates a one-time password reset link for a user
|
|
*/
|
|
export const getAdminIssueResetLinkUrl = (id: number) => {
|
|
return `/api/auth/admin/users/${id}/issue-reset-link`;
|
|
};
|
|
|
|
export const adminIssueResetLink = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<AdminResetLinkResponse> => {
|
|
return customFetch<AdminResetLinkResponse>(getAdminIssueResetLinkUrl(id), {
|
|
...options,
|
|
method: "POST",
|
|
});
|
|
};
|
|
|
|
export const getAdminIssueResetLinkMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof adminIssueResetLink>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof adminIssueResetLink>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["adminIssueResetLink"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof adminIssueResetLink>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return adminIssueResetLink(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type AdminIssueResetLinkMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof adminIssueResetLink>>
|
|
>;
|
|
|
|
export type AdminIssueResetLinkMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Admin generates a one-time password reset link for a user
|
|
*/
|
|
export const useAdminIssueResetLink = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof adminIssueResetLink>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof adminIssueResetLink>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getAdminIssueResetLinkMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get current user
|
|
*/
|
|
export const getGetMeUrl = () => {
|
|
return `/api/auth/me`;
|
|
};
|
|
|
|
export const getMe = async (options?: RequestInit): Promise<AuthUser> => {
|
|
return customFetch<AuthUser>(getGetMeUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetMeQueryKey = () => {
|
|
return [`/api/auth/me`] as const;
|
|
};
|
|
|
|
export const getGetMeQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getMe>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getMe>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetMeQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getMe>>> = ({
|
|
signal,
|
|
}) => getMe({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getMe>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetMeQueryResult = NonNullable<Awaited<ReturnType<typeof getMe>>>;
|
|
export type GetMeQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Get current user
|
|
*/
|
|
|
|
export function useGetMe<
|
|
TData = Awaited<ReturnType<typeof getMe>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getMe>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetMeQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update preferred language
|
|
*/
|
|
export const getUpdateLanguageUrl = () => {
|
|
return `/api/auth/me/language`;
|
|
};
|
|
|
|
export const updateLanguage = async (
|
|
updateLanguageBody: UpdateLanguageBody,
|
|
options?: RequestInit,
|
|
): Promise<AuthUser> => {
|
|
return customFetch<AuthUser>(getUpdateLanguageUrl(), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateLanguageBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateLanguageMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateLanguage>>,
|
|
TError,
|
|
{ data: BodyType<UpdateLanguageBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateLanguage>>,
|
|
TError,
|
|
{ data: BodyType<UpdateLanguageBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateLanguage"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateLanguage>>,
|
|
{ data: BodyType<UpdateLanguageBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return updateLanguage(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateLanguageMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateLanguage>>
|
|
>;
|
|
export type UpdateLanguageMutationBody = BodyType<UpdateLanguageBody>;
|
|
export type UpdateLanguageMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Update preferred language
|
|
*/
|
|
export const useUpdateLanguage = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateLanguage>>,
|
|
TError,
|
|
{ data: BodyType<UpdateLanguageBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateLanguage>>,
|
|
TError,
|
|
{ data: BodyType<UpdateLanguageBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateLanguageMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Update preferred home-screen clock style
|
|
*/
|
|
export const getUpdateClockStyleUrl = () => {
|
|
return `/api/auth/me/clock-style`;
|
|
};
|
|
|
|
export const updateClockStyle = async (
|
|
updateClockStyleBody: UpdateClockStyleBody,
|
|
options?: RequestInit,
|
|
): Promise<AuthUser> => {
|
|
return customFetch<AuthUser>(getUpdateClockStyleUrl(), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateClockStyleBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateClockStyleMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateClockStyle>>,
|
|
TError,
|
|
{ data: BodyType<UpdateClockStyleBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateClockStyle>>,
|
|
TError,
|
|
{ data: BodyType<UpdateClockStyleBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateClockStyle"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateClockStyle>>,
|
|
{ data: BodyType<UpdateClockStyleBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return updateClockStyle(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateClockStyleMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateClockStyle>>
|
|
>;
|
|
export type UpdateClockStyleMutationBody = BodyType<UpdateClockStyleBody>;
|
|
export type UpdateClockStyleMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Update preferred home-screen clock style
|
|
*/
|
|
export const useUpdateClockStyle = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateClockStyle>>,
|
|
TError,
|
|
{ data: BodyType<UpdateClockStyleBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateClockStyle>>,
|
|
TError,
|
|
{ data: BodyType<UpdateClockStyleBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateClockStyleMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Update preferred 12/24-hour clock format
|
|
*/
|
|
export const getUpdateClockHour12Url = () => {
|
|
return `/api/auth/me/clock-hour12`;
|
|
};
|
|
|
|
export const updateClockHour12 = async (
|
|
updateClockHour12Body: UpdateClockHour12Body,
|
|
options?: RequestInit,
|
|
): Promise<AuthUser> => {
|
|
return customFetch<AuthUser>(getUpdateClockHour12Url(), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateClockHour12Body),
|
|
});
|
|
};
|
|
|
|
export const getUpdateClockHour12MutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateClockHour12>>,
|
|
TError,
|
|
{ data: BodyType<UpdateClockHour12Body> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateClockHour12>>,
|
|
TError,
|
|
{ data: BodyType<UpdateClockHour12Body> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateClockHour12"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateClockHour12>>,
|
|
{ data: BodyType<UpdateClockHour12Body> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return updateClockHour12(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateClockHour12MutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateClockHour12>>
|
|
>;
|
|
export type UpdateClockHour12MutationBody = BodyType<UpdateClockHour12Body>;
|
|
export type UpdateClockHour12MutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Update preferred 12/24-hour clock format
|
|
*/
|
|
export const useUpdateClockHour12 = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateClockHour12>>,
|
|
TError,
|
|
{ data: BodyType<UpdateClockHour12Body> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateClockHour12>>,
|
|
TError,
|
|
{ data: BodyType<UpdateClockHour12Body> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateClockHour12MutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List all active apps
|
|
*/
|
|
export const getListAppsUrl = () => {
|
|
return `/api/apps`;
|
|
};
|
|
|
|
export const listApps = async (options?: RequestInit): Promise<App[]> => {
|
|
return customFetch<App[]>(getListAppsUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListAppsQueryKey = () => {
|
|
return [`/api/apps`] as const;
|
|
};
|
|
|
|
export const getListAppsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listApps>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof listApps>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListAppsQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listApps>>> = ({
|
|
signal,
|
|
}) => listApps({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listApps>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListAppsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listApps>>
|
|
>;
|
|
export type ListAppsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List all active apps
|
|
*/
|
|
|
|
export function useListApps<
|
|
TData = Awaited<ReturnType<typeof listApps>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof listApps>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListAppsQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Create a new app (admin)
|
|
*/
|
|
export const getCreateAppUrl = () => {
|
|
return `/api/apps`;
|
|
};
|
|
|
|
export const createApp = async (
|
|
createAppBody: CreateAppBody,
|
|
options?: RequestInit,
|
|
): Promise<App> => {
|
|
return customFetch<App>(getCreateAppUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(createAppBody),
|
|
});
|
|
};
|
|
|
|
export const getCreateAppMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createApp>>,
|
|
TError,
|
|
{ data: BodyType<CreateAppBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof createApp>>,
|
|
TError,
|
|
{ data: BodyType<CreateAppBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["createApp"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof createApp>>,
|
|
{ data: BodyType<CreateAppBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return createApp(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type CreateAppMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof createApp>>
|
|
>;
|
|
export type CreateAppMutationBody = BodyType<CreateAppBody>;
|
|
export type CreateAppMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Create a new app (admin)
|
|
*/
|
|
export const useCreateApp = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createApp>>,
|
|
TError,
|
|
{ data: BodyType<CreateAppBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof createApp>>,
|
|
TError,
|
|
{ data: BodyType<CreateAppBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getCreateAppMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get app by ID
|
|
*/
|
|
export const getGetAppUrl = (id: number) => {
|
|
return `/api/apps/${id}`;
|
|
};
|
|
|
|
export const getApp = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<App> => {
|
|
return customFetch<App>(getGetAppUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetAppQueryKey = (id: number) => {
|
|
return [`/api/apps/${id}`] as const;
|
|
};
|
|
|
|
export const getGetAppQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getApp>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getApp>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetAppQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getApp>>> = ({
|
|
signal,
|
|
}) => getApp(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<Awaited<ReturnType<typeof getApp>>, TError, TData> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
};
|
|
|
|
export type GetAppQueryResult = NonNullable<Awaited<ReturnType<typeof getApp>>>;
|
|
export type GetAppQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get app by ID
|
|
*/
|
|
|
|
export function useGetApp<
|
|
TData = Awaited<ReturnType<typeof getApp>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getApp>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAppQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update app (admin)
|
|
*/
|
|
export const getUpdateAppUrl = (id: number) => {
|
|
return `/api/apps/${id}`;
|
|
};
|
|
|
|
export const updateApp = async (
|
|
id: number,
|
|
updateAppBody: UpdateAppBody,
|
|
options?: RequestInit,
|
|
): Promise<App> => {
|
|
return customFetch<App>(getUpdateAppUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateAppBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateAppMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateApp>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateAppBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateApp>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateAppBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateApp"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateApp>>,
|
|
{ id: number; data: BodyType<UpdateAppBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return updateApp(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateAppMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateApp>>
|
|
>;
|
|
export type UpdateAppMutationBody = BodyType<UpdateAppBody>;
|
|
export type UpdateAppMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Update app (admin)
|
|
*/
|
|
export const useUpdateApp = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateApp>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateAppBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateApp>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateAppBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateAppMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Delete app (admin)
|
|
*/
|
|
export const getDeleteAppUrl = (id: number, params?: DeleteAppParams) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/apps/${id}?${stringifiedParams}`
|
|
: `/api/apps/${id}`;
|
|
};
|
|
|
|
export const deleteApp = async (
|
|
id: number,
|
|
params?: DeleteAppParams,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getDeleteAppUrl(id, params), {
|
|
...options,
|
|
method: "DELETE",
|
|
});
|
|
};
|
|
|
|
export const getDeleteAppMutationOptions = <
|
|
TError = ErrorType<AppDeletionConflict>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteApp>>,
|
|
TError,
|
|
{ id: number; params?: DeleteAppParams },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteApp>>,
|
|
TError,
|
|
{ id: number; params?: DeleteAppParams },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["deleteApp"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof deleteApp>>,
|
|
{ id: number; params?: DeleteAppParams }
|
|
> = (props) => {
|
|
const { id, params } = props ?? {};
|
|
|
|
return deleteApp(id, params, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type DeleteAppMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof deleteApp>>
|
|
>;
|
|
|
|
export type DeleteAppMutationError = ErrorType<AppDeletionConflict>;
|
|
|
|
/**
|
|
* @summary Delete app (admin)
|
|
*/
|
|
export const useDeleteApp = <
|
|
TError = ErrorType<AppDeletionConflict>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteApp>>,
|
|
TError,
|
|
{ id: number; params?: DeleteAppParams },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof deleteApp>>,
|
|
TError,
|
|
{ id: number; params?: DeleteAppParams },
|
|
TContext
|
|
> => {
|
|
return useMutation(getDeleteAppMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* Returns the permissions currently required for users to see this app
|
|
in their launcher. An app with no rows here is unrestricted (visible
|
|
to anyone). When more than one permission is configured, holding any
|
|
one of them is sufficient.
|
|
|
|
* @summary List the permissions that gate this app (admin)
|
|
*/
|
|
export const getListAppPermissionsUrl = (id: number) => {
|
|
return `/api/apps/${id}/permissions`;
|
|
};
|
|
|
|
export const listAppPermissions = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<Permission[]> => {
|
|
return customFetch<Permission[]>(getListAppPermissionsUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListAppPermissionsQueryKey = (id: number) => {
|
|
return [`/api/apps/${id}/permissions`] as const;
|
|
};
|
|
|
|
export const getListAppPermissionsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listAppPermissions>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listAppPermissions>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListAppPermissionsQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof listAppPermissions>>
|
|
> = ({ signal }) => listAppPermissions(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listAppPermissions>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListAppPermissionsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listAppPermissions>>
|
|
>;
|
|
export type ListAppPermissionsQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List the permissions that gate this app (admin)
|
|
*/
|
|
|
|
export function useListAppPermissions<
|
|
TData = Awaited<ReturnType<typeof listAppPermissions>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listAppPermissions>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListAppPermissionsQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* Adds a row to `app_permissions` for the (app_id, permission_id) pair.
|
|
Uses `ON CONFLICT DO NOTHING` against the composite primary key so
|
|
re-adding an existing pair is a no-op.
|
|
|
|
* @summary Add a required permission to this app (admin)
|
|
*/
|
|
export const getAddAppPermissionUrl = (id: number) => {
|
|
return `/api/apps/${id}/permissions`;
|
|
};
|
|
|
|
export const addAppPermission = async (
|
|
id: number,
|
|
addAppPermissionBody: AddAppPermissionBody,
|
|
options?: RequestInit,
|
|
): Promise<AppPermissionLink> => {
|
|
return customFetch<AppPermissionLink>(getAddAppPermissionUrl(id), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(addAppPermissionBody),
|
|
});
|
|
};
|
|
|
|
export const getAddAppPermissionMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof addAppPermission>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddAppPermissionBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof addAppPermission>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddAppPermissionBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["addAppPermission"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof addAppPermission>>,
|
|
{ id: number; data: BodyType<AddAppPermissionBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return addAppPermission(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type AddAppPermissionMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof addAppPermission>>
|
|
>;
|
|
export type AddAppPermissionMutationBody = BodyType<AddAppPermissionBody>;
|
|
export type AddAppPermissionMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Add a required permission to this app (admin)
|
|
*/
|
|
export const useAddAppPermission = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof addAppPermission>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddAppPermissionBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof addAppPermission>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddAppPermissionBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getAddAppPermissionMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* Given a candidate set of permission IDs that would gate this app,
|
|
returns how many users would lose visibility of the app (excluding
|
|
admins, who always see every app), the count of users who currently
|
|
see the app, and the groups that grant the app via `group_apps`. A
|
|
member of any returned group always sees the app regardless of
|
|
permission changes, so listing them lets the admin see which
|
|
populations are protected from the loss.
|
|
|
|
Mirrors `POST /roles/{id}/permissions/impact-preview` so the admin
|
|
UI can show the same kind of warning before committing the change.
|
|
|
|
* @summary Preview the impact of changing the permissions required for an app (admin)
|
|
*/
|
|
export const getPreviewAppPermissionsImpactUrl = (id: number) => {
|
|
return `/api/apps/${id}/permissions/impact-preview`;
|
|
};
|
|
|
|
export const previewAppPermissionsImpact = async (
|
|
id: number,
|
|
appPermissionsImpactBody: AppPermissionsImpactBody,
|
|
options?: RequestInit,
|
|
): Promise<AppPermissionsImpact> => {
|
|
return customFetch<AppPermissionsImpact>(
|
|
getPreviewAppPermissionsImpactUrl(id),
|
|
{
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(appPermissionsImpactBody),
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getPreviewAppPermissionsImpactMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof previewAppPermissionsImpact>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AppPermissionsImpactBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof previewAppPermissionsImpact>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AppPermissionsImpactBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["previewAppPermissionsImpact"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof previewAppPermissionsImpact>>,
|
|
{ id: number; data: BodyType<AppPermissionsImpactBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return previewAppPermissionsImpact(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type PreviewAppPermissionsImpactMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof previewAppPermissionsImpact>>
|
|
>;
|
|
export type PreviewAppPermissionsImpactMutationBody =
|
|
BodyType<AppPermissionsImpactBody>;
|
|
export type PreviewAppPermissionsImpactMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Preview the impact of changing the permissions required for an app (admin)
|
|
*/
|
|
export const usePreviewAppPermissionsImpact = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof previewAppPermissionsImpact>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AppPermissionsImpactBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof previewAppPermissionsImpact>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AppPermissionsImpactBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getPreviewAppPermissionsImpactMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Remove a required permission from this app (admin)
|
|
*/
|
|
export const getRemoveAppPermissionUrl = (id: number, permissionId: number) => {
|
|
return `/api/apps/${id}/permissions/${permissionId}`;
|
|
};
|
|
|
|
export const removeAppPermission = async (
|
|
id: number,
|
|
permissionId: number,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getRemoveAppPermissionUrl(id, permissionId), {
|
|
...options,
|
|
method: "DELETE",
|
|
});
|
|
};
|
|
|
|
export const getRemoveAppPermissionMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof removeAppPermission>>,
|
|
TError,
|
|
{ id: number; permissionId: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof removeAppPermission>>,
|
|
TError,
|
|
{ id: number; permissionId: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["removeAppPermission"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof removeAppPermission>>,
|
|
{ id: number; permissionId: number }
|
|
> = (props) => {
|
|
const { id, permissionId } = props ?? {};
|
|
|
|
return removeAppPermission(id, permissionId, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type RemoveAppPermissionMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof removeAppPermission>>
|
|
>;
|
|
|
|
export type RemoveAppPermissionMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Remove a required permission from this app (admin)
|
|
*/
|
|
export const useRemoveAppPermission = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof removeAppPermission>>,
|
|
TError,
|
|
{ id: number; permissionId: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof removeAppPermission>>,
|
|
TError,
|
|
{ id: number; permissionId: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getRemoveAppPermissionMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Log an app open event for the current user
|
|
*/
|
|
export const getLogAppOpenUrl = (id: number) => {
|
|
return `/api/apps/${id}/open`;
|
|
};
|
|
|
|
export const logAppOpen = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getLogAppOpenUrl(id), {
|
|
...options,
|
|
method: "POST",
|
|
});
|
|
};
|
|
|
|
export const getLogAppOpenMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof logAppOpen>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof logAppOpen>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["logAppOpen"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof logAppOpen>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return logAppOpen(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type LogAppOpenMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof logAppOpen>>
|
|
>;
|
|
|
|
export type LogAppOpenMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Log an app open event for the current user
|
|
*/
|
|
export const useLogAppOpen = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof logAppOpen>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof logAppOpen>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getLogAppOpenMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Set the current user's preferred home apps order
|
|
*/
|
|
export const getUpdateMyAppOrderUrl = () => {
|
|
return `/api/me/app-order`;
|
|
};
|
|
|
|
export const updateMyAppOrder = async (
|
|
updateMyAppOrderBody: UpdateMyAppOrderBody,
|
|
options?: RequestInit,
|
|
): Promise<App[]> => {
|
|
return customFetch<App[]>(getUpdateMyAppOrderUrl(), {
|
|
...options,
|
|
method: "PUT",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateMyAppOrderBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateMyAppOrderMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>,
|
|
TError,
|
|
{ data: BodyType<UpdateMyAppOrderBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>,
|
|
TError,
|
|
{ data: BodyType<UpdateMyAppOrderBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateMyAppOrder"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>,
|
|
{ data: BodyType<UpdateMyAppOrderBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return updateMyAppOrder(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateMyAppOrderMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>
|
|
>;
|
|
export type UpdateMyAppOrderMutationBody = BodyType<UpdateMyAppOrderBody>;
|
|
export type UpdateMyAppOrderMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Set the current user's preferred home apps order
|
|
*/
|
|
export const useUpdateMyAppOrder = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>,
|
|
TError,
|
|
{ data: BodyType<UpdateMyAppOrderBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateMyAppOrder>>,
|
|
TError,
|
|
{ data: BodyType<UpdateMyAppOrderBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateMyAppOrderMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get application settings (public)
|
|
*/
|
|
export const getGetAppSettingsUrl = () => {
|
|
return `/api/settings`;
|
|
};
|
|
|
|
export const getAppSettings = async (
|
|
options?: RequestInit,
|
|
): Promise<AppSettings> => {
|
|
return customFetch<AppSettings>(getGetAppSettingsUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetAppSettingsQueryKey = () => {
|
|
return [`/api/settings`] as const;
|
|
};
|
|
|
|
export const getGetAppSettingsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAppSettings>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAppSettings>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetAppSettingsQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getAppSettings>>> = ({
|
|
signal,
|
|
}) => getAppSettings({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAppSettings>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAppSettingsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAppSettings>>
|
|
>;
|
|
export type GetAppSettingsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get application settings (public)
|
|
*/
|
|
|
|
export function useGetAppSettings<
|
|
TData = Awaited<ReturnType<typeof getAppSettings>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAppSettings>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAppSettingsQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update application settings (admin)
|
|
*/
|
|
export const getUpdateAppSettingsUrl = () => {
|
|
return `/api/settings`;
|
|
};
|
|
|
|
export const updateAppSettings = async (
|
|
updateAppSettingsBody: UpdateAppSettingsBody,
|
|
options?: RequestInit,
|
|
): Promise<AppSettings> => {
|
|
return customFetch<AppSettings>(getUpdateAppSettingsUrl(), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateAppSettingsBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateAppSettingsMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateAppSettings>>,
|
|
TError,
|
|
{ data: BodyType<UpdateAppSettingsBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateAppSettings>>,
|
|
TError,
|
|
{ data: BodyType<UpdateAppSettingsBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateAppSettings"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateAppSettings>>,
|
|
{ data: BodyType<UpdateAppSettingsBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return updateAppSettings(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateAppSettingsMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateAppSettings>>
|
|
>;
|
|
export type UpdateAppSettingsMutationBody = BodyType<UpdateAppSettingsBody>;
|
|
export type UpdateAppSettingsMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Update application settings (admin)
|
|
*/
|
|
export const useUpdateAppSettings = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateAppSettings>>,
|
|
TError,
|
|
{ data: BodyType<UpdateAppSettingsBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateAppSettings>>,
|
|
TError,
|
|
{ data: BodyType<UpdateAppSettingsBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateAppSettingsMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Request a presigned URL for file upload
|
|
*/
|
|
export const getRequestUploadUrlUrl = () => {
|
|
return `/api/storage/uploads/request-url`;
|
|
};
|
|
|
|
export const requestUploadUrl = async (
|
|
requestUploadUrlBody: RequestUploadUrlBody,
|
|
options?: RequestInit,
|
|
): Promise<RequestUploadUrlResponse> => {
|
|
return customFetch<RequestUploadUrlResponse>(getRequestUploadUrlUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(requestUploadUrlBody),
|
|
});
|
|
};
|
|
|
|
export const getRequestUploadUrlMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>,
|
|
TError,
|
|
{ data: BodyType<RequestUploadUrlBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>,
|
|
TError,
|
|
{ data: BodyType<RequestUploadUrlBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["requestUploadUrl"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>,
|
|
{ data: BodyType<RequestUploadUrlBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return requestUploadUrl(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type RequestUploadUrlMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>
|
|
>;
|
|
export type RequestUploadUrlMutationBody = BodyType<RequestUploadUrlBody>;
|
|
export type RequestUploadUrlMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Request a presigned URL for file upload
|
|
*/
|
|
export const useRequestUploadUrl = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>,
|
|
TError,
|
|
{ data: BodyType<RequestUploadUrlBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof requestUploadUrl>>,
|
|
TError,
|
|
{ data: BodyType<RequestUploadUrlBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getRequestUploadUrlMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List all services
|
|
*/
|
|
export const getListServicesUrl = () => {
|
|
return `/api/services`;
|
|
};
|
|
|
|
export const listServices = async (
|
|
options?: RequestInit,
|
|
): Promise<Service[]> => {
|
|
return customFetch<Service[]>(getListServicesUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListServicesQueryKey = () => {
|
|
return [`/api/services`] as const;
|
|
};
|
|
|
|
export const getListServicesQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listServices>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServices>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListServicesQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listServices>>> = ({
|
|
signal,
|
|
}) => listServices({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServices>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListServicesQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listServices>>
|
|
>;
|
|
export type ListServicesQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List all services
|
|
*/
|
|
|
|
export function useListServices<
|
|
TData = Awaited<ReturnType<typeof listServices>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServices>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListServicesQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Create a service (admin)
|
|
*/
|
|
export const getCreateServiceUrl = () => {
|
|
return `/api/services`;
|
|
};
|
|
|
|
export const createService = async (
|
|
createServiceBody: CreateServiceBody,
|
|
options?: RequestInit,
|
|
): Promise<Service> => {
|
|
return customFetch<Service>(getCreateServiceUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(createServiceBody),
|
|
});
|
|
};
|
|
|
|
export const getCreateServiceMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createService>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof createService>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["createService"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof createService>>,
|
|
{ data: BodyType<CreateServiceBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return createService(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type CreateServiceMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof createService>>
|
|
>;
|
|
export type CreateServiceMutationBody = BodyType<CreateServiceBody>;
|
|
export type CreateServiceMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Create a service (admin)
|
|
*/
|
|
export const useCreateService = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createService>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof createService>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getCreateServiceMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get service by ID
|
|
*/
|
|
export const getGetServiceUrl = (id: number) => {
|
|
return `/api/services/${id}`;
|
|
};
|
|
|
|
export const getService = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<Service> => {
|
|
return customFetch<Service>(getGetServiceUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetServiceQueryKey = (id: number) => {
|
|
return [`/api/services/${id}`] as const;
|
|
};
|
|
|
|
export const getGetServiceQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getService>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getService>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetServiceQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getService>>> = ({
|
|
signal,
|
|
}) => getService(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getService>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetServiceQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getService>>
|
|
>;
|
|
export type GetServiceQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get service by ID
|
|
*/
|
|
|
|
export function useGetService<
|
|
TData = Awaited<ReturnType<typeof getService>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getService>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetServiceQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update service (admin)
|
|
*/
|
|
export const getUpdateServiceUrl = (id: number) => {
|
|
return `/api/services/${id}`;
|
|
};
|
|
|
|
export const updateService = async (
|
|
id: number,
|
|
updateServiceBody: UpdateServiceBody,
|
|
options?: RequestInit,
|
|
): Promise<Service> => {
|
|
return customFetch<Service>(getUpdateServiceUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateServiceBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateServiceMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateService>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateService>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateService"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateService>>,
|
|
{ id: number; data: BodyType<UpdateServiceBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return updateService(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateServiceMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateService>>
|
|
>;
|
|
export type UpdateServiceMutationBody = BodyType<UpdateServiceBody>;
|
|
export type UpdateServiceMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Update service (admin)
|
|
*/
|
|
export const useUpdateService = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateService>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateService>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateServiceMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Delete service (admin)
|
|
*/
|
|
export const getDeleteServiceUrl = (
|
|
id: number,
|
|
params?: DeleteServiceParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/services/${id}?${stringifiedParams}`
|
|
: `/api/services/${id}`;
|
|
};
|
|
|
|
export const deleteService = async (
|
|
id: number,
|
|
params?: DeleteServiceParams,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getDeleteServiceUrl(id, params), {
|
|
...options,
|
|
method: "DELETE",
|
|
});
|
|
};
|
|
|
|
export const getDeleteServiceMutationOptions = <
|
|
TError = ErrorType<ServiceDeletionConflict>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteService>>,
|
|
TError,
|
|
{ id: number; params?: DeleteServiceParams },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteService>>,
|
|
TError,
|
|
{ id: number; params?: DeleteServiceParams },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["deleteService"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof deleteService>>,
|
|
{ id: number; params?: DeleteServiceParams }
|
|
> = (props) => {
|
|
const { id, params } = props ?? {};
|
|
|
|
return deleteService(id, params, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type DeleteServiceMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof deleteService>>
|
|
>;
|
|
|
|
export type DeleteServiceMutationError = ErrorType<ServiceDeletionConflict>;
|
|
|
|
/**
|
|
* @summary Delete service (admin)
|
|
*/
|
|
export const useDeleteService = <
|
|
TError = ErrorType<ServiceDeletionConflict>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteService>>,
|
|
TError,
|
|
{ id: number; params?: DeleteServiceParams },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof deleteService>>,
|
|
TError,
|
|
{ id: number; params?: DeleteServiceParams },
|
|
TContext
|
|
> => {
|
|
return useMutation(getDeleteServiceMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Place a service order
|
|
*/
|
|
export const getCreateServiceOrderUrl = () => {
|
|
return `/api/orders`;
|
|
};
|
|
|
|
export const createServiceOrder = async (
|
|
createServiceOrderBody: CreateServiceOrderBody,
|
|
options?: RequestInit,
|
|
): Promise<ServiceOrder> => {
|
|
return customFetch<ServiceOrder>(getCreateServiceOrderUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(createServiceOrderBody),
|
|
});
|
|
};
|
|
|
|
export const getCreateServiceOrderMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createServiceOrder>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceOrderBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof createServiceOrder>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceOrderBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["createServiceOrder"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof createServiceOrder>>,
|
|
{ data: BodyType<CreateServiceOrderBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return createServiceOrder(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type CreateServiceOrderMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof createServiceOrder>>
|
|
>;
|
|
export type CreateServiceOrderMutationBody = BodyType<CreateServiceOrderBody>;
|
|
export type CreateServiceOrderMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Place a service order
|
|
*/
|
|
export const useCreateServiceOrder = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createServiceOrder>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceOrderBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof createServiceOrder>>,
|
|
TError,
|
|
{ data: BodyType<CreateServiceOrderBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getCreateServiceOrderMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List orders placed by the current user
|
|
*/
|
|
export const getListMyServiceOrdersUrl = () => {
|
|
return `/api/orders/my`;
|
|
};
|
|
|
|
export const listMyServiceOrders = async (
|
|
options?: RequestInit,
|
|
): Promise<ServiceOrder[]> => {
|
|
return customFetch<ServiceOrder[]>(getListMyServiceOrdersUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListMyServiceOrdersQueryKey = () => {
|
|
return [`/api/orders/my`] as const;
|
|
};
|
|
|
|
export const getListMyServiceOrdersQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listMyServiceOrders>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listMyServiceOrders>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListMyServiceOrdersQueryKey();
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof listMyServiceOrders>>
|
|
> = ({ signal }) => listMyServiceOrders({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listMyServiceOrders>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListMyServiceOrdersQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listMyServiceOrders>>
|
|
>;
|
|
export type ListMyServiceOrdersQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List orders placed by the current user
|
|
*/
|
|
|
|
export function useListMyServiceOrders<
|
|
TData = Awaited<ReturnType<typeof listMyServiceOrders>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listMyServiceOrders>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListMyServiceOrdersQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary List active orders for receivers (requires orders.receive permission). Returns pending+unassigned orders plus orders assigned to me that are not completed/cancelled.
|
|
*/
|
|
export const getListIncomingServiceOrdersUrl = () => {
|
|
return `/api/orders/incoming`;
|
|
};
|
|
|
|
export const listIncomingServiceOrders = async (
|
|
options?: RequestInit,
|
|
): Promise<ServiceOrder[]> => {
|
|
return customFetch<ServiceOrder[]>(getListIncomingServiceOrdersUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListIncomingServiceOrdersQueryKey = () => {
|
|
return [`/api/orders/incoming`] as const;
|
|
};
|
|
|
|
export const getListIncomingServiceOrdersQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listIncomingServiceOrders>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listIncomingServiceOrders>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ?? getListIncomingServiceOrdersQueryKey();
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof listIncomingServiceOrders>>
|
|
> = ({ signal }) => listIncomingServiceOrders({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listIncomingServiceOrders>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListIncomingServiceOrdersQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listIncomingServiceOrders>>
|
|
>;
|
|
export type ListIncomingServiceOrdersQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List active orders for receivers (requires orders.receive permission). Returns pending+unassigned orders plus orders assigned to me that are not completed/cancelled.
|
|
*/
|
|
|
|
export function useListIncomingServiceOrders<
|
|
TData = Awaited<ReturnType<typeof listIncomingServiceOrders>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listIncomingServiceOrders>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListIncomingServiceOrdersQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update order status. Preparing/completed restricted to assigned receiver or admin; cancelled allowed for owner (while pending|received) or admin (any time); pending/received are restore-from-cancelled transitions allowed for owner or admin.
|
|
*/
|
|
export const getUpdateServiceOrderStatusUrl = (id: number) => {
|
|
return `/api/orders/${id}/status`;
|
|
};
|
|
|
|
export const updateServiceOrderStatus = async (
|
|
id: number,
|
|
updateServiceOrderStatusBody: UpdateServiceOrderStatusBody,
|
|
options?: RequestInit,
|
|
): Promise<ServiceOrder> => {
|
|
return customFetch<ServiceOrder>(getUpdateServiceOrderStatusUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateServiceOrderStatusBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateServiceOrderStatusMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateServiceOrderStatus>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceOrderStatusBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateServiceOrderStatus>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceOrderStatusBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateServiceOrderStatus"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateServiceOrderStatus>>,
|
|
{ id: number; data: BodyType<UpdateServiceOrderStatusBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return updateServiceOrderStatus(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateServiceOrderStatusMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateServiceOrderStatus>>
|
|
>;
|
|
export type UpdateServiceOrderStatusMutationBody =
|
|
BodyType<UpdateServiceOrderStatusBody>;
|
|
export type UpdateServiceOrderStatusMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Update order status. Preparing/completed restricted to assigned receiver or admin; cancelled allowed for owner (while pending|received) or admin (any time); pending/received are restore-from-cancelled transitions allowed for owner or admin.
|
|
*/
|
|
export const useUpdateServiceOrderStatus = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateServiceOrderStatus>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceOrderStatusBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateServiceOrderStatus>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateServiceOrderStatusBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateServiceOrderStatusMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Receiver atomically claims a pending order (sets status=received, assigned_to=current user). Requires orders.receive permission. Returns 409 already_claimed if the order is no longer pending+unassigned.
|
|
*/
|
|
export const getConfirmServiceOrderReceiptUrl = (id: number) => {
|
|
return `/api/orders/${id}/confirm-receipt`;
|
|
};
|
|
|
|
export const confirmServiceOrderReceipt = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<ServiceOrder> => {
|
|
return customFetch<ServiceOrder>(getConfirmServiceOrderReceiptUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
});
|
|
};
|
|
|
|
export const getConfirmServiceOrderReceiptMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof confirmServiceOrderReceipt>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof confirmServiceOrderReceipt>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["confirmServiceOrderReceipt"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof confirmServiceOrderReceipt>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return confirmServiceOrderReceipt(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type ConfirmServiceOrderReceiptMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof confirmServiceOrderReceipt>>
|
|
>;
|
|
|
|
export type ConfirmServiceOrderReceiptMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Receiver atomically claims a pending order (sets status=received, assigned_to=current user). Requires orders.receive permission. Returns 409 already_claimed if the order is no longer pending+unassigned.
|
|
*/
|
|
export const useConfirmServiceOrderReceipt = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof confirmServiceOrderReceipt>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof confirmServiceOrderReceipt>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getConfirmServiceOrderReceiptMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List service categories
|
|
*/
|
|
export const getListServiceCategoriesUrl = () => {
|
|
return `/api/service-categories`;
|
|
};
|
|
|
|
export const listServiceCategories = async (
|
|
options?: RequestInit,
|
|
): Promise<ServiceCategory[]> => {
|
|
return customFetch<ServiceCategory[]>(getListServiceCategoriesUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListServiceCategoriesQueryKey = () => {
|
|
return [`/api/service-categories`] as const;
|
|
};
|
|
|
|
export const getListServiceCategoriesQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listServiceCategories>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServiceCategories>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListServiceCategoriesQueryKey();
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof listServiceCategories>>
|
|
> = ({ signal }) => listServiceCategories({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServiceCategories>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListServiceCategoriesQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listServiceCategories>>
|
|
>;
|
|
export type ListServiceCategoriesQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List service categories
|
|
*/
|
|
|
|
export function useListServiceCategories<
|
|
TData = Awaited<ReturnType<typeof listServiceCategories>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listServiceCategories>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListServiceCategoriesQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary List conversations for current user
|
|
*/
|
|
export const getListConversationsUrl = () => {
|
|
return `/api/conversations`;
|
|
};
|
|
|
|
export const listConversations = async (
|
|
options?: RequestInit,
|
|
): Promise<ConversationWithDetails[]> => {
|
|
return customFetch<ConversationWithDetails[]>(getListConversationsUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListConversationsQueryKey = () => {
|
|
return [`/api/conversations`] as const;
|
|
};
|
|
|
|
export const getListConversationsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listConversations>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listConversations>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListConversationsQueryKey();
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof listConversations>>
|
|
> = ({ signal }) => listConversations({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listConversations>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListConversationsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listConversations>>
|
|
>;
|
|
export type ListConversationsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List conversations for current user
|
|
*/
|
|
|
|
export function useListConversations<
|
|
TData = Awaited<ReturnType<typeof listConversations>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listConversations>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListConversationsQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Create a conversation
|
|
*/
|
|
export const getCreateConversationUrl = () => {
|
|
return `/api/conversations`;
|
|
};
|
|
|
|
export const createConversation = async (
|
|
createConversationBody: CreateConversationBody,
|
|
options?: RequestInit,
|
|
): Promise<ConversationWithDetails> => {
|
|
return customFetch<ConversationWithDetails>(getCreateConversationUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(createConversationBody),
|
|
});
|
|
};
|
|
|
|
export const getCreateConversationMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createConversation>>,
|
|
TError,
|
|
{ data: BodyType<CreateConversationBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof createConversation>>,
|
|
TError,
|
|
{ data: BodyType<CreateConversationBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["createConversation"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof createConversation>>,
|
|
{ data: BodyType<CreateConversationBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return createConversation(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type CreateConversationMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof createConversation>>
|
|
>;
|
|
export type CreateConversationMutationBody = BodyType<CreateConversationBody>;
|
|
export type CreateConversationMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Create a conversation
|
|
*/
|
|
export const useCreateConversation = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createConversation>>,
|
|
TError,
|
|
{ data: BodyType<CreateConversationBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof createConversation>>,
|
|
TError,
|
|
{ data: BodyType<CreateConversationBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getCreateConversationMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get conversation by ID
|
|
*/
|
|
export const getGetConversationUrl = (id: number) => {
|
|
return `/api/conversations/${id}`;
|
|
};
|
|
|
|
export const getConversation = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<ConversationWithDetails> => {
|
|
return customFetch<ConversationWithDetails>(getGetConversationUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetConversationQueryKey = (id: number) => {
|
|
return [`/api/conversations/${id}`] as const;
|
|
};
|
|
|
|
export const getGetConversationQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getConversation>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getConversation>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetConversationQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getConversation>>> = ({
|
|
signal,
|
|
}) => getConversation(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getConversation>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetConversationQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getConversation>>
|
|
>;
|
|
export type GetConversationQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get conversation by ID
|
|
*/
|
|
|
|
export function useGetConversation<
|
|
TData = Awaited<ReturnType<typeof getConversation>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getConversation>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetConversationQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update conversation properties (admin only)
|
|
*/
|
|
export const getUpdateConversationUrl = (id: number) => {
|
|
return `/api/conversations/${id}`;
|
|
};
|
|
|
|
export const updateConversation = async (
|
|
id: number,
|
|
updateConversationBody: UpdateConversationBody,
|
|
options?: RequestInit,
|
|
): Promise<ConversationWithDetails> => {
|
|
return customFetch<ConversationWithDetails>(getUpdateConversationUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateConversationBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateConversationMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateConversation>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateConversationBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateConversation>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateConversationBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateConversation"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateConversation>>,
|
|
{ id: number; data: BodyType<UpdateConversationBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return updateConversation(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateConversationMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateConversation>>
|
|
>;
|
|
export type UpdateConversationMutationBody = BodyType<UpdateConversationBody>;
|
|
export type UpdateConversationMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Update conversation properties (admin only)
|
|
*/
|
|
export const useUpdateConversation = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateConversation>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateConversationBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateConversation>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateConversationBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateConversationMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Add participants to a group conversation (admin only)
|
|
*/
|
|
export const getAddConversationParticipantsUrl = (id: number) => {
|
|
return `/api/conversations/${id}/participants`;
|
|
};
|
|
|
|
export const addConversationParticipants = async (
|
|
id: number,
|
|
addParticipantsBody: AddParticipantsBody,
|
|
options?: RequestInit,
|
|
): Promise<ConversationWithDetails> => {
|
|
return customFetch<ConversationWithDetails>(
|
|
getAddConversationParticipantsUrl(id),
|
|
{
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(addParticipantsBody),
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getAddConversationParticipantsMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof addConversationParticipants>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddParticipantsBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof addConversationParticipants>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddParticipantsBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["addConversationParticipants"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof addConversationParticipants>>,
|
|
{ id: number; data: BodyType<AddParticipantsBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return addConversationParticipants(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type AddConversationParticipantsMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof addConversationParticipants>>
|
|
>;
|
|
export type AddConversationParticipantsMutationBody =
|
|
BodyType<AddParticipantsBody>;
|
|
export type AddConversationParticipantsMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Add participants to a group conversation (admin only)
|
|
*/
|
|
export const useAddConversationParticipants = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof addConversationParticipants>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddParticipantsBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof addConversationParticipants>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddParticipantsBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getAddConversationParticipantsMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Remove a participant from a group conversation (admin only)
|
|
*/
|
|
export const getRemoveConversationParticipantUrl = (
|
|
id: number,
|
|
userId: number,
|
|
) => {
|
|
return `/api/conversations/${id}/participants/${userId}`;
|
|
};
|
|
|
|
export const removeConversationParticipant = async (
|
|
id: number,
|
|
userId: number,
|
|
options?: RequestInit,
|
|
): Promise<ConversationWithDetails> => {
|
|
return customFetch<ConversationWithDetails>(
|
|
getRemoveConversationParticipantUrl(id, userId),
|
|
{
|
|
...options,
|
|
method: "DELETE",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getRemoveConversationParticipantMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof removeConversationParticipant>>,
|
|
TError,
|
|
{ id: number; userId: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof removeConversationParticipant>>,
|
|
TError,
|
|
{ id: number; userId: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["removeConversationParticipant"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof removeConversationParticipant>>,
|
|
{ id: number; userId: number }
|
|
> = (props) => {
|
|
const { id, userId } = props ?? {};
|
|
|
|
return removeConversationParticipant(id, userId, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type RemoveConversationParticipantMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof removeConversationParticipant>>
|
|
>;
|
|
|
|
export type RemoveConversationParticipantMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Remove a participant from a group conversation (admin only)
|
|
*/
|
|
export const useRemoveConversationParticipant = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof removeConversationParticipant>>,
|
|
TError,
|
|
{ id: number; userId: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof removeConversationParticipant>>,
|
|
TError,
|
|
{ id: number; userId: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getRemoveConversationParticipantMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Update per-user state (mute, archive)
|
|
*/
|
|
export const getUpdateConversationStateUrl = (id: number) => {
|
|
return `/api/conversations/${id}/state`;
|
|
};
|
|
|
|
export const updateConversationState = async (
|
|
id: number,
|
|
updateConversationStateBody: UpdateConversationStateBody,
|
|
options?: RequestInit,
|
|
): Promise<ConversationWithDetails> => {
|
|
return customFetch<ConversationWithDetails>(
|
|
getUpdateConversationStateUrl(id),
|
|
{
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateConversationStateBody),
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getUpdateConversationStateMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateConversationState>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateConversationStateBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateConversationState>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateConversationStateBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateConversationState"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateConversationState>>,
|
|
{ id: number; data: BodyType<UpdateConversationStateBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return updateConversationState(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateConversationStateMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateConversationState>>
|
|
>;
|
|
export type UpdateConversationStateMutationBody =
|
|
BodyType<UpdateConversationStateBody>;
|
|
export type UpdateConversationStateMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Update per-user state (mute, archive)
|
|
*/
|
|
export const useUpdateConversationState = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateConversationState>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateConversationStateBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateConversationState>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateConversationStateBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateConversationStateMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Leave a group conversation
|
|
*/
|
|
export const getLeaveConversationUrl = (id: number) => {
|
|
return `/api/conversations/${id}/leave`;
|
|
};
|
|
|
|
export const leaveConversation = async (
|
|
id: number,
|
|
leaveConversationBody?: LeaveConversationBody,
|
|
options?: RequestInit,
|
|
): Promise<SuccessResponse> => {
|
|
return customFetch<SuccessResponse>(getLeaveConversationUrl(id), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(leaveConversationBody),
|
|
});
|
|
};
|
|
|
|
export const getLeaveConversationMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof leaveConversation>>,
|
|
TError,
|
|
{ id: number; data: BodyType<LeaveConversationBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof leaveConversation>>,
|
|
TError,
|
|
{ id: number; data: BodyType<LeaveConversationBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["leaveConversation"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof leaveConversation>>,
|
|
{ id: number; data: BodyType<LeaveConversationBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return leaveConversation(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type LeaveConversationMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof leaveConversation>>
|
|
>;
|
|
export type LeaveConversationMutationBody = BodyType<LeaveConversationBody>;
|
|
export type LeaveConversationMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Leave a group conversation
|
|
*/
|
|
export const useLeaveConversation = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof leaveConversation>>,
|
|
TError,
|
|
{ id: number; data: BodyType<LeaveConversationBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof leaveConversation>>,
|
|
TError,
|
|
{ id: number; data: BodyType<LeaveConversationBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getLeaveConversationMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List messages in a conversation
|
|
*/
|
|
export const getListMessagesUrl = (id: number) => {
|
|
return `/api/conversations/${id}/messages`;
|
|
};
|
|
|
|
export const listMessages = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<MessageWithSender[]> => {
|
|
return customFetch<MessageWithSender[]>(getListMessagesUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListMessagesQueryKey = (id: number) => {
|
|
return [`/api/conversations/${id}/messages`] as const;
|
|
};
|
|
|
|
export const getListMessagesQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listMessages>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listMessages>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListMessagesQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listMessages>>> = ({
|
|
signal,
|
|
}) => listMessages(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listMessages>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListMessagesQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listMessages>>
|
|
>;
|
|
export type ListMessagesQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List messages in a conversation
|
|
*/
|
|
|
|
export function useListMessages<
|
|
TData = Awaited<ReturnType<typeof listMessages>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listMessages>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListMessagesQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Send a message
|
|
*/
|
|
export const getSendMessageUrl = (id: number) => {
|
|
return `/api/conversations/${id}/messages`;
|
|
};
|
|
|
|
export const sendMessage = async (
|
|
id: number,
|
|
sendMessageBody: SendMessageBody,
|
|
options?: RequestInit,
|
|
): Promise<MessageWithSender> => {
|
|
return customFetch<MessageWithSender>(getSendMessageUrl(id), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(sendMessageBody),
|
|
});
|
|
};
|
|
|
|
export const getSendMessageMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof sendMessage>>,
|
|
TError,
|
|
{ id: number; data: BodyType<SendMessageBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof sendMessage>>,
|
|
TError,
|
|
{ id: number; data: BodyType<SendMessageBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["sendMessage"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof sendMessage>>,
|
|
{ id: number; data: BodyType<SendMessageBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return sendMessage(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type SendMessageMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof sendMessage>>
|
|
>;
|
|
export type SendMessageMutationBody = BodyType<SendMessageBody>;
|
|
export type SendMessageMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Send a message
|
|
*/
|
|
export const useSendMessage = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof sendMessage>>,
|
|
TError,
|
|
{ id: number; data: BodyType<SendMessageBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof sendMessage>>,
|
|
TError,
|
|
{ id: number; data: BodyType<SendMessageBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getSendMessageMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Mark all messages in conversation as read
|
|
*/
|
|
export const getMarkConversationReadUrl = (id: number) => {
|
|
return `/api/conversations/${id}/read`;
|
|
};
|
|
|
|
export const markConversationRead = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<SuccessResponse> => {
|
|
return customFetch<SuccessResponse>(getMarkConversationReadUrl(id), {
|
|
...options,
|
|
method: "POST",
|
|
});
|
|
};
|
|
|
|
export const getMarkConversationReadMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markConversationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof markConversationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["markConversationRead"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof markConversationRead>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return markConversationRead(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type MarkConversationReadMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof markConversationRead>>
|
|
>;
|
|
|
|
export type MarkConversationReadMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Mark all messages in conversation as read
|
|
*/
|
|
export const useMarkConversationRead = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markConversationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof markConversationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getMarkConversationReadMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List notifications for current user
|
|
*/
|
|
export const getListNotificationsUrl = () => {
|
|
return `/api/notifications`;
|
|
};
|
|
|
|
export const listNotifications = async (
|
|
options?: RequestInit,
|
|
): Promise<Notification[]> => {
|
|
return customFetch<Notification[]>(getListNotificationsUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListNotificationsQueryKey = () => {
|
|
return [`/api/notifications`] as const;
|
|
};
|
|
|
|
export const getListNotificationsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listNotifications>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listNotifications>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListNotificationsQueryKey();
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof listNotifications>>
|
|
> = ({ signal }) => listNotifications({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listNotifications>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListNotificationsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listNotifications>>
|
|
>;
|
|
export type ListNotificationsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List notifications for current user
|
|
*/
|
|
|
|
export function useListNotifications<
|
|
TData = Awaited<ReturnType<typeof listNotifications>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listNotifications>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListNotificationsQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Mark notification as read
|
|
*/
|
|
export const getMarkNotificationReadUrl = (id: number) => {
|
|
return `/api/notifications/${id}/read`;
|
|
};
|
|
|
|
export const markNotificationRead = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<Notification> => {
|
|
return customFetch<Notification>(getMarkNotificationReadUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
});
|
|
};
|
|
|
|
export const getMarkNotificationReadMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markNotificationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof markNotificationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["markNotificationRead"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof markNotificationRead>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return markNotificationRead(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type MarkNotificationReadMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof markNotificationRead>>
|
|
>;
|
|
|
|
export type MarkNotificationReadMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Mark notification as read
|
|
*/
|
|
export const useMarkNotificationRead = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markNotificationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof markNotificationRead>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getMarkNotificationReadMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Mark all notifications as read
|
|
*/
|
|
export const getMarkAllNotificationsReadUrl = () => {
|
|
return `/api/notifications/read-all`;
|
|
};
|
|
|
|
export const markAllNotificationsRead = async (
|
|
options?: RequestInit,
|
|
): Promise<SuccessResponse> => {
|
|
return customFetch<SuccessResponse>(getMarkAllNotificationsReadUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
});
|
|
};
|
|
|
|
export const getMarkAllNotificationsReadMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["markAllNotificationsRead"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>,
|
|
void
|
|
> = () => {
|
|
return markAllNotificationsRead(requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type MarkAllNotificationsReadMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>
|
|
>;
|
|
|
|
export type MarkAllNotificationsReadMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Mark all notifications as read
|
|
*/
|
|
export const useMarkAllNotificationsRead = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof markAllNotificationsRead>>,
|
|
TError,
|
|
void,
|
|
TContext
|
|
> => {
|
|
return useMutation(getMarkAllNotificationsReadMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List all users (admin)
|
|
*/
|
|
export const getListUsersUrl = (params?: ListUsersParams) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/users?${stringifiedParams}`
|
|
: `/api/users`;
|
|
};
|
|
|
|
export const listUsers = async (
|
|
params?: ListUsersParams,
|
|
options?: RequestInit,
|
|
): Promise<UserProfile[]> => {
|
|
return customFetch<UserProfile[]>(getListUsersUrl(params), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListUsersQueryKey = (params?: ListUsersParams) => {
|
|
return [`/api/users`, ...(params ? [params] : [])] as const;
|
|
};
|
|
|
|
export const getListUsersQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listUsers>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
params?: ListUsersParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listUsers>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListUsersQueryKey(params);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listUsers>>> = ({
|
|
signal,
|
|
}) => listUsers(params, { signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listUsers>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListUsersQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listUsers>>
|
|
>;
|
|
export type ListUsersQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List all users (admin)
|
|
*/
|
|
|
|
export function useListUsers<
|
|
TData = Awaited<ReturnType<typeof listUsers>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
params?: ListUsersParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listUsers>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListUsersQueryOptions(params, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Create a user (admin)
|
|
*/
|
|
export const getCreateUserUrl = () => {
|
|
return `/api/users`;
|
|
};
|
|
|
|
export const createUser = async (
|
|
createUserBody: CreateUserBody,
|
|
options?: RequestInit,
|
|
): Promise<UserProfile> => {
|
|
return customFetch<UserProfile>(getCreateUserUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(createUserBody),
|
|
});
|
|
};
|
|
|
|
export const getCreateUserMutationOptions = <
|
|
TError = ErrorType<void>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createUser>>,
|
|
TError,
|
|
{ data: BodyType<CreateUserBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof createUser>>,
|
|
TError,
|
|
{ data: BodyType<CreateUserBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["createUser"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof createUser>>,
|
|
{ data: BodyType<CreateUserBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return createUser(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type CreateUserMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof createUser>>
|
|
>;
|
|
export type CreateUserMutationBody = BodyType<CreateUserBody>;
|
|
export type CreateUserMutationError = ErrorType<void>;
|
|
|
|
/**
|
|
* @summary Create a user (admin)
|
|
*/
|
|
export const useCreateUser = <
|
|
TError = ErrorType<void>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createUser>>,
|
|
TError,
|
|
{ data: BodyType<CreateUserBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof createUser>>,
|
|
TError,
|
|
{ data: BodyType<CreateUserBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getCreateUserMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get user by ID (admin)
|
|
*/
|
|
export const getGetUserUrl = (id: number) => {
|
|
return `/api/users/${id}`;
|
|
};
|
|
|
|
export const getUser = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<UserProfile> => {
|
|
return customFetch<UserProfile>(getGetUserUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetUserQueryKey = (id: number) => {
|
|
return [`/api/users/${id}`] as const;
|
|
};
|
|
|
|
export const getGetUserQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getUser>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getUser>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetUserQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getUser>>> = ({
|
|
signal,
|
|
}) => getUser(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<Awaited<ReturnType<typeof getUser>>, TError, TData> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
};
|
|
|
|
export type GetUserQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getUser>>
|
|
>;
|
|
export type GetUserQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get user by ID (admin)
|
|
*/
|
|
|
|
export function useGetUser<
|
|
TData = Awaited<ReturnType<typeof getUser>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof getUser>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetUserQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update user (admin)
|
|
*/
|
|
export const getUpdateUserUrl = (id: number) => {
|
|
return `/api/users/${id}`;
|
|
};
|
|
|
|
export const updateUser = async (
|
|
id: number,
|
|
updateUserBody: UpdateUserBody,
|
|
options?: RequestInit,
|
|
): Promise<UserProfile> => {
|
|
return customFetch<UserProfile>(getUpdateUserUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateUserBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateUserMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateUser>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateUserBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateUser>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateUserBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateUser"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateUser>>,
|
|
{ id: number; data: BodyType<UpdateUserBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return updateUser(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateUserMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateUser>>
|
|
>;
|
|
export type UpdateUserMutationBody = BodyType<UpdateUserBody>;
|
|
export type UpdateUserMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Update user (admin)
|
|
*/
|
|
export const useUpdateUser = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateUser>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateUserBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateUser>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateUserBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateUserMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Delete user (admin)
|
|
*/
|
|
export const getDeleteUserUrl = (id: number, params?: DeleteUserParams) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/users/${id}?${stringifiedParams}`
|
|
: `/api/users/${id}`;
|
|
};
|
|
|
|
export const deleteUser = async (
|
|
id: number,
|
|
params?: DeleteUserParams,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getDeleteUserUrl(id, params), {
|
|
...options,
|
|
method: "DELETE",
|
|
});
|
|
};
|
|
|
|
export const getDeleteUserMutationOptions = <
|
|
TError = ErrorType<UserDeletionConflict>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteUser>>,
|
|
TError,
|
|
{ id: number; params?: DeleteUserParams },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteUser>>,
|
|
TError,
|
|
{ id: number; params?: DeleteUserParams },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["deleteUser"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof deleteUser>>,
|
|
{ id: number; params?: DeleteUserParams }
|
|
> = (props) => {
|
|
const { id, params } = props ?? {};
|
|
|
|
return deleteUser(id, params, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type DeleteUserMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof deleteUser>>
|
|
>;
|
|
|
|
export type DeleteUserMutationError = ErrorType<UserDeletionConflict>;
|
|
|
|
/**
|
|
* @summary Delete user (admin)
|
|
*/
|
|
export const useDeleteUser = <
|
|
TError = ErrorType<UserDeletionConflict>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteUser>>,
|
|
TError,
|
|
{ id: number; params?: DeleteUserParams },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof deleteUser>>,
|
|
TError,
|
|
{ id: number; params?: DeleteUserParams },
|
|
TContext
|
|
> => {
|
|
return useMutation(getDeleteUserMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* Permanently deletes the order. Allowed when the caller owns the order
|
|
AND it is in a terminal status (completed/cancelled), OR the caller is
|
|
an admin (any status).
|
|
|
|
* @summary Delete a service order
|
|
*/
|
|
export const getDeleteServiceOrderUrl = (id: number) => {
|
|
return `/api/orders/${id}`;
|
|
};
|
|
|
|
export const deleteServiceOrder = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getDeleteServiceOrderUrl(id), {
|
|
...options,
|
|
method: "DELETE",
|
|
});
|
|
};
|
|
|
|
export const getDeleteServiceOrderMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteServiceOrder>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteServiceOrder>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["deleteServiceOrder"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof deleteServiceOrder>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return deleteServiceOrder(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type DeleteServiceOrderMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof deleteServiceOrder>>
|
|
>;
|
|
|
|
export type DeleteServiceOrderMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Delete a service order
|
|
*/
|
|
export const useDeleteServiceOrder = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteServiceOrder>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof deleteServiceOrder>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getDeleteServiceOrderMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Idempotently add a role to a user (admin)
|
|
*/
|
|
export const getAddUserRoleUrl = (id: number) => {
|
|
return `/api/users/${id}/roles`;
|
|
};
|
|
|
|
export const addUserRole = async (
|
|
id: number,
|
|
addUserRoleBody: AddUserRoleBody,
|
|
options?: RequestInit,
|
|
): Promise<UserProfile> => {
|
|
return customFetch<UserProfile>(getAddUserRoleUrl(id), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(addUserRoleBody),
|
|
});
|
|
};
|
|
|
|
export const getAddUserRoleMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof addUserRole>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddUserRoleBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof addUserRole>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddUserRoleBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["addUserRole"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof addUserRole>>,
|
|
{ id: number; data: BodyType<AddUserRoleBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return addUserRole(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type AddUserRoleMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof addUserRole>>
|
|
>;
|
|
export type AddUserRoleMutationBody = BodyType<AddUserRoleBody>;
|
|
export type AddUserRoleMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Idempotently add a role to a user (admin)
|
|
*/
|
|
export const useAddUserRole = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof addUserRole>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddUserRoleBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof addUserRole>>,
|
|
TError,
|
|
{ id: number; data: BodyType<AddUserRoleBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getAddUserRoleMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Idempotently remove a role from a user (admin)
|
|
*/
|
|
export const getRemoveUserRoleUrl = (id: number, roleName: string) => {
|
|
return `/api/users/${id}/roles/${roleName}`;
|
|
};
|
|
|
|
export const removeUserRole = async (
|
|
id: number,
|
|
roleName: string,
|
|
options?: RequestInit,
|
|
): Promise<UserProfile> => {
|
|
return customFetch<UserProfile>(getRemoveUserRoleUrl(id, roleName), {
|
|
...options,
|
|
method: "DELETE",
|
|
});
|
|
};
|
|
|
|
export const getRemoveUserRoleMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof removeUserRole>>,
|
|
TError,
|
|
{ id: number; roleName: string },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof removeUserRole>>,
|
|
TError,
|
|
{ id: number; roleName: string },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["removeUserRole"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof removeUserRole>>,
|
|
{ id: number; roleName: string }
|
|
> = (props) => {
|
|
const { id, roleName } = props ?? {};
|
|
|
|
return removeUserRole(id, roleName, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type RemoveUserRoleMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof removeUserRole>>
|
|
>;
|
|
|
|
export type RemoveUserRoleMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Idempotently remove a role from a user (admin)
|
|
*/
|
|
export const useRemoveUserRole = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof removeUserRole>>,
|
|
TError,
|
|
{ id: number; roleName: string },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof removeUserRole>>,
|
|
TError,
|
|
{ id: number; roleName: string },
|
|
TContext
|
|
> => {
|
|
return useMutation(getRemoveUserRoleMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List all available permissions (admin)
|
|
*/
|
|
export const getListPermissionsUrl = () => {
|
|
return `/api/permissions`;
|
|
};
|
|
|
|
export const listPermissions = async (
|
|
options?: RequestInit,
|
|
): Promise<Permission[]> => {
|
|
return customFetch<Permission[]>(getListPermissionsUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListPermissionsQueryKey = () => {
|
|
return [`/api/permissions`] as const;
|
|
};
|
|
|
|
export const getListPermissionsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listPermissions>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listPermissions>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListPermissionsQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listPermissions>>> = ({
|
|
signal,
|
|
}) => listPermissions({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listPermissions>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListPermissionsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listPermissions>>
|
|
>;
|
|
export type ListPermissionsQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List all available permissions (admin)
|
|
*/
|
|
|
|
export function useListPermissions<
|
|
TData = Awaited<ReturnType<typeof listPermissions>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listPermissions>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListPermissionsQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary List roles (admin)
|
|
*/
|
|
export const getListRolesUrl = () => {
|
|
return `/api/roles`;
|
|
};
|
|
|
|
export const listRoles = async (options?: RequestInit): Promise<Role[]> => {
|
|
return customFetch<Role[]>(getListRolesUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListRolesQueryKey = () => {
|
|
return [`/api/roles`] as const;
|
|
};
|
|
|
|
export const getListRolesQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listRoles>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof listRoles>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListRolesQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listRoles>>> = ({
|
|
signal,
|
|
}) => listRoles({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listRoles>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListRolesQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listRoles>>
|
|
>;
|
|
export type ListRolesQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List roles (admin)
|
|
*/
|
|
|
|
export function useListRoles<
|
|
TData = Awaited<ReturnType<typeof listRoles>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<Awaited<ReturnType<typeof listRoles>>, TError, TData>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListRolesQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Create role (admin)
|
|
*/
|
|
export const getCreateRoleUrl = () => {
|
|
return `/api/roles`;
|
|
};
|
|
|
|
export const createRole = async (
|
|
createRoleBody: CreateRoleBody,
|
|
options?: RequestInit,
|
|
): Promise<Role> => {
|
|
return customFetch<Role>(getCreateRoleUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(createRoleBody),
|
|
});
|
|
};
|
|
|
|
export const getCreateRoleMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createRole>>,
|
|
TError,
|
|
{ data: BodyType<CreateRoleBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof createRole>>,
|
|
TError,
|
|
{ data: BodyType<CreateRoleBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["createRole"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof createRole>>,
|
|
{ data: BodyType<CreateRoleBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return createRole(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type CreateRoleMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof createRole>>
|
|
>;
|
|
export type CreateRoleMutationBody = BodyType<CreateRoleBody>;
|
|
export type CreateRoleMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Create role (admin)
|
|
*/
|
|
export const useCreateRole = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createRole>>,
|
|
TError,
|
|
{ data: BodyType<CreateRoleBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof createRole>>,
|
|
TError,
|
|
{ data: BodyType<CreateRoleBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getCreateRoleMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Update role name and descriptions (admin)
|
|
*/
|
|
export const getUpdateRoleUrl = (id: number) => {
|
|
return `/api/roles/${id}`;
|
|
};
|
|
|
|
export const updateRole = async (
|
|
id: number,
|
|
updateRoleBody: UpdateRoleBody,
|
|
options?: RequestInit,
|
|
): Promise<Role> => {
|
|
return customFetch<Role>(getUpdateRoleUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateRoleBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateRoleMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateRole>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateRoleBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateRole>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateRoleBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateRole"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateRole>>,
|
|
{ id: number; data: BodyType<UpdateRoleBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return updateRole(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateRoleMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateRole>>
|
|
>;
|
|
export type UpdateRoleMutationBody = BodyType<UpdateRoleBody>;
|
|
export type UpdateRoleMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Update role name and descriptions (admin)
|
|
*/
|
|
export const useUpdateRole = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateRole>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateRoleBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateRole>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateRoleBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateRoleMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Delete role (admin)
|
|
*/
|
|
export const getDeleteRoleUrl = (id: number) => {
|
|
return `/api/roles/${id}`;
|
|
};
|
|
|
|
export const deleteRole = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getDeleteRoleUrl(id), {
|
|
...options,
|
|
method: "DELETE",
|
|
});
|
|
};
|
|
|
|
export const getDeleteRoleMutationOptions = <
|
|
TError = ErrorType<ErrorResponse | RoleDeletionConflict>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteRole>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteRole>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["deleteRole"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof deleteRole>>,
|
|
{ id: number }
|
|
> = (props) => {
|
|
const { id } = props ?? {};
|
|
|
|
return deleteRole(id, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type DeleteRoleMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof deleteRole>>
|
|
>;
|
|
|
|
export type DeleteRoleMutationError = ErrorType<
|
|
ErrorResponse | RoleDeletionConflict
|
|
>;
|
|
|
|
/**
|
|
* @summary Delete role (admin)
|
|
*/
|
|
export const useDeleteRole = <
|
|
TError = ErrorType<ErrorResponse | RoleDeletionConflict>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteRole>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof deleteRole>>,
|
|
TError,
|
|
{ id: number },
|
|
TContext
|
|
> => {
|
|
return useMutation(getDeleteRoleMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Count users and groups currently assigned to a role (admin)
|
|
*/
|
|
export const getGetRoleUsageUrl = (id: number) => {
|
|
return `/api/roles/${id}/usage`;
|
|
};
|
|
|
|
export const getRoleUsage = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<RoleUsage> => {
|
|
return customFetch<RoleUsage>(getGetRoleUsageUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetRoleUsageQueryKey = (id: number) => {
|
|
return [`/api/roles/${id}/usage`] as const;
|
|
};
|
|
|
|
export const getGetRoleUsageQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getRoleUsage>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getRoleUsage>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetRoleUsageQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getRoleUsage>>> = ({
|
|
signal,
|
|
}) => getRoleUsage(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getRoleUsage>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetRoleUsageQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getRoleUsage>>
|
|
>;
|
|
export type GetRoleUsageQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Count users and groups currently assigned to a role (admin)
|
|
*/
|
|
|
|
export function useGetRoleUsage<
|
|
TData = Awaited<ReturnType<typeof getRoleUsage>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getRoleUsage>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetRoleUsageQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* Returns permission-change audit records for the given role, newest
|
|
first. Supports offset-based pagination via `limit`/`offset` and
|
|
optional filters by acting user (`actorUserId`) and a date range
|
|
(`from`/`to`, inclusive UTC days). The response includes the total
|
|
matching count and the next offset to load (or `null` when the end
|
|
has been reached). Each entry captures the actor (if known), the
|
|
previous permission IDs, the new permission IDs, and the timestamp.
|
|
|
|
* @summary List recent permission-change audit entries for a role (admin)
|
|
*/
|
|
export const getGetRolePermissionAuditUrl = (
|
|
id: number,
|
|
params?: GetRolePermissionAuditParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/roles/${id}/audit?${stringifiedParams}`
|
|
: `/api/roles/${id}/audit`;
|
|
};
|
|
|
|
export const getRolePermissionAudit = async (
|
|
id: number,
|
|
params?: GetRolePermissionAuditParams,
|
|
options?: RequestInit,
|
|
): Promise<RolePermissionAuditList> => {
|
|
return customFetch<RolePermissionAuditList>(
|
|
getGetRolePermissionAuditUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetRolePermissionAuditQueryKey = (
|
|
id: number,
|
|
params?: GetRolePermissionAuditParams,
|
|
) => {
|
|
return [`/api/roles/${id}/audit`, ...(params ? [params] : [])] as const;
|
|
};
|
|
|
|
export const getGetRolePermissionAuditQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getRolePermissionAudit>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetRolePermissionAuditParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getRolePermissionAudit>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ?? getGetRolePermissionAuditQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getRolePermissionAudit>>
|
|
> = ({ signal }) =>
|
|
getRolePermissionAudit(id, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getRolePermissionAudit>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetRolePermissionAuditQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getRolePermissionAudit>>
|
|
>;
|
|
export type GetRolePermissionAuditQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List recent permission-change audit entries for a role (admin)
|
|
*/
|
|
|
|
export function useGetRolePermissionAudit<
|
|
TData = Awaited<ReturnType<typeof getRolePermissionAudit>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetRolePermissionAuditParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getRolePermissionAudit>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetRolePermissionAuditQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* Given a candidate set of permission IDs for the role, returns the list of
|
|
permissions that would be removed and, for each one, how many users would
|
|
lose the permission (because they hold this role directly or via a group
|
|
and have no other role granting the permission), plus the groups that
|
|
currently grant this role.
|
|
|
|
* @summary Preview the impact of changing a role's permission set (admin)
|
|
*/
|
|
export const getPreviewRolePermissionsImpactUrl = (id: number) => {
|
|
return `/api/roles/${id}/permissions/impact-preview`;
|
|
};
|
|
|
|
export const previewRolePermissionsImpact = async (
|
|
id: number,
|
|
rolePermissionsImpactBody: RolePermissionsImpactBody,
|
|
options?: RequestInit,
|
|
): Promise<RolePermissionsImpact> => {
|
|
return customFetch<RolePermissionsImpact>(
|
|
getPreviewRolePermissionsImpactUrl(id),
|
|
{
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(rolePermissionsImpactBody),
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getPreviewRolePermissionsImpactMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof previewRolePermissionsImpact>>,
|
|
TError,
|
|
{ id: number; data: BodyType<RolePermissionsImpactBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof previewRolePermissionsImpact>>,
|
|
TError,
|
|
{ id: number; data: BodyType<RolePermissionsImpactBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["previewRolePermissionsImpact"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof previewRolePermissionsImpact>>,
|
|
{ id: number; data: BodyType<RolePermissionsImpactBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return previewRolePermissionsImpact(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type PreviewRolePermissionsImpactMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof previewRolePermissionsImpact>>
|
|
>;
|
|
export type PreviewRolePermissionsImpactMutationBody =
|
|
BodyType<RolePermissionsImpactBody>;
|
|
export type PreviewRolePermissionsImpactMutationError =
|
|
ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Preview the impact of changing a role's permission set (admin)
|
|
*/
|
|
export const usePreviewRolePermissionsImpact = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof previewRolePermissionsImpact>>,
|
|
TError,
|
|
{ id: number; data: BodyType<RolePermissionsImpactBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof previewRolePermissionsImpact>>,
|
|
TError,
|
|
{ id: number; data: BodyType<RolePermissionsImpactBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getPreviewRolePermissionsImpactMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List permissions assigned to a role (admin)
|
|
*/
|
|
export const getGetRolePermissionsUrl = (id: number) => {
|
|
return `/api/roles/${id}/permissions`;
|
|
};
|
|
|
|
export const getRolePermissions = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<Permission[]> => {
|
|
return customFetch<Permission[]>(getGetRolePermissionsUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetRolePermissionsQueryKey = (id: number) => {
|
|
return [`/api/roles/${id}/permissions`] as const;
|
|
};
|
|
|
|
export const getGetRolePermissionsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getRolePermissions>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getRolePermissions>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetRolePermissionsQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getRolePermissions>>
|
|
> = ({ signal }) => getRolePermissions(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getRolePermissions>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetRolePermissionsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getRolePermissions>>
|
|
>;
|
|
export type GetRolePermissionsQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List permissions assigned to a role (admin)
|
|
*/
|
|
|
|
export function useGetRolePermissions<
|
|
TData = Awaited<ReturnType<typeof getRolePermissions>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getRolePermissions>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetRolePermissionsQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Atomically replace the permissions assigned to a role (admin)
|
|
*/
|
|
export const getReplaceRolePermissionsUrl = (id: number) => {
|
|
return `/api/roles/${id}/permissions`;
|
|
};
|
|
|
|
export const replaceRolePermissions = async (
|
|
id: number,
|
|
replaceRolePermissionsBody: ReplaceRolePermissionsBody,
|
|
options?: RequestInit,
|
|
): Promise<Permission[]> => {
|
|
return customFetch<Permission[]>(getReplaceRolePermissionsUrl(id), {
|
|
...options,
|
|
method: "PUT",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(replaceRolePermissionsBody),
|
|
});
|
|
};
|
|
|
|
export const getReplaceRolePermissionsMutationOptions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof replaceRolePermissions>>,
|
|
TError,
|
|
{ id: number; data: BodyType<ReplaceRolePermissionsBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof replaceRolePermissions>>,
|
|
TError,
|
|
{ id: number; data: BodyType<ReplaceRolePermissionsBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["replaceRolePermissions"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof replaceRolePermissions>>,
|
|
{ id: number; data: BodyType<ReplaceRolePermissionsBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return replaceRolePermissions(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type ReplaceRolePermissionsMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof replaceRolePermissions>>
|
|
>;
|
|
export type ReplaceRolePermissionsMutationBody =
|
|
BodyType<ReplaceRolePermissionsBody>;
|
|
export type ReplaceRolePermissionsMutationError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Atomically replace the permissions assigned to a role (admin)
|
|
*/
|
|
export const useReplaceRolePermissions = <
|
|
TError = ErrorType<ErrorResponse>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof replaceRolePermissions>>,
|
|
TError,
|
|
{ id: number; data: BodyType<ReplaceRolePermissionsBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof replaceRolePermissions>>,
|
|
TError,
|
|
{ id: number; data: BodyType<ReplaceRolePermissionsBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getReplaceRolePermissionsMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary List groups (admin)
|
|
*/
|
|
export const getListGroupsUrl = (params?: ListGroupsParams) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/groups?${stringifiedParams}`
|
|
: `/api/groups`;
|
|
};
|
|
|
|
export const listGroups = async (
|
|
params?: ListGroupsParams,
|
|
options?: RequestInit,
|
|
): Promise<Group[]> => {
|
|
return customFetch<Group[]>(getListGroupsUrl(params), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListGroupsQueryKey = (params?: ListGroupsParams) => {
|
|
return [`/api/groups`, ...(params ? [params] : [])] as const;
|
|
};
|
|
|
|
export const getListGroupsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listGroups>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
params?: ListGroupsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listGroups>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListGroupsQueryKey(params);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listGroups>>> = ({
|
|
signal,
|
|
}) => listGroups(params, { signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listGroups>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListGroupsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listGroups>>
|
|
>;
|
|
export type ListGroupsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary List groups (admin)
|
|
*/
|
|
|
|
export function useListGroups<
|
|
TData = Awaited<ReturnType<typeof listGroups>>,
|
|
TError = ErrorType<unknown>,
|
|
>(
|
|
params?: ListGroupsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listGroups>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListGroupsQueryOptions(params, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Create group (admin)
|
|
*/
|
|
export const getCreateGroupUrl = () => {
|
|
return `/api/groups`;
|
|
};
|
|
|
|
export const createGroup = async (
|
|
createGroupBody: CreateGroupBody,
|
|
options?: RequestInit,
|
|
): Promise<Group> => {
|
|
return customFetch<Group>(getCreateGroupUrl(), {
|
|
...options,
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(createGroupBody),
|
|
});
|
|
};
|
|
|
|
export const getCreateGroupMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createGroup>>,
|
|
TError,
|
|
{ data: BodyType<CreateGroupBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof createGroup>>,
|
|
TError,
|
|
{ data: BodyType<CreateGroupBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["createGroup"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof createGroup>>,
|
|
{ data: BodyType<CreateGroupBody> }
|
|
> = (props) => {
|
|
const { data } = props ?? {};
|
|
|
|
return createGroup(data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type CreateGroupMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof createGroup>>
|
|
>;
|
|
export type CreateGroupMutationBody = BodyType<CreateGroupBody>;
|
|
export type CreateGroupMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Create group (admin)
|
|
*/
|
|
export const useCreateGroup = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof createGroup>>,
|
|
TError,
|
|
{ data: BodyType<CreateGroupBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof createGroup>>,
|
|
TError,
|
|
{ data: BodyType<CreateGroupBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getCreateGroupMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Get group with members and apps (admin)
|
|
*/
|
|
export const getGetGroupUrl = (id: number) => {
|
|
return `/api/groups/${id}`;
|
|
};
|
|
|
|
export const getGroup = async (
|
|
id: number,
|
|
options?: RequestInit,
|
|
): Promise<GroupDetail> => {
|
|
return customFetch<GroupDetail>(getGetGroupUrl(id), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetGroupQueryKey = (id: number) => {
|
|
return [`/api/groups/${id}`] as const;
|
|
};
|
|
|
|
export const getGetGroupQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getGroup>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getGroup>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetGroupQueryKey(id);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getGroup>>> = ({
|
|
signal,
|
|
}) => getGroup(id, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<Awaited<ReturnType<typeof getGroup>>, TError, TData> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
};
|
|
|
|
export type GetGroupQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getGroup>>
|
|
>;
|
|
export type GetGroupQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Get group with members and apps (admin)
|
|
*/
|
|
|
|
export function useGetGroup<
|
|
TData = Awaited<ReturnType<typeof getGroup>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getGroup>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetGroupQueryOptions(id, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Update group (admin)
|
|
*/
|
|
export const getUpdateGroupUrl = (id: number) => {
|
|
return `/api/groups/${id}`;
|
|
};
|
|
|
|
export const updateGroup = async (
|
|
id: number,
|
|
updateGroupBody: UpdateGroupBody,
|
|
options?: RequestInit,
|
|
): Promise<GroupDetail> => {
|
|
return customFetch<GroupDetail>(getUpdateGroupUrl(id), {
|
|
...options,
|
|
method: "PATCH",
|
|
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
body: JSON.stringify(updateGroupBody),
|
|
});
|
|
};
|
|
|
|
export const getUpdateGroupMutationOptions = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateGroup>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateGroupBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateGroup>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateGroupBody> },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["updateGroup"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof updateGroup>>,
|
|
{ id: number; data: BodyType<UpdateGroupBody> }
|
|
> = (props) => {
|
|
const { id, data } = props ?? {};
|
|
|
|
return updateGroup(id, data, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type UpdateGroupMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof updateGroup>>
|
|
>;
|
|
export type UpdateGroupMutationBody = BodyType<UpdateGroupBody>;
|
|
export type UpdateGroupMutationError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Update group (admin)
|
|
*/
|
|
export const useUpdateGroup = <
|
|
TError = ErrorType<unknown>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof updateGroup>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateGroupBody> },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof updateGroup>>,
|
|
TError,
|
|
{ id: number; data: BodyType<UpdateGroupBody> },
|
|
TContext
|
|
> => {
|
|
return useMutation(getUpdateGroupMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* @summary Delete group (admin)
|
|
*/
|
|
export const getDeleteGroupUrl = (id: number, params?: DeleteGroupParams) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/groups/${id}?${stringifiedParams}`
|
|
: `/api/groups/${id}`;
|
|
};
|
|
|
|
export const deleteGroup = async (
|
|
id: number,
|
|
params?: DeleteGroupParams,
|
|
options?: RequestInit,
|
|
): Promise<void> => {
|
|
return customFetch<void>(getDeleteGroupUrl(id, params), {
|
|
...options,
|
|
method: "DELETE",
|
|
});
|
|
};
|
|
|
|
export const getDeleteGroupMutationOptions = <
|
|
TError = ErrorType<ErrorResponse | GroupDeletionConflict>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteGroup>>,
|
|
TError,
|
|
{ id: number; params?: DeleteGroupParams },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteGroup>>,
|
|
TError,
|
|
{ id: number; params?: DeleteGroupParams },
|
|
TContext
|
|
> => {
|
|
const mutationKey = ["deleteGroup"];
|
|
const { mutation: mutationOptions, request: requestOptions } = options
|
|
? options.mutation &&
|
|
"mutationKey" in options.mutation &&
|
|
options.mutation.mutationKey
|
|
? options
|
|
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
|
: { mutation: { mutationKey }, request: undefined };
|
|
|
|
const mutationFn: MutationFunction<
|
|
Awaited<ReturnType<typeof deleteGroup>>,
|
|
{ id: number; params?: DeleteGroupParams }
|
|
> = (props) => {
|
|
const { id, params } = props ?? {};
|
|
|
|
return deleteGroup(id, params, requestOptions);
|
|
};
|
|
|
|
return { mutationFn, ...mutationOptions };
|
|
};
|
|
|
|
export type DeleteGroupMutationResult = NonNullable<
|
|
Awaited<ReturnType<typeof deleteGroup>>
|
|
>;
|
|
|
|
export type DeleteGroupMutationError = ErrorType<
|
|
ErrorResponse | GroupDeletionConflict
|
|
>;
|
|
|
|
/**
|
|
* @summary Delete group (admin)
|
|
*/
|
|
export const useDeleteGroup = <
|
|
TError = ErrorType<ErrorResponse | GroupDeletionConflict>,
|
|
TContext = unknown,
|
|
>(options?: {
|
|
mutation?: UseMutationOptions<
|
|
Awaited<ReturnType<typeof deleteGroup>>,
|
|
TError,
|
|
{ id: number; params?: DeleteGroupParams },
|
|
TContext
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseMutationResult<
|
|
Awaited<ReturnType<typeof deleteGroup>>,
|
|
TError,
|
|
{ id: number; params?: DeleteGroupParams },
|
|
TContext
|
|
> => {
|
|
return useMutation(getDeleteGroupMutationOptions(options));
|
|
};
|
|
|
|
/**
|
|
* Returns permission-change audit records for the given user, newest
|
|
first. Mirrors the role audit endpoint shape and supports the same
|
|
`limit`/`offset`/`actorUserId`/`from`/`to` filters. Each entry
|
|
captures the actor (if known), the previous and new id sets, and
|
|
the change kind (`user.roles` or `user.groups`).
|
|
|
|
* @summary List recent permission-change audit entries for a user (admin)
|
|
*/
|
|
export const getGetUserPermissionAuditUrl = (
|
|
id: number,
|
|
params?: GetUserPermissionAuditParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/users/${id}/audit?${stringifiedParams}`
|
|
: `/api/users/${id}/audit`;
|
|
};
|
|
|
|
export const getUserPermissionAudit = async (
|
|
id: number,
|
|
params?: GetUserPermissionAuditParams,
|
|
options?: RequestInit,
|
|
): Promise<PermissionAuditList> => {
|
|
return customFetch<PermissionAuditList>(
|
|
getGetUserPermissionAuditUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetUserPermissionAuditQueryKey = (
|
|
id: number,
|
|
params?: GetUserPermissionAuditParams,
|
|
) => {
|
|
return [`/api/users/${id}/audit`, ...(params ? [params] : [])] as const;
|
|
};
|
|
|
|
export const getGetUserPermissionAuditQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getUserPermissionAudit>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetUserPermissionAuditParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getUserPermissionAudit>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ?? getGetUserPermissionAuditQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getUserPermissionAudit>>
|
|
> = ({ signal }) =>
|
|
getUserPermissionAudit(id, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getUserPermissionAudit>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetUserPermissionAuditQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getUserPermissionAudit>>
|
|
>;
|
|
export type GetUserPermissionAuditQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List recent permission-change audit entries for a user (admin)
|
|
*/
|
|
|
|
export function useGetUserPermissionAudit<
|
|
TData = Awaited<ReturnType<typeof getUserPermissionAudit>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetUserPermissionAuditParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getUserPermissionAudit>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetUserPermissionAuditQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* Returns permission-change audit records for the given group, newest
|
|
first. Captures changes to the group's user, role and app sets via
|
|
the discriminator field `changeKind`.
|
|
|
|
* @summary List recent permission-change audit entries for a group (admin)
|
|
*/
|
|
export const getGetGroupPermissionAuditUrl = (
|
|
id: number,
|
|
params?: GetGroupPermissionAuditParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/groups/${id}/audit?${stringifiedParams}`
|
|
: `/api/groups/${id}/audit`;
|
|
};
|
|
|
|
export const getGroupPermissionAudit = async (
|
|
id: number,
|
|
params?: GetGroupPermissionAuditParams,
|
|
options?: RequestInit,
|
|
): Promise<PermissionAuditList> => {
|
|
return customFetch<PermissionAuditList>(
|
|
getGetGroupPermissionAuditUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetGroupPermissionAuditQueryKey = (
|
|
id: number,
|
|
params?: GetGroupPermissionAuditParams,
|
|
) => {
|
|
return [`/api/groups/${id}/audit`, ...(params ? [params] : [])] as const;
|
|
};
|
|
|
|
export const getGetGroupPermissionAuditQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getGroupPermissionAudit>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetGroupPermissionAuditParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getGroupPermissionAudit>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ?? getGetGroupPermissionAuditQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getGroupPermissionAudit>>
|
|
> = ({ signal }) =>
|
|
getGroupPermissionAudit(id, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getGroupPermissionAudit>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetGroupPermissionAuditQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getGroupPermissionAudit>>
|
|
>;
|
|
export type GetGroupPermissionAuditQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List recent permission-change audit entries for a group (admin)
|
|
*/
|
|
|
|
export function useGetGroupPermissionAudit<
|
|
TData = Awaited<ReturnType<typeof getGroupPermissionAudit>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetGroupPermissionAuditParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getGroupPermissionAudit>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetGroupPermissionAuditQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* Returns permission-change audit records for the given app, newest
|
|
first. Captures changes to the set of permissions required to open
|
|
the app (`changeKind: app.permissions`).
|
|
|
|
* @summary List recent permission-change audit entries for an app (admin)
|
|
*/
|
|
export const getGetAppPermissionAuditUrl = (
|
|
id: number,
|
|
params?: GetAppPermissionAuditParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/apps/${id}/audit?${stringifiedParams}`
|
|
: `/api/apps/${id}/audit`;
|
|
};
|
|
|
|
export const getAppPermissionAudit = async (
|
|
id: number,
|
|
params?: GetAppPermissionAuditParams,
|
|
options?: RequestInit,
|
|
): Promise<PermissionAuditList> => {
|
|
return customFetch<PermissionAuditList>(
|
|
getGetAppPermissionAuditUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetAppPermissionAuditQueryKey = (
|
|
id: number,
|
|
params?: GetAppPermissionAuditParams,
|
|
) => {
|
|
return [`/api/apps/${id}/audit`, ...(params ? [params] : [])] as const;
|
|
};
|
|
|
|
export const getGetAppPermissionAuditQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAppPermissionAudit>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAppPermissionAuditParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAppPermissionAudit>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ?? getGetAppPermissionAuditQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getAppPermissionAudit>>
|
|
> = ({ signal }) =>
|
|
getAppPermissionAudit(id, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAppPermissionAudit>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAppPermissionAuditQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAppPermissionAudit>>
|
|
>;
|
|
export type GetAppPermissionAuditQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List recent permission-change audit entries for an app (admin)
|
|
*/
|
|
|
|
export function useGetAppPermissionAudit<
|
|
TData = Awaited<ReturnType<typeof getAppPermissionAudit>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAppPermissionAuditParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAppPermissionAudit>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAppPermissionAuditQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Get home screen stats
|
|
*/
|
|
export const getGetHomeStatsUrl = () => {
|
|
return `/api/stats/home`;
|
|
};
|
|
|
|
export const getHomeStats = async (
|
|
options?: RequestInit,
|
|
): Promise<HomeStats> => {
|
|
return customFetch<HomeStats>(getGetHomeStatsUrl(), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetHomeStatsQueryKey = () => {
|
|
return [`/api/stats/home`] as const;
|
|
};
|
|
|
|
export const getGetHomeStatsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getHomeStats>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getHomeStats>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetHomeStatsQueryKey();
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getHomeStats>>> = ({
|
|
signal,
|
|
}) => getHomeStats({ signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getHomeStats>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetHomeStatsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getHomeStats>>
|
|
>;
|
|
export type GetHomeStatsQueryError = ErrorType<unknown>;
|
|
|
|
/**
|
|
* @summary Get home screen stats
|
|
*/
|
|
|
|
export function useGetHomeStats<
|
|
TData = Awaited<ReturnType<typeof getHomeStats>>,
|
|
TError = ErrorType<unknown>,
|
|
>(options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getHomeStats>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetHomeStatsQueryOptions(options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Get admin dashboard trend stats
|
|
*/
|
|
export const getGetAdminStatsUrl = (params?: GetAdminStatsParams) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/stats/admin?${stringifiedParams}`
|
|
: `/api/stats/admin`;
|
|
};
|
|
|
|
export const getAdminStats = async (
|
|
params?: GetAdminStatsParams,
|
|
options?: RequestInit,
|
|
): Promise<AdminStats> => {
|
|
return customFetch<AdminStats>(getGetAdminStatsUrl(params), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getGetAdminStatsQueryKey = (params?: GetAdminStatsParams) => {
|
|
return [`/api/stats/admin`, ...(params ? [params] : [])] as const;
|
|
};
|
|
|
|
export const getGetAdminStatsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminStats>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
params?: GetAdminStatsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminStats>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getGetAdminStatsQueryKey(params);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof getAdminStats>>> = ({
|
|
signal,
|
|
}) => getAdminStats(params, { signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminStats>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminStatsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminStats>>
|
|
>;
|
|
export type GetAdminStatsQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Get admin dashboard trend stats
|
|
*/
|
|
|
|
export function useGetAdminStats<
|
|
TData = Awaited<ReturnType<typeof getAdminStats>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
params?: GetAdminStatsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminStats>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminStatsQueryOptions(params, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Recent opens of a single app within the selected range
|
|
*/
|
|
export const getGetAdminAppOpensByAppUrl = (
|
|
appId: number,
|
|
params?: GetAdminAppOpensByAppParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/stats/admin/app-opens/by-app/${appId}?${stringifiedParams}`
|
|
: `/api/stats/admin/app-opens/by-app/${appId}`;
|
|
};
|
|
|
|
export const getAdminAppOpensByApp = async (
|
|
appId: number,
|
|
params?: GetAdminAppOpensByAppParams,
|
|
options?: RequestInit,
|
|
): Promise<AdminAppOpensByApp> => {
|
|
return customFetch<AdminAppOpensByApp>(
|
|
getGetAdminAppOpensByAppUrl(appId, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetAdminAppOpensByAppQueryKey = (
|
|
appId: number,
|
|
params?: GetAdminAppOpensByAppParams,
|
|
) => {
|
|
return [
|
|
`/api/stats/admin/app-opens/by-app/${appId}`,
|
|
...(params ? [params] : []),
|
|
] as const;
|
|
};
|
|
|
|
export const getGetAdminAppOpensByAppQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminAppOpensByApp>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
appId: number,
|
|
params?: GetAdminAppOpensByAppParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppOpensByApp>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ?? getGetAdminAppOpensByAppQueryKey(appId, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getAdminAppOpensByApp>>
|
|
> = ({ signal }) =>
|
|
getAdminAppOpensByApp(appId, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!appId,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppOpensByApp>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminAppOpensByAppQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminAppOpensByApp>>
|
|
>;
|
|
export type GetAdminAppOpensByAppQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Recent opens of a single app within the selected range
|
|
*/
|
|
|
|
export function useGetAdminAppOpensByApp<
|
|
TData = Awaited<ReturnType<typeof getAdminAppOpensByApp>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
appId: number,
|
|
params?: GetAdminAppOpensByAppParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppOpensByApp>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminAppOpensByAppQueryOptions(
|
|
appId,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary Recent app opens by a single user within the selected range
|
|
*/
|
|
export const getGetAdminAppOpensByUserUrl = (
|
|
userId: number,
|
|
params?: GetAdminAppOpensByUserParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/stats/admin/app-opens/by-user/${userId}?${stringifiedParams}`
|
|
: `/api/stats/admin/app-opens/by-user/${userId}`;
|
|
};
|
|
|
|
export const getAdminAppOpensByUser = async (
|
|
userId: number,
|
|
params?: GetAdminAppOpensByUserParams,
|
|
options?: RequestInit,
|
|
): Promise<AdminAppOpensByUser> => {
|
|
return customFetch<AdminAppOpensByUser>(
|
|
getGetAdminAppOpensByUserUrl(userId, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetAdminAppOpensByUserQueryKey = (
|
|
userId: number,
|
|
params?: GetAdminAppOpensByUserParams,
|
|
) => {
|
|
return [
|
|
`/api/stats/admin/app-opens/by-user/${userId}`,
|
|
...(params ? [params] : []),
|
|
] as const;
|
|
};
|
|
|
|
export const getGetAdminAppOpensByUserQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminAppOpensByUser>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
userId: number,
|
|
params?: GetAdminAppOpensByUserParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppOpensByUser>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ?? getGetAdminAppOpensByUserQueryKey(userId, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getAdminAppOpensByUser>>
|
|
> = ({ signal }) =>
|
|
getAdminAppOpensByUser(userId, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!userId,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppOpensByUser>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminAppOpensByUserQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminAppOpensByUser>>
|
|
>;
|
|
export type GetAdminAppOpensByUserQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Recent app opens by a single user within the selected range
|
|
*/
|
|
|
|
export function useGetAdminAppOpensByUser<
|
|
TData = Awaited<ReturnType<typeof getAdminAppOpensByUser>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
userId: number,
|
|
params?: GetAdminAppOpensByUserParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppOpensByUser>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminAppOpensByUserQueryOptions(
|
|
userId,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* Returns recent entries from the audit log, newest first. Admin only.
|
|
Filter by action (exact match) and/or a date range (inclusive).
|
|
|
|
* @summary List audit log entries (admin)
|
|
*/
|
|
export const getListAuditLogsUrl = (params?: ListAuditLogsParams) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/admin/audit-logs?${stringifiedParams}`
|
|
: `/api/admin/audit-logs`;
|
|
};
|
|
|
|
export const listAuditLogs = async (
|
|
params?: ListAuditLogsParams,
|
|
options?: RequestInit,
|
|
): Promise<AuditLogList> => {
|
|
return customFetch<AuditLogList>(getListAuditLogsUrl(params), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getListAuditLogsQueryKey = (params?: ListAuditLogsParams) => {
|
|
return [`/api/admin/audit-logs`, ...(params ? [params] : [])] as const;
|
|
};
|
|
|
|
export const getListAuditLogsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof listAuditLogs>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
params?: ListAuditLogsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listAuditLogs>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey = queryOptions?.queryKey ?? getListAuditLogsQueryKey(params);
|
|
|
|
const queryFn: QueryFunction<Awaited<ReturnType<typeof listAuditLogs>>> = ({
|
|
signal,
|
|
}) => listAuditLogs(params, { signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof listAuditLogs>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ListAuditLogsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof listAuditLogs>>
|
|
>;
|
|
export type ListAuditLogsQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List audit log entries (admin)
|
|
*/
|
|
|
|
export function useListAuditLogs<
|
|
TData = Awaited<ReturnType<typeof listAuditLogs>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
params?: ListAuditLogsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof listAuditLogs>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getListAuditLogsQueryOptions(params, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* Streams the filtered audit log as a CSV download.
|
|
Honors the same `action`, `forcedOnly`, `from`, and `to` filters as the
|
|
list endpoint.
|
|
Columns: action, actor_username, target_type, target_id, created_at, metadata.
|
|
Capped at 50,000 rows per export to bound response size.
|
|
|
|
* @summary Export filtered audit log as CSV (admin)
|
|
*/
|
|
export const getExportAuditLogsCsvUrl = (params?: ExportAuditLogsCsvParams) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/admin/audit-logs/export?${stringifiedParams}`
|
|
: `/api/admin/audit-logs/export`;
|
|
};
|
|
|
|
export const exportAuditLogsCsv = async (
|
|
params?: ExportAuditLogsCsvParams,
|
|
options?: RequestInit,
|
|
): Promise<Blob> => {
|
|
return customFetch<Blob>(getExportAuditLogsCsvUrl(params), {
|
|
...options,
|
|
method: "GET",
|
|
});
|
|
};
|
|
|
|
export const getExportAuditLogsCsvQueryKey = (
|
|
params?: ExportAuditLogsCsvParams,
|
|
) => {
|
|
return [`/api/admin/audit-logs/export`, ...(params ? [params] : [])] as const;
|
|
};
|
|
|
|
export const getExportAuditLogsCsvQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof exportAuditLogsCsv>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
params?: ExportAuditLogsCsvParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof exportAuditLogsCsv>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ?? getExportAuditLogsCsvQueryKey(params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof exportAuditLogsCsv>>
|
|
> = ({ signal }) => exportAuditLogsCsv(params, { signal, ...requestOptions });
|
|
|
|
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
|
Awaited<ReturnType<typeof exportAuditLogsCsv>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type ExportAuditLogsCsvQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof exportAuditLogsCsv>>
|
|
>;
|
|
export type ExportAuditLogsCsvQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary Export filtered audit log as CSV (admin)
|
|
*/
|
|
|
|
export function useExportAuditLogsCsv<
|
|
TData = Awaited<ReturnType<typeof exportAuditLogsCsv>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
params?: ExportAuditLogsCsvParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof exportAuditLogsCsv>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getExportAuditLogsCsvQueryOptions(params, options);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* Returns the groups behind the inline "<n> groups" badge on the
|
|
admin Apps row, paginated. Admin only.
|
|
|
|
* @summary List groups granting access to an app
|
|
*/
|
|
export const getGetAdminAppDependentGroupsUrl = (
|
|
id: number,
|
|
params?: GetAdminAppDependentGroupsParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/admin/apps/${id}/dependents/groups?${stringifiedParams}`
|
|
: `/api/admin/apps/${id}/dependents/groups`;
|
|
};
|
|
|
|
export const getAdminAppDependentGroups = async (
|
|
id: number,
|
|
params?: GetAdminAppDependentGroupsParams,
|
|
options?: RequestInit,
|
|
): Promise<AppDependentGroupsPage> => {
|
|
return customFetch<AppDependentGroupsPage>(
|
|
getGetAdminAppDependentGroupsUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetAdminAppDependentGroupsQueryKey = (
|
|
id: number,
|
|
params?: GetAdminAppDependentGroupsParams,
|
|
) => {
|
|
return [
|
|
`/api/admin/apps/${id}/dependents/groups`,
|
|
...(params ? [params] : []),
|
|
] as const;
|
|
};
|
|
|
|
export const getGetAdminAppDependentGroupsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminAppDependentGroups>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminAppDependentGroupsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppDependentGroups>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ?? getGetAdminAppDependentGroupsQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getAdminAppDependentGroups>>
|
|
> = ({ signal }) =>
|
|
getAdminAppDependentGroups(id, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppDependentGroups>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminAppDependentGroupsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminAppDependentGroups>>
|
|
>;
|
|
export type GetAdminAppDependentGroupsQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List groups granting access to an app
|
|
*/
|
|
|
|
export function useGetAdminAppDependentGroups<
|
|
TData = Awaited<ReturnType<typeof getAdminAppDependentGroups>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminAppDependentGroupsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppDependentGroups>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminAppDependentGroupsQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* Returns the legacy permissions gating an app, with the role names
|
|
currently holding each permission, paginated. Admin only.
|
|
|
|
* @summary List permission restrictions on an app
|
|
*/
|
|
export const getGetAdminAppDependentRestrictionsUrl = (
|
|
id: number,
|
|
params?: GetAdminAppDependentRestrictionsParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/admin/apps/${id}/dependents/restrictions?${stringifiedParams}`
|
|
: `/api/admin/apps/${id}/dependents/restrictions`;
|
|
};
|
|
|
|
export const getAdminAppDependentRestrictions = async (
|
|
id: number,
|
|
params?: GetAdminAppDependentRestrictionsParams,
|
|
options?: RequestInit,
|
|
): Promise<AppDependentRestrictionsPage> => {
|
|
return customFetch<AppDependentRestrictionsPage>(
|
|
getGetAdminAppDependentRestrictionsUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetAdminAppDependentRestrictionsQueryKey = (
|
|
id: number,
|
|
params?: GetAdminAppDependentRestrictionsParams,
|
|
) => {
|
|
return [
|
|
`/api/admin/apps/${id}/dependents/restrictions`,
|
|
...(params ? [params] : []),
|
|
] as const;
|
|
};
|
|
|
|
export const getGetAdminAppDependentRestrictionsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminAppDependentRestrictions>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminAppDependentRestrictionsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppDependentRestrictions>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ??
|
|
getGetAdminAppDependentRestrictionsQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getAdminAppDependentRestrictions>>
|
|
> = ({ signal }) =>
|
|
getAdminAppDependentRestrictions(id, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppDependentRestrictions>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminAppDependentRestrictionsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminAppDependentRestrictions>>
|
|
>;
|
|
export type GetAdminAppDependentRestrictionsQueryError =
|
|
ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List permission restrictions on an app
|
|
*/
|
|
|
|
export function useGetAdminAppDependentRestrictions<
|
|
TData = Awaited<ReturnType<typeof getAdminAppDependentRestrictions>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminAppDependentRestrictionsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppDependentRestrictions>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminAppDependentRestrictionsQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* Returns every recorded open for the app newest-first, paginated.
|
|
Unlike /stats/admin/app-opens/by-app/{appId}, this endpoint does
|
|
not apply a date range so the badge total and the list match.
|
|
|
|
* @summary List recent opens for an app (no time filter)
|
|
*/
|
|
export const getGetAdminAppDependentOpensUrl = (
|
|
id: number,
|
|
params?: GetAdminAppDependentOpensParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/admin/apps/${id}/dependents/opens?${stringifiedParams}`
|
|
: `/api/admin/apps/${id}/dependents/opens`;
|
|
};
|
|
|
|
export const getAdminAppDependentOpens = async (
|
|
id: number,
|
|
params?: GetAdminAppDependentOpensParams,
|
|
options?: RequestInit,
|
|
): Promise<AppDependentOpensPage> => {
|
|
return customFetch<AppDependentOpensPage>(
|
|
getGetAdminAppDependentOpensUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetAdminAppDependentOpensQueryKey = (
|
|
id: number,
|
|
params?: GetAdminAppDependentOpensParams,
|
|
) => {
|
|
return [
|
|
`/api/admin/apps/${id}/dependents/opens`,
|
|
...(params ? [params] : []),
|
|
] as const;
|
|
};
|
|
|
|
export const getGetAdminAppDependentOpensQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminAppDependentOpens>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminAppDependentOpensParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppDependentOpens>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ?? getGetAdminAppDependentOpensQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getAdminAppDependentOpens>>
|
|
> = ({ signal }) =>
|
|
getAdminAppDependentOpens(id, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppDependentOpens>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminAppDependentOpensQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminAppDependentOpens>>
|
|
>;
|
|
export type GetAdminAppDependentOpensQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List recent opens for an app (no time filter)
|
|
*/
|
|
|
|
export function useGetAdminAppDependentOpens<
|
|
TData = Awaited<ReturnType<typeof getAdminAppDependentOpens>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminAppDependentOpensParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminAppDependentOpens>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminAppDependentOpensQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* Returns the service orders behind the inline "<n> orders" badge
|
|
on the admin Services row, paginated, newest-first. Admin only.
|
|
|
|
* @summary List orders placed against a service
|
|
*/
|
|
export const getGetAdminServiceDependentOrdersUrl = (
|
|
id: number,
|
|
params?: GetAdminServiceDependentOrdersParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/admin/services/${id}/dependents/orders?${stringifiedParams}`
|
|
: `/api/admin/services/${id}/dependents/orders`;
|
|
};
|
|
|
|
export const getAdminServiceDependentOrders = async (
|
|
id: number,
|
|
params?: GetAdminServiceDependentOrdersParams,
|
|
options?: RequestInit,
|
|
): Promise<ServiceDependentOrdersPage> => {
|
|
return customFetch<ServiceDependentOrdersPage>(
|
|
getGetAdminServiceDependentOrdersUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetAdminServiceDependentOrdersQueryKey = (
|
|
id: number,
|
|
params?: GetAdminServiceDependentOrdersParams,
|
|
) => {
|
|
return [
|
|
`/api/admin/services/${id}/dependents/orders`,
|
|
...(params ? [params] : []),
|
|
] as const;
|
|
};
|
|
|
|
export const getGetAdminServiceDependentOrdersQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminServiceDependentOrders>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminServiceDependentOrdersParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminServiceDependentOrders>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ??
|
|
getGetAdminServiceDependentOrdersQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getAdminServiceDependentOrders>>
|
|
> = ({ signal }) =>
|
|
getAdminServiceDependentOrders(id, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminServiceDependentOrders>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminServiceDependentOrdersQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminServiceDependentOrders>>
|
|
>;
|
|
export type GetAdminServiceDependentOrdersQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List orders placed against a service
|
|
*/
|
|
|
|
export function useGetAdminServiceDependentOrders<
|
|
TData = Awaited<ReturnType<typeof getAdminServiceDependentOrders>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminServiceDependentOrdersParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminServiceDependentOrders>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminServiceDependentOrdersQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary List notes owned by a user
|
|
*/
|
|
export const getGetAdminUserDependentNotesUrl = (
|
|
id: number,
|
|
params?: GetAdminUserDependentNotesParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/admin/users/${id}/dependents/notes?${stringifiedParams}`
|
|
: `/api/admin/users/${id}/dependents/notes`;
|
|
};
|
|
|
|
export const getAdminUserDependentNotes = async (
|
|
id: number,
|
|
params?: GetAdminUserDependentNotesParams,
|
|
options?: RequestInit,
|
|
): Promise<UserDependentNotesPage> => {
|
|
return customFetch<UserDependentNotesPage>(
|
|
getGetAdminUserDependentNotesUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetAdminUserDependentNotesQueryKey = (
|
|
id: number,
|
|
params?: GetAdminUserDependentNotesParams,
|
|
) => {
|
|
return [
|
|
`/api/admin/users/${id}/dependents/notes`,
|
|
...(params ? [params] : []),
|
|
] as const;
|
|
};
|
|
|
|
export const getGetAdminUserDependentNotesQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminUserDependentNotes>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminUserDependentNotesParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentNotes>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ?? getGetAdminUserDependentNotesQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getAdminUserDependentNotes>>
|
|
> = ({ signal }) =>
|
|
getAdminUserDependentNotes(id, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentNotes>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminUserDependentNotesQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminUserDependentNotes>>
|
|
>;
|
|
export type GetAdminUserDependentNotesQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List notes owned by a user
|
|
*/
|
|
|
|
export function useGetAdminUserDependentNotes<
|
|
TData = Awaited<ReturnType<typeof getAdminUserDependentNotes>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminUserDependentNotesParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentNotes>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminUserDependentNotesQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary List service orders placed by a user
|
|
*/
|
|
export const getGetAdminUserDependentOrdersUrl = (
|
|
id: number,
|
|
params?: GetAdminUserDependentOrdersParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/admin/users/${id}/dependents/orders?${stringifiedParams}`
|
|
: `/api/admin/users/${id}/dependents/orders`;
|
|
};
|
|
|
|
export const getAdminUserDependentOrders = async (
|
|
id: number,
|
|
params?: GetAdminUserDependentOrdersParams,
|
|
options?: RequestInit,
|
|
): Promise<UserDependentOrdersPage> => {
|
|
return customFetch<UserDependentOrdersPage>(
|
|
getGetAdminUserDependentOrdersUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetAdminUserDependentOrdersQueryKey = (
|
|
id: number,
|
|
params?: GetAdminUserDependentOrdersParams,
|
|
) => {
|
|
return [
|
|
`/api/admin/users/${id}/dependents/orders`,
|
|
...(params ? [params] : []),
|
|
] as const;
|
|
};
|
|
|
|
export const getGetAdminUserDependentOrdersQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminUserDependentOrders>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminUserDependentOrdersParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentOrders>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ??
|
|
getGetAdminUserDependentOrdersQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getAdminUserDependentOrders>>
|
|
> = ({ signal }) =>
|
|
getAdminUserDependentOrders(id, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentOrders>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminUserDependentOrdersQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminUserDependentOrders>>
|
|
>;
|
|
export type GetAdminUserDependentOrdersQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List service orders placed by a user
|
|
*/
|
|
|
|
export function useGetAdminUserDependentOrders<
|
|
TData = Awaited<ReturnType<typeof getAdminUserDependentOrders>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminUserDependentOrdersParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentOrders>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminUserDependentOrdersQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary List conversations created by a user
|
|
*/
|
|
export const getGetAdminUserDependentConversationsUrl = (
|
|
id: number,
|
|
params?: GetAdminUserDependentConversationsParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/admin/users/${id}/dependents/conversations?${stringifiedParams}`
|
|
: `/api/admin/users/${id}/dependents/conversations`;
|
|
};
|
|
|
|
export const getAdminUserDependentConversations = async (
|
|
id: number,
|
|
params?: GetAdminUserDependentConversationsParams,
|
|
options?: RequestInit,
|
|
): Promise<UserDependentConversationsPage> => {
|
|
return customFetch<UserDependentConversationsPage>(
|
|
getGetAdminUserDependentConversationsUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetAdminUserDependentConversationsQueryKey = (
|
|
id: number,
|
|
params?: GetAdminUserDependentConversationsParams,
|
|
) => {
|
|
return [
|
|
`/api/admin/users/${id}/dependents/conversations`,
|
|
...(params ? [params] : []),
|
|
] as const;
|
|
};
|
|
|
|
export const getGetAdminUserDependentConversationsQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminUserDependentConversations>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminUserDependentConversationsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentConversations>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ??
|
|
getGetAdminUserDependentConversationsQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getAdminUserDependentConversations>>
|
|
> = ({ signal }) =>
|
|
getAdminUserDependentConversations(id, params, {
|
|
signal,
|
|
...requestOptions,
|
|
});
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentConversations>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminUserDependentConversationsQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminUserDependentConversations>>
|
|
>;
|
|
export type GetAdminUserDependentConversationsQueryError =
|
|
ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List conversations created by a user
|
|
*/
|
|
|
|
export function useGetAdminUserDependentConversations<
|
|
TData = Awaited<ReturnType<typeof getAdminUserDependentConversations>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminUserDependentConversationsParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentConversations>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminUserDependentConversationsQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|
|
|
|
/**
|
|
* @summary List messages sent by a user
|
|
*/
|
|
export const getGetAdminUserDependentMessagesUrl = (
|
|
id: number,
|
|
params?: GetAdminUserDependentMessagesParams,
|
|
) => {
|
|
const normalizedParams = new URLSearchParams();
|
|
|
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
}
|
|
});
|
|
|
|
const stringifiedParams = normalizedParams.toString();
|
|
|
|
return stringifiedParams.length > 0
|
|
? `/api/admin/users/${id}/dependents/messages?${stringifiedParams}`
|
|
: `/api/admin/users/${id}/dependents/messages`;
|
|
};
|
|
|
|
export const getAdminUserDependentMessages = async (
|
|
id: number,
|
|
params?: GetAdminUserDependentMessagesParams,
|
|
options?: RequestInit,
|
|
): Promise<UserDependentMessagesPage> => {
|
|
return customFetch<UserDependentMessagesPage>(
|
|
getGetAdminUserDependentMessagesUrl(id, params),
|
|
{
|
|
...options,
|
|
method: "GET",
|
|
},
|
|
);
|
|
};
|
|
|
|
export const getGetAdminUserDependentMessagesQueryKey = (
|
|
id: number,
|
|
params?: GetAdminUserDependentMessagesParams,
|
|
) => {
|
|
return [
|
|
`/api/admin/users/${id}/dependents/messages`,
|
|
...(params ? [params] : []),
|
|
] as const;
|
|
};
|
|
|
|
export const getGetAdminUserDependentMessagesQueryOptions = <
|
|
TData = Awaited<ReturnType<typeof getAdminUserDependentMessages>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminUserDependentMessagesParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentMessages>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
) => {
|
|
const { query: queryOptions, request: requestOptions } = options ?? {};
|
|
|
|
const queryKey =
|
|
queryOptions?.queryKey ??
|
|
getGetAdminUserDependentMessagesQueryKey(id, params);
|
|
|
|
const queryFn: QueryFunction<
|
|
Awaited<ReturnType<typeof getAdminUserDependentMessages>>
|
|
> = ({ signal }) =>
|
|
getAdminUserDependentMessages(id, params, { signal, ...requestOptions });
|
|
|
|
return {
|
|
queryKey,
|
|
queryFn,
|
|
enabled: !!id,
|
|
...queryOptions,
|
|
} as UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentMessages>>,
|
|
TError,
|
|
TData
|
|
> & { queryKey: QueryKey };
|
|
};
|
|
|
|
export type GetAdminUserDependentMessagesQueryResult = NonNullable<
|
|
Awaited<ReturnType<typeof getAdminUserDependentMessages>>
|
|
>;
|
|
export type GetAdminUserDependentMessagesQueryError = ErrorType<ErrorResponse>;
|
|
|
|
/**
|
|
* @summary List messages sent by a user
|
|
*/
|
|
|
|
export function useGetAdminUserDependentMessages<
|
|
TData = Awaited<ReturnType<typeof getAdminUserDependentMessages>>,
|
|
TError = ErrorType<ErrorResponse>,
|
|
>(
|
|
id: number,
|
|
params?: GetAdminUserDependentMessagesParams,
|
|
options?: {
|
|
query?: UseQueryOptions<
|
|
Awaited<ReturnType<typeof getAdminUserDependentMessages>>,
|
|
TError,
|
|
TData
|
|
>;
|
|
request?: SecondParameter<typeof customFetch>;
|
|
},
|
|
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
|
const queryOptions = getGetAdminUserDependentMessagesQueryOptions(
|
|
id,
|
|
params,
|
|
options,
|
|
);
|
|
|
|
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
|
queryKey: QueryKey;
|
|
};
|
|
|
|
return { ...query, queryKey: queryOptions.queryKey };
|
|
}
|