mirror of
https://github.com/christianvidalwolf-prog/Craze-Data-check.git
synced 2026-08-03 12:55:23 +02:00
feat: implement multi-word AND search in all views and initialize RuFlo V3
This commit is contained in:
@@ -148,10 +148,15 @@ export function DimensionsView({ data, headers, onEdit, onSaveRow, onCaptureStat
|
||||
if (search || lineFilter.length > 0 || classFilter.length > 0) {
|
||||
const s = search.toLowerCase();
|
||||
result = result.filter(g => {
|
||||
const matchesSearch = !search || g.rows.some(({ row }) =>
|
||||
String(row[COLUMNS.ARTICLE_NO] || '').toLowerCase().includes(s) ||
|
||||
String(row[COLUMNS.ARTICLE_NAME] || '').toLowerCase().includes(s)
|
||||
);
|
||||
const matchesSearch = !search || (() => {
|
||||
const terms = search.toLowerCase().split(/\s+/).filter(Boolean);
|
||||
if (terms.length === 0) return true;
|
||||
return g.rows.some(({ row }) => {
|
||||
const articleNo = String(row[COLUMNS.ARTICLE_NO] || '').toLowerCase();
|
||||
const articleName = String(row[COLUMNS.ARTICLE_NAME] || '').toLowerCase();
|
||||
return terms.every(term => articleNo.includes(term) || articleName.includes(term));
|
||||
});
|
||||
})();
|
||||
const matchesLine = lineFilter.length === 0 || g.rows.some(({ row }) => lineFilter.includes(String(row[COLUMNS.LINE] || '')));
|
||||
const matchesClass = classFilter.length === 0 || g.rows.some(({ row }) => classFilter.includes(String(row[COLUMNS.CLASSIFICATION] || '')));
|
||||
|
||||
|
||||
@@ -78,11 +78,13 @@ export function HistoryView({ headers, data, onRevert, onEdit }: HistoryViewProp
|
||||
}).format(date);
|
||||
};
|
||||
|
||||
const filteredHistory = history.filter(entry =>
|
||||
entry.article_name?.toLowerCase().includes(search.toLowerCase()) ||
|
||||
entry.product_id.toLowerCase().includes(search.toLowerCase()) ||
|
||||
entry.changed_by?.toLowerCase().includes(search.toLowerCase())
|
||||
);
|
||||
const filteredHistory = history.filter(entry => {
|
||||
const terms = search.toLowerCase().split(/\s+/).filter(Boolean);
|
||||
if (terms.length === 0) return true;
|
||||
|
||||
const searchableText = `${entry.article_name} ${entry.product_id} ${entry.changed_by}`.toLowerCase();
|
||||
return terms.every(term => searchableText.includes(term));
|
||||
});
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
|
||||
@@ -203,12 +203,16 @@ export function MissingDataView({ data, headers, onSaveRow, onCaptureState }: Mi
|
||||
}
|
||||
}
|
||||
|
||||
// Global search (SKU + Name) - Multi-word AND support
|
||||
if (search) {
|
||||
const s = search.toLowerCase();
|
||||
result = result.filter(r =>
|
||||
String(r.row[COLUMNS.ARTICLE_NO] || '').toLowerCase().includes(s) ||
|
||||
String(r.row[COLUMNS.ARTICLE_NAME] || '').toLowerCase().includes(s)
|
||||
);
|
||||
const terms = search.toLowerCase().split(/\s+/).filter(Boolean);
|
||||
if (terms.length > 0) {
|
||||
result = result.filter(r => {
|
||||
const articleNo = String(r.row[COLUMNS.ARTICLE_NO] || '').toLowerCase();
|
||||
const articleName = String(r.row[COLUMNS.ARTICLE_NAME] || '').toLowerCase();
|
||||
return terms.every(term => articleNo.includes(term) || articleName.includes(term));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
(Object.entries(columnFilters) as [string, string[]][]).forEach(([colIdx, filterValues]) => {
|
||||
|
||||
@@ -19,12 +19,15 @@ export function PendingValidationView({ data, pendingRows, rowStatuses, onRevert
|
||||
|
||||
const pendingEntries = Object.entries(pendingRows);
|
||||
|
||||
const filteredEntries = search
|
||||
? pendingEntries.filter(([articleNo, { articleName }]) =>
|
||||
articleNo.toLowerCase().includes(search.toLowerCase()) ||
|
||||
articleName.toLowerCase().includes(search.toLowerCase())
|
||||
)
|
||||
: pendingEntries;
|
||||
const filteredEntries = (() => {
|
||||
const terms = search.toLowerCase().split(/\s+/).filter(Boolean);
|
||||
if (terms.length === 0) return pendingEntries;
|
||||
|
||||
return pendingEntries.filter(([articleNo, { articleName }]) => {
|
||||
const searchableText = `${articleNo} ${articleName}`.toLowerCase();
|
||||
return terms.every(term => searchableText.includes(term));
|
||||
});
|
||||
})();
|
||||
|
||||
const getFieldDiff = (original: ExcelRow, updated: ExcelRow, colIndex: number) => {
|
||||
const orig = original[colIndex];
|
||||
|
||||
@@ -114,12 +114,16 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit,
|
||||
const searchSuggestions = useMemo(() => {
|
||||
if (!search && selectedSearchItems.size === 0) return data.slice(0, 50);
|
||||
if (!search) return [];
|
||||
const s = search.toLowerCase();
|
||||
return data.filter(r =>
|
||||
String(r[COLUMNS.ARTICLE_NO] || '').toLowerCase().includes(s) ||
|
||||
String(r[COLUMNS.ARTICLE_NAME] || '').toLowerCase().includes(s)
|
||||
).slice(0, 50);
|
||||
}, [data, search, selectedSearchItems]);
|
||||
|
||||
const terms = search.toLowerCase().split(/\s+/).filter(Boolean);
|
||||
if (terms.length === 0) return data.slice(0, 50);
|
||||
|
||||
return data.filter(r => {
|
||||
const articleNo = String(r[COLUMNS.ARTICLE_NO] || '').toLowerCase();
|
||||
const articleName = String(r[COLUMNS.ARTICLE_NAME] || '').toLowerCase();
|
||||
return terms.every(term => articleNo.includes(term) || articleName.includes(term));
|
||||
}).slice(0, 50);
|
||||
}, [data, search, selectedSearchItems, COLUMNS]);
|
||||
|
||||
const handleSearchItemClick = (index: number) => {
|
||||
const newSelected = new Set(selectedSearchItems);
|
||||
@@ -310,13 +314,16 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit,
|
||||
case 'units_errors': result = analyzedRows.filter(r => r.unitErrors.length > 0); break;
|
||||
}
|
||||
|
||||
// Global search (SKU + Name)
|
||||
// Global search (SKU + Name) - Multi-word AND support
|
||||
if (search) {
|
||||
const s = search.toLowerCase();
|
||||
result = result.filter(r =>
|
||||
String(r.row[COLUMNS.ARTICLE_NO] || '').toLowerCase().includes(s) ||
|
||||
String(r.row[COLUMNS.ARTICLE_NAME] || '').toLowerCase().includes(s)
|
||||
);
|
||||
const terms = search.toLowerCase().split(/\s+/).filter(Boolean);
|
||||
if (terms.length > 0) {
|
||||
result = result.filter(r => {
|
||||
const articleNo = String(r.row[COLUMNS.ARTICLE_NO] || '').toLowerCase();
|
||||
const articleName = String(r.row[COLUMNS.ARTICLE_NAME] || '').toLowerCase();
|
||||
return terms.every(term => articleNo.includes(term) || articleName.includes(term));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Selected items from search dropdown
|
||||
|
||||
@@ -65,11 +65,14 @@ export function ProductDescriptions({ data, headers, asinColumnIndex, onEdit, ro
|
||||
|
||||
// Search filter
|
||||
if (search) {
|
||||
const s = search.toLowerCase();
|
||||
result = result.filter(r =>
|
||||
String(r.row[COLUMNS.ARTICLE_NO] || '').toLowerCase().includes(s) ||
|
||||
String(r.row[COLUMNS.ARTICLE_NAME] || '').toLowerCase().includes(s)
|
||||
);
|
||||
const terms = search.toLowerCase().split(/\s+/).filter(Boolean);
|
||||
if (terms.length > 0) {
|
||||
result = result.filter(r => {
|
||||
const articleNo = String(r.row[COLUMNS.ARTICLE_NO] || '').toLowerCase();
|
||||
const articleName = String(r.row[COLUMNS.ARTICLE_NAME] || '').toLowerCase();
|
||||
return terms.every(term => articleNo.includes(term) || articleName.includes(term));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Dropdown filters
|
||||
|
||||
Reference in New Issue
Block a user