Skip to content

Commit cb1d027

Browse files
authored
Feature/implement ocr button (#2731)
* updated ocr button logic of the backend * generated fetcher for backoffice functionality * feat: generated ocr request in workflow service backoffice * updated logic of pressing on the OCR button * feat: added OCR button for OCR * feat: update values from OCR logic * feat: finalized process of ocr to creation * removed unnecessary blocks logic * feat: fixed comments over OCR logic * feat: fixed coderabit comments * feat: fixed tests * updated mime type * feat: updated naming of fetch document * feat: fixed PR comments * feat: fixed comments over ocr logic * fixed tests ovr cron logic * removed unnecessary code * removed unnecessary code * removed unnecessary css
1 parent be436dc commit cb1d027

File tree

29 files changed

+472
-158
lines changed

29 files changed

+472
-158
lines changed

apps/backoffice-v2/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
"i18next-http-backend": "^2.1.1",
9999
"leaflet": "^1.9.4",
100100
"libphonenumber-js": "^1.10.49",
101-
"lucide-react": "^0.239.0",
101+
"lucide-react": "^0.445.0",
102102
"match-sorter": "^6.3.1",
103103
"msw": "^1.0.0",
104104
"posthog-js": "^1.154.2",

apps/backoffice-v2/public/locales/en/toast.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@
8181
"pdf_certificate": {
8282
"error": "Failed to open PDF certificate."
8383
},
84+
"document_ocr": {
85+
"success": "OCR performed successfully.",
86+
"error": "Failed to perform OCR on the document."
87+
},
8488
"business_report_creation": {
8589
"success": "Merchant check created successfully.",
8690
"error": "Error occurred while creating a merchant check.",
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { ctw } from '@/common/utils/ctw/ctw';
2+
import { ComponentProps, FunctionComponent } from 'react';
3+
import { Loader2, ScanTextIcon } from 'lucide-react';
4+
5+
export interface IImageOCR extends ComponentProps<'button'> {
6+
onOcrPressed?: () => void;
7+
isOcrDisabled: boolean;
8+
isLoadingOCR?: boolean;
9+
}
10+
11+
export const ImageOCR: FunctionComponent<IImageOCR> = ({
12+
isOcrDisabled,
13+
onOcrPressed,
14+
className,
15+
isLoadingOCR,
16+
...props
17+
}) => (
18+
<button
19+
{...props}
20+
type="button"
21+
className={ctw(
22+
'btn btn-circle btn-ghost btn-sm bg-base-300/70 text-[0.688rem] focus:outline-primary disabled:bg-base-300/70',
23+
isLoadingOCR,
24+
className,
25+
)}
26+
onClick={() => onOcrPressed?.()}
27+
disabled={isOcrDisabled || isLoadingOCR}
28+
>
29+
{isLoadingOCR ? (
30+
<Loader2 className="animate-spin stroke-foreground" />
31+
) : (
32+
<ScanTextIcon className={'p-0.5'} />
33+
)}
34+
</button>
35+
);

apps/backoffice-v2/src/domains/customer/fetchers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const CustomerSchema = z.object({
2727
createBusinessReportBatch: z
2828
.object({ enabled: z.boolean().default(false), options: createBusinessReportOptions })
2929
.optional(),
30+
isDocumentOcrEnabled: z.boolean().default(false).optional(),
3031
})
3132
.nullable(),
3233
config: z
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { useMutation, useQueryClient } from '@tanstack/react-query';
2+
import { fetchWorkflowDocumentOCRResult } from '@/domains/workflows/fetchers';
3+
import { toast } from 'sonner';
4+
import { t } from 'i18next';
5+
import { workflowsQueryKeys } from '@/domains/workflows/query-keys';
6+
import { useFilterId } from '@/common/hooks/useFilterId/useFilterId';
7+
8+
export const useDocumentOcr = ({ workflowId }: { workflowId: string }) => {
9+
const filterId = useFilterId();
10+
const workflowById = workflowsQueryKeys.byId({ workflowId, filterId });
11+
const queryClient = useQueryClient();
12+
13+
return useMutation({
14+
mutationFn: ({ documentId }: { documentId: string }) => {
15+
return fetchWorkflowDocumentOCRResult({
16+
workflowRuntimeId: workflowId,
17+
documentId,
18+
});
19+
},
20+
onSuccess: (data, variables) => {
21+
void queryClient.invalidateQueries(workflowsQueryKeys._def);
22+
toast.success(t('toast:document_ocr.success'));
23+
},
24+
onError: (error, variables) => {
25+
console.error('OCR error:', error, 'for document:', variables.documentId);
26+
void queryClient.invalidateQueries(workflowsQueryKeys._def);
27+
toast.error(t('toast:document_ocr.error'));
28+
},
29+
});
30+
};

apps/backoffice-v2/src/domains/workflows/fetchers.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,21 @@ export const createWorkflowRequest = async ({
298298

299299
return handleZodError(error, workflow);
300300
};
301+
302+
export const fetchWorkflowDocumentOCRResult = async ({
303+
workflowRuntimeId,
304+
documentId,
305+
}: {
306+
workflowRuntimeId: string;
307+
documentId: string;
308+
}) => {
309+
const [workflow, error] = await apiClient({
310+
method: Method.GET,
311+
url: `${getOriginUrl(
312+
env.VITE_API_URL,
313+
)}/api/v1/internal/workflows/${workflowRuntimeId}/documents/${documentId}/run-ocr`,
314+
schema: z.any(),
315+
});
316+
317+
return handleZodError(error, workflow);
318+
};

apps/backoffice-v2/src/lib/blocks/components/CallToActionLegacy/hooks/useCallToActionLegacyLogic/useCallToActionLegacyLogic.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { CommonWorkflowEvent } from '@ballerine/common';
21
import { ComponentProps, FunctionComponent, useCallback, useEffect, useState } from 'react';
32
import { toast } from 'sonner';
43
import { useApproveTaskByIdMutation } from '../../../../../../domains/entities/hooks/mutations/useApproveTaskByIdMutation/useApproveTaskByIdMutation';

apps/backoffice-v2/src/lib/blocks/components/Details/Details.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const Details: FunctionComponent<ExtractCellProps<'details'>> = ({
1313
workflowId,
1414
documents = [],
1515
onSubmit,
16+
isSaveDisabled,
1617
props,
1718
}) => {
1819
if (!value.data?.length) {
@@ -38,6 +39,7 @@ export const Details: FunctionComponent<ExtractCellProps<'details'>> = ({
3839
documents={documents}
3940
title={value?.title}
4041
data={sortedData}
42+
isSaveDisabled={isSaveDisabled}
4143
contextUpdateMethod={contextUpdateMethod}
4244
onSubmit={onSubmit}
4345
/>

apps/backoffice-v2/src/lib/blocks/components/EditableDetails/EditableDetails.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ export const EditableDetails: FunctionComponent<IEditableDetails> = ({
103103
documents,
104104
title,
105105
workflowId,
106+
isSaveDisabled,
106107
contextUpdateMethod = 'base',
107108
onSubmit: onSubmitCallback,
108109
}) => {
@@ -427,7 +428,11 @@ export const EditableDetails: FunctionComponent<IEditableDetails> = ({
427428
</div>
428429
<div className={`flex justify-end`}>
429430
{data?.some(({ isEditable }) => isEditable) && (
430-
<Button type="submit" className={`ms-auto mt-3`}>
431+
<Button
432+
type="submit"
433+
className={`ms-auto mt-3 aria-disabled:pointer-events-none aria-disabled:opacity-50`}
434+
aria-disabled={isSaveDisabled}
435+
>
431436
Save
432437
</Button>
433438
)}

apps/backoffice-v2/src/lib/blocks/components/EditableDetails/interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface IEditableDetails {
2525
documents: IEditableDetailsDocument[];
2626
title: string;
2727
workflowId: string;
28+
isSaveDisabled?: boolean;
2829
contextUpdateMethod?: 'base' | 'director';
2930
onSubmit?: (document: AnyObject) => void;
3031
}

0 commit comments

Comments
 (0)