perf: isolate pull check refreshes (Closes #521)
This commit is contained in:
1 parent
8907263760
commit
e5a352b418
8 files changed
+255
-10
No files matched your search
+26
-3
@@ -2333,6 +2333,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
function renderPullCheckStatus(status) {
|
||||
qs('#pull-ci-state').textContent = 'CI ' + (status.ci_state || 'unknown');
|
||||
renderCheckSection('pull', status);
|
||||
if (status.head_sha !== selectedPullDetail?.head_sha) {
|
||||
qs('#pull-review-status').textContent = 'New commits detected. Reload review data before merging.';
|
||||
qs('#pull-merge-state').textContent = 'Review data is stale';
|
||||
qs('#merge-pull').disabled = true;
|
||||
return;
|
||||
}
|
||||
selectedPullDetail = { ...selectedPullDetail, ...status };
|
||||
const eligibility = createPullSheet.mergeEligibility(selectedPullDetail, pullReviewState);
|
||||
qs('#pull-merge-state').textContent = eligibility.reason;
|
||||
qs('#merge-pull').disabled = !eligibility.allowed;
|
||||
qs('#pull-review-status').textContent = 'Checks refreshed for the current head.';
|
||||
}
|
||||
|
||||
function focusNextUnreviewedPullFile() {
|
||||
if (!selectedPullDetail || !pullReviewState) return;
|
||||
const filename = pullController.nextUnreviewed(selectedPullDetail, pullReviewState);
|
||||
@@ -4280,11 +4296,18 @@
|
||||
});
|
||||
qs('#pull-review-retry').addEventListener('click', loadPullReview);
|
||||
qs('#refresh-pull-checks').addEventListener('click', async () => {
|
||||
if (!selectedPull || !selectedPullDetail?.head_sha) return;
|
||||
const item = selectedPull;
|
||||
const button = qs('#refresh-pull-checks');
|
||||
button.disabled = true;
|
||||
qs('#pull-checks-summary').textContent = 'Refreshing…';
|
||||
try { await loadPullReview({ refresh: true }); }
|
||||
finally { button.disabled = false; }
|
||||
try {
|
||||
const status = await pullController.loadChecks(item);
|
||||
if (selectedPull !== item) return;
|
||||
renderPullCheckStatus(status);
|
||||
} catch (_error) {
|
||||
if (selectedPull === item) qs('#pull-checks-summary').textContent = 'Refresh failed · retry';
|
||||
} finally { button.disabled = false; }
|
||||
});
|
||||
qs('#next-unreviewed-pull-file').addEventListener('click', focusNextUnreviewedPullFile);
|
||||
qs('#load-older-pull-comments').addEventListener('click', async () => {
|
||||
@@ -4490,7 +4513,7 @@
|
||||
button.disabled = true;
|
||||
qs('#review-checks-summary').textContent = 'Refreshing…';
|
||||
try {
|
||||
const detail = await reviewController.load(item);
|
||||
const detail = await reviewController.loadChecks(item);
|
||||
if (selectedReview !== item) return;
|
||||
if (selectedReviewHead && detail.head_sha !== selectedReviewHead) {
|
||||
qs('#review-sheet-status').textContent = 'New commits detected. Reload the review before submitting feedback.';
|
||||
|
||||
@@ -44,6 +44,7 @@ function renderFile(file, index, reviewed, escapeHtml) {
|
||||
function createPullSheet({ fetchJson, storage, createConversationPager = globalThis.createConversationPager, createOperationId = () => globalThis.crypto?.randomUUID?.() || String(Date.now()) + '-' + Math.random() }) {
|
||||
let commentRequest = null;
|
||||
let mergeRequest = null;
|
||||
let checkRequest = null;
|
||||
const reviewRequests = new Map();
|
||||
const reviewCache = new Map();
|
||||
const pathFor = item => 'api/v1/repos/' + String(item.repository || '').split('/')
|
||||
@@ -82,6 +83,13 @@ function createPullSheet({ fetchJson, storage, createConversationPager = globalT
|
||||
reviewRequests.set(key, request);
|
||||
return request;
|
||||
},
|
||||
loadChecks(item) {
|
||||
if (checkRequest) return checkRequest;
|
||||
checkRequest = fetchJson(pathFor(item) + '/checks', {
|
||||
headers: { Accept: 'application/json' },
|
||||
}).finally(() => { checkRequest = null; });
|
||||
return checkRequest;
|
||||
},
|
||||
conversation(item, initialPage) {
|
||||
const pager = createConversationPager({
|
||||
loadPage: page => fetchJson(pathFor(item) + '/comments?page=' + encodeURIComponent(page) + '&limit=20', {
|
||||
|
||||
@@ -4,6 +4,7 @@ function createReviewController({
|
||||
createOperationId = () => globalThis.crypto?.randomUUID?.() || String(Date.now()) + '-' + Math.random(),
|
||||
}) {
|
||||
let pendingSubmission = null;
|
||||
let pendingChecks = null;
|
||||
|
||||
function endpoint(item) {
|
||||
const [owner, repo] = String(item.repository || '').split('/');
|
||||
@@ -18,6 +19,14 @@ function createReviewController({
|
||||
return fetchJson(endpoint(item), { headers: { Accept: 'application/json' } });
|
||||
}
|
||||
|
||||
function loadChecks(item) {
|
||||
if (pendingChecks) return pendingChecks;
|
||||
pendingChecks = fetchJson(endpoint(item) + '/checks', {
|
||||
headers: { Accept: 'application/json' },
|
||||
}).finally(() => { pendingChecks = null; });
|
||||
return pendingChecks;
|
||||
}
|
||||
|
||||
function submit(item, payload) {
|
||||
if (pendingSubmission) return pendingSubmission;
|
||||
const operationKey = 'stackchain.review-submit.v1:' + item.repository + '#' + item.number;
|
||||
@@ -44,7 +53,7 @@ function createReviewController({
|
||||
return pendingSubmission;
|
||||
}
|
||||
|
||||
return { load, submit };
|
||||
return { load, loadChecks, submit };
|
||||
}
|
||||
|
||||
function createWrapPreference({ storage, mobile }) {
|
||||
|
||||
Reference in new issue
Block a user