feat: open Week Ahead planned work (Closes #1222)
This commit is contained in:
1 parent
a3861da125
commit
9f5baaef6e
8 files changed
+119
-25
No files matched your search
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import threading
|
||||
from datetime import date, timedelta
|
||||
from pathlib import Path
|
||||
@@ -75,6 +76,18 @@ def test_release_artifact_plans_seven_touch_safe_mobile_dates(
|
||||
expect(page.locator("#confirm-week-plan")).to_be_hidden()
|
||||
edit_week = page.locator("#edit-week-plan")
|
||||
expect(edit_week).to_be_visible()
|
||||
planned_item = cards.first.locator("[data-week-open-item]")
|
||||
expect(planned_item).to_have_count(1)
|
||||
planned_bounds = planned_item.bounding_box()
|
||||
assert planned_bounds and planned_bounds["height"] >= 44
|
||||
planned_item.click()
|
||||
expect(page.locator("#issue-sheet")).to_have_class(re.compile(r"\bopen\b"))
|
||||
expect(page.locator("#issue-sheet-title")).to_have_text("Ship mobile capture")
|
||||
expect(overview).to_be_visible()
|
||||
page.locator("#close-issue-sheet").click()
|
||||
expect(page.locator("#issue-sheet")).not_to_have_class(re.compile(r"\bopen\b"))
|
||||
expect(overview).to_be_visible()
|
||||
expect(planned_item).to_be_focused()
|
||||
assert saved == [], "opening and inspecting Week Ahead must not write"
|
||||
for control in (cards.first.locator("[data-week-edit-day]"), edit_week):
|
||||
bounds = control.bounding_box()
|
||||
|
||||
@@ -7788,7 +7788,7 @@ async def test_assigned_issues_open_accessible_mobile_action_sheet_with_safe_mut
|
||||
assert "window.confirm(confirmation)" in html
|
||||
assert "issueController.close(selectedIssue)" in html
|
||||
assert "lastMyWork.filter" in html
|
||||
assert "if (issueTrigger?.isConnected) issueTrigger.focus()" in html
|
||||
assert "setTimeout(()=>issueTrigger?.focus())" in html
|
||||
assert "e.key === 'Escape' && selectedIssue" in html
|
||||
|
||||
|
||||
|
||||
@@ -312,6 +312,6 @@ def test_mobile_settings_and_launch_route_wire_start_day_into_existing_promotion
|
||||
assert "startDayControl:qs('#push-start-day')" in dashboard
|
||||
assert "startDayHour:qs('#push-start-day-hour')" in dashboard
|
||||
assert "window.location.hash === '#/my-work/start-day'" in dashboard
|
||||
assert "weekWorkflow.promote(plan).finally(() =>" in dashboard
|
||||
assert "weekFlow.promote(plan).finally(() =>" in dashboard
|
||||
assert "onRemotePlan: async plan =>" not in dashboard
|
||||
assert "openMobileStartDay()" in dashboard
|
||||
@@ -419,5 +419,5 @@ def test_tomorrow_plan_has_a_touch_safe_mobile_entry_and_reuses_the_ordered_plan
|
||||
assert "qs('#plan-tomorrow').addEventListener('click'" in dashboard
|
||||
assert "planningTomorrow ? saveTomorrowPlan(plan) : saveTodayPlan(plan)" in dashboard
|
||||
assert "tomorrowPlan.load()" in dashboard
|
||||
assert "weekWorkflow.promote(plan)" in dashboard
|
||||
assert "weekFlow.promote(plan)" in dashboard
|
||||
assert "tomorrowPlan.startLifecycle" in dashboard
|
||||
@@ -260,6 +260,77 @@ console.log(JSON.stringify({reviewing:workflow.reviewing(),reviewMode,writes,ope
|
||||
assert result["editWeekLabel"] == "Edit week"
|
||||
|
||||
|
||||
def test_week_overview_opens_known_work_with_the_originating_control_and_leaves_unknown_work_static():
|
||||
result = run_controller("""
|
||||
const createWorkflow=createWeekPlan.Workflow;
|
||||
const dates=['2026-08-21','2026-08-22','2026-08-23','2026-08-24','2026-08-25','2026-08-26','2026-08-27'];
|
||||
const elements=new Map();
|
||||
const makeElement=()=>({hidden:false,textContent:'',disabled:false,innerHTML:'',addEventListener:()=>{},focus:()=>{},
|
||||
querySelectorAll:()=>[],querySelector:()=>null,scrollIntoView:()=>{}});
|
||||
const dateRoot=makeElement();
|
||||
Object.defineProperty(dateRoot,'innerHTML',{set(value){this.value=value;},get(){return this.value||'';}});
|
||||
elements.set('#week-plan-dates',dateRoot);
|
||||
const reviewDays=makeElement();
|
||||
Object.defineProperty(reviewDays,'innerHTML',{set(value){
|
||||
this.value=value;
|
||||
this.openButtons=[...value.matchAll(/data-week-open-item=\"([^\"]+)/g)].map(match=>({
|
||||
dataset:{weekOpenItem:match[1]},listeners:{},isConnected:true,focused:false,
|
||||
addEventListener(name,listener){this.listeners[name]=listener;},focus(){this.focused=true;}
|
||||
}));
|
||||
},get(){return this.value||'';}});
|
||||
reviewDays.querySelectorAll=selector=>selector==='[data-week-open-item]'?reviewDays.openButtons||[]:[];
|
||||
elements.set('#week-review-days',reviewDays);
|
||||
for(const selector of ['#mobile-week-summary','#my-work-action-status','#week-plan-progress','#save-today-plan',
|
||||
'#week-review','#week-review-duplicates','#confirm-week-plan','#week-review-status','#back-to-week-review',
|
||||
'#edit-week-plan','#week-offline-snapshot','#retry-week-live','#open-week-capacity-import'])
|
||||
if(!elements.has(selector))elements.set(selector,makeElement());
|
||||
const known={kind:'issue',title:'Inspect planned work',repository:'stackchain/dashboard',number:42};
|
||||
const review={days:dates.map((date,index)=>({plan_date:date,label:'Day '+(index+1),
|
||||
ids:index===0?['known','missing']:[],capacity_minutes:90,
|
||||
estimates:index===0?{known:30,missing:20}:{},planned_minutes:index===0?50:0,overloaded:false})),
|
||||
duplicates:[],blockers:[],can_confirm:true};
|
||||
let opened=null,writes=0;
|
||||
const controller={dates:()=>dates.map((date,index)=>({date,label:'Day '+(index+1)})),day:date=>review.days.find(day=>day.plan_date===date),
|
||||
pass:()=>({}),load:async()=>({}),summary:()=> '2 items across 1 day',review:()=>review,pending:()=>false,offline:()=>false,
|
||||
move:()=>true,flush:async()=>{writes+=1;}};
|
||||
const workflow=createWorkflow({controller,qs:selector=>elements.get(selector),getLogin:()=> 'timmy',
|
||||
getItem:id=>id==='known'?known:null,openItem:(item,trigger)=>{opened={item,sameTrigger:trigger===reviewDays.openButtons[0]};},
|
||||
openPlanner:()=>{},setReviewMode:()=>{},escapeHtml:value=>value,escapeAttribute:value=>value,
|
||||
todayWork:{replace:()=>{},replacePlanning:()=>{}},refresh:()=>{},warm:()=>{}});
|
||||
await workflow.open({disabled:false});
|
||||
const button=reviewDays.openButtons[0];
|
||||
if(button)button.listeners.click({currentTarget:button});
|
||||
console.log(JSON.stringify({markup:reviewDays.innerHTML,buttonCount:reviewDays.openButtons.length,opened,writes}));
|
||||
""")
|
||||
|
||||
assert result["buttonCount"] == 1
|
||||
assert 'class="week-review-item-open"' in result["markup"]
|
||||
assert 'data-week-open-item="known"' in result["markup"]
|
||||
assert 'data-week-open-item="missing"' not in result["markup"]
|
||||
assert result["opened"] == {
|
||||
"item": {
|
||||
"kind": "issue",
|
||||
"title": "Inspect planned work",
|
||||
"repository": "stackchain/dashboard",
|
||||
"number": 42,
|
||||
},
|
||||
"sameTrigger": True,
|
||||
}
|
||||
assert result["writes"] == 0
|
||||
|
||||
|
||||
def test_dashboard_routes_week_overview_controls_through_existing_detail_flow_with_mobile_targets():
|
||||
dashboard = (FRONTEND / "dashboard.js").read_text()
|
||||
css = (FRONTEND / "dashboard.css").read_text()
|
||||
|
||||
workflow_mount = dashboard.split("const weekFlow=createWeekPlanWorkflow({", 1)[1].split("});", 1)[0]
|
||||
assert "openItem:openRoutedWork" in workflow_mount
|
||||
assert ".week-review-item-open" in css
|
||||
rule = css.split(".week-review-item-open", 1)[1].split("}", 1)[0]
|
||||
assert "min-height:44px" in rule
|
||||
assert "width:100%" in rule
|
||||
|
||||
|
||||
def test_week_workflow_marks_a_confirmed_fallback_read_only_and_retries_live_data():
|
||||
result = run_controller("""
|
||||
const createWorkflow=createWeekPlan.Workflow;
|
||||
@@ -933,7 +1004,7 @@ def test_mobile_week_ahead_entry_and_date_strip_are_touch_safe():
|
||||
assert 'id="week-plan-dates"' in index
|
||||
assert '<script src="static/week-plan.js"></script>' in index
|
||||
assert "name === 'week' ? openWeekPlanner" in dashboard
|
||||
assert "weekWorkflow.save" in dashboard
|
||||
assert "weekFlow.save" in dashboard
|
||||
assert ".week-plan-dates button { min-height:44px;" in css
|
||||
assert "overflow-x:auto" in css
|
||||
|
||||
@@ -948,7 +1019,7 @@ def test_mobile_week_ahead_review_is_rendered_touch_safe_and_confirmed_explicitl
|
||||
assert 'id="week-review-duplicates"' in index
|
||||
assert 'id="confirm-week-plan"' in index
|
||||
assert "setReviewMode:value=>qs('#plan-today-sheet').classList.toggle('week-review-mode',value)" in dashboard
|
||||
assert "weekWorkflow.confirm()" in dashboard
|
||||
assert "weekFlow.confirm()" in dashboard
|
||||
assert ".week-review-day.is-overloaded" in css
|
||||
assert ".week-review-day button { min-height:44px;" in css
|
||||
assert ".week-review-mode .mobile-plan-today-nav" in css
|
||||
|
||||
Reference in new issue
Block a user