mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-16 20:15:44 +00:00
* Move data export code out of "importer" directory * Refactoring to allow data export via plugin * Add brief docs framework * Add basic DataExportMixin class * Pass context data through to the serializer * Extract custom serializer * Refactoring * Add builtin plugin for BomExport * More refactoring * Cleanup for UseForm hooks * Allow GET methods in forms * Create new 'exporter' app * Refactor imports * Run cleanup task on boot * Add enumeration for plugin mixin types * Refactor with_mixin call * Generate export options serializer * Pass plugin information through * Offload export functionality to the plugin * Generate output * Download generated file * Refactor frontend code * Generate params for downloading * Pass custom fields through to the plugin * Implement multi-level export for BOM data * Export supplier and manufacturer information * Export substitute data * Remove old BOM exporter * Export part parameter data * Try different app order * Use GET instead of POST request - Less 'dangerous' - no chance of performing a destructive operation * Fix for constructing query parameters - Ignore any undefined values! * Trying something * Revert to POST - Required, other query data are ignored * Fix spelling mistakes * Remove SettingsMixin * Revert python version * Fix for settings.py * Fix missing return * Fix for label mixin code * Run playwright tests in --host mode * Fix for choice field - Prevent empty value if field is required * Remove debug prints * Update table header * Playwright tests for data export * Rename app from "exporter" to "data_exporter" * Add frontend table for export sessions * Updated playwright testing * Fix for unit test * Fix build order unit test * Back to using GET instead of POST - Otherwise, users need POST permissions to export! - A bit of trickery with the forms architecture * Fix remaining unit tests * Implement unit test for BOM export - Including test for custom plugin * Fix unit test * Bump API version * Enhanced playwright tests * Add debug for CI testing * Single unit test only (for debugging) * Fix typo * typo fix * Remove debugs * Docs updates * Revert typo * Update tests * Serializer fix * Fix typo * Offload data export to the background worker - Requires mocking the original request object - Will need some further unit testing! * Refactor existing models into DataOutput - Remove LabelOutput table - Remove ReportOutput table - Remove ExportOutput table - Consolidate into single API endpoint * Remove "output" tables from frontend * Refactor frontend hook to be generic * Frontend now works with background data export * Fix tasks.py * Adjust unit tests * Revert 'plugin_key' to 'plugin' * Improve user checking when printing * Updates * Remove erroneous migration file * Tweak plugin registry * Adjust playwright tests * Refactor data export - Convert into custom hook - Enable for calendar view also * Add playwright tests * Adjust unit testing * Tweak unit tests * Add extra timeout to data export * Fix for RUF045
126 lines
3.1 KiB
TypeScript
126 lines
3.1 KiB
TypeScript
import { t } from '@lingui/macro';
|
|
import { useQuery } from '@tanstack/react-query';
|
|
import { useMemo, useState } from 'react';
|
|
import type { ApiFormFieldSet } from '../components/forms/fields/ApiFormField';
|
|
import { useApi } from '../contexts/ApiContext';
|
|
import { extractAvailableFields } from '../functions/forms';
|
|
import useDataOutput from './UseDataOutput';
|
|
import { useCreateApiFormModal } from './UseForm';
|
|
|
|
/**
|
|
* Custom hook for managing data export functionality
|
|
* This is intended to be used from a table or calendar view,
|
|
* to export the data displayed in the table or calendar
|
|
*/
|
|
export default function useDataExport({
|
|
url,
|
|
enabled,
|
|
filters,
|
|
searchTerm
|
|
}: {
|
|
url: string;
|
|
enabled: boolean;
|
|
filters: any;
|
|
searchTerm?: string;
|
|
}) {
|
|
const api = useApi();
|
|
|
|
// Selected plugin to use for data export
|
|
const [pluginKey, setPluginKey] = useState<string>('inventree-exporter');
|
|
|
|
const [exportId, setExportId] = useState<number | undefined>(undefined);
|
|
|
|
const progress = useDataOutput({
|
|
title: t`Exporting Data`,
|
|
id: exportId
|
|
});
|
|
|
|
// Construct a set of export parameters
|
|
const exportParams = useMemo(() => {
|
|
const queryParams: Record<string, any> = {
|
|
export: true
|
|
};
|
|
|
|
if (!!pluginKey) {
|
|
queryParams.export_plugin = pluginKey;
|
|
}
|
|
|
|
// Add in any additional parameters which have a defined value
|
|
for (const [key, value] of Object.entries(filters ?? {})) {
|
|
if (value != undefined) {
|
|
queryParams[key] = value;
|
|
}
|
|
}
|
|
|
|
if (!!searchTerm) {
|
|
queryParams.search = searchTerm;
|
|
}
|
|
|
|
return queryParams;
|
|
}, [pluginKey, filters, searchTerm]);
|
|
|
|
// Fetch available export fields via OPTIONS request
|
|
const extraExportFields = useQuery({
|
|
enabled: !!url && enabled,
|
|
queryKey: ['export-fields', pluginKey, url, exportParams],
|
|
gcTime: 500,
|
|
queryFn: () =>
|
|
api
|
|
.options(url, {
|
|
params: exportParams
|
|
})
|
|
.then((response: any) => {
|
|
return extractAvailableFields(response, 'GET') || {};
|
|
})
|
|
.catch(() => {
|
|
return {};
|
|
})
|
|
});
|
|
|
|
// Construct a field set for the export form
|
|
const exportFields: ApiFormFieldSet = useMemo(() => {
|
|
const extraFields: ApiFormFieldSet = extraExportFields.data || {};
|
|
|
|
const fields: ApiFormFieldSet = {
|
|
export_format: {},
|
|
export_plugin: {},
|
|
...extraFields
|
|
};
|
|
|
|
fields.export_format = {
|
|
...fields.export_format,
|
|
required: true
|
|
};
|
|
|
|
fields.export_plugin = {
|
|
...fields.export_plugin,
|
|
required: true,
|
|
onValueChange: (value: string) => {
|
|
if (!!value) {
|
|
setPluginKey(value);
|
|
}
|
|
}
|
|
};
|
|
|
|
return fields;
|
|
}, [extraExportFields]);
|
|
|
|
// Modal for exporting data
|
|
const exportModal = useCreateApiFormModal({
|
|
url: url,
|
|
queryParams: new URLSearchParams(exportParams),
|
|
title: t`Export Data`,
|
|
method: 'GET',
|
|
fields: exportFields,
|
|
submitText: t`Export`,
|
|
successMessage: null,
|
|
timeout: 30 * 1000,
|
|
onFormSuccess: (response: any) => {
|
|
setExportId(response.pk);
|
|
setPluginKey('inventree-exporter');
|
|
}
|
|
});
|
|
|
|
return exportModal;
|
|
}
|