diff --git a/lint_output.txt b/lint_output.txt deleted file mode 100644 index 875024b..0000000 --- a/lint_output.txt +++ /dev/null @@ -1,14 +0,0 @@ - -> react-example@0.0.0 lint -> tsc --noEmit - -src/components/PricingView.tsx(200,25): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. -src/components/PricingView.tsx(201,26): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. -src/components/PricingView.tsx(203,23): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. -src/components/PricingView.tsx(1042,16): error TS2741: Property 'triggerId' is missing in type '{ value: { terms: string[]; op: "and" | "or"; }; onChange: (value: { terms: string[]; op: "and" | "or"; } | ((prev: { terms: string[]; op: "and" | "or"; }) => { terms: string[]; op: "and" | "or"; })) => void; onClose: () => any; }' but required in type '{ value: { terms: string[]; op: "and" | "or"; }; onChange: (v: { terms: string[]; op: "and" | "or"; }) => void; onClose: () => void; triggerId: string; }'. -src/components/PricingView.tsx(1304,23): error TS2322: Type '{ triggerId: string; value: { terms: string[]; op: "and" | "or"; }; onChange: (value: { terms: string[]; op: "and" | "or"; } | ((prev: { terms: string[]; op: "and" | "or"; }) => { terms: string[]; op: "and" | "or"; })) => void; onClose: () => any; zIndex: number; }' is not assignable to type '{ value: { terms: string[]; op: "and" | "or"; }; onChange: (v: { terms: string[]; op: "and" | "or"; }) => void; onClose: () => void; triggerId: string; }'. - Property 'zIndex' does not exist on type '{ value: { terms: string[]; op: "and" | "or"; }; onChange: (v: { terms: string[]; op: "and" | "or"; }) => void; onClose: () => void; triggerId: string; }'. -src/components/PricingView.tsx(1339,23): error TS2322: Type '{ triggerId: string; value: { terms: string[]; op: "and" | "or"; }; onChange: (value: { terms: string[]; op: "and" | "or"; } | ((prev: { terms: string[]; op: "and" | "or"; }) => { terms: string[]; op: "and" | "or"; })) => void; onClose: () => any; zIndex: number; }' is not assignable to type '{ value: { terms: string[]; op: "and" | "or"; }; onChange: (v: { terms: string[]; op: "and" | "or"; }) => void; onClose: () => void; triggerId: string; }'. - Property 'zIndex' does not exist on type '{ value: { terms: string[]; op: "and" | "or"; }; onChange: (v: { terms: string[]; op: "and" | "or"; }) => void; onClose: () => void; triggerId: string; }'. -src/components/ProductDescriptions.tsx(205,21): error TS2304: Cannot find name 'TabType'. -src/types.ts(50,14): error TS2740: Type '{ ARTICLE_NO: string[]; ARTICLE_NAME: string[]; LINE: string[]; LICENSE: string[]; DETAILS_EN: string[]; DETAILS_DE: string[]; BARCODE: string[]; TARIFF_CODE: string[]; COUNTRY_ORIGIN: string[]; LONG_DE: string[]; ... 15 more ...; OUTER_H: string[]; }' is missing the following properties from type 'Record<"ASIN" | "ARTICLE_NO" | "ARTICLE_NAME" | "LINE" | "LICENSE" | "DETAILS_EN" | "DETAILS_DE" | "BARCODE" | "TARIFF_CODE" | "COUNTRY_ORIGIN" | "LONG_DE" | "LONG_EN" | "SHORT_DE" | ... 19 more ... | "ANNA_NOTE", string[]>': VERIFIED_DIMS, VALIDATED_CHECK, VALIDATED_NOTE, PRODUCT_TYPE, and 3 more. diff --git a/src/components/PricingView.tsx b/src/components/PricingView.tsx index 2118d7f..be091da 100644 --- a/src/components/PricingView.tsx +++ b/src/components/PricingView.tsx @@ -105,7 +105,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, const [checkYingFilter, setCheckYingFilter] = usePersistentState('pricing-checkYingFilter', []); const [checkAnnaFilter, setCheckAnnaFilter] = usePersistentState('pricing-checkAnnaFilter', []); const [dynamicColFilters, setDynamicColFilters] = usePersistentState>('pricing-dynamicColFilters', {}); - const [weightIssueFilter, setWeightIssueFilter] = usePersistentState<'all' | 'with' | 'without'>('pricing-weightIssueFilter', 'all'); + const [weightIssueFilter, setWeightIssueFilter] = usePersistentState('pricing-weightIssueFilter', []); const [selectedSearchItems, setSelectedSearchItems] = usePersistentState>('pricing-selectedSearchItems', new Set()); const [openFilter, setOpenFilter] = useState(null); const [isSearchOpen, setIsSearchOpen] = useState(false); @@ -115,15 +115,12 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, const [pinnedColumns, setPinnedColumns] = usePersistentState>('pricing-pinnedColumns', new Set(['articleNo', 'articleName'])); const [showPinPanel, setShowPinPanel] = useState(false); - // Drag-to-check state (Excel-style drag to toggle Check Ying) + // Drag-to-select state (Excel-style row selection) const [dragSelectedRows, setDragSelectedRows] = useState>(new Set()); const isDraggingRef = useRef(false); const dragStartIndexRef = useRef(null); - const dragCheckValueRef = useRef(true); // what value to set on mouseup const lastDragIndexRef = useRef(null); const visibleDataIndexesRef = useRef([]); - const dataRef = useRef(data); - dataRef.current = data; const handleRowMouseDown = useCallback((e: React.MouseEvent, dataIndex: number) => { if ((e.target as HTMLElement).closest('input, button, a')) return; @@ -131,10 +128,8 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, isDraggingRef.current = true; dragStartIndexRef.current = dataIndex; lastDragIndexRef.current = dataIndex; - // Toggle based on current state of the first row touched - dragCheckValueRef.current = !dataRef.current[dataIndex]?.[COLUMNS.VALIDATED_CHECK]; setDragSelectedRows(new Set([dataIndex])); - }, [COLUMNS.VALIDATED_CHECK]); + }, []); const handleRowMouseEnter = useCallback((dataIndex: number) => { if (!isDraggingRef.current || dragStartIndexRef.current === null) return; @@ -155,19 +150,18 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, }, []); useEffect(() => { - const handleMouseUp = async () => { - if (!isDraggingRef.current) return; - isDraggingRef.current = false; - const rows = new Set(dragSelectedRows); - if (rows.size === 0) return; - setDragSelectedRows(new Set()); - const targetValue = dragCheckValueRef.current; - for (const idx of Array.from(rows)) { - await handleToggleCheck(idx as number, targetValue); - } - }; + const handleMouseUp = () => { isDraggingRef.current = false; }; document.addEventListener('mouseup', handleMouseUp); return () => document.removeEventListener('mouseup', handleMouseUp); + }, []); + + const applyCheckToSelection = useCallback(async (column: 'ying' | 'anna', value: boolean) => { + const rows = Array.from(dragSelectedRows) as number[]; + setDragSelectedRows(new Set()); + for (const idx of rows) { + if (column === 'ying') await handleToggleCheck(idx, value); + else await handleToggleAnnaCheck(idx, value); + } }, [dragSelectedRows]); // Close search dropdown on click outside @@ -499,10 +493,13 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, }); // Weight issue filter - if (weightIssueFilter === 'with') { - result = result.filter(r => r.unitErrors.some(e => e.startsWith('NW'))); - } else if (weightIssueFilter === 'without') { - result = result.filter(r => !r.unitErrors.some(e => e.startsWith('NW'))); + if ((weightIssueFilter || []).length > 0) { + result = result.filter(r => { + const hasWeightError = r.unitErrors.some(e => e.startsWith('NW')); + if (weightIssueFilter.includes('with') && hasWeightError) return true; + if (weightIssueFilter.includes('without') && !hasWeightError) return true; + return false; + }); } return result; @@ -1792,30 +1789,27 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit,
Weight Issues
{openFilter === 'weightIssue' && ( -
- {(['all', 'with', 'without'] as const).map(opt => ( - - ))} -
+ setWeightIssueFilter(prev => (prev || []).includes(val) ? (prev || []).filter(v => v !== val) : [...(prev || []), val])} + onSelectAll={vals => setWeightIssueFilter(vals || [])} + onClear={() => { setWeightIssueFilter([]); setOpenFilter(null); }} + onClose={() => setOpenFilter(null)} + zIndex={50} + /> )} @@ -1833,6 +1827,17 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, + {dragSelectedRows.size > 0 && ( +
e.stopPropagation()}> + ) => applyCheckToSelection('ying', e.target.checked)} + className="w-3.5 h-3.5 rounded border-blue-500 bg-slate-900 text-blue-600 cursor-pointer" + /> + {dragSelectedRows.size} filas +
+ )} {openFilter === 'check' && ( + {dragSelectedRows.size > 0 && ( +
e.stopPropagation()}> + ) => applyCheckToSelection('anna', e.target.checked)} + className="w-3.5 h-3.5 rounded border-pink-500 bg-slate-900 text-pink-600 cursor-pointer" + /> + {dragSelectedRows.size} filas +
+ )} {openFilter === 'checkAnna' && (