From 8aad3eeefa2fd29942b926f1063449cac45baf49 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Sun, 29 Oct 2023 23:56:07 +0100 Subject: [PATCH] [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 --- InvenTree/InvenTree/api.py | 12 +- InvenTree/InvenTree/api_version.py | 5 +- InvenTree/InvenTree/version.py | 6 + .../part/templatetags/inventree_extras.py | 8 +- .../components/items/DocumentationLinks.tsx | 76 ++++++++-- .../src/components/items/OnlyStaff.tsx | 10 ++ .../src/components/modals/ServerInfoModal.tsx | 141 ++++++++++++++++++ src/frontend/src/contexts/ThemeContext.tsx | 3 +- src/frontend/src/defaults/defaults.tsx | 7 +- src/frontend/src/defaults/links.tsx | 17 ++- src/frontend/src/states/states.tsx | 5 + 11 files changed, 257 insertions(+), 33 deletions(-) create mode 100644 src/frontend/src/components/items/OnlyStaff.tsx create mode 100644 src/frontend/src/components/modals/ServerInfoModal.tsx diff --git a/InvenTree/InvenTree/api.py b/InvenTree/InvenTree/api.py index b1947e1582..d2524f9fc4 100644 --- a/InvenTree/InvenTree/api.py +++ b/InvenTree/InvenTree/api.py @@ -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) diff --git a/InvenTree/InvenTree/api_version.py b/InvenTree/InvenTree/api_version.py index 98a7c71143..3697898dea 100644 --- a/InvenTree/InvenTree/api_version.py +++ b/InvenTree/InvenTree/api_version.py @@ -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 diff --git a/InvenTree/InvenTree/version.py b/InvenTree/InvenTree/version.py index 4b7b0efe49..72b6455ca6 100644 --- a/InvenTree/InvenTree/version.py +++ b/InvenTree/InvenTree/version.py @@ -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.', '') diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 753a63dc34..8e7e488bad 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -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() diff --git a/src/frontend/src/components/items/DocumentationLinks.tsx b/src/frontend/src/components/items/DocumentationLinks.tsx index 6d8b18a5b7..5d652db40a 100644 --- a/src/frontend/src/components/items/DocumentationLinks.tsx +++ b/src/frontend/src/components/items/DocumentationLinks.tsx @@ -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 = ( + + {link.title} + + ); + + const Linker = ({ children }: { children: any }) => { + if (link.link) + return ( + + {children} + + ); + + if (link.action) + return ( + + {children} + + ); + + console.log('Neither link nor action found for link:', link); + return children; + }; + + return ( + + {link.placeholder ? ( + + {content} + + + ) : ( + content + )} + + ); + }; + return ( {links.map((link) => ( - - {link.placeholder ? ( - - - {link.title} - - - - ) : ( - - {link.title} - - )} - + ))} diff --git a/src/frontend/src/components/items/OnlyStaff.tsx b/src/frontend/src/components/items/OnlyStaff.tsx new file mode 100644 index 0000000000..6b8816d9d3 --- /dev/null +++ b/src/frontend/src/components/items/OnlyStaff.tsx @@ -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 This information is only available for staff users; +}; diff --git a/src/frontend/src/components/modals/ServerInfoModal.tsx b/src/frontend/src/components/modals/ServerInfoModal.tsx new file mode 100644 index 0000000000..ee244cd6a1 --- /dev/null +++ b/src/frontend/src/components/modals/ServerInfoModal.tsx @@ -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 ( + + + <Trans>Server</Trans> + + + + + + + + + + + + {server.debug_mode && ( + + + + + )} + {server.docker_mode && ( + + + + + )} + + + + + + + + + {server.worker_running != true && ( + + + + + )} + {server.email_configured != true && ( + + + + + )} + +
+ Instance Name + {server.instance}
+ Database + + {server.database} +
+ Bebug Mode + + Server is running in debug mode +
+ Docker Mode + + Server is deployed using docker +
+ Plugin Support + + + {server.plugins_enabled ? ( + Plugin support enabled + ) : ( + Plugin support disabled + )} + +
+ Server status + + + + {server.system_health ? ( + Healthy + ) : ( + Issues detected + )} + + +
+ Background Worker + + + Background worker not running + +
+ Email Settings + + + Email settings not configured + +
+ + <Trans>Version</Trans> + + + + + + + + + + + + +
+ Server Version + {server.version}
+ API Version + {server.apiVersion}
+ +
+ ); +} diff --git a/src/frontend/src/contexts/ThemeContext.tsx b/src/frontend/src/contexts/ThemeContext.tsx index 66db20e48d..92ed79f454 100644 --- a/src/frontend/src/contexts/ThemeContext.tsx +++ b/src/frontend/src/contexts/ThemeContext.tsx @@ -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 }) { {children} diff --git a/src/frontend/src/defaults/defaults.tsx b/src/frontend/src/defaults/defaults.tsx index 09cfdc8f25..f9f161c081 100644 --- a/src/frontend/src/defaults/defaults.tsx +++ b/src/frontend/src/defaults/defaults.tsx @@ -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 { diff --git a/src/frontend/src/defaults/links.tsx b/src/frontend/src/defaults/links.tsx index 93fc816d76..08032b19db 100644 --- a/src/frontend/src/defaults/links.tsx +++ b/src/frontend/src/defaults/links.tsx @@ -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: System Information, + size: 'xl', + innerProps: {} + }); +} + // TODO @matmair: Add the following pages and adjust the links export const aboutLinks: DocumentationLinkItem[] = [ { id: 'instance', - title: Instance, + title: System Information, description: About this Inventree instance, - link: '/instance', - placeholder: true + action: serverInfo }, { id: 'about', - title: InvenTree, + title: About InvenTree, description: About the InvenTree org, link: '/about', placeholder: true diff --git a/src/frontend/src/states/states.tsx b/src/frontend/src/states/states.tsx index 29b97452f9..5e67621d6b 100644 --- a/src/frontend/src/states/states.tsx +++ b/src/frontend/src/states/states.tsx @@ -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