From 198d13de4c0a96f6ffa442d3c301ca255085aad6 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 30 Mar 2026 16:01:52 +0800 Subject: [PATCH] revert frontend change --- .../features/repo-issue-sidebar-combolist.ts | 76 +++++++------------ .../js/features/repo-issue-sidebar-project.ts | 39 ---------- web_src/js/features/repo-issue-sidebar.ts | 4 - 3 files changed, 27 insertions(+), 92 deletions(-) delete mode 100644 web_src/js/features/repo-issue-sidebar-project.ts diff --git a/web_src/js/features/repo-issue-sidebar-combolist.ts b/web_src/js/features/repo-issue-sidebar-combolist.ts index 839b4bdf81..c4eef16d7c 100644 --- a/web_src/js/features/repo-issue-sidebar-combolist.ts +++ b/web_src/js/features/repo-issue-sidebar-combolist.ts @@ -32,9 +32,6 @@ export class IssueSidebarComboList { elComboValue: HTMLInputElement; initialValues: string[]; container: HTMLElement; - // Optional callback invoked after the backend update completes. - // If it returns true, the page reload is skipped. - onAfterUpdate?: (response: Response, changedValues: string[]) => Promise; constructor(container: HTMLElement) { this.container = container; @@ -66,33 +63,38 @@ export class IssueSidebarComboList { toggleElem(elEmptyTip, !hasItems); } - async updateToBackend(changedValues: Array) { - let resp: Response | undefined; - try { - if (this.updateAlgo === 'diff') { - for (const value of this.initialValues) { - if (!changedValues.includes(value)) { - await POST(this.updateUrl, {data: new URLSearchParams({action: 'detach', id: value})}); - } + async sendRequestToBackend(changedValues: Array): Promise { + if (!changedValues.length) throw new Error('No changed values to update'); + let lastResp: Response | null = null; + if (this.updateAlgo === 'diff') { + for (const value of this.initialValues) { + if (!changedValues.includes(value)) { + lastResp = await POST(this.updateUrl, {data: new URLSearchParams({action: 'detach', id: value})}); } - for (const value of changedValues) { - if (!this.initialValues.includes(value)) { - resp = await POST(this.updateUrl, {data: new URLSearchParams({action: 'attach', id: value})}); - } - } - } else { - resp = await POST(this.updateUrl, {data: new URLSearchParams({id: changedValues.join(',')})}); } - if (resp && !resp.ok) { - showErrorToast(`Failed to update: ${resp.statusText}`); + for (const value of changedValues) { + if (!this.initialValues.includes(value)) { + lastResp = await POST(this.updateUrl, {data: new URLSearchParams({action: 'attach', id: value})}); + } + } + } else { + lastResp = await POST(this.updateUrl, {data: new URLSearchParams({id: changedValues.join(',')})}); + } + return lastResp!; + } + + async updateToBackend(changedValues: Array) { + if (!changedValues.length) return; + try { + const resp = await this.sendRequestToBackend(changedValues); + if (!resp.ok) { + showErrorToast(`Failed to update to backend: ${resp.statusText}`); return; } - } catch { - showErrorToast('Failed to update'); - return; + issueSidebarReloadConfirmDraftComment(); + } catch (e) { + showErrorToast(`Failed to update to backend: ${e}`); } - if (this.onAfterUpdate && resp && await this.onAfterUpdate(resp, changedValues)) return; - issueSidebarReloadConfirmDraftComment(); } async doUpdate() { @@ -147,31 +149,7 @@ export class IssueSidebarComboList { if (this.selectionMode === 'multiple') this.doUpdate(); } - rerender(items: {value: string; text: string}[], selectedValue: string) { - const menu = this.elDropdown.querySelector('.menu')!; - menu.innerHTML = ''; - for (const item of items) { - const el = document.createElement('div'); - el.className = `item${item.value === selectedValue ? ' checked' : ''}`; - el.setAttribute('data-value', item.value); - el.textContent = item.text; - menu.append(el); - } - this.elComboValue.value = selectedValue; - this.initialValues = selectedValue ? [selectedValue] : []; - this.updateUiList(this.initialValues); - addDelegatedEventListener(this.elDropdown, 'click', '.item', (el, e) => this.onItemClick(el, e)); - fomanticQuery(this.elDropdown).dropdown('destroy'); - fomanticQuery(this.elDropdown).dropdown({ - action: 'nothing', - fullTextSearch: 'exact', - hideDividers: 'empty', - onHide: () => this.onHide(), - }); - } - init() { - (this.container as any)._comboList = this; // init the checked items from initial value if (this.elComboValue.value && this.elComboValue.value !== '0' && !queryElems(this.elDropdown, `.menu > .item.checked`).length) { const values = this.elComboValue.value.split(','); diff --git a/web_src/js/features/repo-issue-sidebar-project.ts b/web_src/js/features/repo-issue-sidebar-project.ts deleted file mode 100644 index f68154a66e..0000000000 --- a/web_src/js/features/repo-issue-sidebar-project.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type {IssueSidebarComboList} from './repo-issue-sidebar-combolist.ts'; - -type ColumnInfo = { - id: number; - title: string; -}; - -export function initProjectColumnPicker() { - const projectCombo = document.querySelector('.issue-sidebar-combo[data-update-url*="/issues/projects?"]'); - if (!projectCombo) return; - - const comboList = (projectCombo as any)._comboList as IssueSidebarComboList | undefined; - if (!comboList) return; - - const columnComboEl = document.querySelector('#sidebar-project-column'); - if (!columnComboEl) return; - - const columnComboList = (columnComboEl as any)._comboList as IssueSidebarComboList | undefined; - if (!columnComboList) return; - - comboList.onAfterUpdate = async (response: Response, _changedValues: string[]): Promise => { - const data = await response.json(); - const columns: ColumnInfo[] = data.columns || []; - const selectedColumnID: number = data.selected_column_id || 0; - - comboList.updateUiList(comboList.collectCheckedValues()); - - if (columns.length > 1) { - columnComboList.rerender( - columns.map((c) => ({value: String(c.id), text: c.title})), - String(selectedColumnID), - ); - columnComboEl.classList.remove('tw-hidden'); - } else { - columnComboEl.classList.add('tw-hidden'); - } - return true; - }; -} diff --git a/web_src/js/features/repo-issue-sidebar.ts b/web_src/js/features/repo-issue-sidebar.ts index c123cc4efb..2ff077e6db 100644 --- a/web_src/js/features/repo-issue-sidebar.ts +++ b/web_src/js/features/repo-issue-sidebar.ts @@ -1,7 +1,6 @@ import {POST} from '../modules/fetch.ts'; import {queryElems, toggleElem} from '../utils/dom.ts'; import {IssueSidebarComboList} from './repo-issue-sidebar-combolist.ts'; -import {initProjectColumnPicker} from './repo-issue-sidebar-project.ts'; function initBranchSelector() { // TODO: RemoveIssueRef: see "repo/issue/branch_selector_field.tmpl" @@ -50,7 +49,4 @@ export function initRepoIssueSidebar() { // init the combo list: a dropdown for selecting items, and a list for showing selected items and related actions queryElems(document, '.issue-sidebar-combo', (el) => new IssueSidebarComboList(el).init()); - - // hook up the project column picker (must run after combo list init) - initProjectColumnPicker(); }