Refactor htmx and fetch-action related code (#37186)

This is the first step (the hardest part):

* repo file list last commit message lazy load
* admin server status monitor
* watch/unwatch (normal page, watchers page)
* star/unstar (normal page, watchers page)
* project view, delete column
* workflow dispatch, switch the branch
* commit page: load branches and tags referencing this commit

The legacy "data-redirect" attribute is removed, it only makes the page
reload (sometimes using an incorrect link).

Also did cleanup for some devtest pages.
This commit is contained in:
wxiaoguang
2026-04-14 02:53:55 +08:00
committed by GitHub
parent 6eae04241d
commit 6bcb666a9d
41 changed files with 457 additions and 242 deletions

View File

@@ -1,20 +1,57 @@
import {showInfoToast, showWarningToast, showErrorToast} from './toast.ts';
import type {Toast} from './toast.ts';
import {registerGlobalInitFunc} from './observer.ts';
import {fomanticQuery} from './fomantic/base.ts';
import {createElementFromHTML} from '../utils/dom.ts';
import {html} from '../utils/html.ts';
type LevelMap = Record<string, (message: string) => Toast | null>;
export function initDevtest() {
registerGlobalInitFunc('initDevtestPage', () => {
const els = document.querySelectorAll('.toast-test-button');
if (!els.length) return;
function initDevtestPage() {
const toastButtons = document.querySelectorAll('.toast-test-button');
if (toastButtons.length) {
const levelMap: LevelMap = {info: showInfoToast, warning: showWarningToast, error: showErrorToast};
for (const el of els) {
for (const el of toastButtons) {
el.addEventListener('click', () => {
const level = el.getAttribute('data-toast-level')!;
const message = el.getAttribute('data-toast-message')!;
levelMap[level](message);
});
}
});
}
const modalButtons = document.querySelector('.modal-buttons');
if (modalButtons) {
for (const el of document.querySelectorAll('.ui.modal:not([data-skip-button])')) {
const btn = createElementFromHTML(html`<button class="ui button">${el.id}</button`);
btn.addEventListener('click', () => fomanticQuery(el).modal('show'));
modalButtons.append(btn);
}
}
const sampleButtons = document.querySelectorAll('#devtest-button-samples button.ui.button');
if (sampleButtons.length) {
const buttonStyles = document.querySelectorAll<HTMLInputElement>('input[name*="button-style"]');
for (const elStyle of buttonStyles) {
elStyle.addEventListener('click', () => {
for (const btn of sampleButtons) {
for (const el of buttonStyles) {
if (el.value) btn.classList.toggle(el.value, el.checked);
}
}
});
}
const buttonStates = document.querySelectorAll<HTMLInputElement>('input[name*="button-state"]');
for (const elState of buttonStates) {
elState.addEventListener('click', () => {
for (const btn of sampleButtons) {
(btn as any)[elState.value] = elState.checked;
}
});
}
}
}
export function initDevtest() {
registerGlobalInitFunc('initDevtestPage', initDevtestPage);
}

View File

@@ -2,7 +2,7 @@ import {isObject} from '../utils.ts';
import type {RequestOpts} from '../types.ts';
// fetch wrapper, use below method name functions and the `data` option to pass in data
// which will automatically set an appropriate headers. For json content, only object
// which will automatically set an appropriate headers. For JSON content, only object
// and array types are currently supported.
export function request(url: string, {method = 'GET', data, headers = {}, ...other}: RequestOpts = {}): Promise<Response> {
let body: string | FormData | URLSearchParams | undefined;
@@ -14,17 +14,13 @@ export function request(url: string, {method = 'GET', data, headers = {}, ...oth
body = JSON.stringify(data);
}
const headersMerged = new Headers({
...(contentType && {'content-type': contentType}),
});
for (const [name, value] of Object.entries(headers)) {
headersMerged.set(name, value);
headers = new Headers(headers);
if (!headers.has('content-type') && contentType) {
headers.set('content-type', contentType);
}
return fetch(url, { // eslint-disable-line no-restricted-globals
method,
headers: headersMerged,
headers,
...other,
...(body && {body}),
});