2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-03-12 15:13:34 +00:00

Enhance MonitorDataOutput (#11458)

* Enhance MonitorDataOutput

- Optionally pass QueryClient
- Required when running outside of <ApiContext />

* Fix default base URL if not specified

* Remove "allow_null" from Mantine props

* Bump lib version to 0.8.2

* Bump CHANGELOG.md
This commit is contained in:
Oliver
2026-03-12 12:22:16 +11:00
committed by GitHub
parent f7da51b752
commit c292e807b9
5 changed files with 83 additions and 71 deletions

View File

@@ -2,6 +2,10 @@
This file contains historical changelog information for the InvenTree UI components library.
### 0.8.2 - March 2026
Bug fixes for the `monitorDataOutput` hook - https://github.com/inventree/InvenTree/pull/11458
### 0.8.0 - March 2026
Exposes the `monitorDataOutput` hook, which allows plugins to monitor the output of a long-running task and display notifications when the task is complete. This is useful for plugins that need to perform long-running tasks and want to provide feedback to the user when the task is complete.

View File

@@ -2,7 +2,7 @@ import { t } from '@lingui/core/macro';
import { useDocumentVisibility } from '@mantine/hooks';
import { notifications, showNotification } from '@mantine/notifications';
import { IconCircleCheck, IconExclamationCircle } from '@tabler/icons-react';
import { useQuery } from '@tanstack/react-query';
import { type QueryClient, useQuery } from '@tanstack/react-query';
import type { AxiosInstance } from 'axios';
import { useEffect, useState } from 'react';
import { ProgressBar } from '../components/ProgressBar';
@@ -14,11 +14,13 @@ import { apiUrl } from '../functions/Api';
*/
export default function monitorDataOutput({
api,
queryClient,
title,
hostname,
id
}: {
api: AxiosInstance;
queryClient?: QueryClient;
title: string;
hostname?: string;
id?: number;
@@ -41,82 +43,86 @@ export default function monitorDataOutput({
} else setLoading(false);
}, [id, title]);
useQuery({
enabled: !!id && loading && visibility === 'visible',
refetchInterval: 500,
queryKey: ['data-output', id, title],
queryFn: () =>
api
.get(apiUrl(ApiEndpoints.data_output, id))
.then((response) => {
const data = response?.data ?? {};
useQuery(
{
enabled: !!id && loading && visibility === 'visible',
refetchInterval: 500,
queryKey: ['data-output', id, title],
queryFn: () =>
api
.get(apiUrl(ApiEndpoints.data_output, id))
.then((response) => {
const data = response?.data ?? {};
if (!!data.errors || !!data.error) {
if (!!data.errors || !!data.error) {
setLoading(false);
const error: string =
data?.error ?? data?.errors?.error ?? t`Process failed`;
notifications.update({
id: `data-output-${id}`,
loading: false,
icon: <IconExclamationCircle />,
autoClose: 2500,
title: title,
message: error,
color: 'red'
});
} else if (data.complete) {
setLoading(false);
notifications.update({
id: `data-output-${id}`,
loading: false,
autoClose: 2500,
title: title,
message: t`Process completed successfully`,
color: 'green',
icon: <IconCircleCheck />
});
if (data.output) {
const url = data.output;
const base = hostname ?? window.location.origin;
const downloadUrl = new URL(url, base);
window.open(downloadUrl.toString(), '_blank');
}
} else {
notifications.update({
id: `data-output-${id}`,
loading: true,
autoClose: false,
withCloseButton: false,
message: (
<ProgressBar
size='lg'
maximum={data.total}
value={data.progress}
progressLabel={data.total > 0}
animated
/>
)
});
}
return data;
})
.catch((error: Error) => {
console.error('Error in monitorDataOutput:', error);
setLoading(false);
const error: string =
data?.error ?? data?.errors?.error ?? t`Process failed`;
notifications.update({
id: `data-output-${id}`,
loading: false,
icon: <IconExclamationCircle />,
autoClose: 2500,
title: title,
message: error,
message: error.message || t`Process failed`,
color: 'red'
});
} else if (data.complete) {
setLoading(false);
notifications.update({
id: `data-output-${id}`,
loading: false,
autoClose: 2500,
title: title,
message: t`Process completed successfully`,
color: 'green',
icon: <IconCircleCheck />
});
if (data.output) {
const url = data.output;
const base = hostname ?? window.location.hostname;
const downloadUrl = new URL(url, base);
window.open(downloadUrl.toString(), '_blank');
}
} else {
notifications.update({
id: `data-output-${id}`,
loading: true,
autoClose: false,
withCloseButton: false,
message: (
<ProgressBar
size='lg'
maximum={data.total}
value={data.progress}
progressLabel={data.total > 0}
animated
/>
)
});
}
return data;
})
.catch(() => {
setLoading(false);
notifications.update({
id: `data-output-${id}`,
loading: false,
autoClose: 2500,
title: title,
message: t`Process failed`,
color: 'red'
});
return {};
})
});
return {};
})
},
queryClient
);
}

View File

@@ -1,7 +1,7 @@
{
"name": "@inventreedb/ui",
"description": "UI components for the InvenTree project",
"version": "0.8.0",
"version": "0.8.2",
"private": false,
"type": "module",
"license": "MIT",

View File

@@ -85,6 +85,7 @@ export function ApiFormField({
onValueChange: undefined,
adjustFilters: undefined,
adjustValue: undefined,
allow_null: undefined,
read_only: undefined,
children: undefined,
exclude: undefined

View File

@@ -380,6 +380,7 @@ export function RelatedModelField({
onValueChange: undefined,
adjustFilters: undefined,
exclude: undefined,
allow_null: undefined,
read_only: undefined
};
}, [definition]);