修复无法单击的错误
This commit is contained in:
@@ -199,7 +199,7 @@ html, body {
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
border: 1px solid var(--border-light);
|
border: 1px solid var(--border-light);
|
||||||
overflow: hidden;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
|
|||||||
@@ -39,7 +39,9 @@
|
|||||||
realname: { list: [], pagination: null },
|
realname: { list: [], pagination: null },
|
||||||
devices: { list: [], pagination: null },
|
devices: { list: [], pagination: null },
|
||||||
ipv6: { list: [], pagination: null },
|
ipv6: { list: [], pagination: null },
|
||||||
expandedNodes: new Set()
|
expandedNodes: new Set(),
|
||||||
|
prevUser: null,
|
||||||
|
prevRoute: null
|
||||||
};
|
};
|
||||||
|
|
||||||
const ROUTE_META = {
|
const ROUTE_META = {
|
||||||
@@ -73,6 +75,9 @@
|
|||||||
root.addEventListener("click", onClick);
|
root.addEventListener("click", onClick);
|
||||||
root.addEventListener("submit", onSubmit);
|
root.addEventListener("submit", onSubmit);
|
||||||
|
|
||||||
|
// Initialize shell and modal containers
|
||||||
|
root.innerHTML = '<div id="admin-shell-container"></div><div id="admin-modal-container"></div><div id="admin-busy-container"></div>';
|
||||||
|
|
||||||
if (state.token) {
|
if (state.token) {
|
||||||
await loadBootstrap();
|
await loadBootstrap();
|
||||||
} else {
|
} else {
|
||||||
@@ -266,6 +271,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action === "plan-delete") {
|
if (action === "plan-delete") {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
if (confirm("确认删除该套餐吗?")) {
|
if (confirm("确认删除该套餐吗?")) {
|
||||||
await adminPost(`${cfg.api.adminBase}/plan/drop`, { id: Number(actionEl.getAttribute("data-id")) });
|
await adminPost(`${cfg.api.adminBase}/plan/drop`, { id: Number(actionEl.getAttribute("data-id")) });
|
||||||
await hydrateRoute();
|
await hydrateRoute();
|
||||||
@@ -280,6 +287,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action === "coupon-delete") {
|
if (action === "coupon-delete") {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
if (confirm("确认删除该优惠券吗?")) {
|
if (confirm("确认删除该优惠券吗?")) {
|
||||||
await adminPost(`${cfg.api.adminBase}/coupon/drop`, { id: Number(actionEl.getAttribute("data-id")) });
|
await adminPost(`${cfg.api.adminBase}/coupon/drop`, { id: Number(actionEl.getAttribute("data-id")) });
|
||||||
await hydrateRoute();
|
await hydrateRoute();
|
||||||
@@ -312,6 +321,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action === "order-paid") {
|
if (action === "order-paid") {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
await adminPost(`${cfg.api.adminBase}/order/paid`, {
|
await adminPost(`${cfg.api.adminBase}/order/paid`, {
|
||||||
trade_no: actionEl.getAttribute("data-trade")
|
trade_no: actionEl.getAttribute("data-trade")
|
||||||
});
|
});
|
||||||
@@ -320,6 +331,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action === "order-cancel") {
|
if (action === "order-cancel") {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
await adminPost(`${cfg.api.adminBase}/order/cancel`, {
|
await adminPost(`${cfg.api.adminBase}/order/cancel`, {
|
||||||
trade_no: actionEl.getAttribute("data-trade")
|
trade_no: actionEl.getAttribute("data-trade")
|
||||||
});
|
});
|
||||||
@@ -334,13 +347,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action === "node-edit") {
|
if (action === "node-edit") {
|
||||||
const item = state.nodes.find((row) => String(row.id) === actionEl.getAttribute("data-id"));
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
const nodeId = String(actionEl.getAttribute("data-id"));
|
||||||
|
const item = state.nodes.find((row) => String(row.id) === nodeId);
|
||||||
state.modal = { type: "node", data: item || {} };
|
state.modal = { type: "node", data: item || {} };
|
||||||
render();
|
render();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action === "node-copy") {
|
if (action === "node-copy") {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
const nodeId = Number(actionEl.getAttribute("data-id"));
|
const nodeId = Number(actionEl.getAttribute("data-id"));
|
||||||
try {
|
try {
|
||||||
await adminPost(`${cfg.api.adminBase}/server/manage/copy`, { id: nodeId });
|
await adminPost(`${cfg.api.adminBase}/server/manage/copy`, { id: nodeId });
|
||||||
@@ -350,6 +368,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action === "node-delete") {
|
if (action === "node-delete") {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
if (confirm("确认删除该节点吗?")) {
|
if (confirm("确认删除该节点吗?")) {
|
||||||
const nodeId = Number(actionEl.getAttribute("data-id"));
|
const nodeId = Number(actionEl.getAttribute("data-id"));
|
||||||
try {
|
try {
|
||||||
@@ -544,19 +564,32 @@
|
|||||||
await hydrateRoute();
|
await hydrateRoute();
|
||||||
}
|
}
|
||||||
|
|
||||||
function render() {
|
function render(force) {
|
||||||
root.innerHTML = state.user ? renderDashboard() : renderLogin();
|
const shellContainer = document.getElementById("admin-shell-container");
|
||||||
if (state.modal) {
|
const modalContainer = document.getElementById("admin-modal-container");
|
||||||
const modalShell = document.createElement("div");
|
const busyContainer = document.getElementById("admin-busy-container");
|
||||||
modalShell.className = "modal-overlay";
|
|
||||||
modalShell.innerHTML = renderModalContent();
|
if (!shellContainer || !modalContainer || !busyContainer) return;
|
||||||
root.appendChild(modalShell);
|
|
||||||
|
// Re-render the shell if user or route changed, or if forced (e.g., data updated)
|
||||||
|
if (force || state.user !== state.prevUser || state.route !== state.prevRoute) {
|
||||||
|
shellContainer.innerHTML = state.user ? renderDashboard() : renderLogin();
|
||||||
|
state.prevUser = state.user;
|
||||||
|
state.prevRoute = state.route;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle Modal independently
|
||||||
|
if (state.modal) {
|
||||||
|
modalContainer.innerHTML = `<div class="modal-overlay">${renderModalContent()}</div>`;
|
||||||
|
} else {
|
||||||
|
modalContainer.innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Busy overlay independently
|
||||||
if (state.busy) {
|
if (state.busy) {
|
||||||
const overlay = document.createElement("div");
|
busyContainer.innerHTML = '<div class="busy-overlay"><div class="busy-spinner">正在处理...</div></div>';
|
||||||
overlay.className = "busy-overlay";
|
} else {
|
||||||
overlay.innerHTML = '<div class="busy-spinner">正在处理...</div>';
|
busyContainer.innerHTML = "";
|
||||||
root.appendChild(overlay);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -741,7 +774,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderNodeManage() {
|
function renderNodeManage() {
|
||||||
const roots = state.nodes.filter((node) => !node.parent_id);
|
const isRoot = (node) => !node.parent_id || String(node.parent_id) === "0";
|
||||||
|
const roots = state.nodes.filter(isRoot);
|
||||||
const childrenByParent = {};
|
const childrenByParent = {};
|
||||||
state.nodes.forEach((node) => {
|
state.nodes.forEach((node) => {
|
||||||
if (node.parent_id) {
|
if (node.parent_id) {
|
||||||
@@ -1332,17 +1366,17 @@
|
|||||||
|
|
||||||
function setBusy(value) {
|
function setBusy(value) {
|
||||||
state.busy = value;
|
state.busy = value;
|
||||||
render();
|
render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function show(message, type) {
|
function show(message, type) {
|
||||||
state.message = message;
|
state.message = message;
|
||||||
state.messageType = type || "info";
|
state.messageType = type || "info";
|
||||||
render();
|
render(true);
|
||||||
window.clearTimeout(show._timer);
|
window.clearTimeout(show._timer);
|
||||||
show._timer = window.setTimeout(function () {
|
show._timer = window.setTimeout(function () {
|
||||||
state.message = "";
|
state.message = "";
|
||||||
render();
|
render(true);
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -232827,9 +232827,7 @@ function qst({ title: e, icon: t, label: n, sub: i, closeNav: r }) {
|
|||||||
children: [
|
children: [
|
||||||
Q.jsx(Fst, {
|
Q.jsx(Fst, {
|
||||||
asChild: !0,
|
asChild: !0,
|
||||||
children: Q.jsx(Lot, {
|
children: Q.jsx(Lot, { asChild: !0, onClick: (e) => (e.stopPropagation(), e.preventDefault()), children: Q.jsx(Nm, {
|
||||||
asChild: !0,
|
|
||||||
children: Q.jsx(Nm, {
|
|
||||||
variant: a ? "secondary" : "ghost",
|
variant: a ? "secondary" : "ghost",
|
||||||
size: "icon",
|
size: "icon",
|
||||||
className: "h-12 w-12",
|
className: "h-12 w-12",
|
||||||
@@ -235896,9 +235894,7 @@ function vut() {
|
|||||||
o = r.substring(0, 2).toUpperCase();
|
o = r.substring(0, 2).toUpperCase();
|
||||||
return Q.jsxs(Not, {
|
return Q.jsxs(Not, {
|
||||||
children: [
|
children: [
|
||||||
Q.jsx(Lot, {
|
Q.jsx(Lot, { asChild: !0, onClick: (e) => (e.stopPropagation(), e.preventDefault()), children: Q.jsx(Nm, {
|
||||||
asChild: !0,
|
|
||||||
children: Q.jsx(Nm, {
|
|
||||||
variant: "ghost",
|
variant: "ghost",
|
||||||
className: "relative h-8 w-8 rounded-full",
|
className: "relative h-8 w-8 rounded-full",
|
||||||
children: Q.jsxs(fut, {
|
children: Q.jsxs(fut, {
|
||||||
@@ -292882,6 +292878,7 @@ function c5t() {
|
|||||||
v = kv({ resolver: Ov(n), defaultValues: i, mode: "onChange" }),
|
v = kv({ resolver: Ov(n), defaultValues: i, mode: "onChange" }),
|
||||||
b = T_({ control: v.control, name: "protocol_settings" }),
|
b = T_({ control: v.control, name: "protocol_settings" }),
|
||||||
y = H.useRef(new Map()),
|
y = H.useRef(new Map()),
|
||||||
|
T = H.useRef(0),
|
||||||
x = H.useCallback(async () => {
|
x = H.useCallback(async () => {
|
||||||
if (!r) return;
|
if (!r) return;
|
||||||
const [e, t, n] = await Promise.all([eD(), rD(), UL()]);
|
const [e, t, n] = await Promise.all([eD(), rD(), UL()]);
|
||||||
@@ -292899,6 +292896,9 @@ function c5t() {
|
|||||||
(H.useEffect(() => {
|
(H.useEffect(() => {
|
||||||
x();
|
x();
|
||||||
}, [x]),
|
}, [x]),
|
||||||
|
H.useEffect(() => {
|
||||||
|
r && s && (T.current = Date.now());
|
||||||
|
}, [r, s]),
|
||||||
H.useEffect(() => {
|
H.useEffect(() => {
|
||||||
if (s) {
|
if (s) {
|
||||||
const e =
|
const e =
|
||||||
@@ -292939,9 +292939,11 @@ function c5t() {
|
|||||||
),
|
),
|
||||||
E = (e) => {
|
E = (e) => {
|
||||||
if (e) {
|
if (e) {
|
||||||
|
s && (T.current = Date.now());
|
||||||
o(!0);
|
o(!0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (s && Date.now() - T.current < 250) return;
|
||||||
(o(!1), a(null), v.reset(i));
|
(o(!1), a(null), v.reset(i));
|
||||||
};
|
};
|
||||||
return Q.jsxs(Jet, {
|
return Q.jsxs(Jet, {
|
||||||
@@ -293992,9 +293994,7 @@ function h5t({ table: e, refetch: t, saveOrder: n, isSortMode: i, groups: r }) {
|
|||||||
Q.jsxs(Not, {
|
Q.jsxs(Not, {
|
||||||
modal: !1,
|
modal: !1,
|
||||||
children: [
|
children: [
|
||||||
Q.jsx(Lot, {
|
Q.jsx(Lot, { asChild: !0, onClick: (e) => (e.stopPropagation(), e.preventDefault()), children: Q.jsx(Nm, {
|
||||||
asChild: !0,
|
|
||||||
children: Q.jsx(Nm, {
|
|
||||||
variant: "outline",
|
variant: "outline",
|
||||||
size: "sm",
|
size: "sm",
|
||||||
className: "h-8 border-dashed",
|
className: "h-8 border-dashed",
|
||||||
@@ -294097,9 +294097,7 @@ function h5t({ table: e, refetch: t, saveOrder: n, isSortMode: i, groups: r }) {
|
|||||||
Q.jsxs(Not, {
|
Q.jsxs(Not, {
|
||||||
modal: !1,
|
modal: !1,
|
||||||
children: [
|
children: [
|
||||||
Q.jsx(Lot, {
|
Q.jsx(Lot, { asChild: !0, onClick: (e) => (e.stopPropagation(), e.preventDefault()), children: Q.jsx(Nm, {
|
||||||
asChild: !0,
|
|
||||||
children: Q.jsx(Nm, {
|
|
||||||
variant: "outline",
|
variant: "outline",
|
||||||
size: "sm",
|
size: "sm",
|
||||||
className: "h-8 border-dashed",
|
className: "h-8 border-dashed",
|
||||||
@@ -294399,14 +294397,26 @@ function D5t({ node: e, refetch: t }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
function T5t({ node: e, refetch: t, t: n }) {
|
function T5t({ node: e, refetch: t, t: n }) {
|
||||||
const { setIsOpen: i, setEditingServer: r, setServerType: o } = p4t();
|
const { setIsOpen: i, setEditingServer: r, setServerType: o } = p4t(),
|
||||||
|
[s, a] = H.useState(!1),
|
||||||
|
l = H.useCallback(() => {
|
||||||
|
(a(!1),
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
(o(e.type), r(e), i(!0));
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}, [e, i, r, o]);
|
||||||
return Q.jsx("div", {
|
return Q.jsx("div", {
|
||||||
className: "flex justify-center",
|
className: "flex justify-center",
|
||||||
children: Q.jsxs(Not, {
|
children: Q.jsxs(Not, {
|
||||||
modal: !1,
|
modal: !1,
|
||||||
|
open: s,
|
||||||
|
onOpenChange: a,
|
||||||
children: [
|
children: [
|
||||||
Q.jsx(Lot, {
|
Q.jsx(Lot, {
|
||||||
asChild: !0,
|
asChild: !0,
|
||||||
|
onClick: (e) => (e.stopPropagation(), e.preventDefault()),
|
||||||
children: Q.jsx(Nm, {
|
children: Q.jsx(Nm, {
|
||||||
variant: "ghost",
|
variant: "ghost",
|
||||||
className: "h-8 w-8 p-0 hover:bg-muted",
|
className: "h-8 w-8 p-0 hover:bg-muted",
|
||||||
@@ -294420,9 +294430,8 @@ function T5t({ node: e, refetch: t, t: n }) {
|
|||||||
children: [
|
children: [
|
||||||
Q.jsx(Rot, {
|
Q.jsx(Rot, {
|
||||||
className: "cursor-pointer",
|
className: "cursor-pointer",
|
||||||
onSelect: (t) => {
|
onSelect: (e) => {
|
||||||
t.preventDefault();
|
(e.preventDefault(), e.stopPropagation(), l());
|
||||||
(o(e.type), r(e), i(!0));
|
|
||||||
},
|
},
|
||||||
children: Q.jsxs("div", {
|
children: Q.jsxs("div", {
|
||||||
className: "flex w-full items-center",
|
className: "flex w-full items-center",
|
||||||
@@ -302584,9 +302593,7 @@ function P6t({ table: e, refetch: t, subscriptionPlans: n = [] }) {
|
|||||||
Q.jsxs(Not, {
|
Q.jsxs(Not, {
|
||||||
modal: !1,
|
modal: !1,
|
||||||
children: [
|
children: [
|
||||||
Q.jsx(Lot, {
|
Q.jsx(Lot, { asChild: !0, onClick: (e) => (e.stopPropagation(), e.preventDefault()), children: Q.jsx(Nm, {
|
||||||
asChild: !0,
|
|
||||||
children: Q.jsx(Nm, {
|
|
||||||
variant: "outline",
|
variant: "outline",
|
||||||
size: "sm",
|
size: "sm",
|
||||||
className: "h-8 border-dashed",
|
className: "h-8 border-dashed",
|
||||||
|
|||||||
19
scratch/patch_bundle.ps1
Normal file
19
scratch/patch_bundle.ps1
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
$filePath = "d:\Development\SingBox-Gopanel\frontend\admin\reverse\output\index-CO3BwsT2.pretty.js"
|
||||||
|
|
||||||
|
# Read file
|
||||||
|
$content = [System.IO.File]::ReadAllText($filePath)
|
||||||
|
|
||||||
|
# Regex patterns (escaping literals to handle parens and braces correctly)
|
||||||
|
$t1 = [regex]::Escape("Q.jsx(Lot, {") + "\s+" + [regex]::Escape("asChild: !0,") + "\s+" + [regex]::Escape("children: Q.jsx(Nm, {")
|
||||||
|
$r1 = "Q.jsx(Lot, { asChild: !0, onClick: (e) => (e.stopPropagation(), e.preventDefault()), children: Q.jsx(Nm, {"
|
||||||
|
|
||||||
|
$t2 = [regex]::Escape("onSelect: (e) => {") + "\s+" + [regex]::Escape("(e.preventDefault(), l());")
|
||||||
|
$r2 = "onSelect: (e) => { (e.preventDefault(), e.stopPropagation(), l());"
|
||||||
|
|
||||||
|
# Perform replacements
|
||||||
|
$content = [System.Text.RegularExpressions.Regex]::Replace($content, $t1, $r1)
|
||||||
|
$content = [System.Text.RegularExpressions.Regex]::Replace($content, $t2, $r2)
|
||||||
|
|
||||||
|
# Write back
|
||||||
|
[System.IO.File]::WriteAllText($filePath, $content)
|
||||||
|
Write-Output "Patch applied successfully (Regex Escaped)"
|
||||||
Reference in New Issue
Block a user