stackchain-dashboard/frontend/update-ownership.js
timmy 0ea264a942
All checks were successful
CI / lint (pull_request) Successful in 32s
CI / build-frontend (pull_request) Successful in 4s
feat: claim work from unread updates (#321)
2026-08-08 17:19:13 +00:00

79 lines
2.4 KiB
JavaScript

function createUpdateOwnership({ claim, addToday, onClaimed, onState }) {
let detail = null;
let update = null;
let claimedItem = null;
let request = null;
function state(value) {
onState?.(value);
}
function open(nextDetail, nextUpdate) {
detail = nextDetail;
update = nextUpdate;
claimedItem = null;
request = null;
state({
action: nextDetail?.issue?.claimable ? 'claim' : 'hidden',
busy: false,
message: '',
});
}
function act() {
if (request) return request;
if (claimedItem) {
const result = addToday(claimedItem);
const messages = {
added: 'Added to Today.',
exists: 'This issue is already in Today.',
full: 'Today is limited to 5 items. Remove one before adding more.',
unavailable: 'Could not save Today on this device.',
};
state({ action: 'today', busy: false, message: messages[result] || messages.unavailable });
return Promise.resolve(result);
}
if (!detail?.issue?.claimable) return Promise.resolve('hidden');
state({ action: 'claim', busy: true, message: 'Assigning…' });
request = Promise.resolve(claim({
repository: detail.repository,
number: detail.issue.number,
})).then(result => {
claimedItem = {
...result,
repository: detail.repository,
kind: 'issue',
notification_id: update?.notification_id,
updated_at: update?.updated_at || result.updated_at,
has_update: true,
};
detail.issue.claimable = false;
onClaimed?.(claimedItem);
state({ action: 'today', busy: false, message: 'Assigned to you. The update is still unread.' });
return claimedItem;
}).catch(error => {
if (error?.status === 409) {
detail.issue.claimable = false;
state({
action: 'hidden',
busy: false,
message: 'Someone else claimed or closed this issue. The update is still unread.',
});
return 'conflict';
}
state({
action: 'claim',
busy: false,
message: (error?.message || 'The issue could not be assigned.') + ' The update and your reply draft are safe; retry.',
});
return 'retry';
}).finally(() => { request = null; });
return request;
}
return { open, act };
}
if (typeof module !== 'undefined' && module.exports) module.exports = createUpdateOwnership;