mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 11:36:44 +00:00
[PUI] Add currency stats (#7971)
* factor out stats overview * move to panel * Add currency stas overview Closes https://github.com/invenhost/InvenTree/issues/115
This commit is contained in:
parent
ed2da62a46
commit
8a59829ef1
19
src/frontend/src/components/settings/FactCollection.tsx
Normal file
19
src/frontend/src/components/settings/FactCollection.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { SimpleGrid } from '@mantine/core';
|
||||||
|
|
||||||
|
import { FactItem } from './FactItem';
|
||||||
|
|
||||||
|
export function FactCollection({
|
||||||
|
items,
|
||||||
|
minItems = 3
|
||||||
|
}: {
|
||||||
|
items: { title: string; value: any }[];
|
||||||
|
minItems?: number;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<SimpleGrid cols={minItems} spacing="xs">
|
||||||
|
{items.map((item, index) => (
|
||||||
|
<FactItem key={index} title={item.title} value={item.value} />
|
||||||
|
))}
|
||||||
|
</SimpleGrid>
|
||||||
|
);
|
||||||
|
}
|
14
src/frontend/src/components/settings/FactItem.tsx
Normal file
14
src/frontend/src/components/settings/FactItem.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { Paper, Stack, Text } from '@mantine/core';
|
||||||
|
|
||||||
|
import { StylishText } from '../items/StylishText';
|
||||||
|
|
||||||
|
export function FactItem({ title, value }: { title: string; value: number }) {
|
||||||
|
return (
|
||||||
|
<Paper p="md" shadow="xs">
|
||||||
|
<Stack gap="xs">
|
||||||
|
<StylishText size="md">{title}</StylishText>
|
||||||
|
<Text>{value}</Text>
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
}
|
@ -1,21 +1,24 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
|
import { Divider, Stack } from '@mantine/core';
|
||||||
import { showNotification } from '@mantine/notifications';
|
import { showNotification } from '@mantine/notifications';
|
||||||
import { IconReload } from '@tabler/icons-react';
|
import { IconReload } from '@tabler/icons-react';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { api } from '../../App';
|
import { api } from '../../../../App';
|
||||||
import { ActionButton } from '../../components/buttons/ActionButton';
|
import { ActionButton } from '../../../../components/buttons/ActionButton';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { FactCollection } from '../../../../components/settings/FactCollection';
|
||||||
import { useTable } from '../../hooks/UseTable';
|
import { ApiEndpoints } from '../../../../enums/ApiEndpoints';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { useTable } from '../../../../hooks/UseTable';
|
||||||
import { InvenTreeTable } from '../InvenTreeTable';
|
import { apiUrl } from '../../../../states/ApiState';
|
||||||
|
import { InvenTreeTable } from '../../../../tables/InvenTreeTable';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Table for displaying available currencies
|
* Table for displaying available currencies
|
||||||
*/
|
*/
|
||||||
export default function CurrencyTable() {
|
export function CurrencyTable({
|
||||||
|
setInfo
|
||||||
|
}: Readonly<{ setInfo: (info: any) => void }>) {
|
||||||
const table = useTable('currency');
|
const table = useTable('currency');
|
||||||
|
|
||||||
const columns = useMemo(() => {
|
const columns = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -53,6 +56,7 @@ export default function CurrencyTable() {
|
|||||||
const tableActions = useMemo(() => {
|
const tableActions = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
key="refresh"
|
||||||
onClick={refreshCurrencies}
|
onClick={refreshCurrencies}
|
||||||
tooltip={t`Refresh currency exchange rates`}
|
tooltip={t`Refresh currency exchange rates`}
|
||||||
icon={<IconReload />}
|
icon={<IconReload />}
|
||||||
@ -69,6 +73,7 @@ export default function CurrencyTable() {
|
|||||||
idAccessor: 'currency',
|
idAccessor: 'currency',
|
||||||
tableActions: tableActions,
|
tableActions: tableActions,
|
||||||
dataFormatter: (data: any) => {
|
dataFormatter: (data: any) => {
|
||||||
|
setInfo(data);
|
||||||
let rates = data.exchange_rates ?? {};
|
let rates = data.exchange_rates ?? {};
|
||||||
|
|
||||||
return Object.entries(rates).map(([currency, rate]) => {
|
return Object.entries(rates).map(([currency, rate]) => {
|
||||||
@ -82,3 +87,20 @@ export default function CurrencyTable() {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default function CurrencyManagmentPanel() {
|
||||||
|
const [info, setInfo] = useState<any>({});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack gap="xs">
|
||||||
|
<FactCollection
|
||||||
|
items={[
|
||||||
|
{ title: t`Last fetched`, value: info?.updated },
|
||||||
|
{ title: t`Base currency`, value: info?.base_currency }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<Divider />
|
||||||
|
<CurrencyTable setInfo={setInfo} />
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
@ -48,6 +48,10 @@ const TaskManagementPanel = Loadable(
|
|||||||
lazy(() => import('./TaskManagementPanel'))
|
lazy(() => import('./TaskManagementPanel'))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const CurrencyManagmentPanel = Loadable(
|
||||||
|
lazy(() => import('./CurrencyManagmentPanel'))
|
||||||
|
);
|
||||||
|
|
||||||
const PluginManagementPanel = Loadable(
|
const PluginManagementPanel = Loadable(
|
||||||
lazy(() => import('./PluginManagementPanel'))
|
lazy(() => import('./PluginManagementPanel'))
|
||||||
);
|
);
|
||||||
@ -88,10 +92,6 @@ const LocationTypesTable = Loadable(
|
|||||||
lazy(() => import('../../../../tables/stock/LocationTypesTable'))
|
lazy(() => import('../../../../tables/stock/LocationTypesTable'))
|
||||||
);
|
);
|
||||||
|
|
||||||
const CurrencyTable = Loadable(
|
|
||||||
lazy(() => import('../../../../tables/settings/CurrencyTable'))
|
|
||||||
);
|
|
||||||
|
|
||||||
export default function AdminCenter() {
|
export default function AdminCenter() {
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ export default function AdminCenter() {
|
|||||||
name: 'currencies',
|
name: 'currencies',
|
||||||
label: t`Currencies`,
|
label: t`Currencies`,
|
||||||
icon: <IconCoins />,
|
icon: <IconCoins />,
|
||||||
content: <CurrencyTable />
|
content: <CurrencyManagmentPanel />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'projectcodes',
|
name: 'projectcodes',
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import {
|
import { Accordion, Alert, Divider, Stack, Text } from '@mantine/core';
|
||||||
Accordion,
|
|
||||||
Alert,
|
|
||||||
Divider,
|
|
||||||
Paper,
|
|
||||||
SimpleGrid,
|
|
||||||
Stack,
|
|
||||||
Text
|
|
||||||
} from '@mantine/core';
|
|
||||||
import { lazy } from 'react';
|
import { lazy } from 'react';
|
||||||
|
|
||||||
import { StylishText } from '../../../../components/items/StylishText';
|
import { StylishText } from '../../../../components/items/StylishText';
|
||||||
|
import { FactCollection } from '../../../../components/settings/FactCollection';
|
||||||
import { ApiEndpoints } from '../../../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../../../enums/ApiEndpoints';
|
||||||
import { Loadable } from '../../../../functions/loading';
|
import { Loadable } from '../../../../functions/loading';
|
||||||
import { useInstance } from '../../../../hooks/UseInstance';
|
import { useInstance } from '../../../../hooks/UseInstance';
|
||||||
@ -27,17 +20,6 @@ const FailedTasksTable = Loadable(
|
|||||||
lazy(() => import('../../../../tables/settings/FailedTasksTable'))
|
lazy(() => import('../../../../tables/settings/FailedTasksTable'))
|
||||||
);
|
);
|
||||||
|
|
||||||
function TaskCountOverview({ title, value }: { title: string; value: number }) {
|
|
||||||
return (
|
|
||||||
<Paper p="md" shadow="xs">
|
|
||||||
<Stack gap="xs">
|
|
||||||
<StylishText size="md">{title}</StylishText>
|
|
||||||
<Text>{value}</Text>
|
|
||||||
</Stack>
|
|
||||||
</Paper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function TaskManagementPanel() {
|
export default function TaskManagementPanel() {
|
||||||
const { instance: taskInfo } = useInstance({
|
const { instance: taskInfo } = useInstance({
|
||||||
endpoint: ApiEndpoints.task_overview,
|
endpoint: ApiEndpoints.task_overview,
|
||||||
@ -55,20 +37,13 @@ export default function TaskManagementPanel() {
|
|||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
<Stack gap="xs">
|
<Stack gap="xs">
|
||||||
<SimpleGrid cols={3} spacing="xs">
|
<FactCollection
|
||||||
<TaskCountOverview
|
items={[
|
||||||
title={t`Pending Tasks`}
|
{ title: t`Pending Tasks`, value: taskInfo?.pending_tasks },
|
||||||
value={taskInfo?.pending_tasks}
|
{ title: t`Scheduled Tasks`, value: taskInfo?.scheduled_tasks },
|
||||||
/>
|
{ title: t`Failed Tasks`, value: taskInfo?.failed_tasks }
|
||||||
<TaskCountOverview
|
]}
|
||||||
title={t`Scheduled Tasks`}
|
/>
|
||||||
value={taskInfo?.scheduled_tasks}
|
|
||||||
/>
|
|
||||||
<TaskCountOverview
|
|
||||||
title={t`Failed Tasks`}
|
|
||||||
value={taskInfo?.failed_tasks}
|
|
||||||
/>
|
|
||||||
</SimpleGrid>
|
|
||||||
<Divider />
|
<Divider />
|
||||||
<Accordion defaultValue="pending">
|
<Accordion defaultValue="pending">
|
||||||
<Accordion.Item value="pending" key="pending-tasks">
|
<Accordion.Item value="pending" key="pending-tasks">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user