mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
[PUI] Added Server Info Modal (#5810)
* updated typing to allow either link or action * fixed typing * made it possible to use an action instead of a link * added ServerInfo Modal skeleton * fixed anchor * added content to ServerInfo * Factored database lookup out * Extended status API to CUI level * extended ServerInfo to CUI level * Made modal larger * fixed default settings
This commit is contained in:
parent
7ff3f99dc9
commit
8aad3eeefa
@ -18,10 +18,11 @@ from InvenTree.permissions import RolePermission
|
||||
from part.templatetags.inventree_extras import plugins_info
|
||||
from plugin.serializers import MetadataSerializer
|
||||
|
||||
from .email import is_email_configured
|
||||
from .mixins import RetrieveUpdateAPI
|
||||
from .status import is_worker_running
|
||||
from .version import (inventreeApiVersion, inventreeInstanceName,
|
||||
inventreeVersion)
|
||||
from .status import check_system_health, is_worker_running
|
||||
from .version import (inventreeApiVersion, inventreeDatabase,
|
||||
inventreeInstanceName, inventreeVersion)
|
||||
from .views import AjaxView
|
||||
|
||||
|
||||
@ -48,6 +49,11 @@ class InfoView(AjaxView):
|
||||
'worker_pending_tasks': self.worker_pending_tasks(),
|
||||
'plugins_enabled': settings.PLUGINS_ENABLED,
|
||||
'active_plugins': plugins_info(),
|
||||
'email_configured': is_email_configured(),
|
||||
'debug_mode': settings.DEBUG,
|
||||
'docker_mode': settings.DOCKER,
|
||||
'system_health': check_system_health() if request.user.is_staff else None,
|
||||
'database': inventreeDatabase()if request.user.is_staff else None
|
||||
}
|
||||
|
||||
return JsonResponse(data)
|
||||
|
@ -2,11 +2,14 @@
|
||||
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 142
|
||||
INVENTREE_API_VERSION = 143
|
||||
|
||||
"""
|
||||
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
||||
|
||||
v143 -> 2023-10-29: https://github.com/inventree/InvenTree/pull/5810
|
||||
- Extends the status endpoint to include information about system status and health
|
||||
|
||||
v142 -> 2023-10-20: https://github.com/inventree/InvenTree/pull/5759
|
||||
- Adds generic API endpoints for looking up status models
|
||||
|
||||
|
@ -199,3 +199,9 @@ def inventreeTarget():
|
||||
def inventreePlatform():
|
||||
"""Returns the platform for the instance."""
|
||||
return platform.platform(aliased=True)
|
||||
|
||||
|
||||
def inventreeDatabase():
|
||||
"""Return the InvenTree database backend e.g. 'postgresql'."""
|
||||
db = settings.DATABASES['default']
|
||||
return db.get('ENGINE', None).replace('django.db.backends.', '')
|
||||
|
@ -183,13 +183,7 @@ def plugins_info(*args, **kwargs):
|
||||
@register.simple_tag()
|
||||
def inventree_db_engine(*args, **kwargs):
|
||||
"""Return the InvenTree database backend e.g. 'postgresql'."""
|
||||
db = djangosettings.DATABASES['default']
|
||||
|
||||
engine = db.get('ENGINE', _('Unknown database'))
|
||||
|
||||
engine = engine.replace('django.db.backends.', '')
|
||||
|
||||
return engine
|
||||
return version.inventreeDatabase() or _('Unknown database')
|
||||
|
||||
|
||||
@register.simple_tag()
|
||||
|
@ -3,37 +3,81 @@ import { Anchor, Group, SimpleGrid, Text } from '@mantine/core';
|
||||
import { DocTooltip } from './DocTooltip';
|
||||
import { PlaceholderPill } from './Placeholder';
|
||||
|
||||
export interface DocumentationLinkItem {
|
||||
interface DocumentationLinkBase {
|
||||
id: string;
|
||||
title: string | JSX.Element;
|
||||
description: string | JSX.Element;
|
||||
link: string;
|
||||
placeholder?: boolean;
|
||||
}
|
||||
|
||||
interface DocumentationLinkItemLink extends DocumentationLinkBase {
|
||||
link: string;
|
||||
action?: never;
|
||||
}
|
||||
|
||||
interface DocumentationLinkItemAction extends DocumentationLinkBase {
|
||||
link?: never;
|
||||
action: () => void;
|
||||
}
|
||||
|
||||
export type DocumentationLinkItem =
|
||||
| DocumentationLinkItemLink
|
||||
| DocumentationLinkItemAction;
|
||||
|
||||
export function DocumentationLinks({
|
||||
links
|
||||
}: {
|
||||
links: DocumentationLinkItem[];
|
||||
}) {
|
||||
const DocumentationLinkRenderer = ({
|
||||
link
|
||||
}: {
|
||||
link: DocumentationLinkItem;
|
||||
}) => {
|
||||
const content = (
|
||||
<Text size="sm" fw={500}>
|
||||
{link.title}
|
||||
</Text>
|
||||
);
|
||||
|
||||
const Linker = ({ children }: { children: any }) => {
|
||||
if (link.link)
|
||||
return (
|
||||
<Anchor href={link.link} key={link.id}>
|
||||
{children}
|
||||
</Anchor>
|
||||
);
|
||||
|
||||
if (link.action)
|
||||
return (
|
||||
<Anchor component="button" type="button" onClick={link.action}>
|
||||
{children}
|
||||
</Anchor>
|
||||
);
|
||||
|
||||
console.log('Neither link nor action found for link:', link);
|
||||
return children;
|
||||
};
|
||||
|
||||
return (
|
||||
<Linker>
|
||||
{link.placeholder ? (
|
||||
<Group>
|
||||
{content}
|
||||
<PlaceholderPill />
|
||||
</Group>
|
||||
) : (
|
||||
content
|
||||
)}
|
||||
</Linker>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SimpleGrid cols={2} spacing={0}>
|
||||
{links.map((link) => (
|
||||
<DocTooltip key={link.id} text={link.description}>
|
||||
<Anchor href={link.link} key={link.id}>
|
||||
{link.placeholder ? (
|
||||
<Group>
|
||||
<Text size="sm" fw={500}>
|
||||
{link.title}
|
||||
</Text>
|
||||
<PlaceholderPill />
|
||||
</Group>
|
||||
) : (
|
||||
<Text size="sm" fw={500}>
|
||||
{link.title}
|
||||
</Text>
|
||||
)}
|
||||
</Anchor>
|
||||
<DocumentationLinkRenderer link={link} />
|
||||
</DocTooltip>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
|
10
src/frontend/src/components/items/OnlyStaff.tsx
Normal file
10
src/frontend/src/components/items/OnlyStaff.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { Trans } from '@lingui/macro';
|
||||
|
||||
import { useUserState } from '../../states/UserState';
|
||||
|
||||
export const OnlyStaff = ({ children }: { children: any }) => {
|
||||
const [user] = useUserState((state) => [state.user]);
|
||||
|
||||
if (user?.is_staff) return children;
|
||||
return <Trans>This information is only available for staff users</Trans>;
|
||||
};
|
141
src/frontend/src/components/modals/ServerInfoModal.tsx
Normal file
141
src/frontend/src/components/modals/ServerInfoModal.tsx
Normal file
@ -0,0 +1,141 @@
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { Badge, Button, Stack, Table, Title } from '@mantine/core';
|
||||
import { ContextModalProps } from '@mantine/modals';
|
||||
|
||||
import { useServerApiState } from '../../states/ApiState';
|
||||
import { OnlyStaff } from '../items/OnlyStaff';
|
||||
|
||||
export function ServerInfoModal({
|
||||
context,
|
||||
id
|
||||
}: ContextModalProps<{ modalBody: string }>) {
|
||||
const [server] = useServerApiState((state) => [state.server]);
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Title order={5}>
|
||||
<Trans>Server</Trans>
|
||||
</Title>
|
||||
<Table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<Trans>Instance Name</Trans>
|
||||
</td>
|
||||
<td>{server.instance}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Trans>Database</Trans>
|
||||
</td>
|
||||
<td>
|
||||
<OnlyStaff>{server.database}</OnlyStaff>
|
||||
</td>
|
||||
</tr>
|
||||
{server.debug_mode && (
|
||||
<tr>
|
||||
<td>
|
||||
<Trans>Bebug Mode</Trans>
|
||||
</td>
|
||||
<td>
|
||||
<Trans>Server is running in debug mode</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{server.docker_mode && (
|
||||
<tr>
|
||||
<td>
|
||||
<Trans>Docker Mode</Trans>
|
||||
</td>
|
||||
<td>
|
||||
<Trans>Server is deployed using docker</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
<tr>
|
||||
<td>
|
||||
<Trans>Plugin Support</Trans>
|
||||
</td>
|
||||
<td>
|
||||
<Badge color={server.plugins_enabled ? 'green' : 'red'}>
|
||||
{server.plugins_enabled ? (
|
||||
<Trans>Plugin support enabled</Trans>
|
||||
) : (
|
||||
<Trans>Plugin support disabled</Trans>
|
||||
)}
|
||||
</Badge>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Trans>Server status</Trans>
|
||||
</td>
|
||||
<td>
|
||||
<OnlyStaff>
|
||||
<Badge color={server.system_health ? 'green' : 'yellow'}>
|
||||
{server.system_health ? (
|
||||
<Trans>Healthy</Trans>
|
||||
) : (
|
||||
<Trans>Issues detected</Trans>
|
||||
)}
|
||||
</Badge>
|
||||
</OnlyStaff>
|
||||
</td>
|
||||
</tr>
|
||||
{server.worker_running != true && (
|
||||
<tr>
|
||||
<td>
|
||||
<Trans>Background Worker</Trans>
|
||||
</td>
|
||||
<td>
|
||||
<Badge color="red">
|
||||
<Trans>Background worker not running</Trans>
|
||||
</Badge>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{server.email_configured != true && (
|
||||
<tr>
|
||||
<td>
|
||||
<Trans>Email Settings</Trans>
|
||||
</td>
|
||||
<td>
|
||||
<Badge color="red">
|
||||
<Trans>Email settings not configured</Trans>
|
||||
</Badge>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</Table>
|
||||
<Title order={5}>
|
||||
<Trans>Version</Trans>
|
||||
</Title>
|
||||
<Table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<Trans>Server Version</Trans>
|
||||
</td>
|
||||
<td>{server.version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Trans>API Version</Trans>
|
||||
</td>
|
||||
<td>{server.apiVersion}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</Table>
|
||||
<Button
|
||||
color="red"
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
context.closeModal(id);
|
||||
}}
|
||||
>
|
||||
<Trans>Close modal</Trans>
|
||||
</Button>
|
||||
</Stack>
|
||||
);
|
||||
}
|
@ -10,6 +10,7 @@ import { ModalsProvider } from '@mantine/modals';
|
||||
import { Notifications } from '@mantine/notifications';
|
||||
|
||||
import { QrCodeModal } from '../components/modals/QrCodeModal';
|
||||
import { ServerInfoModal } from '../components/modals/ServerInfoModal';
|
||||
import { useLocalState } from '../states/LocalState';
|
||||
|
||||
export function ThemeContext({ children }: { children: JSX.Element }) {
|
||||
@ -60,7 +61,7 @@ export function ThemeContext({ children }: { children: JSX.Element }) {
|
||||
<Notifications />
|
||||
<ModalsProvider
|
||||
labels={{ confirm: t`Submit`, cancel: t`Cancel` }}
|
||||
modals={{ qr: QrCodeModal }}
|
||||
modals={{ qr: QrCodeModal, info: ServerInfoModal }}
|
||||
>
|
||||
{children}
|
||||
</ModalsProvider>
|
||||
|
@ -8,7 +8,12 @@ export const emptyServerAPI = {
|
||||
worker_running: null,
|
||||
worker_pending_tasks: null,
|
||||
plugins_enabled: null,
|
||||
active_plugins: []
|
||||
active_plugins: [],
|
||||
email_configured: null,
|
||||
debug_mode: null,
|
||||
docker_mode: null,
|
||||
database: null,
|
||||
system_health: null
|
||||
};
|
||||
|
||||
export interface SiteMarkProps {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { openContextModal } from '@mantine/modals';
|
||||
|
||||
import { DocumentationLinkItem } from '../components/items/DocumentationLinks';
|
||||
import { IS_DEV_OR_DEMO } from '../main';
|
||||
@ -69,18 +70,26 @@ export const navDocLinks: DocumentationLinkItem[] = [
|
||||
}
|
||||
];
|
||||
|
||||
function serverInfo() {
|
||||
return openContextModal({
|
||||
modal: 'info',
|
||||
title: <Trans>System Information</Trans>,
|
||||
size: 'xl',
|
||||
innerProps: {}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO @matmair: Add the following pages and adjust the links
|
||||
export const aboutLinks: DocumentationLinkItem[] = [
|
||||
{
|
||||
id: 'instance',
|
||||
title: <Trans>Instance</Trans>,
|
||||
title: <Trans>System Information</Trans>,
|
||||
description: <Trans>About this Inventree instance</Trans>,
|
||||
link: '/instance',
|
||||
placeholder: true
|
||||
action: serverInfo
|
||||
},
|
||||
{
|
||||
id: 'about',
|
||||
title: <Trans>InvenTree</Trans>,
|
||||
title: <Trans>About InvenTree</Trans>,
|
||||
description: <Trans>About the InvenTree org</Trans>,
|
||||
link: '/about',
|
||||
placeholder: true
|
||||
|
@ -28,6 +28,11 @@ export interface ServerAPIProps {
|
||||
worker_pending_tasks: null | number;
|
||||
plugins_enabled: null | boolean;
|
||||
active_plugins: PluginProps[];
|
||||
email_configured: null | boolean;
|
||||
debug_mode: null | boolean;
|
||||
docker_mode: null | boolean;
|
||||
database: null | string;
|
||||
system_health: null | boolean;
|
||||
}
|
||||
|
||||
// Type interface defining a single 'setting' object
|
||||
|
Loading…
Reference in New Issue
Block a user