Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | 3x 3x 3x 62x 62x 62x 62x 42x 28x 48x 17x 30x 17x 9x 9x 8x 7x 62x 46x 34x 62x 62x | import { processorMap } from "@features/Merchants/MerchantSidePanel/constants";
import { useGetProcessors } from "@hooks/acquirer-api/merchants/useGetProcessors";
import { useGetCurrentMerchantId } from "@hooks/common";
import { useEffect, useMemo } from "react";
import { useAcquirerDefaultProcessor } from "../hooks/useAcquirerDefaultProcessor";
import { UNRESOLVED_PROCESSOR } from "../useHubFilters";
import HubDropdown, { HubDropdownOption } from "./HubDropdown";
interface Props {
value: string;
onChange: (processorName: string) => void;
disabled?: boolean;
}
const ALL_PROCESSORS: HubDropdownOption = {
value: "all",
label: "All Processors",
};
const RESOLVING_LABEL = "Processor";
/**
* Controlled processor selector for the Reconciliation Hub. Reuses
* `useGetProcessors` + `processorMap` (the same source as the shared
* `ProcessorDropdownFilter`) but drives the hub's local filter state, and owns
* resolving the hub's initial processor — see the effect below.
*/
const HubProcessorDropdown = ({ value, onChange, disabled }: Props) => {
const { merchantId } = useGetCurrentMerchantId();
const { data, isLoading } = useGetProcessors(merchantId);
const { defaultProcessorName, isResolving } = useAcquirerDefaultProcessor();
// Resolves the hub's initial processor to the acquirer's own default
// (GB-21646) and corrects a value the acquirer doesn't have. A specific
// processor is only ever auto-selected when it is known to be the acquirer's
// default: the catalogue is global and arbitrarily ordered, so picking from
// it would just as easily land a non-Worldpay acquirer on Worldpay — the very
// empty hub this fixes. Everything else resolves to "all", which is both
// truthful and populated (the BE materialises parent rows at processor_id 0).
useEffect(() => {
// `!merchantId` matters on its own: both queries are `enabled: !!id`, so
// before getAccounts() lands they sit idle — undefined data, isLoading
// false — and the "all" fallback below would latch before either had a
// chance to run, permanently (an "all" value short-circuits every later
// resolution).
if (!merchantId || isLoading || isResolving) return;
if (value === ALL_PROCESSORS.value) return;
if (data?.some((processor) => processor.name === value)) return;
const defaultOption = data?.find(
(processor) => processor.name === defaultProcessorName,
);
if (defaultOption) {
onChange(defaultOption.name);
return;
}
// An unusable catalogue only ever rescopes the seed — a failed background
// refetch must not pull an existing selection out from under the user.
if (data?.length || value === UNRESOLVED_PROCESSOR) {
onChange(ALL_PROCESSORS.value);
}
}, [
merchantId,
data,
isLoading,
value,
defaultProcessorName,
isResolving,
onChange,
]);
const options = useMemo<HubDropdownOption[]>(() => {
const processorOptions =
data?.map((processor) => ({
value: processor.name,
label: processorMap[processor.name] ?? processor.name,
})) ?? [];
return [ALL_PROCESSORS, ...processorOptions];
}, [data]);
const selectedLabel =
value === UNRESOLVED_PROCESSOR
? RESOLVING_LABEL
: value === ALL_PROCESSORS.value
? ALL_PROCESSORS.label
: // Fall back to the raw processor key (not a hardcoded "Worldpay") when a
// processor isn't in processorMap.
processorMap[value as keyof typeof processorMap] ?? value;
return (
<HubDropdown
dataTestId="hub-processor-dropdown"
selectedValue={value}
selectedLabel={selectedLabel}
options={options}
isLoading={isLoading}
onSelect={(option) => onChange(option.value)}
disabled={disabled}
/>
);
};
export default HubProcessorDropdown;
|