fix: customer-based board visibility, chat widget UX, atomized Subdivide, static cache-busting

- Board visibility (§4.4): developers now see tasks for any customer with a
  consultant who pooled them, not only tasks whose consultantId is in their
  pool. Fixes a published task being invisible to its own author who is both
  consultant and developer. Adds TestBoardVisibilityIsCustomerBased.
- Chat widget: working ✕ close, distinct (non-ghost) header buttons, reliable
  conversation switching, ← Back, title ellipsis.
- Atomization: atomized/imported subtasks now expose a Subdivide button.
- Static assets: serve with ETag + Cache-Control: no-cache so JS/CSS fixes
  reach clients immediately instead of being masked by stale max-age caching.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
etalon
2026-06-13 10:20:06 +02:00
parent c59aea42ef
commit 05dc91410f
6 changed files with 152 additions and 50 deletions
+4
View File
@@ -149,6 +149,8 @@ function renderChildren(parent, kids, depth) {
</label>
<span>
<button class="btn small" data-act="edit">Edit</button>
${['imported', 'atomized'].includes(k.status)
? '<button class="btn small" data-act="subdivide" data-needs-atomizer>Subdivide</button>' : ''}
<button class="btn small" data-act="extend" data-needs-atomizer>Extend</button>
${k.status === 'atomized' ? '<button class="btn small primary" data-act="publish">Publish</button>' : ''}
<button class="btn small" data-act="archive">Archive</button>
@@ -183,6 +185,8 @@ function renderChildren(parent, kids, depth) {
});
}
row.querySelector('[data-act=edit]').addEventListener('click', () => openEdit(k, false));
const sd = row.querySelector('[data-act=subdivide]');
if (sd) sd.addEventListener('click', () => openSubdivide(k));
row.querySelector('[data-act=extend]').addEventListener('click', () => openExtend(k));
row.querySelector('[data-act=archive]').addEventListener('click', () => archive(k));
const pub = row.querySelector('[data-act=publish]');