2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-15 19:45:46 +00:00

[PUI] Added AboutInventreeModal (#5813)

* 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

* Refactored urls into seperate functions

* Refactored python version into seperate function

* Added endpoint and modal for PUI version modal

* switched to indirect imports to reduce imports

* Added copy button

* Added full copy button

* added default

* cleaned unused vars

* cleaned unused  vars

* Refactored auth check for InfoView

* implemented suggested changes

* fixed check logic
This commit is contained in:
Matthias Mair
2023-10-31 00:02:28 +01:00
committed by GitHub
parent 43fac17796
commit 782f36cd48
15 changed files with 335 additions and 24 deletions

View File

@ -1,5 +1,4 @@
import { ActionIcon, Menu, Tooltip } from '@mantine/core';
import { Component } from 'react';
/**
* A ButtonMenu is a button that opens a menu when clicked.

View File

@ -0,0 +1,28 @@
import { t } from '@lingui/macro';
import { Button, CopyButton as MantineCopyButton } from '@mantine/core';
import { IconCopy } from '@tabler/icons-react';
export function CopyButton({
value,
label
}: {
value: any;
label?: JSX.Element;
}) {
return (
<MantineCopyButton value={value}>
{({ copied, copy }) => (
<Button
color={copied ? 'teal' : 'gray'}
onClick={copy}
title={t`Copy to clipboard`}
variant="subtle"
compact
>
<IconCopy size={10} />
{label && label}
</Button>
)}
</MantineCopyButton>
);
}

View File

@ -0,0 +1,171 @@
import { Trans } from '@lingui/macro';
import { Anchor, Badge, Group, Stack, Table, Text, Title } from '@mantine/core';
import { ContextModalProps } from '@mantine/modals';
import { useQuery } from '@tanstack/react-query';
import { api } from '../../App';
import { ApiPaths, apiUrl, useServerApiState } from '../../states/ApiState';
import { useLocalState } from '../../states/LocalState';
import { useUserState } from '../../states/UserState';
import { CopyButton } from '../items/CopyButton';
type AboutLookupRef = {
ref: string;
title: JSX.Element;
link?: string;
copy?: boolean;
};
export function AboutInvenTreeModal({}: ContextModalProps<{
modalBody: string;
}>) {
const [user] = useUserState((state) => [state.user]);
const { host } = useLocalState.getState();
const [server] = useServerApiState((state) => [state.server]);
if (user?.is_staff != true)
return (
<Text>
<Trans>This information is only available for staff users</Trans>
</Text>
);
const { isLoading, data } = useQuery({
queryKey: ['version'],
queryFn: () => api.get(apiUrl(ApiPaths.version)).then((res) => res.data)
});
function fillTable(
lookup: AboutLookupRef[],
data: any,
alwaysLink: boolean = false
) {
return lookup.map((map: AboutLookupRef, idx) => (
<tr key={idx}>
<td>{map.title}</td>
<td>
<Group position="apart" spacing="xs">
{alwaysLink ? (
<Anchor href={data[map.ref]} target="_blank">
{data[map.ref]}
</Anchor>
) : map.link ? (
<Anchor href={map.link} target="_blank">
{data[map.ref]}
</Anchor>
) : (
data[map.ref]
)}
{map.copy && <CopyButton value={data[map.ref]} />}
</Group>
</td>
</tr>
));
}
/* renderer */
if (isLoading) return <Trans>Loading</Trans>;
const copyval = `InvenTree-Version: ${data.version.server}\nDjango Version: ${
data.version.django
}\n${
data.version.commit_hash &&
`Commit Hash: ${data.version.commit_hash}\nCommit Date: ${data.version.commit_date}\nCommit Branch: ${data.version.commit_branch}\n`
}Database: ${server.database}\nDebug-Mode: ${
server.debug_mode ? 'True' : 'False'
}\nDeployed using Docker: ${
server.docker_mode ? 'True' : 'False'
}\nPlatform: ${server.platform}\nInstaller: ${server.installer}\n${
server.target && `Target: ${server.target}\n`
}Active plugins: ${JSON.stringify(server.active_plugins)}`;
return (
<Stack>
<Group>
<Text>
<Trans>Your InvenTree version status is</Trans>
</Text>
{data.dev ? (
<Badge color="blue">
<Trans>Development Version</Trans>
</Badge>
) : data.up_to_date ? (
<Badge color="green">
<Trans>Up to Date</Trans>
</Badge>
) : (
<Badge color="teal">
<Trans>Update Available</Trans>
</Badge>
)}
</Group>
<Title order={5}>
<Trans>Version Information</Trans>
</Title>
<Table>
<tbody>
{fillTable(
[
{
ref: 'server',
title: <Trans>InvenTree Version</Trans>,
link: 'https://github.com/inventree/InvenTree/releases',
copy: true
},
{
ref: 'commit_hash',
title: <Trans>Commit Hash</Trans>,
copy: true
},
{
ref: 'commit_date',
title: <Trans>Commit Date</Trans>,
copy: true
},
{
ref: 'commit_branch',
title: <Trans>Commit Branch</Trans>,
copy: true
},
{
ref: 'api',
title: <Trans>API Version</Trans>,
link: `${host}api-doc/`
},
{ ref: 'python', title: <Trans>Python Version</Trans> },
{
ref: 'django',
title: <Trans>Django Version</Trans>,
link: 'https://www.djangoproject.com/',
copy: true
}
],
data.version
)}
</tbody>
</Table>
<Title order={5}>
<Trans>Links</Trans>
</Title>
<Table>
<tbody>
{fillTable(
[
{ ref: 'doc', title: <Trans>InvenTree Documentation</Trans> },
{ ref: 'code', title: <Trans>View Code on GitHub</Trans> },
{ ref: 'credit', title: <Trans>Credits</Trans> },
{ ref: 'app', title: <Trans>Mobile App</Trans> },
{ ref: 'bug', title: <Trans>Submit Bug Report</Trans> }
],
data.links,
true
)}
</tbody>
</Table>
<Group>
<CopyButton
value={copyval}
label={<Trans>Copy version information</Trans>}
/>
</Group>
</Stack>
);
}

View File

@ -9,6 +9,7 @@ import { useColorScheme, useLocalStorage } from '@mantine/hooks';
import { ModalsProvider } from '@mantine/modals';
import { Notifications } from '@mantine/notifications';
import { AboutInvenTreeModal } from '../components/modals/AboutInvenTreeModal';
import { QrCodeModal } from '../components/modals/QrCodeModal';
import { ServerInfoModal } from '../components/modals/ServerInfoModal';
import { useLocalState } from '../states/LocalState';
@ -61,7 +62,11 @@ export function ThemeContext({ children }: { children: JSX.Element }) {
<Notifications />
<ModalsProvider
labels={{ confirm: t`Submit`, cancel: t`Cancel` }}
modals={{ qr: QrCodeModal, info: ServerInfoModal }}
modals={{
qr: QrCodeModal,
info: ServerInfoModal,
about: AboutInvenTreeModal
}}
>
{children}
</ModalsProvider>

View File

@ -13,7 +13,10 @@ export const emptyServerAPI = {
debug_mode: null,
docker_mode: null,
database: null,
system_health: null
system_health: null,
platform: null,
installer: null,
target: null
};
export interface SiteMarkProps {

View File

@ -79,6 +79,15 @@ function serverInfo() {
});
}
function aboutInvenTree() {
return openContextModal({
modal: 'about',
title: <Trans>About InvenTree</Trans>,
size: 'xl',
innerProps: {}
});
}
// TODO @matmair: Add the following pages and adjust the links
export const aboutLinks: DocumentationLinkItem[] = [
{
@ -91,8 +100,7 @@ export const aboutLinks: DocumentationLinkItem[] = [
id: 'about',
title: <Trans>About InvenTree</Trans>,
description: <Trans>About the InvenTree org</Trans>,
link: '/about',
placeholder: true
action: aboutInvenTree
},
{
id: 'licenses',

View File

@ -4,7 +4,6 @@ import { IconBellCheck, IconBellExclamation } from '@tabler/icons-react';
import { useMemo } from 'react';
import { api } from '../App';
import { StylishText } from '../components/items/StylishText';
import { PageDetail } from '../components/nav/PageDetail';
import { PanelGroup } from '../components/nav/PanelGroup';
import { NotificationTable } from '../components/tables/notifications/NotificationsTable';

View File

@ -68,6 +68,7 @@ export enum ApiPaths {
barcode = 'api-barcode',
news = 'news',
global_status = 'api-global-status',
version = 'api-version',
// Build order URLs
build_order_list = 'api-build-list',
@ -158,6 +159,8 @@ export function apiEndpoint(path: ApiPaths): string {
return 'news/';
case ApiPaths.global_status:
return 'generic/status/';
case ApiPaths.version:
return 'version/';
case ApiPaths.build_order_list:
return 'build/';
case ApiPaths.build_order_attachment_list:

View File

@ -33,6 +33,9 @@ export interface ServerAPIProps {
docker_mode: null | boolean;
database: null | string;
system_health: null | boolean;
platform: null | string;
installer: null | string;
target: null | string;
}
// Type interface defining a single 'setting' object