feat: proširi prikaz dizalice i vlasnika u zadacima
Dodaj detalje dizalice (proizvođač, model i SN) te vlasnika u modal radnog zadatka i kalendar zadataka, uz zajednički frontend helper za DRY prikaz. Proširi Task API serializer dodatnim poljima za prikaz dizalice/vlasnika i ažuriraj testove serializera za nova izlazna polja. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useMemo, useState } from 'preact/hooks';
|
||||
import { getStatusLabel } from '../../stores/taskStore';
|
||||
import LeftSlideDrawer from '../layout/LeftSlideDrawer';
|
||||
import { getTaskCraneKind, getTaskCraneOwner, getTaskCraneSerial } from '../../lib/taskCraneDisplay';
|
||||
|
||||
const WEEKDAY_LABELS = ['Po', 'Ut', 'Sr', 'Če', 'Pe', 'Su', 'Ne'];
|
||||
const MONTH_NAMES = [
|
||||
@@ -242,6 +243,9 @@ export default function TaskCalendarWidget({ tasks = [], notes = [], onTaskClick
|
||||
{task.assigned_to_name || '-'} •{' '}
|
||||
{getStatusLabel(task.status || '-')}
|
||||
</span>
|
||||
<span className="mt-0.5 block text-[11px] text-text-muted">
|
||||
{getTaskCraneSerial(task)} • {getTaskCraneKind(task)} • {getTaskCraneOwner(task)}
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useEffect, useMemo, useState } from 'preact/hooks';
|
||||
import ModalShell from '../ui/ModalShell';
|
||||
import { formatWorkOrderDisplayCode } from '../../lib/displayIds';
|
||||
import { getStatusLabel } from '../../stores/taskStore';
|
||||
import { getTaskCraneDisplay, getTaskCraneOwner } from '../../lib/taskCraneDisplay';
|
||||
|
||||
const STATUS_OPTIONS = ['aktivan', 'servis', 'spreman_za_zavrsetak', 'zavrsen', 'neaktivan'];
|
||||
|
||||
@@ -211,9 +212,13 @@ export default function TaskServiceRecordsModal({
|
||||
<dt className="text-xs text-text-muted">Dodijeljeno</dt>
|
||||
<dd className="text-text-main">{task.assigned_to_name || '-'}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt className="text-xs text-text-muted">Vlasnik</dt>
|
||||
<dd className="text-text-main">{getTaskCraneOwner(task)}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt className="text-xs text-text-muted">Dizalica</dt>
|
||||
<dd className="text-text-main">{task.vehicle_registration || '-'}</dd>
|
||||
<dd className="text-text-main">{getTaskCraneDisplay(task)}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt className="text-xs text-text-muted">Putni nalog</dt>
|
||||
@@ -255,6 +260,26 @@ export default function TaskServiceRecordsModal({
|
||||
className="resize-none rounded-lg border border-border-hairline bg-canvas-elevated px-3 py-2 text-text-main disabled:opacity-60"
|
||||
/>
|
||||
</label>
|
||||
<div className="grid gap-3 sm:grid-cols-2">
|
||||
<label className="flex flex-col gap-1 text-sm">
|
||||
<span className="text-xs text-text-muted">Vlasnik</span>
|
||||
<input
|
||||
type="text"
|
||||
value={getTaskCraneOwner(task)}
|
||||
disabled
|
||||
className="rounded-lg border border-border-hairline bg-canvas-deep px-3 py-2 text-text-main disabled:opacity-80"
|
||||
/>
|
||||
</label>
|
||||
<label className="flex flex-col gap-1 text-sm">
|
||||
<span className="text-xs text-text-muted">Dizalica</span>
|
||||
<input
|
||||
type="text"
|
||||
value={getTaskCraneDisplay(task)}
|
||||
disabled
|
||||
className="rounded-lg border border-border-hairline bg-canvas-deep px-3 py-2 text-text-main disabled:opacity-80"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<label className="flex flex-col gap-1 text-sm">
|
||||
<span className="text-xs text-text-muted">Status</span>
|
||||
<select
|
||||
|
||||
35
frontend/src/lib/taskCraneDisplay.js
Normal file
35
frontend/src/lib/taskCraneDisplay.js
Normal file
@@ -0,0 +1,35 @@
|
||||
function normalizeText(value) {
|
||||
const text = String(value || '').trim();
|
||||
return text || '';
|
||||
}
|
||||
|
||||
export function getTaskCraneKind(task) {
|
||||
const make = normalizeText(task?.vehicle_make);
|
||||
const model = normalizeText(task?.vehicle_model);
|
||||
const kind = [make, model].filter(Boolean).join(' ').trim();
|
||||
return kind || '-';
|
||||
}
|
||||
|
||||
export function getTaskCraneSerial(task) {
|
||||
const serial = normalizeText(task?.crane_serial_number);
|
||||
return serial || '-';
|
||||
}
|
||||
|
||||
export function getTaskCraneOwner(task) {
|
||||
return normalizeText(task?.vehicle_owner_name) || '-';
|
||||
}
|
||||
|
||||
export function getTaskCraneDisplay(task) {
|
||||
const kind = getTaskCraneKind(task);
|
||||
const serial = getTaskCraneSerial(task);
|
||||
if (kind !== '-' && serial !== '-') {
|
||||
return `${kind} (SN ${serial})`;
|
||||
}
|
||||
if (kind !== '-') {
|
||||
return kind;
|
||||
}
|
||||
if (serial !== '-') {
|
||||
return `SN ${serial}`;
|
||||
}
|
||||
return normalizeText(task?.vehicle_registration) || '-';
|
||||
}
|
||||
Reference in New Issue
Block a user