From 25df8901faedcffa2e0469fc1a73f35c6b2331c7 Mon Sep 17 00:00:00 2001
From: Shane <66246046+shanegrouber@users.noreply.github.com>
Date: Thu, 19 Dec 2024 11:32:23 +0200
Subject: [PATCH 1/4] feat(business-reports): add UI for filtering by merchant
type
- Update reportType to accept 'All' alongside existing options
- Modify query parameters to exclude type when 'All' is selected
- Integrate a dropdown for selecting report types in the Merchant Monitoring page
(Your dropdown is so user-friendly, it practically holds their hand through the process)
---
.../src/domains/business-reports/fetchers.ts | 4 +-
.../useBusinessReportsQuery.tsx | 2 +-
.../domains/business-reports/query-keys.ts | 2 +-
.../MerchantMonitoring.page.tsx | 37 +++++++++++++++++--
.../get-merchant-monitoring-search-schema.ts | 12 +++++-
.../useMerchantMonitoringLogic.tsx | 31 ++++++++++++++--
.../workflows-service/prisma/data-migrations | 2 +-
7 files changed, 77 insertions(+), 13 deletions(-)
diff --git a/apps/backoffice-v2/src/domains/business-reports/fetchers.ts b/apps/backoffice-v2/src/domains/business-reports/fetchers.ts
index 78d5a3f251..282083eeb7 100644
--- a/apps/backoffice-v2/src/domains/business-reports/fetchers.ts
+++ b/apps/backoffice-v2/src/domains/business-reports/fetchers.ts
@@ -88,7 +88,7 @@ export const fetchBusinessReports = async ({
reportType,
...params
}: {
- reportType: MerchantReportType;
+ reportType: MerchantReportType | 'All';
page: {
number: number;
size: number;
@@ -98,7 +98,7 @@ export const fetchBusinessReports = async ({
const queryParams = qs.stringify(
{
...params,
- type: reportType,
+ ...(reportType !== 'All' && { type: reportType }),
},
{ encode: false },
);
diff --git a/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx b/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx
index 35ccbad732..47002e099c 100644
--- a/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx
+++ b/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx
@@ -12,7 +12,7 @@ export const useBusinessReportsQuery = ({
sortBy,
sortDir,
}: {
- reportType: MerchantReportType;
+ reportType: MerchantReportType | 'All';
search: string;
page: number;
pageSize: number;
diff --git a/apps/backoffice-v2/src/domains/business-reports/query-keys.ts b/apps/backoffice-v2/src/domains/business-reports/query-keys.ts
index f7c417ee52..72d5d3389f 100644
--- a/apps/backoffice-v2/src/domains/business-reports/query-keys.ts
+++ b/apps/backoffice-v2/src/domains/business-reports/query-keys.ts
@@ -15,7 +15,7 @@ export const businessReportsQueryKey = createQueryKeys('business-reports', {
sortDir,
...params
}: {
- reportType: MerchantReportType;
+ reportType: MerchantReportType | 'All';
search: string;
page: number;
pageSize: number;
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
index 77ef7582a3..ed2d831620 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
@@ -5,15 +5,23 @@ import { useMerchantMonitoringLogic } from '@/pages/MerchantMonitoring/hooks/use
import { NoBusinessReports } from '@/pages/MerchantMonitoring/components/NoBusinessReports/NoBusinessReports';
import { MerchantMonitoringTable } from '@/pages/MerchantMonitoring/components/MerchantMonitoringTable/MerchantMonitoringTable';
import { buttonVariants } from '@/common/components/atoms/Button/Button';
-import { Plus, Table2 } from 'lucide-react';
+import { Plus, SlidersHorizontal, Table2 } from 'lucide-react';
import { Link } from 'react-router-dom';
import { Search } from '@/common/components/molecules/Search';
-import { Skeleton } from '@ballerine/ui';
+import {
+ Button,
+ DropdownMenuTrigger,
+ DropdownMenu,
+ Skeleton,
+ DropdownMenuContent,
+ DropdownMenuCheckboxItem,
+} from '@ballerine/ui';
import { TooltipProvider } from '@/common/components/atoms/Tooltip/Tooltip.Provider';
import { Tooltip } from '@/common/components/atoms/Tooltip/Tooltip';
import { TooltipTrigger } from '@/common/components/atoms/Tooltip/Tooltip.Trigger';
import { TooltipContent } from '@/common/components/atoms/Tooltip/Tooltip.Content';
import { t } from 'i18next';
+import { titleCase } from 'string-ts';
export const MerchantMonitoring: FunctionComponent = () => {
const {
@@ -31,6 +39,9 @@ export const MerchantMonitoring: FunctionComponent = () => {
locale,
createBusinessReport,
createBusinessReportBatch,
+ reportType,
+ onReportTypeChange,
+ REPORT_TYPE_TO_DISPLAY_TEXT,
} = useMerchantMonitoringLogic();
return (
@@ -90,8 +101,28 @@ export const MerchantMonitoring: FunctionComponent = () => {
-
+
+
+
+
+
+
+ {Object.entries(REPORT_TYPE_TO_DISPLAY_TEXT).map(([type, displayText]) => (
+
+ onReportTypeChange(type as keyof typeof REPORT_TYPE_TO_DISPLAY_TEXT)
+ }
+ >
+ {displayText}
+
+ ))}
+
+
{isNonEmptyArray(businessReports) &&
}
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts b/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts
index 2671b17e1c..d42eb90689 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts
@@ -2,6 +2,7 @@ import { BaseSearchSchema } from '@/common/hooks/useSearchParamsByEntity/validat
import { z } from 'zod';
import { TBusinessReport } from '@/domains/business-reports/fetchers';
import { BooleanishRecordSchema } from '@ballerine/ui';
+import { REPORT_TYPE_TO_DISPLAY_TEXT } from './hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
export const getMerchantMonitoringSearchSchema = () =>
BaseSearchSchema.extend({
@@ -14,15 +15,24 @@ export const getMerchantMonitoringSearchSchema = () =>
'business.country',
'riskScore',
'status',
+ 'reportType',
] as const satisfies ReadonlyArray<
| Extract<
keyof NonNullable
,
- 'createdAt' | 'updatedAt' | 'riskScore' | 'status'
+ 'createdAt' | 'updatedAt' | 'riskScore' | 'status' | 'reportType'
>
| 'business.website'
| 'business.companyName'
| 'business.country'
>)
.catch('createdAt'),
+ reportType: z
+ .enum([
+ ...(Object.values(REPORT_TYPE_TO_DISPLAY_TEXT) as [
+ (typeof REPORT_TYPE_TO_DISPLAY_TEXT)['All'],
+ ...Array<(typeof REPORT_TYPE_TO_DISPLAY_TEXT)[keyof typeof REPORT_TYPE_TO_DISPLAY_TEXT]>,
+ ]),
+ ])
+ .catch('All'),
selected: BooleanishRecordSchema.optional(),
});
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
index b0392aecdf..563a34f507 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
@@ -6,15 +6,28 @@ import { useLocale } from '@/common/hooks/useLocale/useLocale';
import { useCustomerQuery } from '@/domains/customer/hooks/queries/useCustomerQuery/useCustomerQuery';
import { useSearch } from '@/common/hooks/useSearch/useSearch';
+export const REPORT_TYPE_TO_DISPLAY_TEXT = {
+ All: 'All',
+ MERCHANT_REPORT_T1: 'Onboarding',
+ ONGOING_MERCHANT_REPORT_T1: 'Monitoring',
+} as const;
+
+const DISPLAY_TEXT_TO_MERCHANT_REPORT_TYPE = {
+ All: 'All',
+ MERCHANT_REPORT_T1: 'MERCHANT_REPORT_T1',
+ ONGOING_MERCHANT_REPORT_T1: 'ONGOING_MERCHANT_REPORT_T1',
+} as const;
+
export const useMerchantMonitoringLogic = () => {
const locale = useLocale();
const { data: customer } = useCustomerQuery();
const MerchantMonitoringSearchSchema = getMerchantMonitoringSearchSchema();
- const [{ page, pageSize, sortBy, sortDir, search: searchParamValue }] = useZodSearchParams(
- MerchantMonitoringSearchSchema,
- );
+ const [
+ { page, pageSize, sortBy, sortDir, search: searchParamValue, reportType },
+ setSearchParams,
+ ] = useZodSearchParams(MerchantMonitoringSearchSchema);
const { search: searchTerm, onSearch } = useSearch({
initialSearch: searchParamValue,
@@ -23,7 +36,10 @@ export const useMerchantMonitoringLogic = () => {
const search = searchTerm as string;
const { data, isLoading: isLoadingBusinessReports } = useBusinessReportsQuery({
- reportType: 'MERCHANT_REPORT_T1',
+ reportType:
+ DISPLAY_TEXT_TO_MERCHANT_REPORT_TYPE[
+ reportType as keyof typeof DISPLAY_TEXT_TO_MERCHANT_REPORT_TYPE
+ ],
search,
page,
pageSize,
@@ -31,6 +47,10 @@ export const useMerchantMonitoringLogic = () => {
sortDir,
});
+ const onReportTypeChange = (reportType: keyof typeof REPORT_TYPE_TO_DISPLAY_TEXT) => {
+ setSearchParams({ reportType: REPORT_TYPE_TO_DISPLAY_TEXT[reportType] });
+ };
+
const { onPaginate, onPrevPage, onNextPage, onLastPage, isLastPage } = usePagination({
totalPages: data?.totalPages ?? 0,
});
@@ -51,5 +71,8 @@ export const useMerchantMonitoringLogic = () => {
onPaginate,
isLastPage,
locale,
+ reportType,
+ onReportTypeChange,
+ REPORT_TYPE_TO_DISPLAY_TEXT,
};
};
diff --git a/services/workflows-service/prisma/data-migrations b/services/workflows-service/prisma/data-migrations
index f7a9926755..bfc772b0ad 160000
--- a/services/workflows-service/prisma/data-migrations
+++ b/services/workflows-service/prisma/data-migrations
@@ -1 +1 @@
-Subproject commit f7a9926755b98bc9e1c908a81b86baf9824bc7f1
+Subproject commit bfc772b0ade3ae49465629d6c85ac26aac3796ab
From 0d282c439acaa1eadafccde26be419a7b470b37f Mon Sep 17 00:00:00 2001
From: Shane <66246046+shanegrouber@users.noreply.github.com>
Date: Thu, 19 Dec 2024 14:59:06 +0200
Subject: [PATCH 2/4] feat(business-reports): add risk level filtering to
business reports
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Integrate risk level filters in the business reports fetching logic
- Update the MerchantMonitoring component to support risk level selection
- Enhance search schema to include risk level as an optional filter
(You've just added complexity like it's a family reunion—everyone’s confused!)
---
.../src/domains/business-reports/fetchers.ts | 4 +++
.../useBusinessReportsQuery.tsx | 13 ++++++-
.../domains/business-reports/query-keys.ts | 2 ++
.../MerchantMonitoring.page.tsx | 18 +++++++++-
.../get-merchant-monitoring-search-schema.ts | 15 +++++++-
.../useMerchantMonitoringLogic.tsx | 34 ++++++++++++++++++-
6 files changed, 82 insertions(+), 4 deletions(-)
diff --git a/apps/backoffice-v2/src/domains/business-reports/fetchers.ts b/apps/backoffice-v2/src/domains/business-reports/fetchers.ts
index 282083eeb7..9d82771336 100644
--- a/apps/backoffice-v2/src/domains/business-reports/fetchers.ts
+++ b/apps/backoffice-v2/src/domains/business-reports/fetchers.ts
@@ -14,6 +14,7 @@ import {
MerchantReportVersion,
} from '@/domains/business-reports/constants';
import { UnknownRecord } from 'type-fest';
+import { RISK_LEVELS } from '@/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
export const BusinessReportSchema = z
.object({
@@ -86,9 +87,11 @@ export const fetchLatestBusinessReport = async ({
export const fetchBusinessReports = async ({
reportType,
+ riskLevel,
...params
}: {
reportType: MerchantReportType | 'All';
+ riskLevel: Array<(typeof RISK_LEVELS)[number]>;
page: {
number: number;
size: number;
@@ -99,6 +102,7 @@ export const fetchBusinessReports = async ({
{
...params,
...(reportType !== 'All' && { type: reportType }),
+ riskLevel: riskLevel,
},
{ encode: false },
);
diff --git a/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx b/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx
index 47002e099c..57de088021 100644
--- a/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx
+++ b/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx
@@ -3,6 +3,7 @@ import { useQuery } from '@tanstack/react-query';
import { businessReportsQueryKey } from '@/domains/business-reports/query-keys';
import { isString } from '@/common/utils/is-string/is-string';
import { MerchantReportType } from '@/domains/business-reports/constants';
+import { RISK_LEVELS } from '@/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
export const useBusinessReportsQuery = ({
reportType,
@@ -11,6 +12,7 @@ export const useBusinessReportsQuery = ({
pageSize,
sortBy,
sortDir,
+ riskLevel,
}: {
reportType: MerchantReportType | 'All';
search: string;
@@ -18,11 +20,20 @@ export const useBusinessReportsQuery = ({
pageSize: number;
sortBy: string;
sortDir: string;
+ riskLevel: Array<(typeof RISK_LEVELS)[number]>;
}) => {
const isAuthenticated = useIsAuthenticated();
return useQuery({
- ...businessReportsQueryKey.list({ reportType, search, page, pageSize, sortBy, sortDir }),
+ ...businessReportsQueryKey.list({
+ reportType,
+ search,
+ page,
+ pageSize,
+ sortBy,
+ sortDir,
+ riskLevel,
+ }),
enabled:
isAuthenticated &&
isString(reportType) &&
diff --git a/apps/backoffice-v2/src/domains/business-reports/query-keys.ts b/apps/backoffice-v2/src/domains/business-reports/query-keys.ts
index 72d5d3389f..07f4a2c8fa 100644
--- a/apps/backoffice-v2/src/domains/business-reports/query-keys.ts
+++ b/apps/backoffice-v2/src/domains/business-reports/query-keys.ts
@@ -6,6 +6,7 @@ import {
fetchLatestBusinessReport,
} from '@/domains/business-reports/fetchers';
import { MerchantReportType } from '@/domains/business-reports/constants';
+import { RISK_LEVELS } from '@/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
export const businessReportsQueryKey = createQueryKeys('business-reports', {
list: ({
@@ -21,6 +22,7 @@ export const businessReportsQueryKey = createQueryKeys('business-reports', {
pageSize: number;
sortBy: string;
sortDir: string;
+ riskLevel: Array<(typeof RISK_LEVELS)[number]>;
}) => ({
queryKey: [{ page, pageSize, sortBy, sortDir, ...params }],
queryFn: () => {
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
index ed2d831620..dc20d50899 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
@@ -21,7 +21,7 @@ import { Tooltip } from '@/common/components/atoms/Tooltip/Tooltip';
import { TooltipTrigger } from '@/common/components/atoms/Tooltip/Tooltip.Trigger';
import { TooltipContent } from '@/common/components/atoms/Tooltip/Tooltip.Content';
import { t } from 'i18next';
-import { titleCase } from 'string-ts';
+import { MultiSelect } from '@/common/components/atoms/MultiSelect/MultiSelect';
export const MerchantMonitoring: FunctionComponent = () => {
const {
@@ -42,6 +42,9 @@ export const MerchantMonitoring: FunctionComponent = () => {
reportType,
onReportTypeChange,
REPORT_TYPE_TO_DISPLAY_TEXT,
+ RISK_LEVEL_FILTERS,
+ onRiskLevelChange,
+ onClearSelect,
} = useMerchantMonitoringLogic();
return (
@@ -123,6 +126,19 @@ export const MerchantMonitoring: FunctionComponent = () => {
))}
+
+
+ {RISK_LEVEL_FILTERS.map(({ title, options }) => (
+
+ ))}
+
{isNonEmptyArray(businessReports) &&
}
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts b/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts
index d42eb90689..39dc8dea04 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts
@@ -2,7 +2,10 @@ import { BaseSearchSchema } from '@/common/hooks/useSearchParamsByEntity/validat
import { z } from 'zod';
import { TBusinessReport } from '@/domains/business-reports/fetchers';
import { BooleanishRecordSchema } from '@ballerine/ui';
-import { REPORT_TYPE_TO_DISPLAY_TEXT } from './hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
+import {
+ REPORT_TYPE_TO_DISPLAY_TEXT,
+ RISK_LEVELS,
+} from './hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
export const getMerchantMonitoringSearchSchema = () =>
BaseSearchSchema.extend({
@@ -35,4 +38,14 @@ export const getMerchantMonitoringSearchSchema = () =>
])
.catch('All'),
selected: BooleanishRecordSchema.optional(),
+ riskLevel: z
+ .array(
+ z.enum(
+ RISK_LEVELS.map(riskLevel => riskLevel.toLowerCase()) as [
+ (typeof RISK_LEVELS)[number],
+ ...Array<(typeof RISK_LEVELS)[number]>,
+ ],
+ ),
+ )
+ .optional(),
});
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
index 563a34f507..92eeb6fd03 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
@@ -5,6 +5,7 @@ import { usePagination } from '@/common/hooks/usePagination/usePagination';
import { useLocale } from '@/common/hooks/useLocale/useLocale';
import { useCustomerQuery } from '@/domains/customer/hooks/queries/useCustomerQuery/useCustomerQuery';
import { useSearch } from '@/common/hooks/useSearch/useSearch';
+import { useCallback } from 'react';
export const REPORT_TYPE_TO_DISPLAY_TEXT = {
All: 'All',
@@ -18,6 +19,18 @@ const DISPLAY_TEXT_TO_MERCHANT_REPORT_TYPE = {
ONGOING_MERCHANT_REPORT_T1: 'ONGOING_MERCHANT_REPORT_T1',
} as const;
+export const RISK_LEVELS = ['Critical', 'High', 'Medium', 'Low'] as const;
+
+const RISK_LEVEL_FILTERS = [
+ {
+ title: 'Risk Level',
+ options: RISK_LEVELS.map(riskLevel => ({
+ label: riskLevel,
+ value: riskLevel.toLowerCase(),
+ })),
+ },
+];
+
export const useMerchantMonitoringLogic = () => {
const locale = useLocale();
const { data: customer } = useCustomerQuery();
@@ -25,7 +38,7 @@ export const useMerchantMonitoringLogic = () => {
const MerchantMonitoringSearchSchema = getMerchantMonitoringSearchSchema();
const [
- { page, pageSize, sortBy, sortDir, search: searchParamValue, reportType },
+ { page, pageSize, sortBy, sortDir, search: searchParamValue, reportType, riskLevel },
setSearchParams,
] = useZodSearchParams(MerchantMonitoringSearchSchema);
@@ -45,12 +58,28 @@ export const useMerchantMonitoringLogic = () => {
pageSize,
sortBy,
sortDir,
+ riskLevel: riskLevel ?? [],
});
const onReportTypeChange = (reportType: keyof typeof REPORT_TYPE_TO_DISPLAY_TEXT) => {
setSearchParams({ reportType: REPORT_TYPE_TO_DISPLAY_TEXT[reportType] });
};
+ const onRiskLevelChange = useCallback(
+ (selected: unknown[]) => {
+ const selectedRiskLevels = selected as Array<(typeof RISK_LEVELS)[number]>;
+
+ setSearchParams({
+ riskLevel: selectedRiskLevels,
+ });
+ },
+ [setSearchParams],
+ );
+
+ const onClearSelect = useCallback(() => {
+ setSearchParams({ riskLevel: [] });
+ }, [setSearchParams]);
+
const { onPaginate, onPrevPage, onNextPage, onLastPage, isLastPage } = usePagination({
totalPages: data?.totalPages ?? 0,
});
@@ -74,5 +103,8 @@ export const useMerchantMonitoringLogic = () => {
reportType,
onReportTypeChange,
REPORT_TYPE_TO_DISPLAY_TEXT,
+ RISK_LEVEL_FILTERS,
+ onRiskLevelChange,
+ onClearSelect,
};
};
From 1ab4ea509e8e2742afeceb091d1a2641358569e9 Mon Sep 17 00:00:00 2001
From: Shane <66246046+shanegrouber@users.noreply.github.com>
Date: Thu, 19 Dec 2024 17:23:27 +0200
Subject: [PATCH 3/4] feat(MerchantMonitoring): add status filters to reports
- Refactor MultiSelect components to include status filters
- Update handling functions for new status parameter
(your code is now as organized as a folder full of junk drawers)
---
.../atoms/MultiSelect/MultiSelect.tsx | 13 +-----
.../src/domains/business-reports/fetchers.ts | 10 ++++-
.../useBusinessReportsQuery.tsx | 8 +++-
.../domains/business-reports/query-keys.ts | 6 ++-
.../MerchantMonitoring.page.tsx | 39 ++++++++++------
.../get-merchant-monitoring-search-schema.ts | 13 +++++-
.../useMerchantMonitoringLogic.tsx | 45 ++++++++++++++-----
.../AlertsFilters/AlertsFilters.tsx | 3 +-
8 files changed, 94 insertions(+), 43 deletions(-)
diff --git a/apps/backoffice-v2/src/common/components/atoms/MultiSelect/MultiSelect.tsx b/apps/backoffice-v2/src/common/components/atoms/MultiSelect/MultiSelect.tsx
index 02c64a0242..78d5bdbaac 100644
--- a/apps/backoffice-v2/src/common/components/atoms/MultiSelect/MultiSelect.tsx
+++ b/apps/backoffice-v2/src/common/components/atoms/MultiSelect/MultiSelect.tsx
@@ -39,13 +39,11 @@ export const MultiSelect = <
},
>({
title,
- selectedValues,
+ selectedValues: selected,
onSelect,
onClearSelect,
options,
}: IMultiSelectProps
) => {
- const [selected, setSelected] = useState(selectedValues);
-
const onSelectChange = useCallback(
(value: TOption['value']) => {
const isSelected = selected.some(selectedValue => selectedValue === value);
@@ -53,7 +51,6 @@ export const MultiSelect = <
? selected.filter(selectedValue => selectedValue !== value)
: [...selected, value];
- setSelected(nextSelected);
onSelect(nextSelected);
},
[onSelect, selected],
@@ -125,13 +122,7 @@ export const MultiSelect = <
<>
- {
- onClearSelect();
- setSelected([]);
- }}
- className="justify-center text-center"
- >
+
Clear filters
diff --git a/apps/backoffice-v2/src/domains/business-reports/fetchers.ts b/apps/backoffice-v2/src/domains/business-reports/fetchers.ts
index 9d82771336..eb923fe846 100644
--- a/apps/backoffice-v2/src/domains/business-reports/fetchers.ts
+++ b/apps/backoffice-v2/src/domains/business-reports/fetchers.ts
@@ -14,7 +14,10 @@ import {
MerchantReportVersion,
} from '@/domains/business-reports/constants';
import { UnknownRecord } from 'type-fest';
-import { RISK_LEVELS } from '@/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
+import {
+ RISK_LEVELS,
+ STATUS_OPTIONS,
+} from '@/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
export const BusinessReportSchema = z
.object({
@@ -88,10 +91,12 @@ export const fetchLatestBusinessReport = async ({
export const fetchBusinessReports = async ({
reportType,
riskLevel,
+ status,
...params
}: {
reportType: MerchantReportType | 'All';
riskLevel: Array<(typeof RISK_LEVELS)[number]>;
+ status: Array<(typeof STATUS_OPTIONS)[number]>;
page: {
number: number;
size: number;
@@ -102,7 +107,8 @@ export const fetchBusinessReports = async ({
{
...params,
...(reportType !== 'All' && { type: reportType }),
- riskLevel: riskLevel,
+ riskLevel,
+ status,
},
{ encode: false },
);
diff --git a/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx b/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx
index 57de088021..0f0cbd232d 100644
--- a/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx
+++ b/apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx
@@ -3,7 +3,10 @@ import { useQuery } from '@tanstack/react-query';
import { businessReportsQueryKey } from '@/domains/business-reports/query-keys';
import { isString } from '@/common/utils/is-string/is-string';
import { MerchantReportType } from '@/domains/business-reports/constants';
-import { RISK_LEVELS } from '@/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
+import {
+ RISK_LEVELS,
+ STATUS_OPTIONS,
+} from '@/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
export const useBusinessReportsQuery = ({
reportType,
@@ -13,6 +16,7 @@ export const useBusinessReportsQuery = ({
sortBy,
sortDir,
riskLevel,
+ status,
}: {
reportType: MerchantReportType | 'All';
search: string;
@@ -21,6 +25,7 @@ export const useBusinessReportsQuery = ({
sortBy: string;
sortDir: string;
riskLevel: Array<(typeof RISK_LEVELS)[number]>;
+ status: Array<(typeof STATUS_OPTIONS)[number]>;
}) => {
const isAuthenticated = useIsAuthenticated();
@@ -33,6 +38,7 @@ export const useBusinessReportsQuery = ({
sortBy,
sortDir,
riskLevel,
+ status,
}),
enabled:
isAuthenticated &&
diff --git a/apps/backoffice-v2/src/domains/business-reports/query-keys.ts b/apps/backoffice-v2/src/domains/business-reports/query-keys.ts
index 07f4a2c8fa..6b192ad952 100644
--- a/apps/backoffice-v2/src/domains/business-reports/query-keys.ts
+++ b/apps/backoffice-v2/src/domains/business-reports/query-keys.ts
@@ -6,7 +6,10 @@ import {
fetchLatestBusinessReport,
} from '@/domains/business-reports/fetchers';
import { MerchantReportType } from '@/domains/business-reports/constants';
-import { RISK_LEVELS } from '@/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
+import {
+ RISK_LEVELS,
+ STATUS_OPTIONS,
+} from '@/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
export const businessReportsQueryKey = createQueryKeys('business-reports', {
list: ({
@@ -23,6 +26,7 @@ export const businessReportsQueryKey = createQueryKeys('business-reports', {
sortBy: string;
sortDir: string;
riskLevel: Array<(typeof RISK_LEVELS)[number]>;
+ status: Array<(typeof STATUS_OPTIONS)[number]>;
}) => ({
queryKey: [{ page, pageSize, sortBy, sortDir, ...params }],
queryFn: () => {
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
index dc20d50899..fdc2691786 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
@@ -43,8 +43,11 @@ export const MerchantMonitoring: FunctionComponent = () => {
onReportTypeChange,
REPORT_TYPE_TO_DISPLAY_TEXT,
RISK_LEVEL_FILTERS,
- onRiskLevelChange,
- onClearSelect,
+ STATUS_LEVEL_FILTERS,
+ handleFilterChange,
+ handleFilterClear,
+ riskLevel,
+ status,
} = useMerchantMonitoringLogic();
return (
@@ -127,18 +130,26 @@ export const MerchantMonitoring: FunctionComponent = () => {
-
- {RISK_LEVEL_FILTERS.map(({ title, options }) => (
-
- ))}
-
+ {RISK_LEVEL_FILTERS.map(({ title, accessor, options }) => (
+
+ ))}
+ {STATUS_LEVEL_FILTERS.map(({ title, accessor, options }) => (
+
+ ))}
{isNonEmptyArray(businessReports) &&
}
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts b/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts
index 39dc8dea04..ea1453a6c9 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/get-merchant-monitoring-search-schema.ts
@@ -5,6 +5,7 @@ import { BooleanishRecordSchema } from '@ballerine/ui';
import {
REPORT_TYPE_TO_DISPLAY_TEXT,
RISK_LEVELS,
+ STATUS_OPTIONS,
} from './hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic';
export const getMerchantMonitoringSearchSchema = () =>
@@ -47,5 +48,15 @@ export const getMerchantMonitoringSearchSchema = () =>
],
),
)
- .optional(),
+ .catch([]),
+ status: z
+ .array(
+ z.enum(
+ STATUS_OPTIONS.map(status => status.toLowerCase()) as [
+ (typeof STATUS_OPTIONS)[number],
+ ...Array<(typeof STATUS_OPTIONS)[number]>,
+ ],
+ ),
+ )
+ .catch([]),
});
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
index 92eeb6fd03..53c85af6de 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
@@ -24,6 +24,7 @@ export const RISK_LEVELS = ['Critical', 'High', 'Medium', 'Low'] as const;
const RISK_LEVEL_FILTERS = [
{
title: 'Risk Level',
+ accessor: 'riskLevel',
options: RISK_LEVELS.map(riskLevel => ({
label: riskLevel,
value: riskLevel.toLowerCase(),
@@ -31,6 +32,19 @@ const RISK_LEVEL_FILTERS = [
},
];
+export const STATUS_OPTIONS = ['In Progress', 'Quality Control', 'Manual Review'] as const;
+
+const STATUS_LEVEL_FILTERS = [
+ {
+ title: 'Status',
+ accessor: 'status',
+ options: STATUS_OPTIONS.map(status => ({
+ label: status,
+ value: status.toLowerCase(),
+ })),
+ },
+];
+
export const useMerchantMonitoringLogic = () => {
const locale = useLocale();
const { data: customer } = useCustomerQuery();
@@ -38,7 +52,7 @@ export const useMerchantMonitoringLogic = () => {
const MerchantMonitoringSearchSchema = getMerchantMonitoringSearchSchema();
const [
- { page, pageSize, sortBy, sortDir, search: searchParamValue, reportType, riskLevel },
+ { page, pageSize, sortBy, sortDir, search: searchParamValue, reportType, riskLevel, status },
setSearchParams,
] = useZodSearchParams(MerchantMonitoringSearchSchema);
@@ -59,26 +73,32 @@ export const useMerchantMonitoringLogic = () => {
sortBy,
sortDir,
riskLevel: riskLevel ?? [],
+ status: status ?? [],
});
const onReportTypeChange = (reportType: keyof typeof REPORT_TYPE_TO_DISPLAY_TEXT) => {
setSearchParams({ reportType: REPORT_TYPE_TO_DISPLAY_TEXT[reportType] });
};
- const onRiskLevelChange = useCallback(
- (selected: unknown[]) => {
- const selectedRiskLevels = selected as Array<(typeof RISK_LEVELS)[number]>;
-
+ const handleFilterChange = useCallback(
+ (filterKey: string) => (selected: unknown) => {
setSearchParams({
- riskLevel: selectedRiskLevels,
+ [filterKey]: Array.isArray(selected) ? selected : [selected],
+ page: '1',
});
},
[setSearchParams],
);
- const onClearSelect = useCallback(() => {
- setSearchParams({ riskLevel: [] });
- }, [setSearchParams]);
+ const handleFilterClear = useCallback(
+ (filterKey: string) => () => {
+ setSearchParams({
+ [filterKey]: [],
+ page: '1',
+ });
+ },
+ [setSearchParams],
+ );
const { onPaginate, onPrevPage, onNextPage, onLastPage, isLastPage } = usePagination({
totalPages: data?.totalPages ?? 0,
@@ -104,7 +124,10 @@ export const useMerchantMonitoringLogic = () => {
onReportTypeChange,
REPORT_TYPE_TO_DISPLAY_TEXT,
RISK_LEVEL_FILTERS,
- onRiskLevelChange,
- onClearSelect,
+ STATUS_LEVEL_FILTERS,
+ handleFilterChange,
+ handleFilterClear,
+ riskLevel,
+ status,
};
};
diff --git a/apps/backoffice-v2/src/pages/TransactionMonitoringAlerts/components/AlertsFilters/AlertsFilters.tsx b/apps/backoffice-v2/src/pages/TransactionMonitoringAlerts/components/AlertsFilters/AlertsFilters.tsx
index 9258e26d9d..d01798d4f6 100644
--- a/apps/backoffice-v2/src/pages/TransactionMonitoringAlerts/components/AlertsFilters/AlertsFilters.tsx
+++ b/apps/backoffice-v2/src/pages/TransactionMonitoringAlerts/components/AlertsFilters/AlertsFilters.tsx
@@ -4,7 +4,6 @@ import { MultiSelect } from '@/common/components/atoms/MultiSelect/MultiSelect';
import { useFilter } from '@/common/hooks/useFilter/useFilter';
import { AlertStatuses } from '@/domains/alerts/fetchers';
import { titleCase } from 'string-ts';
-import { keyFactory } from '@/common/utils/key-factory/key-factory';
export const AlertsFilters: FunctionComponent<{
assignees: TUsers;
@@ -79,7 +78,7 @@ export const AlertsFilters: FunctionComponent<{
{filters.map(({ title, accessor, options }) => (
Date: Sun, 22 Dec 2024 12:53:29 +0200
Subject: [PATCH 4/4] feat(multi-select): enhance multi-select component with
optional props
- Add support for left and right icons in multi-select trigger
- Refactor button styling in multi-select to accommodate new props
- Modify multi-select usage in MerchantMonitoring to utilize new features
(Your multi-select options are so numerous, I'm surprised it's not a buffet)
---
.../atoms/MultiSelect/MultiSelect.tsx | 31 +++++++++++++++----
.../DateRangePicker/DateRangePicker.tsx | 2 +-
.../components/molecules/Search/Search.tsx | 2 +-
.../MerchantMonitoring.page.tsx | 12 ++++---
.../MerchantMonitoringTable/columns.tsx | 21 ++++++++-----
.../useMerchantMonitoringLogic.tsx | 26 ++++++++++++----
6 files changed, 68 insertions(+), 26 deletions(-)
diff --git a/apps/backoffice-v2/src/common/components/atoms/MultiSelect/MultiSelect.tsx b/apps/backoffice-v2/src/common/components/atoms/MultiSelect/MultiSelect.tsx
index 78d5bdbaac..fc54f15ee5 100644
--- a/apps/backoffice-v2/src/common/components/atoms/MultiSelect/MultiSelect.tsx
+++ b/apps/backoffice-v2/src/common/components/atoms/MultiSelect/MultiSelect.tsx
@@ -1,4 +1,5 @@
-import { ReactNode, useCallback, useState } from 'react';
+import { CheckIcon, PlusCircledIcon } from '@radix-ui/react-icons';
+import { ReactNode, useCallback } from 'react';
import {
Badge,
Button,
@@ -14,7 +15,7 @@ import {
PopoverContent,
PopoverTrigger,
} from '@ballerine/ui';
-import { CheckIcon, PlusCircledIcon } from '@radix-ui/react-icons';
+
import { Separator } from '@/common/components/atoms/Separator/Separator';
interface IMultiSelectProps<
@@ -29,6 +30,16 @@ interface IMultiSelectProps<
onSelect: (value: Array) => void;
onClearSelect: () => void;
options: TOption[];
+ props?: {
+ trigger?: {
+ leftIcon?: JSX.Element;
+ rightIcon?: JSX.Element;
+ className?: string;
+ title?: {
+ className?: string;
+ };
+ };
+ };
}
export const MultiSelect = <
@@ -43,6 +54,7 @@ export const MultiSelect = <
onSelect,
onClearSelect,
options,
+ props,
}: IMultiSelectProps) => {
const onSelectChange = useCallback(
(value: TOption['value']) => {
@@ -56,12 +68,18 @@ export const MultiSelect = <
[onSelect, selected],
);
+ const TriggerLeftIcon = props?.trigger?.leftIcon ?? ;
+
return (
-
>
)}
+ {props?.trigger?.rightIcon}
diff --git a/apps/backoffice-v2/src/common/components/molecules/DateRangePicker/DateRangePicker.tsx b/apps/backoffice-v2/src/common/components/molecules/DateRangePicker/DateRangePicker.tsx
index def20aa47e..1441864d4f 100644
--- a/apps/backoffice-v2/src/common/components/molecules/DateRangePicker/DateRangePicker.tsx
+++ b/apps/backoffice-v2/src/common/components/molecules/DateRangePicker/DateRangePicker.tsx
@@ -19,7 +19,7 @@ export const DateRangePicker = ({ onChange, value, className }: TDateRangePicker
diff --git a/apps/backoffice-v2/src/common/components/molecules/Search/Search.tsx b/apps/backoffice-v2/src/common/components/molecules/Search/Search.tsx
index b10c986d85..b7fab4c87a 100644
--- a/apps/backoffice-v2/src/common/components/molecules/Search/Search.tsx
+++ b/apps/backoffice-v2/src/common/components/molecules/Search/Search.tsx
@@ -8,7 +8,7 @@ export const Search: FunctionComponent<{
}> = ({ value, placeholder, onChange }) => {
return (
-
+
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
index 875f79edc6..e384013601 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx
@@ -51,6 +51,7 @@ export const MerchantMonitoring: FunctionComponent = () => {
handleFilterClear,
riskLevel,
status,
+ multiselectProps,
} = useMerchantMonitoringLogic();
return (
@@ -121,8 +122,9 @@ export const MerchantMonitoring: FunctionComponent = () => {
/>
-
- Type
+
+
+ Type
@@ -143,20 +145,22 @@ export const MerchantMonitoring: FunctionComponent = () => {
))}
{STATUS_LEVEL_FILTERS.map(({ title, accessor, options }) => (
))}
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/components/MerchantMonitoringTable/columns.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoring/components/MerchantMonitoringTable/columns.tsx
index 3ba4b15a7b..97d532ac93 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/components/MerchantMonitoringTable/columns.tsx
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/components/MerchantMonitoringTable/columns.tsx
@@ -26,7 +26,12 @@ const columnHelper = createColumnHelper
();
const SCAN_TYPES = {
ONBOARDING: 'Onboarding',
MONITORING: 'Monitoring',
-};
+} as const;
+
+const REPORT_STATUS_TO_DISPLAY_STATUS = {
+ [MERCHANT_REPORT_STATUSES_MAP.completed]: 'Manual Review',
+ [MERCHANT_REPORT_STATUSES_MAP['quality-control']]: 'Quality Control',
+} as const;
const REPORT_TYPE_TO_SCAN_TYPE = {
[MERCHANT_REPORT_TYPES_MAP.MERCHANT_REPORT_T1]: SCAN_TYPES.ONBOARDING,
@@ -152,24 +157,24 @@ export const columns = [
);
},
- header: 'Risk Score',
+ header: 'Risk Level',
}),
columnHelper.accessor('status', {
cell: info => {
const status = info.getValue();
- const statusToDisplayStatus = {
- [MERCHANT_REPORT_STATUSES_MAP.completed]: 'Manual Review',
- [MERCHANT_REPORT_STATUSES_MAP['quality-control']]: 'Quality Control',
- } as const;
return (
- {titleCase(statusToDisplayStatus[status as keyof typeof statusToDisplayStatus] ?? status)}
+ {titleCase(
+ REPORT_STATUS_TO_DISPLAY_STATUS[
+ status as keyof typeof REPORT_STATUS_TO_DISPLAY_STATUS
+ ] ?? status,
+ )}
);
},
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
index c80c231c70..f3b4d0cbdb 100644
--- a/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
+++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx
@@ -1,9 +1,15 @@
import dayjs from 'dayjs';
-import { useCallback, ComponentProps } from 'react';
+import { SlidersHorizontal } from 'lucide-react';
+import React, { useCallback, ComponentProps, useMemo } from 'react';
import { useLocale } from '@/common/hooks/useLocale/useLocale';
import { useSearch } from '@/common/hooks/useSearch/useSearch';
import { usePagination } from '@/common/hooks/usePagination/usePagination';
+import { useFindings } from '@/pages/MerchantMonitoring/hooks/useFindings/useFindings';
+import { useZodSearchParams } from '@/common/hooks/useZodSearchParams/useZodSearchParams';
+import { DateRangePicker } from '@/common/components/molecules/DateRangePicker/DateRangePicker';
+import { useCustomerQuery } from '@/domains/customer/hooks/queries/useCustomerQuery/useCustomerQuery';
+import { useBusinessReportsQuery } from '@/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery';
import {
DISPLAY_TEXT_TO_MERCHANT_REPORT_TYPE,
MerchantMonitoringSearchSchema,
@@ -11,11 +17,6 @@ import {
RISK_LEVEL_FILTERS,
STATUS_LEVEL_FILTERS,
} from '@/pages/MerchantMonitoring/schemas';
-import { useFindings } from '@/pages/MerchantMonitoring/hooks/useFindings/useFindings';
-import { useZodSearchParams } from '@/common/hooks/useZodSearchParams/useZodSearchParams';
-import { DateRangePicker } from '@/common/components/molecules/DateRangePicker/DateRangePicker';
-import { useCustomerQuery } from '@/domains/customer/hooks/queries/useCustomerQuery/useCustomerQuery';
-import { useBusinessReportsQuery } from '@/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery';
export const useMerchantMonitoringLogic = () => {
const locale = useLocale();
@@ -81,6 +82,18 @@ export const useMerchantMonitoringLogic = () => {
setSearchParams({ from, to });
};
+ const multiselectProps = useMemo(
+ () => ({
+ trigger: {
+ leftIcon:
,
+ title: {
+ className: `font-normal text-sm`,
+ },
+ },
+ }),
+ [],
+ );
+
return {
totalPages: data?.totalPages || 0,
totalItems: data?.totalItems || 0,
@@ -99,6 +112,7 @@ export const useMerchantMonitoringLogic = () => {
locale,
reportType,
onReportTypeChange,
+ multiselectProps,
REPORT_TYPE_TO_DISPLAY_TEXT,
RISK_LEVEL_FILTERS,
STATUS_LEVEL_FILTERS,