diff --git a/modules/catalogs/src/web/settings/payment-methods/ui/components/payment-method-row-actions.tsx b/modules/catalogs/src/web/settings/payment-methods/ui/components/payment-method-row-actions.tsx
index da6bb337..a17e9a6c 100644
--- a/modules/catalogs/src/web/settings/payment-methods/ui/components/payment-method-row-actions.tsx
+++ b/modules/catalogs/src/web/settings/payment-methods/ui/components/payment-method-row-actions.tsx
@@ -1,6 +1,6 @@
-import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@repo/shadcn-ui/components";
-import { Button, Spinner } from "@repo/shadcn-ui/components";
-import { MoreHorizontalIcon } from "lucide-react";
+import { type RdxRowAction, RdxRowActions } from "@repo/rdx-ui/components";
+import { Spinner } from "@repo/shadcn-ui/components";
+import { PencilIcon, PowerIcon, PowerOffIcon, Trash2Icon } from "lucide-react";
import { useTranslation } from "../../../../i18n";
import type { PaymentMethodListRow } from "../../../../payment-methods/shared";
@@ -30,67 +30,52 @@ export const PaymentMethodRowActions = ({
const toggleDisabled = paymentMethod.isSystem || paymentMethod.isDefault || isTogglingActive;
const deleteDisabled = paymentMethod.isSystem || paymentMethod.isDefault;
+ const primaryActions: RdxRowAction[] = [
+ {
+ id: "edit",
+ label: t("settings.paymentMethods.actions.edit"),
+ icon: ,
+ disabled: editDisabled,
+ disabledReason: editDisabled
+ ? t("settings.paymentMethods.protections.systemEdit")
+ : undefined,
+ onSelect: () => onEdit(paymentMethod),
+ },
+ {
+ id: "toggle-active",
+ label: paymentMethod.isActive
+ ? t("settings.paymentMethods.actions.disable")
+ : t("settings.paymentMethods.actions.enable"),
+ icon: isTogglingActive ? (
+
+ ) : paymentMethod.isActive ? (
+
+ ) : (
+
+ ),
+ disabled: toggleDisabled,
+ disabledReason: toggleDisabled ? activeDisabledReason : undefined,
+ onSelect: () => onToggleActive(paymentMethod),
+ },
+ ];
+
+ const overflowActions: RdxRowAction[] = [
+ {
+ id: "delete",
+ label: t("settings.paymentMethods.actions.delete"),
+ icon: ,
+ destructive: true,
+ disabled: deleteDisabled,
+ disabledReason: deleteDisabled ? deleteDisabledReason : undefined,
+ onSelect: () => onDelete(paymentMethod),
+ },
+ ];
+
return (
-
-
-
-
-
-
-
-
-
- }
- />
- onDelete(paymentMethod)}
- title={deleteDisabled ? deleteDisabledReason : undefined}
- variant="destructive"
- >
- {t("settings.paymentMethods.actions.delete")}
-
- }
- />
-
-
+
);
};
diff --git a/modules/catalogs/src/web/settings/payment-methods/ui/pages/payment-methods-settings-page.tsx b/modules/catalogs/src/web/settings/payment-methods/ui/pages/payment-methods-settings-page.tsx
index cbcd789f..325d1f2c 100644
--- a/modules/catalogs/src/web/settings/payment-methods/ui/pages/payment-methods-settings-page.tsx
+++ b/modules/catalogs/src/web/settings/payment-methods/ui/pages/payment-methods-settings-page.tsx
@@ -135,7 +135,7 @@ export const PaymentMethodsSettingsPage = () => {
id={`payment-method-default-${paymentMethod.id}`}
value={paymentMethod.id}
/>
-
+
diff --git a/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/proforma-row-actions.tsx b/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/proforma-row-actions.tsx
new file mode 100644
index 00000000..345d3111
--- /dev/null
+++ b/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/proforma-row-actions.tsx
@@ -0,0 +1,254 @@
+import { type RdxRowAction, RdxRowActions } from "@repo/rdx-ui/components";
+import { Spinner } from "@repo/shadcn-ui/components";
+import {
+ CalendarSyncIcon,
+ CopyIcon,
+ ExternalLinkIcon,
+ EyeIcon,
+ FileDownIcon,
+ FileTextIcon,
+ FolderArchiveIcon,
+ PencilIcon,
+ RefreshCwIcon,
+ Trash2Icon,
+ Undo2Icon,
+} from "lucide-react";
+import type { ComponentType } from "react";
+
+import { useTranslation } from "../../../../../i18n";
+import {
+ PROFORMA_STATUS,
+ PROFORMA_STATUS_TRANSITIONS,
+ type ProformaListRow,
+ type ProformaStatus,
+} from "../../../../shared";
+import type { ProformaListScope } from "../../../types/proforma-list-filters";
+
+export interface ProformaRowActionHandlers {
+ onViewClick?: (proforma: ProformaListRow) => void;
+ onEditClick?: (proforma: ProformaListRow) => void;
+ onIssueClick?: (proforma: ProformaListRow) => void;
+ onArchiveClick?: (proforma: ProformaListRow) => void;
+ onDuplicateClick?: (proforma: ProformaListRow) => void;
+ onCreateRecurringClick?: (proforma: ProformaListRow) => void;
+ onUnarchiveClick?: (proforma: ProformaListRow) => void;
+ onDeleteClick?: (proforma: ProformaListRow) => void;
+ onChangeStatusClick?: (proforma: ProformaListRow, nextStatus: ProformaStatus) => void;
+ onLinkedInvoiceClick?: (proforma: ProformaListRow) => void;
+ onDownloadPdf?: (proforma: ProformaListRow) => void;
+ pdfDownloadingId?: string | null;
+ isPdfDownloading?: boolean;
+}
+
+interface ProformaRowActionsProps {
+ proforma: ProformaListRow;
+ scope: ProformaListScope;
+ actionHandlers?: ProformaRowActionHandlers;
+}
+
+const renderActionIcon = (Icon: ComponentType<{ className?: string }>, loading?: boolean) =>
+ loading ?
:
;
+
+// biome-ignore lint/complexity/noExcessiveCognitiveComplexity:
+export function ProformaRowActions({
+ proforma,
+ scope,
+ actionHandlers = {},
+}: ProformaRowActionsProps) {
+ const { t } = useTranslation();
+ const isDraft = proforma.status === PROFORMA_STATUS.DRAFT;
+ const isIssued = proforma.status === PROFORMA_STATUS.ISSUED;
+ const isApproved = proforma.status === PROFORMA_STATUS.APPROVED;
+ const isNormalScope = scope === "normal";
+ const isArchivedScope = scope === "archived";
+ const isDeletedScope = scope === "deleted";
+ const isArchivable =
+ isNormalScope &&
+ !proforma.isArchived &&
+ (proforma.status === PROFORMA_STATUS.DRAFT || proforma.status === PROFORMA_STATUS.REJECTED);
+ const isUnarchivable =
+ isArchivedScope &&
+ proforma.isArchived &&
+ (proforma.status === PROFORMA_STATUS.DRAFT || proforma.status === PROFORMA_STATUS.REJECTED);
+ const availableTransitions = isNormalScope
+ ? (PROFORMA_STATUS_TRANSITIONS[proforma.status as ProformaStatus] ?? [])
+ : [];
+
+ const isPDFLoading =
+ actionHandlers.isPdfDownloading && actionHandlers.pdfDownloadingId === proforma.id;
+ const nextTransition = availableTransitions[0] ?? null;
+
+ const handleView = () => actionHandlers.onViewClick?.(proforma);
+ const handleEdit = () => actionHandlers.onEditClick?.(proforma);
+ const handleDuplicate = () => actionHandlers.onDuplicateClick?.(proforma);
+ const handleCreateRecurring = () => actionHandlers.onCreateRecurringClick?.(proforma);
+ const handleArchive = () => actionHandlers.onArchiveClick?.(proforma);
+ const handleUnarchive = () => actionHandlers.onUnarchiveClick?.(proforma);
+ const handleIssue = () => actionHandlers.onIssueClick?.(proforma);
+ const handleDownloadPdf = () => actionHandlers.onDownloadPdf?.(proforma);
+ const handleDelete = () => actionHandlers.onDeleteClick?.(proforma);
+ const handleChangeStatus = () => {
+ if (!nextTransition) {
+ return;
+ }
+
+ actionHandlers.onChangeStatusClick?.(proforma, nextTransition);
+ };
+
+ const getScopeReason = () => {
+ if (isArchivedScope) {
+ return t("pages.proformas.list.actions.disabled_reasons.archived_scope");
+ }
+
+ if (isDeletedScope) {
+ return t("pages.proformas.list.actions.disabled_reasons.deleted_scope");
+ }
+
+ return undefined;
+ };
+
+ const visibleActions: RdxRowAction[] = [
+ {
+ id: "view",
+ label: t("pages.proformas.list.actions.view"),
+ icon: renderActionIcon(EyeIcon),
+ disabled: !actionHandlers.onViewClick || isDeletedScope,
+ disabledReason: isDeletedScope
+ ? t("pages.proformas.list.actions.disabled_reasons.deleted_scope")
+ : undefined,
+ onSelect: handleView,
+ },
+ {
+ id: "edit",
+ label: t("pages.proformas.list.actions.edit"),
+ icon: renderActionIcon(PencilIcon),
+ disabled: !(actionHandlers.onEditClick && isNormalScope) || isIssued,
+ disabledReason: isNormalScope
+ ? isIssued
+ ? t("pages.proformas.list.actions.disabled_reasons.edit_issued")
+ : undefined
+ : getScopeReason(),
+ onSelect: handleEdit,
+ },
+ ];
+
+ const menuActions: RdxRowAction[] = [
+ {
+ id: "linked-invoice",
+ label: t("pages.proformas.list.actions.view_linked_invoice"),
+ icon: renderActionIcon(ExternalLinkIcon),
+ disabled: !(isIssued && proforma.linkedInvoiceId),
+ disabledReason:
+ isIssued && proforma.linkedInvoiceId
+ ? undefined
+ : t("pages.proformas.list.actions.disabled_reasons.linked_invoice_unavailable"),
+ onSelect: () => {
+ if (proforma.linkedInvoiceId) {
+ window.location.href = "/customer-invoices";
+ }
+ },
+ },
+ {
+ id: "change-status",
+ label: t("pages.proformas.list.actions.change_status"),
+ icon: renderActionIcon(RefreshCwIcon),
+ disabled:
+ !(actionHandlers.onChangeStatusClick && isNormalScope && nextTransition) || isIssued,
+ disabledReason: isNormalScope
+ ? isIssued
+ ? t("pages.proformas.list.actions.disabled_reasons.status_issued")
+ : nextTransition
+ ? undefined
+ : t("proformas.change_proforma_status_dialog.empty_available_statuses")
+ : getScopeReason(),
+ onSelect: handleChangeStatus,
+ },
+ {
+ id: "issue",
+ label: t("pages.proformas.list.actions.issue"),
+ icon: renderActionIcon(FileTextIcon),
+ disabled: !(actionHandlers.onIssueClick && isNormalScope && isApproved) || isIssued,
+ disabledReason: isNormalScope
+ ? isApproved
+ ? undefined
+ : t("proformas.issue_proforma_dialog.not_allowed_description")
+ : getScopeReason(),
+ onSelect: handleIssue,
+ },
+ {
+ id: "duplicate",
+ label: t("pages.proformas.list.actions.duplicate"),
+ icon: renderActionIcon(CopyIcon),
+ disabled: !actionHandlers.onDuplicateClick || isDeletedScope,
+ disabledReason: isDeletedScope
+ ? t("pages.proformas.list.actions.disabled_reasons.deleted_scope")
+ : undefined,
+ onSelect: handleDuplicate,
+ },
+ {
+ id: "create-recurring",
+ label: t("pages.proformas.list.actions.create_recurring"),
+ icon: renderActionIcon(CalendarSyncIcon),
+ disabled: !(actionHandlers.onCreateRecurringClick && isNormalScope),
+ disabledReason: isNormalScope ? undefined : getScopeReason(),
+ onSelect: handleCreateRecurring,
+ },
+ {
+ id: "archive",
+ label: t("pages.proformas.list.actions.archive"),
+ icon: renderActionIcon(FolderArchiveIcon),
+ disabled: !(actionHandlers.onArchiveClick && isArchivable),
+ disabledReason: actionHandlers.onArchiveClick
+ ? isNormalScope
+ ? t("proformas.archive.error_conflict_message")
+ : getScopeReason()
+ : undefined,
+ onSelect: handleArchive,
+ },
+ {
+ id: "unarchive",
+ label: t("pages.proformas.list.actions.unarchive"),
+ icon: renderActionIcon(Undo2Icon),
+ disabled: !(actionHandlers.onUnarchiveClick && isUnarchivable),
+ disabledReason: actionHandlers.onUnarchiveClick
+ ? isArchivedScope
+ ? t("proformas.unarchive.error_conflict_message")
+ : t("pages.proformas.list.actions.disabled_reasons.archived_only")
+ : undefined,
+ onSelect: handleUnarchive,
+ },
+ {
+ id: "download-pdf",
+ label: t("pages.proformas.list.actions.download_pdf"),
+ icon: renderActionIcon(FileDownIcon, isPDFLoading),
+ disabled: Boolean(!actionHandlers.onDownloadPdf || isDeletedScope || isPDFLoading),
+ disabledReason: isDeletedScope
+ ? t("pages.proformas.list.actions.disabled_reasons.deleted_scope")
+ : isPDFLoading
+ ? t("pages.proformas.list.actions.disabled_reasons.operation_in_progress")
+ : undefined,
+ onSelect: handleDownloadPdf,
+ },
+ {
+ id: "delete",
+ label: t("pages.proformas.list.actions.delete"),
+ icon: renderActionIcon(Trash2Icon),
+ destructive: true,
+ disabled: !actionHandlers.onDeleteClick || isDeletedScope || !isDraft,
+ disabledReason: isDeletedScope
+ ? t("pages.proformas.list.actions.disabled_reasons.deleted_scope")
+ : isDraft
+ ? undefined
+ : t("proformas.delete_proforma_dialog.error_conflict_message"),
+ onSelect: handleDelete,
+ },
+ ];
+
+ return (
+
+ );
+}
diff --git a/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.test.tsx b/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.test.tsx
index 9736c495..da68a604 100644
--- a/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.test.tsx
+++ b/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.test.tsx
@@ -1,14 +1,15 @@
import assert from "node:assert/strict";
import test from "node:test";
-import { RdxRowActions, type RdxRowActionsProps } from "@repo/rdx-ui/components";
import type { CellContext } from "@tanstack/react-table";
+import type { ComponentProps, ReactElement } from "react";
import { isValidElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import type { ProformaListRow } from "../../../../shared";
import { PROFORMA_STATUS } from "../../../../shared";
+import { ProformaRowActions } from "./proforma-row-actions";
import { useProformasGridColumns } from "./use-proforma-grid-columns";
const proformaFixture: ProformaListRow = {
@@ -50,17 +51,21 @@ const proformaFixture: ProformaListRow = {
linkedInvoiceId: null,
};
-const getRowActionsProps = (
+const getRowActionsNode = (
scope: Parameters[0],
actionHandlers: Parameters[1] = {}
-): RdxRowActionsProps => {
+): ReactElement> => {
let cellNode: unknown = null;
const Harness = () => {
const columns = useProformasGridColumns(scope, actionHandlers);
const actionsColumn = columns.find((column) => column.id === "actions");
- cellNode = actionsColumn?.cell?.({
+ const cell = actionsColumn?.cell as
+ | ((context: CellContext) => ReactElement)
+ | undefined;
+
+ cellNode = cell?.({
row: { original: proformaFixture },
} as unknown as CellContext);
@@ -70,87 +75,32 @@ const getRowActionsProps = (
renderToStaticMarkup();
if (!isValidElement(cellNode)) {
- throw new Error("Expected RdxRowActions cell");
+ throw new Error("Expected ProformaRowActions cell");
}
- assert.equal(cellNode.type, RdxRowActions);
+ assert.equal(cellNode.type, ProformaRowActions);
- return cellNode.props as RdxRowActionsProps;
+ return cellNode as ReactElement>;
};
-test("mantiene ver y editar como acciones visibles de referencia", () => {
- const props = getRowActionsProps("normal", {
+test("delegates the action cell to ProformaRowActions", () => {
+ const handlers = {
onEditClick: () => undefined,
onViewClick: () => undefined,
- });
+ };
+ const node = getRowActionsNode("normal", handlers);
- assert.deepEqual(
- props.primaryActions?.map((action) => action.id),
- ["view", "edit"]
- );
- assert.ok(["Más acciones", "common.more_actions"].includes(props.overflowLabel));
+ assert.equal(node.props.proforma, proformaFixture);
+ assert.equal(node.props.scope, "normal");
+ assert.equal(node.props.actionHandlers, handlers);
});
-test("mantiene las destructivas en overflow y conserva disabled", () => {
- const props = getRowActionsProps("normal", {
+test("preserves the supplied handlers for archived and normal scopes", () => {
+ const handlers = {
+ onCreateRecurringClick: () => undefined,
onDeleteClick: () => undefined,
- });
+ };
- const deleteAction = props.overflowActions?.find((action) => action.id === "delete");
- const viewAction = props.primaryActions?.find((action) => action.id === "view");
-
- assert.ok(deleteAction);
- assert.equal(deleteAction?.destructive, true);
- assert.equal(deleteAction?.disabled, false);
- assert.equal(viewAction?.disabled, true);
-});
-
-test("preserva callbacks de view, edit, crear recurrencia y delete", () => {
- let didView = false;
- let didEdit = false;
- let didCreateRecurring = false;
- let didDelete = false;
-
- const props = getRowActionsProps("normal", {
- onCreateRecurringClick: () => {
- didCreateRecurring = true;
- },
- onDeleteClick: () => {
- didDelete = true;
- },
- onEditClick: () => {
- didEdit = true;
- },
- onViewClick: () => {
- didView = true;
- },
- });
-
- props.primaryActions?.find((action) => action.id === "view")?.onSelect();
- props.primaryActions?.find((action) => action.id === "edit")?.onSelect();
- props.overflowActions?.find((action) => action.id === "create-recurring")?.onSelect();
- props.overflowActions?.find((action) => action.id === "delete")?.onSelect();
-
- assert.equal(didView, true);
- assert.equal(didEdit, true);
- assert.equal(didCreateRecurring, true);
- assert.equal(didDelete, true);
-});
-
-test("solo permite crear recurrencia desde el listado normal", () => {
- const normalProps = getRowActionsProps("normal", {
- onCreateRecurringClick: () => undefined,
- });
- const archivedProps = getRowActionsProps("archived", {
- onCreateRecurringClick: () => undefined,
- });
-
- assert.equal(
- normalProps.overflowActions?.find((action) => action.id === "create-recurring")?.disabled,
- false
- );
- assert.equal(
- archivedProps.overflowActions?.find((action) => action.id === "create-recurring")?.disabled,
- true
- );
+ assert.equal(getRowActionsNode("normal", handlers).props.actionHandlers, handlers);
+ assert.equal(getRowActionsNode("archived", handlers).props.actionHandlers, handlers);
});
diff --git a/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.tsx b/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.tsx
index 7afa405d..165b24ec 100644
--- a/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.tsx
+++ b/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.tsx
@@ -1,62 +1,20 @@
import { EmptyCellValue } from "@erp/core/components";
-import { DataTableColumnHeader, type RdxRowAction, RdxRowActions } from "@repo/rdx-ui/components";
+import { DataTableColumnHeader } from "@repo/rdx-ui/components";
import { DateHelper } from "@repo/rdx-utils";
-import { Checkbox, Spinner } from "@repo/shadcn-ui/components";
+import { Checkbox } from "@repo/shadcn-ui/components";
import type { ColumnDef } from "@tanstack/react-table";
-import {
- CalendarSyncIcon,
- CopyIcon,
- ExternalLinkIcon,
- EyeIcon,
- FileDownIcon,
- FileTextIcon,
- FolderArchiveIcon,
- PencilIcon,
- RefreshCwIcon,
- Trash2Icon,
- Undo2Icon,
-} from "lucide-react";
-import type { ComponentType } from "react";
import * as React from "react";
import { useTranslation } from "../../../../../i18n";
-import {
- PROFORMA_STATUS,
- PROFORMA_STATUS_TRANSITIONS,
- type ProformaListRow,
- type ProformaStatus,
-} from "../../../../shared";
+import type { ProformaListRow } from "../../../../shared";
import type { ProformaListScope } from "../../../types/proforma-list-filters";
import { ProformaStatusBadge } from "../../components";
-type GridActionHandlers = {
- onViewClick?: (proforma: ProformaListRow) => void;
- onEditClick?: (proforma: ProformaListRow) => void;
- onIssueClick?: (proforma: ProformaListRow) => void;
- onArchiveClick?: (proforma: ProformaListRow) => void;
- onDuplicateClick?: (proforma: ProformaListRow) => void;
- onCreateRecurringClick?: (proforma: ProformaListRow) => void;
- onUnarchiveClick?: (proforma: ProformaListRow) => void;
- onDeleteClick?: (proforma: ProformaListRow) => void;
- onChangeStatusClick?: (proforma: ProformaListRow, nextStatus: ProformaStatus) => void;
- onLinkedInvoiceClick?: (proforma: ProformaListRow) => void;
- getNextStatus?: (proforma: ProformaListRow) => ProformaStatus | null;
-
- canIssue?: (proforma: ProformaListRow) => boolean;
- canEdit?: (proforma: ProformaListRow) => boolean;
- canDelete?: (proforma: ProformaListRow) => boolean;
-
- onDownloadPdf?: (proforma: ProformaListRow) => void;
- pdfDownloadingId?: string | null;
- isPdfDownloading?: boolean;
-};
-
-const renderActionIcon = (Icon: ComponentType<{ className?: string }>, loading?: boolean) =>
- loading ? : ;
+import { type ProformaRowActionHandlers, ProformaRowActions } from "./proforma-row-actions";
export function useProformasGridColumns(
scope: ProformaListScope,
- actionHandlers: GridActionHandlers = {}
+ actionHandlers: ProformaRowActionHandlers = {}
): ColumnDef[] {
const { t } = useTranslation();
@@ -280,207 +238,13 @@ export function useProformasGridColumns(
header: "Acciones",
enableSorting: false,
- cell: ({ row }) => {
- const proforma = row.original;
- const isDraft = proforma.status === PROFORMA_STATUS.DRAFT;
- const isIssued = proforma.status === PROFORMA_STATUS.ISSUED;
- const isApproved = proforma.status === PROFORMA_STATUS.APPROVED;
- const isNormalScope = scope === "normal";
- const isArchivedScope = scope === "archived";
- const isDeletedScope = scope === "deleted";
- const isArchivable =
- isNormalScope &&
- !proforma.isArchived &&
- (proforma.status === PROFORMA_STATUS.DRAFT ||
- proforma.status === PROFORMA_STATUS.REJECTED);
- const isUnarchivable =
- isArchivedScope &&
- proforma.isArchived &&
- (proforma.status === PROFORMA_STATUS.DRAFT ||
- proforma.status === PROFORMA_STATUS.REJECTED);
- const availableTransitions = isNormalScope
- ? (PROFORMA_STATUS_TRANSITIONS[proforma.status as ProformaStatus] ?? [])
- : [];
-
- const isPDFLoading =
- actionHandlers.isPdfDownloading && actionHandlers.pdfDownloadingId === proforma.id;
- const nextTransition = availableTransitions[0] ?? null;
-
- const handleView = () => actionHandlers.onViewClick?.(proforma);
- const handleEdit = () => actionHandlers.onEditClick?.(proforma);
- const handleDuplicate = () => actionHandlers.onDuplicateClick?.(proforma);
- const handleCreateRecurring = () => actionHandlers.onCreateRecurringClick?.(proforma);
- const handleArchive = () => actionHandlers.onArchiveClick?.(proforma);
- const handleUnarchive = () => actionHandlers.onUnarchiveClick?.(proforma);
- const handleIssue = () => actionHandlers.onIssueClick?.(proforma);
- const handleDownloadPdf = () => actionHandlers.onDownloadPdf?.(proforma);
- const handleDelete = () => actionHandlers.onDeleteClick?.(proforma);
- const handleChangeStatus = () => {
- if (!nextTransition) {
- return;
- }
-
- actionHandlers.onChangeStatusClick?.(proforma, nextTransition);
- };
-
- const getScopeReason = () => {
- if (isArchivedScope) {
- return t("pages.proformas.list.actions.disabled_reasons.archived_scope");
- }
-
- if (isDeletedScope) {
- return t("pages.proformas.list.actions.disabled_reasons.deleted_scope");
- }
-
- return undefined;
- };
-
- const visibleActions: RdxRowAction[] = [
- {
- id: "view",
- label: t("pages.proformas.list.actions.view"),
- icon: renderActionIcon(EyeIcon),
- disabled: !actionHandlers.onViewClick || isDeletedScope,
- disabledReason: isDeletedScope
- ? t("pages.proformas.list.actions.disabled_reasons.deleted_scope")
- : undefined,
- onSelect: handleView,
- },
- {
- id: "edit",
- label: t("pages.proformas.list.actions.edit"),
- icon: renderActionIcon(PencilIcon),
- disabled: !(actionHandlers.onEditClick && isNormalScope) || isIssued,
- disabledReason: isNormalScope
- ? isIssued
- ? t("pages.proformas.list.actions.disabled_reasons.edit_issued")
- : undefined
- : getScopeReason(),
- onSelect: handleEdit,
- },
- ];
-
- const menuActions: RdxRowAction[] = [
- {
- id: "linked-invoice",
- label: t("pages.proformas.list.actions.view_linked_invoice"),
- icon: renderActionIcon(ExternalLinkIcon),
- disabled: !(isIssued && proforma.linkedInvoiceId),
- disabledReason:
- isIssued && proforma.linkedInvoiceId
- ? undefined
- : t("pages.proformas.list.actions.disabled_reasons.linked_invoice_unavailable"),
- onSelect: () => {
- if (proforma.linkedInvoiceId) {
- window.location.href = "/customer-invoices";
- }
- },
- },
- {
- id: "change-status",
- label: t("pages.proformas.list.actions.change_status"),
- icon: renderActionIcon(RefreshCwIcon),
- disabled:
- !(actionHandlers.onChangeStatusClick && isNormalScope && nextTransition) ||
- isIssued,
- disabledReason: isNormalScope
- ? isIssued
- ? t("pages.proformas.list.actions.disabled_reasons.status_issued")
- : nextTransition
- ? undefined
- : t("proformas.change_proforma_status_dialog.empty_available_statuses")
- : getScopeReason(),
- onSelect: handleChangeStatus,
- },
- {
- id: "issue",
- label: t("pages.proformas.list.actions.issue"),
- icon: renderActionIcon(FileTextIcon),
- disabled: !(actionHandlers.onIssueClick && isNormalScope && isApproved) || isIssued,
- disabledReason: isNormalScope
- ? isApproved
- ? undefined
- : t("proformas.issue_proforma_dialog.not_allowed_description")
- : getScopeReason(),
- onSelect: handleIssue,
- },
- {
- id: "duplicate",
- label: t("pages.proformas.list.actions.duplicate"),
- icon: renderActionIcon(CopyIcon),
- disabled: !actionHandlers.onDuplicateClick || isDeletedScope,
- disabledReason: isDeletedScope
- ? t("pages.proformas.list.actions.disabled_reasons.deleted_scope")
- : undefined,
- onSelect: handleDuplicate,
- },
- {
- id: "create-recurring",
- label: t("pages.proformas.list.actions.create_recurring"),
- icon: renderActionIcon(CalendarSyncIcon),
- disabled: !(actionHandlers.onCreateRecurringClick && isNormalScope),
- disabledReason: isNormalScope ? undefined : getScopeReason(),
- onSelect: handleCreateRecurring,
- },
- {
- id: "archive",
- label: t("pages.proformas.list.actions.archive"),
- icon: renderActionIcon(FolderArchiveIcon),
- disabled: !(actionHandlers.onArchiveClick && isArchivable),
- disabledReason: actionHandlers.onArchiveClick
- ? isNormalScope
- ? t("proformas.archive.error_conflict_message")
- : getScopeReason()
- : undefined,
- onSelect: handleArchive,
- },
- {
- id: "unarchive",
- label: t("pages.proformas.list.actions.unarchive"),
- icon: renderActionIcon(Undo2Icon),
- disabled: !(actionHandlers.onUnarchiveClick && isUnarchivable),
- disabledReason: actionHandlers.onUnarchiveClick
- ? isArchivedScope
- ? t("proformas.unarchive.error_conflict_message")
- : t("pages.proformas.list.actions.disabled_reasons.archived_only")
- : undefined,
- onSelect: handleUnarchive,
- },
- {
- id: "download-pdf",
- label: t("pages.proformas.list.actions.download_pdf"),
- icon: renderActionIcon(FileDownIcon, isPDFLoading),
- disabled: Boolean(!actionHandlers.onDownloadPdf || isDeletedScope || isPDFLoading),
- disabledReason: isDeletedScope
- ? t("pages.proformas.list.actions.disabled_reasons.deleted_scope")
- : isPDFLoading
- ? t("pages.proformas.list.actions.disabled_reasons.operation_in_progress")
- : undefined,
- onSelect: handleDownloadPdf,
- },
- {
- id: "delete",
- label: t("pages.proformas.list.actions.delete"),
- icon: renderActionIcon(Trash2Icon),
- destructive: true,
- disabled: !actionHandlers.onDeleteClick || isDeletedScope || !isDraft,
- disabledReason: isDeletedScope
- ? t("pages.proformas.list.actions.disabled_reasons.deleted_scope")
- : isDraft
- ? undefined
- : t("proformas.delete_proforma_dialog.error_conflict_message"),
- onSelect: handleDelete,
- },
- ];
-
- return (
-
- );
- },
+ cell: ({ row }) => (
+
+ ),
},
],
[t, actionHandlers, scope]