Добавить функционал массового изменения категорий товаров
- Добавлен UI для пакетного выбора товаров с чекбоксами - Реализована возможность выбора всех товаров на странице - Реализована возможность выбора всех отфильтрованных товаров - Добавлено модальное окно для массового управления категориями - Добавлены API эндпоинты: get_filtered_items_ids, bulk_update_categories - Реализованы три режима работы с категориями: добавление, замена, очистка - Добавлен селектор количества элементов на странице (20/50/100) - Улучшена информативность о количестве выбранных элементов
This commit is contained in:
@@ -108,7 +108,17 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6">
|
||||
<!-- Показывать по -->
|
||||
<div class="col-12 col-md-2">
|
||||
<label for="per_page" class="form-label"><i class="bi bi-list-ol"></i> Показывать по:</label>
|
||||
<select class="form-select" id="per_page" name="per_page" onchange="this.form.submit()">
|
||||
<option value="20" {% if filters.current.per_page == '20' %}selected{% endif %}>20</option>
|
||||
<option value="50" {% if filters.current.per_page == '50' %}selected{% endif %}>50</option>
|
||||
<option value="100" {% if filters.current.per_page == '100' %}selected{% endif %}>100</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-4">
|
||||
<label class="form-label d-none d-md-block"> </label>
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
@@ -125,10 +135,71 @@
|
||||
</div>
|
||||
|
||||
{% if items %}
|
||||
<!-- Инструментальная панель для пакетных действий -->
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
{% if is_paginated %}
|
||||
<span class="text-muted">
|
||||
Показано {{ page_obj.start_index }}–{{ page_obj.end_index }} из {{ page_obj.paginator.count }}
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="text-muted">Всего: {{ items|length }}</span>
|
||||
{% endif %}
|
||||
|
||||
<!-- Dropdown для выбора всех отфильтрованных -->
|
||||
<div class="btn-group" id="select-all-dropdown-group" style="display: none;">
|
||||
<button type="button" class="btn btn-sm btn-outline-primary dropdown-toggle"
|
||||
data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="bi bi-check2-square"></i> Выбрать
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a class="dropdown-item" href="#" onclick="document.getElementById('select-all-checkbox').click(); return false;">
|
||||
<i class="bi bi-check2"></i> Все на странице
|
||||
</a>
|
||||
</li>
|
||||
{% if is_paginated %}
|
||||
<li>
|
||||
<a class="dropdown-item" href="#" onclick="window.BatchSelection.selectAllFiltered(); return false;">
|
||||
<i class="bi bi-check2-all"></i> Все отфильтрованные ({{ page_obj.paginator.count }})
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="#" onclick="window.BatchSelection.clearSelection(); return false;">
|
||||
<i class="bi bi-x-square"></i> Снять выбор
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-secondary" id="batch-actions-btn" disabled>
|
||||
<i class="bi bi-gear-fill"></i> Действия над выбранными (<span id="selection-count">0</span>)
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split"
|
||||
id="batch-actions-dropdown" data-bs-toggle="dropdown" aria-expanded="false" disabled>
|
||||
<span class="visually-hidden">Открыть меню</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="batch-actions-dropdown">
|
||||
<li>
|
||||
<a class="dropdown-item" href="#" id="bulk-category-action">
|
||||
<i class="bi bi-bookmark-fill"></i> Изменить категории
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover align-middle">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th style="width: 50px;">
|
||||
<input type="checkbox" id="select-all-checkbox" class="form-check-input"
|
||||
title="Выбрать все на странице">
|
||||
</th>
|
||||
<th style="width: 80px;">Фото</th>
|
||||
<th>Название</th>
|
||||
<th style="width: 120px;">Артикул</th>
|
||||
@@ -144,6 +215,14 @@
|
||||
<tbody>
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
<td>
|
||||
<input type="checkbox" name="selected_items"
|
||||
value="{{ item.item_type }}:{{ item.pk }}"
|
||||
class="form-check-input item-checkbox"
|
||||
data-item-type="{{ item.item_type }}"
|
||||
data-item-id="{{ item.pk }}"
|
||||
data-item-name="{{ item.name }}">
|
||||
</td>
|
||||
<td>
|
||||
{% if item.photos.all %}
|
||||
{% with photo=item.photos.first %}
|
||||
@@ -318,4 +397,78 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Модальное окно для массового изменения категорий -->
|
||||
<div class="modal fade" id="bulkCategoryModal" tabindex="-1" aria-labelledby="bulkCategoryModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="bulkCategoryModalLabel">
|
||||
<i class="bi bi-bookmark-fill"></i> Изменить категории для выбранных товаров
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Информация о выбранных товарах -->
|
||||
<div class="alert alert-info mb-3">
|
||||
<i class="bi bi-info-circle"></i> <strong>Выбрано:</strong> <span id="selectedItemsCount">0</span> товаров
|
||||
<span id="selectedItemsBreakdown" class="ms-2 text-muted"></span>
|
||||
</div>
|
||||
|
||||
<!-- Опции применения -->
|
||||
<div class="mb-4">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="clearExistingCategoriesToggle" role="switch">
|
||||
<label class="form-check-label" for="clearExistingCategoriesToggle">
|
||||
<i class="bi bi-trash"></i> Очистить существующие категории перед сохранением
|
||||
</label>
|
||||
<div class="form-text text-warning">
|
||||
<i class="bi bi-exclamation-triangle"></i>
|
||||
При включении все текущие категории товаров будут удалены, а затем применены только выбранные ниже
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Выбор категорий -->
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Выберите категории:</label>
|
||||
|
||||
<!-- Поиск по категориям -->
|
||||
<input type="text" class="form-control mb-2" id="categorySearchInput"
|
||||
placeholder="Поиск категорий...">
|
||||
|
||||
<!-- Список категорий -->
|
||||
<div id="categoryListContainer" style="max-height: 300px; overflow-y: auto; border: 1px solid #dee2e6; border-radius: 0.25rem; padding: 0.5rem;">
|
||||
<div class="text-center py-3">
|
||||
<div class="spinner-border spinner-border-sm" role="status">
|
||||
<span class="visually-hidden">Загрузка...</span>
|
||||
</div>
|
||||
<div class="mt-2 text-muted">Загрузка категорий...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Сообщения об ошибках -->
|
||||
<div id="bulkCategoryError" class="alert alert-danger d-none" role="alert"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger me-auto" id="clearAllCategoriesBtn">
|
||||
<i class="bi bi-trash3"></i> Очистить все категории
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="bi bi-x-circle"></i> Отмена
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" id="applyBulkCategoriesBtn" disabled>
|
||||
<i class="bi bi-check2-circle"></i> Применить
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
{% load static %}
|
||||
<script src="{% static 'products/js/batch-selection.js' %}?v=1.1"></script>
|
||||
<script src="{% static 'products/js/bulk-category-modal.js' %}?v=1.0"></script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user