fix: keyboard layout map, picker type tabs as filters, add unit tests
1. Fix RU_TO_EN keyboard map in keyboardLayout.ts: - ч was mapped to 'c' (wrong), now correctly 'x' - с was mapped to 'v' (wrong), now correctly 'c' - ю was mapped to '.' (wrong), now correctly ',' - Full rewrite with standard QWERTY/ЙЦУКЕН positional mapping - Examples: dthcnfr→верстак, руддщ→hello, цщкдв→world all correct now 2. Root cause of search breaking after 3-4 chars: Old map had ч:'c', с:'v' swapped. So dthcnfr → 'верчиак' (wrong). Each character was mapped to wrong Cyrillic equivalent. 3. Add unit tests: keyboardLayout.test.js (39 tests, node-runner): - EN→RU: dthcnfr, ghbdtn, ntcn - RU→EN: руддщ, цщкдв, ышеш - Unicode safety: Latin c (U+0063) ≠ Cyrillic с (U+0441) - expandKeyboardVariants for mixed inputs - Edge cases: empty, single char, mixed case, numbers 4. InternalLinkPicker type tabs → filters (not search modes): - Store rawResults (all) + filtered results by activeType - Switching type tab no longer clears query or triggers new search - Just filters existing rawResults by selected type - Shows 'Нет результатов для этого типа' when filtered empty 5. Both GlobalSearch and InternalLinkPicker use same expandKeyboardVariants() All tests PASS, full build OK.
This commit is contained in:
@@ -17,7 +17,8 @@
|
||||
|
||||
let activeType = 'note';
|
||||
let query = '';
|
||||
let results = [];
|
||||
let rawResults = []; // all search results (unfiltered)
|
||||
let results = []; // filtered by activeType
|
||||
let selectedIndex = 0;
|
||||
let loading = false;
|
||||
let error = '';
|
||||
@@ -31,8 +32,15 @@
|
||||
return 'case';
|
||||
}
|
||||
|
||||
// Filter rawResults by activeType into displayed results
|
||||
function applyTypeFilter() {
|
||||
results = rawResults.filter(n => nodeTypeToFilter(n.type) === activeType);
|
||||
selectedIndex = 0;
|
||||
}
|
||||
|
||||
async function search() {
|
||||
if (!query.trim() || query.trim().length < 2) {
|
||||
rawResults = [];
|
||||
results = [];
|
||||
return;
|
||||
}
|
||||
@@ -41,7 +49,6 @@
|
||||
try {
|
||||
// Expand query with keyboard layout variants for tolerant search
|
||||
const variants = expandKeyboardVariants(query.trim());
|
||||
// Deduplicate: skip variants identical to the original query's lowercase
|
||||
const seen = new Set();
|
||||
const queries = [];
|
||||
for (const v of variants) {
|
||||
@@ -63,11 +70,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
// Filter by active type
|
||||
results = Array.from(merged.values()).filter(n => nodeTypeToFilter(n.type) === activeType);
|
||||
selectedIndex = 0;
|
||||
rawResults = Array.from(merged.values());
|
||||
applyTypeFilter();
|
||||
} catch (e) {
|
||||
error = String(e);
|
||||
rawResults = [];
|
||||
results = [];
|
||||
} finally {
|
||||
loading = false;
|
||||
@@ -104,9 +111,7 @@
|
||||
|
||||
function handleTypeChange(typeId) {
|
||||
activeType = typeId;
|
||||
query = '';
|
||||
results = [];
|
||||
error = '';
|
||||
applyTypeFilter();
|
||||
if (inputRef) inputRef.focus();
|
||||
}
|
||||
|
||||
@@ -159,8 +164,10 @@
|
||||
<div class="picker-loading">Загрузка...</div>
|
||||
{:else if error}
|
||||
<div class="picker-error">{error}</div>
|
||||
{:else if query.trim().length >= 2 && results.length === 0}
|
||||
<div class="picker-empty">Ничего не найдено</div>
|
||||
{:else if query.trim().length >= 2 && results.length === 0 && !loading}
|
||||
<div class="picker-empty">
|
||||
{rawResults.length > 0 ? 'Нет результатов для этого типа' : 'Ничего не найдено'}
|
||||
</div>
|
||||
{:else}
|
||||
{#each results as item, i}
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user