bug
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Trash2, Search, Loader2 } from 'lucide-react';
|
||||
import { LookupCallsign } from '../../wailsjs/go/main/App';
|
||||
import { LookupCallsign, DXCCForCountry } from '../../wailsjs/go/main/App';
|
||||
import {
|
||||
Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription,
|
||||
} from '@/components/ui/dialog';
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
Select, SelectTrigger, SelectValue, SelectContent, SelectItem,
|
||||
} from '@/components/ui/select';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { Combobox } from '@/components/ui/combobox';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { flagURL } from '@/lib/flags';
|
||||
import type { QSOForm } from '@/types';
|
||||
@@ -63,6 +64,11 @@ const CONFIRMATIONS: ConfDef[] = [
|
||||
// Colour-coded status cell for the confirmation grid.
|
||||
function StatusCell({ value }: { value?: string }) {
|
||||
const v = (value || '').toUpperCase();
|
||||
// Empty = no value set yet → show a neutral dash, NOT "No" (which is the
|
||||
// explicit "N" status). Mirrors the dropdown, which shows "—" for empty.
|
||||
if (v === '') {
|
||||
return <span className="block text-center text-[11px] text-muted-foreground">—</span>;
|
||||
}
|
||||
const label = v === 'Y' ? 'Yes' : v === 'R' ? 'Requested' : v === 'I' ? 'Ignore' : v === 'M' ? 'Modified' : 'No';
|
||||
const cls = v === 'Y' ? 'bg-emerald-600 text-white'
|
||||
: v === 'R' ? 'bg-orange-400 text-white'
|
||||
@@ -76,6 +82,7 @@ interface Props {
|
||||
onSave: (q: QSO) => void;
|
||||
onDelete: (id: number) => void;
|
||||
onClose: () => void;
|
||||
countries?: string[];
|
||||
}
|
||||
|
||||
function toLocalISO(d: any): string {
|
||||
@@ -138,7 +145,7 @@ function QslSelect({ value, onChange }: { value?: string; onChange: (v: string)
|
||||
);
|
||||
}
|
||||
|
||||
export function QSOEditModal({ qso, onSave, onDelete, onClose }: Props) {
|
||||
export function QSOEditModal({ qso, onSave, onDelete, onClose, countries = [] }: Props) {
|
||||
const [draft, setDraft] = useState<QSO>(() => JSON.parse(JSON.stringify(qso)));
|
||||
// Frequencies are edited as kHz + Hz (Log4OM style) and recombined on save.
|
||||
const splitHz = (hz?: number) => hz
|
||||
@@ -163,6 +170,16 @@ export function QSOEditModal({ qso, onSave, onDelete, onClose }: Props) {
|
||||
setDraft((d) => ({ ...d, [key]: value }));
|
||||
}
|
||||
|
||||
// Country drives the DXCC entity number (ADIF). The DXCC field is read-only;
|
||||
// picking a Country resolves and stamps its DXCC# so they can't diverge.
|
||||
async function onCountryChange(v: string) {
|
||||
set('country', v);
|
||||
try {
|
||||
const n = await DXCCForCountry(v);
|
||||
set('dxcc', (n && n > 0 ? n : undefined) as any);
|
||||
} catch { /* leave DXCC as-is if resolution fails */ }
|
||||
}
|
||||
|
||||
// Re-run a callsign lookup (QRZ/HamQTH + cty.dat) and merge the result into
|
||||
// the draft — handy after correcting the callsign. Only overwrites the
|
||||
// lookup-derived fields; leaves call/band/mode/RST/dates alone.
|
||||
@@ -270,7 +287,6 @@ export function QSOEditModal({ qso, onSave, onDelete, onClose }: Props) {
|
||||
<TabsTrigger value="contest">Contest</TabsTrigger>
|
||||
<TabsTrigger value="sat">Sat / Prop</TabsTrigger>
|
||||
<TabsTrigger value="mystation">My Station</TabsTrigger>
|
||||
<TabsTrigger value="notes">Notes</TabsTrigger>
|
||||
<TabsTrigger value="extras">
|
||||
Extras
|
||||
{extrasCount > 0 && (
|
||||
@@ -331,14 +347,15 @@ export function QSOEditModal({ qso, onSave, onDelete, onClose }: Props) {
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Label className="w-20 shrink-0">Country</Label>
|
||||
<Input value={draft.country ?? ''} onChange={(e) => set('country', e.target.value)} className="flex-1" />
|
||||
<Combobox value={draft.country ?? ''} options={countries} placeholder="Country"
|
||||
onChange={onCountryChange} className="flex-1" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Label className="w-20 shrink-0">ITU</Label>
|
||||
<Input type="number" value={draft.ituz ?? ''} onChange={(e) => set('ituz', intOrUndef(e.target.value) as any)} className="font-mono w-16 text-center" />
|
||||
<Label>CQ</Label>
|
||||
<Input type="number" value={draft.cqz ?? ''} onChange={(e) => set('cqz', intOrUndef(e.target.value) as any)} className="font-mono w-16 text-center" />
|
||||
<Input type="number" value={draft.dxcc ?? ''} onChange={(e) => set('dxcc', intOrUndef(e.target.value) as any)} className="font-mono w-16 text-center bg-muted/40" title="DXCC entity #" />
|
||||
<Input type="number" value={draft.dxcc ?? ''} readOnly tabIndex={-1} className="font-mono w-16 text-center bg-muted/60 text-muted-foreground cursor-not-allowed" title="DXCC entity # — set automatically from Country" />
|
||||
{flagURL(draft.dxcc) && <img src={flagURL(draft.dxcc)} alt="" className="h-4 rounded-[2px] border border-border/50" referrerPolicy="no-referrer" />}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -368,11 +385,6 @@ export function QSOEditModal({ qso, onSave, onDelete, onClose }: Props) {
|
||||
</div>
|
||||
<div><Label>Comment</Label><Input value={draft.comment ?? ''} onChange={(e) => set('comment', e.target.value)} /></div>
|
||||
<div><Label>Note</Label><Textarea rows={3} value={draft.notes ?? ''} onChange={(e) => set('notes', e.target.value)} /></div>
|
||||
<div><Label>Contest</Label><Input value={draft.contest_id ?? ''} onChange={(e) => set('contest_id', e.target.value)} /></div>
|
||||
<div className="flex items-end gap-2">
|
||||
<div className="flex flex-col flex-1"><Label>Sent</Label><Input value={draft.stx_string ?? (draft.stx != null ? String(draft.stx) : '')} onChange={(e) => set('stx_string', e.target.value)} /></div>
|
||||
<div className="flex flex-col flex-1"><Label>Received</Label><Input value={draft.srx_string ?? (draft.srx != null ? String(draft.srx) : '')} onChange={(e) => set('srx_string', e.target.value)} /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TabsContent>
|
||||
@@ -495,7 +507,7 @@ export function QSOEditModal({ qso, onSave, onDelete, onClose }: Props) {
|
||||
<F label="Operator" span={3}><Input value={draft.operator ?? ''} onChange={(e) => set('operator', e.target.value)} /></F>
|
||||
<F label="My grid"><Input value={draft.my_grid ?? ''} onChange={(e) => set('my_grid', e.target.value)} /></F>
|
||||
<F label="Grid ext"><Input value={draft.my_gridsquare_ext ?? ''} onChange={(e) => set('my_gridsquare_ext', e.target.value)} /></F>
|
||||
<F label="Country" span={2}><Input value={draft.my_country ?? ''} onChange={(e) => set('my_country', e.target.value)} /></F>
|
||||
<F label="Country" span={2}><Combobox value={draft.my_country ?? ''} options={countries} placeholder="Country" onChange={(v) => set('my_country', v)} /></F>
|
||||
<F label="State"><Input value={draft.my_state ?? ''} onChange={(e) => set('my_state', e.target.value)} /></F>
|
||||
<F label="County"><Input value={draft.my_cnty ?? ''} onChange={(e) => set('my_cnty', e.target.value)} /></F>
|
||||
<F label="DXCC"><Input type="number" value={draft.my_dxcc ?? ''} onChange={(e) => set('my_dxcc', intOrUndef(e.target.value) as any)} /></F>
|
||||
@@ -514,13 +526,6 @@ export function QSOEditModal({ qso, onSave, onDelete, onClose }: Props) {
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="notes" className="mt-0">
|
||||
<div className="grid grid-cols-6 gap-3">
|
||||
<F label="Comment" span={6}><Input value={draft.comment ?? ''} onChange={(e) => set('comment', e.target.value)} /></F>
|
||||
<F label="Notes" span={6}><Textarea rows={6} value={draft.notes ?? ''} onChange={(e) => set('notes', e.target.value)} /></F>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="extras" className="mt-0 space-y-2">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
ADIF fields not promoted to first-class columns. One per line:{' '}
|
||||
|
||||
Reference in New Issue
Block a user