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:
@@ -78,6 +78,19 @@ function localPlanet(
|
||||
};
|
||||
}
|
||||
|
||||
function shipClass(
|
||||
overrides: Partial<ShipClassSummary> & Pick<ShipClassSummary, "name">,
|
||||
): ShipClassSummary {
|
||||
return {
|
||||
drive: 0,
|
||||
armament: 0,
|
||||
weapons: 0,
|
||||
shields: 0,
|
||||
cargo: 0,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function mountProduction(
|
||||
planet: ReportPlanet,
|
||||
localShipClass: ShipClassSummary[] = [],
|
||||
@@ -167,8 +180,8 @@ describe("planet inspector — production controls", () => {
|
||||
|
||||
test("Build-Ship click on a class emits a SHIP setProductionType command", async () => {
|
||||
const ui = mountProduction(localPlanet({ number: 7 }), [
|
||||
{ name: "Scout" },
|
||||
{ name: "Destroyer" },
|
||||
shipClass({ name: "Scout" }),
|
||||
shipClass({ name: "Destroyer" }),
|
||||
]);
|
||||
await fireEvent.click(
|
||||
ui.getByTestId("inspector-planet-production-segment-ship"),
|
||||
@@ -185,7 +198,7 @@ describe("planet inspector — production controls", () => {
|
||||
|
||||
test("re-clicks on the same planet collapse to the latest entry via the store", async () => {
|
||||
const ui = mountProduction(localPlanet({ number: 7 }), [
|
||||
{ name: "Scout" },
|
||||
shipClass({ name: "Scout" }),
|
||||
]);
|
||||
await fireEvent.click(
|
||||
ui.getByTestId("inspector-planet-production-segment-industry"),
|
||||
@@ -224,7 +237,7 @@ describe("planet inspector — production controls", () => {
|
||||
for (const tc of cases) {
|
||||
const ui = mountProduction(
|
||||
localPlanet({ number: 1, production: tc.production }),
|
||||
[{ name: "Scout" }],
|
||||
[shipClass({ name: "Scout" })],
|
||||
);
|
||||
const ids: ReadonlyArray<
|
||||
"industry" | "materials" | "research" | "ship"
|
||||
@@ -268,7 +281,7 @@ describe("planet inspector — production controls", () => {
|
||||
test("ship class sub-row matches when production equals a class name", async () => {
|
||||
const ui = mountProduction(
|
||||
localPlanet({ number: 1, production: "Scout" }),
|
||||
[{ name: "Scout" }, { name: "Destroyer" }],
|
||||
[shipClass({ name: "Scout" }), shipClass({ name: "Destroyer" })],
|
||||
);
|
||||
expect(
|
||||
ui.getByTestId("inspector-planet-production-ship-Scout").classList
|
||||
|
||||
Reference in New Issue
Block a user