Fix creating template from validate table row
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user