diff --git a/src/components/creditNote/CreditNotesTable.tsx b/src/components/creditNote/CreditNotesTable.tsx index 99166dd7a..448ee76ee 100644 --- a/src/components/creditNote/CreditNotesTable.tsx +++ b/src/components/creditNote/CreditNotesTable.tsx @@ -298,15 +298,13 @@ const CreditNotesTable = ({ return actions }} - onRowAction={(creditNote) => { - navigate( - generatePath(CUSTOMER_INVOICE_CREDIT_NOTE_DETAILS_ROUTE, { - customerId: creditNote?.invoice?.customer?.id as string, - invoiceId: creditNote?.invoice?.id as string, - creditNoteId: creditNote?.id as string, - }), - ) - }} + onRowActionLink={(creditNote) => + generatePath(CUSTOMER_INVOICE_CREDIT_NOTE_DETAILS_ROUTE, { + customerId: creditNote?.invoice?.customer?.id as string, + invoiceId: creditNote?.invoice?.id as string, + creditNoteId: creditNote?.id as string, + }) + } columns={[ { key: 'totalAmountCents', diff --git a/src/components/customers/CustomerInvoicesList.tsx b/src/components/customers/CustomerInvoicesList.tsx index ae7b295c9..8181c0856 100644 --- a/src/components/customers/CustomerInvoicesList.tsx +++ b/src/components/customers/CustomerInvoicesList.tsx @@ -173,14 +173,12 @@ export const CustomerInvoicesList: FC = ({ isLoading={isLoading} hasError={hasError} data={invoiceData?.collection ?? []} - onRowAction={({ id }) => - navigate( - generatePath(CUSTOMER_INVOICE_DETAILS_ROUTE, { - customerId, - invoiceId: id, - tab: CustomerInvoiceDetailsTabsOptionsEnum.overview, - }), - ) + onRowActionLink={({ id }) => + generatePath(CUSTOMER_INVOICE_DETAILS_ROUTE, { + customerId, + invoiceId: id, + tab: CustomerInvoiceDetailsTabsOptionsEnum.overview, + }) } placeholder={{ errorState: { diff --git a/src/components/designSystem/Table/Table.tsx b/src/components/designSystem/Table/Table.tsx index 05d60a540..1471e6c5b 100644 --- a/src/components/designSystem/Table/Table.tsx +++ b/src/components/designSystem/Table/Table.tsx @@ -8,6 +8,7 @@ import { TableRowProps, } from '@mui/material' import { MouseEvent, PropsWithChildren, ReactNode, useRef } from 'react' +import { useNavigate } from 'react-router-dom' import { Button, IconName, Popper, Skeleton, Tooltip, Typography } from '~/components/designSystem' import { GenericPlaceholder, GenericPlaceholderProps } from '~/components/GenericPlaceholder' @@ -76,7 +77,7 @@ interface TableProps { emptyState?: Partial errorState?: Partial } - onRowAction?: (item: T) => void + onRowActionLink?: (item: T) => string actionColumn?: (item: T) => Array | null> | ReactNode actionColumnTooltip?: (item: T) => string rowDataTestId?: (item: T) => string @@ -333,7 +334,7 @@ export const Table = ({ containerSize = 48, rowSize = 48, placeholder, - onRowAction, + onRowActionLink, actionColumn, actionColumnTooltip, rowDataTestId, @@ -343,6 +344,7 @@ export const Table = ({ const maxSpaceColumns = countMaxSpaceColumns(filteredColumns) const tableRef = useRef(null) const { translate } = useInternationalization() + const navigate = useNavigate() const { onKeyDown } = useListKeysNavigation({ getElmId: (i) => `${TABLE_ID}-row-${i}`, @@ -350,12 +352,12 @@ export const Table = ({ const item = data.find((dataItem) => dataItem.id === id) if (item) { - onRowAction?.(item) + onRowActionLink?.(item) } }, }) - const isClickable = !!onRowAction && !isLoading + const isClickable = !!onRowActionLink && !isLoading const shouldDisplayActionColumn = !!actionColumn && (data.length > 0 @@ -382,6 +384,8 @@ export const Table = ({ const colSpan = filteredColumns.length + (shouldDisplayActionColumn ? 1 : 0) const handleRowClick = (e: MouseEvent, item: T) => { + if (!onRowActionLink) return + // Prevent row action when clicking on button or link in cell if (e.target instanceof HTMLAnchorElement || e.target instanceof HTMLButtonElement) { return @@ -397,8 +401,17 @@ export const Table = ({ if (e.target instanceof HTMLElement) { const actionColumnButton = e.target.closest('button')?.dataset.id + const hasSideKeyPressed = e.metaKey || e.ctrlKey + + // Make sure anything other than the action column button is clicked if (actionColumnButton !== ACTION_COLUMN_ID) { - onRowAction?.(item) + const link = onRowActionLink(item) + + if (hasSideKeyPressed) { + window.open(link, '_blank') + } else { + navigate(link) + } } } } diff --git a/src/components/invoices/InvoicesList.tsx b/src/components/invoices/InvoicesList.tsx index e5014c5dd..af43a35e5 100644 --- a/src/components/invoices/InvoicesList.tsx +++ b/src/components/invoices/InvoicesList.tsx @@ -416,15 +416,13 @@ const InvoicesList = ({ ), }, ]} - onRowAction={(invoice) => { - navigate( - generatePath(CUSTOMER_INVOICE_DETAILS_ROUTE, { - customerId: invoice?.customer?.id, - invoiceId: invoice.id, - tab: CustomerInvoiceDetailsTabsOptionsEnum.overview, - }), - ) - }} + onRowActionLink={(invoice) => + generatePath(CUSTOMER_INVOICE_DETAILS_ROUTE, { + customerId: invoice?.customer?.id, + invoiceId: invoice.id, + tab: CustomerInvoiceDetailsTabsOptionsEnum.overview, + }) + } placeholder={{ errorState: variables?.searchTerm ? { diff --git a/src/pages/AddOnsList.tsx b/src/pages/AddOnsList.tsx index 99db1b63c..d0dddab99 100644 --- a/src/pages/AddOnsList.tsx +++ b/src/pages/AddOnsList.tsx @@ -109,7 +109,7 @@ const AddOnsList = () => { rowSize={72} isLoading={isLoading} hasError={!!error} - onRowAction={({ id }) => navigate(generatePath(ADD_ON_DETAILS_ROUTE, { addOnId: id }))} + onRowActionLink={({ id }) => generatePath(ADD_ON_DETAILS_ROUTE, { addOnId: id })} rowDataTestId={(addOn) => `${addOn.name}`} columns={[ { diff --git a/src/pages/BillableMetricsList.tsx b/src/pages/BillableMetricsList.tsx index 4ff532433..ff6728f20 100644 --- a/src/pages/BillableMetricsList.tsx +++ b/src/pages/BillableMetricsList.tsx @@ -101,8 +101,8 @@ const BillableMetricsList = () => { rowSize={72} isLoading={isLoading} hasError={!!error} - onRowAction={({ id }) => - navigate(generatePath(UPDATE_BILLABLE_METRIC_ROUTE, { billableMetricId: id })) + onRowActionLink={({ id }) => + generatePath(UPDATE_BILLABLE_METRIC_ROUTE, { billableMetricId: id }) } columns={[ { diff --git a/src/pages/CouponsList.tsx b/src/pages/CouponsList.tsx index e01d7c513..6f5e586ce 100644 --- a/src/pages/CouponsList.tsx +++ b/src/pages/CouponsList.tsx @@ -138,7 +138,7 @@ const CouponsList = () => { rowSize={72} isLoading={isLoading} hasError={!!error} - onRowAction={({ id }) => navigate(generatePath(COUPON_DETAILS_ROUTE, { couponId: id }))} + onRowActionLink={({ id }) => generatePath(COUPON_DETAILS_ROUTE, { couponId: id })} rowDataTestId={(addOn) => `${addOn.name}`} columns={[ { diff --git a/src/pages/CustomersList.tsx b/src/pages/CustomersList.tsx index 120dcada4..23515d7e3 100644 --- a/src/pages/CustomersList.tsx +++ b/src/pages/CustomersList.tsx @@ -1,6 +1,6 @@ import { gql } from '@apollo/client' import { useRef } from 'react' -import { generatePath, useNavigate } from 'react-router-dom' +import { generatePath } from 'react-router-dom' import { AddCustomerDrawer, @@ -56,7 +56,6 @@ gql` ` const CustomersList = () => { - const navigate = useNavigate() const { translate } = useInternationalization() const { hasPermissions } = usePermissions() const { formatTimeOrgaTZ } = useOrganizationInfos() @@ -115,9 +114,7 @@ const CustomersList = () => { default: 16, md: 48, }} - onRowAction={({ id }) => - navigate(generatePath(CUSTOMER_DETAILS_ROUTE, { customerId: id })) - } + onRowActionLink={({ id }) => generatePath(CUSTOMER_DETAILS_ROUTE, { customerId: id })} columns={[ { key: 'displayName', diff --git a/src/pages/PlansList.tsx b/src/pages/PlansList.tsx index d25dbb83d..912abc54d 100644 --- a/src/pages/PlansList.tsx +++ b/src/pages/PlansList.tsx @@ -107,13 +107,11 @@ const PlansList = () => { isLoading={isLoading} hasError={!!error} rowDataTestId={(plan) => `${plan.name}`} - onRowAction={({ id }) => - navigate( - generatePath(PLAN_DETAILS_ROUTE, { - planId: id, - tab: PlanDetailsTabsOptionsEnum.overview, - }), - ) + onRowActionLink={({ id }) => + generatePath(PLAN_DETAILS_ROUTE, { + planId: id, + tab: PlanDetailsTabsOptionsEnum.overview, + }) } columns={[ { diff --git a/src/pages/__devOnly/DesignSystem.tsx b/src/pages/__devOnly/DesignSystem.tsx index 7b99dd845..b9d754ca9 100644 --- a/src/pages/__devOnly/DesignSystem.tsx +++ b/src/pages/__devOnly/DesignSystem.tsx @@ -643,7 +643,7 @@ const DesignSystem = () => { content: (row) => row.date, }, ]} - onRowAction={(item) => alert(`You clicked on ${item.id}`)} + onRowActionLink={(item) => `you clicked on ${item.id}`} actionColumn={(currentItem) => [ currentItem.amount > 1000 ? { @@ -706,7 +706,7 @@ const DesignSystem = () => { ), }, ]} - onRowAction={(item) => alert(`You clicked on ${item.id}`)} + onRowActionLink={(item) => `you clicked on ${item.id}`} /> diff --git a/src/pages/developers/Webhooks.tsx b/src/pages/developers/Webhooks.tsx index 161f08886..a803f407b 100644 --- a/src/pages/developers/Webhooks.tsx +++ b/src/pages/developers/Webhooks.tsx @@ -1,6 +1,6 @@ import { gql } from '@apollo/client' import { useRef, useState } from 'react' -import { generatePath, useNavigate } from 'react-router-dom' +import { generatePath } from 'react-router-dom' import { Button, Table, Tooltip, Typography } from '~/components/designSystem' import { @@ -55,7 +55,6 @@ gql` ` const Webhooks = () => { - const navigate = useNavigate() const { translate } = useInternationalization() const [showOrganizationHmac, setShowOrganizationHmac] = useState(false) const createDialogRef = useRef(null) @@ -208,9 +207,7 @@ const Webhooks = () => { ), }, ]} - onRowAction={({ id }) => { - navigate(generatePath(WEBHOOK_LOGS_ROUTE, { webhookId: id })) - }} + onRowActionLink={({ id }) => generatePath(WEBHOOK_LOGS_ROUTE, { webhookId: id })} actionColumnTooltip={() => translate('text_6256de3bba111e00b3bfa51b')} actionColumn={(webhook) => { return [ diff --git a/src/pages/settings/EmailSettings.tsx b/src/pages/settings/EmailSettings.tsx index aad97f121..0e4f8de81 100644 --- a/src/pages/settings/EmailSettings.tsx +++ b/src/pages/settings/EmailSettings.tsx @@ -88,13 +88,11 @@ const EmailSettings = () => { containerSize={{ default: 0 }} rowSize={72} data={EMAIL_SCENARIOS} - onRowAction={({ setting }) => { - navigate( - generatePath(EMAILS_SCENARIO_CONFIG_ROUTE, { - type: setting, - }), - ) - }} + onRowActionLink={({ setting }) => + generatePath(EMAILS_SCENARIO_CONFIG_ROUTE, { + type: setting, + }) + } columns={[ { key: 'id',