From f37d130bc7a507fc7d084cd6ebf8eb5ecf3bb644 Mon Sep 17 00:00:00 2001 From: mariomitte Date: Fri, 7 Aug 2026 10:20:32 +0200 Subject: [PATCH] Reapply "predzadnji unstagaeni dijelovi" This reverts commit fe4ba3b5ddc02696d870a9f28a77f53075d3b47b. --- backend/modules/fleet/views.py | 16 +- frontend/src/components/Navbar.jsx | 14 +- .../dashboard/TaskCalendarWidget.jsx | 32 ++-- .../components/dashboard/TaskCreateModal.jsx | 176 ------------------ .../dashboard/TaskServiceRecordsModal.jsx | 22 +-- .../dashboard/WorkOrderInvoicesPdfPage.jsx | 34 ++-- frontend/src/stores/fleetDashboardStore.js | 76 +------- 7 files changed, 50 insertions(+), 320 deletions(-) diff --git a/backend/modules/fleet/views.py b/backend/modules/fleet/views.py index 9f8f161..6333f65 100644 --- a/backend/modules/fleet/views.py +++ b/backend/modules/fleet/views.py @@ -3055,17 +3055,10 @@ def _request_monthly_archive_generation(*, request, archive_type): .first() ) if existing_pending: - stale_pending_threshold = timezone.now() - timedelta(minutes=3) - if existing_pending.created_at and existing_pending.created_at < stale_pending_threshold: - existing_pending.is_active = False - existing_pending.status = 'failed' - existing_pending.error_message = 'ZIP zahtjev je ostao predugo u pending statusu; pokrece se novi zahtjev.' - existing_pending.save(update_fields=['is_active', 'status', 'error_message', 'updated_at']) - else: - return { - 'status': 'processing', - 'generated_archive_id': str(existing_pending.pk), - } + return { + 'status': 'processing', + 'generated_archive_id': str(existing_pending.pk), + } generated_archive = GeneratedFleetArchive.objects.create( requested_by=request.user, @@ -3087,7 +3080,6 @@ def _request_monthly_archive_generation(*, request, archive_type): stage='requested', year=year, month=month, - generated_archive=generated_archive, ) try: diff --git a/frontend/src/components/Navbar.jsx b/frontend/src/components/Navbar.jsx index 2e2c03f..c732828 100644 --- a/frontend/src/components/Navbar.jsx +++ b/frontend/src/components/Navbar.jsx @@ -4,7 +4,7 @@ import AuthWidget from './AuthWidget'; import UserDisplay from './ui/UserDisplay'; import { useEffect, useRef, useState } from 'preact/hooks'; import { useSpring, animated } from '@react-spring/web'; -import { hydrateAuthFromStorage, loadCurrentUser, $user, $accessToken } from '../stores/authStore'; +import { hydrateAuthFromStorage } from '../stores/authStore'; const ITEMS = [ { id: 'dashboard', label: 'Dashboard', href: '/' }, @@ -21,12 +21,8 @@ function normalizePath(p) { } function getActiveIndex(path) { - // Exact match (e.g. '/' → Dashboard) - const exact = ITEMS.findIndex((item) => item.href === path); - if (exact >= 0) return exact; - // Prefix match for sub-paths (e.g. '/putni-nalozi/racuni' → Putni nalozi) - const prefix = ITEMS.findIndex((item) => item.href !== '/' && path.startsWith(item.href)); - return prefix >= 0 ? prefix : 0; + const idx = ITEMS.findIndex((item) => item.href === path); + return idx >= 0 ? idx : 0; } export default function Navbar({ minimal = false }) { @@ -59,10 +55,6 @@ export default function Navbar({ minimal = false }) { // Mount: izmjeri početnu poziciju bez animacije, pa uključi animaciju za buduće navigacije useEffect(() => { hydrateAuthFromStorage(); - // Učitaj korisnika ako token postoji ali $user još nije popunjen - if (!$user.get() && $accessToken.get()) { - loadCurrentUser(); - } const timer = setTimeout(() => { measureIndicator(); diff --git a/frontend/src/components/dashboard/TaskCalendarWidget.jsx b/frontend/src/components/dashboard/TaskCalendarWidget.jsx index 8cfcb36..294eb4a 100644 --- a/frontend/src/components/dashboard/TaskCalendarWidget.jsx +++ b/frontend/src/components/dashboard/TaskCalendarWidget.jsx @@ -367,10 +367,10 @@ export default function TaskCalendarWidget({ tasks = [], notes = [], workOrders async function handleDownloadAllTasksArchive() { if (downloadingAllTasks) return; - setBulkDownloadOpen(false); setDownloadingAllTasks(true); try { await downloadMonthlyServiceTasksArchive(viewYear, viewMonth + 1); + setBulkDownloadOpen(false); } finally { setDownloadingAllTasks(false); } @@ -378,10 +378,10 @@ export default function TaskCalendarWidget({ tasks = [], notes = [], workOrders async function handleDownloadAllWorkOrdersArchive() { if (downloadingAllWorkOrders) return; - setBulkDownloadOpen(false); setDownloadingAllWorkOrders(true); try { await downloadMonthlyWorkOrdersArchive(viewYear, viewMonth + 1); + setBulkDownloadOpen(false); } finally { setDownloadingAllWorkOrders(false); } @@ -655,25 +655,23 @@ export default function TaskCalendarWidget({ tasks = [], notes = [], workOrders {MONTH_NAMES[viewMonth]} {viewYear} -
+ + {reportType === 'servicer' && ( - {reportType === 'servicer' && ( - - )} -
+ )}

diff --git a/frontend/src/components/dashboard/TaskCreateModal.jsx b/frontend/src/components/dashboard/TaskCreateModal.jsx index 86d05ef..41b21e8 100644 --- a/frontend/src/components/dashboard/TaskCreateModal.jsx +++ b/frontend/src/components/dashboard/TaskCreateModal.jsx @@ -2,7 +2,6 @@ import { createTask, fetchTaskTemplates, getStatusLabel } from '../../stores/taskStore'; import { formatPurposeLabel, formatWorkOrderDisplayCode } from '../../lib/displayIds'; import ModalShell from '../ui/ModalShell'; -import { updateVehicle } from '../../stores/fleetDashboardStore'; const STATUS_OPTIONS = ['aktivan', 'servis', 'zavrsen', 'neaktivan']; @@ -33,10 +32,6 @@ export default function TaskCreateModal({ open, workOrders = [], contextCrane = const [templateLoading, setTemplateLoading] = useState(false); const [templateId, setTemplateId] = useState(''); const [templates, setTemplates] = useState([]); - const [craneDataModalOpen, setCraneDataModalOpen] = useState(false); - const [craneDataForm, setCraneDataForm] = useState({ superstructure_working_hours: '', chassis_working_hours: '', current_mileage: '' }); - const [savingCraneData, setSavingCraneData] = useState(false); - const [craneDataError, setCraneDataError] = useState(''); const selectedTemplate = useMemo( () => templates.find((template) => String(template.id) === String(templateId)) || null, @@ -56,10 +51,6 @@ export default function TaskCreateModal({ open, workOrders = [], contextCrane = setTemplateId(''); setTemplates([]); setTemplateLoading(false); - setCraneDataModalOpen(false); - setCraneDataForm({ superstructure_working_hours: '', chassis_working_hours: '', current_mileage: '' }); - setSavingCraneData(false); - setCraneDataError(''); return; } // Auto-pre-select today's open work order if exactly one exists for this crane @@ -85,60 +76,6 @@ export default function TaskCreateModal({ open, workOrders = [], contextCrane = })); }, [selectedTemplate]); - function openCraneDataModal() { - if (!contextCrane?.id) { - setCraneDataError('Dizalica nije odabrana u servisnom kontekstu.'); - return; - } - setCraneDataForm({ - superstructure_working_hours: String(contextCrane?.superstructure_working_hours ?? ''), - chassis_working_hours: String(contextCrane?.chassis_working_hours ?? ''), - current_mileage: String(contextCrane?.current_mileage ?? ''), - }); - setCraneDataError(''); - setCraneDataModalOpen(true); - } - - async function handleSaveCraneData() { - if (!contextCrane?.id) { - setCraneDataError('Dizalica nije odabrana u servisnom kontekstu.'); - return; - } - const superstructure = craneDataForm.superstructure_working_hours === '' ? undefined : Number(craneDataForm.superstructure_working_hours); - const chassis = craneDataForm.chassis_working_hours === '' ? undefined : Number(craneDataForm.chassis_working_hours); - const mileage = craneDataForm.current_mileage === '' ? undefined : Number(craneDataForm.current_mileage); - if (superstructure !== undefined && (Number.isNaN(superstructure) || superstructure < 0)) { - setCraneDataError('Radni sati nadogradnje moraju biti pozitivan broj.'); - return; - } - if (chassis !== undefined && (Number.isNaN(chassis) || chassis < 0)) { - setCraneDataError('Radni sati podvozja moraju biti pozitivan broj.'); - return; - } - if (mileage !== undefined && (Number.isNaN(mileage) || mileage < 0)) { - setCraneDataError('Kilometraza mora biti pozitivan broj.'); - return; - } - const payload = {}; - if (superstructure !== undefined) payload.superstructure_working_hours = superstructure; - if (chassis !== undefined) payload.chassis_working_hours = chassis; - if (mileage !== undefined) payload.current_mileage = mileage; - if (Object.keys(payload).length === 0) { - setCraneDataError('Unesite barem jednu vrijednost za azuriranje.'); - return; - } - setSavingCraneData(true); - setCraneDataError(''); - try { - await updateVehicle(contextCrane.id, payload); - setCraneDataModalOpen(false); - } catch (err) { - setCraneDataError(err?.message || 'Azuriranje podataka dizalice nije uspjelo.'); - } finally { - setSavingCraneData(false); - } - } - if (!open) return null; function setField(name, value) { @@ -219,7 +156,6 @@ export default function TaskCreateModal({ open, workOrders = [], contextCrane = } return ( - <> )} - {contextCrane && ( -

-
-
-

Podaci odabrane dizalice

-

{contextCrane.registration_number || '-'} / {contextCrane.make || '-'} {contextCrane.model || ''}

-
- -
-
-
-
Radni sati nadogradnje
-
{contextCrane.superstructure_working_hours ?? '-'}
-
-
-
Radni sati podvozja
-
{contextCrane.chassis_working_hours ?? '-'}
-
-
-
Kilometraza
-
{contextCrane.current_mileage ?? '-'}
-
-
-
- )} -