59c7338d63
- Added GET /api/roles/:id/usage endpoint returning {userCount, groupCount},
guarded by requireAdmin and validating the role id.
- Updated PATCH /api/roles/:id audit metadata to record renamed=true,
renamedFrom, and renamedTo when the role name changes (in addition to
existing name fields), satisfying the traceability requirement.
- Added RoleUsage schema + /roles/{id}/usage operation to openapi.yaml,
regenerated lib/api-zod via orval. Codegen script in lib/api-spec was
updated intentionally to preserve `export * from './manual'` in
api-zod's index, which orval was overwriting.
- RolesPanel edit dialog (admin.tsx) now tracks the original role name
on open and shows an amber warning banner with from/to text plus a
usage line (users + groups counts) whenever the trimmed name input
differs from the original. Warning is suppressed for system or
protected roles since their name input is disabled.
- Added en/ar locale strings: renameWarningTitle, renameWarningBody,
renameUsage.
- Reverted accidental opengraph.jpg change picked up earlier in the
session — it is unrelated to this task.
Verification: e2e test created a non-system role, assigned the admin
user to it, opened the edit dialog, observed the warning + usage line,
saved the rename, and confirmed both the role name persisted and the
audit log captured renamed/renamedFrom/renamedTo.
Note: The pnpm `test` workflow shows pre-existing failures in
executive-meetings.ts that are unrelated to this task (verified via
git stash before changes).
Replit-Task-Id: c1ee048d-50c6-4439-a430-ee0b7ec09959
6456 lines
172 KiB
TypeScript
6456 lines
172 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 {
|
|
AddParticipantsBody,
|
|
AddUserRoleBody,
|
|
AdminAppOpensByApp,
|
|
AdminAppOpensByUser,
|
|
AdminResetLinkResponse,
|
|
AdminStats,
|
|
App,
|
|
AppDeletionConflict,
|
|
AppSettings,
|
|
AuditLogList,
|
|
AuthUser,
|
|
ConversationWithDetails,
|
|
CreateAppBody,
|
|
CreateConversationBody,
|
|
CreateGroupBody,
|
|
CreateRoleBody,
|
|
CreateServiceBody,
|
|
CreateServiceOrderBody,
|
|
CreateUserBody,
|
|
DeleteAppParams,
|
|
DeleteGroupParams,
|
|
DeleteServiceParams,
|
|
DeleteUserParams,
|
|
ErrorResponse,
|
|
ExportAuditLogsCsvParams,
|
|
ForgotPasswordBody,
|
|
ForgotPasswordResponse,
|
|
GetAdminAppOpensByAppParams,
|
|
GetAdminAppOpensByUserParams,
|
|
GetAdminStatsParams,
|
|
Group,
|
|
GroupDeletionConflict,
|
|
GroupDetail,
|
|
HealthStatus,
|
|
HomeStats,
|
|
LeaveConversationBody,
|
|
ListAuditLogsParams,
|
|
ListGroupsParams,
|
|
ListUsersParams,
|
|
LoginBody,
|
|
MessageWithSender,
|
|
Notification,
|
|
Permission,
|
|
RegisterBody,
|
|
ReplaceRolePermissionsBody,
|
|
RequestUploadUrlBody,
|
|
RequestUploadUrlResponse,
|
|
ResetPasswordBody,
|
|
Role,
|
|
RoleDeletionConflict,
|
|
RoleUsage,
|
|
SendMessageBody,
|
|
Service,
|
|
ServiceCategory,
|
|
ServiceDeletionConflict,
|
|
ServiceOrder,
|
|
SuccessResponse,
|
|
UpdateAppBody,
|
|
UpdateAppSettingsBody,
|
|
UpdateClockHour12Body,
|
|
UpdateClockStyleBody,
|
|
UpdateConversationBody,
|
|
UpdateConversationStateBody,
|
|
UpdateGroupBody,
|
|
UpdateLanguageBody,
|
|
UpdateMyAppOrderBody,
|
|
UpdateRoleBody,
|
|
UpdateServiceBody,
|
|
UpdateServiceOrderStatusBody,
|
|
UpdateUserBody,
|
|
UserDeletionConflict,
|
|
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));
|
|
};
|
|
|
|
/**
|
|
* @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 };
|
|
}
|
|
|
|
/**
|
|
* @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));
|
|
};
|
|
|
|
/**
|
|
* @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 };
|
|
}
|