diff --git a/server/src/controllers/jobs.controller.ts b/server/src/controllers/jobs.controller.ts index 792c6b0d..292209ba 100644 --- a/server/src/controllers/jobs.controller.ts +++ b/server/src/controllers/jobs.controller.ts @@ -8,6 +8,7 @@ import tryCatch from "../utils/tryCatch.utils"; export const startJob = tryCatch(async (req: any, res: any) => { const jobId = uuidv4(); const jobType = req.body.jobType; + const jobOnlyAnonymized = req.body.onlyAnonymized; const status = JOB_STATUS.IN_PROGRESS; let worker; @@ -17,7 +18,11 @@ export const startJob = tryCatch(async (req: any, res: any) => { }); } else if (jobType === JOB_TYPES.VERBATIMS_THEMES_EXTRACTION) { worker = new Worker("./dist/workers/verbatimsExpositionPreparation.js", { - workerData: { jobId, processAll: true }, + workerData: { + jobId, + processAll: jobOnlyAnonymized ? false : true, + type: jobOnlyAnonymized ? "onlyAnonymized" : null, + }, }); } diff --git a/server/src/validators/jobs.validators.ts b/server/src/validators/jobs.validators.ts index 0c544c31..02e8c3b0 100644 --- a/server/src/validators/jobs.validators.ts +++ b/server/src/validators/jobs.validators.ts @@ -6,4 +6,5 @@ export const startJobSchema = Joi.object({ jobType: Joi.string() .valid(...Object.values(JOB_TYPES)) .required(), + onlyAnonymized: Joi.boolean(), }); diff --git a/server/src/workers/verbatimsExpositionPreparation.ts b/server/src/workers/verbatimsExpositionPreparation.ts index a6a51f7c..e7b25a7d 100644 --- a/server/src/workers/verbatimsExpositionPreparation.ts +++ b/server/src/workers/verbatimsExpositionPreparation.ts @@ -117,17 +117,19 @@ const cancellationMonitor = async (jobId: string) => { }; (async () => { - const { jobId, processAll } = workerData; + const { jobId, processAll, type } = workerData; try { await connectToPgDb(config.psql.uri); cancellationMonitor(jobId); - const verbatimsQuery = getKbdClient().selectFrom("verbatims").selectAll(); + let verbatimsQuery = getKbdClient().selectFrom("verbatims").selectAll(); - if (!processAll) { - verbatimsQuery.where("deleted_at", "is", null).where("themes", "is", null); + if (!processAll && !type) { + verbatimsQuery = verbatimsQuery.where("deleted_at", "is", null).where("themes", "is", null); + } else if (!processAll && type === "onlyAnonymized") { + verbatimsQuery = verbatimsQuery.where("deleted_at", "is", null).where("is_anonymized", "=", true); } const verbatims = await verbatimsQuery.execute(); diff --git a/ui/src/hooks/useStartJob.js b/ui/src/hooks/useStartJob.js index e21fa23a..94731a94 100644 --- a/ui/src/hooks/useStartJob.js +++ b/ui/src/hooks/useStartJob.js @@ -9,7 +9,7 @@ const useStartJob = () => { const [userContext] = useContext(UserContext); const { mutate, data, isSuccess, isError, isLoading } = useMutation({ - mutationFn: (jobType) => startJob({ jobType, token: userContext.token }), + mutationFn: ({ jobType, onlyAnonymized }) => startJob({ jobType, onlyAnonymized, token: userContext.token }), mutationKey: "start-job", onSuccess: () => { queryClient.invalidateQueries(["jobs"]); diff --git a/ui/src/jobs/ManageJobsPage.js b/ui/src/jobs/ManageJobsPage.js index 1f13f6cf..7ef34d30 100644 --- a/ui/src/jobs/ManageJobsPage.js +++ b/ui/src/jobs/ManageJobsPage.js @@ -1,6 +1,7 @@ import { fr } from "@codegouvfr/react-dsfr"; import { Alert } from "@codegouvfr/react-dsfr/Alert"; import { Button } from "@codegouvfr/react-dsfr/Button"; +import { Checkbox } from "@codegouvfr/react-dsfr/Checkbox"; import { Select } from "@codegouvfr/react-dsfr/SelectNext"; import { Table } from "@codegouvfr/react-dsfr/Table"; import { useQueryClient } from "@tanstack/react-query"; @@ -57,6 +58,7 @@ const ManageJobsPage = () => { const [selectedJob, setSelectedJob] = useState(null); const [runningJob, setRunningJob] = useState(null); + const [onlyAlreadyAnonymizedVerbatims, setOnlyAlreadyAnonymizedVerbatims] = useState(false); const { jobs, isError, isLoading, isSuccess } = useFetchJobs(); const { mutate: startJob, startedJob } = useStartJob(); const { mutate: stopJob, stoppedJob } = useStopJob(); @@ -65,7 +67,7 @@ const ManageJobsPage = () => { const handleRunningJob = () => { if (!selectedJob) return; - startJob(selectedJob); + startJob({ jobType: selectedJob, onlyAnonymized: onlyAlreadyAnonymizedVerbatims }); }; const handleJobCancelation = () => { @@ -129,6 +131,20 @@ const ManageJobsPage = () => { options={jobsOption} onChange={(event) => setSelectedJob(event.target.value)} /> + {selectedJob === JOB_TYPES.VERBATIMS_THEMES_EXTRACTION && ( + setOnlyAlreadyAnonymizedVerbatims(!onlyAlreadyAnonymizedVerbatims), + }, + }, + ]} + /> + )} diff --git a/ui/src/queries/jobs.js b/ui/src/queries/jobs.js index f69f8806..dd1fda1f 100644 --- a/ui/src/queries/jobs.js +++ b/ui/src/queries/jobs.js @@ -16,11 +16,11 @@ export const fetchJobs = async ({ token }) => { return response; }; -export const startJob = async ({ jobType, token }) => { +export const startJob = async ({ jobType, onlyAnonymized, token }) => { const url = `/jobs/start`; const response = await apiPost(url, { - body: { jobType }, + body: { jobType, onlyAnonymized }, headers: { Authorization: `Bearer ${token}`, },