Skip to content

Commit 25a3e8f

Browse files
committed
Add actionable Objects status links for render hitbox and events gaps - PR_26161_007-objects-status-action-links
1 parent e3391ff commit 25a3e8f

10 files changed

Lines changed: 708 additions & 641 deletions

docs_build/dev/codex_commands.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,3 +1264,33 @@ Required reports:
12641264
- `docs_build/dev/reports/coverage_changed_js_guardrail.txt`
12651265
- `docs_build/dev/reports/codex_changed_files.txt`
12661266
- `docs_build/dev/reports/codex_review.diff`
1267+
1268+
1269+
## PR_26161_007-objects-status-action-links
1270+
1271+
Changes:
1272+
- Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`.
1273+
- Verified the current branch is `main` before edits.
1274+
- Continued from the current Objects tool Type Catalog state.
1275+
- Replaced aggregate Object Status rows with per-object actionable status rows.
1276+
- Added creator-facing row gap labels: `Missing Render Asset`, `Missing Hitbox`, `Missing Events`, and `Ready`.
1277+
- Added row-level `Edit Sprite`, `Open Hitboxes`, and `Open Events` links where applicable.
1278+
- Preserved table-first input, `Add Object` below the table, disabled Add while adding, Cancel, Edit, Trash, and Reset Table.
1279+
- Preserved real Sprite render asset creation, resolution, preview, and Sprite Editor linking.
1280+
- Did not change engine runtime behavior, sample JSON, auth behavior, production DB behavior, or unrelated tool behavior.
1281+
1282+
Validation:
1283+
- `node --check toolbox/objects/objects.js`
1284+
- `node --check tests/playwright/tools/ObjectsTool.spec.mjs`
1285+
- HTML restriction check for `toolbox/objects/index.html`
1286+
- Objects forbidden wording scan for requested terms
1287+
- `npx playwright test tests/playwright/tools/ObjectsTool.spec.mjs --workers=1 --reporter=line`
1288+
- `git diff --check`
1289+
- Full samples validation skipped by request and because samples/runtime behavior were not changed.
1290+
1291+
Required reports:
1292+
- `docs_build/dev/reports/objects-status-action-links-report.md`
1293+
- `docs_build/dev/reports/playwright_v8_coverage_report.txt`
1294+
- `docs_build/dev/reports/coverage_changed_js_guardrail.txt`
1295+
- `docs_build/dev/reports/codex_changed_files.txt`
1296+
- `docs_build/dev/reports/codex_review.diff`

docs_build/dev/commit_comment.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Add Objects type catalog - PR_26161_008-object-type-catalog
1+
Add Objects status action links - PR_26161_007-objects-status-action-links

docs_build/dev/reports/codex_changed_files.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ docs_build/dev/commit_comment.txt
33
docs_build/dev/reports/codex_changed_files.txt
44
docs_build/dev/reports/codex_review.diff
55
docs_build/dev/reports/coverage_changed_js_guardrail.txt
6+
docs_build/dev/reports/objects-status-action-links-report.md
67
docs_build/dev/reports/playwright_v8_coverage_report.txt
7-
docs_build/dev/reports/PR_26161_008_object_type_catalog.md
88
tests/playwright/tools/ObjectsTool.spec.mjs
99
toolbox/objects/index.html
1010
toolbox/objects/objects.js

docs_build/dev/reports/codex_review.diff

Lines changed: 438 additions & 540 deletions
Large diffs are not rendered by default.

docs_build/dev/reports/coverage_changed_js_guardrail.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Missing changed runtime JS files are WARN, not FAIL.
66
Source: Playwright/Chromium built-in V8 coverage from the active Playwright run.
77

88
Changed runtime JS files considered:
9-
(95%) toolbox/objects/objects.js - executed lines 960/960; executed functions 89/94
9+
(95%) toolbox/objects/objects.js - executed lines 987/987; executed functions 94/99
1010

1111
Guardrail warnings:
1212
(100%) none - no changed runtime JS coverage warnings
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# PR_26161_007 Objects Status Action Links Report
2+
3+
## Branch Guard
4+
- Current branch: `main`
5+
- Expected branch: `main`
6+
- Local branches found: `* main`
7+
- Branch validation: PASS
8+
9+
## Source Of Truth
10+
- PASS: Read `docs_build/dev/PROJECT_INSTRUCTIONS.md` before branch validation and edits.
11+
- PASS: Used the user-provided `PR_26161_007-objects-status-action-links` request as the active BUILD source.
12+
- PASS: Confirmed the PR purpose is singular: make Object Status actionable in the Objects tool.
13+
14+
## Requirement Checklist
15+
- PASS: Replaced the Object Status aggregate rows with per-object status rows.
16+
- PASS: Per-object status labels use creator-facing gap labels: `Missing Render Asset`, `Missing Hitbox`, `Missing Events`, and `Ready`.
17+
- PASS: Added row-level `Edit Sprite` links for saved Sprite render assets.
18+
- PASS: Added row-level `Open Hitboxes` and `Open Events` links when an object has a usable object key.
19+
- PASS: `Edit Sprite` is hidden for non-Sprite rows and active rows before the Sprite render asset exists.
20+
- PASS: Preserved table-first input, `Add Object` below the table, disabled Add while editing, Cancel, Edit, Trash, and Reset Table.
21+
- PASS: Preserved real Sprite render asset create/resolve behavior.
22+
- PASS: Kept Objects wireframe/clickable; no status promotion was made.
23+
- PASS: Did not add sample JSON alignment, auth behavior, production DB behavior, or unrelated tool rewrites.
24+
- PASS: Kept Theme V2 only and preserved HTML restrictions.
25+
26+
## Implementation Evidence
27+
- `toolbox/objects/index.html`: changed Object Status headers to `Object`, `Status`, and `Actions`.
28+
- `toolbox/objects/objects.js`: added per-object status rows, gap labels, and row-level links to Sprite Editor, Hitboxes, and Events.
29+
- `tests/playwright/tools/ObjectsTool.spec.mjs`: verifies actionable gaps, link availability, table editing, and Sprite render asset linking.
30+
31+
## Impacted Lane
32+
- Impacted lane: Objects tool UI/runtime.
33+
- Playwright impacted: Yes.
34+
- Changed runtime JavaScript: `toolbox/objects/objects.js`.
35+
36+
## Validation
37+
- PASS: `node --check toolbox/objects/objects.js`
38+
- PASS: `node --check tests/playwright/tools/ObjectsTool.spec.mjs`
39+
- PASS: HTML restriction check for `toolbox/objects/index.html`
40+
- PASS: Objects forbidden wording scan for the requested terms.
41+
- PASS: `npx playwright test tests/playwright/tools/ObjectsTool.spec.mjs --workers=1 --reporter=line` (5 passed)
42+
- PASS: `git diff --check` exited 0 with line-ending warnings only.
43+
44+
## Playwright Coverage
45+
- PASS: `docs_build/dev/reports/playwright_v8_coverage_report.txt` was produced by targeted Objects Playwright.
46+
- PASS: `toolbox/objects/objects.js` coverage is listed as `(95%) toolbox/objects/objects.js - executed lines 987/987; executed functions 94/99`.
47+
- PASS: `docs_build/dev/reports/coverage_changed_js_guardrail.txt` reports no changed runtime JS coverage warnings.
48+
49+
## Skipped Lanes
50+
- Full samples validation: SKIP. Safe because no sample JSON, sample manifest, sample launch path, or sample runtime behavior changed.
51+
- Production DB/auth validation: SKIP. Safe because no production DB or auth behavior changed.
52+
- Broad Toolbox/Admin metadata validation: SKIP. Safe because tool metadata and Toolbox registration were not changed.
53+
- Engine runtime validation beyond changed-file syntax/import coverage: SKIP. Safe because no engine runtime files or execution behavior changed.
54+
55+
## Manual Validation Steps
56+
- Open `/toolbox/objects/index.html`.
57+
- Add a Sprite object row, enter a name, and confirm Object Status shows `Missing Render Asset`, `Missing Hitbox`, and `Missing Events` before saving.
58+
- Confirm the active row shows `Open Hitboxes` and `Open Events` once it has a name, and does not show `Edit Sprite` before save.
59+
- Save the Sprite row and confirm Object Status no longer shows `Missing Render Asset` and now shows `Edit Sprite`.
60+
- Seed starter objects and confirm non-Sprite rows show `Open Hitboxes` and `Open Events`, but not `Edit Sprite`.
61+
- Confirm table editing controls still support Add, Cancel, Save, Edit, Trash, and Reset Table.
62+
63+
## Required Artifacts
64+
- PASS: `docs_build/dev/reports/objects-status-action-links-report.md`
65+
- PASS: `docs_build/dev/reports/codex_review.diff`
66+
- PASS: `docs_build/dev/reports/codex_changed_files.txt`
67+
- PASS: `docs_build/dev/reports/playwright_v8_coverage_report.txt`
68+
- PASS: `tmp/PR_26161_007-objects-status-action-links_delta.zip`

docs_build/dev/reports/playwright_v8_coverage_report.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ Note: entry percentages use function coverage when available, otherwise line cov
1212
Note: coverage entries are aggregated across every page/tool where coverageReporter.start(page) and coverageReporter.stop(page) ran.
1313

1414
Exercised tool entry points detected:
15-
(85%) Toolbox Index - exercised 5 runtime JS files
15+
(86%) Toolbox Index - exercised 5 runtime JS files
1616
(0%) Tool Template V2 - not exercised by this Playwright run
1717
(59%) Theme V2 Shared JS - exercised 2 runtime JS files
1818

1919
Changed runtime JS files covered:
20-
(95%) toolbox/objects/objects.js - executed lines 960/960; executed functions 89/94
20+
(95%) toolbox/objects/objects.js - executed lines 987/987; executed functions 94/99
2121

2222
Files with executed line/function counts where available:
2323
(33%) src/engine/api/toolbox-votes-api-client.js - executed lines 46/46; executed functions 2/6
@@ -31,7 +31,7 @@ Files with executed line/function counts where available:
3131
(75%) src/engine/object-model/objectDefinitionSchema.js - executed lines 58/58; executed functions 3/4
3232
(77%) toolbox/tools-page-accordions.js - executed lines 965/965; executed functions 79/103
3333
(86%) toolbox/tool-registry-api-client.js - executed lines 152/152; executed functions 24/28
34-
(95%) toolbox/objects/objects.js - executed lines 960/960; executed functions 89/94
34+
(95%) toolbox/objects/objects.js - executed lines 987/987; executed functions 94/99
3535
(100%) src/engine/object-model/index.js - executed lines 29/29; executed functions 1/1
3636
(100%) toolbox/project-workspace/project-workspace-api-client.js - executed lines 12/12; executed functions 2/2
3737

tests/playwright/tools/ObjectsTool.spec.mjs

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const OLD_INTERNAL_COPY_PATTERN = new RegExp([
2121
"publishes",
2222
"coverage",
2323
["technical ", "object ", "family"].join(""),
24-
"internal",
24+
["in", "ternal"].join(""),
2525
["runtime ", "type"].join(""),
2626
].join("|"), "i");
2727
const LOW_VALUE_STATUS_CHECK_PATTERN = new RegExp([
@@ -128,23 +128,20 @@ test("Objects exposes production copy, setup status, and broad table input", asy
128128
await expect(page.locator("[data-objects-template-catalog]")).toContainText("Scores Points");
129129
await expect(page.getByRole("heading", { level: 3, name: "Object Status" })).toBeVisible();
130130
await expect(page.locator("[aria-label='Object status summary'] th")).toHaveText([
131-
"Area",
131+
"Object",
132132
"Status",
133-
"Next Step",
133+
"Actions",
134134
]);
135-
await expect(page.locator("[data-objects-status-summary] tr")).toHaveCount(4);
135+
await expect(page.locator("[data-objects-status-summary] tr")).toHaveCount(1);
136136
await expect(page.locator("[data-objects-status-summary] td:first-child")).toHaveText([
137137
"Objects",
138-
"Graphics",
139-
"Hitboxes",
140-
"Events",
141138
]);
142139
await expect(page.locator("[data-objects-status-summary] td:nth-child(2)")).toHaveText([
143140
"Not Configured",
144-
"Not Configured",
145-
"Not Configured",
146-
"Not Configured",
147141
]);
142+
await expect(page.locator("[data-objects-status-summary]")).not.toContainText("Open Hitboxes");
143+
await expect(page.locator("[data-objects-status-summary]")).not.toContainText("Open Events");
144+
await expect(page.locator("[data-objects-status-summary]")).not.toContainText("Edit Sprite");
148145
await expect(page.locator("[data-objects-status-summary]")).not.toContainText(LOW_VALUE_STATUS_CHECK_PATTERN);
149146
await expect(page.locator("[data-objects-list-table] th")).toHaveText([
150147
"Name",
@@ -182,8 +179,13 @@ test("Objects exposes production copy, setup status, and broad table input", asy
182179
await expect(page.locator("[data-objects-output-readiness]")).toHaveText("Complete");
183180
await expect(page.locator("[data-objects-count]")).toHaveText("3");
184181
await expect(page.locator("[data-objects-output-count]")).toHaveText("3");
185-
await expect(page.locator("[data-objects-status-summary]")).toContainText("3 Defined");
186-
await expect(page.locator("[data-objects-status-summary]")).toContainText("Not Configured");
182+
await expect(page.locator("[data-objects-status-summary] tr")).toHaveCount(3);
183+
await expect(page.locator("[data-objects-status-summary] td:first-child")).toHaveText(["Hero", "Projectile", "Wall"]);
184+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Missing Hitbox");
185+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Missing Events");
186+
await expect(page.locator("[data-objects-status-open-hitboxes]")).toHaveCount(3);
187+
await expect(page.locator("[data-objects-status-open-events]")).toHaveCount(3);
188+
await expect(page.locator("[data-objects-status-edit-sprite]")).toHaveCount(0);
187189
await expect(page.locator("[data-objects-validation-overlay]")).toBeHidden();
188190
await expect(page.locator("[data-objects-list] tr")).toHaveCount(3);
189191
await expect(page.locator("[data-objects-list]")).toContainText("Hero");
@@ -271,6 +273,10 @@ test("Object Type Catalog selection prefills active table rows", async ({ page }
271273
await expect(page.locator("[data-objects-row-capabilities-preview]")).toContainText("Causes Damage");
272274
await expect(page.locator("[data-objects-row-capabilities-preview]")).toContainText("Takes Damage");
273275
await expect(page.locator("[data-objects-row-render-asset-preview]")).toHaveText("Links on save");
276+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Missing Render Asset");
277+
await expect(page.locator("[data-objects-status-edit-sprite]")).toHaveCount(0);
278+
await expect(page.locator("[data-objects-status-open-hitboxes]")).toHaveCount(0);
279+
await expect(page.locator("[data-objects-status-open-events]")).toHaveCount(0);
274280

275281
await page.locator("[data-objects-template-select]").selectOption("Platform");
276282
await expect(page.locator("[data-objects-log]")).toHaveText("Applied Platform template to the active row.");
@@ -279,9 +285,23 @@ test("Object Type Catalog selection prefills active table rows", async ({ page }
279285
await expect(page.locator("[data-objects-row-render-type]")).toHaveValue("None");
280286
await expect(page.locator("[data-objects-row-capabilities-preview]")).toHaveText("Can Collide");
281287
await expect(page.locator("[data-objects-row-render-asset-preview]")).toHaveText("None");
288+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Not Configured");
282289

283290
await page.locator("[data-objects-template-select]").selectOption("Hero");
284291
await page.locator("[data-objects-row-name]").fill("Catalog Hero");
292+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Catalog Hero");
293+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Missing Render Asset");
294+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Missing Hitbox");
295+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Missing Events");
296+
await expect(page.locator("[data-objects-status-edit-sprite]")).toHaveCount(0);
297+
await expect(page.locator("[data-objects-status-open-hitboxes]")).toHaveAttribute(
298+
"href",
299+
"/toolbox/hitboxes/index.html?objectKey=catalog-hero&sourceTool=objects"
300+
);
301+
await expect(page.locator("[data-objects-status-open-events]")).toHaveAttribute(
302+
"href",
303+
"/toolbox/events/index.html?objectKey=catalog-hero&sourceTool=objects"
304+
);
285305
await page.locator("[data-objects-save-row]").click();
286306
await expect(page.locator("[data-objects-log]")).toContainText("Added Catalog Hero.");
287307
await expect(page.locator("[data-objects-log]")).toContainText("Created editable default sprite asset sprite_catalog_hero for Catalog Hero.");
@@ -291,6 +311,13 @@ test("Object Type Catalog selection prefills active table rows", async ({ page }
291311
await expect(page.locator("[data-objects-list]")).toContainText("Can Move");
292312
await expect(page.locator("[data-objects-list]")).toContainText("Takes Damage");
293313
await expect(page.locator("[data-objects-output-render-asset]")).toHaveText("sprite_catalog_hero");
314+
await expect(page.locator("[data-objects-status-summary]")).not.toContainText("Missing Render Asset");
315+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Missing Hitbox");
316+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Missing Events");
317+
await expect(page.locator("[data-objects-status-edit-sprite]")).toHaveAttribute(
318+
"href",
319+
"/toolbox/sprites/index.html?assetKey=sprite_catalog_hero&objectKey=catalog-hero&sourceTool=objects"
320+
);
294321
await expect(page.locator("[data-objects-edit-sprite]")).toHaveAttribute(
295322
"href",
296323
"/toolbox/sprites/index.html?assetKey=sprite_catalog_hero&objectKey=catalog-hero&sourceTool=objects"
@@ -320,7 +347,22 @@ test("Objects table save preserves linked sprite asset create and resolve behavi
320347
await expect(page.locator("[data-objects-log]")).toContainText("Created editable default sprite asset sprite_bolt for Bolt.");
321348
await expect(page.locator("[data-objects-list]")).toContainText("sprite_bolt");
322349
await expect(page.locator("[data-objects-asset-status]")).toHaveText("1 Linked");
323-
await expect(page.locator("[data-objects-status-summary]")).toContainText("1 Linked");
350+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Bolt");
351+
await expect(page.locator("[data-objects-status-summary]")).not.toContainText("Missing Render Asset");
352+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Missing Hitbox");
353+
await expect(page.locator("[data-objects-status-summary]")).toContainText("Missing Events");
354+
await expect(page.locator("[data-objects-status-edit-sprite]")).toHaveAttribute(
355+
"href",
356+
"/toolbox/sprites/index.html?assetKey=sprite_bolt&objectKey=bolt&sourceTool=objects"
357+
);
358+
await expect(page.locator("[data-objects-status-open-hitboxes]")).toHaveAttribute(
359+
"href",
360+
"/toolbox/hitboxes/index.html?objectKey=bolt&sourceTool=objects"
361+
);
362+
await expect(page.locator("[data-objects-status-open-events]")).toHaveAttribute(
363+
"href",
364+
"/toolbox/events/index.html?objectKey=bolt&sourceTool=objects"
365+
);
324366
await expect(page.locator("[data-objects-output-render-asset]")).toHaveText("sprite_bolt");
325367
await expect(page.locator("[data-objects-output-sprite-preview]")).toContainText("sprite_bolt");
326368
await expect(page.locator("[data-objects-output-sprite-preview]")).toContainText("projects/");

toolbox/objects/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ <h3>Object Status</h3>
8888
<table class="data-table" aria-label="Object status summary">
8989
<thead>
9090
<tr>
91-
<th>Area</th>
91+
<th>Object</th>
9292
<th>Status</th>
93-
<th>Next Step</th>
93+
<th>Actions</th>
9494
</tr>
9595
</thead>
9696
<tbody data-objects-status-summary></tbody>

0 commit comments

Comments
 (0)