feat: @-mention autocomplete; consultant bounty-board access; clickable atomization tasks
- @-mentions: typing "@" in task comments, the messages composer and the chat
widget now opens a user picker (new shared mention.js) that inserts "@Name ".
Backed by the existing /api/v1/users search; menus de-dupe per field.
- Consultants can now open the bounty board (read-only): nav link + page/API
access extended to consultants, board visibility resolves their assigned
customers, and cards show "Open" instead of claim actions for non-developers.
- Atomization board task titles (roots and subtasks) link to /tasks/{id} so
consultants can reach the detail view (comments, assignment, timeline).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import { subscribe, onPollFallback } from '/static/js/ws.js';
|
||||
const grid = document.getElementById('board-grid');
|
||||
const errorBox = document.getElementById('error');
|
||||
let meId = '';
|
||||
let isDeveloper = false;
|
||||
let tasks = [];
|
||||
const customerNames = new Map();
|
||||
|
||||
@@ -69,9 +70,11 @@ function renderCard(t) {
|
||||
${myClaim ? '<span class="badge" style="color:var(--ok)">requested by you</span>' : ''}
|
||||
${others ? `<span class="badge">${others} other request(s)</span>` : ''}
|
||||
</span>
|
||||
${myClaim
|
||||
? '<button class="btn small" data-act="withdraw">Withdraw</button>'
|
||||
: '<button class="btn primary small" data-act="claim">Request assignment</button>'}
|
||||
${!isDeveloper
|
||||
? '<a class="btn small" href="/tasks/' + t.id + '">Open</a>'
|
||||
: myClaim
|
||||
? '<button class="btn small" data-act="withdraw">Withdraw</button>'
|
||||
: '<button class="btn primary small" data-act="claim">Request assignment</button>'}
|
||||
</div>`;
|
||||
const claimBtn = card.querySelector('[data-act=claim]');
|
||||
if (claimBtn) claimBtn.addEventListener('click', () => openClaim(t));
|
||||
@@ -121,6 +124,7 @@ async function restoreFilters() {
|
||||
try {
|
||||
const me = await api('GET', '/api/v1/auth/me');
|
||||
meId = me.user.id;
|
||||
isDeveloper = !!(me.user.roles && me.user.roles.developer);
|
||||
const saved = me.user.extra && me.user.extra.savedBoardFilters;
|
||||
if (saved) {
|
||||
const f = JSON.parse(saved);
|
||||
|
||||
Reference in New Issue
Block a user