mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
feat(ui): use mobile memory popup in task monitor
This commit is contained in:
101
style.css
101
style.css
@@ -1438,6 +1438,101 @@
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* ==================== Memory Popup (Mobile) ==================== */
|
||||
|
||||
.bme-memory-popup-scrim {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 999;
|
||||
background: rgba(0, 0, 0, 0.55);
|
||||
backdrop-filter: blur(2px);
|
||||
-webkit-backdrop-filter: blur(2px);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.bme-memory-popup-scrim[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.bme-memory-popup {
|
||||
display: none;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%) scale(0.92);
|
||||
width: min(460px, calc(100vw - 24px));
|
||||
max-height: min(82vh, 680px);
|
||||
background: var(--bme-surface, #131316);
|
||||
border: 1px solid var(--bme-border);
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 12px 48px rgba(0, 0, 0, 0.65);
|
||||
z-index: 1000;
|
||||
overflow-y: auto;
|
||||
padding: 18px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transition: transform 0.18s ease, opacity 0.18s ease, visibility 0.18s ease;
|
||||
}
|
||||
|
||||
.bme-memory-popup.open {
|
||||
display: block;
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.bme-memory-popup__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.bme-memory-popup__title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--bme-on-surface);
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.bme-memory-popup__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.bme-memory-popup__badges {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.bme-memory-popup__body {
|
||||
font-size: 12px;
|
||||
color: var(--bme-on-surface);
|
||||
}
|
||||
|
||||
.bme-memory-popup::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
.bme-memory-popup::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.bme-memory-popup::-webkit-scrollbar-thumb {
|
||||
background: var(--bme-surface-highest);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* ==================== Injection Preview ==================== */
|
||||
|
||||
.bme-injection-token-bar {
|
||||
@@ -7063,11 +7158,11 @@
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid var(--bme-border);
|
||||
max-height: 40vh;
|
||||
border-bottom: none;
|
||||
max-height: none;
|
||||
}
|
||||
.bme-memory-detail-panel {
|
||||
padding: 14px;
|
||||
display: none;
|
||||
}
|
||||
.bme-batch-stages {
|
||||
flex-wrap: wrap;
|
||||
|
||||
@@ -2986,6 +2986,26 @@
|
||||
<div class="bme-task-section" data-task-section="trace" id="bme-task-trace"></div>
|
||||
<div class="bme-task-section" data-task-section="persistence" id="bme-task-persistence"></div>
|
||||
</div>
|
||||
|
||||
<div class="bme-memory-popup-scrim" id="bme-memory-popup-scrim" hidden></div>
|
||||
<div class="bme-memory-popup" id="bme-memory-popup">
|
||||
<div class="bme-memory-popup__header">
|
||||
<h3 class="bme-memory-popup__title" id="bme-memory-popup-title">节点详情</h3>
|
||||
<div class="bme-memory-popup__actions">
|
||||
<button class="bme-detail-action-btn" id="bme-memory-popup-save" type="button" title="保存修改">
|
||||
<i class="fa-solid fa-floppy-disk"></i>
|
||||
</button>
|
||||
<button class="bme-detail-action-btn bme-detail-action-danger" id="bme-memory-popup-delete" type="button" title="删除节点">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
<button class="bme-panel-close" id="bme-memory-popup-close" type="button" title="关闭">
|
||||
<i class="fa-solid fa-xmark"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bme-memory-popup__badges" id="bme-memory-popup-badges"></div>
|
||||
<div class="bme-memory-popup__body" id="bme-memory-popup-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
81
ui/panel.js
81
ui/panel.js
@@ -932,6 +932,7 @@ export async function initPanel({
|
||||
_bindTabs();
|
||||
_bindClose();
|
||||
_bindNodeDetailPanel();
|
||||
_bindMemoryPopup();
|
||||
_bindResizeHandle();
|
||||
_bindPanelResize();
|
||||
_bindGraphControls();
|
||||
@@ -1186,6 +1187,7 @@ export function openPanel() {
|
||||
export function closePanel() {
|
||||
if (!overlayEl) return;
|
||||
overlayEl.classList.remove("active");
|
||||
_closeMemoryPopup();
|
||||
_clearScheduledVisibleGraphRefresh();
|
||||
lastVisibleGraphRefreshToken = "";
|
||||
}
|
||||
@@ -1246,6 +1248,7 @@ function _switchTab(tabId) {
|
||||
}
|
||||
currentTabId = next;
|
||||
_closeNodeDetailUi();
|
||||
_closeMemoryPopup();
|
||||
panelEl?.querySelectorAll(".bme-tab-btn").forEach((btn) => {
|
||||
btn.classList.toggle("active", btn.dataset.tab === currentTabId);
|
||||
});
|
||||
@@ -1352,6 +1355,7 @@ function _bindTaskNavigation() {
|
||||
|
||||
function _switchTaskSection(sectionId) {
|
||||
currentTaskSectionId = sectionId || "pipeline";
|
||||
_closeMemoryPopup();
|
||||
_syncTaskSectionState();
|
||||
_refreshTaskMonitor();
|
||||
}
|
||||
@@ -1758,7 +1762,12 @@ function _bindTaskMemoryListClick() {
|
||||
currentSelectedMemoryNodeId = item.dataset.nodeId || "";
|
||||
list.querySelectorAll(".bme-memory-node-item").forEach((n) => n.classList.toggle("selected", n.dataset.nodeId === currentSelectedMemoryNodeId));
|
||||
const graph = _getGraph?.();
|
||||
_renderTaskMemoryDetailSelection(graph);
|
||||
if (_isMobile()) {
|
||||
const node = (graph?.nodes || []).find((c) => c.id === currentSelectedMemoryNodeId) || null;
|
||||
if (node) _openMemoryPopup(node, graph);
|
||||
} else {
|
||||
_renderTaskMemoryDetailSelection(graph);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1832,20 +1841,31 @@ function _renderTaskMemoryDetailPanel(detailEl, node, graph) {
|
||||
}
|
||||
|
||||
function _saveTaskMemoryDetail() {
|
||||
const detailEl = document.getElementById("bme-task-memory-detail");
|
||||
const bodyEl = detailEl?.querySelector("#bme-task-memory-editor-body");
|
||||
const popupBody = document.getElementById("bme-memory-popup-body");
|
||||
const popupOpen = document.getElementById("bme-memory-popup")?.classList.contains("open");
|
||||
const detailEl = popupOpen ? null : document.getElementById("bme-task-memory-detail");
|
||||
const bodyEl = popupOpen
|
||||
? popupBody
|
||||
: detailEl?.querySelector("#bme-task-memory-editor-body");
|
||||
const nodeId = currentSelectedMemoryNodeId;
|
||||
if (!nodeId || !bodyEl) return;
|
||||
|
||||
const collected = _collectNodeDetailEditorUpdates(bodyEl, {
|
||||
idPrefix: "bme-task-detail",
|
||||
});
|
||||
const idPrefix = popupOpen ? "bme-popup-detail" : "bme-task-detail";
|
||||
const collected = _collectNodeDetailEditorUpdates(bodyEl, { idPrefix });
|
||||
if (!collected.ok) {
|
||||
toastr.error(collected.errorMessage || "保存失败", "ST-BME");
|
||||
return;
|
||||
}
|
||||
|
||||
_persistNodeDetailEdits(nodeId, collected.updates);
|
||||
_persistNodeDetailEdits(nodeId, collected.updates, {
|
||||
afterSuccess: () => {
|
||||
if (popupOpen) {
|
||||
const graph = _getGraph?.();
|
||||
const refreshedNode = (graph?.nodes || []).find((n) => n.id === nodeId);
|
||||
if (refreshedNode) _openMemoryPopup(refreshedNode, graph);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function _deleteTaskMemoryDetail() {
|
||||
@@ -1855,10 +1875,57 @@ function _deleteTaskMemoryDetail() {
|
||||
_deleteGraphNodeById(nodeId, {
|
||||
afterSuccess: () => {
|
||||
currentSelectedMemoryNodeId = "";
|
||||
_closeMemoryPopup();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function _openMemoryPopup(node, graph) {
|
||||
const popup = document.getElementById("bme-memory-popup");
|
||||
const scrim = document.getElementById("bme-memory-popup-scrim");
|
||||
const titleEl = document.getElementById("bme-memory-popup-title");
|
||||
const badgesEl = document.getElementById("bme-memory-popup-badges");
|
||||
const bodyEl = document.getElementById("bme-memory-popup-body");
|
||||
if (!popup || !bodyEl) return;
|
||||
|
||||
const displayName = getNodeDisplayName(node);
|
||||
const scopeBadge = buildScopeBadgeText(node.scope);
|
||||
const badges = [
|
||||
node.type ? `<span class="bme-memory-node-item__type ${_getMemoryNodeTypeClass(node.type)}">${_escHtml(_typeLabel(node.type))}</span>` : "",
|
||||
scopeBadge ? `<span class="bme-memory-node-item__type type-default">${_escHtml(scopeBadge)}</span>` : "",
|
||||
node.archived ? '<span class="bme-memory-node-item__type type-default">ARCHIVED</span>' : "",
|
||||
].filter(Boolean).join("");
|
||||
|
||||
if (titleEl) titleEl.textContent = displayName;
|
||||
if (badgesEl) badgesEl.innerHTML = badges;
|
||||
|
||||
bodyEl.replaceChildren(
|
||||
_buildNodeDetailEditorFragment(node, { idPrefix: "bme-popup-detail" }),
|
||||
);
|
||||
|
||||
scrim?.removeAttribute("hidden");
|
||||
popup.classList.add("open");
|
||||
}
|
||||
|
||||
function _closeMemoryPopup() {
|
||||
const popup = document.getElementById("bme-memory-popup");
|
||||
const scrim = document.getElementById("bme-memory-popup-scrim");
|
||||
popup?.classList.remove("open");
|
||||
scrim?.setAttribute("hidden", "");
|
||||
}
|
||||
|
||||
function _bindMemoryPopup() {
|
||||
const closeBtn = document.getElementById("bme-memory-popup-close");
|
||||
const scrim = document.getElementById("bme-memory-popup-scrim");
|
||||
const saveBtn = document.getElementById("bme-memory-popup-save");
|
||||
const deleteBtn = document.getElementById("bme-memory-popup-delete");
|
||||
|
||||
closeBtn?.addEventListener("click", () => _closeMemoryPopup());
|
||||
scrim?.addEventListener("click", () => _closeMemoryPopup());
|
||||
saveBtn?.addEventListener("click", () => _saveTaskMemoryDetail());
|
||||
deleteBtn?.addEventListener("click", () => _deleteTaskMemoryDetail());
|
||||
}
|
||||
|
||||
// ---------- Injection Preview ----------
|
||||
|
||||
function _refreshTaskInjectionPreview() {
|
||||
|
||||
Reference in New Issue
Block a user