Skip to content
176 changes: 176 additions & 0 deletions openreview/arr/webfield/programChairsWebfield.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,182 @@ return {
return hasReply;
})
return metaReviewReplies?.length??0;
`,
reviewerEmergencyDeclarationCount: `
const replies = row.note?.details?.replies ?? [];
const reviewers = row.reviewers ?? [];
const signatureToReviewerIndex = new Map();
const reviewersWithEmergencyDeclaration = new Set();

reviewers.forEach((reviewer, reviewerIndex) => {
if (reviewer?.anonymizedGroup) {
signatureToReviewerIndex.set(reviewer.anonymizedGroup, reviewerIndex);
}
if (reviewer?.preferredId) {
signatureToReviewerIndex.set(reviewer.preferredId, reviewerIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isEmergencyDeclaration = (reply?.invitations ?? []).some(invitation => invitation.includes('Emergency_Declaration'));

if (!isEmergencyDeclaration || !signatureToReviewerIndex.has(replySignature)) {
return;
}

reviewersWithEmergencyDeclaration.add(signatureToReviewerIndex.get(replySignature));
});

return reviewersWithEmergencyDeclaration.size;
`,
areaChairEmergencyDeclarationCount: `
const replies = row.note?.details?.replies ?? [];
const areaChairs = row.metaReviewData?.areaChairs ?? [];
const signatureToAreaChairIndex = new Map();
const areaChairsWithEmergencyDeclaration = new Set();

areaChairs.forEach((areaChair, areaChairIndex) => {
if (areaChair?.anonymizedGroup) {
signatureToAreaChairIndex.set(areaChair.anonymizedGroup, areaChairIndex);
}
if (areaChair?.preferredId) {
signatureToAreaChairIndex.set(areaChair.preferredId, areaChairIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isEmergencyDeclaration = (reply?.invitations ?? []).some(invitation => invitation.includes('Emergency_Declaration'));

if (!isEmergencyDeclaration || !signatureToAreaChairIndex.has(replySignature)) {
return;
}

areaChairsWithEmergencyDeclaration.add(signatureToAreaChairIndex.get(replySignature));
});

return areaChairsWithEmergencyDeclaration.size;
`,
reviewerDelayNotificationCount: `
const replies = row.note?.details?.replies ?? [];
const reviewers = row.reviewers ?? [];
const signatureToReviewerIndex = new Map();
const reviewersWithDelayNotification = new Set();

reviewers.forEach((reviewer, reviewerIndex) => {
if (reviewer?.anonymizedGroup) {
signatureToReviewerIndex.set(reviewer.anonymizedGroup, reviewerIndex);
}
if (reviewer?.preferredId) {
signatureToReviewerIndex.set(reviewer.preferredId, reviewerIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isDelayNotification = (reply?.invitations ?? []).some(invitation => invitation.includes('Delay_Notification'));

if (!isDelayNotification || !signatureToReviewerIndex.has(replySignature)) {
return;
}

reviewersWithDelayNotification.add(signatureToReviewerIndex.get(replySignature));
});

return reviewersWithDelayNotification.size;
`,
areaChairDelayNotificationCount: `
const replies = row.note?.details?.replies ?? [];
const areaChairs = row.metaReviewData?.areaChairs ?? [];
const signatureToAreaChairIndex = new Map();
const areaChairsWithDelayNotification = new Set();

areaChairs.forEach((areaChair, areaChairIndex) => {
if (areaChair?.anonymizedGroup) {
signatureToAreaChairIndex.set(areaChair.anonymizedGroup, areaChairIndex);
}
if (areaChair?.preferredId) {
signatureToAreaChairIndex.set(areaChair.preferredId, areaChairIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isDelayNotification = (reply?.invitations ?? []).some(invitation => invitation.includes('Delay_Notification'));

if (!isDelayNotification || !signatureToAreaChairIndex.has(replySignature)) {
return;
}

areaChairsWithDelayNotification.add(signatureToAreaChairIndex.get(replySignature));
});

return areaChairsWithDelayNotification.size;
`,
assignedReviewersMinusEmergencyDeclarationsCount: `
const replies = row.note?.details?.replies ?? [];
const reviewers = row.reviewers ?? [];
const signatureToReviewerIndex = new Map();
const reviewersWithEmergencyDeclaration = new Set();

reviewers.forEach((reviewer, reviewerIndex) => {
if (reviewer?.anonymizedGroup) {
signatureToReviewerIndex.set(reviewer.anonymizedGroup, reviewerIndex);
}
if (reviewer?.preferredId) {
signatureToReviewerIndex.set(reviewer.preferredId, reviewerIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isEmergencyDeclaration = (reply?.invitations ?? []).some(invitation => invitation.includes('Emergency_Declaration'));

if (!isEmergencyDeclaration || !signatureToReviewerIndex.has(replySignature)) {
return;
}

reviewersWithEmergencyDeclaration.add(signatureToReviewerIndex.get(replySignature));
});

return Math.max(0, reviewers.length - reviewersWithEmergencyDeclaration.size);
`,
completedReviewsPlusDelayNotificationsCount: `
const replies = row.note?.details?.replies ?? [];
const reviewers = row.reviewers ?? [];
const officialReviews = row.officialReviews ?? [];
const signatureToReviewerIndex = new Map();
const reviewersWithDelayNotification = new Set();
const reviewersWithOfficialReview = new Set(
officialReviews
.map(review => review?.anonymousId)
.filter(Boolean)
);

reviewers.forEach((reviewer, reviewerIndex) => {
if (reviewer?.anonymizedGroup) {
signatureToReviewerIndex.set(reviewer.anonymizedGroup, reviewerIndex);
}
if (reviewer?.preferredId) {
signatureToReviewerIndex.set(reviewer.preferredId, reviewerIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isDelayNotification = (reply?.invitations ?? []).some(invitation => invitation.includes('Delay_Notification'));

if (!isDelayNotification || !signatureToReviewerIndex.has(replySignature)) {
return;
}

reviewersWithDelayNotification.add(signatureToReviewerIndex.get(replySignature));
});

return reviewers.filter((reviewer, reviewerIndex) => {
return reviewersWithOfficialReview.has(reviewer?.anonymousId) || reviewersWithDelayNotification.has(reviewerIndex);
}).length;
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The completedReviewsPlusDelayNotificationsCount implementation counts unique assigned reviewers who either submitted an official review OR submitted a delay notification (it does not add the two counts, and it won’t double-count a reviewer who did both). This behavior doesn’t match the PR description wording (“plus”), and the Plus name is misleading given the OR/union semantics. Consider either renaming to reflect OR/union semantics (and aligning with the SAC console param name), or adjusting the computation if a true sum is required.

Copilot uses AI. Check for mistakes.
`
},
reviewerEmailFuncs: [
Expand Down
176 changes: 176 additions & 0 deletions openreview/arr/webfield/seniorAreaChairsWebfield.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,182 @@ return {
return hasReply;
})
return metaReviewReplies?.length??0;
`,
reviewerEmergencyDeclarationCount: `
const replies = row.note?.details?.replies ?? [];
const reviewers = row.reviewers ?? [];
const signatureToReviewerIndex = new Map();
const reviewersWithEmergencyDeclaration = new Set();

reviewers.forEach((reviewer, reviewerIndex) => {
if (reviewer?.anonymizedGroup) {
signatureToReviewerIndex.set(reviewer.anonymizedGroup, reviewerIndex);
}
if (reviewer?.preferredId) {
signatureToReviewerIndex.set(reviewer.preferredId, reviewerIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isEmergencyDeclaration = (reply?.invitations ?? []).some(invitation => invitation.includes('Emergency_Declaration'));

if (!isEmergencyDeclaration || !signatureToReviewerIndex.has(replySignature)) {
return;
}

reviewersWithEmergencyDeclaration.add(signatureToReviewerIndex.get(replySignature));
});

return reviewersWithEmergencyDeclaration.size;
`,
areaChairEmergencyDeclarationCount: `
const replies = row.note?.details?.replies ?? [];
const areaChairs = row.metaReviewData?.areaChairs ?? [];
const signatureToAreaChairIndex = new Map();
const areaChairsWithEmergencyDeclaration = new Set();

areaChairs.forEach((areaChair, areaChairIndex) => {
if (areaChair?.anonymizedGroup) {
signatureToAreaChairIndex.set(areaChair.anonymizedGroup, areaChairIndex);
}
if (areaChair?.preferredId) {
signatureToAreaChairIndex.set(areaChair.preferredId, areaChairIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isEmergencyDeclaration = (reply?.invitations ?? []).some(invitation => invitation.includes('Emergency_Declaration'));

if (!isEmergencyDeclaration || !signatureToAreaChairIndex.has(replySignature)) {
return;
}

areaChairsWithEmergencyDeclaration.add(signatureToAreaChairIndex.get(replySignature));
});

return areaChairsWithEmergencyDeclaration.size;
`,
reviewerDelayNotificationCount: `
const replies = row.note?.details?.replies ?? [];
const reviewers = row.reviewers ?? [];
const signatureToReviewerIndex = new Map();
const reviewersWithDelayNotification = new Set();

reviewers.forEach((reviewer, reviewerIndex) => {
if (reviewer?.anonymizedGroup) {
signatureToReviewerIndex.set(reviewer.anonymizedGroup, reviewerIndex);
}
if (reviewer?.preferredId) {
signatureToReviewerIndex.set(reviewer.preferredId, reviewerIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isDelayNotification = (reply?.invitations ?? []).some(invitation => invitation.includes('Delay_Notification'));

if (!isDelayNotification || !signatureToReviewerIndex.has(replySignature)) {
return;
}

reviewersWithDelayNotification.add(signatureToReviewerIndex.get(replySignature));
});

return reviewersWithDelayNotification.size;
`,
areaChairDelayNotificationCount: `
const replies = row.note?.details?.replies ?? [];
const areaChairs = row.metaReviewData?.areaChairs ?? [];
const signatureToAreaChairIndex = new Map();
const areaChairsWithDelayNotification = new Set();

areaChairs.forEach((areaChair, areaChairIndex) => {
if (areaChair?.anonymizedGroup) {
signatureToAreaChairIndex.set(areaChair.anonymizedGroup, areaChairIndex);
}
if (areaChair?.preferredId) {
signatureToAreaChairIndex.set(areaChair.preferredId, areaChairIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isDelayNotification = (reply?.invitations ?? []).some(invitation => invitation.includes('Delay_Notification'));

if (!isDelayNotification || !signatureToAreaChairIndex.has(replySignature)) {
return;
}

areaChairsWithDelayNotification.add(signatureToAreaChairIndex.get(replySignature));
});

return areaChairsWithDelayNotification.size;
`,
assignedReviewersAfterEmergencyDeclarationsCount: `
const replies = row.note?.details?.replies ?? [];
const reviewers = row.reviewers ?? [];
const signatureToReviewerIndex = new Map();
const reviewersWithEmergencyDeclaration = new Set();

reviewers.forEach((reviewer, reviewerIndex) => {
if (reviewer?.anonymizedGroup) {
signatureToReviewerIndex.set(reviewer.anonymizedGroup, reviewerIndex);
}
if (reviewer?.preferredId) {
signatureToReviewerIndex.set(reviewer.preferredId, reviewerIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isEmergencyDeclaration = (reply?.invitations ?? []).some(invitation => invitation.includes('Emergency_Declaration'));

if (!isEmergencyDeclaration || !signatureToReviewerIndex.has(replySignature)) {
return;
}

reviewersWithEmergencyDeclaration.add(signatureToReviewerIndex.get(replySignature));
});

return Math.max(0, reviewers.length - reviewersWithEmergencyDeclaration.size);
`,
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SAC console uses assignedReviewersAfterEmergencyDeclarationsCount while the PC console uses assignedReviewersMinusEmergencyDeclarationsCount for the same concept (assigned reviewers minus emergency declarations). This inconsistency makes the query language harder to use across consoles and diverges from the PR description terminology; consider standardizing the parameter name across both webfields.

Copilot uses AI. Check for mistakes.
completedReviewsOrDelayNotificationsCount: `
const replies = row.note?.details?.replies ?? [];
const reviewers = row.reviewers ?? [];
const officialReviews = row.officialReviews ?? [];
const signatureToReviewerIndex = new Map();
const reviewersWithDelayNotification = new Set();
const reviewersWithOfficialReview = new Set(
officialReviews
.map(review => review?.anonymousId)
.filter(Boolean)
);

reviewers.forEach((reviewer, reviewerIndex) => {
if (reviewer?.anonymizedGroup) {
signatureToReviewerIndex.set(reviewer.anonymizedGroup, reviewerIndex);
}
if (reviewer?.preferredId) {
signatureToReviewerIndex.set(reviewer.preferredId, reviewerIndex);
}
});

replies.forEach(reply => {
const replySignature = reply?.signatures?.[0];
const isDelayNotification = (reply?.invitations ?? []).some(invitation => invitation.includes('Delay_Notification'));

if (!isDelayNotification || !signatureToReviewerIndex.has(replySignature)) {
return;
}

reviewersWithDelayNotification.add(signatureToReviewerIndex.get(replySignature));
});

return reviewers.filter((reviewer, reviewerIndex) => {
return reviewersWithOfficialReview.has(reviewer?.anonymousId) || reviewersWithDelayNotification.has(reviewerIndex);
}).length;
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the PC console’s completedReviewsPlusDelayNotificationsCount, this function counts unique reviewers who submitted an official review OR a delay notification (union), not a literal sum of the two counts. If the intended behavior is a true sum (per PR description wording), the logic/name should be adjusted; otherwise consider renaming for clarity and consistency across consoles.

Copilot uses AI. Check for mistakes.
`
}
}
Expand Down
Loading