2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-05-03 13:58:47 +00:00

Revert "[PUI] URl / panel fix (#6078)" (#6088)

This reverts commit 902eafcc752c71d027cddac68fafd059b7b5b8fc.
This commit is contained in:
Oliver 2023-12-15 08:38:30 +11:00 committed by GitHub
parent cd3e7037c5
commit aecdc0739d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 101 additions and 111 deletions

View File

@ -15,14 +15,8 @@ export function setApiDefaults() {
const token = useSessionState.getState().token; const token = useSessionState.getState().token;
api.defaults.baseURL = host; api.defaults.baseURL = host;
api.defaults.headers.common['Authorization'] = `Token ${token}`;
if (token) {
api.defaults.headers.common['Authorization'] = `Token ${token}`;
} else {
api.defaults.headers.common['Authorization'] = null;
}
} }
export const queryClient = new QueryClient(); export const queryClient = new QueryClient();
function checkMobile() { function checkMobile() {

View File

@ -10,8 +10,15 @@ import {
IconLayoutSidebarLeftCollapse, IconLayoutSidebarLeftCollapse,
IconLayoutSidebarRightCollapse IconLayoutSidebarRightCollapse
} from '@tabler/icons-react'; } from '@tabler/icons-react';
import { ReactNode, useCallback, useMemo } from 'react'; import { ReactNode, useMemo } from 'react';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import {
Navigate,
Route,
Routes,
useNavigate,
useParams
} from 'react-router-dom';
import { useLocalState } from '../../states/LocalState'; import { useLocalState } from '../../states/LocalState';
import { PlaceholderPanel } from '../items/Placeholder'; import { PlaceholderPanel } from '../items/Placeholder';
@ -37,57 +44,61 @@ export type PanelProps = {
collapsible?: boolean; collapsible?: boolean;
}; };
export function PanelGroup({ function BasePanelGroup({
pageKey, pageKey,
panels, panels,
onPanelChange, onPanelChange,
selectedPanel, selectedPanel,
collapsible = true collapsible = true
}: PanelProps): ReactNode { }: PanelProps): ReactNode {
const localState = useLocalState(); const navigate = useNavigate();
const { panel } = useParams();
const [panel, setPanel] = useState<string>(selectedPanel ?? '');
// Keep a list of active panels (hidden and disabled panels are not active)
const activePanels = useMemo( const activePanels = useMemo(
() => panels.filter((panel) => !panel.hidden && !panel.disabled), () => panels.filter((panel) => !panel.hidden && !panel.disabled),
[panels] [panels]
); );
// Set selected panel when component is initially loaded, or when the selected panel changes const setLastUsedPanel = useLocalState((state) =>
state.setLastUsedPanel(pageKey)
);
useEffect(() => { useEffect(() => {
let first_panel: string = activePanels[0]?.name ?? ''; if (panel) {
let active_panel: string = setLastUsedPanel(panel);
useLocalState.getState().getLastUsedPanel(pageKey)() ?? '';
let panelName = selectedPanel || active_panel || first_panel;
if (panelName != panel) {
setPanel(panelName);
} }
// panel is intentionally no dependency as this should only run on initial render
if (panelName != active_panel) { }, [setLastUsedPanel]);
useLocalState.getState().setLastUsedPanel(pageKey)(panelName);
}
}, [activePanels, panels, selectedPanel]);
// Callback when the active panel changes // Callback when the active panel changes
const handlePanelChange = useCallback( function handlePanelChange(panel: string) {
(panelName: string) => { if (activePanels.findIndex((p) => p.name === panel) === -1) {
// Ensure that the panel name is valid setLastUsedPanel('');
if (!activePanels.some((panel) => panel.name == panelName)) { return navigate('../');
return; }
}
setPanel(panelName); navigate(`../${panel}`);
localState.setLastUsedPanel(pageKey)(panelName);
if (onPanelChange) { // Optionally call external callback hook
onPanelChange(panelName); if (onPanelChange) {
} onPanelChange(panel);
}, }
[onPanelChange, pageKey] }
);
// if the selected panel state changes update the current panel
useEffect(() => {
if (selectedPanel && selectedPanel !== panel) {
handlePanelChange(selectedPanel);
}
}, [selectedPanel, panel]);
// Update the active panel when panels changes and the active is no longer available
useEffect(() => {
if (activePanels.findIndex((p) => p.name === panel) === -1) {
setLastUsedPanel('');
return navigate('../');
}
}, [activePanels, panel]);
const [expanded, setExpanded] = useState<boolean>(true); const [expanded, setExpanded] = useState<boolean>(true);
@ -158,3 +169,38 @@ export function PanelGroup({
</Paper> </Paper>
); );
} }
function IndexPanelComponent({ pageKey, selectedPanel, panels }: PanelProps) {
const lastUsedPanel = useLocalState((state) => {
const panelName =
selectedPanel || state.lastUsedPanels[pageKey] || panels[0]?.name;
if (
panels.findIndex(
(p) => p.name === panelName && !p.disabled && !p.hidden
) === -1
) {
return panels[0]?.name;
}
return panelName;
});
return <Navigate to={lastUsedPanel} replace />;
}
/**
* Render a panel group. The current panel will be appended to the current url.
* The last opened panel will be stored in local storage and opened if no panel is provided via url param
* @param panels - The list of panels to display
* @param onPanelChange - Callback when the active panel changes
* @param collapsible - If true, the panel group can be collapsed (defaults to true)
*/
export function PanelGroup(props: PanelProps) {
return (
<Routes>
<Route index element={<IndexPanelComponent {...props} />} />
<Route path="/:panel/*" element={<BasePanelGroup {...props} />} />
</Routes>
);
}

View File

@ -27,9 +27,7 @@ export const doClassicLogin = async (username: string, password: string) => {
name: 'inventree-web-app' name: 'inventree-web-app'
} }
}) })
.then((response) => { .then((response) => response.data.token)
return response.status == 200 ? response.data?.token : undefined;
})
.catch((error) => { .catch((error) => {
showNotification({ showNotification({
title: t`Login failed`, title: t`Login failed`,
@ -39,7 +37,7 @@ export const doClassicLogin = async (username: string, password: string) => {
return false; return false;
}); });
if (!token) return false; if (token === false) return token;
// log in with token // log in with token
doTokenLogin(token); doTokenLogin(token);
@ -53,7 +51,6 @@ export const doClassicLogout = async () => {
// TODO @matmair - logout from the server session // TODO @matmair - logout from the server session
// Set token in context // Set token in context
const { setToken } = useSessionState.getState(); const { setToken } = useSessionState.getState();
setToken(undefined); setToken(undefined);
notifications.show({ notifications.show({

View File

@ -22,11 +22,9 @@ import { useInstance } from '../../hooks/UseInstance';
* *
* Note: If no category ID is supplied, this acts as the top-level part category page * Note: If no category ID is supplied, this acts as the top-level part category page
*/ */
export function CategoryPage({ export default function CategoryDetail({}: {}) {
categoryId const { id } = useParams();
}: {
categoryId?: string | undefined;
}) {
const [treeOpen, setTreeOpen] = useState(false); const [treeOpen, setTreeOpen] = useState(false);
const { const {
@ -35,8 +33,7 @@ export function CategoryPage({
instanceQuery instanceQuery
} = useInstance({ } = useInstance({
endpoint: ApiPaths.category_list, endpoint: ApiPaths.category_list,
pk: categoryId, pk: id,
hasPrimaryKey: true,
params: { params: {
path_detail: true path_detail: true
} }
@ -52,7 +49,7 @@ export function CategoryPage({
<PartListTable <PartListTable
props={{ props={{
params: { params: {
category: categoryId category: id
} }
}} }}
/> />
@ -65,7 +62,7 @@ export function CategoryPage({
content: ( content: (
<PartCategoryTable <PartCategoryTable
params={{ params={{
parent: categoryId ?? 'null' parent: id
}} }}
/> />
) )
@ -77,7 +74,7 @@ export function CategoryPage({
content: <PlaceholderPanel /> content: <PlaceholderPanel />
} }
], ],
[categoryId] [category, id]
); );
const breadcrumbs = useMemo( const breadcrumbs = useMemo(
@ -113,13 +110,3 @@ export function CategoryPage({
</Stack> </Stack>
); );
} }
/**
* Detail page for a specific Part Category instance.
* Uses the :id parameter in the URL to determine which category to display.admin in
*/
export default function CategoryDetail({}: {}) {
const { id } = useParams();
return <CategoryPage categoryId={id} />;
}

View File

@ -1,5 +0,0 @@
import { CategoryPage } from './CategoryDetail';
export default function PartIndex({}: {}) {
return <CategoryPage />;
}

View File

@ -12,11 +12,9 @@ import { StockLocationTable } from '../../components/tables/stock/StockLocationT
import { ApiPaths } from '../../enums/ApiEndpoints'; import { ApiPaths } from '../../enums/ApiEndpoints';
import { useInstance } from '../../hooks/UseInstance'; import { useInstance } from '../../hooks/UseInstance';
export function LocationPage({ export default function Stock() {
locationId const { id } = useParams();
}: {
locationId?: string | undefined;
}) {
const [treeOpen, setTreeOpen] = useState(false); const [treeOpen, setTreeOpen] = useState(false);
const { const {
@ -25,8 +23,7 @@ export function LocationPage({
instanceQuery instanceQuery
} = useInstance({ } = useInstance({
endpoint: ApiPaths.stock_location_list, endpoint: ApiPaths.stock_location_list,
pk: locationId, pk: id,
hasPrimaryKey: true,
params: { params: {
path_detail: true path_detail: true
} }
@ -41,7 +38,7 @@ export function LocationPage({
content: ( content: (
<StockItemTable <StockItemTable
params={{ params={{
location: locationId location: id
}} }}
/> />
) )
@ -53,13 +50,13 @@ export function LocationPage({
content: ( content: (
<StockLocationTable <StockLocationTable
params={{ params={{
parent: locationId ?? 'null' parent: id
}} }}
/> />
) )
} }
]; ];
}, [locationId]); }, [location, id]);
const breadcrumbs = useMemo( const breadcrumbs = useMemo(
() => [ () => [
@ -94,13 +91,3 @@ export function LocationPage({
</> </>
); );
} }
/**
* Detail page for a specific Stock Location instance
* Uses the :id parameter in the URL to determine which location to display
*/
export default function LocationDetail({}: {}) {
const { id } = useParams();
return <LocationPage locationId={id} />;
}

View File

@ -1,5 +0,0 @@
import { LocationPage } from './LocationDetail';
export default function StockIndex({}: {}) {
return <LocationPage />;
}

View File

@ -28,12 +28,9 @@ export const ManufacturerDetail = Loadable(
lazy(() => import('./pages/company/ManufacturerDetail')) lazy(() => import('./pages/company/ManufacturerDetail'))
); );
export const PartIndex = Loadable(lazy(() => import('./pages/part/PartIndex')));
export const CategoryDetail = Loadable( export const CategoryDetail = Loadable(
lazy(() => import('./pages/part/CategoryDetail')) lazy(() => import('./pages/part/CategoryDetail'))
); );
export const PartDetail = Loadable( export const PartDetail = Loadable(
lazy(() => import('./pages/part/PartDetail')) lazy(() => import('./pages/part/PartDetail'))
); );
@ -42,10 +39,6 @@ export const LocationDetail = Loadable(
lazy(() => import('./pages/stock/LocationDetail')) lazy(() => import('./pages/stock/LocationDetail'))
); );
export const StockIndex = Loadable(
lazy(() => import('./pages/stock/StockIndex'))
);
export const StockDetail = Loadable( export const StockDetail = Loadable(
lazy(() => import('./pages/stock/StockDetail')) lazy(() => import('./pages/stock/StockDetail'))
); );
@ -126,13 +119,13 @@ export const routes = (
<Route path="user/*" element={<UserSettings />} /> <Route path="user/*" element={<UserSettings />} />
</Route> </Route>
<Route path="part/"> <Route path="part/">
<Route index element={<PartIndex />} /> <Route index element={<Navigate to="category/" />} />
<Route path="category/:id/*" element={<CategoryDetail />} /> <Route path="category/:id?/*" element={<CategoryDetail />} />
<Route path=":id/*" element={<PartDetail />} /> <Route path=":id/*" element={<PartDetail />} />
</Route> </Route>
<Route path="stock/"> <Route path="stock/">
<Route index element={<StockIndex />} /> <Route index element={<Navigate to="location/" />} />
<Route path="location/:id/*" element={<LocationDetail />} /> <Route path="location/:id?/*" element={<LocationDetail />} />
<Route path="item/:id/*" element={<StockDetail />} /> <Route path="item/:id/*" element={<StockDetail />} />
</Route> </Route>
<Route path="build/"> <Route path="build/">

View File

@ -24,7 +24,6 @@ interface LocalStateProps {
loader: LoaderType; loader: LoaderType;
lastUsedPanels: Record<string, string>; lastUsedPanels: Record<string, string>;
setLastUsedPanel: (panelKey: string) => (value: string) => void; setLastUsedPanel: (panelKey: string) => (value: string) => void;
getLastUsedPanel: (panelKey: string) => () => string | undefined;
} }
export const useLocalState = create<LocalStateProps>()( export const useLocalState = create<LocalStateProps>()(
@ -56,9 +55,6 @@ export const useLocalState = create<LocalStateProps>()(
lastUsedPanels: { ...get().lastUsedPanels, [panelKey]: value } lastUsedPanels: { ...get().lastUsedPanels, [panelKey]: value }
}); });
} }
},
getLastUsedPanel(panelKey) {
return () => get().lastUsedPanels[panelKey];
} }
}), }),
{ {