Update color note, option skip test physical

This commit is contained in:
andrew.ng 2026-05-28 16:43:19 +07:00
parent aa223c67c1
commit 4b7e87e768
2 changed files with 91 additions and 42 deletions

View File

@ -2026,20 +2026,21 @@ Ports Missing/Down: ${missing.length}\n\n`
let verdictBd = '#a7f3d0' let verdictBd = '#a7f3d0'
let verdictTx = '#065f46' let verdictTx = '#065f46'
if (!physicalPass && !aiPass) { // if (!physicalPass && !aiPass) {
verdictLabel = 'CRITICAL ISSUES' // verdictLabel = 'CRITICAL ISSUES'
verdictMsg = 'Physical failures + AI detected problems' // verdictMsg = 'Physical failures + AI detected problems'
verdictBg = '#fef2f2' // verdictBg = '#fef2f2'
verdictBd = '#fecaca' // verdictBd = '#fecaca'
verdictTx = '#991b1b' // verdictTx = '#991b1b'
} else if (!physicalPass) { // } else
if (!physicalPass) {
verdictLabel = 'PHYSICAL INCOMPLETE' verdictLabel = 'PHYSICAL INCOMPLETE'
verdictMsg = `${missing.length} port(s) untested${isSkipped ? ' — testing skipped' : ''}` verdictMsg = `${missing.length} port(s) untested${isSkipped ? ' — testing skipped' : ''}`
verdictBg = '#fef2f2' verdictBg = '#fef2f2'
verdictBd = '#fecaca' verdictBd = '#fecaca'
verdictTx = '#991b1b' verdictTx = '#991b1b'
} else if (!aiPass) { } else if (!aiPass) {
verdictLabel = `AI: ${summaryStatus}` verdictLabel = summaryStatus === 'FAIL' ? 'CRITICAL ISSUES' : `AI: ${summaryStatus}`
verdictMsg = verdictMsg =
summaryStatus === 'FAIL' summaryStatus === 'FAIL'
? 'AI analysis failed — review required' ? 'AI analysis failed — review required'
@ -2110,12 +2111,12 @@ Ports Missing/Down: ${missing.length}\n\n`
const missingParts: string[] = [] const missingParts: string[] = []
if (missingPoE.length) { if (missingPoE.length) {
missingParts.push( missingParts.push(
`<div style="margin-top:8px;padding:8px 12px;background:#fef2f2;border-left:3px solid #ef4444;border-radius:0 6px 6px 0;font-size:10px;color:#991b1b;"><b>Missing PoE (${missingPoE.length}):</b><br/><span style="font-family:Consolas,monospace;color:#5f6978;">${missingPoE.map((p) => escapeHtml(physicalTest.normalizePortName(p.name))).join(', ')}</span></div>` `<div style="margin-top:8px;padding:8px 12px;background:#fef2f2;border-left:3px solid #ef4444;border-radius:0 6px 6px 0;font-size:10px;color:#991b1b;"><b>Untested PoE (${missingPoE.length}):</b><br/><span style="font-family:Consolas,monospace;color:#5f6978;">${missingPoE.map((p) => escapeHtml(physicalTest.normalizePortName(p.name))).join(', ')}</span></div>`
) )
} }
if (missingSFP.length) { if (missingSFP.length) {
missingParts.push( missingParts.push(
`<div style="margin-top:6px;padding:8px 12px;background:#fef2f2;border-left:3px solid #ef4444;border-radius:0 6px 6px 0;font-size:10px;color:#991b1b;"><b>Missing SFP (${missingSFP.length}):</b><br/><span style="font-family:Consolas,monospace;color:#5f6978;">${missingSFP.map((p) => escapeHtml(physicalTest.normalizePortName(p.name))).join(', ')}</span></div>` `<div style="margin-top:6px;padding:8px 12px;background:#fef2f2;border-left:3px solid #ef4444;border-radius:0 6px 6px 0;font-size:10px;color:#991b1b;"><b>Untested SFP (${missingSFP.length}):</b><br/><span style="font-family:Consolas,monospace;color:#5f6978;">${missingSFP.map((p) => escapeHtml(physicalTest.normalizePortName(p.name))).join(', ')}</span></div>`
) )
} }
if (isSkipped) { if (isSkipped) {
@ -2327,7 +2328,7 @@ Ports Missing/Down: ${missing.length}\n\n`
<div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:#9ca3af;">Receiving &amp; Inspection Notes</div> <div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:#9ca3af;">Receiving &amp; Inspection Notes</div>
<div style="color:#222222;font-size:11px;font-weight:500;opacity:.65;">${dataIncomingBySN?.packagePo?.receivedBy?.fullName || 'Unknown'} · ${dataIncomingBySN?.packagePo?.receivedDate ? momentTZ(dataIncomingBySN?.packagePo?.receivedDate).tz(timeZone).format('DD MMM YYYY, HH:mm') : ''}</div> <div style="color:#222222;font-size:11px;font-weight:500;opacity:.65;">${dataIncomingBySN?.packagePo?.receivedBy?.fullName || 'Unknown'} · ${dataIncomingBySN?.packagePo?.receivedDate ? momentTZ(dataIncomingBySN?.packagePo?.receivedDate).tz(timeZone).format('DD MMM YYYY, HH:mm') : ''}</div>
</div> </div>
<div style="padding:10px 14px;background:#fffbeb;border-left:3px solid #f59e0b;border-radius:0 6px 6px 0;font-size:12px;color:#92400e;margin-bottom:8px;"> <div style="padding:10px 14px;${!dataIncomingBySN?.packagePo?.notes && !serialInfo?.notes ? "background:#f9fafb;border-left:3px solid #e5e7eb;color:#5f6978;" : "background:#fffbeb;border-left:3px solid #f59e0b;color:#92400e;"}border-radius:0 6px 6px 0;font-size:12px;margin-bottom:8px;">
<div style="font-weight:700;margin-bottom:4px;font-size:11px;">&#9888; Warning from Warehouse</div> <div style="font-weight:700;margin-bottom:4px;font-size:11px;">&#9888; Warning from Warehouse</div>
<p style="margin:0;">${dataIncomingBySN?.packagePo?.notes || ''}</p> <p style="margin:0;">${dataIncomingBySN?.packagePo?.notes || ''}</p>
<p style="margin:0;">${serialInfo?.notes || ''}</p> <p style="margin:0;">${serialInfo?.notes || ''}</p>

View File

@ -7,6 +7,8 @@ import {
TextInput, TextInput,
Button, Button,
ScrollArea, ScrollArea,
Radio,
Group,
} from "@mantine/core"; } from "@mantine/core";
import type { TLine, TStation } from "../../untils/types"; import type { TLine, TStation } from "../../untils/types";
import type { Socket } from "socket.io-client"; import type { Socket } from "socket.io-client";
@ -21,6 +23,7 @@ interface Props {
interface PropsLines { interface PropsLines {
id: number | undefined; id: number | undefined;
note: string; note: string;
reasonType?: string;
pid?: string; pid?: string;
sn?: string; sn?: string;
vid?: string; vid?: string;
@ -48,10 +51,13 @@ export default function ModalConfirmSkipTestPort({
pid: line?.inventory?.pid, pid: line?.inventory?.pid,
sn: line?.inventory?.sn, sn: line?.inventory?.sn,
vid: line?.inventory?.vid, vid: line?.inventory?.vid,
reasonType: prev?.find((el) => el.id === line.id)
? prev?.find((el) => el.id === line.id)?.reasonType || ""
: "",
note: prev?.find((el) => el.id === line.id) note: prev?.find((el) => el.id === line.id)
? prev?.find((el) => el.id === line.id)?.note || "" ? prev?.find((el) => el.id === line.id)?.note || ""
: "", : "",
})) })),
); );
} }
}, [listLines]); }, [listLines]);
@ -99,39 +105,80 @@ export default function ModalConfirmSkipTestPort({
</Text> </Text>
</Flex> </Flex>
<Box> <Box>
<TextInput <Group mt="8px" mb="4px">
required <Radio
placeholder="Enter the reason for skip test ports" label="No PoE"
mt="4px" value="no_poe"
mb="4px" checked={line.reasonType === "no_poe"}
value={line.note} onChange={() =>
onChange={(e) => setDataLines(
setDataLines( dataLines.map((el) =>
dataLines.map((el) => el.id === line.id
el.id === line.id ? {
? { ...el,
...el, reasonType: "no_poe",
note: e.target.value, note: "",
isError: false, isError: false,
} }
: el : el,
),
) )
) }
} />
error={ <Radio
line.isError label="Other"
? "Please enter the reason for skip test ports" value="other"
: "" checked={line.reasonType === "other"}
} onChange={() =>
/> setDataLines(
dataLines.map((el) =>
el.id === line.id
? {
...el,
reasonType: "other",
isError: false,
}
: el,
),
)
}
/>
</Group>
{line.reasonType === "other" && (
<TextInput
required
placeholder="Enter the reason for skip test ports"
mt="4px"
mb="4px"
value={line.note}
onChange={(e) =>
setDataLines(
dataLines.map((el) =>
el.id === line.id
? {
...el,
note: e.target.value,
isError: false,
}
: el,
),
)
}
error={
line.isError
? "Please enter the reason for skip test ports"
: ""
}
/>
)}
</Box> </Box>
<Flex justify={"end"}> <Flex justify={"end"}>
<Button <Button
disabled={isDisabled} disabled={isDisabled || !line.reasonType}
color={"green"} color={"green"}
size="xs" size="xs"
onClick={() => { onClick={() => {
if (!line.note) if (line.reasonType === "other" && !line.note) {
setDataLines( setDataLines(
dataLines.map((el) => dataLines.map((el) =>
el.id === line.id el.id === line.id
@ -139,14 +186,15 @@ export default function ModalConfirmSkipTestPort({
...el, ...el,
isError: true, isError: true,
} }
: el : el,
) ),
); );
else { } else {
socket?.emit("end_run_physical_test", { socket?.emit("end_run_physical_test", {
lineId: line?.id, lineId: line?.id,
stationId: Number(station?.id), stationId: Number(station?.id),
reasonSkipPhysical: line?.note, reasonSkipPhysical:
line.reasonType === "no_poe" ? "No PoE" : line?.note,
}); });
setDataLines(dataLines.filter((el) => el.id !== line.id)); setDataLines(dataLines.filter((el) => el.id !== line.id));
setListLines(listLines.filter((el) => el.id !== line.id)); setListLines(listLines.filter((el) => el.id !== line.id));