Упрощён компонент поиска товаров: убран мультивыбор, только single-select

- Удалён весь функционал множественного выбора
- Удалены кнопки 'Выбрать все' и 'Сбросить'
- Удалён счётчик выбранных товаров
- state.selected теперь содержит один объект вместо словаря
- Убраны параметры multi_select, max_selection, show_select_all
- onAddSelected теперь возвращает объект вместо массива
- Удалены методы getSelectedIds() и setSelection()
- Упрощена логика _toggleProduct для single-select
- Обновлены все callback'и для работы с одним товаром
- Компонент стал значительно проще и понятнее
This commit is contained in:
2025-12-11 00:26:48 +03:00
parent 1607fbe3fe
commit b115869b2d
3 changed files with 57 additions and 186 deletions

View File

@@ -1,18 +1,15 @@
{% comment %}
Переиспользуемый компонент поиска и выбора штучных товаров (Product).
Переиспользуемый компонент поиска и выбора товара (Product).
Только единичный выбор (single-select).
Параметры (Django template variables):
- container_id: уникальный ID контейнера (default: 'product-search-picker')
- title: заголовок компонента (default: 'Выбор товаров')
- title: заголовок компонента (default: 'Выбор товара')
- api_url: URL для AJAX поиска (default: '/products/api/search-products-variants/')
- show_filters: показывать фильтры (default: True)
- show_view_toggle: показывать переключатель вида (default: True)
- show_select_all: показывать кнопку "Выбрать все" (default: True)
- show_add_button: показывать кнопку "Добавить выбранные" (default: True)
- add_button_text: текст кнопки добавления (default: 'Добавить выбранные')
- add_button_text: текст кнопки добавления (default: 'Выбрать товар')
- initial_view: начальный вид 'grid' или 'list' (default: 'list')
- multi_select: множественный выбор (default: True)
- max_selection: максимальное количество выбранных товаров (default: null)
- filter_in_stock_only: показывать только товары в наличии (default: False)
- warehouse_id: ID склада для фильтрации товаров (default: None)
- categories: список категорий для фильтра (queryset или list)
@@ -22,7 +19,7 @@
Пример использования:
{% include 'products/components/product_search_picker.html' with
container_id='writeoff-products'
title='Выберите товары для списания'
title='Выберите товар для списания'
show_filters=True
filter_in_stock_only=True
categories=categories
@@ -31,9 +28,9 @@
После включения инициализируйте JS:
<script>
ProductSearchPicker.init('#writeoff-products', {
onAddSelected: function(products, instance) {
// products = [{id, text, sku, price, in_stock, photo_url}, ...]
products.forEach(addToForm);
onAddSelected: function(product, instance) {
// product = {id, text, sku, price, in_stock, photo_url}
addToForm(product);
instance.clearSelection();
}
});
@@ -45,8 +42,6 @@ ProductSearchPicker.init('#writeoff-products', {
<div class="product-search-picker"
id="{{ container_id|default:'product-search-picker' }}"
data-api-url="{{ api_url|default:'/products/api/search-products-variants/' }}"
data-multi-select="{{ multi_select|default:'true' }}"
data-max-selection="{{ max_selection|default:'' }}"
data-exclude-kits="true"
{% if warehouse_id %}data-warehouse-id="{{ warehouse_id }}"{% endif %}>
@@ -55,7 +50,7 @@ ProductSearchPicker.init('#writeoff-products', {
<div class="card-header bg-white py-2 d-flex justify-content-between align-items-center flex-wrap gap-2">
<strong>
<i class="bi bi-box-seam text-primary"></i>
{{ title|default:'Выбор товаров' }}
{{ title|default:'Выбор товара' }}
</strong>
<div class="d-flex gap-2 align-items-center flex-wrap">
@@ -128,11 +123,7 @@ ProductSearchPicker.init('#writeoff-products', {
</div>
</div>
<!-- Счетчик выбранных -->
<div class="col-auto ms-auto">
<span class="badge bg-primary product-picker-selected-count">0</span>
<span class="text-muted small">выбрано</span>
</div>
<!-- Счетчик выбранных - УБРАН в single-select режиме -->
</div>
</div>
{% endif %}
@@ -158,27 +149,14 @@ ProductSearchPicker.init('#writeoff-products', {
</div>
</div>
<!-- Футер с кнопками действий -->
<!-- Футер с кнопкой действия -->
<div class="card-footer bg-white py-2 d-flex justify-content-between align-items-center flex-wrap gap-2">
{% if show_select_all|default:True %}
<div class="d-flex gap-2">
<button class="btn btn-outline-secondary btn-sm product-picker-select-all">
<i class="bi bi-check2-all"></i> Выбрать все
</button>
<button class="btn btn-outline-secondary btn-sm product-picker-clear-selection">
<i class="bi bi-x-lg"></i> Сбросить
</button>
</div>
{% else %}
<div></div>
{% endif %}
{% if show_add_button|default:True %}
<button class="btn btn-primary btn-sm product-picker-add-selected" disabled>
<i class="bi bi-plus-circle"></i>
{{ add_button_text|default:'Добавить выбранные' }}
{{ add_button_text|default:'Выбрать товар' }}
</button>
{% endif %}
</div>
</div>
</div>