Compare commits

..

No commits in common. "994417e48fa943199bf1aed0b90c5658522983df" and "bd1266a6a2512fa4e8d3d662ce097ca05085ff0b" have entirely different histories.

15 changed files with 191 additions and 215 deletions

View File

@ -13,10 +13,8 @@ if (rootElement) {
createRoot(rootElement).render( createRoot(rootElement).render(
<StrictMode> <StrictMode>
<ThemeProvider defaultTheme="light" storageKey="vite-ui-theme"> <ThemeProvider defaultTheme="light" storageKey="vite-ui-theme">
<> <App />
<App /> <TailwindIndicator />
<TailwindIndicator />
</>
</ThemeProvider> </ThemeProvider>
</StrictMode> </StrictMode>
); );

View File

@ -1,52 +1,60 @@
// proformas/delete/controllers/use-delete-proforma-dialog-controller.ts
import { showErrorToast, showSuccessToast } from "@repo/rdx-ui/helpers"; import { showErrorToast, showSuccessToast } from "@repo/rdx-ui/helpers";
import * as React from "react"; import React from "react";
import { useTranslation } from "../../../i18n"; import { useTranslation } from "../../../i18n";
import type { DeleteProformaByIdParams } from "../../shared"; import { type ProformaListRow, useDeleteProformaMutation } from "../../shared";
import { useProformaDeleteMutation } from "../../shared";
import type { DeleteProformaTarget } from "../entities";
type ConfirmStep = "initial" | "second";
interface DeleteProformaDialogState { interface DeleteProformaDialogState {
open: boolean; open: boolean;
targets: DeleteProformaTarget[]; proformas: ProformaListRow[];
confirmStep: ConfirmStep; isSubmitting: boolean;
requiresSecondConfirm: boolean;
confirmStep: "initial" | "second";
} }
const INITIAL_STATE: DeleteProformaDialogState = { const INITIAL_STATE: DeleteProformaDialogState = {
open: false, open: false,
targets: [], proformas: [],
isSubmitting: false,
requiresSecondConfirm: false,
confirmStep: "initial", confirmStep: "initial",
}; };
const buildDeleteParams = (target: DeleteProformaTarget): DeleteProformaByIdParams => ({ const SECOND_CONFIRM_THRESHOLD = 5;
id: target.id,
});
const getProformaLabel = (target: DeleteProformaTarget) => target.reference || `#${target.id}`; function canSubmitDelete(isSubmitting: boolean, proformas: ProformaListRow[]): boolean {
return !isSubmitting && proformas.length > 0;
}
export const useDeleteProformaDialogController = () => { function shouldMoveToSecondConfirmStep(
requiresSecondConfirm: boolean,
confirmStep: "initial" | "second"
): boolean {
return requiresSecondConfirm && confirmStep === "initial";
}
export function useDeleteProformaDialogController() {
const { t } = useTranslation(); const { t } = useTranslation();
const deleteMutation = useProformaDeleteMutation(); const { deleteProforma } = useDeleteProformaMutation();
const [state, setState] = React.useState<DeleteProformaDialogState>(INITIAL_STATE); const [state, setState] = React.useState<DeleteProformaDialogState>(INITIAL_STATE);
const { isSubmitting, proformas, requiresSecondConfirm, confirmStep } = state;
const openDialog = React.useCallback((targets: DeleteProformaTarget[]) => { const openDialog = React.useCallback((proformas: ProformaListRow[]) => {
if (targets.length === 0) return; const requiresSecondConfirm = proformas.length > SECOND_CONFIRM_THRESHOLD;
setState({ setState({
open: true, open: true,
targets, proformas,
isSubmitting: false,
requiresSecondConfirm,
confirmStep: "initial", confirmStep: "initial",
}); });
}, []); }, []);
const closeDialog = React.useCallback(() => { const closeDialog = React.useCallback(() => {
if (deleteMutation.isPending) return;
setState(INITIAL_STATE); setState(INITIAL_STATE);
}, [deleteMutation.isPending]); }, []);
const moveToSecondConfirmStep = React.useCallback(() => { const moveToSecondConfirmStep = React.useCallback(() => {
setState((current) => ({ setState((current) => ({
@ -55,109 +63,124 @@ export const useDeleteProformaDialogController = () => {
})); }));
}, []); }, []);
const notifySuccess = React.useCallback( const deleteSelectedProformas = React.useCallback(
(targets: DeleteProformaTarget[]) => { async (proformas: ProformaListRow[]) => {
if (targets.length === 1) { const results = await Promise.allSettled(
proformas.map((proforma) =>
deleteProforma({
proformaId: proforma.id,
})
)
);
const successCount = results.filter((result) => result.status === "fulfilled").length;
const errorCount = results.length - successCount;
return {
successCount,
errorCount,
};
},
[deleteProforma]
);
const notifyDeleteResult = React.useCallback(
(proformas: ProformaListRow[], successCount: number, errorCount: number) => {
if (proformas.length === 1 && successCount === 1) {
const proforma = proformas[0];
showSuccessToast( showSuccessToast(
t("pages.proformas.delete.successTitle"), t("pages.proformas.delete.successTitle"),
t("pages.proformas.delete.successSingleMessage", { t("pages.proformas.delete.successSingleMessage", {
reference: getProformaLabel(targets[0]), reference: proforma.reference || `#${proforma.id}`,
})
);
} else if (successCount > 0) {
showSuccessToast(
t("pages.proformas.delete.successTitle"),
t("pages.proformas.delete.successMultipleMessage", {
count: successCount,
}) })
); );
return;
} }
showSuccessToast( if (errorCount > 0) {
t("pages.proformas.delete.successTitle"),
t("pages.proformas.delete.successMultipleMessage", {
count: targets.length,
})
);
},
[t]
);
const notifyPartialError = React.useCallback(
(targets: DeleteProformaTarget[], errorCount: number) => {
if (targets.length === 1) {
showErrorToast( showErrorToast(
t("pages.proformas.delete.errorTitle"), t("pages.proformas.delete.errorTitle"),
t("pages.proformas.delete.errorSingleMessage") proformas.length === 1
? t("pages.proformas.delete.errorSingleMessage")
: t("pages.proformas.delete.errorMultipleMessage", {
count: errorCount,
})
); );
return;
} }
showErrorToast(
t("pages.proformas.delete.errorTitle"),
t("pages.proformas.delete.errorMultipleMessage", {
count: errorCount,
})
);
}, },
[t] [t]
); );
const submitDelete = React.useCallback(async () => { const submitDelete = React.useCallback(async () => {
const { targets } = state; setState((current) => ({
...current,
const results = await Promise.allSettled( isSubmitting: true,
targets.map((target) => deleteMutation.mutateAsync(buildDeleteParams(target))) }));
);
const successCount = results.filter((result) => result.status === "fulfilled").length;
const errorCount = results.length - successCount;
if (successCount > 0) {
const fulfilledTargets = targets.filter((_, index) => results[index]?.status === "fulfilled");
const rejectedTargets = targets.filter((_, index) => results[index]?.status === "rejected");
if (fulfilledTargets.length > 0) {
notifySuccess(fulfilledTargets);
}
if (rejectedTargets.length > 0) {
notifyPartialError(targets, rejectedTargets.length);
return;
}
}
if (errorCount > 0) {
notifyPartialError(targets, errorCount);
return;
}
setState(INITIAL_STATE);
}, [deleteMutation, notifyPartialError, notifySuccess, state]);
const confirmDelete = React.useCallback(async () => {
if (deleteMutation.isPending || state.targets.length === 0) {
return;
}
if (state.confirmStep === "initial") {
moveToSecondConfirmStep();
return;
}
try { try {
await submitDelete(); const { successCount, errorCount } = await deleteSelectedProformas(proformas);
notifyDeleteResult(proformas, successCount, errorCount);
if (errorCount === 0) {
closeDialog();
return;
}
setState((current) => ({
...current,
isSubmitting: false,
}));
} catch { } catch {
showErrorToast( showErrorToast(
t("pages.proformas.delete.errorTitle"), t("pages.proformas.delete.errorTitle"),
t("pages.proformas.delete.errorUnexpectedMessage") t("pages.proformas.delete.errorUnexpectedMessage")
); );
setState((current) => ({
...current,
isSubmitting: false,
}));
} }
}, [deleteMutation.isPending, moveToSecondConfirmStep, state, submitDelete, t]); }, [closeDialog, deleteSelectedProformas, notifyDeleteResult, proformas, t]);
const confirmDelete = React.useCallback(async () => {
if (!canSubmitDelete(isSubmitting, proformas)) {
return;
}
if (shouldMoveToSecondConfirmStep(requiresSecondConfirm, confirmStep)) {
moveToSecondConfirmStep();
return;
}
await submitDelete();
}, [
moveToSecondConfirmStep,
submitDelete,
isSubmitting,
proformas,
requiresSecondConfirm,
confirmStep,
]);
return { return {
open: state.open, open: state.open,
targets: state.targets, proformas: state.proformas,
isSubmitting: deleteMutation.isPending, isSubmitting: state.isSubmitting,
requiresSecondConfirm: state.requiresSecondConfirm,
isSecondConfirmStep: state.confirmStep === "second", isSecondConfirmStep: state.confirmStep === "second",
isBulkDelete: state.targets.length > 1, isBulkDelete: state.proformas.length > 1,
openDialog, openDialog,
closeDialog, closeDialog,
confirmDelete, confirmDelete,
}; };
}; }

View File

@ -1,4 +0,0 @@
export interface DeleteProformaTarget {
id: string;
reference?: string;
}

View File

@ -1 +0,0 @@
export * from "./delete-proforma-target.entity";

View File

@ -10,60 +10,46 @@ import {
} from "@repo/shadcn-ui/components"; } from "@repo/shadcn-ui/components";
import { useTranslation } from "../../../../i18n"; import { useTranslation } from "../../../../i18n";
import type { DeleteProformaTarget } from "../../entities"; import type { ProformaListRow } from "../../../shared";
interface DeleteProformaDialogProps { interface DeleteProformaDialogProps {
open: boolean; open: boolean;
onOpenChange: (open: boolean) => void; onOpenChange: (open: boolean) => void;
targets: DeleteProformaTarget[]; proformas: ProformaListRow[];
isSubmitting: boolean; isSubmitting: boolean;
onConfirm: () => void; onConfirm: () => void;
requiresSecondConfirm: boolean;
isSecondConfirmStep: boolean; isSecondConfirmStep: boolean;
} }
const getTargetLabel = (target: DeleteProformaTarget) => target.reference || `#${target.id}`; export function DeleteProformaDialog({
export const DeleteProformaDialog = ({
open, open,
onOpenChange, onOpenChange,
targets, proformas,
isSubmitting, isSubmitting,
onConfirm, onConfirm,
requiresSecondConfirm,
isSecondConfirmStep, isSecondConfirmStep,
}: DeleteProformaDialogProps) => { }: DeleteProformaDialogProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const total = targets.length; const total = proformas.length;
const isSingle = total === 1; const isSingle = total === 1;
const firstTarget = targets[0]; const firstProforma = proformas[0];
const title = isSecondConfirmStep const title = isSecondConfirmStep
? isSingle ? t("proformas.delete_proforma_dialog.second_confirm_title", { count: total })
? t("components.delete_proforma_dialog.second_confirm_single_title", {
reference: getTargetLabel(firstTarget),
})
: t("components.delete_proforma_dialog.second_confirm_multiple_title", {
count: total,
})
: isSingle : isSingle
? t("components.delete_proforma_dialog.single_title", { ? t("proformas.delete_proforma_dialog.single_title", {
reference: getTargetLabel(firstTarget), reference: firstProforma?.reference ?? `#${firstProforma?.id}`,
}) })
: t("components.delete_proforma_dialog.multiple_title", { : t("proformas.delete_proforma_dialog.multiple_title", { count: total });
count: total,
});
const description = isSecondConfirmStep const description = isSecondConfirmStep
? isSingle ? t("proformas.delete_proforma_dialog.second_confirm_description", { count: total })
? t("components.delete_proforma_dialog.second_confirm_single_description")
: t("components.delete_proforma_dialog.second_confirm_multiple_description", {
count: total,
})
: isSingle : isSingle
? t("components.delete_proforma_dialog.single_description") ? t("proformas.delete_proforma_dialog.single_description")
: t("components.delete_proforma_dialog.multiple_description", { : t("proformas.delete_proforma_dialog.multiple_description", { count: total });
count: total,
});
return ( return (
<AlertDialog <AlertDialog
@ -79,39 +65,45 @@ export const DeleteProformaDialog = ({
<AlertDialogDescription>{description}</AlertDialogDescription> <AlertDialogDescription>{description}</AlertDialogDescription>
</AlertDialogHeader> </AlertDialogHeader>
{!isSecondConfirmStep && total > 1 ? ( {!isSecondConfirmStep && total > 1 && (
<div className="mt-4 max-h-48 overflow-y-auto rounded-md border p-3 text-sm"> <div className="mt-4 max-h-48 overflow-y-auto rounded-md border p-3 text-sm">
<ul className="space-y-1"> <ul className="space-y-1">
{targets.map((target) => ( {proformas.map((proforma) => (
<li className="text-muted-foreground" key={target.id}> <li className="flex justify-between text-muted-foreground" key={proforma.id}>
{t("components.delete_proforma_dialog.list_item", { <span>
reference: getTargetLabel(target), {t("proformas.delete_proforma_dialog.list_item", {
})} reference: proforma.reference ?? `#${proforma.id}`,
})}
</span>
</li> </li>
))} ))}
</ul> </ul>
</div> </div>
) : null} )}
<AlertDialogFooter className="sm:justify-between"> <AlertDialogFooter className="sm:justify-between">
<Button disabled={isSubmitting} onClick={() => onOpenChange(false)} variant="outline"> <Button disabled={isSubmitting} onClick={() => onOpenChange(false)} variant="outline">
{t("components.delete_proforma_dialog.cancel")} {t("proformas.delete_proforma_dialog.cancel")}
</Button> </Button>
<Button disabled={isSubmitting || total === 0} onClick={onConfirm} variant="destructive"> <Button disabled={isSubmitting} onClick={onConfirm} variant="destructive">
{isSubmitting ? ( {isSubmitting ? (
<> <>
<Spinner className="mr-2 size-4" /> <Spinner className="mr-2 size-4" />
{t("components.delete_proforma_dialog.deleting")} {t("proformas.delete_proforma_dialog.deleting")}
</> </>
) : isSecondConfirmStep ? ( ) : isSecondConfirmStep ? (
t("components.delete_proforma_dialog.confirm_delete") t("proformas.delete_proforma_dialog.confirm_mass_delete")
) : isSingle ? (
t("proformas.delete_proforma_dialog.delete")
) : requiresSecondConfirm ? (
t("proformas.delete_proforma_dialog.continue")
) : ( ) : (
t("components.delete_proforma_dialog.continue") t("proformas.delete_proforma_dialog.delete_plural")
)} )}
</Button> </Button>
</AlertDialogFooter> </AlertDialogFooter>
</AlertDialogContent> </AlertDialogContent>
</AlertDialog> </AlertDialog>
); );
}; }

View File

@ -1 +0,0 @@
export * from "./prepare-delete-proforma-targets";

View File

@ -1,15 +0,0 @@
import type { Proforma, ProformaListRow } from "../../shared";
import type { DeleteProformaTarget } from "../entities";
export const prepareDeleteProformaTargets = (
input: Proforma | ProformaListRow | Array<Proforma | ProformaListRow>
): DeleteProformaTarget[] => {
const items = Array.isArray(input) ? input : [input];
return items.map(mapToDeleteProformaTarget);
};
const mapToDeleteProformaTarget = (proforma: Proforma | ProformaListRow): DeleteProformaTarget => ({
id: proforma.id,
reference: proforma.reference,
});

View File

@ -1,15 +1,11 @@
import type { RightPanelMode } from "@repo/rdx-ui/hooks"; import type { RightPanelMode } from "@repo/rdx-ui/hooks";
import { useSearchParams } from "react-router-dom"; import { useSearchParams } from "react-router-dom";
import { useDeleteProformaDialogController } from "../../delete";
import { useListProformasController } from "./use-list-proformas.controller"; import { useListProformasController } from "./use-list-proformas.controller";
import { useProformaSummaryPanelController } from "./use-proforma-summary-panel.controller"; import { useProformaSummaryPanelController } from "./use-proforma-summary-panel.controller";
export const useListProformasPageController = () => { export const useListProformasPageController = () => {
const listCtrl = useListProformasController(); const listCtrl = useListProformasController();
const deleteDialogCtrl = useDeleteProformaDialogController();
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const proformaId = searchParams.get("proformaId") ?? ""; const proformaId = searchParams.get("proformaId") ?? "";
@ -24,7 +20,5 @@ export const useListProformasPageController = () => {
return { return {
listCtrl, listCtrl,
panelCtrl, panelCtrl,
deleteDialogCtrl,
}; };
}; };

View File

@ -32,7 +32,7 @@ export const useListProformasController = () => {
pageNumber: pageIndex, pageNumber: pageIndex,
pageSize, pageSize,
order: "desc", order: "desc",
orderBy: "invoice_date", orderBy: "invoiceDate",
filters: filters:
statusFilter === "all" ? [] : [{ field: "status", operator: "eq", value: statusFilter }], statusFilter === "all" ? [] : [{ field: "status", operator: "eq", value: statusFilter }],
}), }),

View File

@ -22,7 +22,6 @@ interface ProformasGridProps {
export const ProformasGrid = ({ export const ProformasGrid = ({
data, data,
loading, loading,
fetching,
columns, columns,
pageIndex, pageIndex,
pageSize, pageSize,
@ -33,7 +32,7 @@ export const ProformasGrid = ({
const { t } = useTranslation(); const { t } = useTranslation();
const { items, totalItems } = data || { items: [], totalItems: 0 }; const { items, totalItems } = data || { items: [], totalItems: 0 };
if (loading) { if (loading)
return ( return (
<SkeletonDataTable <SkeletonDataTable
columns={columns.length} columns={columns.length}
@ -42,7 +41,6 @@ export const ProformasGrid = ({
showFooter showFooter
/> />
); );
}
return ( return (
<DataTable <DataTable
@ -53,6 +51,7 @@ export const ProformasGrid = ({
manualPagination manualPagination
onPageChange={onPageChange} onPageChange={onPageChange}
onPageSizeChange={onPageSizeChange} onPageSizeChange={onPageSizeChange}
onRowClick={(row, _index) => onRowClick?.(row.id)}
pageIndex={pageIndex} pageIndex={pageIndex}
pageSize={pageSize} pageSize={pageSize}
totalItems={totalItems} totalItems={totalItems}

View File

@ -96,6 +96,7 @@ export function useProformasGridColumns(
return ( return (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<ProformaStatusBadge status={proforma.status} /> <ProformaStatusBadge status={proforma.status} />
{/* Enlace discreto a factura real */} {/* Enlace discreto a factura real */}
{isIssued && ( {isIssued && (
<TooltipProvider> <TooltipProvider>
@ -104,13 +105,12 @@ export function useProformasGridColumns(
<Button <Button
asChild asChild
className="size-6 text-foreground hover:text-primary" className="size-6 text-foreground hover:text-primary"
onClick={() => actionHandlers.onLinkedInvoiceClick?.(proforma)}
size="icon" size="icon"
variant="ghost" variant="ghost"
> >
<a href={`/facturas/${invoiceId}`}> <ExternalLinkIcon />
<ExternalLinkIcon /> <span className="sr-only">Ver factura {invoiceId}</span>
<span className="sr-only">Ver factura {invoiceId}</span>
</a>
</Button> </Button>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent>Ver factura {invoiceId}</TooltipContent> <TooltipContent>Ver factura {invoiceId}</TooltipContent>
@ -148,6 +148,8 @@ export function useProformasGridColumns(
> >
{proforma.recipient.name} {proforma.recipient.name}
</button> </button>
<br />
<div className="text-xs text-muted-foreground">{proforma.recipient.tin}</div> <div className="text-xs text-muted-foreground">{proforma.recipient.tin}</div>
</div> </div>
); );

View File

@ -15,9 +15,8 @@ import { FilterIcon, PlusIcon } from "lucide-react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { useTranslation } from "../../../../i18n"; import { useTranslation } from "../../../../i18n";
import { DeleteProformaDialog } from "../../../delete"; import { ChangeStatusDialog } from "../../../change-status";
import { prepareDeleteProformaTargets } from "../../../delete/utils"; import { ProformaIssueDialog } from "../../../issue-proforma";
import type { ProformaListRow } from "../../../shared";
import { useListProformasPageController } from "../../controllers"; import { useListProformasPageController } from "../../controllers";
import { ProformaSummaryPanel, ProformasGrid, useProformasGridColumns } from "../blocks"; import { ProformaSummaryPanel, ProformasGrid, useProformasGridColumns } from "../blocks";
@ -25,17 +24,13 @@ export const ListProformasPage = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const navigate = useNavigate(); const navigate = useNavigate();
const { listCtrl, panelCtrl, deleteDialogCtrl } = useListProformasPageController(); const { listCtrl, panelCtrl } = useListProformasPageController();
const handleDeleteProforma = (proformaRow: ProformaListRow) => {
deleteDialogCtrl.openDialog(prepareDeleteProformaTargets(proformaRow));
};
const columns = useProformasGridColumns({ const columns = useProformasGridColumns({
onEditClick: (proforma) => navigate(`/proformas/${proforma.id}/edit`), onEditClick: (proforma) => navigate(`/proformas/${proforma.id}/edit`),
//onIssueClick: handleIssueProforma, onIssueClick: handleIssueProforma,
onDeleteClick: handleDeleteProforma, onDeleteClick: handleDeleteProforma,
//onChangeStatusClick: handleChangeStatusProforma, onChangeStatusClick: handleChangeStatusProforma,
}); });
const isPanelOpen = panelCtrl.panelState.isOpen; const isPanelOpen = panelCtrl.panelState.isOpen;
@ -148,18 +143,32 @@ export const ListProformasPage = () => {
<div className="flex min-h-0 flex-1 overflow-hidden">{listContent}</div> <div className="flex min-h-0 flex-1 overflow-hidden">{listContent}</div>
)} )}
<> <>
{/* Emitir factura */}
<ProformaIssueDialog
isSubmitting={issueDialogCtrl.isSubmitting}
onConfirm={issueDialogCtrl.confirmIssue}
onOpenChange={(open) => !open && issueDialogCtrl.closeDialog()}
open={issueDialogCtrl.open}
proforma={issueDialogCtrl.proforma}
/>
{/* Cambiar estado */}
<ChangeStatusDialog
isSubmitting={changeStatusDialogCtrl.isSubmitting}
onConfirm={changeStatusDialogCtrl.confirmChangeStatus}
onOpenChange={(open) => !open && changeStatusDialogCtrl.closeDialog()}
open={changeStatusDialogCtrl.open}
proformas={changeStatusDialogCtrl.proformas} // ← recibe el status seleccionado
/>
{/* Eliminar */} {/* Eliminar */}
<DeleteProformaDialog <DeleteProformaDialog
isSecondConfirmStep={deleteDialogCtrl.isSecondConfirmStep}
isSubmitting={deleteDialogCtrl.isSubmitting} isSubmitting={deleteDialogCtrl.isSubmitting}
onConfirm={deleteDialogCtrl.confirmDelete} onConfirm={deleteDialogCtrl.confirmDelete}
onOpenChange={(open) => { onOpenChange={(open) => !open && deleteDialogCtrl.closeDialog()}
if (!open) {
deleteDialogCtrl.closeDialog();
}
}}
open={deleteDialogCtrl.open} open={deleteDialogCtrl.open}
targets={deleteDialogCtrl.targets} proformas={deleteDialogCtrl.proformas}
requireSecondConfirm={true}
/> />
</> </>
</AppContent> </AppContent>

View File

@ -4,3 +4,5 @@ export * from "./use-proforma-delete-mutation";
export * from "./use-proforma-get-query"; export * from "./use-proforma-get-query";
export * from "./use-proforma-update-mutation"; export * from "./use-proforma-update-mutation";
export * from "./use-proformas-list-query"; export * from "./use-proformas-list-query";
:

View File

@ -192,16 +192,6 @@
} }
}, },
"components": { "components": {
"delete_proforma_dialog": {
"single_title": "Eliminar proforoma",
"single_description": "",
"second_confirm_single_title": "Confirmar eliminación",
"second_confirm_single_description": "",
"confirm_delete": "Confirmar eliminación",
"deleting": "Eliminando...",
"cancel": "Cancelar",
"continue": "Eliminar"
},
"entity_selector": { "entity_selector": {
"close": "Close", "close": "Close",
"select_entity": "Select entity", "select_entity": "Select entity",

View File

@ -194,18 +194,6 @@
} }
}, },
"components": { "components": {
"delete_proforma_dialog": {
"single_title": "Eliminar proforoma",
"single_description": "",
"second_confirm_single_title": "Confirmar eliminación",
"second_confirm_single_description": "",
"multiple_description": "",
"confirm_delete": "Confirmar eliminación",
"deleting": "Eliminando...",
"cancel": "Cancelar",
"continue": "Eliminar",
"list_item": ""
},
"entity_selector": { "entity_selector": {
"close": "Cerrar", "close": "Cerrar",
"select_entity": "Seleccionar entidad", "select_entity": "Seleccionar entidad",