T1.1 - F1: one source of truth for the active project; the app bar subscribes
The hero, the picker and the create-user card showed the active project while
the app bar still read "Select a project". Three separate causes, all of them
the same shape - a reader with its own copy of the value.
1. Nothing told the bar. wp-chrome.js rendered projectLabel() once at build
time and refreshed it only when /api/projects came back, so selecting a
project updated the hero and left the bar behind. ProjectData.setActive now
notifies, and the bar subscribes through ProjectData.onActiveChange instead
of holding a copy. A plain array of callbacks - this is one value with a
handful of readers, not a reason for a state library.
2. admin.html and users.html load wp-chrome.js but never loaded
project-data.js, so window.ProjectData was undefined and their bar could
NEVER show a project - it read "Select a project" permanently, whatever was
selected. Both now load it, ahead of wp-chrome.js.
3. setActive({id}) erased the name. field.js, wp-creation-app.js and
work-package-suite-app.js all set the id first and the full record second;
writing that stub verbatim left the bar rendering "(unnamed)". setActive now
merges onto the stored record when the id matches, so a partial write cannot
lose fields it did not mean to touch.
Also: index.html never honoured ?project=<id>, though every other page does, so
a deep link on a browser with nothing stored showed "Select a project" while
the URL said otherwise. It now resolves the parameter before reconciling.
setActive is the only code path that writes wp_active_project /
wp_active_project_obj - project-data.js:83-105, noted there in a comment so it
stays that way. A storage listener keeps a second tab from showing a project
the user has since switched away from.
Verified, all at 1440px and against the wave 0 baseline:
- bar shows the project on launcher, SOP wizard, admin, field, users
- survives a hard refresh on each of them
- selecting a project updates hero and bar in one interaction, no reload
- with nothing selected the bar reads "Select a project" and both the
launcher picker and the bar's own switcher are reachable
- deep link ?project= works on a cold browser, hero and bar agree
- setActive({id}) after a full record keeps the name
The creator is the one page with no app bar to fix: it loads neither
wp-chrome.js nor wp-chrome.css, because it renders as the iframe child of the
SOP wizard. Giving it chrome is T7.1's work once B7 dissolves that boundary -
adding it here would put a second app bar inside the embedded view. This is the
"all 6 pages" wording in the plan meeting the 7 pages that exist; see file-map
D1.
tests/f_items.py F1 now reports FIXED. F2-F6 still reproduce, untouched.
browser_check.py 71/71.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -423,6 +423,15 @@
|
||||
function initProjects(){
|
||||
ProjectData.list().then(list => {
|
||||
_projects = list || [];
|
||||
// A deep link names the project explicitly, and every other page in the
|
||||
// suite already honours ?project=<id>. This one did not, so arriving here
|
||||
// with a link on a browser that had nothing stored showed "Select a
|
||||
// project" while the URL said otherwise. Honour it before reconciling.
|
||||
const wanted = new URLSearchParams(location.search).get('project');
|
||||
if(wanted){
|
||||
const target = _projects.find(p => p.id === wanted);
|
||||
if(target) ProjectData.setActive(target);
|
||||
}
|
||||
// Reconcile the active project against the list; clear if it's gone.
|
||||
const active = ProjectData.getActive();
|
||||
const dropped = (active && !_projects.some(p => p.id === active.id)) ? active : null;
|
||||
|
||||
Reference in New Issue
Block a user