feat(pos): глобальный поиск с учетом режима витрины

- При поиске из режима "Витрина" показываются товары И витринные комплекты
- При поиске из других категорий - только обычные товары и комплекты
- При очистке поиска возвращается к предыдущему режиму (витрина или категория)
- Добавлена визуальная индикация глобального поиска (подсветка "Все товары")

Изменения:
- terminal.js: добавлена переменная wasShowcaseViewBeforeSearch,
  обновлены renderProducts(), обработчики поиска
- views.py: get_items_api() игнорирует category_id при search_query
This commit is contained in:
2026-01-27 15:30:59 +03:00
parent 90906944dd
commit 907c21f22e

View File

@@ -65,6 +65,9 @@ let searchDebounceTimer = null;
let isEditMode = false;
let editingKitId = null;
// Переменная для сохранения состояния витрины перед поиском
let wasShowcaseViewBeforeSearch = false;
// Временная корзина для модального окна создания/редактирования комплекта
const tempCart = new Map();
@@ -848,26 +851,30 @@ function renderProducts() {
let filtered;
// Если активен поиск (3+ символов) - показываем результаты поиска по всем товарам
// независимо от режима (витрина или обычный)
if (currentSearchQuery && currentSearchQuery.length >= 3 && !isShowcaseView) {
// Обычный режим - ITEMS уже отфильтрованы на сервере (поиск по всем товарам)
filtered = ITEMS;
} else if (isShowcaseView) {
// Режим витрины - показываем витринные комплекты
filtered = showcaseKits;
// Если активен поиск (3+ символов) - показываем результаты поиска
if (currentSearchQuery && currentSearchQuery.length >= 3) {
// Базовые результаты - товары из API (поиск по всем товарам)
filtered = [...ITEMS];
// Для витрины — клиентская фильтрация по поиску (только если менее 3 символов)
const searchTerm = document.getElementById('searchInput').value.toLowerCase().trim();
if (searchTerm && searchTerm.length < 3) {
// Если перед началом поиска была активна витрина - добавляем витринные комплекты в результаты
if (wasShowcaseViewBeforeSearch) {
const searchTerm = currentSearchQuery.toLowerCase().trim();
const tokens = searchTerm.split(/\s+/).filter(t => t.length > 0);
filtered = filtered.filter(item => {
// Фильтруем витринные комплекты по поисковому запросу
const filteredShowcaseKits = showcaseKits.filter(item => {
const name = (item.name || '').toLowerCase();
const sku = (item.sku || '').toLowerCase();
// Каждый токен должен совпадать хотя бы с одним словом в name или sku
return tokens.every(token => name.includes(token) || sku.includes(token));
});
// Объединяем товары и витринные комплекты
filtered = [...filtered, ...filteredShowcaseKits];
}
} else if (isShowcaseView) {
// Режим витрины без поиска - показываем все витринные комплекты
filtered = showcaseKits;
} else {
// Обычный режим без поиска - ITEMS отфильтрованы по категории
filtered = ITEMS;
@@ -3856,8 +3863,14 @@ searchInput.addEventListener('input', (e) => {
if (query === '') {
currentSearchQuery = '';
updateSearchIndicator(); // Обновляем индикацию
// Если поиск начинался с витрины - возвращаемся к витрине
if (wasShowcaseViewBeforeSearch) {
isShowcaseView = true;
wasShowcaseViewBeforeSearch = false;
renderCategories();
renderProducts();
} else if (!isShowcaseView) {
// Возвращаем товары выбранной категории
if (!isShowcaseView) {
loadItems();
}
return;
@@ -3869,8 +3882,10 @@ searchInput.addEventListener('input', (e) => {
return;
}
// Для витрины при 3+ символах - переключаемся на глобальный поиск по всем товарам
// Для витрины при 3+ символах - сохраняем состояние и переключаемся на глобальный поиск
if (isShowcaseView) {
// Сохраняем, что была активна витрина перед поиском
wasShowcaseViewBeforeSearch = true;
// Выходим из режима витрины для глобального поиска
isShowcaseView = false;
// Обновляем UI категорий (снимаем выделение с витрины)
@@ -3899,8 +3914,14 @@ clearSearchBtn.addEventListener('click', () => {
clearSearchBtn.style.display = 'none';
currentSearchQuery = '';
updateSearchIndicator(); // Обновляем индикацию
// Если поиск начинался с витрины - возвращаемся к витрине
if (wasShowcaseViewBeforeSearch) {
isShowcaseView = true;
wasShowcaseViewBeforeSearch = false;
renderCategories();
renderProducts();
} else if (!isShowcaseView) {
// Возвращаем товары выбранной категории
if (!isShowcaseView) {
loadItems();
} else {
renderProducts(); // Для витрины - просто перерисовываем