From f2e9129a7776515bea6477d53df658e3ec77354e Mon Sep 17 00:00:00 2001 From: lokses Date: Tue, 13 Oct 2026 11:32:32 +0300 Subject: [PATCH] =?UTF-8?q?it:=20=D1=84=D0=BE=D1=80=D0=BC=D1=8B=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BE?= =?UTF-8?q?=D0=B1=D0=BE=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B8=20=D0=B2=D1=8B=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D0=BE=D0=B9=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B?= =?UTF-8?q?=20=D0=B2=20popup.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- apps/it_manager/tests.py | 30 ++++++++++++++ static/assets/js/it-manager.js | 64 ++++++++++++++++++++++++----- templates/pages/it-manager.html | 71 ++++++++++++++++++++++----------- 3 files changed, 130 insertions(+), 35 deletions(-) diff --git a/apps/it_manager/tests.py b/apps/it_manager/tests.py index b13d3bf..5d2f07f 100644 --- a/apps/it_manager/tests.py +++ b/apps/it_manager/tests.py @@ -145,6 +145,21 @@ class ItManagerEquipmentTests(TestCase): r = self.client.get('/it-manager/') self.assertEqual(r.status_code, 200) + def test_equipment_create_is_popup(self): + r = self.client.get('/it-manager/') + self.assertContains(r, 'id="it-equipment-panel"') + self.assertContains(r, 'it-equipment-modal-title') + self.assertContains(r, 'role="dialog"') + self.assertNotContains(r, 'id="it-equipment-panel-overlay"') + + def test_bulk_create_error_reopens_popup(self): + r = self.client.post('/it-manager/equipment/bulk-create/', { + 'serial_numbers': 'SN-X', + }, HTTP_HX_REQUEST='true') + self.assertEqual(r.status_code, 200) + self.assertContains(r, 'data-it-equipment-open="1"') + self.assertContains(r, 'it-equipment-modal-title') + def test_bulk_create_equipment(self): model = make_equipment_model() # масовий ввід: одна модель + список серійників (з дублем) @@ -682,6 +697,21 @@ class ItManagerWorkLogTests(TestCase): self.assertEqual(float(log.hours_spent), 2.5) self.assertContains(r, 'Запись о выполненной работе сохранена') + def test_worklog_create_is_popup(self): + r = self.client.get('/it-manager/?tab=worklog') + self.assertContains(r, 'id="it-worklog-panel"') + self.assertContains(r, 'it-worklog-modal-title') + self.assertContains(r, 'role="dialog"') + self.assertNotContains(r, 'id="it-worklog-panel-overlay"') + + def test_worklog_error_reopens_popup(self): + r = self.client.post('/it-manager/worklog/create/', { + 'description': 'без работы', + }, HTTP_HX_REQUEST='true') + self.assertEqual(r.status_code, 200) + self.assertContains(r, 'data-it-worklog-open="1"') + self.assertContains(r, 'типовую работу') + def test_create_worklog_requires_catalog_and_details(self): before = WorkLog.objects.count() r = self.client.post('/it-manager/worklog/create/', { diff --git a/static/assets/js/it-manager.js b/static/assets/js/it-manager.js index eb6cb5e..6921983 100644 --- a/static/assets/js/it-manager.js +++ b/static/assets/js/it-manager.js @@ -20,22 +20,45 @@ function itToggleRow(key) { if (toggle) toggle.style.transform = opening ? 'rotate(90deg)' : ''; } +function itIsModal(panel) { + return panel && panel.getAttribute('role') === 'dialog'; +} + function itPanelOpen(id) { var panel = document.getElementById(id); + if (!panel) return; + if (itIsModal(panel)) { + panel.style.display = 'flex'; + document.body.style.overflow = 'hidden'; + if (typeof initSearchableSelects === 'function') initSearchableSelects(panel); + return; + } var overlay = document.getElementById(id + '-overlay'); if (overlay) overlay.style.display = 'block'; - if (panel) panel.style.transform = 'translateX(0)'; + panel.style.transform = 'translateX(0)'; document.body.style.overflow = 'hidden'; } function itPanelClose(id) { var panel = document.getElementById(id); + if (!panel) return; + if (itIsModal(panel)) { + panel.style.display = 'none'; + document.body.style.overflow = ''; + return; + } var overlay = document.getElementById(id + '-overlay'); if (overlay) overlay.style.display = 'none'; - if (panel) panel.style.transform = 'translateX(100%)'; + panel.style.transform = 'translateX(100%)'; document.body.style.overflow = ''; } +function itModalsInit(root) { + if (!root) return; + if (root.getAttribute('data-it-equipment-open') === '1') itPanelOpen('it-equipment-panel'); + if (root.getAttribute('data-it-worklog-open') === '1') itPanelOpen('it-worklog-panel'); +} + function itContractServiceToggle(serviceTypeCode) { var block = document.getElementById('it-contract-ip-block'); if (!block) return; @@ -413,19 +436,38 @@ function itReportPreviewClose() { document.addEventListener('keydown', function (ev) { if (ev.key !== 'Escape') return; - var modal = document.getElementById('it-report-preview-modal'); - if (modal && modal.style.display === 'flex') itReportPreviewClose(); + var preview = document.getElementById('it-report-preview-modal'); + if (preview && preview.style.display === 'flex') { + itReportPreviewClose(); + return; + } + ['it-equipment-panel', 'it-worklog-panel'].forEach(function (id) { + var el = document.getElementById(id); + if (el && el.style.display === 'flex') itPanelClose(id); + }); }); +function itPageAfterLoad(scope) { + var root = (scope || document).querySelector('[data-it-active-tab]'); + if (!root) return; + if (typeof itTabSwitch === 'function') { + itTabSwitch(root.getAttribute('data-it-active-tab') || 'equipment'); + } + if (typeof initSearchableSelects === 'function') { + initSearchableSelects(scope || document); + } + itModalsInit(root); +} + +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', function () { itPageAfterLoad(document); }); +} else { + itPageAfterLoad(document); +} + document.addEventListener('htmx:afterSwap', function (ev) { var target = ev.detail && ev.detail.target; if (!target || target.id !== 'main-content') return; - var root = target.querySelector('[data-it-active-tab]'); - if (root && typeof itTabSwitch === 'function') { - itTabSwitch(root.getAttribute('data-it-active-tab') || 'equipment'); - } - if (typeof initSearchableSelects === 'function') { - initSearchableSelects(target); - } + itPageAfterLoad(target); }); diff --git a/templates/pages/it-manager.html b/templates/pages/it-manager.html index e19bed3..dd25e3a 100644 --- a/templates/pages/it-manager.html +++ b/templates/pages/it-manager.html @@ -1,7 +1,7 @@ {% load common_tags %} {% load i18n %} {% with active_tab=it_active_tab|default:"equipment" %} -
+

{% trans "IT-отдел" %}

@@ -82,17 +82,27 @@
- - -
+ + {% endif %} - - -
+ +