Fix: hand upload and rev approval lines name the person, not the user id; PLAN questions 53, 54 and the phase 10 note
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -146,7 +146,7 @@ describe("Packet page, VISUAL box", () => {
|
||||
it("uploads a hand BOM as multipart with the signature fields", async () => {
|
||||
const fetch = mockFetch({
|
||||
...base(visualDraft()),
|
||||
"POST /api/packets/1/hand/bom": { body: visualDraft({ version: 4, visual: { manual_bom: { name: "bom.csv", reason: "No materials yet", lines: 3 } } }) },
|
||||
"POST /api/packets/1/hand/bom": { body: visualDraft({ version: 4, visual: { manual_bom: { name: "bom.csv", reason: "No materials yet", lines: 3, by: "cf284ce9-e7a6-45d0-bba6-d46b752d553d", by_name: "Clara Clerk" } } }) },
|
||||
});
|
||||
renderApp("/packets/1");
|
||||
fireEvent.click(await screen.findByRole("button", { name: "Upload BOM" }));
|
||||
@@ -165,6 +165,9 @@ describe("Packet page, VISUAL box", () => {
|
||||
expect((fd.get("file") as File).name).toBe("bom.csv");
|
||||
expect(await screen.findByRole("button", { name: "Use VISUAL's BOM again" })).toBeInTheDocument();
|
||||
expect(screen.getByText("BOM uploaded by hand:", { exact: false })).toBeInTheDocument();
|
||||
// The line names the person, never the stored user id.
|
||||
expect(screen.getByText(/BOM uploaded by hand:.*Clara Clerk/)).toBeInTheDocument();
|
||||
expect(screen.queryByText(/cf284ce9/)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("uploads a hand drawing: the asset first, then the attach with reason and sign", async () => {
|
||||
|
||||
@@ -21,9 +21,11 @@ type AskReason = (opts: ReasonOptions) => Promise<string | null>;
|
||||
const isCl = (roles: readonly string[]) => roles.some((r) => r === "clerical" || r === "clerical_supervisor" || r === "admin");
|
||||
const isClSup = (roles: readonly string[]) => roles.some((r) => r === "clerical_supervisor" || r === "admin");
|
||||
|
||||
function whoName(by: WhoRef | string | null | undefined): string {
|
||||
if (!by) return "";
|
||||
return typeof by === "string" ? by : by.display_name;
|
||||
/** The server stores `by` as the user id and the display name beside it in `by_name`. */
|
||||
function whoName(m: { by?: WhoRef | string | null; by_name?: string | null }): string {
|
||||
if (m.by_name) return m.by_name;
|
||||
if (!m.by) return "";
|
||||
return typeof m.by === "string" ? m.by : m.by.display_name;
|
||||
}
|
||||
|
||||
function foldedText(f: FoldedOp): string {
|
||||
@@ -126,7 +128,7 @@ function HandLine({ what, m }: { what: string; m: HandUpload }) {
|
||||
return (
|
||||
<div className="small">
|
||||
{what} uploaded by hand: <span className="mono">{m.name ?? ""}</span>
|
||||
{m.by ? ` - ${whoName(m.by)}` : ""} {m.at ? fmtTime(m.at) : ""}
|
||||
{m.by ? ` - ${whoName(m)}` : ""} {m.at ? fmtTime(m.at) : ""}
|
||||
{m.reason ? ` · ${m.reason}` : ""}
|
||||
{typeof m.lines === "number" ? ` · ${m.lines} line${m.lines === 1 ? "" : "s"}` : ""}
|
||||
</div>
|
||||
@@ -237,7 +239,7 @@ export function VisualBox({
|
||||
<b>Rev {String(v.rev_ok.rev)} approved by hand</b> in place of VISUAL rev {v.rev_ok.vis_rev || "-"}
|
||||
</>
|
||||
)}
|
||||
{v.rev_ok.by ? ` - ${whoName(v.rev_ok.by)}` : ""} {v.rev_ok.at ? fmtTime(v.rev_ok.at) : ""}
|
||||
{v.rev_ok.by ? ` - ${whoName(v.rev_ok)}` : ""} {v.rev_ok.at ? fmtTime(v.rev_ok.at) : ""}
|
||||
{v.rev_ok.reason ? `: ${v.rev_ok.reason}` : ""}.
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user