feat: add unread updates to My Work (#133)
This commit is contained in:
1 parent
d75a55f3f7
commit
f34fc8b5f5
7 files changed
+336
-13
No files matched your search
+20
-6
@@ -131,6 +131,7 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
<button class="work-filter" data-work-filter="issue" aria-pressed="false">Issues <span data-work-count="issue">0</span></button>
|
||||
<button class="work-filter" data-work-filter="pull" aria-pressed="false">PRs <span data-work-count="pull">0</span></button>
|
||||
<button class="work-filter" data-work-filter="review" aria-pressed="false">Reviews <span data-work-count="review">0</span></button>
|
||||
<button class="work-filter" data-work-filter="update" aria-pressed="false">Updates <span data-work-count="update">0</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-work-list" id="my-work-list"></div>
|
||||
@@ -300,11 +301,12 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
let selectedWorkFilter = 'all';
|
||||
try {
|
||||
const savedFilter = sessionStorage.getItem(WORK_FILTER_KEY);
|
||||
if (['all', 'issue', 'pull', 'review'].includes(savedFilter)) selectedWorkFilter = savedFilter;
|
||||
if (['all', 'issue', 'pull', 'review', 'update'].includes(savedFilter)) selectedWorkFilter = savedFilter;
|
||||
} catch (e) {
|
||||
console.warn('Could not restore My Work filter', e);
|
||||
}
|
||||
let lastMyWork = [];
|
||||
let lastNotifications = [];
|
||||
let hasContextSnapshot = false;
|
||||
let selectedReview = null;
|
||||
let reviewTrigger = null;
|
||||
@@ -381,7 +383,7 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
});
|
||||
qs('#my-work').removeAttribute('data-stale');
|
||||
qs('#my-work-status').textContent = lastMyWork.length ?
|
||||
summarizeMyWork(lastMyWork) : 'No assigned work or review requests.';
|
||||
summarizeMyWork(lastMyWork) : 'No assigned work, review requests, or unread updates.';
|
||||
renderMyWork();
|
||||
}
|
||||
|
||||
@@ -389,7 +391,7 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
const visible = filterMyWork(lastMyWork, selectedWorkFilter);
|
||||
qs('#my-work-list').innerHTML = visible.length ? visible.map(item => {
|
||||
const contents =
|
||||
'<span class="small">' + escapeHtml(item.key) + ' · ' + escapeHtml(item.kind === 'pull' ? 'PR' : 'Issue') + '</span>' +
|
||||
'<span class="small">' + escapeHtml(item.key) + ' · ' + escapeHtml(item.kind === 'pull' ? 'PR' : (item.kind === 'update' ? 'Update' : 'Issue')) + '</span>' +
|
||||
'<span class="my-work-card-title">' + escapeHtml(item.title) + '</span>' +
|
||||
'<span class="pill">' + escapeHtml(item.reason) + '</span>' +
|
||||
(item.updated_at ? '<span class="small"> · Updated ' + escapeHtml(fmt(item.updated_at)) + '</span>' : '');
|
||||
@@ -398,7 +400,7 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
return '<button class="my-work-card review-trigger" data-review-index="' + index + '">' + contents + '</button>';
|
||||
}
|
||||
return '<a class="my-work-card" href="' + escAttr(item.url) + '" target="_blank" rel="noopener noreferrer">' + contents + '</a>';
|
||||
}).join('') : '<div class="muted">No ' + (selectedWorkFilter === 'review' ? 'reviews' : (selectedWorkFilter === 'all' ? 'work' : selectedWorkFilter + ' items')) + '.</div>';
|
||||
}).join('') : '<div class="muted">No ' + (selectedWorkFilter === 'review' ? 'reviews' : (selectedWorkFilter === 'update' ? 'unread updates' : (selectedWorkFilter === 'all' ? 'work' : selectedWorkFilter + ' items'))) + '.</div>';
|
||||
document.querySelectorAll('[data-review-index]').forEach(button => {
|
||||
button.addEventListener('click', () => openReviewSheet(lastMyWork[Number(button.dataset.reviewIndex)], button));
|
||||
});
|
||||
@@ -533,6 +535,13 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
'Update failed · showing last known work' : 'Work inbox unavailable.';
|
||||
}
|
||||
|
||||
function markNotificationsStale() {
|
||||
qs('#my-work').setAttribute('data-stale', 'true');
|
||||
qs('#my-work-status').textContent = lastNotifications.length ?
|
||||
'Unread updates unavailable · showing last known updates' :
|
||||
'Unread updates unavailable · assigned work is fresh';
|
||||
}
|
||||
|
||||
function paintDeltas(deltas) {
|
||||
const el = qs('#ai');
|
||||
el.innerHTML = deltas.length ? deltas.map(d => '<div class="suggestion ' + d.priority + '"><span class="pill">' + escapeHtml(d.priority) + '</span> <strong>' + escapeHtml(d.action) + '</strong> ' + escapeHtml(d.target || '') + '<div class="muted">' + escapeHtml(d.panel) + '</div></div>').join('') : '<div class="muted">No suggestions yet.</div>';
|
||||
@@ -553,8 +562,13 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
}
|
||||
|
||||
function renderLiveSnapshot(snapshot) {
|
||||
if (snapshot.context) renderContextSnapshot(snapshot.context);
|
||||
else handleContextError(new Error('Context section unavailable'));
|
||||
const notificationsFresh = Array.isArray(snapshot.notifications);
|
||||
if (notificationsFresh) lastNotifications = snapshot.notifications;
|
||||
if (snapshot.context) {
|
||||
snapshot.context.notifications = lastNotifications;
|
||||
renderContextSnapshot(snapshot.context);
|
||||
if (!notificationsFresh) markNotificationsStale();
|
||||
} else handleContextError(new Error('Context section unavailable'));
|
||||
if (snapshot.events) {
|
||||
paintEventStream(snapshot.events);
|
||||
setEventStreamStatus('Updated ' + fmt(new Date()));
|
||||
|
||||
Reference in new issue
Block a user