mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-01 13:06:45 +00:00
Added base for admin center (#5862)
This commit is contained in:
parent
fb7020a85a
commit
93f642c790
@ -5,6 +5,7 @@ import {
|
|||||||
IconLogout,
|
IconLogout,
|
||||||
IconPlugConnected,
|
IconPlugConnected,
|
||||||
IconSettings,
|
IconSettings,
|
||||||
|
IconUserBolt,
|
||||||
IconUserCog
|
IconUserCog
|
||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
@ -34,6 +35,15 @@ export function MainMenu() {
|
|||||||
</UnstyledButton>
|
</UnstyledButton>
|
||||||
</Menu.Target>
|
</Menu.Target>
|
||||||
<Menu.Dropdown>
|
<Menu.Dropdown>
|
||||||
|
{userState.user?.is_staff && (
|
||||||
|
<Menu.Item
|
||||||
|
icon={<IconUserBolt />}
|
||||||
|
component={Link}
|
||||||
|
to="/settings/admin"
|
||||||
|
>
|
||||||
|
<Trans>Admin Center</Trans>
|
||||||
|
</Menu.Item>
|
||||||
|
)}
|
||||||
<Menu.Label>
|
<Menu.Label>
|
||||||
<Trans>Settings</Trans>
|
<Trans>Settings</Trans>
|
||||||
</Menu.Label>
|
</Menu.Label>
|
||||||
|
@ -35,18 +35,21 @@ export type PanelType = {
|
|||||||
* @param activePanel : string - The name of the currently active panel (defaults to the first panel)
|
* @param activePanel : string - The name of the currently active panel (defaults to the first panel)
|
||||||
* @param setActivePanel : (panel: string) => void - Function to set the active panel
|
* @param setActivePanel : (panel: string) => void - Function to set the active panel
|
||||||
* @param onPanelChange : (panel: string) => void - Callback when the active panel changes
|
* @param onPanelChange : (panel: string) => void - Callback when the active panel changes
|
||||||
|
* @param collabsible : boolean - If true, the panel group can be collapsed (defaults to true)
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function PanelGroup({
|
export function PanelGroup({
|
||||||
pageKey,
|
pageKey,
|
||||||
panels,
|
panels,
|
||||||
selectedPanel,
|
selectedPanel,
|
||||||
onPanelChange
|
onPanelChange,
|
||||||
|
collabsible = true
|
||||||
}: {
|
}: {
|
||||||
pageKey: string;
|
pageKey: string;
|
||||||
panels: PanelType[];
|
panels: PanelType[];
|
||||||
selectedPanel?: string;
|
selectedPanel?: string;
|
||||||
onPanelChange?: (panel: string) => void;
|
onPanelChange?: (panel: string) => void;
|
||||||
|
collabsible?: boolean;
|
||||||
}): ReactNode {
|
}): ReactNode {
|
||||||
const [activePanel, setActivePanel] = useLocalStorage<string>({
|
const [activePanel, setActivePanel] = useLocalStorage<string>({
|
||||||
key: `panel-group-active-panel-${pageKey}`,
|
key: `panel-group-active-panel-${pageKey}`,
|
||||||
@ -105,18 +108,20 @@ export function PanelGroup({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
<ActionIcon
|
{collabsible && (
|
||||||
style={{
|
<ActionIcon
|
||||||
paddingLeft: '10px'
|
style={{
|
||||||
}}
|
paddingLeft: '10px'
|
||||||
onClick={() => setExpanded(!expanded)}
|
}}
|
||||||
>
|
onClick={() => setExpanded(!expanded)}
|
||||||
{expanded ? (
|
>
|
||||||
<IconLayoutSidebarLeftCollapse opacity={0.5} />
|
{expanded ? (
|
||||||
) : (
|
<IconLayoutSidebarLeftCollapse opacity={0.5} />
|
||||||
<IconLayoutSidebarRightCollapse opacity={0.5} />
|
) : (
|
||||||
)}
|
<IconLayoutSidebarRightCollapse opacity={0.5} />
|
||||||
</ActionIcon>
|
)}
|
||||||
|
</ActionIcon>
|
||||||
|
)}
|
||||||
</Tabs.List>
|
</Tabs.List>
|
||||||
{panels.map(
|
{panels.map(
|
||||||
(panel, idx) =>
|
(panel, idx) =>
|
||||||
|
@ -14,12 +14,12 @@ export function SettingsHeader({
|
|||||||
switch_text,
|
switch_text,
|
||||||
switch_link
|
switch_link
|
||||||
}: {
|
}: {
|
||||||
title: string;
|
title: string | ReactNode;
|
||||||
shorthand?: string;
|
shorthand?: string;
|
||||||
subtitle: string | ReactNode;
|
subtitle: string | ReactNode;
|
||||||
switch_condition?: boolean;
|
switch_condition?: boolean;
|
||||||
switch_text: string | ReactNode;
|
switch_text?: string | ReactNode;
|
||||||
switch_link: string;
|
switch_link?: string;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Stack spacing="0" ml={'sm'}>
|
<Stack spacing="0" ml={'sm'}>
|
||||||
@ -29,7 +29,7 @@ export function SettingsHeader({
|
|||||||
</Group>
|
</Group>
|
||||||
<Group>
|
<Group>
|
||||||
<Text c="dimmed">{subtitle}</Text>
|
<Text c="dimmed">{subtitle}</Text>
|
||||||
{switch_condition && (
|
{switch_text && switch_link && switch_condition && (
|
||||||
<Anchor component={Link} to={switch_link}>
|
<Anchor component={Link} to={switch_link}>
|
||||||
<IconSwitch size={14} />
|
<IconSwitch size={14} />
|
||||||
{switch_text}
|
{switch_text}
|
||||||
|
105
src/frontend/src/pages/Index/Settings/AdminCenter.tsx
Normal file
105
src/frontend/src/pages/Index/Settings/AdminCenter.tsx
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import { Trans, t } from '@lingui/macro';
|
||||||
|
import {
|
||||||
|
Anchor,
|
||||||
|
Divider,
|
||||||
|
Group,
|
||||||
|
Paper,
|
||||||
|
SimpleGrid,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
Title
|
||||||
|
} from '@mantine/core';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { PlaceholderPill } from '../../../components/items/Placeholder';
|
||||||
|
import { PanelGroup, PanelType } from '../../../components/nav/PanelGroup';
|
||||||
|
import { SettingsHeader } from '../../../components/nav/SettingsHeader';
|
||||||
|
import { GlobalSettingList } from '../../../components/settings/SettingList';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* System settings page
|
||||||
|
*/
|
||||||
|
export default function AdminCenter() {
|
||||||
|
const adminCenterPanels: PanelType[] = useMemo(() => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'user',
|
||||||
|
label: t`User Management`,
|
||||||
|
content: (
|
||||||
|
<Stack spacing="xs">
|
||||||
|
<PlaceholderPill />
|
||||||
|
<Divider />
|
||||||
|
<Stack spacing={0}>
|
||||||
|
<Text>
|
||||||
|
<Trans>Settings</Trans>
|
||||||
|
</Text>
|
||||||
|
<Group>
|
||||||
|
<Text c="dimmed">
|
||||||
|
<Trans>
|
||||||
|
Select settings relevant for user lifecycle. More available
|
||||||
|
in
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
<Anchor component={Link} to={'/settings/system'}>
|
||||||
|
<Trans>System settings</Trans>
|
||||||
|
</Anchor>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
<GlobalSettingList
|
||||||
|
keys={[
|
||||||
|
'LOGIN_ENABLE_REG',
|
||||||
|
'SIGNUP_GROUP',
|
||||||
|
'LOGIN_ENABLE_SSO_REG'
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const QuickAction = () => (
|
||||||
|
<Stack spacing={'xs'} ml={'sm'}>
|
||||||
|
<Title order={5}>
|
||||||
|
<Trans>Quick Actions</Trans>
|
||||||
|
</Title>
|
||||||
|
<SimpleGrid cols={3}>
|
||||||
|
<Paper shadow="xs" p="sm" withBorder>
|
||||||
|
<Text>
|
||||||
|
<Trans>Add a new user</Trans>
|
||||||
|
</Text>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
<Paper shadow="xs" p="sm" withBorder>
|
||||||
|
<PlaceholderPill />
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
<Paper shadow="xs" p="sm" withBorder>
|
||||||
|
<PlaceholderPill />
|
||||||
|
</Paper>
|
||||||
|
</SimpleGrid>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Stack spacing="xs">
|
||||||
|
<SettingsHeader
|
||||||
|
title={<Trans>Admin Center</Trans>}
|
||||||
|
subtitle={
|
||||||
|
<Trans>Advanced Amininistrative Options for InvenTree</Trans>
|
||||||
|
}
|
||||||
|
switch_link="/settings/system"
|
||||||
|
switch_text="System Settings"
|
||||||
|
/>
|
||||||
|
<QuickAction />
|
||||||
|
<PanelGroup
|
||||||
|
pageKey="admin-center"
|
||||||
|
panels={adminCenterPanels}
|
||||||
|
collabsible={false}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -92,6 +92,9 @@ export const SystemSettings = Loadable(
|
|||||||
export const PluginSettings = Loadable(
|
export const PluginSettings = Loadable(
|
||||||
lazy(() => import('./pages/Index/Settings/PluginSettings'))
|
lazy(() => import('./pages/Index/Settings/PluginSettings'))
|
||||||
);
|
);
|
||||||
|
export const AdminCenter = Loadable(
|
||||||
|
lazy(() => import('./pages/Index/Settings/AdminCenter'))
|
||||||
|
);
|
||||||
|
|
||||||
export const NotFound = Loadable(lazy(() => import('./pages/NotFound')));
|
export const NotFound = Loadable(lazy(() => import('./pages/NotFound')));
|
||||||
export const Login = Loadable(lazy(() => import('./pages/Auth/Login')));
|
export const Login = Loadable(lazy(() => import('./pages/Auth/Login')));
|
||||||
@ -113,7 +116,8 @@ export const routes = (
|
|||||||
<Route path="playground/" element={<Playground />} />,
|
<Route path="playground/" element={<Playground />} />,
|
||||||
<Route path="scan/" element={<Scan />} />,
|
<Route path="scan/" element={<Scan />} />,
|
||||||
<Route path="settings/">
|
<Route path="settings/">
|
||||||
<Route index element={<SystemSettings />} />
|
<Route index element={<AdminCenter />} />
|
||||||
|
<Route path="admin/" element={<AdminCenter />} />
|
||||||
<Route path="system/" element={<SystemSettings />} />
|
<Route path="system/" element={<SystemSettings />} />
|
||||||
<Route path="user/" element={<UserSettings />} />
|
<Route path="user/" element={<UserSettings />} />
|
||||||
<Route path="plugin/" element={<PluginSettings />} />
|
<Route path="plugin/" element={<PluginSettings />} />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user