mirror of
https://github.com/christianvidalwolf-prog/Craze-Data-check.git
synced 2026-08-03 20:15:23 +02:00
Add column filters to Missing Data view and include Classification in editable columns
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { ExcelRow, COLUMNS } from '../types';
|
||||
import { Search, ChevronDown, ChevronUp, X, Edit2, Save } from 'lucide-react';
|
||||
import { Search, ChevronDown, ChevronUp, X, Edit2, Save, Filter, XCircle } from 'lucide-react';
|
||||
import { cn } from '../lib/utils';
|
||||
|
||||
interface MissingDataViewProps {
|
||||
@@ -52,6 +52,8 @@ export function MissingDataView({ data, headers, onSaveRow, onCaptureState }: Mi
|
||||
const [sortDesc, setSortDesc] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [editing, setEditing] = useState<EditingState | null>(null);
|
||||
const [columnFilters, setColumnFilters] = useState<Record<number, string>>({});
|
||||
const [showFilterMenu, setShowFilterMenu] = useState<number | null>(null);
|
||||
const pageSize = 100;
|
||||
|
||||
const launchDateCol = useMemo(() =>
|
||||
@@ -87,6 +89,19 @@ export function MissingDataView({ data, headers, onSaveRow, onCaptureState }: Mi
|
||||
);
|
||||
}
|
||||
|
||||
(Object.entries(columnFilters) as [string, string][]).forEach(([colIdx, filterValue]) => {
|
||||
if (!filterValue) return;
|
||||
const colIdxNum = parseInt(colIdx);
|
||||
const filterLower = filterValue.toLowerCase();
|
||||
result = result.filter(r => {
|
||||
const val: any = r.row[colIdxNum];
|
||||
const displayVal = colIdxNum === launchDateCol || colIdxNum === readyToOrderCol
|
||||
? formatDateValue(val) || String(val ?? '')
|
||||
: String(val ?? '');
|
||||
return displayVal.toLowerCase().includes(filterLower);
|
||||
});
|
||||
});
|
||||
|
||||
if (sortCol !== null) {
|
||||
result.sort((a, b) => {
|
||||
const valA = a.row[sortCol];
|
||||
@@ -101,7 +116,7 @@ export function MissingDataView({ data, headers, onSaveRow, onCaptureState }: Mi
|
||||
}
|
||||
|
||||
return result;
|
||||
}, [data, activeTab, search, sortCol, sortDesc, launchDateCol]);
|
||||
}, [data, activeTab, search, sortCol, sortDesc, launchDateCol, columnFilters]);
|
||||
|
||||
const paginatedData = useMemo(() => {
|
||||
const start = (page - 1) * pageSize;
|
||||
@@ -203,18 +218,45 @@ export function MissingDataView({ data, headers, onSaveRow, onCaptureState }: Mi
|
||||
<th
|
||||
key={col}
|
||||
style={{ width, minWidth: width }}
|
||||
className="px-3 py-3 font-medium border-r border-slate-700/30 select-none cursor-pointer hover:text-white"
|
||||
onClick={() => handleSort(col)}
|
||||
className="px-2 py-2 font-medium border-r border-slate-700/30 relative"
|
||||
>
|
||||
<span className="flex items-center gap-1">
|
||||
<div
|
||||
className="flex items-center gap-1 cursor-pointer select-none hover:text-white"
|
||||
onClick={() => handleSort(col)}
|
||||
>
|
||||
{label}
|
||||
{sortCol === col && (
|
||||
sortDesc ? <ChevronDown className="w-3 h-3" /> : <ChevronUp className="w-3 h-3" />
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="mt-1 relative">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Filter..."
|
||||
value={columnFilters[col] || ''}
|
||||
onChange={(e) => {
|
||||
setColumnFilters(prev => ({ ...prev, [col]: e.target.value }));
|
||||
setPage(1);
|
||||
}}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="w-full px-1.5 py-0.5 bg-slate-800 border border-slate-600 rounded text-[10px] text-white placeholder-slate-500 focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
{columnFilters[col] && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setColumnFilters(prev => { const n = { ...prev }; delete n[col]; return n; });
|
||||
setPage(1);
|
||||
}}
|
||||
className="absolute right-1 top-1/2 -translate-y-1/2 text-slate-500 hover:text-white"
|
||||
>
|
||||
<XCircle className="w-3 h-3" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</th>
|
||||
))}
|
||||
<th className="px-3 py-3 font-medium text-right" style={{ width: 60 }}></th>
|
||||
<th className="px-2 py-2 font-medium text-right" style={{ width: 60 }}></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-slate-700/30">
|
||||
|
||||
Reference in New Issue
Block a user