aboutsummaryrefslogtreecommitdiffstats
path: root/web_src/js/features
diff options
context:
space:
mode:
Diffstat (limited to 'web_src/js/features')
-rw-r--r--web_src/js/features/repo-issue-pr-form.ts10
-rw-r--r--web_src/js/features/repo-issue-pr-status.ts10
-rw-r--r--web_src/js/features/repo-issue-pull.ts133
-rw-r--r--web_src/js/features/repo-issue.ts48
-rw-r--r--web_src/js/features/repo-legacy.ts8
5 files changed, 135 insertions, 74 deletions
diff --git a/web_src/js/features/repo-issue-pr-form.ts b/web_src/js/features/repo-issue-pr-form.ts
deleted file mode 100644
index 94a2857340..0000000000
--- a/web_src/js/features/repo-issue-pr-form.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import {createApp} from 'vue';
-import PullRequestMergeForm from '../components/PullRequestMergeForm.vue';
-
-export function initRepoPullRequestMergeForm() {
- const el = document.querySelector('#pull-request-merge-form');
- if (!el) return;
-
- const view = createApp(PullRequestMergeForm);
- view.mount(el);
-}
diff --git a/web_src/js/features/repo-issue-pr-status.ts b/web_src/js/features/repo-issue-pr-status.ts
deleted file mode 100644
index 8426b389f0..0000000000
--- a/web_src/js/features/repo-issue-pr-status.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export function initRepoPullRequestCommitStatus() {
- for (const btn of document.querySelectorAll('.commit-status-hide-checks')) {
- const panel = btn.closest('.commit-status-panel');
- const list = panel.querySelector<HTMLElement>('.commit-status-list');
- btn.addEventListener('click', () => {
- list.style.maxHeight = list.style.maxHeight ? '' : '0px'; // toggle
- btn.textContent = btn.getAttribute(list.style.maxHeight ? 'data-show-all' : 'data-hide-all');
- });
- }
-}
diff --git a/web_src/js/features/repo-issue-pull.ts b/web_src/js/features/repo-issue-pull.ts
new file mode 100644
index 0000000000..c415dad08f
--- /dev/null
+++ b/web_src/js/features/repo-issue-pull.ts
@@ -0,0 +1,133 @@
+import {createApp} from 'vue';
+import PullRequestMergeForm from '../components/PullRequestMergeForm.vue';
+import {GET, POST} from '../modules/fetch.ts';
+import {fomanticQuery} from '../modules/fomantic/base.ts';
+import {createElementFromHTML} from '../utils/dom.ts';
+
+function initRepoPullRequestUpdate(el: HTMLElement) {
+ const prUpdateButtonContainer = el.querySelector('#update-pr-branch-with-base');
+ if (!prUpdateButtonContainer) return;
+
+ 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');
+ let response: Response;
+ try {
+ response = await POST(this.getAttribute('data-do'));
+ } catch (error) {
+ console.error(error);
+ } finally {
+ this.classList.remove('is-loading');
+ }
+ let data: Record<string, any>;
+ try {
+ data = await response?.json(); // the response is probably not a JSON
+ } catch (error) {
+ console.error(error);
+ }
+ if (data?.redirect) {
+ window.location.href = data.redirect;
+ } else if (redirect) {
+ window.location.href = redirect;
+ } else {
+ window.location.reload();
+ }
+ });
+
+ fomanticQuery(prUpdateDropdown).dropdown({
+ onChange(_text: string, _value: string, $choice: any) {
+ const choiceEl = $choice[0];
+ const url = choiceEl.getAttribute('data-do');
+ if (url) {
+ const buttonText = prUpdateButton.querySelector('.button-text');
+ if (buttonText) {
+ buttonText.textContent = choiceEl.textContent;
+ }
+ prUpdateButton.setAttribute('data-do', url);
+ }
+ },
+ });
+}
+
+function initRepoPullRequestCommitStatus(el: HTMLElement) {
+ for (const btn of el.querySelectorAll('.commit-status-hide-checks')) {
+ const panel = btn.closest('.commit-status-panel');
+ const list = panel.querySelector<HTMLElement>('.commit-status-list');
+ btn.addEventListener('click', () => {
+ list.style.maxHeight = list.style.maxHeight ? '' : '0px'; // toggle
+ btn.textContent = btn.getAttribute(list.style.maxHeight ? 'data-show-all' : 'data-hide-all');
+ });
+ }
+}
+
+function initRepoPullRequestMergeForm(box: HTMLElement) {
+ const el = box.querySelector('#pull-request-merge-form');
+ if (!el) return;
+
+ const view = createApp(PullRequestMergeForm);
+ view.mount(el);
+}
+
+function executeScripts(elem: HTMLElement) {
+ for (const oldScript of elem.querySelectorAll('script')) {
+ // TODO: that's the only way to load the data for the merge form. In the future
+ // we need to completely decouple the page data and embedded script
+ // eslint-disable-next-line github/no-dynamic-script-tag
+ const newScript = document.createElement('script');
+ for (const attr of oldScript.attributes) {
+ if (attr.name === 'type' && attr.value === 'module') continue;
+ newScript.setAttribute(attr.name, attr.value);
+ }
+ newScript.text = oldScript.text;
+ document.body.append(newScript);
+ }
+}
+
+export function initRepoPullMergeBox(el: HTMLElement) {
+ initRepoPullRequestCommitStatus(el);
+ initRepoPullRequestUpdate(el);
+ initRepoPullRequestMergeForm(el);
+
+ const reloadingIntervalValue = el.getAttribute('data-pull-merge-box-reloading-interval');
+ if (!reloadingIntervalValue) return;
+
+ const reloadingInterval = parseInt(reloadingIntervalValue);
+ const pullLink = el.getAttribute('data-pull-link');
+ let timerId: number;
+
+ let reloadMergeBox: () => Promise<void>;
+ const stopReloading = () => {
+ if (!timerId) return;
+ clearTimeout(timerId);
+ timerId = null;
+ };
+ const startReloading = () => {
+ if (timerId) return;
+ setTimeout(reloadMergeBox, reloadingInterval);
+ };
+ const onVisibilityChange = () => {
+ if (document.hidden) {
+ stopReloading();
+ } else {
+ startReloading();
+ }
+ };
+ reloadMergeBox = async () => {
+ const resp = await GET(`${pullLink}/merge_box`);
+ stopReloading();
+ if (!resp.ok) {
+ startReloading();
+ return;
+ }
+ document.removeEventListener('visibilitychange', onVisibilityChange);
+ const newElem = createElementFromHTML(await resp.text());
+ executeScripts(newElem);
+ el.replaceWith(newElem);
+ };
+
+ document.addEventListener('visibilitychange', onVisibilityChange);
+ startReloading();
+}
diff --git a/web_src/js/features/repo-issue.ts b/web_src/js/features/repo-issue.ts
index ed79cbfe50..bc7d4dee19 100644
--- a/web_src/js/features/repo-issue.ts
+++ b/web_src/js/features/repo-issue.ts
@@ -197,54 +197,6 @@ export function initRepoIssueCodeCommentCancel() {
});
}
-export function initRepoPullRequestUpdate() {
- const prUpdateButtonContainer = document.querySelector('#update-pr-branch-with-base');
- if (!prUpdateButtonContainer) return;
-
- 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');
- let response: Response;
- try {
- response = await POST(this.getAttribute('data-do'));
- } catch (error) {
- console.error(error);
- } finally {
- this.classList.remove('is-loading');
- }
- let data: Record<string, any>;
- try {
- data = await response?.json(); // the response is probably not a JSON
- } catch (error) {
- console.error(error);
- }
- if (data?.redirect) {
- window.location.href = data.redirect;
- } else if (redirect) {
- window.location.href = redirect;
- } else {
- window.location.reload();
- }
- });
-
- fomanticQuery(prUpdateDropdown).dropdown({
- onChange(_text: string, _value: string, $choice: any) {
- const choiceEl = $choice[0];
- const url = choiceEl.getAttribute('data-do');
- if (url) {
- const buttonText = prUpdateButton.querySelector('.button-text');
- if (buttonText) {
- buttonText.textContent = choiceEl.textContent;
- }
- prUpdateButton.setAttribute('data-do', url);
- }
- },
- });
-}
-
export function initRepoPullRequestAllowMaintainerEdit() {
const wrapper = document.querySelector('#allow-edits-from-maintainers');
if (!wrapper) return;
diff --git a/web_src/js/features/repo-legacy.ts b/web_src/js/features/repo-legacy.ts
index 0ff6feba2d..249d181b25 100644
--- a/web_src/js/features/repo-legacy.ts
+++ b/web_src/js/features/repo-legacy.ts
@@ -4,7 +4,6 @@ import {
initRepoIssueBranchSelect, initRepoIssueCodeCommentCancel, initRepoIssueCommentDelete,
initRepoIssueComments, initRepoIssueReferenceIssue,
initRepoIssueTitleEdit, initRepoIssueWipNewTitle, initRepoIssueWipToggle,
- initRepoPullRequestUpdate,
} from './repo-issue.ts';
import {initUnicodeEscapeButton} from './repo-unicode-escape.ts';
import {initRepoCloneButtons} from './repo-common.ts';
@@ -12,14 +11,13 @@ import {initCitationFileCopyContent} from './citation.ts';
import {initCompLabelEdit} from './comp/LabelEdit.ts';
import {initCompReactionSelector} from './comp/ReactionSelector.ts';
import {initRepoSettings} from './repo-settings.ts';
-import {initRepoPullRequestMergeForm} from './repo-issue-pr-form.ts';
-import {initRepoPullRequestCommitStatus} from './repo-issue-pr-status.ts';
import {hideElem, queryElemChildren, queryElems, showElem} from '../utils/dom.ts';
import {initRepoIssueCommentEdit} from './repo-issue-edit.ts';
import {initRepoMilestone} from './repo-milestone.ts';
import {initRepoNew} from './repo-new.ts';
import {createApp} from 'vue';
import RepoBranchTagSelector from '../components/RepoBranchTagSelector.vue';
+import {initRepoPullMergeBox} from './repo-issue-pull.ts';
function initRepoBranchTagSelector() {
registerGlobalInitFunc('initRepoBranchTagSelector', async (elRoot: HTMLInputElement) => {
@@ -69,11 +67,9 @@ export function initRepository() {
initRepoIssueCommentDelete();
initRepoIssueCodeCommentCancel();
- initRepoPullRequestUpdate();
initCompReactionSelector();
- initRepoPullRequestMergeForm();
- initRepoPullRequestCommitStatus();
+ registerGlobalInitFunc('initRepoPullMergeBox', initRepoPullMergeBox);
}
initUnicodeEscapeButton();