From 2369cfc997fdf2d803c7c77d5ecb6de2aa8617bb Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Sun, 11 Jan 2026 19:07:19 +0300 Subject: [PATCH] =?UTF-8?q?feat(ui):=20=D1=83=D0=BB=D1=83=D1=87=D1=88?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20UX=20=D0=B4=D0=BB=D1=8F=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D0=BC=D0=BE=D0=BA=D0=BE=D0=B4=D0=BE=D0=B2=20=D0=B8?= =?UTF-8?q?=20=D1=84=D0=BE=D1=80=D0=BC=20=D0=B7=D0=B0=D0=BA=D0=B0=D0=B7?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Добавлена кнопка копирования промокода в клипборд с визуальной обратной связью - Улучшено отображение ошибок валидации в форме заказа (is-invalid класс) - Добавлен флаг _draftFieldsFilled для корректной обработки пустого черновика - Убран value="1" для quantity чтобы избежать конфликтов с draft-data Co-Authored-By: Claude Opus 4.5 --- .../templates/discounts/promocode_list.html | 55 ++++++++++++++++++- myproject/orders/forms.py | 8 ++- .../orders/templates/orders/order_form.html | 10 +++- 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/myproject/discounts/templates/discounts/promocode_list.html b/myproject/discounts/templates/discounts/promocode_list.html index f3f882c..8c44a8d 100644 --- a/myproject/discounts/templates/discounts/promocode_list.html +++ b/myproject/discounts/templates/discounts/promocode_list.html @@ -76,7 +76,14 @@ {% for promo in promocodes %} - {{ promo.code }} +
+ {{ promo.code }} + +
@@ -199,4 +206,50 @@ {% endif %} + + {% endblock %} diff --git a/myproject/orders/forms.py b/myproject/orders/forms.py index bd52222..395ef0d 100644 --- a/myproject/orders/forms.py +++ b/myproject/orders/forms.py @@ -459,7 +459,7 @@ class OrderItemForm(forms.ModelForm): fields = ['product', 'product_kit', 'sales_unit', 'quantity', 'price', 'is_custom_price', 'is_from_showcase'] # ВАЖНО: НЕ включаем 'id' в fields - это предотвращает ошибку валидации widgets = { - 'quantity': forms.NumberInput(attrs={'min': 1, 'value': 1}), + 'quantity': forms.NumberInput(attrs={'min': 1}), # Скрываем поля product и product_kit - они будут заполняться через JS 'product': forms.HiddenInput(), 'product_kit': forms.HiddenInput(), @@ -474,7 +474,11 @@ class OrderItemForm(forms.ModelForm): # Bootstrap классы for field_name, field in self.fields.items(): if not isinstance(field.widget, forms.HiddenInput): - field.widget.attrs.update({'class': 'form-control'}) + css_class = 'form-control' + # Добавляем is-invalid если есть ошибки в поле + if self.errors.get(field_name): + css_class += ' is-invalid' + field.widget.attrs.update({'class': css_class}) # Поля product и product_kit опциональны self.fields['product'].required = False diff --git a/myproject/orders/templates/orders/order_form.html b/myproject/orders/templates/orders/order_form.html index 43102b4..a6c7ddc 100644 --- a/myproject/orders/templates/orders/order_form.html +++ b/myproject/orders/templates/orders/order_form.html @@ -272,8 +272,11 @@ - {% if item_form.errors %} -
{{ item_form.errors }}
+ {% if item_form.non_field_errors %} +
+ Ошибка валидации: + {{ item_form.non_field_errors }} +
{% endif %} {% endfor %} @@ -2058,6 +2061,9 @@ document.addEventListener('DOMContentLoaded', function() { const draftItems = JSON.parse(draftItemsJson); if (draftItems.length === 0) { + console.log('[Draft Items] Пустой массив черновика, устанавливаем флаг и выходим'); + // ВАЖНО: Устанавливаем флаг, чтобы initExistingOrderItems мог продолжить! + window._draftFieldsFilled = true; return; }