ui/phase-17: ship-class CRUD without calc
Phase 17 lights up the ship-class table and designer active views, extends the order-draft pipeline with createShipClass and removeShipClass commands, and projects pending Save/Delete actions through applyOrderOverlay so the table reflects the player's intent before auto-sync lands. The plan is corrected in the same patch: per game/rules.txt, ship classes are designed once and cannot be edited — the engine has no Update command, so the UI exposes only Create + Delete. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import { fetchOrder } from "./order-load";
|
||||
import type { CommandStatus, OrderCommand } from "./order-types";
|
||||
import { submitOrder } from "./submit";
|
||||
import { validateEntityName } from "$lib/util/entity-name";
|
||||
import { validateShipClass } from "$lib/util/ship-class-validation";
|
||||
|
||||
const NAMESPACE = "order-drafts";
|
||||
const draftKey = (gameId: string): string => `${gameId}/draft`;
|
||||
@@ -487,6 +488,31 @@ function validateCommand(cmd: OrderCommand): CommandStatus {
|
||||
// which the inspector enforces by only mounting the
|
||||
// component on `kind === "local"`.
|
||||
return "valid";
|
||||
case "createShipClass":
|
||||
// Mirrors `pkg/calc/validator.go.ValidateShipTypeValues`
|
||||
// plus the entity-name rules. The duplicate-name check is
|
||||
// the designer's responsibility (it sees the live overlay
|
||||
// list); here the validator runs without `existingNames`
|
||||
// so a draft that was valid at creation time does not flip
|
||||
// to invalid just because another `createShipClass` for
|
||||
// the same name landed in the draft afterwards — both
|
||||
// rows ride out the wire and the engine arbitrates.
|
||||
return validateShipClass({
|
||||
name: cmd.name,
|
||||
drive: cmd.drive,
|
||||
armament: cmd.armament,
|
||||
weapons: cmd.weapons,
|
||||
shields: cmd.shields,
|
||||
cargo: cmd.cargo,
|
||||
}).ok
|
||||
? "valid"
|
||||
: "invalid";
|
||||
case "removeShipClass":
|
||||
// `removeShipClass` carries only the name; the engine
|
||||
// checks that the class exists and is not referenced by
|
||||
// active production / ship groups. Local validation only
|
||||
// guards the name shape.
|
||||
return validateEntityName(cmd.name).ok ? "valid" : "invalid";
|
||||
case "placeholder":
|
||||
// Phase 12 placeholder entries are content-free and never
|
||||
// transition out of `draft` — they are not submittable.
|
||||
|
||||
Reference in New Issue
Block a user