mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-04 06:18:48 +00:00
Enable "link" column for tables (#6765)
- Have to handle click events cleverly
This commit is contained in:
parent
0cb4e8ec1c
commit
7227670142
@ -17,6 +17,7 @@ import { useMemo, useState } from 'react';
|
|||||||
|
|
||||||
import { api } from '../../App';
|
import { api } from '../../App';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
|
import { cancelEvent } from '../../functions/events';
|
||||||
import { InvenTreeIcon } from '../../functions/icons';
|
import { InvenTreeIcon } from '../../functions/icons';
|
||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
import { PartThumbTable } from '../../tables/part/PartThumbTable';
|
import { PartThumbTable } from '../../tables/part/PartThumbTable';
|
||||||
@ -267,9 +268,8 @@ function ImageActionButtons({
|
|||||||
size="lg"
|
size="lg"
|
||||||
tooltipAlignment="top"
|
tooltipAlignment="top"
|
||||||
onClick={(event: any) => {
|
onClick={(event: any) => {
|
||||||
event?.preventDefault();
|
cancelEvent(event);
|
||||||
event?.stopPropagation();
|
|
||||||
event?.nativeEvent?.stopImmediatePropagation();
|
|
||||||
modals.open({
|
modals.open({
|
||||||
title: <StylishText size="xl">{t`Select Image`}</StylishText>,
|
title: <StylishText size="xl">{t`Select Image`}</StylishText>,
|
||||||
size: 'xxl',
|
size: 'xxl',
|
||||||
@ -288,9 +288,7 @@ function ImageActionButtons({
|
|||||||
size="lg"
|
size="lg"
|
||||||
tooltipAlignment="top"
|
tooltipAlignment="top"
|
||||||
onClick={(event: any) => {
|
onClick={(event: any) => {
|
||||||
event?.preventDefault();
|
cancelEvent(event);
|
||||||
event?.stopPropagation();
|
|
||||||
event?.nativeEvent?.stopImmediatePropagation();
|
|
||||||
modals.open({
|
modals.open({
|
||||||
title: <StylishText size="xl">{t`Upload Image`}</StylishText>,
|
title: <StylishText size="xl">{t`Upload Image`}</StylishText>,
|
||||||
children: (
|
children: (
|
||||||
@ -310,9 +308,7 @@ function ImageActionButtons({
|
|||||||
size="lg"
|
size="lg"
|
||||||
tooltipAlignment="top"
|
tooltipAlignment="top"
|
||||||
onClick={(event: any) => {
|
onClick={(event: any) => {
|
||||||
event?.preventDefault();
|
cancelEvent(event);
|
||||||
event?.stopPropagation();
|
|
||||||
event?.nativeEvent?.stopImmediatePropagation();
|
|
||||||
removeModal(apiPath, setImage);
|
removeModal(apiPath, setImage);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -349,9 +345,7 @@ export function DetailsImage(props: DetailImageProps) {
|
|||||||
}, [props.imageActions]);
|
}, [props.imageActions]);
|
||||||
|
|
||||||
const expandImage = (event: any) => {
|
const expandImage = (event: any) => {
|
||||||
event?.preventDefault();
|
cancelEvent(event);
|
||||||
event?.stopPropagation();
|
|
||||||
event?.nativeEvent?.stopImmediatePropagation();
|
|
||||||
modals.open({
|
modals.open({
|
||||||
children: <ApiImage src={img} />,
|
children: <ApiImage src={img} />,
|
||||||
withCloseButton: false
|
withCloseButton: false
|
||||||
|
6
src/frontend/src/functions/events.tsx
Normal file
6
src/frontend/src/functions/events.tsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// Helper function to cancel event propagation
|
||||||
|
export function cancelEvent(event: any) {
|
||||||
|
event?.preventDefault();
|
||||||
|
event?.stopPropagation();
|
||||||
|
event?.nativeEvent?.stopImmediatePropagation();
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
* Common rendering functions for table column data.
|
* Common rendering functions for table column data.
|
||||||
*/
|
*/
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
|
import { Anchor } from '@mantine/core';
|
||||||
|
|
||||||
import { Thumbnail } from '../components/images/Thumbnail';
|
import { Thumbnail } from '../components/images/Thumbnail';
|
||||||
import { ProgressBar } from '../components/items/ProgressBar';
|
import { ProgressBar } from '../components/items/ProgressBar';
|
||||||
@ -10,6 +11,7 @@ import { TableStatusRenderer } from '../components/render/StatusRenderer';
|
|||||||
import { RenderOwner } from '../components/render/User';
|
import { RenderOwner } from '../components/render/User';
|
||||||
import { formatCurrency, renderDate } from '../defaults/formatters';
|
import { formatCurrency, renderDate } from '../defaults/formatters';
|
||||||
import { ModelType } from '../enums/ModelType';
|
import { ModelType } from '../enums/ModelType';
|
||||||
|
import { cancelEvent } from '../functions/events';
|
||||||
import { TableColumn } from './Column';
|
import { TableColumn } from './Column';
|
||||||
import { ProjectCodeHoverCard } from './TableHoverCard';
|
import { ProjectCodeHoverCard } from './TableHoverCard';
|
||||||
|
|
||||||
@ -55,11 +57,36 @@ export function DescriptionColumn({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LinkColumn(): TableColumn {
|
export function LinkColumn({
|
||||||
|
accessor = 'link'
|
||||||
|
}: {
|
||||||
|
accessor?: string;
|
||||||
|
}): TableColumn {
|
||||||
return {
|
return {
|
||||||
accessor: 'link',
|
accessor: accessor,
|
||||||
sortable: false
|
sortable: false,
|
||||||
// TODO: Custom URL hyperlink renderer?
|
render: (record: any) => {
|
||||||
|
let url = record[accessor];
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Anchor
|
||||||
|
href={url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
onClick={(event: any) => {
|
||||||
|
cancelEvent(event);
|
||||||
|
|
||||||
|
window.open(url, '_blank', 'noopener,noreferrer');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{url}
|
||||||
|
</Anchor>
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import { Menu } from '@mantine/core';
|
|||||||
import { IconCopy, IconDots, IconEdit, IconTrash } from '@tabler/icons-react';
|
import { IconCopy, IconDots, IconEdit, IconTrash } from '@tabler/icons-react';
|
||||||
import { ReactNode, useMemo, useState } from 'react';
|
import { ReactNode, useMemo, useState } from 'react';
|
||||||
|
|
||||||
|
import { cancelEvent } from '../functions/events';
|
||||||
import { notYetImplemented } from '../functions/notifications';
|
import { notYetImplemented } from '../functions/notifications';
|
||||||
|
|
||||||
// Type definition for a table row action
|
// Type definition for a table row action
|
||||||
@ -93,9 +94,7 @@ export function RowActions({
|
|||||||
// Prevent default event handling
|
// Prevent default event handling
|
||||||
// Ref: https://icflorescu.github.io/mantine-datatable/examples/links-or-buttons-inside-clickable-rows-or-cells
|
// Ref: https://icflorescu.github.io/mantine-datatable/examples/links-or-buttons-inside-clickable-rows-or-cells
|
||||||
function openMenu(event: any) {
|
function openMenu(event: any) {
|
||||||
event?.preventDefault();
|
cancelEvent(event);
|
||||||
event?.stopPropagation();
|
|
||||||
event?.nativeEvent?.stopImmediatePropagation();
|
|
||||||
setOpened(!opened);
|
setOpened(!opened);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,9 +117,7 @@ export function RowActions({
|
|||||||
icon={action.icon}
|
icon={action.icon}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
// Prevent clicking on the action from selecting the row itself
|
// Prevent clicking on the action from selecting the row itself
|
||||||
event?.preventDefault();
|
cancelEvent(event);
|
||||||
event?.stopPropagation();
|
|
||||||
event?.nativeEvent?.stopImmediatePropagation();
|
|
||||||
|
|
||||||
if (action.onClick) {
|
if (action.onClick) {
|
||||||
action.onClick();
|
action.onClick();
|
||||||
|
@ -11,6 +11,7 @@ import { YesNoButton } from '../../components/items/YesNoButton';
|
|||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
|
import { cancelEvent } from '../../functions/events';
|
||||||
import {
|
import {
|
||||||
useCreateApiFormModal,
|
useCreateApiFormModal,
|
||||||
useEditApiFormModal
|
useEditApiFormModal
|
||||||
@ -60,9 +61,7 @@ function ParameterCell({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleClick = useCallback((event: any) => {
|
const handleClick = useCallback((event: any) => {
|
||||||
event?.preventDefault();
|
cancelEvent(event);
|
||||||
event?.stopPropagation();
|
|
||||||
event?.nativeEvent?.stopImmediatePropagation();
|
|
||||||
onEdit();
|
onEdit();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ function partTableColumns(): TableColumn[] {
|
|||||||
render: (record: any) =>
|
render: (record: any) =>
|
||||||
formatPriceRange(record.pricing_min, record.pricing_max)
|
formatPriceRange(record.pricing_min, record.pricing_max)
|
||||||
},
|
},
|
||||||
LinkColumn()
|
LinkColumn({})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ export function ManufacturerPartTable({ params }: { params: any }): ReactNode {
|
|||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
DescriptionColumn({}),
|
DescriptionColumn({}),
|
||||||
LinkColumn()
|
LinkColumn({})
|
||||||
];
|
];
|
||||||
}, [params]);
|
}, [params]);
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import { useUserState } from '../../states/UserState';
|
|||||||
import {
|
import {
|
||||||
CurrencyColumn,
|
CurrencyColumn,
|
||||||
LinkColumn,
|
LinkColumn,
|
||||||
|
NoteColumn,
|
||||||
ReferenceColumn,
|
ReferenceColumn,
|
||||||
TargetDateColumn,
|
TargetDateColumn,
|
||||||
TotalPriceColumn
|
TotalPriceColumn
|
||||||
@ -177,11 +178,8 @@ export function PurchaseOrderLineItemTable({
|
|||||||
? RenderStockLocation({ instance: record.destination_detail })
|
? RenderStockLocation({ instance: record.destination_detail })
|
||||||
: '-'
|
: '-'
|
||||||
},
|
},
|
||||||
{
|
NoteColumn(),
|
||||||
accessor: 'notes',
|
LinkColumn({})
|
||||||
title: t`Notes`
|
|
||||||
},
|
|
||||||
LinkColumn()
|
|
||||||
];
|
];
|
||||||
}, [orderId, user]);
|
}, [orderId, user]);
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
LinkColumn(),
|
LinkColumn({}),
|
||||||
NoteColumn(),
|
NoteColumn(),
|
||||||
{
|
{
|
||||||
accessor: 'available',
|
accessor: 'available',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user