diff --git a/lint_output.txt b/lint_output.txt new file mode 100644 index 0000000..875024b --- /dev/null +++ b/lint_output.txt @@ -0,0 +1,14 @@ + +> 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 38f2822..2bcc1df 100644 --- a/src/components/PricingView.tsx +++ b/src/components/PricingView.tsx @@ -101,6 +101,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, const [outerWFilter, setOuterWFilter] = usePersistentState('pricing-outerWFilter', []); const [outerLFilter, setOuterLFilter] = usePersistentState('pricing-outerLFilter', []); const [outerHFilter, setOuterHFilter] = usePersistentState('pricing-outerHFilter', []); + const [moqFilter, setMoqFilter] = usePersistentState('pricing-moqFilter', []); const [checkYingFilter, setCheckYingFilter] = usePersistentState('pricing-checkYingFilter', []); const [checkAnnaFilter, setCheckAnnaFilter] = usePersistentState('pricing-checkAnnaFilter', []); const [dynamicColFilters, setDynamicColFilters] = usePersistentState>('pricing-dynamicColFilters', {}); @@ -368,6 +369,10 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, Array.from(new Set(data.map(r => String(r[COLUMNS.OUTER_H] || '')))).filter(v => v).sort((a, b) => Number(a) - Number(b)), [data]); + const uniqueMoq = useMemo(() => + Array.from(new Set(data.map(r => String(r[COLUMNS.MOQ] || '')))).filter(v => v).sort((a, b) => Number(a) - Number(b)), + [data]); + const uniqueItemToLogistic = useMemo(() => Array.from(new Set(data.map(r => String(r[COLUMNS.ITEM_TO_LOGISTIC] || '')))).filter(v => v).sort(), [data]); @@ -472,6 +477,9 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, if ((outerHFilter || []).length > 0) { result = result.filter(r => (outerHFilter || []).includes(String(r.row[COLUMNS.OUTER_H] || ''))); } + if ((moqFilter || []).length > 0) { + result = result.filter(r => (moqFilter || []).includes(String(r.row[COLUMNS.MOQ] || ''))); + } if ((itemToLogisticFilter || []).length > 0) { result = result.filter(r => (itemToLogisticFilter || []).includes(String(r.row[COLUMNS.ITEM_TO_LOGISTIC] || ''))); } @@ -499,7 +507,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, } return result; - }, [analyzedRows, filterMode, search, nameColFilter, articleNoColFilter, globalAdvancedFilter, lineMultiFilter, classificationFilter, productTypeFilter, unitsOuterFilter, outerWFilter, outerLFilter, outerHFilter, dynamicColFilters, weightIssueFilter, selectedSearchItems]); + }, [analyzedRows, filterMode, search, nameColFilter, articleNoColFilter, globalAdvancedFilter, lineMultiFilter, classificationFilter, productTypeFilter, unitsOuterFilter, outerWFilter, outerLFilter, outerHFilter, moqFilter, dynamicColFilters, weightIssueFilter, selectedSearchItems]); // ── Sorted rows ────────────────────────────────────────────────────────── const sortedRows = useMemo(() => { @@ -522,6 +530,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, case 'outerW': colIndex = COLUMNS.OUTER_W; break; case 'outerL': colIndex = COLUMNS.OUTER_L; break; case 'outerH': colIndex = COLUMNS.OUTER_H; break; + case 'moq': colIndex = COLUMNS.MOQ; break; case 'itemToLogistic': colIndex = COLUMNS.ITEM_TO_LOGISTIC; break; default: return filteredRows; } @@ -565,7 +574,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, }, [sortedRows, currentPage]); // Keep ref in sync so drag handlers can read current visible indexes without stale closure - visibleDataIndexesRef.current = paginatedRows.map(r => r.dataIndex); + visibleDataIndexesRef.current = paginatedRows.map((r: { dataIndex: number }) => r.dataIndex); const totalPages = Math.ceil(sortedRows.length / pageSize); @@ -808,6 +817,11 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, COLUMNS.OUTER_W, COLUMNS.OUTER_L, COLUMNS.OUTER_H, + COLUMNS.VALIDATED_CHECK, + COLUMNS.VALIDATED_NOTE, + COLUMNS.ANNA_CHECK, + COLUMNS.ANNA_NOTE, + COLUMNS.MOQ, ]); if (uvpIdx >= 0) set.add(uvpIdx); srpCols.forEach(c => set.add(c.index)); @@ -1748,7 +1762,29 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, {isPinned('moq') && } MOQ + + {openFilter === 'moq' && ( + setMoqFilter(prev => (prev || []).includes(val) ? (prev || []).filter(v => v !== val) : [...(prev || []), val])} + onSelectAll={vals => setMoqFilter(vals || [])} + onClear={() => { setMoqFilter([]); setOpenFilter(null); }} + onClose={() => setOpenFilter(null)} + zIndex={isPinned('moq') ? 200 : 50} + /> + )} { e.stopPropagation(); handleResizeStart(e, 'moq', columnWidths.moq); }} /> @@ -1863,22 +1899,29 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, const isValidated = !!row[COLUMNS.VALIDATED_CHECK]; const note = String(row[COLUMNS.VALIDATED_NOTE] || ''); + const isRowSelected = selectedRows.has(dataIndex); + return ( ) => handleRowMouseDown(e, dataIndex)} + onMouseEnter={() => handleRowMouseEnter(dataIndex)} + style={{ userSelect: 'none' }} className={cn( - 'border-b border-slate-700/50 transition-colors group relative hover:z-50', - isValidated - ? 'bg-green-400/30 border-l-4 border-l-green-400' // Vibrant high-visibility green - : saveStatus === 'error' - ? 'bg-red-400/20 border-l-4 border-l-red-500' - : saveStatus === 'pending' - ? 'bg-amber-400/20 border-l-4 border-l-amber-400' - : isCritical - ? 'bg-red-950/20' - : pricingErrors.length > 0 - ? 'bg-amber-950/10' - : '' + 'border-b border-slate-700/50 transition-colors group relative hover:z-50 cursor-default', + isRowSelected + ? 'bg-blue-500/20 border-l-4 border-l-blue-400' + : isValidated + ? 'bg-green-400/30 border-l-4 border-l-green-400' + : saveStatus === 'error' + ? 'bg-red-400/20 border-l-4 border-l-red-500' + : saveStatus === 'pending' + ? 'bg-amber-400/20 border-l-4 border-l-amber-400' + : isCritical + ? 'bg-red-950/20' + : pricingErrors.length > 0 + ? 'bg-amber-950/10' + : '' )} > {/* Art. No. */} @@ -2182,12 +2225,26 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, {/* ── Footer count & Pagination ── */}
-

- Showing {paginatedRows.length} of {sortedRows.length} products {totalPages > 1 && `(${currentPage}/${totalPages})`} - {pricingEditableCols.length > 0 && ( - <> · Click any price cell to edit inline +

+

+ Showing {paginatedRows.length} of {sortedRows.length} products {totalPages > 1 && `(${currentPage}/${totalPages})`} + {pricingEditableCols.length > 0 && ( + <> · Click any price cell to edit inline + )} +

+ {selectedRows.size > 0 && ( + + {selectedRows.size} selected + + )} -

+
{totalPages > 1 && (