feat(landing): single-project click navigates to <project>/archive.html
Previously every project click — single or group — built archive.html?projects=<list> and let the archive tool's URL-state detection fan out from there. For a single project that's a single-page-app trick that obscures the canonical URL. Now single-project clicks navigate to <project>/archive.html instead. The benefit is direct URL manipulation: the user can swap archive.html for working/, staging/, reviewing/, archive/<party>/mdl/table.html etc. in the address bar without going back through landing. zddc-server's availability.go already auto-serves the right tool at each canonical folder, so the destinations resolve without any server change. Multi-project clicks (groups) keep the ?projects=A,B form because there's no single subtree root. ACL-trimmed groups that collapse to one project also take the new single-project path, since the result is effectively a single-project view either way. The ?v= channel selector continues to carry across both paths. Two existing landing.spec.js assertions updated to match the new single-project URL shape; multi-project assertion unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8ba029612e
commit
cc515b0f56
2 changed files with 23 additions and 3 deletions
|
|
@ -429,8 +429,22 @@
|
|||
function openArchiveWith(names) {
|
||||
if (!names || names.length === 0) return;
|
||||
var base = location.pathname.replace(/\/[^\/]*$/, '/');
|
||||
var params = ['projects=' + names.map(encodeURIComponent).join(',')];
|
||||
var v = new URLSearchParams(location.search).get('v');
|
||||
|
||||
if (names.length === 1) {
|
||||
// Single project → canonical project-subtree URL so the user
|
||||
// can edit the address bar to swap archive.html for
|
||||
// working/, staging/, reviewing/, etc. zddc-server's
|
||||
// availability.go auto-serves the right tool at each.
|
||||
// Multi-project (the `else` branch) keeps the ?projects=
|
||||
// form because there's no single subtree root.
|
||||
var url = base + encodeURIComponent(names[0]) + '/archive.html';
|
||||
if (v) url += '?v=' + encodeURIComponent(v);
|
||||
navigate(url);
|
||||
return;
|
||||
}
|
||||
|
||||
var params = ['projects=' + names.map(encodeURIComponent).join(',')];
|
||||
if (v) params.push('v=' + encodeURIComponent(v));
|
||||
navigate(base + 'archive.html?' + params.join('&'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,10 @@ test.describe('Landing page', () => {
|
|||
await page.locator('.project-table-row[data-name="197072"]').click();
|
||||
|
||||
const navTo = await page.evaluate(() => window.__navTo);
|
||||
expect(navTo).toContain('archive.html?projects=197072');
|
||||
// Single-project click navigates to the project's canonical subtree
|
||||
// (so the user can swap archive.html for working/, staging/, etc.).
|
||||
expect(navTo).toContain('/197072/archive.html');
|
||||
expect(navTo).not.toContain('?projects=');
|
||||
});
|
||||
|
||||
test('column filters narrow the table; filters persist in URL', async ({ page }) => {
|
||||
|
|
@ -217,8 +220,11 @@ test.describe('Landing page', () => {
|
|||
await page.locator('#openSelectedBtn').click();
|
||||
|
||||
const navTo = await page.evaluate(() => window.__navTo);
|
||||
expect(navTo).toContain('archive.html?projects=176109');
|
||||
// After the visibility-filter trims to one project, this collapses
|
||||
// to the single-project path (no ?projects= form).
|
||||
expect(navTo).toContain('/176109/archive.html');
|
||||
expect(navTo).not.toContain('197072');
|
||||
expect(navTo).not.toContain('?projects=');
|
||||
});
|
||||
|
||||
test('legacy presets are migrated to groups on first load', async ({ page }) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue