feat: sidebar nav (default), group member management, per-customer ticketing identity mapping
- Navigation: new per-user setting (default "side") renders the page links as a left sidebar while keeping theme/bell/avatar/logout in the top-right; falls back to a top bar under 760px or when set to "top". Profile selector added. - Group conversations: record a creatorId; the creator gets a "Manage members" button to add/remove participants (new GET/POST/DELETE members endpoints, creator-only). Existing groups backfilled. - Customer ticketing: admin can map each assigned consultant to their username in that customer's ticketing system. Per-customer mapping takes precedence over the consultant's global ticketingIdentities during sync. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -84,6 +84,11 @@
|
||||
<select id="c-consultants" multiple size="4"></select>
|
||||
<p class="hint">Hold Ctrl/Cmd to select multiple. At least one is needed for syncing.</p>
|
||||
</div>
|
||||
<div class="field" id="c-identities-wrap" hidden>
|
||||
<label>Ticketing account mapping</label>
|
||||
<p class="hint">Username in this project's ticketing system for each assigned consultant. Overrides the consultant's global identity. Leave blank to use their global one.</p>
|
||||
<div id="c-identities"></div>
|
||||
</div>
|
||||
<div class="spread">
|
||||
<span id="c-test-result" class="hint" aria-live="polite"></span>
|
||||
<span>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<link rel="stylesheet" href="/static/css/app.css">
|
||||
<script src="/static/js/theme.js"></script>
|
||||
</head>
|
||||
<body {{if .User}}data-logged-in="1"{{end}}>
|
||||
<body {{if .User}}data-logged-in="1"{{end}} data-nav="{{if .User}}{{.NavLayout}}{{else}}top{{end}}">
|
||||
<nav class="topnav">
|
||||
<a class="brand" href="/">Bounty Board</a>
|
||||
<div class="links">
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
<section class="chat-main card">
|
||||
<div class="spread">
|
||||
<h2 id="chat-title">Select a conversation</h2>
|
||||
<span class="muted" id="typing-indicator" aria-live="polite"></span>
|
||||
<span style="display:flex;align-items:center;gap:10px">
|
||||
<span class="muted" id="typing-indicator" aria-live="polite"></span>
|
||||
<button class="btn small" id="chat-members" type="button" hidden>Manage members</button>
|
||||
</span>
|
||||
</div>
|
||||
<div id="chat-messages" class="chat-messages" aria-live="polite"></div>
|
||||
<form id="chat-form" hidden>
|
||||
@@ -66,6 +69,21 @@
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<dialog id="members-dialog">
|
||||
<div class="stack" style="min-width:420px">
|
||||
<div class="spread">
|
||||
<h2 style="margin:0">Group members</h2>
|
||||
<button class="btn small" type="button" id="mm-close">Close</button>
|
||||
</div>
|
||||
<ul id="mm-list" class="conv-list"></ul>
|
||||
<div class="field" id="mm-add-wrap">
|
||||
<label for="mm-search">Add someone</label>
|
||||
<input type="search" id="mm-search" placeholder="Search people…">
|
||||
<div id="mm-results" role="listbox" aria-label="Search results"></div>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<dialog id="lightbox" class="lightbox">
|
||||
<img id="lightbox-img" alt="">
|
||||
</dialog>
|
||||
|
||||
@@ -65,6 +65,13 @@
|
||||
<option value="sunset" {{if eq .User.Settings.Theme "sunset"}}selected{{end}}>Sunset (vaporwave)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="p-nav">Navigation</label>
|
||||
<select id="p-nav">
|
||||
<option value="side" {{if ne .User.Settings.NavLayout "top"}}selected{{end}}>Sidebar (left)</option>
|
||||
<option value="top" {{if eq .User.Settings.NavLayout "top"}}selected{{end}}>Top bar</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button class="btn primary" type="submit">Save profile</button>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user