cleanup
This commit is contained in:
@@ -4,6 +4,7 @@ import type { ManufacturingStationDto } from "@mrp/shared";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
import { ConfirmActionDialog } from "../../components/ConfirmActionDialog";
|
||||
import { useAuth } from "../../auth/AuthProvider";
|
||||
import { api, ApiError } from "../../lib/api";
|
||||
import { emptyInventoryBomLineInput, emptyInventoryItemInput, emptyInventoryOperationInput, inventoryStatusOptions, inventoryTypeOptions, inventoryUnitOptions } from "./config";
|
||||
@@ -26,6 +27,7 @@ export function InventoryFormPage({ mode }: InventoryFormPageProps) {
|
||||
const [vendorPickerOpen, setVendorPickerOpen] = useState(false);
|
||||
const [status, setStatus] = useState(mode === "create" ? "Create a new inventory item." : "Loading inventory item...");
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [pendingRemoval, setPendingRemoval] = useState<{ kind: "operation" | "bom-line"; index: number } | null>(null);
|
||||
|
||||
function getComponentOption(componentItemId: string) {
|
||||
return componentOptions.find((option) => option.id === componentItemId) ?? null;
|
||||
@@ -192,6 +194,12 @@ export function InventoryFormPage({ mode }: InventoryFormPageProps) {
|
||||
setActiveComponentPicker((current) => (current === index ? null : current != null && current > index ? current - 1 : current));
|
||||
}
|
||||
|
||||
const pendingRemovalDetail = pendingRemoval
|
||||
? pendingRemoval.kind === "operation"
|
||||
? { label: form.operations[pendingRemoval.index]?.stationId || "this routing operation", typeLabel: "routing operation" }
|
||||
: { label: getComponentSku(form.bomLines[pendingRemoval.index]?.componentItemId ?? "") || "this BOM line", typeLabel: "BOM line" }
|
||||
: null;
|
||||
|
||||
async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
|
||||
event.preventDefault();
|
||||
if (!token) {
|
||||
@@ -472,7 +480,7 @@ export function InventoryFormPage({ mode }: InventoryFormPageProps) {
|
||||
<input type="number" min={0} step={10} value={operation.position} onChange={(event) => updateOperation(index, { ...operation, position: Number(event.target.value) || 0 })} className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand" />
|
||||
</label>
|
||||
<div className="flex items-end">
|
||||
<button type="button" onClick={() => removeOperation(index)} className="rounded-2xl border border-rose-400/40 px-2 py-2 text-sm font-semibold text-rose-700 dark:text-rose-300">
|
||||
<button type="button" onClick={() => setPendingRemoval({ kind: "operation", index })} className="rounded-2xl border border-rose-400/40 px-2 py-2 text-sm font-semibold text-rose-700 dark:text-rose-300">
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
@@ -619,7 +627,7 @@ export function InventoryFormPage({ mode }: InventoryFormPageProps) {
|
||||
<div className="flex items-end">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => removeBomLine(index)}
|
||||
onClick={() => setPendingRemoval({ kind: "bom-line", index })}
|
||||
className="rounded-2xl border border-rose-400/40 px-2 py-2 text-sm font-semibold text-rose-700 dark:text-rose-300"
|
||||
>
|
||||
Remove
|
||||
@@ -649,6 +657,31 @@ export function InventoryFormPage({ mode }: InventoryFormPageProps) {
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
<ConfirmActionDialog
|
||||
open={pendingRemoval != null}
|
||||
title={pendingRemoval?.kind === "operation" ? "Remove routing operation" : "Remove BOM line"}
|
||||
description={
|
||||
pendingRemoval && pendingRemovalDetail
|
||||
? `Remove ${pendingRemovalDetail.label} from the item ${pendingRemovalDetail.typeLabel} draft.`
|
||||
: "Remove this draft row."
|
||||
}
|
||||
impact={
|
||||
pendingRemoval?.kind === "operation"
|
||||
? "The operation will no longer be copied into new work orders from this item."
|
||||
: "The component requirement will be removed from the BOM draft immediately."
|
||||
}
|
||||
recovery="Add the row back before saving if this change was accidental."
|
||||
confirmLabel={pendingRemoval?.kind === "operation" ? "Remove operation" : "Remove BOM line"}
|
||||
onClose={() => setPendingRemoval(null)}
|
||||
onConfirm={() => {
|
||||
if (pendingRemoval?.kind === "operation") {
|
||||
removeOperation(pendingRemoval.index);
|
||||
} else if (pendingRemoval?.kind === "bom-line") {
|
||||
removeBomLine(pendingRemoval.index);
|
||||
}
|
||||
setPendingRemoval(null);
|
||||
}}
|
||||
/>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { WarehouseInput, WarehouseLocationInput } from "@mrp/shared/dist/in
|
||||
import { useEffect, useState } from "react";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
import { ConfirmActionDialog } from "../../components/ConfirmActionDialog";
|
||||
import { useAuth } from "../../auth/AuthProvider";
|
||||
import { api, ApiError } from "../../lib/api";
|
||||
import { emptyWarehouseInput, emptyWarehouseLocationInput } from "./config";
|
||||
@@ -13,6 +14,7 @@ export function WarehouseFormPage({ mode }: { mode: "create" | "edit" }) {
|
||||
const [form, setForm] = useState<WarehouseInput>(emptyWarehouseInput);
|
||||
const [status, setStatus] = useState(mode === "create" ? "Create a new warehouse." : "Loading warehouse...");
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [pendingLocationRemovalIndex, setPendingLocationRemovalIndex] = useState<number | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (mode !== "edit" || !token || !warehouseId) {
|
||||
@@ -67,6 +69,8 @@ export function WarehouseFormPage({ mode }: { mode: "create" | "edit" }) {
|
||||
}));
|
||||
}
|
||||
|
||||
const pendingLocationRemoval = pendingLocationRemovalIndex != null ? form.locations[pendingLocationRemovalIndex] : null;
|
||||
|
||||
async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
|
||||
event.preventDefault();
|
||||
if (!token) {
|
||||
@@ -147,7 +151,7 @@ export function WarehouseFormPage({ mode }: { mode: "create" | "edit" }) {
|
||||
<input value={location.name} onChange={(event) => updateLocation(index, { ...location, name: event.target.value })} className="w-full rounded-2xl border border-line/70 bg-surface px-2 py-2 text-text outline-none transition focus:border-brand" />
|
||||
</label>
|
||||
<div className="flex items-end">
|
||||
<button type="button" onClick={() => removeLocation(index)} className="rounded-2xl border border-rose-400/40 px-2 py-2 text-sm font-semibold text-rose-700 dark:text-rose-300">
|
||||
<button type="button" onClick={() => setPendingLocationRemovalIndex(index)} className="rounded-2xl border border-rose-400/40 px-2 py-2 text-sm font-semibold text-rose-700 dark:text-rose-300">
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
@@ -167,6 +171,21 @@ export function WarehouseFormPage({ mode }: { mode: "create" | "edit" }) {
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
<ConfirmActionDialog
|
||||
open={pendingLocationRemoval != null}
|
||||
title="Remove warehouse location"
|
||||
description={pendingLocationRemoval ? `Remove location ${pendingLocationRemoval.code || pendingLocationRemoval.name || "from this warehouse draft"}.` : "Remove this location."}
|
||||
impact="The location will be removed from the warehouse edit form immediately."
|
||||
recovery="Add the location back before saving if it should remain part of this warehouse."
|
||||
confirmLabel="Remove location"
|
||||
onClose={() => setPendingLocationRemovalIndex(null)}
|
||||
onConfirm={() => {
|
||||
if (pendingLocationRemovalIndex != null) {
|
||||
removeLocation(pendingLocationRemovalIndex);
|
||||
}
|
||||
setPendingLocationRemovalIndex(null);
|
||||
}}
|
||||
/>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user