diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2025-03-05 01:58:17 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-04 17:58:17 +0000 |
commit | 75e85c25c1674627ef750bf7114d3b0b7c0d15aa (patch) | |
tree | aad42466328b7a811d9af1140cbc7484358a3f29 | |
parent | ca0ce003ab33b58a692ceaab71e728c7aef8c216 (diff) | |
download | gitea-75e85c25c1674627ef750bf7114d3b0b7c0d15aa.tar.gz gitea-75e85c25c1674627ef750bf7114d3b0b7c0d15aa.zip |
Refactor repo-issue.ts (#33784)
And remove jQuery
-rw-r--r-- | .github/workflows/pull-db-tests.yml | 6 | ||||
-rw-r--r-- | options/locale/locale_en-US.ini | 2 | ||||
-rw-r--r-- | templates/repo/issue/sidebar/issue_dependencies.tmpl | 47 | ||||
-rw-r--r-- | templates/repo/issue/sidebar/wip_switch.tmpl | 8 | ||||
-rw-r--r-- | templates/repo/issue/view_content/pull.tmpl | 4 | ||||
-rw-r--r-- | templates/repo/issue/view_content/pull_merge_instruction.tmpl | 98 | ||||
-rw-r--r-- | templates/repo/issue/view_content/update_branch_by_merge.tmpl | 2 | ||||
-rw-r--r-- | web_src/js/features/repo-issue.ts | 237 | ||||
-rw-r--r-- | web_src/js/features/repo-legacy.ts | 6 | ||||
-rw-r--r-- | web_src/js/index.ts | 14 |
10 files changed, 191 insertions, 233 deletions
diff --git a/.github/workflows/pull-db-tests.yml b/.github/workflows/pull-db-tests.yml index 0b23de0a66..6e879053d3 100644 --- a/.github/workflows/pull-db-tests.yml +++ b/.github/workflows/pull-db-tests.yml @@ -202,12 +202,10 @@ jobs: test-mssql: if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' needs: files-changed - # specifying the version of ubuntu in use as mssql fails on newer kernels - # pending resolution from vendor - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest services: mssql: - image: mcr.microsoft.com/mssql/server:2017-latest + image: mcr.microsoft.com/mssql/server:2019-latest env: ACCEPT_EULA: Y MSSQL_PID: Standard diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1da2fb61ad..4f1db5da6a 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1938,7 +1938,7 @@ pulls.outdated_with_base_branch = This branch is out-of-date with the base branc pulls.close = Close Pull Request pulls.closed_at = `closed this pull request <a id="%[1]s" href="#%[1]s">%[2]s</a>` pulls.reopened_at = `reopened this pull request <a id="%[1]s" href="#%[1]s">%[2]s</a>` -pulls.cmd_instruction_hint = `View <a class="show-instruction">command line instructions</a>.` +pulls.cmd_instruction_hint = View command line instructions pulls.cmd_instruction_checkout_title = Checkout pulls.cmd_instruction_checkout_desc = From your project repository, check out a new branch and test the changes. pulls.cmd_instruction_merge_title = Merge diff --git a/templates/repo/issue/sidebar/issue_dependencies.tmpl b/templates/repo/issue/sidebar/issue_dependencies.tmpl index 17e9738c6f..bbae011958 100644 --- a/templates/repo/issue/sidebar/issue_dependencies.tmpl +++ b/templates/repo/issue/sidebar/issue_dependencies.tmpl @@ -31,7 +31,9 @@ </div> <div class="item-right tw-flex tw-items-center tw-m-1"> {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} - <a class="delete-dependency-button ci muted" data-id="{{.Issue.ID}}" data-type="blocking" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}"> + <a class="muted show-modal" data-modal="#issue-remove-dependency-confirm" + data-modal-remove-dependency-id="{{.Issue.ID}}" data-modal-dependency-type="blocking" + data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}"> {{svg "octicon-trash" 16}} </a> {{end}} @@ -63,7 +65,9 @@ </div> <div class="item-right tw-flex tw-items-center tw-m-1"> {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} - <a class="delete-dependency-button ci muted" data-id="{{.Issue.ID}}" data-type="blockedBy" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}"> + <a class="muted show-modal" data-modal="#issue-remove-dependency-confirm" + data-modal-remove-dependency-id="{{.Issue.ID}}" data-modal-dependency-type="blockedBy" + data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}"> {{svg "octicon-trash" 16}} </a> {{end}} @@ -86,7 +90,9 @@ </div> <div class="item-right tw-flex tw-items-center tw-m-1"> {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} - <a class="delete-dependency-button ci muted" data-id="{{.Issue.ID}}" data-type="blocking" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}"> + <a class="muted show-modal" data-modal="#issue-remove-dependency-confirm" + data-modal-remove-dependency-id="{{.Issue.ID}}" data-modal-dependency-type="blocking" + data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}"> {{svg "octicon-trash" 16}} </a> {{end}} @@ -106,7 +112,7 @@ <form method="post" action="{{.Issue.Link}}/dependency/add" id="addDependencyForm"> {{$.CsrfTokenHtml}} <div class="ui fluid action input"> - <div class="ui search selection dropdown" id="new-dependency-drop-list" data-issue-id="{{.Issue.ID}}"> + <div class="ui search selection dropdown" id="new-dependency-drop-list" data-issue-id="{{.Issue.ID}}" data-issue-cross-repo-search="{{.AllowCrossRepositoryDependencies}}"> <input name="newDependency" type="hidden"> {{svg "octicon-triangle-down" 14 "dropdown icon"}} <input type="text" class="search"> @@ -122,28 +128,19 @@ </div> {{if and .CanCreateIssueDependencies (not .Repository.IsArchived)}} - <input type="hidden" id="crossRepoSearch" value="{{.AllowCrossRepositoryDependencies}}"> - - <div class="ui g-modal-confirm modal remove-dependency"> - <div class="header"> - {{svg "octicon-trash"}} - {{ctx.Locale.Tr "repo.issues.dependency.remove_header"}} - </div> + <form id="issue-remove-dependency-confirm" class="ui g-modal-confirm modal" method="post" action="{{.Issue.Link}}/dependency/delete"> + <div class="header">{{svg "octicon-trash"}} {{ctx.Locale.Tr "repo.issues.dependency.remove_header"}}</div> <div class="content"> - <form method="post" action="{{.Issue.Link}}/dependency/delete" id="removeDependencyForm"> - {{$.CsrfTokenHtml}} - <input type="hidden" value="" name="removeDependencyID" id="removeDependencyID"> - <input type="hidden" value="" name="dependencyType" id="dependencyType"> - </form> - <p>{{if .Issue.IsPull}} - {{ctx.Locale.Tr "repo.issues.dependency.pr_remove_text"}} - {{else}} - {{ctx.Locale.Tr "repo.issues.dependency.issue_remove_text"}} - {{end}}</p> + {{$.CsrfTokenHtml}} + <input type="hidden" value="" name="removeDependencyID" class="remove-dependency-id"> + <input type="hidden" value="" name="dependencyType" class="dependency-type"> + <p> + {{ctx.Locale.Tr (Iif .Issue.IsPull "repo.issues.dependency.pr_remove_text" "repo.issues.dependency.issue_remove_text")}} + </p> + {{$ModalButtonCancelText := ctx.Locale.Tr "repo.issues.dependency.cancel"}} + {{$ModalButtonOkText := ctx.Locale.Tr "repo.issues.dependency.remove"}} + {{template "base/modal_actions_confirm" (dict "." . "ModalButtonCancelText" $ModalButtonCancelText "ModalButtonOkText" $ModalButtonOkText)}} </div> - {{$ModalButtonCancelText := ctx.Locale.Tr "repo.issues.dependency.cancel"}} - {{$ModalButtonOkText := ctx.Locale.Tr "repo.issues.dependency.remove"}} - {{template "base/modal_actions_confirm" (dict "." . "ModalButtonCancelText" $ModalButtonCancelText "ModalButtonOkText" $ModalButtonOkText)}} - </div> + </form> {{end}} {{end}} diff --git a/templates/repo/issue/sidebar/wip_switch.tmpl b/templates/repo/issue/sidebar/wip_switch.tmpl index 06a3be0d8f..b007399deb 100644 --- a/templates/repo/issue/sidebar/wip_switch.tmpl +++ b/templates/repo/issue/sidebar/wip_switch.tmpl @@ -1,7 +1,5 @@ {{if and (or .HasIssuesOrPullsWritePermission .IsIssuePoster) (not .HasMerged) (not .Issue.IsClosed) (not .IsPullWorkInProgress)}} - <div class="toggle-wip tw-mt-2" data-title="{{.Issue.Title}}" data-wip-prefix="{{index .PullRequestWorkInProgressPrefixes 0}}" data-update-url="{{.Issue.Link}}/title"> - <a class="muted"> - {{ctx.Locale.Tr "repo.pulls.still_in_progress"}} {{ctx.Locale.Tr "repo.pulls.add_prefix" (index .PullRequestWorkInProgressPrefixes 0)}} - </a> - </div> + <a class="toggle-wip tw-block tw-mt-2" data-title="{{.Issue.Title}}" data-wip-prefix="{{index .PullRequestWorkInProgressPrefixes 0}}" data-update-url="{{.Issue.Link}}/title"> + {{ctx.Locale.Tr "repo.pulls.still_in_progress"}} {{ctx.Locale.Tr "repo.pulls.add_prefix" (index .PullRequestWorkInProgressPrefixes 0)}} + </a> {{end}} diff --git a/templates/repo/issue/view_content/pull.tmpl b/templates/repo/issue/view_content/pull.tmpl index 7c53c5edb5..064b62e128 100644 --- a/templates/repo/issue/view_content/pull.tmpl +++ b/templates/repo/issue/view_content/pull.tmpl @@ -83,13 +83,13 @@ {{ctx.Locale.Tr "repo.pulls.data_broken"}} </div> {{else if .IsPullWorkInProgress}} - <div class="item toggle-wip" data-title="{{.Issue.Title}}" data-wip-prefix="{{.WorkInProgressPrefix}}" data-update-url="{{.Issue.Link}}/title"> + <div class="item"> <div class="item-section-left flex-text-inline tw-flex-1"> {{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.cannot_merge_work_in_progress"}} </div> {{if or .HasIssuesOrPullsWritePermission .IsIssuePoster}} - <button class="ui compact button"> + <button class="ui compact button toggle-wip" data-title="{{.Issue.Title}}" data-wip-prefix="{{.WorkInProgressPrefix}}" data-update-url="{{.Issue.Link}}/title"> {{ctx.Locale.Tr "repo.pulls.remove_prefix" .WorkInProgressPrefix}} </button> {{end}} diff --git a/templates/repo/issue/view_content/pull_merge_instruction.tmpl b/templates/repo/issue/view_content/pull_merge_instruction.tmpl index 9a3e2cb7d7..a1cff41a3a 100644 --- a/templates/repo/issue/view_content/pull_merge_instruction.tmpl +++ b/templates/repo/issue/view_content/pull_merge_instruction.tmpl @@ -1,55 +1,57 @@ <div class="divider"></div> -<div class="instruct-toggle"> {{ctx.Locale.Tr "repo.pulls.cmd_instruction_hint"}} </div> -<div class="instruct-content tw-mt-2 tw-hidden"> - <div><h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_title"}}</h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_desc"}}</div> - {{$localBranch := .PullRequest.HeadBranch}} - {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}} - {{$localBranch = print .PullRequest.HeadRepo.OwnerName "-" .PullRequest.HeadBranch}} - {{end}} - <div class="ui secondary segment"> - {{if eq .PullRequest.Flow 0}} - <div>git fetch -u {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}}<origin-url data-url="{{.PullRequest.HeadRepo.Link}}"></origin-url>{{else}}origin{{end}} {{.PullRequest.HeadBranch}}:{{$localBranch}}</div> - {{else}} - <div>git fetch -u origin {{.PullRequest.GetGitRefName}}:{{$localBranch}}</div> +<details> + <summary>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_hint"}}</summary> + <div class="tw-mt-2"> + <div><h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_title"}}</h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_desc"}}</div> + {{$localBranch := .PullRequest.HeadBranch}} + {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}} + {{$localBranch = print .PullRequest.HeadRepo.OwnerName "-" .PullRequest.HeadBranch}} {{end}} - <div>git checkout {{$localBranch}}</div> - </div> - {{if .ShowMergeInstructions}} - <div> - <h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_title"}}</h3> - {{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_desc"}} - {{if not .AutodetectManualMerge}} - <div>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_warning"}}</div> - {{end}} - </div> - <div class="ui secondary segment"> - <div data-pull-merge-style="merge"> - <div>git checkout {{.PullRequest.BaseBranch}}</div> - <div>git merge --no-ff {{$localBranch}}</div> - </div> - <div class="tw-hidden" data-pull-merge-style="rebase"> - <div>git checkout {{.PullRequest.BaseBranch}}</div> - <div>git merge --ff-only {{$localBranch}}</div> - </div> - <div class="tw-hidden" data-pull-merge-style="rebase-merge"> + <div class="ui secondary segment"> + {{if eq .PullRequest.Flow 0}} + <div>git fetch -u {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}}<origin-url data-url="{{.PullRequest.HeadRepo.Link}}"></origin-url>{{else}}origin{{end}} {{.PullRequest.HeadBranch}}:{{$localBranch}}</div> + {{else}} + <div>git fetch -u origin {{.PullRequest.GetGitRefName}}:{{$localBranch}}</div> + {{end}} <div>git checkout {{$localBranch}}</div> - <div>git rebase {{.PullRequest.BaseBranch}}</div> - <div>git checkout {{.PullRequest.BaseBranch}}</div> - <div>git merge --no-ff {{$localBranch}}</div> - </div> - <div class="tw-hidden" data-pull-merge-style="squash"> - <div>git checkout {{.PullRequest.BaseBranch}}</div> - <div>git merge --squash {{$localBranch}}</div> </div> - <div class="tw-hidden" data-pull-merge-style="fast-forward-only"> - <div>git checkout {{.PullRequest.BaseBranch}}</div> - <div>git merge --ff-only {{$localBranch}}</div> + {{if .ShowMergeInstructions}} + <div> + <h3>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_title"}}</h3> + {{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_desc"}} + {{if not .AutodetectManualMerge}} + <div>{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_warning"}}</div> + {{end}} </div> - <div class="tw-hidden" data-pull-merge-style="manually-merged"> - <div>git checkout {{.PullRequest.BaseBranch}}</div> - <div>git merge {{$localBranch}}</div> + <div class="ui secondary segment"> + <div data-pull-merge-style="merge"> + <div>git checkout {{.PullRequest.BaseBranch}}</div> + <div>git merge --no-ff {{$localBranch}}</div> + </div> + <div class="tw-hidden" data-pull-merge-style="rebase"> + <div>git checkout {{.PullRequest.BaseBranch}}</div> + <div>git merge --ff-only {{$localBranch}}</div> + </div> + <div class="tw-hidden" data-pull-merge-style="rebase-merge"> + <div>git checkout {{$localBranch}}</div> + <div>git rebase {{.PullRequest.BaseBranch}}</div> + <div>git checkout {{.PullRequest.BaseBranch}}</div> + <div>git merge --no-ff {{$localBranch}}</div> + </div> + <div class="tw-hidden" data-pull-merge-style="squash"> + <div>git checkout {{.PullRequest.BaseBranch}}</div> + <div>git merge --squash {{$localBranch}}</div> + </div> + <div class="tw-hidden" data-pull-merge-style="fast-forward-only"> + <div>git checkout {{.PullRequest.BaseBranch}}</div> + <div>git merge --ff-only {{$localBranch}}</div> + </div> + <div class="tw-hidden" data-pull-merge-style="manually-merged"> + <div>git checkout {{.PullRequest.BaseBranch}}</div> + <div>git merge {{$localBranch}}</div> + </div> + <div>git push origin {{.PullRequest.BaseBranch}}</div> </div> - <div>git push origin {{.PullRequest.BaseBranch}}</div> + {{end}} </div> - {{end}} -</div> +</details> diff --git a/templates/repo/issue/view_content/update_branch_by_merge.tmpl b/templates/repo/issue/view_content/update_branch_by_merge.tmpl index adce052dee..e0ed262f17 100644 --- a/templates/repo/issue/view_content/update_branch_by_merge.tmpl +++ b/templates/repo/issue/view_content/update_branch_by_merge.tmpl @@ -8,7 +8,7 @@ <div class="item-section-right"> {{if and $.UpdateAllowed $.UpdateByRebaseAllowed}} <div class="tw-inline-block"> - <div class="ui buttons update-button"> + <div id="update-pr-branch-with-base" class="ui buttons"> <button class="ui button" data-do="{{$.Link}}/update" data-redirect="{{$.Link}}"> <span class="button-text"> {{ctx.Locale.Tr "repo.pulls.update_branch"}} diff --git a/web_src/js/features/repo-issue.ts b/web_src/js/features/repo-issue.ts index f5455393b2..ed79cbfe50 100644 --- a/web_src/js/features/repo-issue.ts +++ b/web_src/js/features/repo-issue.ts @@ -1,4 +1,3 @@ -import $ from 'jquery'; import {htmlEscape} from 'escape-goat'; import {createTippy, showTemporaryTooltip} from '../modules/tippy.ts'; import { @@ -21,35 +20,37 @@ import {ignoreAreYouSure} from '../vendor/jquery.are-you-sure.ts'; const {appSubUrl} = window.config; -export function initRepoIssueSidebarList() { +export function initRepoIssueSidebarDependency() { + const elDropdown = document.querySelector('#new-dependency-drop-list'); + if (!elDropdown) return; + const issuePageInfo = parseIssuePageInfo(); - const crossRepoSearch = $('#crossRepoSearch').val(); + const crossRepoSearch = elDropdown.getAttribute('data-issue-cross-repo-search'); let issueSearchUrl = `${issuePageInfo.repoLink}/issues/search?q={query}&type=${issuePageInfo.issueDependencySearchType}`; if (crossRepoSearch === 'true') { issueSearchUrl = `${appSubUrl}/issues/search?q={query}&priority_repo_id=${issuePageInfo.repoId}&type=${issuePageInfo.issueDependencySearchType}`; } - fomanticQuery('#new-dependency-drop-list').dropdown({ + fomanticQuery(elDropdown).dropdown({ fullTextSearch: true, apiSettings: { + cache: false, + rawResponse: true, url: issueSearchUrl, onResponse(response: any) { const filteredResponse = {success: true, results: [] as Array<Record<string, any>>}; - const currIssueId = $('#new-dependency-drop-list').data('issue-id'); + const currIssueId = elDropdown.getAttribute('data-issue-id'); // Parse the response from the api to work with our dropdown - $.each(response, (_i, issue) => { + for (const issue of response) { // Don't list current issue in the dependency list. - if (issue.id === currIssueId) { - return; - } + if (String(issue.id) === currIssueId) continue; filteredResponse.results.push({ + value: issue.id, name: `<div class="gt-ellipsis">#${issue.number} ${htmlEscape(issue.title)}</div> <div class="text small tw-break-anywhere">${htmlEscape(issue.repository.full_name)}</div>`, - value: issue.id, }); - }); + } return filteredResponse; }, - cache: false, }, }); } @@ -181,24 +182,6 @@ export function initRepoIssueCommentDelete() { }); } -export function initRepoIssueDependencyDelete() { - // Delete Issue dependency - $(document).on('click', '.delete-dependency-button', (e) => { - const id = e.currentTarget.getAttribute('data-id'); - const type = e.currentTarget.getAttribute('data-type'); - - $('.remove-dependency').modal({ - closable: false, - duration: 200, - onApprove: () => { - $('#removeDependencyID').val(id); - $('#dependencyType').val(type); - $('#removeDependencyForm').trigger('submit'); - }, - }).modal('show'); - }); -} - export function initRepoIssueCodeCommentCancel() { // Cancel inline code comment document.addEventListener('click', (e: DOMEvent<MouseEvent>) => { @@ -215,11 +198,12 @@ export function initRepoIssueCodeCommentCancel() { } export function initRepoPullRequestUpdate() { - // Pull Request update button - const pullUpdateButton = document.querySelector<HTMLButtonElement>('.update-button > button'); - if (!pullUpdateButton) return; + const prUpdateButtonContainer = document.querySelector('#update-pr-branch-with-base'); + if (!prUpdateButtonContainer) return; - pullUpdateButton.addEventListener('click', async function (e) { + const prUpdateButton = prUpdateButtonContainer.querySelector<HTMLButtonElement>(':scope > button'); + const prUpdateDropdown = prUpdateButtonContainer.querySelector(':scope > .ui.dropdown'); + prUpdateButton.addEventListener('click', async function (e) { e.preventDefault(); const redirect = this.getAttribute('data-redirect'); this.classList.add('is-loading'); @@ -246,27 +230,21 @@ export function initRepoPullRequestUpdate() { } }); - $('.update-button > .dropdown').dropdown({ + fomanticQuery(prUpdateDropdown).dropdown({ onChange(_text: string, _value: string, $choice: any) { const choiceEl = $choice[0]; const url = choiceEl.getAttribute('data-do'); if (url) { - const buttonText = pullUpdateButton.querySelector('.button-text'); + const buttonText = prUpdateButton.querySelector('.button-text'); if (buttonText) { buttonText.textContent = choiceEl.textContent; } - pullUpdateButton.setAttribute('data-do', url); + prUpdateButton.setAttribute('data-do', url); } }, }); } -export function initRepoPullRequestMergeInstruction() { - $('.show-instruction').on('click', () => { - toggleElem($('.instruct-content')); - }); -} - export function initRepoPullRequestAllowMaintainerEdit() { const wrapper = document.querySelector('#allow-edits-from-maintainers'); if (!wrapper) return; @@ -293,54 +271,8 @@ export function initRepoPullRequestAllowMaintainerEdit() { }); } -export function initRepoIssueReferenceRepositorySearch() { - $('.issue_reference_repository_search') - .dropdown({ - apiSettings: { - url: `${appSubUrl}/repo/search?q={query}&limit=20`, - onResponse(response: any) { - const filteredResponse = {success: true, results: [] as Array<Record<string, any>>}; - $.each(response.data, (_r, repo) => { - filteredResponse.results.push({ - name: htmlEscape(repo.repository.full_name), - value: repo.repository.full_name, - }); - }); - return filteredResponse; - }, - cache: false, - }, - onChange(_value: string, _text: string, $choice: any) { - const $form = $choice.closest('form'); - if (!$form.length) return; - - $form[0].setAttribute('action', `${appSubUrl}/${_text}/issues/new`); - }, - fullTextSearch: true, - }); -} - -export function initRepoIssueWipTitle() { - $('.title_wip_desc > a').on('click', (e) => { - e.preventDefault(); - - const $issueTitle = $('#issue_title'); - $issueTitle.trigger('focus'); - const value = ($issueTitle.val() as string).trim().toUpperCase(); - - const wipPrefixes = $('.title_wip_desc').data('wip-prefixes'); - for (const prefix of wipPrefixes) { - if (value.startsWith(prefix.toUpperCase())) { - return; - } - } - - $issueTitle.val(`${wipPrefixes[0]} ${$issueTitle.val()}`); - }); -} - export function initRepoIssueComments() { - if (!$('.repository.view.issue .timeline').length) return; + if (!document.querySelector('.repository.view.issue .timeline')) return; document.addEventListener('click', (e: DOMEvent<MouseEvent>) => { const urlTarget = document.querySelector(':target'); @@ -352,9 +284,9 @@ export function initRepoIssueComments() { if (!/^(issue|pull)(comment)?-\d+$/.test(urlTargetId)) return; if (!e.target.closest(`#${urlTargetId}`)) { - const scrollPosition = $(window).scrollTop(); - window.location.hash = ''; - $(window).scrollTop(scrollPosition); + // if the user clicks outside the comment, remove the hash from the url + // use empty hash and state to avoid scrolling + window.location.hash = ' '; window.history.pushState(null, null, ' '); } }); @@ -395,31 +327,31 @@ export function initRepoPullRequestReview() { } } - $(document).on('click', '.show-outdated', function (e) { + addDelegatedEventListener(document, 'click', '.show-outdated', (el, e) => { e.preventDefault(); - const id = this.getAttribute('data-comment'); - hideElem(this); + const id = el.getAttribute('data-comment'); + hideElem(el); showElem(`#code-comments-${id}`); showElem(`#code-preview-${id}`); showElem(`#hide-outdated-${id}`); }); - $(document).on('click', '.hide-outdated', function (e) { + addDelegatedEventListener(document, 'click', '.hide-outdated', (el, e) => { e.preventDefault(); - const id = this.getAttribute('data-comment'); - hideElem(this); + const id = el.getAttribute('data-comment'); + hideElem(el); hideElem(`#code-comments-${id}`); hideElem(`#code-preview-${id}`); showElem(`#show-outdated-${id}`); }); - $(document).on('click', 'button.comment-form-reply', async function (e) { + addDelegatedEventListener(document, 'click', 'button.comment-form-reply', (el, e) => { e.preventDefault(); - await handleReply(this); + handleReply(el); }); // The following part is only for diff views - if (!$('.repository.pull.diff').length) return; + if (!document.querySelector('.repository.pull.diff')) return; const elReviewBtn = document.querySelector('.js-btn-review'); const elReviewPanel = document.querySelector('.review-box-panel.tippy-target'); @@ -474,26 +406,67 @@ export function initRepoPullRequestReview() { } export function initRepoIssueReferenceIssue() { + const elDropdown = document.querySelector('.issue_reference_repository_search'); + if (!elDropdown) return; + const form = elDropdown.closest('form'); + fomanticQuery(elDropdown).dropdown({ + fullTextSearch: true, + apiSettings: { + cache: false, + rawResponse: true, + url: `${appSubUrl}/repo/search?q={query}&limit=20`, + onResponse(response: any) { + const filteredResponse = {success: true, results: [] as Array<Record<string, any>>}; + for (const repo of response.data) { + filteredResponse.results.push({ + name: htmlEscape(repo.repository.full_name), + value: repo.repository.full_name, + }); + } + return filteredResponse; + }, + }, + onChange(_value: string, _text: string, _$choice: any) { + form.setAttribute('action', `${appSubUrl}/${_text}/issues/new`); + }, + }); + // Reference issue - $(document).on('click', '.reference-issue', function (e) { - const target = this.getAttribute('data-target'); + addDelegatedEventListener(document, 'click', '.reference-issue', (el, e) => { + e.preventDefault(); + const target = el.getAttribute('data-target'); const content = document.querySelector(`#${target}`)?.textContent ?? ''; - const poster = this.getAttribute('data-poster-username'); - const reference = toAbsoluteUrl(this.getAttribute('data-reference')); - const modalSelector = this.getAttribute('data-modal'); + const poster = el.getAttribute('data-poster-username'); + const reference = toAbsoluteUrl(el.getAttribute('data-reference')); + const modalSelector = el.getAttribute('data-modal'); const modal = document.querySelector(modalSelector); - const textarea = modal.querySelector('textarea[name="content"]'); + const textarea = modal.querySelector<HTMLTextAreaElement>('textarea[name="content"]'); textarea.value = `${content}\n\n_Originally posted by @${poster} in ${reference}_`; - $(modal).modal('show'); - e.preventDefault(); + fomanticQuery(modal).modal('show'); }); } +export function initRepoIssueWipNewTitle() { + // Toggle WIP for new PR + queryElems(document, '.title_wip_desc > a', (el) => el.addEventListener('click', (e) => { + e.preventDefault(); + const wipPrefixes = JSON.parse(el.closest('.title_wip_desc').getAttribute('data-wip-prefixes')); + const titleInput = document.querySelector<HTMLInputElement>('#issue_title'); + const titleValue = titleInput.value; + for (const prefix of wipPrefixes) { + if (titleValue.startsWith(prefix.toUpperCase())) { + return; + } + } + titleInput.value = `${wipPrefixes[0]} ${titleValue}`; + })); +} + export function initRepoIssueWipToggle() { - // Toggle WIP - $('.toggle-wip a, .toggle-wip button').on('click', async (e) => { + // Toggle WIP for existing PR + queryElems(document, '.toggle-wip', (el) => el.addEventListener('click', async (e) => { e.preventDefault(); - const toggleWip = e.currentTarget.closest('.toggle-wip'); + const toggleWip = el; const title = toggleWip.getAttribute('data-title'); const wipPrefix = toggleWip.getAttribute('data-wip-prefix'); const updateUrl = toggleWip.getAttribute('data-update-url'); @@ -510,7 +483,7 @@ export function initRepoIssueWipToggle() { } catch (error) { console.error(error); } - }); + })); } export function initRepoIssueTitleEdit() { @@ -583,11 +556,11 @@ export function initRepoIssueBranchSelect() { }); } -async function initSingleCommentEditor($commentForm: any) { +async function initSingleCommentEditor(commentForm: HTMLFormElement) { // pages: // * normal new issue/pr page: no status-button, no comment-button (there is only a normal submit button which can submit empty content) // * issue/pr view page: with comment form, has status-button and comment-button - const editor = await initComboMarkdownEditor($commentForm[0].querySelector('.combo-markdown-editor')); + const editor = await initComboMarkdownEditor(commentForm.querySelector('.combo-markdown-editor')); const statusButton = document.querySelector<HTMLButtonElement>('#status-button'); const commentButton = document.querySelector<HTMLButtonElement>('#comment-button'); const syncUiState = () => { @@ -605,27 +578,27 @@ async function initSingleCommentEditor($commentForm: any) { syncUiState(); } -function initIssueTemplateCommentEditors($commentForm: any) { +function initIssueTemplateCommentEditors(commentForm: HTMLFormElement) { // pages: // * new issue with issue template - const $comboFields = $commentForm.find('.combo-editor-dropzone'); + const comboFields = commentForm.querySelectorAll<HTMLElement>('.combo-editor-dropzone'); const initCombo = async (elCombo: HTMLElement) => { - const $formField = $(elCombo.querySelector('.form-field-real')); + const fieldTextarea = elCombo.querySelector<HTMLTextAreaElement>('.form-field-real'); const dropzoneContainer = elCombo.querySelector<HTMLElement>('.form-field-dropzone'); const markdownEditor = elCombo.querySelector<HTMLElement>('.combo-markdown-editor'); const editor = await initComboMarkdownEditor(markdownEditor); - editor.container.addEventListener(ComboMarkdownEditor.EventEditorContentChanged, () => $formField.val(editor.value())); + editor.container.addEventListener(ComboMarkdownEditor.EventEditorContentChanged, () => fieldTextarea.value = editor.value()); - $formField.on('focus', async () => { + fieldTextarea.addEventListener('focus', async () => { // deactivate all markdown editors - showElem($commentForm.find('.combo-editor-dropzone .form-field-real')); - hideElem($commentForm.find('.combo-editor-dropzone .combo-markdown-editor')); - hideElem($commentForm.find('.combo-editor-dropzone .form-field-dropzone')); + showElem(commentForm.querySelectorAll('.combo-editor-dropzone .form-field-real')); + hideElem(commentForm.querySelectorAll('.combo-editor-dropzone .combo-markdown-editor')); + hideElem(commentForm.querySelectorAll('.combo-editor-dropzone .form-field-dropzone')); // activate this markdown editor - hideElem($formField); + hideElem(fieldTextarea); showElem(markdownEditor); showElem(dropzoneContainer); @@ -634,21 +607,21 @@ function initIssueTemplateCommentEditors($commentForm: any) { }); }; - for (const el of $comboFields) { + for (const el of comboFields) { initCombo(el); } } export function initRepoCommentFormAndSidebar() { - const $commentForm = $('.comment.form'); - if (!$commentForm.length) return; + const commentForm = document.querySelector<HTMLFormElement>('.comment.form'); + if (!commentForm) return; - if ($commentForm.find('.field.combo-editor-dropzone').length) { + if (commentForm.querySelector('.field.combo-editor-dropzone')) { // at the moment, if a form has multiple combo-markdown-editors, it must be an issue template form - initIssueTemplateCommentEditors($commentForm); - } else if ($commentForm.find('.combo-markdown-editor').length) { + initIssueTemplateCommentEditors(commentForm); + } else if (commentForm.querySelector('.combo-markdown-editor')) { // it's quite unclear about the "comment form" elements, sometimes it's for issue comment, sometimes it's for file editor/uploader message - initSingleCommentEditor($commentForm); + initSingleCommentEditor(commentForm); } initRepoIssueSidebar(); diff --git a/web_src/js/features/repo-legacy.ts b/web_src/js/features/repo-legacy.ts index f5a0af175a..0ff6feba2d 100644 --- a/web_src/js/features/repo-legacy.ts +++ b/web_src/js/features/repo-legacy.ts @@ -2,8 +2,8 @@ import {registerGlobalInitFunc} from '../modules/observer.ts'; import { initRepoCommentFormAndSidebar, initRepoIssueBranchSelect, initRepoIssueCodeCommentCancel, initRepoIssueCommentDelete, - initRepoIssueComments, initRepoIssueDependencyDelete, initRepoIssueReferenceIssue, - initRepoIssueTitleEdit, initRepoIssueWipToggle, + initRepoIssueComments, initRepoIssueReferenceIssue, + initRepoIssueTitleEdit, initRepoIssueWipNewTitle, initRepoIssueWipToggle, initRepoPullRequestUpdate, } from './repo-issue.ts'; import {initUnicodeEscapeButton} from './repo-unicode-escape.ts'; @@ -54,6 +54,7 @@ export function initRepository() { initRepoCloneButtons(); initCitationFileCopyContent(); initRepoSettings(); + initRepoIssueWipNewTitle(); // Issues if (pageContent.matches('.page-content.repository.view.issue')) { @@ -67,7 +68,6 @@ export function initRepository() { initRepoIssueReferenceIssue(); initRepoIssueCommentDelete(); - initRepoIssueDependencyDelete(); initRepoIssueCodeCommentCancel(); initRepoPullRequestUpdate(); initCompReactionSelector(); diff --git a/web_src/js/index.ts b/web_src/js/index.ts index c1ec78539d..2e44ef826a 100644 --- a/web_src/js/index.ts +++ b/web_src/js/index.ts @@ -20,15 +20,8 @@ import {initStopwatch} from './features/stopwatch.ts'; import {initFindFileInRepo} from './features/repo-findfile.ts'; import {initMarkupContent} from './markup/content.ts'; import {initPdfViewer} from './render/pdf.ts'; - import {initUserAuthOauth2, initUserCheckAppUrl} from './features/user-auth.ts'; -import { - initRepoIssueReferenceRepositorySearch, - initRepoIssueWipTitle, - initRepoPullRequestMergeInstruction, - initRepoPullRequestAllowMaintainerEdit, - initRepoPullRequestReview, initRepoIssueSidebarList, initRepoIssueFilterItemLabel, -} from './features/repo-issue.ts'; +import {initRepoPullRequestAllowMaintainerEdit, initRepoPullRequestReview, initRepoIssueSidebarDependency, initRepoIssueFilterItemLabel} from './features/repo-issue.ts'; import {initRepoEllipsisButton, initCommitStatuses} from './features/repo-commit.ts'; import {initRepoTopicBar} from './features/repo-home.ts'; import {initAdminCommon} from './features/admin/common.ts'; @@ -137,13 +130,10 @@ onDomReady(() => { initRepoIssueContentHistory, initRepoIssueList, initRepoIssueFilterItemLabel, - initRepoIssueSidebarList, - initRepoIssueReferenceRepositorySearch, - initRepoIssueWipTitle, + initRepoIssueSidebarDependency, initRepoMigration, initRepoMigrationStatusChecker, initRepoProject, - initRepoPullRequestMergeInstruction, initRepoPullRequestAllowMaintainerEdit, initRepoPullRequestReview, initRepoRelease, |