Remove finished work orders
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
be478f3b2e
commit
6883b707ad
4 changed files with 28 additions and 2 deletions
2
app.py
2
app.py
|
|
@ -330,6 +330,8 @@ class Handler(BaseHTTPRequestHandler):
|
||||||
return game.provide_reagent(world, player, body.get("id"), str(item))
|
return game.provide_reagent(world, player, body.get("id"), str(item))
|
||||||
if path == "/api/order/cancel":
|
if path == "/api/order/cancel":
|
||||||
return game.cancel_order(world, player, body.get("id"), now)
|
return game.cancel_order(world, player, body.get("id"), now)
|
||||||
|
if path == "/api/order/remove":
|
||||||
|
return game.remove_orders(world, player, body.get("id"))
|
||||||
if path == "/api/order/work":
|
if path == "/api/order/work":
|
||||||
return game.work_order(world, player, body.get("id"), now)
|
return game.work_order(world, player, body.get("id"), now)
|
||||||
if path == "/api/order/drop":
|
if path == "/api/order/drop":
|
||||||
|
|
|
||||||
10
game.py
10
game.py
|
|
@ -2285,6 +2285,16 @@ def cancel_order(world: dict, player: dict, order_id, now: float) -> str | None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def remove_orders(world: dict, player: dict, order_id=None) -> str | None:
|
||||||
|
"""Clear your finished orders: one, or all of them. Ones still holding items for your bank stay."""
|
||||||
|
gone = [o for o in world["orders"] if o["by"] == player["id"] and o["status"] != "open" and not o["held"]
|
||||||
|
and order_id in (None, o["id"])]
|
||||||
|
if not gone:
|
||||||
|
return "No such order"
|
||||||
|
world["orders"] = [o for o in world["orders"] if o not in gone]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def claim_order(world: dict, player: dict, order_id, claim: bool = True) -> str | None:
|
def claim_order(world: dict, player: dict, order_id, claim: bool = True) -> str | None:
|
||||||
order = order_by_id(world, order_id)
|
order = order_by_id(world, order_id)
|
||||||
if not order or order["status"] != "open" or order["kind"] != "craft":
|
if not order or order["status"] != "open" or order["kind"] != "craft":
|
||||||
|
|
|
||||||
|
|
@ -1240,6 +1240,7 @@ function orderCard(o) {
|
||||||
let buttons = "", status = "";
|
let buttons = "", status = "";
|
||||||
if (o.status !== "open") {
|
if (o.status !== "open") {
|
||||||
status = `<span class="tag ${o.status === "done" ? "good" : ""}">${{ done: "Done", cancelled: "Cancelled", expired: "Expired" }[o.status]}</span>`;
|
status = `<span class="tag ${o.status === "done" ? "good" : ""}">${{ done: "Done", cancelled: "Cancelled", expired: "Expired" }[o.status]}</span>`;
|
||||||
|
if (mine && !o.held) buttons = `<button class="btn" data-order-remove="${o.id}">Remove</button>`;
|
||||||
} else if (mine) {
|
} else if (mine) {
|
||||||
buttons = `<button class="btn danger" data-order-cancel="${o.id}">Cancel</button>`;
|
buttons = `<button class="btn danger" data-order-cancel="${o.id}">Cancel</button>`;
|
||||||
if (o.claimed) status = `<span class="tag">${esc(playerName(o.claimed))}</span>`;
|
if (o.claimed) status = `<span class="tag">${esc(playerName(o.claimed))}</span>`;
|
||||||
|
|
@ -1336,12 +1337,14 @@ function orders() {
|
||||||
const lists = { take: takeable, open, yours };
|
const lists = { take: takeable, open, yours };
|
||||||
if (!lists[orderTab]) orderTab = "take";
|
if (!lists[orderTab]) orderTab = "take";
|
||||||
const shown = lists[orderTab];
|
const shown = lists[orderTab];
|
||||||
const tab = (key, label, n) => `<button class="tab ${orderTab === key ? "on" : ""}" data-otab="${key}">${label}${n ? ` <b class="badge">${n}</b>` : ""}</button>`;
|
const old = orderTab === "yours" && yours.some((o) => o.status !== "open" && !o.held);
|
||||||
|
const tab =(key, label, n) => `<button class="tab ${orderTab === key ? "on" : ""}" data-otab="${key}">${label}${n ? ` <b class="badge">${n}</b>` : ""}</button>`;
|
||||||
return `<div class="panel"><div class="skill-head"><div class="big">${ORDER_ICON()}</div>
|
return `<div class="panel"><div class="skill-head"><div class="big">${ORDER_ICON()}</div>
|
||||||
<div class="info"><h2>Work orders</h2></div>
|
<div class="info"><h2>Work orders</h2></div>
|
||||||
<button class="btn ${draft ? "" : "primary"}" data-order-new>${draft ? "Close" : "New order"}</button></div></div>
|
<button class="btn ${draft ? "" : "primary"}" data-order-new>${draft ? "Close" : "New order"}</button></div></div>
|
||||||
${draft ? orderComposer() : ""}
|
${draft ? orderComposer() : ""}
|
||||||
<div class="tabs">${tab("take", "For you", takeable.length)}${tab("open", "All open", 0)}${tab("yours", "Yours", 0)}</div>
|
<div class="tabs">${tab("take", "For you", takeable.length)}${tab("open", "All open", 0)}${tab("yours", "Yours", 0)}
|
||||||
|
${old ? `<button class="btn" data-order-clear>Clear</button>` : ""}</div>
|
||||||
${shown.length ? `<div class="grid wide">${shown.map(orderCard).join("")}</div>` : `<p class="muted">None.</p>`}`;
|
${shown.length ? `<div class="grid wide">${shown.map(orderCard).join("")}</div>` : `<p class="muted">None.</p>`}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1664,6 +1667,8 @@ document.addEventListener("click", (e) => {
|
||||||
if (d.orderDrop) return act("/api/order/drop", { id: Number(d.orderDrop) });
|
if (d.orderDrop) return act("/api/order/drop", { id: Number(d.orderDrop) });
|
||||||
if (d.orderDeliver) return act("/api/order/deliver", { id: Number(d.orderDeliver) });
|
if (d.orderDeliver) return act("/api/order/deliver", { id: Number(d.orderDeliver) });
|
||||||
if (d.orderCancel) return act("/api/order/cancel", { id: Number(d.orderCancel) });
|
if (d.orderCancel) return act("/api/order/cancel", { id: Number(d.orderCancel) });
|
||||||
|
if (d.orderRemove) return act("/api/order/remove", { id: Number(d.orderRemove) });
|
||||||
|
if ("orderClear" in d) return act("/api/order/remove", {});
|
||||||
if (d.orderFill) return act("/api/order/provide", { id: Number(d.orderFill), item: d.item });
|
if (d.orderFill) return act("/api/order/provide", { id: Number(d.orderFill), item: d.item });
|
||||||
if (d.doll) {
|
if (d.doll) {
|
||||||
dollPick = dollPick === d.doll ? null : d.doll;
|
dollPick = dollPick === d.doll ? null : d.doll;
|
||||||
|
|
|
||||||
|
|
@ -1609,6 +1609,15 @@ class WorkOrderTest(unittest.TestCase):
|
||||||
self.assertEqual(self.mike["gold"], 200)
|
self.assertEqual(self.mike["gold"], 200)
|
||||||
self.assertEqual(self.mike["bank"]["iron_bar"], 3)
|
self.assertEqual(self.mike["bank"]["iron_bar"], 3)
|
||||||
|
|
||||||
|
def test_finished_orders_can_be_removed(self):
|
||||||
|
self.post_hammer()
|
||||||
|
order = self.world["orders"][0]
|
||||||
|
self.assertEqual(game.remove_orders(self.world, self.mike, order["id"]), "No such order") # still open
|
||||||
|
game.cancel_order(self.world, self.mike, order["id"], T0)
|
||||||
|
self.assertEqual(game.remove_orders(self.world, self.fred, order["id"]), "No such order") # not his
|
||||||
|
self.assertIsNone(game.remove_orders(self.world, self.mike))
|
||||||
|
self.assertEqual(self.world["orders"], [])
|
||||||
|
|
||||||
def test_requester_can_fill_a_slot_after_posting(self):
|
def test_requester_can_fill_a_slot_after_posting(self):
|
||||||
self.mike["gold"] = 200
|
self.mike["gold"] = 200
|
||||||
self.mike["bank"] = {"iron_bar": 3, "clay_core": 3}
|
self.mike["bank"] = {"iron_bar": 3, "clay_core": 3}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue