Kaynağa Gözat

Fix: buildTaskRow owner dropdown was empty until a page refresh

Phase 10 replaced the single-select owner filter with a checkbox
multi-filter but left ownerChoices() in sprint-planner.js reading from
the old `[data-owner-filter] option` selector. That selector no longer
matches anything, so the function returns an empty list and every task
row built client-side (admin clicks "+ Add task") gets a dropdown with
no workers in it. A full page reload hides the bug because show.php
and present.php server-render each task row with its `<select
data-owner-select>` already populated from $ownerChoices.

Fix: scrape `[data-owner-filter-opt]` checkbox inputs — the actual
Phase 10 DOM source of truth — and pull the label text from the
adjacent `<span>` inside the same `<label>`. The special `__none__`
entry is skipped (existing ownerChoices contract: no placeholder
entries). Applies to both the main sprint view and the Phase 15
presentation view because they share the same toolbar markup and the
same sprint-planner.js.

phpunit: 88/88, 208 assertions (unchanged). node --check clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
achiappa 2 hafta önce
ebeveyn
işleme
7c298d3844
1 değiştirilmiş dosya ile 11 ekleme ve 3 silme
  1. 11 3
      public/assets/js/sprint-planner.js

+ 11 - 3
public/assets/js/sprint-planner.js

@@ -318,12 +318,20 @@
         return out;
     }
 
+    // The owner dropdown used to be a plain <select>, but Phase 10 replaced
+    // it with a checkbox multi-filter. We now scrape the real source of
+    // truth: the [data-owner-filter-opt] inputs, skipping the special
+    // "__none__" entry. Empty list → new task rows get an empty dropdown,
+    // which was the symptom the user hit after Phase 10 landed.
     function ownerChoices() {
         const out = [];
-        $root.find('[data-owner-filter] option').each(function () {
-            const v = $(this).val();
+        $root.find('[data-owner-filter-opt]').each(function () {
+            const v = String($(this).val());
             if (v === '' || v === '__none__') { return; }
-            out.push({ id: parseInt(String(v), 10), name: String($(this).text()).trim() });
+            const id = parseInt(v, 10);
+            if (!Number.isFinite(id)) { return; }
+            const name = String($(this).closest('label').find('span').text()).trim();
+            out.push({ id: id, name: name });
         });
         return out;
     }