Improve downtime qualification visibility

This commit is contained in:
masterdev
2026-06-17 02:21:47 +01:00
parent c7c11d5060
commit 4e6286b1a3
4 changed files with 138 additions and 28 deletions

View File

@@ -192,6 +192,16 @@ export default function App() {
const selectedMachine = dashboard?.machines.find((machine) => machine.id === selectedMachineId) ?? null;
const machines = dashboard?.machines ?? [];
const selectedMachineOpenDowntimes =
selectedMachineId === null ? [] : openDowntimes.filter((downtime) => downtime.machine_id === selectedMachineId);
const downtimeOptions = [...openDowntimes].sort((left, right) => {
const leftSelected = selectedMachineId !== null && left.machine_id === selectedMachineId;
const rightSelected = selectedMachineId !== null && right.machine_id === selectedMachineId;
if (leftSelected !== rightSelected) {
return Number(rightSelected) - Number(leftSelected);
}
return new Date(left.start_time).getTime() - new Date(right.start_time).getTime();
});
const summaryMetrics = {
production: machines.filter((machine) => machine.status === "production").length,
openDowntimes: openDowntimes.length,
@@ -403,6 +413,22 @@ export default function App() {
return toasts[key] ? <div className="inline-toast">{toasts[key]}</div> : null;
}
function downtimeMachineLabel(downtime: Downtime) {
if (downtime.machine_code) {
return downtime.machine_code;
}
const machine = machines.find((item) => item.id === downtime.machine_id);
return machine?.code ?? `Machine ${downtime.machine_id ?? "-"}`;
}
function downtimeOptionLabel(downtime: Downtime) {
const parts = [`#${downtime.id}`, downtimeMachineLabel(downtime)];
if (downtime.order_number) {
parts.push(downtime.order_number);
}
return parts.join(" / ");
}
function renderModule(): ReactNode {
if (activeModule === "atelier") {
return (
@@ -631,23 +657,31 @@ export default function App() {
if (activeModule === "downtimes") {
return (
<Panel title="Qualification Arret" subtitle={`${openDowntimes.length} open downtime(s)`}>
<Panel
title="Qualification Arret"
subtitle={
selectedMachine
? `${selectedMachineOpenDowntimes.length} open for ${selectedMachine.code} / ${openDowntimes.length} total`
: `${openDowntimes.length} open downtime(s)`
}
>
<div className="module-grid module-grid--form-table">
<form
className="form-grid module-form"
key={selectedMachine?.id ?? "all-downtimes"}
onSubmit={submitDowntimeQualification}
onBlurCapture={(event) => handleFormBlur("downtime", event.currentTarget)}
onInputCapture={(event) => validateForm(event.currentTarget, "downtime")}
onChangeCapture={(event) => validateForm(event.currentTarget, "downtime")}
noValidate
>
<select name="downtime_id" required defaultValue="">
<select name="downtime_id" required defaultValue={selectedMachineOpenDowntimes[0]?.id ?? ""}>
<option value="" disabled>
Open downtime
</option>
{openDowntimes.map((downtime) => (
{downtimeOptions.map((downtime) => (
<option key={downtime.id} value={downtime.id}>
#{downtime.id} machine {downtime.machine_id}
{downtimeOptionLabel(downtime)}
</option>
))}
</select>
@@ -673,17 +707,47 @@ export default function App() {
{toast("downtime")}
</form>
<ul className="timeline-list">
{openDowntimes.map((item) => (
<li key={item.id}>
<div>
<strong>Machine {item.machine_id}</strong>
<span>Waiting qualification</span>
</div>
<time>{new Date(item.start_time).toLocaleString()}</time>
</li>
))}
</ul>
<div className="downtime-board">
{selectedMachine ? (
<section className="downtime-focus">
<span className="meta-label">Selected machine</span>
<strong>{selectedMachine.code}</strong>
{selectedMachineOpenDowntimes.length > 0 ? (
<ul className="timeline-list timeline-list--compact">
{selectedMachineOpenDowntimes.map((item) => (
<li key={item.id}>
<div>
<strong>{downtimeOptionLabel(item)}</strong>
<span>{item.reason_code ?? "Waiting qualification"}</span>
</div>
<time>{new Date(item.start_time).toLocaleString()}</time>
</li>
))}
</ul>
) : (
<div className="empty-state">No open downtime for {selectedMachine.code}.</div>
)}
</section>
) : null}
<section>
<span className="meta-label">All open stops</span>
<ul className="timeline-list">
{downtimeOptions.map((item) => (
<li key={item.id} className={item.machine_id === selectedMachineId ? "is-current-machine" : ""}>
<div>
<strong>{downtimeMachineLabel(item)}</strong>
<span>
{item.order_number ? `${item.order_number} / ` : ""}
{item.reason_code ?? "Waiting qualification"}
</span>
</div>
<time>{new Date(item.start_time).toLocaleString()}</time>
</li>
))}
</ul>
</section>
</div>
{openDowntimes.length === 0 ? <div className="empty-state">No open downtime currently needs qualification.</div> : null}
</div>
</Panel>