mirror of
https://github.com/christianvidalwolf-prog/Craze-Data-check.git
synced 2026-08-03 14:25:23 +02:00
fix: resolve column filter checkboxes not responding to clicks
Replace label+hidden-input pattern in ColumnFilterPopover with direct onClick on div — browsers don't reliably fire onChange for display:none inputs activated via label click. Also adds missing columnFilters to useMemo deps in ProductDescriptions and ArticleDetails, and restores rowStatuses prop wiring in ProductDescriptions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
71a4897f28
commit
d3675bba0b
@@ -369,6 +369,7 @@ export default function App() {
|
||||
<ProductDescriptions
|
||||
data={appState.data}
|
||||
onEdit={(index) => setEditingRowIndex(index)}
|
||||
rowStatuses={rowStatuses}
|
||||
/>
|
||||
)}
|
||||
{activeModule === 'matrix' && (
|
||||
|
||||
@@ -71,7 +71,7 @@ export function ArticleDetails({ data, onEdit, rowStatuses }: ArticleDetailsProp
|
||||
}
|
||||
|
||||
return result;
|
||||
}, [data, activeTab, search, lineFilter, sortCol, sortDesc]);
|
||||
}, [data, activeTab, search, lineFilter, columnFilters, sortCol, sortDesc]);
|
||||
|
||||
const paginatedData = useMemo(() => {
|
||||
const start = (page - 1) * pageSize;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { Search, Check, X } from 'lucide-react';
|
||||
import { Search, Check } from 'lucide-react';
|
||||
import { cn } from '../lib/utils';
|
||||
|
||||
interface ColumnFilterPopoverProps {
|
||||
@@ -54,21 +54,23 @@ export function ColumnFilterPopover({
|
||||
|
||||
<div className="max-h-48 overflow-y-auto space-y-0.5 pr-1 custom-scrollbar">
|
||||
{filteredValues.map(val => (
|
||||
<label key={val} className="flex items-center gap-2 p-1.5 hover:bg-slate-700/50 rounded cursor-pointer group">
|
||||
<div
|
||||
key={val}
|
||||
role="checkbox"
|
||||
aria-checked={selectedValues.includes(val)}
|
||||
tabIndex={0}
|
||||
onClick={() => onToggle(val)}
|
||||
onKeyDown={(e) => { if (e.key === ' ' || e.key === 'Enter') { e.preventDefault(); onToggle(val); } }}
|
||||
className="flex items-center gap-2 p-1.5 hover:bg-slate-700/50 rounded cursor-pointer group"
|
||||
>
|
||||
<div className={cn(
|
||||
"w-4 h-4 rounded border flex items-center justify-center shrink-0 transition-colors",
|
||||
selectedValues.includes(val) ? "bg-blue-600 border-blue-600" : "border-slate-600 bg-slate-900 group-hover:border-slate-500"
|
||||
)}>
|
||||
{selectedValues.includes(val) && <Check className="w-3 h-3 text-white" />}
|
||||
</div>
|
||||
<input
|
||||
type="checkbox"
|
||||
className="hidden"
|
||||
checked={selectedValues.includes(val)}
|
||||
onChange={() => onToggle(val)}
|
||||
/>
|
||||
<span className="text-xs text-slate-300 truncate" title={val}>{val || '(Empty)'}</span>
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
{filteredValues.length === 0 && (
|
||||
<div className="text-[10px] text-slate-500 text-center py-4 italic">No values found</div>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ColumnFilterPopover } from './ColumnFilterPopover';
|
||||
interface ProductDescriptionsProps {
|
||||
data: ExcelRow[];
|
||||
onEdit: (index: number) => void;
|
||||
rowStatuses: Record<string, string>;
|
||||
}
|
||||
|
||||
type TabType = 'all' | 'missingLongDE' | 'missingLongEN' | 'missingLongAny' | 'missingShortDE' | 'missingShortEN' | 'missingShortAny' | 'complete' | 'incomplete';
|
||||
@@ -14,7 +15,7 @@ type TabType = 'all' | 'missingLongDE' | 'missingLongEN' | 'missingLongAny' | 'm
|
||||
// Description columns that should only have Present/Missing filters
|
||||
const DESCRIPTION_COLUMNS = [COLUMNS.LONG_DE, COLUMNS.LONG_EN, COLUMNS.SHORT_DE, COLUMNS.SHORT_EN];
|
||||
|
||||
export function ProductDescriptions({ data, onEdit }: ProductDescriptionsProps) {
|
||||
export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescriptionsProps) {
|
||||
const [activeTab, setActiveTab] = useState<TabType>('all');
|
||||
const [search, setSearch] = useState('');
|
||||
const [lineFilter, setLineFilter] = useState('');
|
||||
@@ -91,7 +92,7 @@ export function ProductDescriptions({ data, onEdit }: ProductDescriptionsProps)
|
||||
}
|
||||
|
||||
return result;
|
||||
}, [data, activeTab, search, lineFilter, licenseFilter, sortCol, sortDesc]);
|
||||
}, [data, activeTab, search, lineFilter, licenseFilter, columnFilters, sortCol, sortDesc]);
|
||||
|
||||
const paginatedData = useMemo(() => {
|
||||
const start = (page - 1) * pageSize;
|
||||
@@ -304,8 +305,17 @@ export function ProductDescriptions({ data, onEdit }: ProductDescriptionsProps)
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-slate-700/50">
|
||||
{paginatedData.map(({ row, index }) => (
|
||||
<tr key={index} className={cn("transition-colors", getRowColor(row))}>
|
||||
{paginatedData.map(({ row, index }) => {
|
||||
const isPending = rowStatuses[String(row[COLUMNS.ARTICLE_NO])] === 'pending';
|
||||
return (
|
||||
<tr
|
||||
key={index}
|
||||
className={cn(
|
||||
"transition-colors",
|
||||
getRowColor(row),
|
||||
isPending ? "bg-yellow-400/20 border-l-4 border-l-yellow-400" : ""
|
||||
)}
|
||||
>
|
||||
<td className="px-4 py-3 font-mono text-slate-300 text-xs">{row[COLUMNS.ARTICLE_NO]}</td>
|
||||
<td className="px-4 py-3 font-medium text-white max-w-[200px] truncate" title={row[COLUMNS.ARTICLE_NAME]}>{row[COLUMNS.ARTICLE_NAME]}</td>
|
||||
<td className="px-4 py-3 text-slate-300 text-xs">{row[COLUMNS.LINE]}</td>
|
||||
@@ -334,7 +344,8 @@ export function ProductDescriptions({ data, onEdit }: ProductDescriptionsProps)
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
{paginatedData.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan={9} className="px-4 py-8 text-center text-slate-500">
|
||||
|
||||
Reference in New Issue
Block a user