fix: keep retained mobile planning available (#289)
This commit is contained in:
1 parent
80417abd5b
commit
8c4e729c4a
5 files changed
+121
-20
No files matched your search
@@ -11,7 +11,11 @@ function createDetailDefer({
|
||||
defer(item, preset) {
|
||||
if (!item) return false;
|
||||
const until = laterWork.presetUntil(preset);
|
||||
if (!laterWork.defer(item, until)) return false;
|
||||
const result = laterWork.defer(item, until);
|
||||
if (result !== 'deferred') {
|
||||
announce(result === 'invalid' ? 'Choose a valid future time.' : 'Could not save Later on this device.');
|
||||
return false;
|
||||
}
|
||||
const inSession = session.active();
|
||||
if (!inSession) close();
|
||||
refresh();
|
||||
|
||||
+38
-11
@@ -540,7 +540,7 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
<button id="release-issue" type="button">Release assignment</button>
|
||||
<button id="close-issue" type="button">Close issue</button>
|
||||
<a id="open-issue-gitea" href="#" target="_blank" rel="noopener noreferrer">Open in Gitea</a>
|
||||
<details class="detail-defer"><summary>Defer</summary><div class="detail-defer-options"><button type="button" data-detail-defer-preset="today">Later today</button><button type="button" data-detail-defer-preset="tomorrow">Tomorrow</button><button type="button" data-detail-defer-cancel>Cancel</button></div></details>
|
||||
<details class="detail-defer"><summary>Defer</summary><div class="detail-defer-options"><button type="button" data-detail-defer-preset="today" disabled data-planning-disabled>Later today</button><button type="button" data-detail-defer-preset="tomorrow" disabled data-planning-disabled>Tomorrow</button><button type="button" data-detail-defer-cancel>Cancel</button></div></details>
|
||||
</div>
|
||||
<nav class="work-session-nav" aria-label="Work session" hidden>
|
||||
<span class="small" aria-live="polite" data-work-session-progress></span>
|
||||
@@ -644,7 +644,7 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
<button class="share-work-route" type="button">Share</button>
|
||||
<button id="mark-update-read-next" type="button">Mark read & next</button>
|
||||
<a id="open-update-gitea" href="#" target="_blank" rel="noopener noreferrer">Open in Gitea</a>
|
||||
<details class="detail-defer"><summary>Defer</summary><div class="detail-defer-options"><button type="button" data-detail-defer-preset="today">Later today</button><button type="button" data-detail-defer-preset="tomorrow">Tomorrow</button><button type="button" data-detail-defer-cancel>Cancel</button></div></details>
|
||||
<details class="detail-defer"><summary>Defer</summary><div class="detail-defer-options"><button type="button" data-detail-defer-preset="today" disabled data-planning-disabled>Later today</button><button type="button" data-detail-defer-preset="tomorrow" disabled data-planning-disabled>Tomorrow</button><button type="button" data-detail-defer-cancel>Cancel</button></div></details>
|
||||
</div>
|
||||
<nav class="work-session-nav" aria-label="Work session" hidden>
|
||||
<span class="small" aria-live="polite" data-work-session-progress></span>
|
||||
@@ -684,7 +684,7 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
<div class="pull-sheet-actions">
|
||||
<button class="share-work-route" type="button">Share</button>
|
||||
<a id="open-pull-gitea" href="#" target="_blank" rel="noopener noreferrer">Open in Gitea</a>
|
||||
<details class="detail-defer"><summary>Defer</summary><div class="detail-defer-options"><button type="button" data-detail-defer-preset="today">Later today</button><button type="button" data-detail-defer-preset="tomorrow">Tomorrow</button><button type="button" data-detail-defer-cancel>Cancel</button></div></details>
|
||||
<details class="detail-defer"><summary>Defer</summary><div class="detail-defer-options"><button type="button" data-detail-defer-preset="today" disabled data-planning-disabled>Later today</button><button type="button" data-detail-defer-preset="tomorrow" disabled data-planning-disabled>Tomorrow</button><button type="button" data-detail-defer-cancel>Cancel</button></div></details>
|
||||
</div>
|
||||
<nav class="work-session-nav" aria-label="Work session" hidden>
|
||||
<span class="small" aria-live="polite" data-work-session-progress></span>
|
||||
@@ -749,7 +749,7 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
</section>
|
||||
<h2>Review history</h2>
|
||||
<div id="review-history" class="muted"></div>
|
||||
<div class="review-sheet-actions"><details class="detail-defer"><summary>Defer</summary><div class="detail-defer-options"><button type="button" data-detail-defer-preset="today">Later today</button><button type="button" data-detail-defer-preset="tomorrow">Tomorrow</button><button type="button" data-detail-defer-cancel>Cancel</button></div></details></div>
|
||||
<div class="review-sheet-actions"><details class="detail-defer"><summary>Defer</summary><div class="detail-defer-options"><button type="button" data-detail-defer-preset="today" disabled data-planning-disabled>Later today</button><button type="button" data-detail-defer-preset="tomorrow" disabled data-planning-disabled>Tomorrow</button><button type="button" data-detail-defer-cancel>Cancel</button></div></details></div>
|
||||
<nav class="work-session-nav" aria-label="Work session" hidden>
|
||||
<span class="small" aria-live="polite" data-work-session-progress></span>
|
||||
<button type="button" data-work-session-previous>Previous</button>
|
||||
@@ -902,17 +902,18 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
let reviewHandoffPending = false;
|
||||
let editingOutboxId = null;
|
||||
let confirmedOwnerLogin = '';
|
||||
let planningOwnerLogin = '';
|
||||
let activeFlushLogin = '';
|
||||
let activeMyWork = [];
|
||||
let laterMyWork = [];
|
||||
let todayMyWork = [];
|
||||
const todayWork = createTodayWork({
|
||||
storage: localStorage,
|
||||
getLogin: () => confirmedOwnerLogin,
|
||||
getLogin: () => planningOwnerLogin,
|
||||
});
|
||||
const laterWork = createLaterWork({
|
||||
storage: localStorage,
|
||||
getLogin: () => confirmedOwnerLogin,
|
||||
getLogin: () => planningOwnerLogin,
|
||||
onWake: () => {
|
||||
qs('#my-work-action-status').textContent = 'Deferred work is ready again.';
|
||||
refreshMyWorkView();
|
||||
@@ -1325,6 +1326,13 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
});
|
||||
});
|
||||
|
||||
function updatePlanningAvailability() {
|
||||
document.querySelectorAll('[data-detail-defer-preset]').forEach(button => {
|
||||
button.disabled = !planningOwnerLogin;
|
||||
button.toggleAttribute('data-planning-disabled', !planningOwnerLogin);
|
||||
});
|
||||
}
|
||||
|
||||
function renderContextSnapshot(data) {
|
||||
liveMode = true;
|
||||
hasContextSnapshot = true;
|
||||
@@ -1573,14 +1581,15 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
'<button class="mark-update-read" data-notification-id="' + item.notification_id + '">Mark read</button>' : '';
|
||||
const readUpdate = item.has_update && Number.isInteger(item.notification_id) ?
|
||||
'<a class="read-update" href="' + escAttr(createWorkRoute.serialize({ kind:'update', notification_id:item.notification_id })) + '" data-update-index="' + index + '">Read update</a>' : '';
|
||||
const planningDisabled = planningOwnerLogin ? '' : ' disabled data-planning-disabled';
|
||||
const laterActions = selectedWorkFilter === 'later' ?
|
||||
'<div class="later-actions"><button type="button" data-later-restore data-work-index="' + index + '">Bring back now</button></div>' :
|
||||
'<div class="later-actions" aria-label="Defer this work"><button type="button" data-later-preset="today" data-work-index="' + index + '">Later today</button><button type="button" data-later-preset="tomorrow" data-work-index="' + index + '">Tomorrow</button></div>';
|
||||
'<div class="later-actions" aria-label="Defer this work"><button type="button" data-later-preset="today" data-work-index="' + index + '"' + planningDisabled + '>Later today</button><button type="button" data-later-preset="tomorrow" data-work-index="' + index + '"' + planningDisabled + '>Tomorrow</button></div>';
|
||||
const alreadyToday = todayWork.contains(item);
|
||||
const todayPosition = todayWork.position(item);
|
||||
const todayActions = selectedWorkFilter === 'today' ?
|
||||
'<div class="today-actions" aria-label="Reorder Today"><button type="button" data-today-move="up" data-work-index="' + index + '"' + (todayPosition.can_up ? '' : ' disabled') + '>Move up</button><button type="button" data-today-move="down" data-work-index="' + index + '"' + (todayPosition.can_down ? '' : ' disabled') + '>Move down</button><button type="button" data-today-remove data-work-index="' + index + '">Remove from Today</button></div>' :
|
||||
'<div class="today-actions"><button type="button" data-today-add data-work-index="' + index + '"' + (alreadyToday ? ' disabled' : '') + '>' + (alreadyToday ? 'Added to Today' : 'Add to Today') + '</button></div>';
|
||||
'<div class="today-actions"><button type="button" data-today-add data-work-index="' + index + '"' + (alreadyToday ? ' disabled' : planningDisabled) + '>' + (alreadyToday ? 'Added to Today' : 'Add to Today') + '</button></div>';
|
||||
const planningActions = todayActions + laterActions;
|
||||
if (item.is_review) {
|
||||
return '<article class="my-work-card"><a class="my-work-card-main review-trigger" href="' + escAttr(routeHref) + '" data-review-index="' + index + '">' + contents + '</a>' + readUpdate + markRead + planningActions + '</article>';
|
||||
@@ -1629,8 +1638,17 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
document.querySelectorAll('[data-later-preset]').forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const item = lastMyWork[Number(button.dataset.workIndex)];
|
||||
if (!item || !laterWork.defer(item, laterWork.presetUntil(button.dataset.laterPreset))) return;
|
||||
qs('#my-work-action-status').textContent = 'Deferred work stays unread and unchanged in Gitea.';
|
||||
if (!item) return;
|
||||
if (!planningOwnerLogin) {
|
||||
qs('#my-work-action-status').textContent = 'Planning is unavailable until your operator identity is restored.';
|
||||
return;
|
||||
}
|
||||
const until = laterWork.presetUntil(button.dataset.laterPreset);
|
||||
const result = laterWork.defer(item, until);
|
||||
qs('#my-work-action-status').textContent = result === 'deferred' ?
|
||||
'Deferred until ' + fmt(until) + '; work stays unread and unchanged in Gitea.' :
|
||||
(result === 'invalid' ? 'Choose a valid future time.' : 'Could not save Later on this device.');
|
||||
if (result !== 'deferred') return;
|
||||
refreshMyWorkView();
|
||||
});
|
||||
});
|
||||
@@ -1644,10 +1662,15 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
});
|
||||
document.querySelectorAll('[data-today-add]').forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
if (!planningOwnerLogin) {
|
||||
qs('#my-work-action-status').textContent = 'Planning is unavailable until your operator identity is restored.';
|
||||
return;
|
||||
}
|
||||
const result = todayWork.add(lastMyWork[Number(button.dataset.workIndex)]);
|
||||
qs('#my-work-action-status').textContent = result === 'full' ?
|
||||
'Today is limited to 5 items. Remove one before adding more.' :
|
||||
(result === 'added' ? 'Added to Today without changing Gitea.' : 'This item is already in Today.');
|
||||
(result === 'added' ? 'Added to Today without changing Gitea.' :
|
||||
(result === 'exists' ? 'This item is already in Today.' : 'Could not save Today on this device.'));
|
||||
refreshMyWorkView();
|
||||
});
|
||||
});
|
||||
@@ -2486,6 +2509,10 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
}
|
||||
if (snapshot.context && workChanged) {
|
||||
setOfflineWorkMode(false);
|
||||
const retainedPlanningLogin = !snapshot.context.error ?
|
||||
String(snapshot.context.user?.login || '').trim() : '';
|
||||
planningOwnerLogin = retainedPlanningLogin;
|
||||
updatePlanningAvailability();
|
||||
const contextIdentityFresh = !snapshot.context.error && !contextFreshness?.stale &&
|
||||
!contextFreshness?.degraded && !contextFreshness?.revalidating;
|
||||
activeFlushLogin = contextIdentityFresh ? String(snapshot.context.user?.login || '').trim() : '';
|
||||
|
||||
@@ -42,11 +42,11 @@ function createLaterWork({ storage, getLogin, now = () => new Date(), setTimer =
|
||||
const key = storageKey();
|
||||
const id = identity(item);
|
||||
const wake = new Date(until);
|
||||
if (!key || !id || Number.isNaN(wake.getTime()) || wake <= now()) return false;
|
||||
if (!key) return 'unavailable';
|
||||
if (!id || Number.isNaN(wake.getTime()) || wake <= now()) return 'invalid';
|
||||
const records = read();
|
||||
records[id] = wake.toISOString();
|
||||
write(records);
|
||||
return true;
|
||||
return write(records) ? 'deferred' : 'unavailable';
|
||||
}
|
||||
|
||||
function presetUntil(preset) {
|
||||
|
||||
Reference in new issue
Block a user