diff --git a/src/frontend/CHANGELOG.md b/src/frontend/CHANGELOG.md
index 97db95266d..0abe69954f 100644
--- a/src/frontend/CHANGELOG.md
+++ b/src/frontend/CHANGELOG.md
@@ -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.
diff --git a/src/frontend/lib/hooks/MonitorDataOutput.tsx b/src/frontend/lib/hooks/MonitorDataOutput.tsx
index a03654cd69..dd75d846b5 100644
--- a/src/frontend/lib/hooks/MonitorDataOutput.tsx
+++ b/src/frontend/lib/hooks/MonitorDataOutput.tsx
@@ -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: ,
+ 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:
+ });
+
+ 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: (
+ 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: ,
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:
- });
-
- 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: (
- 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
+ );
}
diff --git a/src/frontend/package.json b/src/frontend/package.json
index 19eb78fa5a..af1046a375 100644
--- a/src/frontend/package.json
+++ b/src/frontend/package.json
@@ -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",
diff --git a/src/frontend/src/components/forms/fields/ApiFormField.tsx b/src/frontend/src/components/forms/fields/ApiFormField.tsx
index 88bbf034cc..793ab1f217 100644
--- a/src/frontend/src/components/forms/fields/ApiFormField.tsx
+++ b/src/frontend/src/components/forms/fields/ApiFormField.tsx
@@ -85,6 +85,7 @@ export function ApiFormField({
onValueChange: undefined,
adjustFilters: undefined,
adjustValue: undefined,
+ allow_null: undefined,
read_only: undefined,
children: undefined,
exclude: undefined
diff --git a/src/frontend/src/components/forms/fields/RelatedModelField.tsx b/src/frontend/src/components/forms/fields/RelatedModelField.tsx
index 85398bac35..9155bf3c4c 100644
--- a/src/frontend/src/components/forms/fields/RelatedModelField.tsx
+++ b/src/frontend/src/components/forms/fields/RelatedModelField.tsx
@@ -380,6 +380,7 @@ export function RelatedModelField({
onValueChange: undefined,
adjustFilters: undefined,
exclude: undefined,
+ allow_null: undefined,
read_only: undefined
};
}, [definition]);