2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-29 12:06:44 +00:00
InvenTree/src/frontend/src/components/dashboard/widgets/QueryCountDashboardWidget.tsx
Oliver 18e5b0df58
[PUI] Dashboard refactor (#8278)
* Refactor plugin components into <RemoteComponent />

* Clean up footer

* Allow BuildOrder list to be sorted by 'outstanding'

* Fix model name

* Update BuildOrderTable filter

* Add StockItemTable column

* Working towards new dashboard

* Cleanup unused imports

* Updates: Now rendering some custom widgets

* Define icons for model types

* Add icon

* Cleanup / refactor / delete

- Complete transfer of files into new structure

* Follow link for query count widgets

* Add some more widgets to the library

* Remove old dashboard link in header

* Remove feedback widget

* Bump API version

* Remove test widget

* Rename "Home" -> "Dashboard"

* Add some more widgets

* Pass 'editable' property through to widgets

* Cleanup

* Add drawer for selecting new widgets

* Allow different layouts per user on the same machine

* Fixes

* Add ability to *remove* widgets

* Add helpful button

* Add a keyboard shortcut

* Refactoring

* Add backend code for serving custom dashboard items

* Load dashboard items from plugins

* Tweak for dashboard item API query

- Refetch if user changes
- Tweak "loaded" value
- Prevent refetchOnMount

* Add message if no dashboard widgets are displayed

* Refactoring main navigation menu

- Group into sections
- Cleanup / consolidation
- General refactoring

* Remove playground

* Add backend field for storing dashboard layout

* Add extra type definitions for UseInstance

* Manual labels for builtin dashboard items

- Otherwise they will change with translation locale

* Shorten labels for more plugins

* Adjust DashboardMenu

* Reduce stored data

* Add widget filter by text

* Remove back-end settings

* Update playwright tests for dashboard

* Updated tests

* Refactor backend API for fetching plugin features

* Further fixes for back-end code

* More back-end fixes

* Refactor frontend:

- Custom panels
- Custom dashboard items

* Further backend fixes

* Yet more backend fixes

- Improve error handling

* Fix for custom plugin settings rendering

* Enable plugin panels for part index and stock index pages

* Cleanup

* Fix nav menu

* Update typing

* Helper func to return all plugin settings as a dict

* Update API version date

* Fix for UseInstancea

* typing fix

* Tweak layout callbacks

* Pass query parameters through to navigation functions

* Improve custom query display

* Add "news" widget

* Ensure links are prepended with base URL on receipt

* Update NewsWidget

* Bug fix

* Refactor template editor tests

* Refactor unit testing for test_ui_panels

* Unit test for dashboard item API endpoint

* Update comment

* Adjust playwright tests

* More playwright fixes

* Hide barcode scanning options if disabled

* Tweak dashboard widget

* Fix custom panel title

* Update documentation around UIMixin class

* Cleanup

* Additional docs

* Add icon def for 'error' ModelType

* Add error boundary to TemplateEditor component

* Fix so that it works with template editors and previews again

* Tweak error messages

* API unit test fixes

* Unit test fix

* More unit test fixes

* Playwright test tweaks

* Adjust error messages
2024-11-02 08:48:29 +11:00

132 lines
3.3 KiB
TypeScript

import {
ActionIcon,
Card,
Group,
Loader,
Skeleton,
Space,
Stack,
Text
} from '@mantine/core';
import { IconExternalLink } from '@tabler/icons-react';
import { useQuery } from '@tanstack/react-query';
import { on } from 'events';
import { ReactNode, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { api } from '../../../App';
import { ModelType } from '../../../enums/ModelType';
import { identifierString } from '../../../functions/conversion';
import { InvenTreeIcon, InvenTreeIconType } from '../../../functions/icons';
import { navigateToLink } from '../../../functions/navigation';
import { apiUrl } from '../../../states/ApiState';
import { useUserState } from '../../../states/UserState';
import { StylishText } from '../../items/StylishText';
import { ModelInformationDict } from '../../render/ModelType';
import { DashboardWidgetProps } from '../DashboardWidget';
/**
* A simple dashboard widget for displaying the number of results for a particular query
*/
function QueryCountWidget({
modelType,
title,
icon,
params
}: {
modelType: ModelType;
title: string;
icon?: InvenTreeIconType;
params: any;
}): ReactNode {
const user = useUserState();
const navigate = useNavigate();
const modelProperties = ModelInformationDict[modelType];
const query = useQuery({
queryKey: ['dashboard-query-count', modelType, params],
enabled: user.hasViewPermission(modelType),
refetchOnMount: true,
queryFn: () => {
return api
.get(apiUrl(modelProperties.api_endpoint), {
params: {
...params,
limit: 1
}
})
.then((res) => res.data);
}
});
const onFollowLink = useCallback(
(event: any) => {
if (modelProperties.url_overview) {
let url = modelProperties.url_overview;
if (params) {
url += '?';
for (const key in params) {
url += `${key}=${params[key]}&`;
}
}
navigateToLink(url, navigate, event);
}
},
[modelProperties, params]
);
// TODO: Improve visual styling
return (
<Group gap="xs" wrap="nowrap">
<InvenTreeIcon icon={icon ?? modelProperties.icon} />
<Group gap="xs" wrap="nowrap" justify="space-between">
<StylishText size="md">{title}</StylishText>
<Group gap="xs" wrap="nowrap" justify="right">
{query.isFetching ? (
<Loader size="sm" />
) : (
<StylishText size="sm">{query.data?.count ?? '-'}</StylishText>
)}
{modelProperties?.url_overview && (
<ActionIcon size="sm" variant="transparent" onClick={onFollowLink}>
<IconExternalLink />
</ActionIcon>
)}
</Group>
</Group>
</Group>
);
}
/**
* Construct a dashboard widget descriptor, which displays the number of results for a particular query
*/
export default function QueryCountDashboardWidget({
label,
title,
description,
modelType,
params
}: {
label: string;
title: string;
description: string;
modelType: ModelType;
params: any;
}): DashboardWidgetProps {
return {
label: label,
title: title,
description: description,
minWidth: 2,
minHeight: 1,
render: () => (
<QueryCountWidget modelType={modelType} title={title} params={params} />
)
};
}