Переглянути джерело

New sprint form: drop weeks input + task list row hover

- Removes the "Weeks" number input from /sprints/new; the week count is now
  derived from start_date/end_date the same way Phase 21's PATCH does
  (floor((end−start)/7)+1, capped at 26 → "dates_too_long" error redirect
  above that). Drops n_weeks_invalid / n_weeks_range messages, adds
  dates_too_long. The legacy POST /sprints/{id}/weeks JSON endpoint still
  takes n_weeks for back-compat.
- Task list rows gain hover:bg-slate-50 dark:hover:bg-slate-700 to match
  the sprints table on the home page; mirrored on JS-built rows in
  buildTaskRow.

Verified: php -l on the edited PHP file is clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chiappa 2 днів тому
батько
коміт
372810644a

+ 1 - 0
public/assets/js/sprint-planner.js

@@ -353,6 +353,7 @@
         assignments = assignments || {};
         const tr = document.createElement('tr');
         tr.setAttribute('data-task-row', '');
+        tr.className = 'hover:bg-slate-50 dark:hover:bg-slate-700';
         tr.setAttribute('data-task-id',   String(task.id));
         tr.setAttribute('data-prio',      String(task.priority));
         tr.setAttribute('data-owner',     task.owner_worker_id || '');

+ 4 - 8
src/Controllers/SprintController.php

@@ -63,7 +63,6 @@ final class SprintController
                 'start_date'       => '',
                 'end_date'         => '',
                 'reserve_fraction' => '20',
-                'n_weeks'          => '4',
             ],
         ]));
     }
@@ -84,7 +83,6 @@ final class SprintController
         $end      = $req->postString('end_date');
         // reserve_fraction submitted as a percentage (0..100) from the form.
         $reservePct = $req->postString('reserve_fraction');
-        $nWeeksStr  = $req->postString('n_weeks');
 
         if ($name === '') {
             return Response::redirect('/sprints/new?error=name_required');
@@ -104,12 +102,10 @@ final class SprintController
         if ($reserve < 0.0 || $reserve > 1.0) {
             return Response::redirect('/sprints/new?error=reserve_out_of_range');
         }
-        if (!ctype_digit($nWeeksStr)) {
-            return Response::redirect('/sprints/new?error=n_weeks_invalid');
-        }
-        $nWeeks = (int) $nWeeksStr;
-        if ($nWeeks < 1 || $nWeeks > 26) {
-            return Response::redirect('/sprints/new?error=n_weeks_range');
+        // Week count derives from the date range — same rule as PATCH /sprints/{id}.
+        $nWeeks = self::weeksBetween($startD->format('Y-m-d'), $endD->format('Y-m-d'));
+        if ($nWeeks > 26) {
+            return Response::redirect('/sprints/new?error=dates_too_long');
         }
 
         $this->pdo->beginTransaction();

+ 1 - 0
views/sprints/_task_list.twig

@@ -179,6 +179,7 @@
                         {% for v in assign %}{% set tot = tot + v %}{% endfor %}
                         {% set links = linkedMap[t.id]|default([]) %}
                         <tr data-task-row
+                            class="hover:bg-slate-50 dark:hover:bg-slate-700"
                             data-task-id="{{ t.id }}"
                             data-prio="{{ t.priority }}"
                             data-owner="{{ t.ownerWorkerId is not null ? t.ownerWorkerId : '' }}"

+ 8 - 18
views/sprints/new.twig

@@ -4,10 +4,9 @@
     'name_required':        'Sprint name is required.',
     'dates_invalid':        'Start and end dates must both be valid dates (YYYY-MM-DD).',
     'dates_order':          'End date must not be before start date.',
+    'dates_too_long':       'Date range spans more than 26 weeks.',
     'reserve_invalid':      'Reserve must be a number (0–100).',
     'reserve_out_of_range': 'Reserve must be between 0 and 100 percent.',
-    'n_weeks_invalid':      'Weeks must be an integer.',
-    'n_weeks_range':        'Weeks must be between 1 and 26.',
     'db_error':             'Could not save. Try again.',
 } %}
 
@@ -52,22 +51,13 @@
             </label>
         </div>
 
-        <div class="grid grid-cols-2 gap-3">
-            <label class="block">
-                <span class="text-sm text-slate-700 dark:text-slate-300">Reserve (%)</span>
-                <input name="reserve_fraction" type="number" min="0" max="100" step="1" required
-                       value="{{ form.reserve_fraction }}"
-                       class="mt-1 block w-full rounded-md border-slate-300 border shadow-sm px-3 py-2 font-mono focus:outline-none focus:ring-2 focus:ring-slate-400 dark:bg-slate-800 dark:border-slate-600 dark:text-slate-100 dark:focus:ring-slate-500">
-                <span class="text-xs text-slate-500 dark:text-slate-400">Reduction from raw capacity. The Excel uses 20%.</span>
-            </label>
-            <label class="block">
-                <span class="text-sm text-slate-700 dark:text-slate-300">Weeks</span>
-                <input name="n_weeks" type="number" min="1" max="26" step="1" required
-                       value="{{ form.n_weeks }}"
-                       class="mt-1 block w-full rounded-md border-slate-300 border shadow-sm px-3 py-2 font-mono focus:outline-none focus:ring-2 focus:ring-slate-400 dark:bg-slate-800 dark:border-slate-600 dark:text-slate-100 dark:focus:ring-slate-500">
-                <span class="text-xs text-slate-500 dark:text-slate-400">Week rows get 5 days/week by default; edit on the sprint page.</span>
-            </label>
-        </div>
+        <label class="block">
+            <span class="text-sm text-slate-700 dark:text-slate-300">Reserve (%)</span>
+            <input name="reserve_fraction" type="number" min="0" max="100" step="1" required
+                   value="{{ form.reserve_fraction }}"
+                   class="mt-1 block w-full rounded-md border-slate-300 border shadow-sm px-3 py-2 font-mono focus:outline-none focus:ring-2 focus:ring-slate-400 dark:bg-slate-800 dark:border-slate-600 dark:text-slate-100 dark:focus:ring-slate-500">
+            <span class="text-xs text-slate-500 dark:text-slate-400">Reduction from raw capacity. The Excel uses 20%. Week rows derive from the date range and get 5 days/week by default; edit on the sprint page.</span>
+        </label>
 
         <div class="flex gap-3 pt-2">
             <button type="submit"