feat: mejorar el componente de ayuda para proformas y ajustar pruebas de actualización

This commit is contained in:
David Arranz 2026-08-28 13:34:03 +02:00
parent a37d6fc96b
commit 1a8d63373d
4 changed files with 432 additions and 420 deletions

View File

@ -10,6 +10,7 @@ import {
Separator, Separator,
} from "@repo/shadcn-ui/components"; } from "@repo/shadcn-ui/components";
import { AlertCircleIcon, CheckCircle2Icon, CircleDashedIcon, CircleHelpIcon } from "lucide-react"; import { AlertCircleIcon, CheckCircle2Icon, CircleDashedIcon, CircleHelpIcon } from "lucide-react";
import type { ComponentProps } from "react";
import { useTranslation } from "../../../../i18n"; import { useTranslation } from "../../../../i18n";
import type { ProformaIssuanceReadiness } from "../../../shared"; import type { ProformaIssuanceReadiness } from "../../../shared";
@ -23,7 +24,7 @@ interface ProformaUpdateHelpPopoverProps {
onRetryReadiness?: () => void; onRetryReadiness?: () => void;
} }
interface HelpTriggerProps { interface HelpTriggerProps extends ComponentProps<typeof Button> {
ariaLabel: string; ariaLabel: string;
pendingBlockersCount: number; pendingBlockersCount: number;
} }
@ -39,9 +40,16 @@ interface HelpReadinessSectionProps {
translate: (key: string, params?: Record<string, string | number | null | undefined>) => string; translate: (key: string, params?: Record<string, string | number | null | undefined>) => string;
} }
const HelpTrigger = ({ ariaLabel, pendingBlockersCount }: HelpTriggerProps) => { const HelpTrigger = ({ ariaLabel, className, pendingBlockersCount, ...props }: HelpTriggerProps) => {
return ( return (
<Button aria-label={ariaLabel} className="relative" size="icon" type="button" variant="outline"> <Button
{...props}
aria-label={ariaLabel}
className={className ? `relative ${className}` : "relative"}
size="icon"
type="button"
variant="outline"
>
<CircleHelpIcon aria-hidden="true" className="size-4" /> <CircleHelpIcon aria-hidden="true" className="size-4" />
{pendingBlockersCount > 0 ? ( {pendingBlockersCount > 0 ? (
<Badge <Badge
@ -190,9 +198,9 @@ export const ProformaUpdateHelpPopover = ({
return ( return (
<Popover> <Popover>
<PopoverTrigger> <PopoverTrigger
<HelpTrigger ariaLabel={triggerAriaLabel} pendingBlockersCount={pendingBlockersCount} /> render={<HelpTrigger ariaLabel={triggerAriaLabel} pendingBlockersCount={pendingBlockersCount} />}
</PopoverTrigger> />
<PopoverContent <PopoverContent
align="end" align="end"

View File

@ -31,7 +31,7 @@ const buildFormData = (value: Partial<ProformaUpdateForm> = {}): ProformaUpdateF
...value, ...value,
}) as ProformaUpdateForm; }) as ProformaUpdateForm;
test("excluye items vacíos no valorados al construir el PUT de update", () => { test("mantiene los items vacíos y respeta su orden al construir el PUT de update", () => {
const formData = buildFormData({ const formData = buildFormData({
items: [ items: [
{ {
@ -66,7 +66,17 @@ test("excluye items vacíos no valorados al construir el PUT de update", () => {
formData formData
); );
assert.equal(result.data.items?.length, 1); assert.equal(result.data.items?.length, 2);
assert.equal(result.data.items?.[0]?.description, "Servicio"); assert.equal(result.data.items?.[0]?.description, "");
assert.equal(result.data.items?.[0]?.quantity, null);
assert.equal(result.data.items?.[0]?.unit_amount, null);
assert.equal(result.data.items?.[0]?.position, 0); assert.equal(result.data.items?.[0]?.position, 0);
assert.equal(result.data.items?.[1]?.description, "Servicio");
assert.deepEqual(result.data.items?.[1]?.quantity, { value: "100", scale: "2" });
assert.deepEqual(result.data.items?.[1]?.unit_amount, {
value: "1000000",
scale: "4",
currency_code: "EUR",
});
assert.equal(result.data.items?.[1]?.position, 1);
}); });

View File

@ -109,9 +109,7 @@ export const buildUpdateProformaByIdParams = (
// Si se han tocado los detalles, se envían todos // Si se han tocado los detalles, se envían todos
if (shouldReplaceItems(patch)) { if (shouldReplaceItems(patch)) {
const context = buildProformaItemUpdateDTOContext(formData); const context = buildProformaItemUpdateDTOContext(formData);
data.items = formData.items data.items = formData.items.map((item, index) => toProformaItemUpdateDTO(item, index, context));
.filter(isValuedProformaItem)
.map((item, index) => toProformaItemUpdateDTO(item, index, context));
} }
return { return {
@ -146,10 +144,6 @@ const toProformaItemUpdateDTO = (
}; };
}; };
const isValuedProformaItem = (item: ProformaItemUpdateForm): boolean => {
return item.quantity !== null && item.unitAmount !== null;
};
const buildProformaItemUpdateDTOContext = ( const buildProformaItemUpdateDTOContext = (
formData: ProformaUpdateForm formData: ProformaUpdateForm
): ProformaItemUpdateDTOContext => { ): ProformaItemUpdateDTOContext => {