mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-15 11:33:08 +00:00
[PUI] Open links in new window (#7354)
* Breadcrumbs can be opened in a new tab * Support tab nav for top header items * Open panel tab in new window
This commit is contained in:
parent
b402836dc4
commit
89cea3045a
@ -10,6 +10,8 @@ import { IconMenu2 } from '@tabler/icons-react';
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { navigateToLink } from '../../functions/navigation';
|
||||||
|
|
||||||
export type Breadcrumb = {
|
export type Breadcrumb = {
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
@ -57,7 +59,10 @@ export function BreadcrumbList({
|
|||||||
return (
|
return (
|
||||||
<Anchor
|
<Anchor
|
||||||
key={index}
|
key={index}
|
||||||
onClick={() => breadcrumb.url && navigate(breadcrumb.url)}
|
onClick={(event: any) =>
|
||||||
|
breadcrumb.url &&
|
||||||
|
navigateToLink(breadcrumb.url, navigate, event)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Text size="sm">{breadcrumb.name}</Text>
|
<Text size="sm">{breadcrumb.name}</Text>
|
||||||
</Anchor>
|
</Anchor>
|
||||||
|
@ -8,6 +8,7 @@ import { useMatch, useNavigate } from 'react-router-dom';
|
|||||||
import { api } from '../../App';
|
import { api } from '../../App';
|
||||||
import { navTabs as mainNavTabs } from '../../defaults/links';
|
import { navTabs as mainNavTabs } from '../../defaults/links';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
|
import { navigateToLink } from '../../functions/navigation';
|
||||||
import * as classes from '../../main.css';
|
import * as classes from '../../main.css';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
import { useLocalState } from '../../states/LocalState';
|
import { useLocalState } from '../../states/LocalState';
|
||||||
@ -141,13 +142,16 @@ function NavTabs() {
|
|||||||
tab: classes.tab
|
tab: classes.tab
|
||||||
}}
|
}}
|
||||||
value={tabValue}
|
value={tabValue}
|
||||||
onChange={(value) =>
|
|
||||||
value == '/' ? navigate('/') : navigate(`/${value}`)
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<Tabs.List>
|
<Tabs.List>
|
||||||
{mainNavTabs.map((tab) => (
|
{mainNavTabs.map((tab) => (
|
||||||
<Tabs.Tab value={tab.name} key={tab.name}>
|
<Tabs.Tab
|
||||||
|
value={tab.name}
|
||||||
|
key={tab.name}
|
||||||
|
onClick={(event: any) =>
|
||||||
|
navigateToLink(`/${tab.name}`, navigate, event)
|
||||||
|
}
|
||||||
|
>
|
||||||
{tab.text}
|
{tab.text}
|
||||||
</Tabs.Tab>
|
</Tabs.Tab>
|
||||||
))}
|
))}
|
||||||
|
@ -10,15 +10,17 @@ import {
|
|||||||
IconLayoutSidebarLeftCollapse,
|
IconLayoutSidebarLeftCollapse,
|
||||||
IconLayoutSidebarRightCollapse
|
IconLayoutSidebarRightCollapse
|
||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import { ReactNode, useEffect, useMemo, useState } from 'react';
|
import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Navigate,
|
Navigate,
|
||||||
Route,
|
Route,
|
||||||
Routes,
|
Routes,
|
||||||
|
useLocation,
|
||||||
useNavigate,
|
useNavigate,
|
||||||
useParams
|
useParams
|
||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
|
|
||||||
|
import { navigateToLink } from '../../functions/navigation';
|
||||||
import { useLocalState } from '../../states/LocalState';
|
import { useLocalState } from '../../states/LocalState';
|
||||||
import { Boundary } from '../Boundary';
|
import { Boundary } from '../Boundary';
|
||||||
import { PlaceholderPanel } from '../items/Placeholder';
|
import { PlaceholderPanel } from '../items/Placeholder';
|
||||||
@ -52,6 +54,7 @@ function BasePanelGroup({
|
|||||||
selectedPanel,
|
selectedPanel,
|
||||||
collapsible = true
|
collapsible = true
|
||||||
}: Readonly<PanelProps>): ReactNode {
|
}: Readonly<PanelProps>): ReactNode {
|
||||||
|
const location = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { panel } = useParams();
|
const { panel } = useParams();
|
||||||
|
|
||||||
@ -72,19 +75,27 @@ function BasePanelGroup({
|
|||||||
}, [setLastUsedPanel]);
|
}, [setLastUsedPanel]);
|
||||||
|
|
||||||
// Callback when the active panel changes
|
// Callback when the active panel changes
|
||||||
function handlePanelChange(panel: string | null) {
|
const handlePanelChange = useCallback(
|
||||||
if (activePanels.findIndex((p) => p.name === panel) === -1) {
|
(panel: string | null, event?: any) => {
|
||||||
setLastUsedPanel('');
|
if (activePanels.findIndex((p) => p.name === panel) === -1) {
|
||||||
return navigate('../');
|
setLastUsedPanel('');
|
||||||
}
|
return navigate('../');
|
||||||
|
}
|
||||||
|
|
||||||
navigate(`../${panel}`);
|
if (event && (event?.ctrlKey || event?.shiftKey)) {
|
||||||
|
const url = `${location.pathname}/../${panel}`;
|
||||||
|
navigateToLink(url, navigate, event);
|
||||||
|
} else {
|
||||||
|
navigate(`../${panel}`);
|
||||||
|
}
|
||||||
|
|
||||||
// Optionally call external callback hook
|
// Optionally call external callback hook
|
||||||
if (panel && onPanelChange) {
|
if (panel && onPanelChange) {
|
||||||
onPanelChange(panel);
|
onPanelChange(panel);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
[activePanels, setLastUsedPanel, navigate, location, onPanelChange]
|
||||||
|
);
|
||||||
|
|
||||||
// if the selected panel state changes update the current panel
|
// if the selected panel state changes update the current panel
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -129,6 +140,9 @@ function BasePanelGroup({
|
|||||||
hidden={panel.hidden}
|
hidden={panel.hidden}
|
||||||
disabled={panel.disabled}
|
disabled={panel.disabled}
|
||||||
style={{ cursor: panel.disabled ? 'unset' : 'pointer' }}
|
style={{ cursor: panel.disabled ? 'unset' : 'pointer' }}
|
||||||
|
onClick={(event: any) =>
|
||||||
|
handlePanelChange(panel.name, event)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{expanded && panel.label}
|
{expanded && panel.label}
|
||||||
</Tabs.Tab>
|
</Tabs.Tab>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user