|
|
@@ -42,23 +42,23 @@ export function initRepoIssueTimeTracking() { |
|
|
|
} |
|
|
|
|
|
|
|
async function updateDeadline(deadlineString) { |
|
|
|
hideElem($('#deadline-err-invalid-date')); |
|
|
|
$('#deadline-loader').addClass('is-loading'); |
|
|
|
hideElem('#deadline-err-invalid-date'); |
|
|
|
document.getElementById('deadline-loader')?.classList.add('is-loading'); |
|
|
|
|
|
|
|
let realDeadline = null; |
|
|
|
if (deadlineString !== '') { |
|
|
|
const newDate = Date.parse(deadlineString); |
|
|
|
|
|
|
|
if (Number.isNaN(newDate)) { |
|
|
|
$('#deadline-loader').removeClass('is-loading'); |
|
|
|
showElem($('#deadline-err-invalid-date')); |
|
|
|
document.getElementById('deadline-loader')?.classList.remove('is-loading'); |
|
|
|
showElem('#deadline-err-invalid-date'); |
|
|
|
return false; |
|
|
|
} |
|
|
|
realDeadline = new Date(newDate); |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
const response = await POST($('#update-issue-deadline-form').attr('action'), { |
|
|
|
const response = await POST(document.getElementById('update-issue-deadline-form').getAttribute('action'), { |
|
|
|
data: {due_date: realDeadline}, |
|
|
|
}); |
|
|
|
|
|
|
@@ -69,8 +69,8 @@ async function updateDeadline(deadlineString) { |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error(error); |
|
|
|
$('#deadline-loader').removeClass('is-loading'); |
|
|
|
showElem($('#deadline-err-invalid-date')); |
|
|
|
document.getElementById('deadline-loader').classList.remove('is-loading'); |
|
|
|
showElem('#deadline-err-invalid-date'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -87,6 +87,19 @@ export function initRepoIssueDue() { |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param {HTMLElement} item |
|
|
|
*/ |
|
|
|
function excludeLabel(item) { |
|
|
|
const href = item.getAttribute('href'); |
|
|
|
const id = item.getAttribute('data-label-id'); |
|
|
|
|
|
|
|
const regStr = `labels=((?:-?[0-9]+%2c)*)(${id})((?:%2c-?[0-9]+)*)&`; |
|
|
|
const newStr = 'labels=$1-$2$3&'; |
|
|
|
|
|
|
|
window.location = href.replace(new RegExp(regStr), newStr); |
|
|
|
} |
|
|
|
|
|
|
|
export function initRepoIssueSidebarList() { |
|
|
|
const repolink = $('#repolink').val(); |
|
|
|
const repoId = $('#repoId').val(); |
|
|
@@ -123,16 +136,6 @@ export function initRepoIssueSidebarList() { |
|
|
|
fullTextSearch: true, |
|
|
|
}); |
|
|
|
|
|
|
|
function excludeLabel(item) { |
|
|
|
const href = $(item).attr('href'); |
|
|
|
const id = $(item).data('label-id'); |
|
|
|
|
|
|
|
const regStr = `labels=((?:-?[0-9]+%2c)*)(${id})((?:%2c-?[0-9]+)*)&`; |
|
|
|
const newStr = 'labels=$1-$2$3&'; |
|
|
|
|
|
|
|
window.location = href.replace(new RegExp(regStr), newStr); |
|
|
|
} |
|
|
|
|
|
|
|
$('.menu a.label-filter-item').each(function () { |
|
|
|
$(this).on('click', function (e) { |
|
|
|
if (e.altKey) { |
|
|
@@ -144,9 +147,9 @@ export function initRepoIssueSidebarList() { |
|
|
|
|
|
|
|
$('.menu .ui.dropdown.label-filter').on('keydown', (e) => { |
|
|
|
if (e.altKey && e.keyCode === 13) { |
|
|
|
const $selectedItems = $('.menu .ui.dropdown.label-filter .menu .item.selected'); |
|
|
|
if ($selectedItems.length > 0) { |
|
|
|
excludeLabel($($selectedItems[0])); |
|
|
|
const selectedItem = document.querySelector('.menu .ui.dropdown.label-filter .menu .item.selected'); |
|
|
|
if (selectedItem) { |
|
|
|
excludeLabel(selectedItem); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
@@ -166,11 +169,11 @@ export function initRepoIssueCommentDelete() { |
|
|
|
const $parentTimelineGroup = $this.closest('.timeline-item-group'); |
|
|
|
// Check if this was a pending comment. |
|
|
|
if ($conversationHolder.find('.pending-label').length) { |
|
|
|
const $counter = $('#review-box .review-comments-counter'); |
|
|
|
let num = parseInt($counter.attr('data-pending-comment-number')) - 1 || 0; |
|
|
|
const counter = document.querySelector('#review-box .review-comments-counter'); |
|
|
|
let num = parseInt(counter?.getAttribute('data-pending-comment-number')) - 1 || 0; |
|
|
|
num = Math.max(num, 0); |
|
|
|
$counter.attr('data-pending-comment-number', num); |
|
|
|
$counter.text(num); |
|
|
|
counter.setAttribute('data-pending-comment-number', num); |
|
|
|
counter.textContent = String(num); |
|
|
|
} |
|
|
|
|
|
|
|
$(`#${$this.data('comment-id')}`).remove(); |
|
|
@@ -279,14 +282,16 @@ export function initRepoPullRequestMergeInstruction() { |
|
|
|
} |
|
|
|
|
|
|
|
export function initRepoPullRequestAllowMaintainerEdit() { |
|
|
|
const $checkbox = $('#allow-edits-from-maintainers'); |
|
|
|
if (!$checkbox.length) return; |
|
|
|
const checkbox = document.getElementById('allow-edits-from-maintainers'); |
|
|
|
if (!checkbox) return; |
|
|
|
|
|
|
|
const $checkbox = $(checkbox); |
|
|
|
|
|
|
|
const promptError = $checkbox.attr('data-prompt-error'); |
|
|
|
const promptError = checkbox.getAttribute('data-prompt-error'); |
|
|
|
$checkbox.checkbox({ |
|
|
|
'onChange': async () => { |
|
|
|
const checked = $checkbox.checkbox('is checked'); |
|
|
|
let url = $checkbox.attr('data-url'); |
|
|
|
let url = checkbox.getAttribute('data-url'); |
|
|
|
url += '/set_allow_maintainer_edit'; |
|
|
|
$checkbox.checkbox('set disabled'); |
|
|
|
try { |
|
|
@@ -298,7 +303,7 @@ export function initRepoPullRequestAllowMaintainerEdit() { |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error(error); |
|
|
|
showTemporaryTooltip($checkbox[0], promptError); |
|
|
|
showTemporaryTooltip(checkbox, promptError); |
|
|
|
} finally { |
|
|
|
$checkbox.checkbox('set enabled'); |
|
|
|
} |
|
|
@@ -325,7 +330,9 @@ export function initRepoIssueReferenceRepositorySearch() { |
|
|
|
}, |
|
|
|
onChange(_value, _text, $choice) { |
|
|
|
const $form = $choice.closest('form'); |
|
|
|
$form.attr('action', `${appSubUrl}/${_text}/issues/new`); |
|
|
|
if (!$form.length) return; |
|
|
|
|
|
|
|
$form[0].setAttribute('action', `${appSubUrl}/${_text}/issues/new`); |
|
|
|
}, |
|
|
|
fullTextSearch: true, |
|
|
|
}); |
|
|
@@ -375,17 +382,16 @@ export function initRepoIssueComments() { |
|
|
|
window.location.reload(); |
|
|
|
}); |
|
|
|
|
|
|
|
$(document).on('click', (event) => { |
|
|
|
const $urlTarget = $(':target'); |
|
|
|
if (!$urlTarget.length) return; |
|
|
|
document.addEventListener('click', (e) => { |
|
|
|
const urlTarget = document.querySelector(':target'); |
|
|
|
if (!urlTarget) return; |
|
|
|
|
|
|
|
const urlTargetId = $urlTarget.attr('id'); |
|
|
|
const urlTargetId = urlTarget.id; |
|
|
|
if (!urlTargetId) return; |
|
|
|
if (!/^(issue|pull)(comment)?-\d+$/.test(urlTargetId)) return; |
|
|
|
|
|
|
|
const $target = $(event.target); |
|
|
|
if (!/^(issue|pull)(comment)?-\d+$/.test(urlTargetId)) return; |
|
|
|
|
|
|
|
if (!$target.closest(`#${urlTargetId}`).length) { |
|
|
|
if (!e.target.closest(`#${urlTargetId}`)) { |
|
|
|
const scrollPosition = $(window).scrollTop(); |
|
|
|
window.location.hash = ''; |
|
|
|
$(window).scrollTop(scrollPosition); |
|
|
@@ -419,30 +425,33 @@ export function initRepoPullRequestReview() { |
|
|
|
if (window.history.scrollRestoration !== 'manual') { |
|
|
|
window.history.scrollRestoration = 'manual'; |
|
|
|
} |
|
|
|
const $commentDiv = $(window.location.hash); |
|
|
|
if ($commentDiv) { |
|
|
|
const commentDiv = document.querySelector(window.location.hash); |
|
|
|
if (commentDiv) { |
|
|
|
// get the name of the parent id |
|
|
|
const groupID = $commentDiv.closest('div[id^="code-comments-"]').attr('id'); |
|
|
|
const groupID = commentDiv.closest('div[id^="code-comments-"]')?.getAttribute('id'); |
|
|
|
if (groupID && groupID.startsWith('code-comments-')) { |
|
|
|
const id = groupID.slice(14); |
|
|
|
const $ancestorDiffBox = $commentDiv.closest('.diff-file-box'); |
|
|
|
const ancestorDiffBox = commentDiv.closest('.diff-file-box'); |
|
|
|
// on pages like conversation, there is no diff header |
|
|
|
const $diffHeader = $ancestorDiffBox.find('.diff-file-header'); |
|
|
|
const diffHeader = ancestorDiffBox?.querySelector('.diff-file-header'); |
|
|
|
|
|
|
|
// offset is for scrolling |
|
|
|
let offset = 30; |
|
|
|
if ($diffHeader[0]) { |
|
|
|
offset += $('.diff-detail-box').outerHeight() + $diffHeader.outerHeight(); |
|
|
|
if (diffHeader) { |
|
|
|
offset += $('.diff-detail-box').outerHeight() + $(diffHeader).outerHeight(); |
|
|
|
} |
|
|
|
$(`#show-outdated-${id}`).addClass('tw-hidden'); |
|
|
|
$(`#code-comments-${id}`).removeClass('tw-hidden'); |
|
|
|
$(`#code-preview-${id}`).removeClass('tw-hidden'); |
|
|
|
$(`#hide-outdated-${id}`).removeClass('tw-hidden'); |
|
|
|
|
|
|
|
document.getElementById(`show-outdated-${id}`).classList.add('tw-hidden'); |
|
|
|
document.getElementById(`code-comments-${id}`).classList.remove('tw-hidden'); |
|
|
|
document.getElementById(`code-preview-${id}`).classList.remove('tw-hidden'); |
|
|
|
document.getElementById(`hide-outdated-${id}`).classList.remove('tw-hidden'); |
|
|
|
// if the comment box is folded, expand it |
|
|
|
if ($ancestorDiffBox.attr('data-folded') && $ancestorDiffBox.attr('data-folded') === 'true') { |
|
|
|
setFileFolding($ancestorDiffBox[0], $ancestorDiffBox.find('.fold-file')[0], false); |
|
|
|
if (ancestorDiffBox.getAttribute('data-folded') === 'true') { |
|
|
|
setFileFolding(ancestorDiffBox, ancestorDiffBox.querySelector('.fold-file'), false); |
|
|
|
} |
|
|
|
|
|
|
|
window.scrollTo({ |
|
|
|
top: $commentDiv.offset().top - offset, |
|
|
|
top: $(commentDiv).offset().top - offset, |
|
|
|
behavior: 'instant', |
|
|
|
}); |
|
|
|
} |
|
|
@@ -529,7 +538,7 @@ export function initRepoPullRequestReview() { |
|
|
|
const $commentCloud = $td.find('.comment-code-cloud'); |
|
|
|
if (!$commentCloud.length && !$ntr.find('button[name="pending_review"]').length) { |
|
|
|
try { |
|
|
|
const response = await GET($(this).closest('[data-new-comment-url]').attr('data-new-comment-url')); |
|
|
|
const response = await GET(this.closest('[data-new-comment-url]')?.getAttribute('data-new-comment-url')); |
|
|
|
const html = await response.text(); |
|
|
|
$td.html(html); |
|
|
|
$td.find("input[name='line']").val(idx); |
|
|
@@ -585,6 +594,22 @@ export function initRepoIssueWipToggle() { |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
async function pullrequest_targetbranch_change(update_url) { |
|
|
|
const targetBranch = $('#pull-target-branch').data('branch'); |
|
|
|
const $branchTarget = $('#branch_target'); |
|
|
|
if (targetBranch === $branchTarget.text()) { |
|
|
|
window.location.reload(); |
|
|
|
return false; |
|
|
|
} |
|
|
|
try { |
|
|
|
await POST(update_url, {data: new URLSearchParams({target_branch: targetBranch})}); |
|
|
|
} catch (error) { |
|
|
|
console.error(error); |
|
|
|
} finally { |
|
|
|
window.location.reload(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
export function initRepoIssueTitleEdit() { |
|
|
|
// Edit issue title |
|
|
|
const $issueTitle = $('#issue-title'); |
|
|
@@ -607,23 +632,7 @@ export function initRepoIssueTitleEdit() { |
|
|
|
$('#edit-title').on('click', editTitleToggle); |
|
|
|
$('#cancel-edit-title').on('click', editTitleToggle); |
|
|
|
$('#save-edit-title').on('click', editTitleToggle).on('click', async function () { |
|
|
|
const pullrequest_targetbranch_change = async function (update_url) { |
|
|
|
const targetBranch = $('#pull-target-branch').data('branch'); |
|
|
|
const $branchTarget = $('#branch_target'); |
|
|
|
if (targetBranch === $branchTarget.text()) { |
|
|
|
window.location.reload(); |
|
|
|
return false; |
|
|
|
} |
|
|
|
try { |
|
|
|
await POST(update_url, {data: new URLSearchParams({target_branch: targetBranch})}); |
|
|
|
} catch (error) { |
|
|
|
console.error(error); |
|
|
|
} finally { |
|
|
|
window.location.reload(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
const pullrequest_target_update_url = $(this).attr('data-target-update-url'); |
|
|
|
const pullrequest_target_update_url = this.getAttribute('data-target-update-url'); |
|
|
|
if (!$editInput.val().length || $editInput.val() === $issueTitle.text()) { |
|
|
|
$editInput.val($issueTitle.text()); |
|
|
|
await pullrequest_targetbranch_change(pullrequest_target_update_url); |
|
|
@@ -631,7 +640,7 @@ export function initRepoIssueTitleEdit() { |
|
|
|
try { |
|
|
|
const params = new URLSearchParams(); |
|
|
|
params.append('title', $editInput.val()); |
|
|
|
const response = await POST($(this).attr('data-update-url'), {data: params}); |
|
|
|
const response = await POST(this.getAttribute('data-update-url'), {data: params}); |
|
|
|
const data = await response.json(); |
|
|
|
$editInput.val(data.title); |
|
|
|
$issueTitle.text(data.title); |
|
|
@@ -671,10 +680,11 @@ export function initSingleCommentEditor($commentForm) { |
|
|
|
// * normal new issue/pr page, no status-button |
|
|
|
// * issue/pr view page, with comment form, has status-button |
|
|
|
const opts = {}; |
|
|
|
const $statusButton = $('#status-button'); |
|
|
|
if ($statusButton.length) { |
|
|
|
const statusButton = document.getElementById('status-button'); |
|
|
|
if (statusButton) { |
|
|
|
opts.onContentChanged = (editor) => { |
|
|
|
$statusButton.text($statusButton.attr(editor.value().trim() ? 'data-status-and-comment' : 'data-status')); |
|
|
|
const statusText = statusButton.getAttribute(editor.value().trim() ? 'data-status-and-comment' : 'data-status'); |
|
|
|
statusButton.textContent = statusText; |
|
|
|
}; |
|
|
|
} |
|
|
|
initComboMarkdownEditor($commentForm.find('.combo-markdown-editor'), opts); |