Refactor spreadsheet processing to improve validation logic
Enhanced value cleaning and validation for spreadsheet data with dynamic handling of columns and corrections. Improved feedback for users with detailed error messages and visual indicators for corrected or defaulted values. Simplified backend and frontend logic for better maintainability and usability.
This commit is contained in:
@ -488,41 +488,48 @@ const SpreadsheetTable = ({
|
||||
{headers.map((header, colIndex) => {
|
||||
const key = `${row.row_num}-${header}`;
|
||||
const errorMessage = errorMap.get(key);
|
||||
const isInvalid = !!errorMap.get(`${row.row_num}-${headers[colIndex]}`);
|
||||
const isInvalid = !!errorMessage;
|
||||
const cellValue = row.data[colIndex];
|
||||
const editingValue = editingCell[`${rowIndex}-${colIndex}`];
|
||||
const isReadonly = !isInvalid && editingCell[`${rowIndex}-${colIndex}`] === undefined;
|
||||
const isCorrected = colIndex === 7 && row.corrected; // Corrected field exists and is true
|
||||
const isCellCorrected = row.corrected_columns?.includes(header); // Check if this column is marked as corrected
|
||||
const isDefaultAssigned = colIndex === 7 && row.default_set; // Default-assigned field exists and is true
|
||||
|
||||
|
||||
// Dynamic styles for corrected cells
|
||||
const cellStyle = {
|
||||
backgroundColor:
|
||||
isDefaultAssigned
|
||||
? "#e6fbe6" // Light green for default values
|
||||
: isCellCorrected
|
||||
? "#fff8e1" // Light yellow for corrected values
|
||||
: "transparent", // Default for others
|
||||
color: isDefaultAssigned
|
||||
? "#1b5e20" // Dark green for default values
|
||||
: "inherit", // Default for others
|
||||
fontWeight: (isCellCorrected || isDefaultAssigned) ? "bold" : "normal", // Bold text for any change
|
||||
cursor: isInvalid ? "pointer" : "default", // Mouse pointer indicates interactive error cells
|
||||
};
|
||||
|
||||
return (
|
||||
<TableCell
|
||||
key={colIndex}
|
||||
align="center"
|
||||
style={{
|
||||
backgroundColor:
|
||||
colIndex === 7 && isDefaultAssigned
|
||||
? "#e6fbe6" // Default value for "directory"
|
||||
: colIndex === 7 && isCorrected
|
||||
? "#fff8e1" // Corrected directory
|
||||
: "transparent", // No highlight for other columns
|
||||
color: colIndex === 7 && isDefaultAssigned
|
||||
? "#1b5e20" // Dark green text for default
|
||||
: "inherit", // Normal text
|
||||
}}
|
||||
style={cellStyle}
|
||||
>
|
||||
<Tooltip
|
||||
title={
|
||||
colIndex === 7 && isCorrected
|
||||
? "Value corrected automatically by the system."
|
||||
: errorMessage || "" // Show validation errors for other columns
|
||||
isDefaultAssigned
|
||||
? "This value was automatically assigned by the system as a default."
|
||||
: isCellCorrected
|
||||
? "Value corrected automatically by the system."
|
||||
: errorMessage || ""
|
||||
}
|
||||
arrow
|
||||
disableHoverListener={colIndex !== 7 && !errorMessage}
|
||||
disableHoverListener={!isDefaultAssigned && !isCellCorrected && !isInvalid}
|
||||
>
|
||||
{isInvalid ? (
|
||||
<TextField
|
||||
value={editingValue !== undefined ? editingValue : cellValue} // Ensure this reflects corrected value
|
||||
value={editingValue !== undefined ? editingValue : cellValue}
|
||||
onChange={(e) =>
|
||||
setEditingCell({
|
||||
...editingCell,
|
||||
@ -534,10 +541,9 @@ const SpreadsheetTable = ({
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
size="small"
|
||||
disabled={!isInvalid}
|
||||
/>
|
||||
) : (
|
||||
cellValue // This should reflect the updated 'raw_data'
|
||||
cellValue
|
||||
)}
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
|
@ -69,22 +69,26 @@ const UploadDialog: React.FC<UploadDialogProps> = ({ open, onClose, selectedShip
|
||||
|
||||
try {
|
||||
const response = await SpreadsheetService.uploadFileUploadPost(formData);
|
||||
const { headers, raw_data, errors, dewars_count, pucks_count, samples_count } = response;
|
||||
|
||||
setFileSummary({
|
||||
data: raw_data,
|
||||
errors: errors,
|
||||
raw_data: raw_data,
|
||||
headers: headers,
|
||||
dewars_count: dewars_count,
|
||||
pucks_count: pucks_count,
|
||||
samples_count: samples_count,
|
||||
...response,
|
||||
});
|
||||
|
||||
setIsLoading(false);
|
||||
setIsModalOpen(true);
|
||||
} catch (error) {
|
||||
setUploadError('Failed to upload file. Please try again.');
|
||||
} catch (error: any) {
|
||||
if (error.response?.status === 400 && error.response.data?.errors) {
|
||||
// Backend provided detailed error messages
|
||||
const detailedErrors = error.response.data.errors;
|
||||
setUploadError(
|
||||
"Validation errors detected in the file. Please review and correct the following issues:\n" +
|
||||
detailedErrors
|
||||
.map((err: any) => `Row ${err.row}: ${err.errors.map((e: any) => e.msg).join(", ")}`)
|
||||
.join("\n")
|
||||
);
|
||||
} else {
|
||||
// Fallback to generic error message
|
||||
setUploadError('Failed to upload file. Please try again.');
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user