diff --git a/openapi-codegen.config.ts b/openapi-codegen.config.ts index 948b1428..e1297e32 100644 --- a/openapi-codegen.config.ts +++ b/openapi-codegen.config.ts @@ -27,6 +27,7 @@ type EnvironmentName = (typeof ENVIRONMENT_NAMES)[number]; type Environment = { apiBaseUrl: string; userServiceUrl: string; + jobServiceUrl: string; entityServiceUrl: string; }; @@ -34,26 +35,31 @@ const ENVIRONMENTS: { [Property in EnvironmentName]: Environment } = { local: { apiBaseUrl: "http://localhost:8080", userServiceUrl: "http://localhost:4010", + jobServiceUrl: "http://localhost:4020", entityServiceUrl: "http://localhost:4050" }, dev: { apiBaseUrl: "https://api-dev.terramatch.org", userServiceUrl: "https://api-dev.terramatch.org", + jobServiceUrl: "https://api-dev.terramatch.org", entityServiceUrl: "https://api-dev.terramatch.org" }, test: { apiBaseUrl: "https://api-test.terramatch.org", userServiceUrl: "https://api-test.terramatch.org", + jobServiceUrl: "https://api-test.terramatch.org", entityServiceUrl: "https://api-test.terramatch.org" }, staging: { apiBaseUrl: "https://api-staging.terramatch.org", userServiceUrl: "https://api-staging.terramatch.org", + jobServiceUrl: "https://api-staging.terramatch.org", entityServiceUrl: "https://api-staging.terramatch.org" }, prod: { apiBaseUrl: "https://api.terramatch.org", userServiceUrl: "https://api.terramatch.org", + jobServiceUrl: "https://api.terramatch.org", entityServiceUrl: "https://api.terramatch.org" } }; @@ -66,6 +72,7 @@ if (!ENVIRONMENT_NAMES.includes(declaredEnv as EnvironmentName)) { const DEFAULTS = ENVIRONMENTS[declaredEnv]; const apiBaseUrl = process.env.NEXT_PUBLIC_API_BASE_URL ?? DEFAULTS.apiBaseUrl; const userServiceUrl = process.env.NEXT_PUBLIC_USER_SERVICE_URL ?? DEFAULTS.userServiceUrl; +const jobServiceUrl = process.env.NEXT_PUBLIC_JOB_SERVICE_URL ?? DEFAULTS.jobServiceUrl; const entityServiceUrl = process.env.NEXT_PUBLIC_ENTITY_SERVICE_URL ?? DEFAULTS.entityServiceUrl; // The services defined in the v3 Node BE codebase. Although the URL path for APIs in the v3 space @@ -74,6 +81,7 @@ const entityServiceUrl = process.env.NEXT_PUBLIC_ENTITY_SERVICE_URL ?? DEFAULTS. // the associated BE code is for a given FE API integration. const SERVICES = { "user-service": userServiceUrl, + "job-service": jobServiceUrl, "entity-service": entityServiceUrl }; diff --git a/package.json b/package.json index d184e19f..22e502fb 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,10 @@ "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", "generate:api": "openapi-codegen gen api", + "generate:jobService": "openapi-codegen gen jobService", "generate:userService": "openapi-codegen gen userService", "generate:entityService": "openapi-codegen gen entityService", - "generate:services": "yarn generate:userService && yarn generate:entityService", + "generate:services": "yarn generate:userService && yarn generate:entityService && yarn generate:jobService", "tx:push": "eval $(grep '^TRANSIFEX_TOKEN' .env) && eval $(grep '^TRANSIFEX_SECRET' .env) && txjs-cli push --key-generator=hash src/ --token=$TRANSIFEX_TOKEN --secret=$TRANSIFEX_SECRET", "tx:pull": "eval $(grep '^TRANSIFEX_TOKEN' .env) && eval $(grep '^TRANSIFEX_SECRET' .env) && txjs-cli pull --token=$TRANSIFEX_TOKEN --secret=$TRANSIFEX_SECRET" }, diff --git a/src/generated/v3/jobService/jobServiceComponents.ts b/src/generated/v3/jobService/jobServiceComponents.ts new file mode 100644 index 00000000..bdece4f3 --- /dev/null +++ b/src/generated/v3/jobService/jobServiceComponents.ts @@ -0,0 +1,203 @@ +/** + * Generated by @openapi-codegen + * + * @version 1.0 + */ +import type * as Fetcher from "./jobServiceFetcher"; +import { jobServiceFetch } from "./jobServiceFetcher"; +import type * as Schemas from "./jobServiceSchemas"; + +export type ListDelayedJobsError = Fetcher.ErrorWrapper<{ + status: 401; + payload: { + /** + * @example 401 + */ + statusCode: number; + /** + * @example Unauthorized + */ + message: string; + /** + * @example Unauthorized + */ + error?: string; + }; +}>; + +export type ListDelayedJobsResponse = { + data?: { + /** + * @example delayedJobs + */ + type?: string; + /** + * @format uuid + */ + id?: string; + attributes?: Schemas.DelayedJobDto; + }; +}; + +/** + * Retrieve a list of all delayed jobs. + */ +export const listDelayedJobs = (signal?: AbortSignal) => + jobServiceFetch({ + url: "/jobs/v3/delayedJobs", + method: "get", + signal + }); + +export type DelayedJobsFindPathParams = { + uuid: string; +}; + +export type DelayedJobsFindError = Fetcher.ErrorWrapper< + | { + status: 401; + payload: { + /** + * @example 401 + */ + statusCode: number; + /** + * @example Unauthorized + */ + message: string; + /** + * @example Unauthorized + */ + error?: string; + }; + } + | { + status: 404; + payload: { + /** + * @example 404 + */ + statusCode: number; + /** + * @example Not Found + */ + message: string; + /** + * @example Not Found + */ + error?: string; + }; + } +>; + +export type DelayedJobsFindResponse = { + data?: { + /** + * @example delayedJobs + */ + type?: string; + /** + * @format uuid + */ + id?: string; + attributes?: Schemas.DelayedJobDto; + }; +}; + +export type DelayedJobsFindVariables = { + pathParams: DelayedJobsFindPathParams; +}; + +/** + * Get the current status and potentially payload or error from a delayed job. + */ +export const delayedJobsFind = (variables: DelayedJobsFindVariables, signal?: AbortSignal) => + jobServiceFetch({ + url: "/jobs/v3/delayedJobs/{uuid}", + method: "get", + ...variables, + signal + }); + +export type BulkUpdateJobsError = Fetcher.ErrorWrapper< + | { + status: 400; + payload: { + /** + * @example 400 + */ + statusCode: number; + /** + * @example Bad Request + */ + message: string; + /** + * @example Bad Request + */ + error?: string; + }; + } + | { + status: 401; + payload: { + /** + * @example 401 + */ + statusCode: number; + /** + * @example Unauthorized + */ + message: string; + /** + * @example Unauthorized + */ + error?: string; + }; + } + | { + status: 404; + payload: { + /** + * @example 404 + */ + statusCode: number; + /** + * @example Not Found + */ + message: string; + /** + * @example Not Found + */ + error?: string; + }; + } +>; + +export type BulkUpdateJobsResponse = { + data?: { + /** + * @example delayedJobs + */ + type?: string; + /** + * @format uuid + */ + id?: string; + attributes?: Schemas.DelayedJobDto; + }; +}; + +export type BulkUpdateJobsVariables = { + body: Schemas.DelayedJobBulkUpdateBodyDto; +}; + +/** + * Accepts a JSON:API-compliant payload to bulk update jobs, allowing each job's isAcknowledged attribute to be set to true or false. + */ +export const bulkUpdateJobs = (variables: BulkUpdateJobsVariables, signal?: AbortSignal) => + jobServiceFetch({ + url: "/jobs/v3/delayedJobs/bulk-update", + method: "patch", + ...variables, + signal + }); diff --git a/src/generated/v3/jobService/jobServiceFetcher.ts b/src/generated/v3/jobService/jobServiceFetcher.ts new file mode 100644 index 00000000..97ea202d --- /dev/null +++ b/src/generated/v3/jobService/jobServiceFetcher.ts @@ -0,0 +1,6 @@ +// This type is imported in the auto generated `jobServiceComponents` file, so it needs to be +// exported from this file. +export type { ErrorWrapper } from "../utils"; + +// The serviceFetch method is the shared fetch method for all service fetchers. +export { serviceFetch as jobServiceFetch } from "../utils"; diff --git a/src/generated/v3/jobService/jobServicePredicates.ts b/src/generated/v3/jobService/jobServicePredicates.ts new file mode 100644 index 00000000..fdac678c --- /dev/null +++ b/src/generated/v3/jobService/jobServicePredicates.ts @@ -0,0 +1,26 @@ +import { isFetching, fetchFailed } from "../utils"; +import { ApiDataStore } from "@/store/apiSlice"; +import { DelayedJobsFindPathParams, DelayedJobsFindVariables } from "./jobServiceComponents"; + +export const listDelayedJobsIsFetching = (store: ApiDataStore) => + isFetching<{}, {}>({ store, url: "/jobs/v3/delayedJobs", method: "get" }); + +export const listDelayedJobsFetchFailed = (store: ApiDataStore) => + fetchFailed<{}, {}>({ store, url: "/jobs/v3/delayedJobs", method: "get" }); + +export const delayedJobsFindIsFetching = (variables: DelayedJobsFindVariables) => (store: ApiDataStore) => + isFetching<{}, DelayedJobsFindPathParams>({ store, url: "/jobs/v3/delayedJobs/{uuid}", method: "get", ...variables }); + +export const delayedJobsFindFetchFailed = (variables: DelayedJobsFindVariables) => (store: ApiDataStore) => + fetchFailed<{}, DelayedJobsFindPathParams>({ + store, + url: "/jobs/v3/delayedJobs/{uuid}", + method: "get", + ...variables + }); + +export const bulkUpdateJobsIsFetching = (store: ApiDataStore) => + isFetching<{}, {}>({ store, url: "/jobs/v3/delayedJobs/bulk-update", method: "patch" }); + +export const bulkUpdateJobsFetchFailed = (store: ApiDataStore) => + fetchFailed<{}, {}>({ store, url: "/jobs/v3/delayedJobs/bulk-update", method: "patch" }); diff --git a/src/generated/v3/jobService/jobServiceSchemas.ts b/src/generated/v3/jobService/jobServiceSchemas.ts new file mode 100644 index 00000000..23a8612a --- /dev/null +++ b/src/generated/v3/jobService/jobServiceSchemas.ts @@ -0,0 +1,71 @@ +/** + * Generated by @openapi-codegen + * + * @version 1.0 + */ +export type DelayedJobDto = { + /** + * The current status of the job. If the status is not pending, the payload and statusCode will be provided. + */ + status: "pending" | "failed" | "succeeded"; + /** + * If the job is out of pending state, this is the HTTP status code for the completed process + */ + statusCode: number | null; + /** + * If the job is out of pending state, this is the JSON payload for the completed process + */ + payload: Record | null; + /** + * If the job is in progress, this is the total content to process + */ + totalContent: number | null; + /** + * If the job is in progress, this is the total content processed + */ + processedContent: number | null; + /** + * If the job is in progress, this is the progress message + */ + progressMessage: string | null; + /** + * Indicates whether the jobs have been acknowledged (cleared) + */ + isAcknowledged: boolean | null; +}; + +export type DelayedJobAttributes = { + /** + * Value to set for isAcknowledged + * + * @example true + */ + isAcknowledged: boolean; +}; + +export type DelayedJobData = { + /** + * Type of the resource + * + * @example delayedJobs + */ + type: "delayedJobs"; + /** + * UUID of the job + * + * @format uuid + * @example uuid-1 + */ + uuid: string; + /** + * Attributes to update for the job + */ + attributes: DelayedJobAttributes; +}; + +export type DelayedJobBulkUpdateBodyDto = { + /** + * List of jobs to update isAcknowledged + */ + data: DelayedJobData[]; +}; diff --git a/src/store/apiSlice.ts b/src/store/apiSlice.ts index 605d1cbf..d1fff1cc 100644 --- a/src/store/apiSlice.ts +++ b/src/store/apiSlice.ts @@ -6,6 +6,7 @@ import { Store } from "redux"; import { setAccessToken } from "@/admin/apiProvider/utils/token"; import { EstablishmentsTreesDto } from "@/generated/v3/entityService/entityServiceSchemas"; +import { DelayedJobDto } from "@/generated/v3/jobService/jobServiceSchemas"; import { LoginDto, OrganisationDto, UserDto } from "@/generated/v3/userService/userServiceSchemas"; export type PendingErrorState = { @@ -54,9 +55,10 @@ type StoreResourceMap = Record; establishmentTrees: StoreResourceMap; logins: StoreResourceMap; organisations: StoreResourceMap;