51 lines
1.9 KiB
JavaScript
51 lines
1.9 KiB
JavaScript
function createIssueSheet({ fetchJson, storage }) {
|
|
let commentRequest = null;
|
|
let closeRequest = null;
|
|
const issuePath = item => 'api/v1/repos/' + item.repository.split('/').map(encodeURIComponent).join('/') +
|
|
'/issues/' + encodeURIComponent(item.number);
|
|
const draftKey = item => 'stackchain.issue-comment.v1:' + item.repository + '#' + item.number;
|
|
|
|
return {
|
|
load(item) {
|
|
return fetchJson(issuePath(item) + '/detail', {
|
|
headers: { Accept: 'application/json' },
|
|
});
|
|
},
|
|
loadDraft(item) {
|
|
try { return storage?.getItem(draftKey(item)) || ''; }
|
|
catch (_error) { return ''; }
|
|
},
|
|
saveDraft(item, body) {
|
|
try { storage?.setItem(draftKey(item), body); }
|
|
catch (_error) { /* The textarea remains the fallback. */ }
|
|
},
|
|
close(item) {
|
|
if (closeRequest) return closeRequest;
|
|
closeRequest = fetchJson(issuePath(item) + '/close', {
|
|
method: 'PATCH',
|
|
headers: { Accept: 'application/json' },
|
|
}).then(result => {
|
|
if (result?.state !== 'closed') throw new Error('Issue closure was not confirmed.');
|
|
return result;
|
|
}).finally(() => { closeRequest = null; });
|
|
return closeRequest;
|
|
},
|
|
comment(item, body) {
|
|
if (commentRequest) return commentRequest;
|
|
this.saveDraft(item, body);
|
|
commentRequest = fetchJson(issuePath(item) + '/comments', {
|
|
method: 'POST',
|
|
headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ body }),
|
|
}).then(result => {
|
|
try { storage?.removeItem(draftKey(item)); }
|
|
catch (_error) { /* The upstream comment is authoritative. */ }
|
|
return result;
|
|
}).finally(() => { commentRequest = null; });
|
|
return commentRequest;
|
|
},
|
|
};
|
|
}
|
|
|
|
if (typeof module !== 'undefined' && module.exports) module.exports = createIssueSheet;
|