Fix creating template from validate table row

This commit is contained in:
2025-03-09 16:11:49 -04:00
parent c3c48669ad
commit 7cc723ce83
2 changed files with 153 additions and 1613 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -6,13 +6,14 @@ import { Loader2, X, Plus, Edit3, Sparkles, FileText } from 'lucide-react'
import { toast } from 'sonner'
import { Switch } from '@/components/ui/switch'
import { useRsi } from '../../../hooks/useRsi'
import { ProductSearchDialog } from '@/components/products/ProductSearchDialog'
import SearchableTemplateSelect from './SearchableTemplateSelect'
import { useAiValidation } from '../hooks/useAiValidation'
import { AiValidationDialogs } from './AiValidationDialogs'
import config from '@/config'
import { Fields } from '../../../types'
import { SearchProductTemplateDialog } from '@/components/templates/SearchProductTemplateDialog'
import { TemplateForm } from '@/components/templates/TemplateForm'
import axios from 'axios'
/**
* ValidationContainer component - the main wrapper for the validation step
@@ -576,6 +577,143 @@ const ValidationContainer = <T extends string>({
// State for product search dialog
const [isProductSearchDialogOpen, setIsProductSearchDialogOpen] = useState(false)
// Add new state for template form dialog
const [isTemplateFormOpen, setIsTemplateFormOpen] = useState(false)
const [templateFormInitialData, setTemplateFormInitialData] = useState<any>(null)
const [fieldOptions, setFieldOptions] = useState<any>(null)
// Function to fetch field options for template form
const fetchFieldOptions = useCallback(async () => {
try {
const response = await axios.get('/api/import/field-options');
console.log('Field options from API:', response.data);
// Check if suppliers are included in the response
if (response.data && response.data.suppliers) {
console.log('Suppliers available:', response.data.suppliers.length);
} else {
console.warn('No suppliers found in field options response');
}
setFieldOptions(response.data);
return response.data;
} catch (error) {
console.error('Error fetching field options:', error);
toast.error('Failed to load field options');
return null;
}
}, []);
// Function to prepare row data for the template form
const prepareRowDataForTemplateForm = useCallback(() => {
// Get the selected row key (should be only one)
const selectedKey = Object.entries(rowSelection)
.filter(([_, selected]) => selected === true)
.map(([key, _]) => key)[0];
if (!selectedKey) return null;
// Try to find the row in the data array
let selectedRow;
// First check if the key is an index in filteredData
const numericIndex = parseInt(selectedKey);
if (!isNaN(numericIndex) && numericIndex >= 0 && numericIndex < filteredData.length) {
selectedRow = filteredData[numericIndex];
}
// If not found by index, try to find it by __index property
if (!selectedRow) {
selectedRow = data.find(row => row.__index === selectedKey);
}
// If still not found, return null
if (!selectedRow) {
console.error('Selected row not found:', selectedKey);
return null;
}
// TemplateForm expects supplier as a NUMBER - the field options have numeric values
// Convert the supplier to a number if possible
let supplierValue;
if (selectedRow.supplier) {
const numSupplier = Number(selectedRow.supplier);
supplierValue = !isNaN(numSupplier) ? numSupplier : selectedRow.supplier;
} else {
supplierValue = undefined;
}
// Create template form data with the correctly typed supplier value
return {
company: selectedRow.company || '',
product_type: selectedRow.product_type || '',
supplier: supplierValue,
msrp: selectedRow.msrp ? Number(Number(selectedRow.msrp).toFixed(2)) : undefined,
cost_each: selectedRow.cost_each ? Number(Number(selectedRow.cost_each).toFixed(2)) : undefined,
qty_per_unit: selectedRow.qty_per_unit ? Number(selectedRow.qty_per_unit) : undefined,
case_qty: selectedRow.case_qty ? Number(selectedRow.case_qty) : undefined,
hts_code: selectedRow.hts_code || undefined,
description: selectedRow.description || undefined,
weight: selectedRow.weight ? Number(Number(selectedRow.weight).toFixed(2)) : undefined,
length: selectedRow.length ? Number(Number(selectedRow.length).toFixed(2)) : undefined,
width: selectedRow.width ? Number(Number(selectedRow.width).toFixed(2)) : undefined,
height: selectedRow.height ? Number(Number(selectedRow.height).toFixed(2)) : undefined,
tax_cat: selectedRow.tax_cat ? String(selectedRow.tax_cat) : undefined,
size_cat: selectedRow.size_cat ? String(selectedRow.size_cat) : undefined,
categories: Array.isArray(selectedRow.categories) ? selectedRow.categories :
(selectedRow.categories ? [selectedRow.categories] : []),
ship_restrictions: selectedRow.ship_restrictions ? String(selectedRow.ship_restrictions) : undefined
};
}, [data, filteredData, rowSelection]);
// Add useEffect to fetch field options when template form opens
useEffect(() => {
if (isTemplateFormOpen && !fieldOptions) {
fetchFieldOptions();
}
}, [isTemplateFormOpen, fieldOptions, fetchFieldOptions]);
// Function to handle opening the template form
const openTemplateForm = useCallback(async () => {
const templateData = prepareRowDataForTemplateForm();
if (!templateData) return;
setTemplateFormInitialData(templateData);
// Always fetch fresh field options to ensure supplier list is up to date
try {
const options = await fetchFieldOptions();
if (options && options.suppliers) {
console.log(`Loaded ${options.suppliers.length} suppliers for template form`);
// Log if we can find a match for our supplier
if (templateData.supplier !== undefined) {
// Need to compare numeric values since supplier options have numeric values
const supplierMatch = options.suppliers.find(s =>
s.value === templateData.supplier ||
Number(s.value) === Number(templateData.supplier)
);
console.log('Found supplier match:', supplierMatch ? 'Yes' : 'No',
'For supplier value:', templateData.supplier,
'Type:', typeof templateData.supplier);
if (supplierMatch) {
console.log('Matched supplier:', supplierMatch.label);
}
}
setIsTemplateFormOpen(true);
} else {
console.error('Failed to load suppliers for template form');
toast.error('Could not load supplier options');
}
} catch (error) {
console.error('Error loading field options:', error);
toast.error('Failed to prepare template form');
}
}, [prepareRowDataForTemplateForm, fetchFieldOptions]);
// Handle next button click - memoized
const handleNext = useCallback(() => {
// Make sure any pending item numbers are applied
@@ -864,7 +1002,7 @@ const ValidationContainer = <T extends string>({
<Button
variant="outline"
size="sm"
onClick={() => setIsProductSearchDialogOpen(true)}
onClick={openTemplateForm}
>
Save as Template
</Button>
@@ -956,6 +1094,19 @@ const ValidationContainer = <T extends string>({
onClose={() => setIsProductSearchDialogOpen(false)}
onTemplateCreated={loadTemplates}
/>
{/* Template Form Dialog */}
<TemplateForm
isOpen={isTemplateFormOpen}
onClose={() => setIsTemplateFormOpen(false)}
onSuccess={() => {
loadTemplates();
setIsTemplateFormOpen(false);
}}
initialData={templateFormInitialData}
mode="create"
fieldOptions={fieldOptions}
/>
</div>
)
}