Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions ui/src/components/import/DocumentImportView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
XCircle, Receipt, Plus, Minus,
} from "lucide-react";
import { rpc } from "../../api/rpc";
import { UNIT_OPTIONS } from "../../constants";

// ---------------------------------------------------------------------------
// Types — RPC response shapes from `imports.parse_document_for_import`.
Expand Down Expand Up @@ -759,6 +760,9 @@ function InvoiceCard({ item, onUpdate, importedContracts, importedProjects, exis
const missing = (f: string, v: any) => ireq(f) && (v == null || v === "");
const borderCls = (f: string, v: any) =>
missing(f, v) ? "border-red-400/60" : "border-fuchsia-400/20";
const unitOptions = li.unit && !(UNIT_OPTIONS as readonly string[]).includes(li.unit)
? [...UNIT_OPTIONS, li.unit]
: [...UNIT_OPTIONS];
return (
<div key={idx} className="grid grid-cols-[1fr_80px_60px_90px_70px_28px] gap-1.5 items-end">
<div>
Expand All @@ -779,8 +783,11 @@ function InvoiceCard({ item, onUpdate, importedContracts, importedProjects, exis
<label className="block text-[10px] text-tertiary mb-0.5">
Unit{ireq("unit") && <span className="text-red-400 ml-0.5">*</span>}
</label>
<input value={li.unit} onChange={(e) => updateItem(idx, "unit", e.target.value)}
className={`w-full px-2 py-1 rounded text-xs bg-bg-card text-primary border ${borderCls("unit", li.unit)} outline-none focus:border-fuchsia-400`} />
<select value={li.unit ?? ""} onChange={(e) => updateItem(idx, "unit", e.target.value)}
className={`w-full px-2 py-1 rounded text-xs bg-bg-card text-primary border ${borderCls("unit", li.unit)} outline-none focus:border-fuchsia-400`}>
<option value="" disabled>Select unit</option>
{unitOptions.map((u) => <option key={u} value={u}>{u}</option>)}
</select>
</div>
<div>
<label className="block text-[10px] text-tertiary mb-0.5">
Expand Down
3 changes: 1 addition & 2 deletions ui/src/components/invoicing/InvoicingView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from "lucide-react";
import { rpc, readFileAsDataURL } from "../../api/rpc";
import { str, num, bool, entity as subEntity, list as entityList, formatDate, invoiceStatus, deepStr, isReminder, reminderLevel } from "../../api/entity";
import { UNIT_OPTIONS } from "../../constants";
import { StatusBadge } from "../shared/StatusBadge";
import { ViewModeToggle } from "../shared/ViewModeToggle";
import { KanbanBoard, useStageStore, type BoardColumn } from "../shared/KanbanBoard";
Expand Down Expand Up @@ -221,8 +222,6 @@ interface LineItem {
unitPrice: string;
}

const UNIT_OPTIONS = ["hour", "day", "piece", "flat"] as const;

function makeDefaultItem(project?: Entity | null): LineItem {
const contract = project ? (project as Record<string, unknown>).contract as Record<string, unknown> | undefined : undefined;
const unit = contract?.unit as string | undefined;
Expand Down
1 change: 1 addition & 0 deletions ui/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const UNIT_OPTIONS = ["hour", "day", "piece", "flat"] as const;