feat(agents): Add identity and soul template fields to board creation
This commit is contained in:
@@ -4,8 +4,17 @@ const nextConfig: NextConfig = {
|
||||
allowedDevOrigins: [
|
||||
"http://localhost:3000",
|
||||
"http://127.0.0.1:3000",
|
||||
"http://192.168.1.101",
|
||||
"http://192.168.1.101:3000",
|
||||
],
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "img.clerk.com",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
||||
55
frontend/package-lock.json
generated
55
frontend/package-lock.json
generated
@@ -10,11 +10,13 @@
|
||||
"dependencies": {
|
||||
"@clerk/nextjs": "^6.37.1",
|
||||
"@radix-ui/react-dialog": "^1.1.2",
|
||||
"@radix-ui/react-popover": "^1.1.15",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-tabs": "^1.1.1",
|
||||
"@radix-ui/react-tooltip": "^1.1.2",
|
||||
"@tanstack/react-query": "^5.90.20",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"cmdk": "^1.1.1",
|
||||
"next": "16.1.6",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3"
|
||||
@@ -2221,6 +2223,43 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-popover": {
|
||||
"version": "1.1.15",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz",
|
||||
"integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.3",
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
"@radix-ui/react-context": "1.1.2",
|
||||
"@radix-ui/react-dismissable-layer": "1.1.11",
|
||||
"@radix-ui/react-focus-guards": "1.1.3",
|
||||
"@radix-ui/react-focus-scope": "1.1.7",
|
||||
"@radix-ui/react-id": "1.1.1",
|
||||
"@radix-ui/react-popper": "1.2.8",
|
||||
"@radix-ui/react-portal": "1.1.9",
|
||||
"@radix-ui/react-presence": "1.1.5",
|
||||
"@radix-ui/react-primitive": "2.1.3",
|
||||
"@radix-ui/react-slot": "1.2.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.2.2",
|
||||
"aria-hidden": "^1.2.4",
|
||||
"react-remove-scroll": "^2.6.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-popper": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz",
|
||||
@@ -4232,6 +4271,22 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/cmdk": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz",
|
||||
"integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "^1.1.1",
|
||||
"@radix-ui/react-dialog": "^1.1.6",
|
||||
"@radix-ui/react-id": "^1.1.0",
|
||||
"@radix-ui/react-primitive": "^2.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18 || ^19 || ^19.0.0-rc",
|
||||
"react-dom": "^18 || ^19 || ^19.0.0-rc"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
|
||||
@@ -12,12 +12,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@clerk/nextjs": "^6.37.1",
|
||||
"@radix-ui/react-popover": "^1.1.15",
|
||||
"@radix-ui/react-dialog": "^1.1.2",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-tabs": "^1.1.1",
|
||||
"@radix-ui/react-tooltip": "^1.1.2",
|
||||
"@tanstack/react-query": "^5.90.20",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"cmdk": "^1.1.1",
|
||||
"next": "16.1.6",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3"
|
||||
|
||||
238
frontend/src/api/generated/activity/activity.ts
Normal file
238
frontend/src/api/generated/activity/activity.ts
Normal file
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type {
|
||||
DataTag,
|
||||
DefinedInitialDataOptions,
|
||||
DefinedUseQueryResult,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UndefinedInitialDataOptions,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
|
||||
import type {
|
||||
ActivityEventRead,
|
||||
HTTPValidationError,
|
||||
ListActivityApiV1ActivityGetParams,
|
||||
} from ".././model";
|
||||
|
||||
import { customFetch } from "../../mutator";
|
||||
|
||||
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
||||
|
||||
/**
|
||||
* @summary List Activity
|
||||
*/
|
||||
export type listActivityApiV1ActivityGetResponse200 = {
|
||||
data: ActivityEventRead[];
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type listActivityApiV1ActivityGetResponse422 = {
|
||||
data: HTTPValidationError;
|
||||
status: 422;
|
||||
};
|
||||
|
||||
export type listActivityApiV1ActivityGetResponseSuccess =
|
||||
listActivityApiV1ActivityGetResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type listActivityApiV1ActivityGetResponseError =
|
||||
listActivityApiV1ActivityGetResponse422 & {
|
||||
headers: Headers;
|
||||
};
|
||||
|
||||
export type listActivityApiV1ActivityGetResponse =
|
||||
| listActivityApiV1ActivityGetResponseSuccess
|
||||
| listActivityApiV1ActivityGetResponseError;
|
||||
|
||||
export const getListActivityApiV1ActivityGetUrl = (
|
||||
params?: ListActivityApiV1ActivityGetParams,
|
||||
) => {
|
||||
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/v1/activity?${stringifiedParams}`
|
||||
: `/api/v1/activity`;
|
||||
};
|
||||
|
||||
export const listActivityApiV1ActivityGet = async (
|
||||
params?: ListActivityApiV1ActivityGetParams,
|
||||
options?: RequestInit,
|
||||
): Promise<listActivityApiV1ActivityGetResponse> => {
|
||||
return customFetch<listActivityApiV1ActivityGetResponse>(
|
||||
getListActivityApiV1ActivityGetUrl(params),
|
||||
{
|
||||
...options,
|
||||
method: "GET",
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const getListActivityApiV1ActivityGetQueryKey = (
|
||||
params?: ListActivityApiV1ActivityGetParams,
|
||||
) => {
|
||||
return [`/api/v1/activity`, ...(params ? [params] : [])] as const;
|
||||
};
|
||||
|
||||
export const getListActivityApiV1ActivityGetQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
params?: ListActivityApiV1ActivityGetParams,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions, request: requestOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getListActivityApiV1ActivityGetQueryKey(params);
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>
|
||||
> = ({ signal }) =>
|
||||
listActivityApiV1ActivityGet(params, { signal, ...requestOptions });
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
|
||||
export type ListActivityApiV1ActivityGetQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>
|
||||
>;
|
||||
export type ListActivityApiV1ActivityGetQueryError = HTTPValidationError;
|
||||
|
||||
export function useListActivityApiV1ActivityGet<
|
||||
TData = Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
params: undefined | ListActivityApiV1ActivityGetParams,
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useListActivityApiV1ActivityGet<
|
||||
TData = Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
params?: ListActivityApiV1ActivityGetParams,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useListActivityApiV1ActivityGet<
|
||||
TData = Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
params?: ListActivityApiV1ActivityGetParams,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
/**
|
||||
* @summary List Activity
|
||||
*/
|
||||
|
||||
export function useListActivityApiV1ActivityGet<
|
||||
TData = Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
params?: ListActivityApiV1ActivityGetParams,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listActivityApiV1ActivityGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getListActivityApiV1ActivityGetQueryOptions(
|
||||
params,
|
||||
options,
|
||||
);
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
1315
frontend/src/api/generated/agents/agents.ts
Normal file
1315
frontend/src/api/generated/agents/agents.ts
Normal file
File diff suppressed because it is too large
Load Diff
121
frontend/src/api/generated/auth/auth.ts
Normal file
121
frontend/src/api/generated/auth/auth.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import type {
|
||||
MutationFunction,
|
||||
QueryClient,
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
} from "@tanstack/react-query";
|
||||
|
||||
import type { UserRead } from ".././model";
|
||||
|
||||
import { customFetch } from "../../mutator";
|
||||
|
||||
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
||||
|
||||
/**
|
||||
* @summary Bootstrap User
|
||||
*/
|
||||
export type bootstrapUserApiV1AuthBootstrapPostResponse200 = {
|
||||
data: UserRead;
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type bootstrapUserApiV1AuthBootstrapPostResponseSuccess =
|
||||
bootstrapUserApiV1AuthBootstrapPostResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type bootstrapUserApiV1AuthBootstrapPostResponse =
|
||||
bootstrapUserApiV1AuthBootstrapPostResponseSuccess;
|
||||
|
||||
export const getBootstrapUserApiV1AuthBootstrapPostUrl = () => {
|
||||
return `/api/v1/auth/bootstrap`;
|
||||
};
|
||||
|
||||
export const bootstrapUserApiV1AuthBootstrapPost = async (
|
||||
options?: RequestInit,
|
||||
): Promise<bootstrapUserApiV1AuthBootstrapPostResponse> => {
|
||||
return customFetch<bootstrapUserApiV1AuthBootstrapPostResponse>(
|
||||
getBootstrapUserApiV1AuthBootstrapPostUrl(),
|
||||
{
|
||||
...options,
|
||||
method: "POST",
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const getBootstrapUserApiV1AuthBootstrapPostMutationOptions = <
|
||||
TError = unknown,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof bootstrapUserApiV1AuthBootstrapPost>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof bootstrapUserApiV1AuthBootstrapPost>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["bootstrapUserApiV1AuthBootstrapPost"];
|
||||
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 bootstrapUserApiV1AuthBootstrapPost>>,
|
||||
void
|
||||
> = () => {
|
||||
return bootstrapUserApiV1AuthBootstrapPost(requestOptions);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type BootstrapUserApiV1AuthBootstrapPostMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof bootstrapUserApiV1AuthBootstrapPost>>
|
||||
>;
|
||||
|
||||
export type BootstrapUserApiV1AuthBootstrapPostMutationError = unknown;
|
||||
|
||||
/**
|
||||
* @summary Bootstrap User
|
||||
*/
|
||||
export const useBootstrapUserApiV1AuthBootstrapPost = <
|
||||
TError = unknown,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof bootstrapUserApiV1AuthBootstrapPost>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof bootstrapUserApiV1AuthBootstrapPost>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(
|
||||
getBootstrapUserApiV1AuthBootstrapPostMutationOptions(options),
|
||||
queryClient,
|
||||
);
|
||||
};
|
||||
767
frontend/src/api/generated/boards/boards.ts
Normal file
767
frontend/src/api/generated/boards/boards.ts
Normal file
@@ -0,0 +1,767 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import type {
|
||||
DataTag,
|
||||
DefinedInitialDataOptions,
|
||||
DefinedUseQueryResult,
|
||||
MutationFunction,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UndefinedInitialDataOptions,
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
|
||||
import type {
|
||||
BoardCreate,
|
||||
BoardRead,
|
||||
BoardUpdate,
|
||||
DeleteBoardApiV1BoardsBoardIdDelete200,
|
||||
HTTPValidationError,
|
||||
} from ".././model";
|
||||
|
||||
import { customFetch } from "../../mutator";
|
||||
|
||||
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
||||
|
||||
/**
|
||||
* @summary List Boards
|
||||
*/
|
||||
export type listBoardsApiV1BoardsGetResponse200 = {
|
||||
data: BoardRead[];
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type listBoardsApiV1BoardsGetResponse422 = {
|
||||
data: HTTPValidationError;
|
||||
status: 422;
|
||||
};
|
||||
|
||||
export type listBoardsApiV1BoardsGetResponseSuccess =
|
||||
listBoardsApiV1BoardsGetResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type listBoardsApiV1BoardsGetResponseError =
|
||||
listBoardsApiV1BoardsGetResponse422 & {
|
||||
headers: Headers;
|
||||
};
|
||||
|
||||
export type listBoardsApiV1BoardsGetResponse =
|
||||
| listBoardsApiV1BoardsGetResponseSuccess
|
||||
| listBoardsApiV1BoardsGetResponseError;
|
||||
|
||||
export const getListBoardsApiV1BoardsGetUrl = () => {
|
||||
return `/api/v1/boards`;
|
||||
};
|
||||
|
||||
export const listBoardsApiV1BoardsGet = async (
|
||||
options?: RequestInit,
|
||||
): Promise<listBoardsApiV1BoardsGetResponse> => {
|
||||
return customFetch<listBoardsApiV1BoardsGetResponse>(
|
||||
getListBoardsApiV1BoardsGetUrl(),
|
||||
{
|
||||
...options,
|
||||
method: "GET",
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const getListBoardsApiV1BoardsGetQueryKey = () => {
|
||||
return [`/api/v1/boards`] as const;
|
||||
};
|
||||
|
||||
export const getListBoardsApiV1BoardsGetQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
}) => {
|
||||
const { query: queryOptions, request: requestOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getListBoardsApiV1BoardsGetQueryKey();
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>
|
||||
> = ({ signal }) => listBoardsApiV1BoardsGet({ signal, ...requestOptions });
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
|
||||
export type ListBoardsApiV1BoardsGetQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>
|
||||
>;
|
||||
export type ListBoardsApiV1BoardsGetQueryError = HTTPValidationError;
|
||||
|
||||
export function useListBoardsApiV1BoardsGet<
|
||||
TData = Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useListBoardsApiV1BoardsGet<
|
||||
TData = Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useListBoardsApiV1BoardsGet<
|
||||
TData = Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
/**
|
||||
* @summary List Boards
|
||||
*/
|
||||
|
||||
export function useListBoardsApiV1BoardsGet<
|
||||
TData = Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listBoardsApiV1BoardsGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getListBoardsApiV1BoardsGetQueryOptions(options);
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Create Board
|
||||
*/
|
||||
export type createBoardApiV1BoardsPostResponse200 = {
|
||||
data: BoardRead;
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type createBoardApiV1BoardsPostResponse422 = {
|
||||
data: HTTPValidationError;
|
||||
status: 422;
|
||||
};
|
||||
|
||||
export type createBoardApiV1BoardsPostResponseSuccess =
|
||||
createBoardApiV1BoardsPostResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type createBoardApiV1BoardsPostResponseError =
|
||||
createBoardApiV1BoardsPostResponse422 & {
|
||||
headers: Headers;
|
||||
};
|
||||
|
||||
export type createBoardApiV1BoardsPostResponse =
|
||||
| createBoardApiV1BoardsPostResponseSuccess
|
||||
| createBoardApiV1BoardsPostResponseError;
|
||||
|
||||
export const getCreateBoardApiV1BoardsPostUrl = () => {
|
||||
return `/api/v1/boards`;
|
||||
};
|
||||
|
||||
export const createBoardApiV1BoardsPost = async (
|
||||
boardCreate: BoardCreate,
|
||||
options?: RequestInit,
|
||||
): Promise<createBoardApiV1BoardsPostResponse> => {
|
||||
return customFetch<createBoardApiV1BoardsPostResponse>(
|
||||
getCreateBoardApiV1BoardsPostUrl(),
|
||||
{
|
||||
...options,
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", ...options?.headers },
|
||||
body: JSON.stringify(boardCreate),
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const getCreateBoardApiV1BoardsPostMutationOptions = <
|
||||
TError = HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createBoardApiV1BoardsPost>>,
|
||||
TError,
|
||||
{ data: BoardCreate },
|
||||
TContext
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createBoardApiV1BoardsPost>>,
|
||||
TError,
|
||||
{ data: BoardCreate },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["createBoardApiV1BoardsPost"];
|
||||
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 createBoardApiV1BoardsPost>>,
|
||||
{ data: BoardCreate }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
return createBoardApiV1BoardsPost(data, requestOptions);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type CreateBoardApiV1BoardsPostMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof createBoardApiV1BoardsPost>>
|
||||
>;
|
||||
export type CreateBoardApiV1BoardsPostMutationBody = BoardCreate;
|
||||
export type CreateBoardApiV1BoardsPostMutationError = HTTPValidationError;
|
||||
|
||||
/**
|
||||
* @summary Create Board
|
||||
*/
|
||||
export const useCreateBoardApiV1BoardsPost = <
|
||||
TError = HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createBoardApiV1BoardsPost>>,
|
||||
TError,
|
||||
{ data: BoardCreate },
|
||||
TContext
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createBoardApiV1BoardsPost>>,
|
||||
TError,
|
||||
{ data: BoardCreate },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(
|
||||
getCreateBoardApiV1BoardsPostMutationOptions(options),
|
||||
queryClient,
|
||||
);
|
||||
};
|
||||
/**
|
||||
* @summary Get Board
|
||||
*/
|
||||
export type getBoardApiV1BoardsBoardIdGetResponse200 = {
|
||||
data: BoardRead;
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type getBoardApiV1BoardsBoardIdGetResponse422 = {
|
||||
data: HTTPValidationError;
|
||||
status: 422;
|
||||
};
|
||||
|
||||
export type getBoardApiV1BoardsBoardIdGetResponseSuccess =
|
||||
getBoardApiV1BoardsBoardIdGetResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type getBoardApiV1BoardsBoardIdGetResponseError =
|
||||
getBoardApiV1BoardsBoardIdGetResponse422 & {
|
||||
headers: Headers;
|
||||
};
|
||||
|
||||
export type getBoardApiV1BoardsBoardIdGetResponse =
|
||||
| getBoardApiV1BoardsBoardIdGetResponseSuccess
|
||||
| getBoardApiV1BoardsBoardIdGetResponseError;
|
||||
|
||||
export const getGetBoardApiV1BoardsBoardIdGetUrl = (boardId: string) => {
|
||||
return `/api/v1/boards/${boardId}`;
|
||||
};
|
||||
|
||||
export const getBoardApiV1BoardsBoardIdGet = async (
|
||||
boardId: string,
|
||||
options?: RequestInit,
|
||||
): Promise<getBoardApiV1BoardsBoardIdGetResponse> => {
|
||||
return customFetch<getBoardApiV1BoardsBoardIdGetResponse>(
|
||||
getGetBoardApiV1BoardsBoardIdGetUrl(boardId),
|
||||
{
|
||||
...options,
|
||||
method: "GET",
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const getGetBoardApiV1BoardsBoardIdGetQueryKey = (boardId: string) => {
|
||||
return [`/api/v1/boards/${boardId}`] as const;
|
||||
};
|
||||
|
||||
export const getGetBoardApiV1BoardsBoardIdGetQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
boardId: string,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions, request: requestOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getGetBoardApiV1BoardsBoardIdGetQueryKey(boardId);
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>
|
||||
> = ({ signal }) =>
|
||||
getBoardApiV1BoardsBoardIdGet(boardId, { signal, ...requestOptions });
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!boardId,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
|
||||
export type GetBoardApiV1BoardsBoardIdGetQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>
|
||||
>;
|
||||
export type GetBoardApiV1BoardsBoardIdGetQueryError = HTTPValidationError;
|
||||
|
||||
export function useGetBoardApiV1BoardsBoardIdGet<
|
||||
TData = Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
boardId: string,
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useGetBoardApiV1BoardsBoardIdGet<
|
||||
TData = Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
boardId: string,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useGetBoardApiV1BoardsBoardIdGet<
|
||||
TData = Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
boardId: string,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
/**
|
||||
* @summary Get Board
|
||||
*/
|
||||
|
||||
export function useGetBoardApiV1BoardsBoardIdGet<
|
||||
TData = Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError = HTTPValidationError,
|
||||
>(
|
||||
boardId: string,
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getBoardApiV1BoardsBoardIdGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getGetBoardApiV1BoardsBoardIdGetQueryOptions(
|
||||
boardId,
|
||||
options,
|
||||
);
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Update Board
|
||||
*/
|
||||
export type updateBoardApiV1BoardsBoardIdPatchResponse200 = {
|
||||
data: BoardRead;
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type updateBoardApiV1BoardsBoardIdPatchResponse422 = {
|
||||
data: HTTPValidationError;
|
||||
status: 422;
|
||||
};
|
||||
|
||||
export type updateBoardApiV1BoardsBoardIdPatchResponseSuccess =
|
||||
updateBoardApiV1BoardsBoardIdPatchResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type updateBoardApiV1BoardsBoardIdPatchResponseError =
|
||||
updateBoardApiV1BoardsBoardIdPatchResponse422 & {
|
||||
headers: Headers;
|
||||
};
|
||||
|
||||
export type updateBoardApiV1BoardsBoardIdPatchResponse =
|
||||
| updateBoardApiV1BoardsBoardIdPatchResponseSuccess
|
||||
| updateBoardApiV1BoardsBoardIdPatchResponseError;
|
||||
|
||||
export const getUpdateBoardApiV1BoardsBoardIdPatchUrl = (boardId: string) => {
|
||||
return `/api/v1/boards/${boardId}`;
|
||||
};
|
||||
|
||||
export const updateBoardApiV1BoardsBoardIdPatch = async (
|
||||
boardId: string,
|
||||
boardUpdate: BoardUpdate,
|
||||
options?: RequestInit,
|
||||
): Promise<updateBoardApiV1BoardsBoardIdPatchResponse> => {
|
||||
return customFetch<updateBoardApiV1BoardsBoardIdPatchResponse>(
|
||||
getUpdateBoardApiV1BoardsBoardIdPatchUrl(boardId),
|
||||
{
|
||||
...options,
|
||||
method: "PATCH",
|
||||
headers: { "Content-Type": "application/json", ...options?.headers },
|
||||
body: JSON.stringify(boardUpdate),
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const getUpdateBoardApiV1BoardsBoardIdPatchMutationOptions = <
|
||||
TError = HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateBoardApiV1BoardsBoardIdPatch>>,
|
||||
TError,
|
||||
{ boardId: string; data: BoardUpdate },
|
||||
TContext
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateBoardApiV1BoardsBoardIdPatch>>,
|
||||
TError,
|
||||
{ boardId: string; data: BoardUpdate },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["updateBoardApiV1BoardsBoardIdPatch"];
|
||||
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 updateBoardApiV1BoardsBoardIdPatch>>,
|
||||
{ boardId: string; data: BoardUpdate }
|
||||
> = (props) => {
|
||||
const { boardId, data } = props ?? {};
|
||||
|
||||
return updateBoardApiV1BoardsBoardIdPatch(boardId, data, requestOptions);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type UpdateBoardApiV1BoardsBoardIdPatchMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof updateBoardApiV1BoardsBoardIdPatch>>
|
||||
>;
|
||||
export type UpdateBoardApiV1BoardsBoardIdPatchMutationBody = BoardUpdate;
|
||||
export type UpdateBoardApiV1BoardsBoardIdPatchMutationError =
|
||||
HTTPValidationError;
|
||||
|
||||
/**
|
||||
* @summary Update Board
|
||||
*/
|
||||
export const useUpdateBoardApiV1BoardsBoardIdPatch = <
|
||||
TError = HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateBoardApiV1BoardsBoardIdPatch>>,
|
||||
TError,
|
||||
{ boardId: string; data: BoardUpdate },
|
||||
TContext
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof updateBoardApiV1BoardsBoardIdPatch>>,
|
||||
TError,
|
||||
{ boardId: string; data: BoardUpdate },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(
|
||||
getUpdateBoardApiV1BoardsBoardIdPatchMutationOptions(options),
|
||||
queryClient,
|
||||
);
|
||||
};
|
||||
/**
|
||||
* @summary Delete Board
|
||||
*/
|
||||
export type deleteBoardApiV1BoardsBoardIdDeleteResponse200 = {
|
||||
data: DeleteBoardApiV1BoardsBoardIdDelete200;
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type deleteBoardApiV1BoardsBoardIdDeleteResponse422 = {
|
||||
data: HTTPValidationError;
|
||||
status: 422;
|
||||
};
|
||||
|
||||
export type deleteBoardApiV1BoardsBoardIdDeleteResponseSuccess =
|
||||
deleteBoardApiV1BoardsBoardIdDeleteResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type deleteBoardApiV1BoardsBoardIdDeleteResponseError =
|
||||
deleteBoardApiV1BoardsBoardIdDeleteResponse422 & {
|
||||
headers: Headers;
|
||||
};
|
||||
|
||||
export type deleteBoardApiV1BoardsBoardIdDeleteResponse =
|
||||
| deleteBoardApiV1BoardsBoardIdDeleteResponseSuccess
|
||||
| deleteBoardApiV1BoardsBoardIdDeleteResponseError;
|
||||
|
||||
export const getDeleteBoardApiV1BoardsBoardIdDeleteUrl = (boardId: string) => {
|
||||
return `/api/v1/boards/${boardId}`;
|
||||
};
|
||||
|
||||
export const deleteBoardApiV1BoardsBoardIdDelete = async (
|
||||
boardId: string,
|
||||
options?: RequestInit,
|
||||
): Promise<deleteBoardApiV1BoardsBoardIdDeleteResponse> => {
|
||||
return customFetch<deleteBoardApiV1BoardsBoardIdDeleteResponse>(
|
||||
getDeleteBoardApiV1BoardsBoardIdDeleteUrl(boardId),
|
||||
{
|
||||
...options,
|
||||
method: "DELETE",
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const getDeleteBoardApiV1BoardsBoardIdDeleteMutationOptions = <
|
||||
TError = HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
|
||||
TError,
|
||||
{ boardId: string },
|
||||
TContext
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
|
||||
TError,
|
||||
{ boardId: string },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["deleteBoardApiV1BoardsBoardIdDelete"];
|
||||
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 deleteBoardApiV1BoardsBoardIdDelete>>,
|
||||
{ boardId: string }
|
||||
> = (props) => {
|
||||
const { boardId } = props ?? {};
|
||||
|
||||
return deleteBoardApiV1BoardsBoardIdDelete(boardId, requestOptions);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type DeleteBoardApiV1BoardsBoardIdDeleteMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>
|
||||
>;
|
||||
|
||||
export type DeleteBoardApiV1BoardsBoardIdDeleteMutationError =
|
||||
HTTPValidationError;
|
||||
|
||||
/**
|
||||
* @summary Delete Board
|
||||
*/
|
||||
export const useDeleteBoardApiV1BoardsBoardIdDelete = <
|
||||
TError = HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
|
||||
TError,
|
||||
{ boardId: string },
|
||||
TContext
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
|
||||
TError,
|
||||
{ boardId: string },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(
|
||||
getDeleteBoardApiV1BoardsBoardIdDeleteMutationOptions(options),
|
||||
queryClient,
|
||||
);
|
||||
};
|
||||
515
frontend/src/api/generated/default/default.ts
Normal file
515
frontend/src/api/generated/default/default.ts
Normal file
@@ -0,0 +1,515 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type {
|
||||
DataTag,
|
||||
DefinedInitialDataOptions,
|
||||
DefinedUseQueryResult,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UndefinedInitialDataOptions,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
|
||||
import type {
|
||||
HealthHealthGet200,
|
||||
HealthzHealthzGet200,
|
||||
ReadyzReadyzGet200,
|
||||
} from ".././model";
|
||||
|
||||
import { customFetch } from "../../mutator";
|
||||
|
||||
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
||||
|
||||
/**
|
||||
* @summary Health
|
||||
*/
|
||||
export type healthHealthGetResponse200 = {
|
||||
data: HealthHealthGet200;
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type healthHealthGetResponseSuccess = healthHealthGetResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type healthHealthGetResponse = healthHealthGetResponseSuccess;
|
||||
|
||||
export const getHealthHealthGetUrl = () => {
|
||||
return `/health`;
|
||||
};
|
||||
|
||||
export const healthHealthGet = async (
|
||||
options?: RequestInit,
|
||||
): Promise<healthHealthGetResponse> => {
|
||||
return customFetch<healthHealthGetResponse>(getHealthHealthGetUrl(), {
|
||||
...options,
|
||||
method: "GET",
|
||||
});
|
||||
};
|
||||
|
||||
export const getHealthHealthGetQueryKey = () => {
|
||||
return [`/health`] as const;
|
||||
};
|
||||
|
||||
export const getHealthHealthGetQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError = unknown,
|
||||
>(options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof healthHealthGet>>, TError, TData>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
}) => {
|
||||
const { query: queryOptions, request: requestOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getHealthHealthGetQueryKey();
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof healthHealthGet>>> = ({
|
||||
signal,
|
||||
}) => healthHealthGet({ signal, ...requestOptions });
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
|
||||
export type HealthHealthGetQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof healthHealthGet>>
|
||||
>;
|
||||
export type HealthHealthGetQueryError = unknown;
|
||||
|
||||
export function useHealthHealthGet<
|
||||
TData = Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof healthHealthGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useHealthHealthGet<
|
||||
TData = Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof healthHealthGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useHealthHealthGet<
|
||||
TData = Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
/**
|
||||
* @summary Health
|
||||
*/
|
||||
|
||||
export function useHealthHealthGet<
|
||||
TData = Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthHealthGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getHealthHealthGetQueryOptions(options);
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Healthz
|
||||
*/
|
||||
export type healthzHealthzGetResponse200 = {
|
||||
data: HealthzHealthzGet200;
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type healthzHealthzGetResponseSuccess = healthzHealthzGetResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type healthzHealthzGetResponse = healthzHealthzGetResponseSuccess;
|
||||
|
||||
export const getHealthzHealthzGetUrl = () => {
|
||||
return `/healthz`;
|
||||
};
|
||||
|
||||
export const healthzHealthzGet = async (
|
||||
options?: RequestInit,
|
||||
): Promise<healthzHealthzGetResponse> => {
|
||||
return customFetch<healthzHealthzGetResponse>(getHealthzHealthzGetUrl(), {
|
||||
...options,
|
||||
method: "GET",
|
||||
});
|
||||
};
|
||||
|
||||
export const getHealthzHealthzGetQueryKey = () => {
|
||||
return [`/healthz`] as const;
|
||||
};
|
||||
|
||||
export const getHealthzHealthzGetQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError = unknown,
|
||||
>(options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
}) => {
|
||||
const { query: queryOptions, request: requestOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getHealthzHealthzGetQueryKey();
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>
|
||||
> = ({ signal }) => healthzHealthzGet({ signal, ...requestOptions });
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
|
||||
export type HealthzHealthzGetQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>
|
||||
>;
|
||||
export type HealthzHealthzGetQueryError = unknown;
|
||||
|
||||
export function useHealthzHealthzGet<
|
||||
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useHealthzHealthzGet<
|
||||
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useHealthzHealthzGet<
|
||||
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
/**
|
||||
* @summary Healthz
|
||||
*/
|
||||
|
||||
export function useHealthzHealthzGet<
|
||||
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof healthzHealthzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getHealthzHealthzGetQueryOptions(options);
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Readyz
|
||||
*/
|
||||
export type readyzReadyzGetResponse200 = {
|
||||
data: ReadyzReadyzGet200;
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type readyzReadyzGetResponseSuccess = readyzReadyzGetResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type readyzReadyzGetResponse = readyzReadyzGetResponseSuccess;
|
||||
|
||||
export const getReadyzReadyzGetUrl = () => {
|
||||
return `/readyz`;
|
||||
};
|
||||
|
||||
export const readyzReadyzGet = async (
|
||||
options?: RequestInit,
|
||||
): Promise<readyzReadyzGetResponse> => {
|
||||
return customFetch<readyzReadyzGetResponse>(getReadyzReadyzGetUrl(), {
|
||||
...options,
|
||||
method: "GET",
|
||||
});
|
||||
};
|
||||
|
||||
export const getReadyzReadyzGetQueryKey = () => {
|
||||
return [`/readyz`] as const;
|
||||
};
|
||||
|
||||
export const getReadyzReadyzGetQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError = unknown,
|
||||
>(options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<Awaited<ReturnType<typeof readyzReadyzGet>>, TError, TData>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
}) => {
|
||||
const { query: queryOptions, request: requestOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getReadyzReadyzGetQueryKey();
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof readyzReadyzGet>>> = ({
|
||||
signal,
|
||||
}) => readyzReadyzGet({ signal, ...requestOptions });
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
|
||||
export type ReadyzReadyzGetQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof readyzReadyzGet>>
|
||||
>;
|
||||
export type ReadyzReadyzGetQueryError = unknown;
|
||||
|
||||
export function useReadyzReadyzGet<
|
||||
TData = Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof readyzReadyzGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useReadyzReadyzGet<
|
||||
TData = Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof readyzReadyzGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useReadyzReadyzGet<
|
||||
TData = Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
/**
|
||||
* @summary Readyz
|
||||
*/
|
||||
|
||||
export function useReadyzReadyzGet<
|
||||
TData = Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof readyzReadyzGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getReadyzReadyzGetQueryOptions(options);
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
1416
frontend/src/api/generated/gateway/gateway.ts
Normal file
1416
frontend/src/api/generated/gateway/gateway.ts
Normal file
File diff suppressed because it is too large
Load Diff
15
frontend/src/api/generated/model/activityEventRead.ts
Normal file
15
frontend/src/api/generated/model/activityEventRead.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface ActivityEventRead {
|
||||
id: string;
|
||||
event_type: string;
|
||||
message: string | null;
|
||||
agent_id: string | null;
|
||||
task_id: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
14
frontend/src/api/generated/model/agentCreate.ts
Normal file
14
frontend/src/api/generated/model/agentCreate.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { AgentCreateHeartbeatConfig } from "./agentCreateHeartbeatConfig";
|
||||
|
||||
export interface AgentCreate {
|
||||
board_id?: string | null;
|
||||
name: string;
|
||||
status?: string;
|
||||
heartbeat_config?: AgentCreateHeartbeatConfig;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type AgentCreateHeartbeatConfig = { [key: string]: unknown } | null;
|
||||
10
frontend/src/api/generated/model/agentDeleteConfirm.ts
Normal file
10
frontend/src/api/generated/model/agentDeleteConfirm.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface AgentDeleteConfirm {
|
||||
token: string;
|
||||
}
|
||||
10
frontend/src/api/generated/model/agentHeartbeat.ts
Normal file
10
frontend/src/api/generated/model/agentHeartbeat.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface AgentHeartbeat {
|
||||
status?: string | null;
|
||||
}
|
||||
12
frontend/src/api/generated/model/agentHeartbeatCreate.ts
Normal file
12
frontend/src/api/generated/model/agentHeartbeatCreate.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface AgentHeartbeatCreate {
|
||||
status?: string | null;
|
||||
name: string;
|
||||
board_id?: string | null;
|
||||
}
|
||||
11
frontend/src/api/generated/model/agentProvisionConfirm.ts
Normal file
11
frontend/src/api/generated/model/agentProvisionConfirm.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface AgentProvisionConfirm {
|
||||
token: string;
|
||||
action?: string | null;
|
||||
}
|
||||
19
frontend/src/api/generated/model/agentRead.ts
Normal file
19
frontend/src/api/generated/model/agentRead.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { AgentReadHeartbeatConfig } from "./agentReadHeartbeatConfig";
|
||||
|
||||
export interface AgentRead {
|
||||
board_id?: string | null;
|
||||
name: string;
|
||||
status?: string;
|
||||
heartbeat_config?: AgentReadHeartbeatConfig;
|
||||
id: string;
|
||||
openclaw_session_id?: string | null;
|
||||
last_seen_at: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type AgentReadHeartbeatConfig = { [key: string]: unknown } | null;
|
||||
14
frontend/src/api/generated/model/agentUpdate.ts
Normal file
14
frontend/src/api/generated/model/agentUpdate.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { AgentUpdateHeartbeatConfig } from "./agentUpdateHeartbeatConfig";
|
||||
|
||||
export interface AgentUpdate {
|
||||
board_id?: string | null;
|
||||
name?: string | null;
|
||||
status?: string | null;
|
||||
heartbeat_config?: AgentUpdateHeartbeatConfig;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type AgentUpdateHeartbeatConfig = { [key: string]: unknown } | null;
|
||||
17
frontend/src/api/generated/model/boardCreate.ts
Normal file
17
frontend/src/api/generated/model/boardCreate.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface BoardCreate {
|
||||
name: string;
|
||||
slug: string;
|
||||
gateway_url?: string | null;
|
||||
gateway_main_session_key?: string | null;
|
||||
gateway_workspace_root?: string | null;
|
||||
identity_template?: string | null;
|
||||
soul_template?: string | null;
|
||||
gateway_token?: string | null;
|
||||
}
|
||||
19
frontend/src/api/generated/model/boardRead.ts
Normal file
19
frontend/src/api/generated/model/boardRead.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface BoardRead {
|
||||
name: string;
|
||||
slug: string;
|
||||
gateway_url?: string | null;
|
||||
gateway_main_session_key?: string | null;
|
||||
gateway_workspace_root?: string | null;
|
||||
identity_template?: string | null;
|
||||
soul_template?: string | null;
|
||||
id: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
17
frontend/src/api/generated/model/boardUpdate.ts
Normal file
17
frontend/src/api/generated/model/boardUpdate.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface BoardUpdate {
|
||||
name?: string | null;
|
||||
slug?: string | null;
|
||||
gateway_url?: string | null;
|
||||
gateway_token?: string | null;
|
||||
gateway_main_session_key?: string | null;
|
||||
gateway_workspace_root?: string | null;
|
||||
identity_template?: string | null;
|
||||
soul_template?: string | null;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ConfirmDeleteAgentApiV1AgentsAgentIdDeleteConfirmPost200 = {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ConfirmProvisionAgentApiV1AgentsAgentIdProvisionConfirmPost200 = {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type DeleteAgentApiV1AgentsAgentIdDelete200 = { [key: string]: boolean };
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type DeleteBoardApiV1BoardsBoardIdDelete200 = { [key: string]: boolean };
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type DeleteTaskApiV1BoardsBoardIdTasksTaskIdDelete200 = {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type GatewayCommandsApiV1GatewayCommandsGet200 = {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type GatewayStatusApiV1GatewayStatusGet200 = { [key: string]: unknown };
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type GatewayStatusApiV1GatewayStatusGetParams = {
|
||||
board_id?: string | null;
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type GetGatewaySessionApiV1GatewaySessionsSessionIdGet200 = {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type GetGatewaySessionApiV1GatewaySessionsSessionIdGetParams = {
|
||||
board_id?: string | null;
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type GetSessionHistoryApiV1GatewaySessionsSessionIdHistoryGet200 = {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type GetSessionHistoryApiV1GatewaySessionsSessionIdHistoryGetParams = {
|
||||
board_id?: string | null;
|
||||
};
|
||||
11
frontend/src/api/generated/model/hTTPValidationError.ts
Normal file
11
frontend/src/api/generated/model/hTTPValidationError.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import type { ValidationError } from "./validationError";
|
||||
|
||||
export interface HTTPValidationError {
|
||||
detail?: ValidationError[];
|
||||
}
|
||||
8
frontend/src/api/generated/model/healthHealthGet200.ts
Normal file
8
frontend/src/api/generated/model/healthHealthGet200.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type HealthHealthGet200 = { [key: string]: boolean };
|
||||
8
frontend/src/api/generated/model/healthzHealthzGet200.ts
Normal file
8
frontend/src/api/generated/model/healthzHealthzGet200.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type HealthzHealthzGet200 = { [key: string]: boolean };
|
||||
52
frontend/src/api/generated/model/index.ts
Normal file
52
frontend/src/api/generated/model/index.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export * from "./activityEventRead";
|
||||
export * from "./agentCreate";
|
||||
export * from "./agentCreateHeartbeatConfig";
|
||||
export * from "./agentDeleteConfirm";
|
||||
export * from "./agentHeartbeat";
|
||||
export * from "./agentHeartbeatCreate";
|
||||
export * from "./agentProvisionConfirm";
|
||||
export * from "./agentRead";
|
||||
export * from "./agentReadHeartbeatConfig";
|
||||
export * from "./agentUpdate";
|
||||
export * from "./agentUpdateHeartbeatConfig";
|
||||
export * from "./boardCreate";
|
||||
export * from "./boardRead";
|
||||
export * from "./boardUpdate";
|
||||
export * from "./confirmDeleteAgentApiV1AgentsAgentIdDeleteConfirmPost200";
|
||||
export * from "./confirmProvisionAgentApiV1AgentsAgentIdProvisionConfirmPost200";
|
||||
export * from "./deleteAgentApiV1AgentsAgentIdDelete200";
|
||||
export * from "./deleteBoardApiV1BoardsBoardIdDelete200";
|
||||
export * from "./deleteTaskApiV1BoardsBoardIdTasksTaskIdDelete200";
|
||||
export * from "./gatewayCommandsApiV1GatewayCommandsGet200";
|
||||
export * from "./gatewayStatusApiV1GatewayStatusGet200";
|
||||
export * from "./gatewayStatusApiV1GatewayStatusGetParams";
|
||||
export * from "./getGatewaySessionApiV1GatewaySessionsSessionIdGet200";
|
||||
export * from "./getGatewaySessionApiV1GatewaySessionsSessionIdGetParams";
|
||||
export * from "./getSessionHistoryApiV1GatewaySessionsSessionIdHistoryGet200";
|
||||
export * from "./getSessionHistoryApiV1GatewaySessionsSessionIdHistoryGetParams";
|
||||
export * from "./healthHealthGet200";
|
||||
export * from "./healthzHealthzGet200";
|
||||
export * from "./hTTPValidationError";
|
||||
export * from "./listActivityApiV1ActivityGetParams";
|
||||
export * from "./listSessionsApiV1GatewaySessionsGet200";
|
||||
export * from "./listSessionsApiV1GatewaySessionsGetParams";
|
||||
export * from "./listTasksApiV1BoardsBoardIdTasksGetParams";
|
||||
export * from "./readyzReadyzGet200";
|
||||
export * from "./sendSessionMessageApiV1GatewaySessionsSessionIdMessagePost200";
|
||||
export * from "./sendSessionMessageApiV1GatewaySessionsSessionIdMessagePostBody";
|
||||
export * from "./sendSessionMessageApiV1GatewaySessionsSessionIdMessagePostParams";
|
||||
export * from "./taskCommentCreate";
|
||||
export * from "./taskCommentRead";
|
||||
export * from "./taskCreate";
|
||||
export * from "./taskRead";
|
||||
export * from "./taskUpdate";
|
||||
export * from "./userRead";
|
||||
export * from "./userUpdate";
|
||||
export * from "./validationError";
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ListActivityApiV1ActivityGetParams = {
|
||||
/**
|
||||
* @minimum 1
|
||||
* @maximum 200
|
||||
*/
|
||||
limit?: number;
|
||||
/**
|
||||
* @minimum 0
|
||||
*/
|
||||
offset?: number;
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ListSessionsApiV1GatewaySessionsGet200 = { [key: string]: unknown };
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ListSessionsApiV1GatewaySessionsGetParams = {
|
||||
board_id?: string | null;
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ListTasksApiV1BoardsBoardIdTasksGetParams = {
|
||||
status?: string | null;
|
||||
assigned_agent_id?: string | null;
|
||||
unassigned?: boolean | null;
|
||||
limit?: number | null;
|
||||
};
|
||||
8
frontend/src/api/generated/model/readyzReadyzGet200.ts
Normal file
8
frontend/src/api/generated/model/readyzReadyzGet200.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type ReadyzReadyzGet200 = { [key: string]: boolean };
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type SendSessionMessageApiV1GatewaySessionsSessionIdMessagePost200 = {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type SendSessionMessageApiV1GatewaySessionsSessionIdMessagePostBody = {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export type SendSessionMessageApiV1GatewaySessionsSessionIdMessagePostParams = {
|
||||
board_id?: string | null;
|
||||
};
|
||||
10
frontend/src/api/generated/model/taskCommentCreate.ts
Normal file
10
frontend/src/api/generated/model/taskCommentCreate.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface TaskCommentCreate {
|
||||
message: string;
|
||||
}
|
||||
14
frontend/src/api/generated/model/taskCommentRead.ts
Normal file
14
frontend/src/api/generated/model/taskCommentRead.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface TaskCommentRead {
|
||||
id: string;
|
||||
message: string | null;
|
||||
agent_id: string | null;
|
||||
task_id: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
16
frontend/src/api/generated/model/taskCreate.ts
Normal file
16
frontend/src/api/generated/model/taskCreate.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface TaskCreate {
|
||||
title: string;
|
||||
description?: string | null;
|
||||
status?: string;
|
||||
priority?: string;
|
||||
due_at?: string | null;
|
||||
assigned_agent_id?: string | null;
|
||||
created_by_user_id?: string | null;
|
||||
}
|
||||
21
frontend/src/api/generated/model/taskRead.ts
Normal file
21
frontend/src/api/generated/model/taskRead.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface TaskRead {
|
||||
title: string;
|
||||
description?: string | null;
|
||||
status?: string;
|
||||
priority?: string;
|
||||
due_at?: string | null;
|
||||
assigned_agent_id?: string | null;
|
||||
id: string;
|
||||
board_id: string | null;
|
||||
created_by_user_id: string | null;
|
||||
in_progress_at: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
16
frontend/src/api/generated/model/taskUpdate.ts
Normal file
16
frontend/src/api/generated/model/taskUpdate.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface TaskUpdate {
|
||||
title?: string | null;
|
||||
description?: string | null;
|
||||
status?: string | null;
|
||||
priority?: string | null;
|
||||
due_at?: string | null;
|
||||
assigned_agent_id?: string | null;
|
||||
comment?: string | null;
|
||||
}
|
||||
19
frontend/src/api/generated/model/userRead.ts
Normal file
19
frontend/src/api/generated/model/userRead.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface UserRead {
|
||||
clerk_user_id: string;
|
||||
email?: string | null;
|
||||
name?: string | null;
|
||||
preferred_name?: string | null;
|
||||
pronouns?: string | null;
|
||||
timezone?: string | null;
|
||||
notes?: string | null;
|
||||
context?: string | null;
|
||||
id: string;
|
||||
is_super_admin: boolean;
|
||||
}
|
||||
15
frontend/src/api/generated/model/userUpdate.ts
Normal file
15
frontend/src/api/generated/model/userUpdate.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface UserUpdate {
|
||||
name?: string | null;
|
||||
preferred_name?: string | null;
|
||||
pronouns?: string | null;
|
||||
timezone?: string | null;
|
||||
notes?: string | null;
|
||||
context?: string | null;
|
||||
}
|
||||
12
frontend/src/api/generated/model/validationError.ts
Normal file
12
frontend/src/api/generated/model/validationError.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
|
||||
export interface ValidationError {
|
||||
loc: (string | number)[];
|
||||
msg: string;
|
||||
type: string;
|
||||
}
|
||||
1091
frontend/src/api/generated/tasks/tasks.ts
Normal file
1091
frontend/src/api/generated/tasks/tasks.ts
Normal file
File diff suppressed because it is too large
Load Diff
314
frontend/src/api/generated/users/users.ts
Normal file
314
frontend/src/api/generated/users/users.ts
Normal file
@@ -0,0 +1,314 @@
|
||||
/**
|
||||
* Generated by orval v8.2.0 🍺
|
||||
* Do not edit manually.
|
||||
* Mission Control API
|
||||
* OpenAPI spec version: 0.1.0
|
||||
*/
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import type {
|
||||
DataTag,
|
||||
DefinedInitialDataOptions,
|
||||
DefinedUseQueryResult,
|
||||
MutationFunction,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UndefinedInitialDataOptions,
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
|
||||
import type { HTTPValidationError, UserRead, UserUpdate } from ".././model";
|
||||
|
||||
import { customFetch } from "../../mutator";
|
||||
|
||||
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
||||
|
||||
/**
|
||||
* @summary Get Me
|
||||
*/
|
||||
export type getMeApiV1UsersMeGetResponse200 = {
|
||||
data: UserRead;
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type getMeApiV1UsersMeGetResponseSuccess =
|
||||
getMeApiV1UsersMeGetResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type getMeApiV1UsersMeGetResponse = getMeApiV1UsersMeGetResponseSuccess;
|
||||
|
||||
export const getGetMeApiV1UsersMeGetUrl = () => {
|
||||
return `/api/v1/users/me`;
|
||||
};
|
||||
|
||||
export const getMeApiV1UsersMeGet = async (
|
||||
options?: RequestInit,
|
||||
): Promise<getMeApiV1UsersMeGetResponse> => {
|
||||
return customFetch<getMeApiV1UsersMeGetResponse>(
|
||||
getGetMeApiV1UsersMeGetUrl(),
|
||||
{
|
||||
...options,
|
||||
method: "GET",
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const getGetMeApiV1UsersMeGetQueryKey = () => {
|
||||
return [`/api/v1/users/me`] as const;
|
||||
};
|
||||
|
||||
export const getGetMeApiV1UsersMeGetQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError = unknown,
|
||||
>(options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
}) => {
|
||||
const { query: queryOptions, request: requestOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getGetMeApiV1UsersMeGetQueryKey();
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>
|
||||
> = ({ signal }) => getMeApiV1UsersMeGet({ signal, ...requestOptions });
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
};
|
||||
|
||||
export type GetMeApiV1UsersMeGetQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>
|
||||
>;
|
||||
export type GetMeApiV1UsersMeGetQueryError = unknown;
|
||||
|
||||
export function useGetMeApiV1UsersMeGet<
|
||||
TData = Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options: {
|
||||
query: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
DefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): DefinedUseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useGetMeApiV1UsersMeGet<
|
||||
TData = Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
> &
|
||||
Pick<
|
||||
UndefinedInitialDataOptions<
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError,
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>
|
||||
>,
|
||||
"initialData"
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
export function useGetMeApiV1UsersMeGet<
|
||||
TData = Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
};
|
||||
/**
|
||||
* @summary Get Me
|
||||
*/
|
||||
|
||||
export function useGetMeApiV1UsersMeGet<
|
||||
TData = Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError = unknown,
|
||||
>(
|
||||
options?: {
|
||||
query?: Partial<
|
||||
UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getMeApiV1UsersMeGet>>,
|
||||
TError,
|
||||
TData
|
||||
>
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseQueryResult<TData, TError> & {
|
||||
queryKey: DataTag<QueryKey, TData, TError>;
|
||||
} {
|
||||
const queryOptions = getGetMeApiV1UsersMeGetQueryOptions(options);
|
||||
|
||||
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
|
||||
TData,
|
||||
TError
|
||||
> & { queryKey: DataTag<QueryKey, TData, TError> };
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Update Me
|
||||
*/
|
||||
export type updateMeApiV1UsersMePatchResponse200 = {
|
||||
data: UserRead;
|
||||
status: 200;
|
||||
};
|
||||
|
||||
export type updateMeApiV1UsersMePatchResponse422 = {
|
||||
data: HTTPValidationError;
|
||||
status: 422;
|
||||
};
|
||||
|
||||
export type updateMeApiV1UsersMePatchResponseSuccess =
|
||||
updateMeApiV1UsersMePatchResponse200 & {
|
||||
headers: Headers;
|
||||
};
|
||||
export type updateMeApiV1UsersMePatchResponseError =
|
||||
updateMeApiV1UsersMePatchResponse422 & {
|
||||
headers: Headers;
|
||||
};
|
||||
|
||||
export type updateMeApiV1UsersMePatchResponse =
|
||||
| updateMeApiV1UsersMePatchResponseSuccess
|
||||
| updateMeApiV1UsersMePatchResponseError;
|
||||
|
||||
export const getUpdateMeApiV1UsersMePatchUrl = () => {
|
||||
return `/api/v1/users/me`;
|
||||
};
|
||||
|
||||
export const updateMeApiV1UsersMePatch = async (
|
||||
userUpdate: UserUpdate,
|
||||
options?: RequestInit,
|
||||
): Promise<updateMeApiV1UsersMePatchResponse> => {
|
||||
return customFetch<updateMeApiV1UsersMePatchResponse>(
|
||||
getUpdateMeApiV1UsersMePatchUrl(),
|
||||
{
|
||||
...options,
|
||||
method: "PATCH",
|
||||
headers: { "Content-Type": "application/json", ...options?.headers },
|
||||
body: JSON.stringify(userUpdate),
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const getUpdateMeApiV1UsersMePatchMutationOptions = <
|
||||
TError = HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateMeApiV1UsersMePatch>>,
|
||||
TError,
|
||||
{ data: UserUpdate },
|
||||
TContext
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateMeApiV1UsersMePatch>>,
|
||||
TError,
|
||||
{ data: UserUpdate },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ["updateMeApiV1UsersMePatch"];
|
||||
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 updateMeApiV1UsersMePatch>>,
|
||||
{ data: UserUpdate }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
return updateMeApiV1UsersMePatch(data, requestOptions);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type UpdateMeApiV1UsersMePatchMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof updateMeApiV1UsersMePatch>>
|
||||
>;
|
||||
export type UpdateMeApiV1UsersMePatchMutationBody = UserUpdate;
|
||||
export type UpdateMeApiV1UsersMePatchMutationError = HTTPValidationError;
|
||||
|
||||
/**
|
||||
* @summary Update Me
|
||||
*/
|
||||
export const useUpdateMeApiV1UsersMePatch = <
|
||||
TError = HTTPValidationError,
|
||||
TContext = unknown,
|
||||
>(
|
||||
options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateMeApiV1UsersMePatch>>,
|
||||
TError,
|
||||
{ data: UserUpdate },
|
||||
TContext
|
||||
>;
|
||||
request?: SecondParameter<typeof customFetch>;
|
||||
},
|
||||
queryClient?: QueryClient,
|
||||
): UseMutationResult<
|
||||
Awaited<ReturnType<typeof updateMeApiV1UsersMePatch>>,
|
||||
TError,
|
||||
{ data: UserUpdate },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(
|
||||
getUpdateMeApiV1UsersMePatchMutationOptions(options),
|
||||
queryClient,
|
||||
);
|
||||
};
|
||||
@@ -2,7 +2,11 @@ export const customFetch = async <T>(
|
||||
url: string,
|
||||
options: RequestInit
|
||||
): Promise<T> => {
|
||||
const baseUrl = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:8000";
|
||||
const rawBaseUrl = process.env.NEXT_PUBLIC_API_URL;
|
||||
if (!rawBaseUrl) {
|
||||
throw new Error("NEXT_PUBLIC_API_URL is not set.");
|
||||
}
|
||||
const baseUrl = rawBaseUrl.replace(/\/+$/, "");
|
||||
const response = await fetch(`${baseUrl}${url}`, {
|
||||
...options,
|
||||
headers: {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { DashboardSidebar } from "@/components/organisms/DashboardSidebar";
|
||||
import { DashboardShell } from "@/components/templates/DashboardShell";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { getApiBaseUrl } from "@/lib/api-base";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
@@ -17,9 +18,7 @@ import {
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
|
||||
const apiBase =
|
||||
process.env.NEXT_PUBLIC_API_URL?.replace(/\/+$/, "") ||
|
||||
"http://localhost:8000";
|
||||
const apiBase = getApiBaseUrl();
|
||||
|
||||
type Agent = {
|
||||
id: string;
|
||||
|
||||
@@ -18,10 +18,9 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { getApiBaseUrl } from "@/lib/api-base";
|
||||
|
||||
const apiBase =
|
||||
process.env.NEXT_PUBLIC_API_URL?.replace(/\/+$/, "") ||
|
||||
"http://localhost:8000";
|
||||
const apiBase = getApiBaseUrl();
|
||||
|
||||
type Agent = {
|
||||
id: string;
|
||||
|
||||
@@ -9,6 +9,7 @@ import { DashboardSidebar } from "@/components/organisms/DashboardSidebar";
|
||||
import { DashboardShell } from "@/components/templates/DashboardShell";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { getApiBaseUrl } from "@/lib/api-base";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
@@ -17,9 +18,7 @@ import {
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
|
||||
const apiBase =
|
||||
process.env.NEXT_PUBLIC_API_URL?.replace(/\/+$/, "") ||
|
||||
"http://localhost:8000";
|
||||
const apiBase = getApiBaseUrl();
|
||||
|
||||
type Agent = {
|
||||
id: string;
|
||||
|
||||
@@ -33,10 +33,9 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { getApiBaseUrl } from "@/lib/api-base";
|
||||
|
||||
const apiBase =
|
||||
process.env.NEXT_PUBLIC_API_URL?.replace(/\/+$/, "") ||
|
||||
"http://localhost:8000";
|
||||
const apiBase = getApiBaseUrl();
|
||||
|
||||
type Agent = {
|
||||
id: string;
|
||||
|
||||
@@ -9,10 +9,10 @@ import { DashboardSidebar } from "@/components/organisms/DashboardSidebar";
|
||||
import { DashboardShell } from "@/components/templates/DashboardShell";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { getApiBaseUrl } from "@/lib/api-base";
|
||||
|
||||
const apiBase =
|
||||
process.env.NEXT_PUBLIC_API_URL?.replace(/\/+$/, "") ||
|
||||
"http://localhost:8000";
|
||||
const apiBase = getApiBaseUrl();
|
||||
|
||||
type Board = {
|
||||
id: string;
|
||||
@@ -21,6 +21,8 @@ type Board = {
|
||||
gateway_url?: string | null;
|
||||
gateway_main_session_key?: string | null;
|
||||
gateway_workspace_root?: string | null;
|
||||
identity_template?: string | null;
|
||||
soul_template?: string | null;
|
||||
};
|
||||
|
||||
const slugify = (value: string) =>
|
||||
@@ -44,6 +46,8 @@ export default function EditBoardPage() {
|
||||
const [gatewayToken, setGatewayToken] = useState("");
|
||||
const [gatewayMainSessionKey, setGatewayMainSessionKey] = useState("");
|
||||
const [gatewayWorkspaceRoot, setGatewayWorkspaceRoot] = useState("");
|
||||
const [identityTemplate, setIdentityTemplate] = useState("");
|
||||
const [soulTemplate, setSoulTemplate] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
@@ -66,6 +70,8 @@ export default function EditBoardPage() {
|
||||
setGatewayUrl(data.gateway_url ?? "");
|
||||
setGatewayMainSessionKey(data.gateway_main_session_key ?? "");
|
||||
setGatewayWorkspaceRoot(data.gateway_workspace_root ?? "");
|
||||
setIdentityTemplate(data.identity_template ?? "");
|
||||
setSoulTemplate(data.soul_template ?? "");
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : "Something went wrong.");
|
||||
} finally {
|
||||
@@ -96,6 +102,8 @@ export default function EditBoardPage() {
|
||||
gateway_url: gatewayUrl.trim() || null,
|
||||
gateway_main_session_key: gatewayMainSessionKey.trim() || null,
|
||||
gateway_workspace_root: gatewayWorkspaceRoot.trim() || null,
|
||||
identity_template: identityTemplate.trim() || null,
|
||||
soul_template: soulTemplate.trim() || null,
|
||||
};
|
||||
if (gatewayToken.trim()) {
|
||||
payload.gateway_token = gatewayToken.trim();
|
||||
@@ -210,6 +218,28 @@ export default function EditBoardPage() {
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-strong">
|
||||
Identity template (optional)
|
||||
</label>
|
||||
<Textarea
|
||||
value={identityTemplate}
|
||||
onChange={(event) => setIdentityTemplate(event.target.value)}
|
||||
placeholder="Override IDENTITY.md for agents in this board."
|
||||
className="min-h-[140px]"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-strong">
|
||||
Soul template (optional)
|
||||
</label>
|
||||
<Textarea
|
||||
value={soulTemplate}
|
||||
onChange={(event) => setSoulTemplate(event.target.value)}
|
||||
placeholder="Override SOUL.md for agents in this board."
|
||||
className="min-h-[160px]"
|
||||
/>
|
||||
</div>
|
||||
{error ? (
|
||||
<div className="rounded-lg border border-[color:var(--border)] bg-[color:var(--surface-muted)] p-3 text-xs text-muted">
|
||||
{error}
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { getApiBaseUrl } from "@/lib/api-base";
|
||||
|
||||
type Board = {
|
||||
id: string;
|
||||
@@ -57,9 +58,7 @@ type TaskComment = {
|
||||
created_at: string;
|
||||
};
|
||||
|
||||
const apiBase =
|
||||
process.env.NEXT_PUBLIC_API_URL?.replace(/\/+$/, "") ||
|
||||
"http://localhost:8000";
|
||||
const apiBase = getApiBaseUrl();
|
||||
|
||||
const priorities = [
|
||||
{ value: "low", label: "Low" },
|
||||
|
||||
@@ -9,6 +9,8 @@ import { DashboardSidebar } from "@/components/organisms/DashboardSidebar";
|
||||
import { DashboardShell } from "@/components/templates/DashboardShell";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { getApiBaseUrl } from "@/lib/api-base";
|
||||
|
||||
type Board = {
|
||||
id: string;
|
||||
@@ -18,11 +20,11 @@ type Board = {
|
||||
gateway_token?: string | null;
|
||||
gateway_main_session_key?: string | null;
|
||||
gateway_workspace_root?: string | null;
|
||||
identity_template?: string | null;
|
||||
soul_template?: string | null;
|
||||
};
|
||||
|
||||
const apiBase =
|
||||
process.env.NEXT_PUBLIC_API_URL?.replace(/\/+$/, "") ||
|
||||
"http://localhost:8000";
|
||||
const apiBase = getApiBaseUrl();
|
||||
|
||||
const slugify = (value: string) =>
|
||||
value
|
||||
@@ -39,6 +41,8 @@ export default function NewBoardPage() {
|
||||
const [gatewayToken, setGatewayToken] = useState("");
|
||||
const [gatewayMainSessionKey, setGatewayMainSessionKey] = useState("");
|
||||
const [gatewayWorkspaceRoot, setGatewayWorkspaceRoot] = useState("");
|
||||
const [identityTemplate, setIdentityTemplate] = useState("");
|
||||
const [soulTemplate, setSoulTemplate] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
@@ -63,6 +67,12 @@ export default function NewBoardPage() {
|
||||
if (gatewayWorkspaceRoot.trim()) {
|
||||
payload.gateway_workspace_root = gatewayWorkspaceRoot.trim();
|
||||
}
|
||||
if (identityTemplate.trim()) {
|
||||
payload.identity_template = identityTemplate.trim();
|
||||
}
|
||||
if (soulTemplate.trim()) {
|
||||
payload.soul_template = soulTemplate.trim();
|
||||
}
|
||||
const response = await fetch(`${apiBase}/api/v1/boards`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -170,6 +180,28 @@ export default function NewBoardPage() {
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-strong">
|
||||
Identity template (optional)
|
||||
</label>
|
||||
<Textarea
|
||||
value={identityTemplate}
|
||||
onChange={(event) => setIdentityTemplate(event.target.value)}
|
||||
placeholder="Override IDENTITY.md for agents in this board."
|
||||
className="min-h-[140px]"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-strong">
|
||||
Soul template (optional)
|
||||
</label>
|
||||
<Textarea
|
||||
value={soulTemplate}
|
||||
onChange={(event) => setSoulTemplate(event.target.value)}
|
||||
placeholder="Override SOUL.md for agents in this board."
|
||||
className="min-h-[160px]"
|
||||
/>
|
||||
</div>
|
||||
{error ? (
|
||||
<div className="rounded-lg border border-[color:var(--border)] bg-[color:var(--surface-muted)] p-3 text-xs text-muted">
|
||||
{error}
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
import { DashboardSidebar } from "@/components/organisms/DashboardSidebar";
|
||||
import { DashboardShell } from "@/components/templates/DashboardShell";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { getApiBaseUrl } from "@/lib/api-base";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@@ -30,9 +31,7 @@ type Board = {
|
||||
slug: string;
|
||||
};
|
||||
|
||||
const apiBase =
|
||||
process.env.NEXT_PUBLIC_API_URL?.replace(/\/+$/, "") ||
|
||||
"http://localhost:8000";
|
||||
const apiBase = getApiBaseUrl();
|
||||
|
||||
export default function BoardsPage() {
|
||||
const { getToken, isSignedIn } = useAuth();
|
||||
|
||||
@@ -20,8 +20,8 @@ export default function DashboardPage() {
|
||||
</p>
|
||||
<SignInButton
|
||||
mode="modal"
|
||||
forceRedirectUrl="/boards"
|
||||
signUpForceRedirectUrl="/boards"
|
||||
forceRedirectUrl="/onboarding"
|
||||
signUpForceRedirectUrl="/onboarding"
|
||||
>
|
||||
<Button>Sign in</Button>
|
||||
</SignInButton>
|
||||
|
||||
275
frontend/src/app/onboarding/page.tsx
Normal file
275
frontend/src/app/onboarding/page.tsx
Normal file
@@ -0,0 +1,275 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
import { SignInButton, SignedIn, SignedOut, useAuth, useUser } from "@clerk/nextjs";
|
||||
import { Globe, Info, RotateCcw, Save, User } from "lucide-react";
|
||||
|
||||
import { DashboardShell } from "@/components/templates/DashboardShell";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import SearchableSelect from "@/components/ui/searchable-select";
|
||||
import { getApiBaseUrl } from "@/lib/api-base";
|
||||
|
||||
const apiBase = getApiBaseUrl();
|
||||
|
||||
type UserProfile = {
|
||||
id: string;
|
||||
name?: string | null;
|
||||
preferred_name?: string | null;
|
||||
pronouns?: string | null;
|
||||
timezone?: string | null;
|
||||
notes?: string | null;
|
||||
context?: string | null;
|
||||
};
|
||||
|
||||
const isCompleteProfile = (profile: UserProfile | null) => {
|
||||
if (!profile) return false;
|
||||
const resolvedName = profile.preferred_name?.trim() || profile.name?.trim();
|
||||
return Boolean(resolvedName) && Boolean(profile.timezone?.trim());
|
||||
};
|
||||
|
||||
export default function OnboardingPage() {
|
||||
const router = useRouter();
|
||||
const { getToken, isSignedIn } = useAuth();
|
||||
const { user } = useUser();
|
||||
|
||||
const [profile, setProfile] = useState<UserProfile | null>(null);
|
||||
const [name, setName] = useState("");
|
||||
const [timezone, setTimezone] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const requiredMissing = useMemo(
|
||||
() => [name, timezone].some((value) => !value.trim()),
|
||||
[name, timezone]
|
||||
);
|
||||
|
||||
const timezones = useMemo(() => {
|
||||
if (typeof Intl !== "undefined" && "supportedValuesOf" in Intl) {
|
||||
return (Intl as typeof Intl & { supportedValuesOf: (key: string) => string[] })
|
||||
.supportedValuesOf("timeZone")
|
||||
.sort();
|
||||
}
|
||||
return [
|
||||
"America/Los_Angeles",
|
||||
"America/Denver",
|
||||
"America/Chicago",
|
||||
"America/New_York",
|
||||
"America/Sao_Paulo",
|
||||
"Europe/London",
|
||||
"Europe/Berlin",
|
||||
"Europe/Paris",
|
||||
"Asia/Dubai",
|
||||
"Asia/Kolkata",
|
||||
"Asia/Singapore",
|
||||
"Asia/Tokyo",
|
||||
"Australia/Sydney",
|
||||
];
|
||||
}, []);
|
||||
|
||||
const timezoneOptions = useMemo(
|
||||
() => timezones.map((tz) => ({ value: tz, label: tz })),
|
||||
[timezones],
|
||||
);
|
||||
|
||||
const loadProfile = async () => {
|
||||
if (!isSignedIn) return;
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const token = await getToken();
|
||||
const response = await fetch(`${apiBase}/api/v1/users/me`, {
|
||||
headers: { Authorization: token ? `Bearer ${token}` : "" },
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error("Unable to load profile.");
|
||||
}
|
||||
const data = (await response.json()) as UserProfile;
|
||||
setProfile(data);
|
||||
const fallbackName =
|
||||
user?.fullName ?? user?.firstName ?? user?.username ?? "";
|
||||
setName(data.preferred_name ?? data.name ?? fallbackName);
|
||||
setTimezone(data.timezone ?? "");
|
||||
if (isCompleteProfile(data)) {
|
||||
router.replace("/boards");
|
||||
}
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : "Something went wrong.");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!name.trim() && user) {
|
||||
const fallbackName =
|
||||
user.fullName ?? user.firstName ?? user.username ?? "";
|
||||
if (fallbackName) {
|
||||
setName(fallbackName);
|
||||
}
|
||||
}
|
||||
}, [user, name]);
|
||||
|
||||
useEffect(() => {
|
||||
loadProfile();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isSignedIn]);
|
||||
|
||||
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
if (!isSignedIn) return;
|
||||
if (requiredMissing) {
|
||||
setError("Please complete the required fields.");
|
||||
return;
|
||||
}
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const token = await getToken();
|
||||
const normalizedName = name.trim();
|
||||
const payload = {
|
||||
name: normalizedName,
|
||||
preferred_name: normalizedName,
|
||||
timezone: timezone.trim(),
|
||||
};
|
||||
const response = await fetch(`${apiBase}/api/v1/users/me`, {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: token ? `Bearer ${token}` : "",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error("Unable to update profile.");
|
||||
}
|
||||
router.replace("/boards");
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : "Something went wrong.");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardShell>
|
||||
<SignedOut>
|
||||
<div className="lg:col-span-2 flex min-h-[70vh] items-center justify-center">
|
||||
<div className="w-full max-w-2xl rounded-xl border border-slate-200 bg-white shadow-sm">
|
||||
<div className="border-b border-slate-100 px-6 py-5">
|
||||
<h1 className="text-2xl font-semibold tracking-tight text-slate-900">
|
||||
Mission Control profile
|
||||
</h1>
|
||||
<p className="mt-1 text-sm text-slate-600">
|
||||
Sign in to configure your profile and timezone.
|
||||
</p>
|
||||
</div>
|
||||
<div className="px-6 py-6">
|
||||
<SignInButton
|
||||
mode="modal"
|
||||
forceRedirectUrl="/onboarding"
|
||||
signUpForceRedirectUrl="/onboarding"
|
||||
>
|
||||
<Button size="lg">Sign in</Button>
|
||||
</SignInButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</SignedOut>
|
||||
<SignedIn>
|
||||
<div className="lg:col-span-2 flex min-h-[70vh] items-center justify-center">
|
||||
<section className="w-full max-w-2xl rounded-xl border border-slate-200 bg-white shadow-sm">
|
||||
<div className="border-b border-slate-100 px-6 py-5">
|
||||
<h1 className="text-2xl font-semibold tracking-tight text-slate-900">
|
||||
Mission Control profile
|
||||
</h1>
|
||||
<p className="mt-1 text-sm text-slate-600">
|
||||
Configure your mission control settings and preferences.
|
||||
</p>
|
||||
</div>
|
||||
<div className="px-6 py-6">
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-700 flex items-center gap-2">
|
||||
<User className="h-4 w-4 text-slate-500" />
|
||||
Name
|
||||
<span className="text-red-500">*</span>
|
||||
</label>
|
||||
<Input
|
||||
value={name}
|
||||
onChange={(event) => setName(event.target.value)}
|
||||
placeholder="Enter your name"
|
||||
disabled={isLoading}
|
||||
className="border-slate-300 text-slate-900 focus-visible:ring-blue-500"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-slate-700 flex items-center gap-2">
|
||||
<Globe className="h-4 w-4 text-slate-500" />
|
||||
Timezone
|
||||
<span className="text-red-500">*</span>
|
||||
</label>
|
||||
<SearchableSelect
|
||||
ariaLabel="Select timezone"
|
||||
value={timezone}
|
||||
onValueChange={setTimezone}
|
||||
options={timezoneOptions}
|
||||
placeholder="Select timezone"
|
||||
searchPlaceholder="Search timezones..."
|
||||
emptyMessage="No matching timezones."
|
||||
triggerClassName="w-full h-11 rounded-xl border border-slate-300 bg-white px-3 py-2 text-sm font-medium text-slate-900 shadow-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-200"
|
||||
contentClassName="rounded-xl border border-slate-200 shadow-lg"
|
||||
itemClassName="px-4 py-3 text-sm text-slate-700 data-[selected=true]:bg-slate-50 data-[selected=true]:text-slate-900"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-blue-200 bg-blue-50 p-4 text-sm text-blue-800 flex items-start gap-3">
|
||||
<Info className="mt-0.5 h-4 w-4 text-blue-600" />
|
||||
<p>
|
||||
<strong>Note:</strong> Your timezone is used to display all
|
||||
timestamps and schedule mission-critical events accurately.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{error ? (
|
||||
<div className="rounded-lg border border-slate-200 bg-slate-50 p-3 text-xs text-slate-600">
|
||||
{error}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="flex flex-wrap gap-3 pt-2">
|
||||
<Button
|
||||
type="submit"
|
||||
className="flex-1 bg-blue-600 text-white hover:bg-blue-700 py-2.5"
|
||||
disabled={isLoading || requiredMissing}
|
||||
>
|
||||
<Save className="h-4 w-4" />
|
||||
{isLoading ? "Saving…" : "Save Profile"}
|
||||
</Button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setName("");
|
||||
setTimezone("");
|
||||
setError(null);
|
||||
}}
|
||||
className="flex-1 rounded-md border border-slate-300 px-4 py-2.5 text-sm font-medium text-slate-700 transition-colors hover:bg-slate-50"
|
||||
>
|
||||
<span className="inline-flex items-center gap-2">
|
||||
<RotateCcw className="h-4 w-4" />
|
||||
Reset
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</SignedIn>
|
||||
</DashboardShell>
|
||||
);
|
||||
}
|
||||
@@ -14,8 +14,8 @@ export function LandingHero() {
|
||||
<SignedOut>
|
||||
<SignInButton
|
||||
mode="modal"
|
||||
forceRedirectUrl="/boards"
|
||||
signUpForceRedirectUrl="/boards"
|
||||
forceRedirectUrl="/onboarding"
|
||||
signUpForceRedirectUrl="/onboarding"
|
||||
>
|
||||
<Button size="lg" className="w-full sm:w-auto">
|
||||
Sign in to open mission control
|
||||
|
||||
91
frontend/src/components/organisms/UserMenu.tsx
Normal file
91
frontend/src/components/organisms/UserMenu.tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import { SignOutButton, useUser } from "@clerk/nextjs";
|
||||
import { LogOut } from "lucide-react";
|
||||
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export function UserMenu({ className }: { className?: string }) {
|
||||
const { user } = useUser();
|
||||
if (!user) return null;
|
||||
|
||||
const avatarUrl = user.imageUrl ?? null;
|
||||
const avatarLabelSource = user.firstName ?? user.username ?? user.id ?? "U";
|
||||
const avatarLabel = avatarLabelSource.slice(0, 1).toUpperCase();
|
||||
const displayName =
|
||||
user.fullName ?? user.firstName ?? user.username ?? "Account";
|
||||
const displayEmail = user.primaryEmailAddress?.emailAddress ?? "";
|
||||
|
||||
return (
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
"flex h-12 items-center gap-2 rounded-lg px-2.5 text-gray-900 transition hover:bg-gray-100",
|
||||
className,
|
||||
)}
|
||||
aria-label="Open user menu"
|
||||
>
|
||||
<span className="flex h-10 w-10 items-center justify-center overflow-hidden rounded-full bg-gray-100 text-sm font-semibold text-gray-900">
|
||||
{avatarUrl ? (
|
||||
<Image
|
||||
src={avatarUrl}
|
||||
alt="User avatar"
|
||||
width={40}
|
||||
height={40}
|
||||
className="h-10 w-10 object-cover"
|
||||
/>
|
||||
) : (
|
||||
avatarLabel
|
||||
)}
|
||||
</span>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
align="end"
|
||||
sideOffset={8}
|
||||
className="w-64 rounded-2xl border border-[color:var(--border)] bg-[color:var(--surface)] p-0 shadow-lg"
|
||||
>
|
||||
<div className="border-b border-[color:var(--border)] px-4 py-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="flex h-10 w-10 items-center justify-center overflow-hidden rounded-full bg-[color:var(--surface-muted)] text-sm font-semibold text-strong">
|
||||
{avatarUrl ? (
|
||||
<Image
|
||||
src={avatarUrl}
|
||||
alt="User avatar"
|
||||
width={40}
|
||||
height={40}
|
||||
className="h-10 w-10 object-cover"
|
||||
/>
|
||||
) : (
|
||||
avatarLabel
|
||||
)}
|
||||
</span>
|
||||
<div className="min-w-0">
|
||||
<div className="truncate text-sm font-semibold text-strong">
|
||||
{displayName}
|
||||
</div>
|
||||
{displayEmail ? (
|
||||
<div className="truncate text-xs text-muted">{displayEmail}</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-2">
|
||||
<SignOutButton>
|
||||
<button
|
||||
type="button"
|
||||
className="flex w-full items-center gap-2 rounded-xl px-3 py-2 text-sm font-semibold text-strong transition hover:bg-[color:var(--surface-strong)]"
|
||||
>
|
||||
<LogOut className="h-4 w-4 text-[color:var(--text-quiet)]" />
|
||||
Sign out
|
||||
</button>
|
||||
</SignOutButton>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
import { SignedIn, UserButton } from "@clerk/nextjs";
|
||||
import { SignedIn } from "@clerk/nextjs";
|
||||
|
||||
import { BrandMark } from "@/components/atoms/BrandMark";
|
||||
import { UserMenu } from "@/components/organisms/UserMenu";
|
||||
|
||||
export function DashboardShell({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
@@ -14,12 +15,10 @@ export function DashboardShell({ children }: { children: ReactNode }) {
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div className="relative flex min-h-screen w-full flex-col">
|
||||
<header className="flex flex-wrap items-center justify-between gap-4 border-b border-[color:var(--border)] bg-[color:rgba(244,246,250,0.8)] px-6 py-5 backdrop-blur">
|
||||
<header className="flex flex-wrap items-center justify-between gap-4 border-b border-[color:var(--border)] bg-[color:rgba(244,246,250,0.8)] px-6 py-3 backdrop-blur">
|
||||
<BrandMark />
|
||||
<SignedIn>
|
||||
<div className="rounded-full border border-[color:var(--border)] bg-[color:var(--surface)] px-2 py-1 shadow-sm">
|
||||
<UserButton />
|
||||
</div>
|
||||
<UserMenu />
|
||||
</SignedIn>
|
||||
</header>
|
||||
<div className="flex-1 px-6 py-6">
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
import { SignedIn, UserButton } from "@clerk/nextjs";
|
||||
import { SignedIn } from "@clerk/nextjs";
|
||||
|
||||
import { BrandMark } from "@/components/atoms/BrandMark";
|
||||
import { UserMenu } from "@/components/organisms/UserMenu";
|
||||
|
||||
export function LandingShell({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
@@ -27,9 +28,7 @@ export function LandingShell({ children }: { children: ReactNode }) {
|
||||
<header className="flex items-center justify-between gap-4">
|
||||
<BrandMark />
|
||||
<SignedIn>
|
||||
<div className="rounded-full border border-[color:var(--border)] bg-[color:var(--surface)] px-2 py-1 shadow-sm">
|
||||
<UserButton />
|
||||
</div>
|
||||
<UserMenu />
|
||||
</SignedIn>
|
||||
</header>
|
||||
<main>{children}</main>
|
||||
|
||||
133
frontend/src/components/ui/command.tsx
Normal file
133
frontend/src/components/ui/command.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import { Command as CommandPrimitive } from "cmdk";
|
||||
import { Search } from "lucide-react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Command = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CommandPrimitive
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
Command.displayName = CommandPrimitive.displayName;
|
||||
|
||||
const CommandInput = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.Input>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div className="border-b border-slate-200 p-2" cmdk-input-wrapper="">
|
||||
<div className="relative">
|
||||
<Search className="absolute left-2 top-2.5 h-4 w-4 text-slate-400" />
|
||||
<CommandPrimitive.Input
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"w-full rounded-md border border-slate-300 bg-white py-2 pl-8 pr-3 text-sm text-slate-900 placeholder:text-slate-500 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-slate-400 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
));
|
||||
CommandInput.displayName = CommandPrimitive.Input.displayName;
|
||||
|
||||
const CommandList = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.List>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CommandPrimitive.List
|
||||
ref={ref}
|
||||
className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CommandList.displayName = CommandPrimitive.List.displayName;
|
||||
|
||||
const CommandEmpty = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.Empty>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
|
||||
>((props, ref) => (
|
||||
<CommandPrimitive.Empty
|
||||
ref={ref}
|
||||
className="py-6 text-center text-sm"
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
|
||||
|
||||
const CommandGroup = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.Group>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CommandPrimitive.Group
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:text-muted-foreground",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CommandGroup.displayName = CommandPrimitive.Group.displayName;
|
||||
|
||||
const CommandSeparator = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.Separator>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CommandPrimitive.Separator
|
||||
ref={ref}
|
||||
className={cn("-mx-1 h-px bg-muted", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
|
||||
|
||||
const CommandItem = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CommandPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 data-[disabled=true]:cursor-not-allowed",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CommandItem.displayName = CommandPrimitive.Item.displayName;
|
||||
|
||||
const CommandShortcut = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLSpanElement>) => (
|
||||
<span
|
||||
className={cn(
|
||||
"ml-auto text-xs tracking-widest text-muted-foreground",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
CommandShortcut.displayName = "CommandShortcut";
|
||||
|
||||
export {
|
||||
Command,
|
||||
CommandInput,
|
||||
CommandList,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandItem,
|
||||
CommandSeparator,
|
||||
CommandShortcut,
|
||||
};
|
||||
215
frontend/src/components/ui/dropdown-select.tsx
Normal file
215
frontend/src/components/ui/dropdown-select.tsx
Normal file
@@ -0,0 +1,215 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import { Check, ChevronDown } from "lucide-react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
} from "@/components/ui/command";
|
||||
|
||||
export type DropdownSelectOption = {
|
||||
value: string;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
icon?: React.ElementType<{ className?: string }>;
|
||||
iconClassName?: string;
|
||||
};
|
||||
|
||||
type DropdownSelectProps = {
|
||||
value?: string;
|
||||
onValueChange: (value: string) => void;
|
||||
options: DropdownSelectOption[];
|
||||
placeholder?: string;
|
||||
ariaLabel: string;
|
||||
disabled?: boolean;
|
||||
triggerClassName?: string;
|
||||
contentClassName?: string;
|
||||
itemClassName?: string;
|
||||
searchEnabled?: boolean;
|
||||
searchPlaceholder?: string;
|
||||
emptyMessage?: string;
|
||||
};
|
||||
|
||||
const resolvePlaceholder = (ariaLabel: string, placeholder?: string) => {
|
||||
if (placeholder) {
|
||||
return placeholder;
|
||||
}
|
||||
const trimmed = ariaLabel.trim();
|
||||
if (!trimmed) {
|
||||
return "Select an option";
|
||||
}
|
||||
return trimmed.endsWith("...") ? trimmed : `${trimmed}...`;
|
||||
};
|
||||
|
||||
const resolveSearchPlaceholder = (
|
||||
ariaLabel: string,
|
||||
searchPlaceholder?: string,
|
||||
) => {
|
||||
if (searchPlaceholder) {
|
||||
return searchPlaceholder;
|
||||
}
|
||||
const cleaned = ariaLabel.replace(/^select\\s+/i, "").trim();
|
||||
if (!cleaned) {
|
||||
return "Search...";
|
||||
}
|
||||
const value = `Search ${cleaned}`;
|
||||
return value.endsWith("...") ? value : `${value}...`;
|
||||
};
|
||||
|
||||
export default function DropdownSelect({
|
||||
value,
|
||||
onValueChange,
|
||||
options,
|
||||
placeholder,
|
||||
ariaLabel,
|
||||
disabled = false,
|
||||
triggerClassName,
|
||||
contentClassName,
|
||||
itemClassName,
|
||||
searchEnabled = true,
|
||||
searchPlaceholder,
|
||||
emptyMessage,
|
||||
}: DropdownSelectProps) {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [searchValue, setSearchValue] = React.useState("");
|
||||
const listRef = React.useRef<HTMLDivElement | null>(null);
|
||||
const selectedOption = options.find((option) => option.value === value);
|
||||
const resolvedPlaceholder = resolvePlaceholder(ariaLabel, placeholder);
|
||||
const triggerLabel = selectedOption?.label ?? value ?? "";
|
||||
const SelectedIcon = selectedOption?.icon;
|
||||
const selectedIconClassName = selectedOption?.iconClassName;
|
||||
const showPlaceholder = !triggerLabel;
|
||||
const resolvedSearchPlaceholder = searchEnabled
|
||||
? resolveSearchPlaceholder(ariaLabel, searchPlaceholder)
|
||||
: "";
|
||||
|
||||
const handleOpenChange = (nextOpen: boolean) => {
|
||||
setOpen(nextOpen);
|
||||
if (!nextOpen) {
|
||||
setSearchValue("");
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelect = (nextValue: string) => {
|
||||
if (nextValue !== value) {
|
||||
onValueChange(nextValue);
|
||||
}
|
||||
handleOpenChange(false);
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!open) {
|
||||
return;
|
||||
}
|
||||
if (listRef.current) {
|
||||
listRef.current.scrollTop = 0;
|
||||
}
|
||||
}, [open, searchValue]);
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={handleOpenChange}>
|
||||
<PopoverTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
aria-label={ariaLabel}
|
||||
aria-expanded={open}
|
||||
aria-haspopup="listbox"
|
||||
disabled={disabled}
|
||||
className={cn(
|
||||
"inline-flex h-10 w-auto cursor-pointer items-center justify-between gap-2 rounded-md border border-slate-300 bg-white px-3 py-2 text-sm font-medium text-slate-900 shadow-sm transition-colors hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50",
|
||||
open && "bg-slate-50",
|
||||
triggerClassName,
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
"flex min-w-0 items-center gap-2 truncate",
|
||||
showPlaceholder && "text-slate-500",
|
||||
)}
|
||||
>
|
||||
{SelectedIcon ? (
|
||||
<SelectedIcon
|
||||
className={cn("h-4 w-4 text-slate-600", selectedIconClassName)}
|
||||
/>
|
||||
) : null}
|
||||
<span className="truncate">
|
||||
{showPlaceholder ? resolvedPlaceholder : triggerLabel}
|
||||
</span>
|
||||
</span>
|
||||
<ChevronDown
|
||||
className={cn(
|
||||
"h-4 w-4 shrink-0 text-slate-400 transition-transform",
|
||||
open && "rotate-180",
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
align="start"
|
||||
sideOffset={6}
|
||||
className={cn(
|
||||
"w-[var(--radix-popover-trigger-width)] min-w-[12rem] overflow-hidden rounded-md border border-slate-200 bg-white p-0 text-slate-900 shadow-lg",
|
||||
contentClassName,
|
||||
)}
|
||||
>
|
||||
<Command label={ariaLabel} className="w-full">
|
||||
{searchEnabled ? (
|
||||
<CommandInput
|
||||
value={searchValue}
|
||||
onValueChange={setSearchValue}
|
||||
placeholder={resolvedSearchPlaceholder}
|
||||
autoFocus
|
||||
className="text-sm"
|
||||
/>
|
||||
) : null}
|
||||
<CommandList ref={listRef} className="max-h-64 p-1">
|
||||
<CommandEmpty className="px-3 py-6 text-center text-sm text-slate-500">
|
||||
{emptyMessage ?? "No results found."}
|
||||
</CommandEmpty>
|
||||
{options.map((option) => {
|
||||
const isSelected = value === option.value;
|
||||
const OptionIcon = option.icon;
|
||||
return (
|
||||
<CommandItem
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
keywords={[option.label, option.value]}
|
||||
disabled={option.disabled}
|
||||
onSelect={handleSelect}
|
||||
className={cn(
|
||||
"flex items-center justify-between gap-2 rounded-lg px-4 py-3 text-sm text-gray-700 transition-colors data-[selected=true]:bg-gray-50 data-[selected=true]:text-gray-900",
|
||||
isSelected && "font-semibold",
|
||||
!isSelected && "hover:bg-gray-50",
|
||||
itemClassName,
|
||||
)}
|
||||
>
|
||||
<span className="flex min-w-0 items-center gap-2">
|
||||
{OptionIcon ? (
|
||||
<OptionIcon
|
||||
className={cn(
|
||||
"h-4 w-4",
|
||||
isSelected ? "text-gray-700" : "text-gray-500",
|
||||
option.iconClassName,
|
||||
)}
|
||||
/>
|
||||
) : null}
|
||||
<span className="truncate font-medium">{option.label}</span>
|
||||
</span>
|
||||
{isSelected ? (
|
||||
<Check className="h-4 w-4 text-gray-400" />
|
||||
) : null}
|
||||
</CommandItem>
|
||||
);
|
||||
})}
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
31
frontend/src/components/ui/popover.tsx
Normal file
31
frontend/src/components/ui/popover.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Popover = PopoverPrimitive.Root;
|
||||
const PopoverTrigger = PopoverPrimitive.Trigger;
|
||||
const PopoverAnchor = PopoverPrimitive.Anchor;
|
||||
|
||||
const PopoverContent = React.forwardRef<
|
||||
React.ElementRef<typeof PopoverPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
||||
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
|
||||
<PopoverPrimitive.Portal>
|
||||
<PopoverPrimitive.Content
|
||||
ref={ref}
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 w-72 rounded-md border border-popover bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</PopoverPrimitive.Portal>
|
||||
));
|
||||
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
||||
|
||||
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
|
||||
62
frontend/src/components/ui/searchable-select.tsx
Normal file
62
frontend/src/components/ui/searchable-select.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
"use client";
|
||||
|
||||
import DropdownSelect, {
|
||||
type DropdownSelectOption,
|
||||
} from "@/components/ui/dropdown-select";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export type SearchableSelectOption = DropdownSelectOption;
|
||||
|
||||
type SearchableSelectProps = {
|
||||
value?: string;
|
||||
onValueChange: (value: string) => void;
|
||||
options: SearchableSelectOption[];
|
||||
placeholder?: string;
|
||||
ariaLabel: string;
|
||||
disabled?: boolean;
|
||||
triggerClassName?: string;
|
||||
contentClassName?: string;
|
||||
itemClassName?: string;
|
||||
searchEnabled?: boolean;
|
||||
searchPlaceholder?: string;
|
||||
emptyMessage?: string;
|
||||
};
|
||||
|
||||
const baseTriggerClassName =
|
||||
"w-auto h-auto rounded-xl border-2 border-gray-200 bg-white px-4 py-3 text-left text-sm font-semibold text-gray-700 shadow-sm transition-all duration-200 hover:border-gray-300 focus:border-gray-900 focus:ring-4 focus:ring-gray-100";
|
||||
const baseContentClassName =
|
||||
"rounded-xl border-2 border-gray-200 bg-white shadow-xl";
|
||||
const baseItemClassName =
|
||||
"px-4 py-3 text-sm text-gray-700 transition-colors data-[selected=true]:bg-gray-50 data-[selected=true]:text-gray-900 data-[selected=true]:font-semibold hover:bg-gray-50";
|
||||
|
||||
export default function SearchableSelect({
|
||||
value,
|
||||
onValueChange,
|
||||
options,
|
||||
placeholder,
|
||||
ariaLabel,
|
||||
disabled = false,
|
||||
triggerClassName,
|
||||
contentClassName,
|
||||
itemClassName,
|
||||
searchEnabled,
|
||||
searchPlaceholder,
|
||||
emptyMessage,
|
||||
}: SearchableSelectProps) {
|
||||
return (
|
||||
<DropdownSelect
|
||||
value={value}
|
||||
onValueChange={onValueChange}
|
||||
options={options}
|
||||
placeholder={placeholder}
|
||||
ariaLabel={ariaLabel}
|
||||
disabled={disabled}
|
||||
triggerClassName={cn(baseTriggerClassName, triggerClassName)}
|
||||
contentClassName={cn(baseContentClassName, contentClassName)}
|
||||
itemClassName={cn(baseItemClassName, itemClassName)}
|
||||
searchEnabled={searchEnabled}
|
||||
searchPlaceholder={searchPlaceholder}
|
||||
emptyMessage={emptyMessage}
|
||||
/>
|
||||
);
|
||||
}
|
||||
11
frontend/src/lib/api-base.ts
Normal file
11
frontend/src/lib/api-base.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export function getApiBaseUrl(): string {
|
||||
const raw = process.env.NEXT_PUBLIC_API_URL;
|
||||
if (!raw) {
|
||||
throw new Error("NEXT_PUBLIC_API_URL is not set.");
|
||||
}
|
||||
const normalized = raw.replace(/\/+$/, "");
|
||||
if (!normalized) {
|
||||
throw new Error("NEXT_PUBLIC_API_URL is invalid.");
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
Reference in New Issue
Block a user