diff --git a/src/components/Datagrid/Datagrid.tsx b/src/components/Datagrid/Datagrid.tsx index a45d7d8a8..7585662e3 100644 --- a/src/components/Datagrid/Datagrid.tsx +++ b/src/components/Datagrid/Datagrid.tsx @@ -1,5 +1,6 @@ import "@glideapps/glide-data-grid/dist/index.css"; +import useNavigator from "@dashboard/hooks/useNavigator"; import { usePreventHistoryBack } from "@dashboard/hooks/usePreventHistoryBack"; import DataEditor, { DataEditorProps, @@ -94,6 +95,7 @@ export interface DatagridProps { freezeColumns?: DataEditorProps["freezeColumns"]; verticalBorder?: DataEditorProps["verticalBorder"]; columnSelect?: DataEditorProps["columnSelect"]; + rowAnchor?: (item: Item) => string; } export const Datagrid: React.FC = ({ @@ -120,6 +122,7 @@ export const Datagrid: React.FC = ({ onColumnMoved, onColumnResize, loading, + rowAnchor, hasRowHover = false, ...datagridProps }): ReactElement => { @@ -129,6 +132,9 @@ export const Datagrid: React.FC = ({ const editor = useRef(); const customRenderers = useCustomCellRenderers(); + const hackARef = useRef(null); + const navigate = useNavigator(); + const { scrolledToRight, scroller } = useScrollRight(); const defualtColumnPickerProps = getDefultColumnPickerProps( @@ -227,8 +233,25 @@ export const Datagrid: React.FC = ({ if (hasRowHover) { setHoverRow(args.kind !== "cell" ? undefined : args.location[1]); } + + // the code below is responsible for adding native element when hovering over rows in the datagrid + // this makes it possible to open links in a new tab and copy them + if (args.kind !== "cell" || !hackARef.current || !rowAnchor) { + return; + } + const href = rowAnchor(args.location); + + if (!href) { + return; + } + + hackARef.current.style.left = `${window.scrollX + args.bounds.x}px`; + hackARef.current.style.width = `${args.bounds.width}px`; + hackARef.current.style.top = `${window.scrollY + args.bounds.y}px`; + hackARef.current.style.height = `${args.bounds.height}px`; + hackARef.current.href = href; }, - [hasRowHover], + [hasRowHover, rowAnchor], ); const handleGridSelectionChange = (gridSelection: GridSelection) => { @@ -487,6 +510,16 @@ export const Datagrid: React.FC = ({ bounds={tooltip?.bounds} title={tooltip?.title} /> + { + e.preventDefault(); + navigate(e.currentTarget.pathname); + }} + /> ); }; diff --git a/src/orders/components/OrderListDatagrid/OrderListDatagrid.tsx b/src/orders/components/OrderListDatagrid/OrderListDatagrid.tsx index c4377b42f..b4184b517 100644 --- a/src/orders/components/OrderListDatagrid/OrderListDatagrid.tsx +++ b/src/orders/components/OrderListDatagrid/OrderListDatagrid.tsx @@ -22,7 +22,8 @@ interface OrderListDatagridProps extends ListProps, SortPage { orders: RelayToFlat; - onRowClick: (id: string) => void; + onRowClick?: (id: string) => void; + rowAnchor?: (id: string) => string; hasRowHover?: boolean; } @@ -35,6 +36,7 @@ export const OrderListDatagrid: React.FC = ({ sort, onRowClick, hasRowHover, + rowAnchor, }) => { const intl = useIntl(); const datagrid = useDatagridChangeState(); @@ -65,12 +67,27 @@ export const OrderListDatagrid: React.FC = ({ const handleRowClick = useCallback( ([_, row]: Item) => { + if (!onRowClick) { + return; + } + const rowData = orders[row]; onRowClick(rowData.id); }, [onRowClick, orders], ); + const handleRowAnchor = useCallback( + ([, row]: Item) => { + if (!rowAnchor) { + return; + } + const rowData = orders[row]; + return rowAnchor(rowData.id); + }, + [rowAnchor, orders], + ); + const getCellContent = useGetCellContent({ columns, orders, @@ -113,6 +130,7 @@ export const OrderListDatagrid: React.FC = ({ )} fullScreenTitle={intl.formatMessage(messages.orders)} onRowClick={handleRowClick} + rowAnchor={handleRowAnchor} /> diff --git a/src/orders/components/OrderListPage/OrderListPage.tsx b/src/orders/components/OrderListPage/OrderListPage.tsx index f81db8eeb..0567e00ae 100644 --- a/src/orders/components/OrderListPage/OrderListPage.tsx +++ b/src/orders/components/OrderListPage/OrderListPage.tsx @@ -12,7 +12,6 @@ import { useDevModeContext } from "@dashboard/components/DevModePanel/hooks"; import { FilterPresetsSelect } from "@dashboard/components/FilterPresetsSelect"; import { ListPageLayout } from "@dashboard/components/Layouts"; import { OrderListQuery, RefreshLimitsQuery } from "@dashboard/graphql"; -import useNavigator from "@dashboard/hooks/useNavigator"; import { sectionNames } from "@dashboard/intl"; import { orderMessages } from "@dashboard/orders/messages"; import { DevModeQuery } from "@dashboard/orders/queries"; @@ -87,7 +86,6 @@ const OrderListPage: React.FC = ({ }) => { const intl = useIntl(); const classes = useStyles({}); - const navigate = useNavigator(); const filterStructure = createFilterStructure(intl, filterOpts); const limitsReached = isLimitReached(limits, "orders"); const [isFilterPresetOpen, setFilterPresetOpen] = useState(false); @@ -221,9 +219,7 @@ const OrderListPage: React.FC = ({ { - navigate(orderUrl(id)); - }} + rowAnchor={orderUrl} /> diff --git a/src/products/components/ProductListDatagrid/ProductListDatagrid.tsx b/src/products/components/ProductListDatagrid/ProductListDatagrid.tsx index cefd5cec2..bf8339b9d 100644 --- a/src/products/components/ProductListDatagrid/ProductListDatagrid.tsx +++ b/src/products/components/ProductListDatagrid/ProductListDatagrid.tsx @@ -49,7 +49,8 @@ interface ProductListDatagridProps activeAttributeSortId: string; gridAttributes: RelayToFlat; products: RelayToFlat; - onRowClick: (id: string) => void; + onRowClick?: (id: string) => void; + rowAnchor?: (id: string) => string; columnQuery: string; availableInGridAttributes: RelayToFlat< SearchAvailableInGridAttributesQuery["availableInGrid"] @@ -80,6 +81,7 @@ export const ProductListDatagrid: React.FC = ({ activeAttributeSortId, filterDependency, hasRowHover, + rowAnchor, }) => { const intl = useIntl(); const searchProductType = useSearchProductTypes(); @@ -185,12 +187,26 @@ export const ProductListDatagrid: React.FC = ({ const handleRowClick = useCallback( ([_, row]: Item) => { + if (!onRowClick) { + return; + } const rowData = products[row]; onRowClick(rowData.id); }, [onRowClick, products], ); + const handleRowAnchor = useCallback( + ([, row]: Item) => { + if (!rowAnchor) { + return; + } + const rowData = products[row]; + return rowAnchor(rowData.id); + }, + [rowAnchor, products], + ); + const handleGetColumnTooltipContent = useCallback( (colIndex: number): string => { const { columnName } = getColumnMetadata(columns[colIndex].id); @@ -245,6 +261,7 @@ export const ProductListDatagrid: React.FC = ({ selectionActions={() => null} fullScreenTitle={intl.formatMessage(messages.products)} onRowClick={handleRowClick} + rowAnchor={handleRowAnchor} renderColumnPicker={defaultProps => ( = props => { settings={settings} selectedChannelId={selectedChannelId} onUpdateListSettings={onUpdateListSettings} - onRowClick={id => { - navigate(productUrl(id)); - }} + rowAnchor={productUrl} /> ) : (