@dong-victor/dsh-better-sidebar-starter 0.1.3 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +158 -143
- package/lib/client.js.map +1 -1
- package/lib/index.js +479 -122
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -143,7 +143,7 @@ window.__ModuleLoader__.load({
|
|
|
143
143
|
"python",
|
|
144
144
|
"custom"
|
|
145
145
|
];
|
|
146
|
-
const TYPE_LABELS$
|
|
146
|
+
const TYPE_LABELS$1 = {
|
|
147
147
|
npm: "npm",
|
|
148
148
|
springboot: "Spring Boot",
|
|
149
149
|
python: "Python",
|
|
@@ -187,7 +187,7 @@ window.__ModuleLoader__.load({
|
|
|
187
187
|
if (configs.length === 0) return (0, react.createElement)("div", { className: "sts-empty" }, "暂无运行配置", (0, react.createElement)("br"), "点击右上角 + 新建配置");
|
|
188
188
|
return (0, react.createElement)("div", { className: "sts-tree" }, ...groups.map((group) => {
|
|
189
189
|
const isCollapsed = collapsed.has(group.type);
|
|
190
|
-
const label = TYPE_LABELS$
|
|
190
|
+
const label = TYPE_LABELS$1[group.type] ?? group.type;
|
|
191
191
|
const runningCount = instances.filter((inst) => inst.configType === group.type && inst.status === "running").length;
|
|
192
192
|
return (0, react.createElement)("div", { key: group.type }, (0, react.createElement)("div", {
|
|
193
193
|
className: "sts-group-header",
|
|
@@ -628,42 +628,105 @@ window.__ModuleLoader__.load({
|
|
|
628
628
|
/** Render ANSI-colored text segments, applying Java-log syntax highlighting
|
|
629
629
|
* to text the program did not color itself (ANSI-colored spans keep the
|
|
630
630
|
* program's own colors). Tokens with a source link become clickable. */
|
|
631
|
+
/** Split plain text into plain/url parts. Trailing punctuation that is
|
|
632
|
+
* almost certainly sentence text (.,;:)])。,) stays outside the link. */
|
|
633
|
+
const URL_RE = /https?:\/\/[^\s"'<>()\[\]{}]+/g;
|
|
634
|
+
function splitUrlParts(text) {
|
|
635
|
+
const out = [];
|
|
636
|
+
let last = 0;
|
|
637
|
+
for (const m of text.matchAll(URL_RE)) {
|
|
638
|
+
const idx = m.index ?? 0;
|
|
639
|
+
if (idx > last) out.push({ text: text.slice(last, idx) });
|
|
640
|
+
let url = m[0];
|
|
641
|
+
let trail = "";
|
|
642
|
+
while (url.length > 0 && /[.,;:)\]}》」),。;:]$/.test(url)) {
|
|
643
|
+
trail = url.slice(-1) + trail;
|
|
644
|
+
url = url.slice(0, -1);
|
|
645
|
+
}
|
|
646
|
+
if (url !== "") out.push({
|
|
647
|
+
text: url,
|
|
648
|
+
url
|
|
649
|
+
});
|
|
650
|
+
if (trail !== "") out.push({ text: trail });
|
|
651
|
+
last = idx + m[0].length;
|
|
652
|
+
}
|
|
653
|
+
if (last < text.length) out.push({ text: text.slice(last) });
|
|
654
|
+
return out;
|
|
655
|
+
}
|
|
631
656
|
function renderAnsiLine(text, keyBase, onLinkClick) {
|
|
632
657
|
const segments = parseAnsi(text);
|
|
633
658
|
const nodes = [];
|
|
659
|
+
if (segments.length === 0) return nodes;
|
|
634
660
|
let hlCounter = 0;
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
661
|
+
let fullText = "";
|
|
662
|
+
const ranges = [];
|
|
663
|
+
for (const seg of segments) {
|
|
664
|
+
ranges.push({
|
|
665
|
+
seg,
|
|
666
|
+
start: fullText.length,
|
|
667
|
+
end: fullText.length + seg.text.length
|
|
668
|
+
});
|
|
669
|
+
fullText += seg.text;
|
|
670
|
+
}
|
|
671
|
+
const parts = splitUrlParts(fullText);
|
|
672
|
+
let offset = 0;
|
|
673
|
+
for (const part of parts) {
|
|
674
|
+
const pStart = offset;
|
|
675
|
+
const pEnd = offset + part.text.length;
|
|
676
|
+
offset = pEnd;
|
|
677
|
+
for (const r of ranges) {
|
|
678
|
+
const s = Math.max(r.start, pStart);
|
|
679
|
+
const e = Math.min(r.end, pEnd);
|
|
680
|
+
if (s >= e) continue;
|
|
681
|
+
const slice = fullText.slice(s, e);
|
|
682
|
+
const seg = r.seg;
|
|
683
|
+
const style = {};
|
|
684
|
+
if (seg.bold) style.fontWeight = "bold";
|
|
685
|
+
if (seg.dim) style.opacity = "0.6";
|
|
686
|
+
if (seg.italic) style.fontStyle = "italic";
|
|
687
|
+
if (seg.underline) style.textDecoration = "underline";
|
|
688
|
+
const fg = segmentFgColor(seg);
|
|
689
|
+
const bg = segmentBgColor(seg);
|
|
646
690
|
if (fg !== null) style.color = fg;
|
|
647
691
|
if (bg !== null) style.backgroundColor = bg;
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
style
|
|
651
|
-
}, seg.text));
|
|
652
|
-
} else {
|
|
653
|
-
const hl = highlightLogText(seg.text);
|
|
654
|
-
for (const h of hl) {
|
|
655
|
-
const style = { ...baseStyle };
|
|
656
|
-
if (h.color !== void 0) style.color = h.color;
|
|
657
|
-
if (h.bold === true) style.fontWeight = "bold";
|
|
692
|
+
if (part.url !== void 0) {
|
|
693
|
+
const url = part.url;
|
|
658
694
|
nodes.push((0, react.createElement)("span", {
|
|
659
|
-
key: `${keyBase}
|
|
660
|
-
className:
|
|
661
|
-
style
|
|
662
|
-
|
|
695
|
+
key: `${keyBase}-u${hlCounter++}`,
|
|
696
|
+
className: "sts-log-url",
|
|
697
|
+
style: {
|
|
698
|
+
...style,
|
|
699
|
+
textDecoration: "underline",
|
|
700
|
+
cursor: "pointer"
|
|
701
|
+
},
|
|
702
|
+
title: `在浏览器打开 ${url}`,
|
|
703
|
+
onClick: (e) => {
|
|
663
704
|
e.stopPropagation();
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
705
|
+
try {
|
|
706
|
+
window.open(url, "_blank", "noopener");
|
|
707
|
+
} catch {}
|
|
708
|
+
}
|
|
709
|
+
}, slice));
|
|
710
|
+
} else if (fg !== null || bg !== null) nodes.push((0, react.createElement)("span", {
|
|
711
|
+
key: `${keyBase}-c${hlCounter++}`,
|
|
712
|
+
style
|
|
713
|
+
}, slice));
|
|
714
|
+
else {
|
|
715
|
+
const hl = highlightLogText(slice);
|
|
716
|
+
for (const h of hl) {
|
|
717
|
+
const hStyle = { ...style };
|
|
718
|
+
if (h.color !== void 0) hStyle.color = h.color;
|
|
719
|
+
if (h.bold === true) hStyle.fontWeight = "bold";
|
|
720
|
+
nodes.push((0, react.createElement)("span", {
|
|
721
|
+
key: `${keyBase}-hl${hlCounter++}`,
|
|
722
|
+
className: h.link !== void 0 ? "sts-log-link" : void 0,
|
|
723
|
+
style: hStyle,
|
|
724
|
+
onClick: h.link !== void 0 ? (e) => {
|
|
725
|
+
e.stopPropagation();
|
|
726
|
+
onLinkClick(h.link);
|
|
727
|
+
} : void 0
|
|
728
|
+
}, h.text));
|
|
729
|
+
}
|
|
667
730
|
}
|
|
668
731
|
}
|
|
669
732
|
}
|
|
@@ -870,7 +933,7 @@ window.__ModuleLoader__.load({
|
|
|
870
933
|
if (parts.length > 1 && parts[parts.length - 1] === "") pushLine();
|
|
871
934
|
}
|
|
872
935
|
/** The log history viewer. */
|
|
873
|
-
function LogHistoryView({ ctx, sessionId, cwd, onClose }) {
|
|
936
|
+
function LogHistoryView({ ctx, sessionId, cwd, onClose, filter }) {
|
|
874
937
|
const [files, setFiles] = (0, react.useState)(null);
|
|
875
938
|
const [loading, setLoading] = (0, react.useState)(false);
|
|
876
939
|
const [activeFile, setActiveFile] = (0, react.useState)(null);
|
|
@@ -884,7 +947,7 @@ window.__ModuleLoader__.load({
|
|
|
884
947
|
if (cwd !== void 0 && cwd !== "") params.set("cwd", cwd);
|
|
885
948
|
const resp = await fetch(`${API_BASE$1}/logs-history?${params.toString()}`);
|
|
886
949
|
if (!resp.ok) {
|
|
887
|
-
let reason = "加载历史日志失败";
|
|
950
|
+
let reason = filter !== void 0 ? "加载历史日志失败" : "加载历史日志失败";
|
|
888
951
|
try {
|
|
889
952
|
const err = await resp.json();
|
|
890
953
|
if (typeof err.error === "string" && err.error !== "") reason = err.error;
|
|
@@ -893,15 +956,20 @@ window.__ModuleLoader__.load({
|
|
|
893
956
|
setFiles([]);
|
|
894
957
|
return;
|
|
895
958
|
}
|
|
896
|
-
const
|
|
897
|
-
|
|
959
|
+
const all = (await resp.json()).logs ?? [];
|
|
960
|
+
const shown = filter !== void 0 ? all.filter((f) => f.name.startsWith(filter)) : all;
|
|
961
|
+
setFiles(shown);
|
|
898
962
|
} catch {
|
|
899
963
|
showToast("加载历史日志失败", false);
|
|
900
964
|
setFiles([]);
|
|
901
965
|
} finally {
|
|
902
966
|
setLoading(false);
|
|
903
967
|
}
|
|
904
|
-
}, [
|
|
968
|
+
}, [
|
|
969
|
+
sessionId,
|
|
970
|
+
cwd,
|
|
971
|
+
filter
|
|
972
|
+
]);
|
|
905
973
|
const [initialized, setInitialized] = (0, react.useState)(false);
|
|
906
974
|
if (!initialized) {
|
|
907
975
|
setInitialized(true);
|
|
@@ -941,40 +1009,43 @@ window.__ModuleLoader__.load({
|
|
|
941
1009
|
setLoading(false);
|
|
942
1010
|
}
|
|
943
1011
|
}, [sessionId, cwd]);
|
|
944
|
-
if (activeFile === null)
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
title: "
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
className: "sts-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1012
|
+
if (activeFile === null) {
|
|
1013
|
+
const title = filter !== void 0 ? `${filter} · 历史日志` : "历史日志";
|
|
1014
|
+
return (0, react.createElement)("div", { style: {
|
|
1015
|
+
display: "flex",
|
|
1016
|
+
flexDirection: "column",
|
|
1017
|
+
height: "100%",
|
|
1018
|
+
minHeight: 0
|
|
1019
|
+
} }, (0, react.createElement)("div", { className: "sts-log-toolbar" }, title, (0, react.createElement)("div", { className: "sts-log-toolbar-spacer" }), (0, react.createElement)("button", {
|
|
1020
|
+
className: "sts-icon-btn",
|
|
1021
|
+
title: "刷新",
|
|
1022
|
+
onClick: () => {
|
|
1023
|
+
loadList();
|
|
1024
|
+
}
|
|
1025
|
+
}, RefreshIcon({ size: 14 }), (0, react.createElement)("span", { className: "sts-icon-btn-label" }, "刷新")), (0, react.createElement)("button", {
|
|
1026
|
+
className: "sts-icon-btn",
|
|
1027
|
+
title: filter !== void 0 ? "返回服务视图" : "关闭历史日志",
|
|
1028
|
+
onClick: onClose
|
|
1029
|
+
}, CloseIcon({ size: 14 }), (0, react.createElement)("span", { className: "sts-icon-btn-label" }, filter !== void 0 ? "返回" : "关闭"))), (0, react.createElement)("div", { style: {
|
|
1030
|
+
overflow: "auto",
|
|
1031
|
+
flex: 1,
|
|
1032
|
+
minHeight: 0,
|
|
1033
|
+
padding: "4px 0"
|
|
1034
|
+
} }, loading && files === null ? (0, react.createElement)("div", { className: "sts-empty" }, "加载中…") : files !== null && files.length === 0 ? (0, react.createElement)("div", { className: "sts-empty" }, filter !== void 0 ? `「${filter}」暂无历史日志。每次启动都会在 <工作空间>/logs/ 下永久保留一份日志,即使启动失败或 dsh 重启也能查看。` : "暂无历史日志(工作空间 logs/ 为空)。每次启动服务都会在 <工作空间>/logs/ 下永久保留一份日志,即使启动失败或 dsh 重启也能查看。") : (0, react.createElement)("div", {}, (files ?? []).map((f) => (0, react.createElement)("button", {
|
|
1035
|
+
key: f.file,
|
|
1036
|
+
className: "sts-history-item",
|
|
1037
|
+
title: f.file,
|
|
1038
|
+
onClick: () => {
|
|
1039
|
+
openFile(f);
|
|
1040
|
+
}
|
|
1041
|
+
}, (0, react.createElement)(FileIcon, { size: 13 }), (0, react.createElement)("span", { style: {
|
|
1042
|
+
flex: 1,
|
|
1043
|
+
textAlign: "left",
|
|
1044
|
+
overflow: "hidden",
|
|
1045
|
+
textOverflow: "ellipsis",
|
|
1046
|
+
whiteSpace: "nowrap"
|
|
1047
|
+
} }, f.name), (0, react.createElement)("span", { className: "sts-history-item-meta" }, `${new Date(f.mtime).toLocaleString()} ${(f.size / 1024).toFixed(1)} KB`))))));
|
|
1048
|
+
}
|
|
978
1049
|
return (0, react.createElement)("div", { style: {
|
|
979
1050
|
display: "flex",
|
|
980
1051
|
flexDirection: "column",
|
|
@@ -1009,53 +1080,6 @@ window.__ModuleLoader__.load({
|
|
|
1009
1080
|
}, `—— 历史日志已加载完毕(${lines.length} 行),此为只读视图 ——`)));
|
|
1010
1081
|
}
|
|
1011
1082
|
//#endregion
|
|
1012
|
-
//#region src/client/ConfigDetail.tsx
|
|
1013
|
-
/**
|
|
1014
|
-
* Config detail card: shown in the right pane when an idle config is selected.
|
|
1015
|
-
* Displays the config's full info and offers start / edit / delete buttons.
|
|
1016
|
-
* @module dsh-better-sidebar-starter/client/ConfigDetail
|
|
1017
|
-
*/
|
|
1018
|
-
const TYPE_LABELS$1 = {
|
|
1019
|
-
npm: "npm",
|
|
1020
|
-
springboot: "Spring Boot",
|
|
1021
|
-
python: "Python",
|
|
1022
|
-
custom: "Custom"
|
|
1023
|
-
};
|
|
1024
|
-
/** The detail card component. */
|
|
1025
|
-
function ConfigDetail({ config, onStart, onEdit, onDuplicate, onDelete }) {
|
|
1026
|
-
const envEntries = Object.entries(config.env);
|
|
1027
|
-
const dateFmt = (ts) => {
|
|
1028
|
-
if (ts === null) return "—";
|
|
1029
|
-
return new Date(ts).toLocaleString("zh-CN", { hour12: false });
|
|
1030
|
-
};
|
|
1031
|
-
return (0, react.createElement)("div", { className: "sts-detail" }, (0, react.createElement)("div", { className: "sts-detail-card" }, (0, react.createElement)("div", { className: "sts-detail-title" }, typeIcon(config.type, 20), config.name), (0, react.createElement)("div", { className: "sts-detail-row" }, (0, react.createElement)("div", { className: "sts-detail-label" }, "类型"), (0, react.createElement)("div", { className: "sts-detail-value" }, TYPE_LABELS$1[config.type] ?? config.type)), (0, react.createElement)("div", { className: "sts-detail-row" }, (0, react.createElement)("div", { className: "sts-detail-label" }, "命令"), (0, react.createElement)("div", { className: "sts-detail-value" }, config.command)), (0, react.createElement)("div", { className: "sts-detail-row" }, (0, react.createElement)("div", { className: "sts-detail-label" }, "工作目录"), (0, react.createElement)("div", { className: "sts-detail-value" }, config.cwd)), config.type === "springboot" && config.jvmArgs ? (0, react.createElement)("div", { className: "sts-detail-row" }, (0, react.createElement)("div", { className: "sts-detail-label" }, "JVM参数"), (0, react.createElement)("div", { className: "sts-detail-value" }, config.jvmArgs)) : null, config.args ? (0, react.createElement)("div", { className: "sts-detail-row" }, (0, react.createElement)("div", { className: "sts-detail-label" }, "程序实参"), (0, react.createElement)("div", { className: "sts-detail-value" }, config.args)) : null, envEntries.length > 0 ? (0, react.createElement)("div", { className: "sts-detail-row" }, (0, react.createElement)("div", { className: "sts-detail-label" }, "环境变量"), (0, react.createElement)("div", { style: { flex: 1 } }, ...envEntries.map(([key, value]) => (0, react.createElement)("div", {
|
|
1032
|
-
key,
|
|
1033
|
-
className: "sts-detail-value"
|
|
1034
|
-
}, `${key} = ${value}`)))) : null, (0, react.createElement)("div", { className: "sts-detail-row" }, (0, react.createElement)("div", { className: "sts-detail-label" }, "创建时间"), (0, react.createElement)("div", { className: "sts-detail-value" }, dateFmt(config.createdAt))), config.lastRunAt !== null ? (0, react.createElement)("div", { className: "sts-detail-row" }, (0, react.createElement)("div", { className: "sts-detail-label" }, "最近运行"), (0, react.createElement)("div", { className: "sts-detail-value" }, dateFmt(config.lastRunAt))) : null, (0, react.createElement)("div", { className: "sts-detail-actions" }, (0, react.createElement)("button", {
|
|
1035
|
-
className: "sts-detail-btn danger",
|
|
1036
|
-
onClick: onDelete
|
|
1037
|
-
}, (0, react.createElement)(TrashIcon, { size: 14 }), " 删除"), (0, react.createElement)("button", {
|
|
1038
|
-
className: "sts-detail-btn",
|
|
1039
|
-
onClick: onDuplicate,
|
|
1040
|
-
title: "复制为副本(保留全部信息)"
|
|
1041
|
-
}, (0, react.createElement)(CopyIcon, { size: 14 }), " 复制"), (0, react.createElement)("button", {
|
|
1042
|
-
className: "sts-detail-btn",
|
|
1043
|
-
onClick: onEdit
|
|
1044
|
-
}, (0, react.createElement)(GearIcon, { size: 14 }), " 编辑"), (0, react.createElement)("button", {
|
|
1045
|
-
className: "sts-detail-btn primary",
|
|
1046
|
-
onClick: onStart,
|
|
1047
|
-
style: {
|
|
1048
|
-
background: "#1a1a1e",
|
|
1049
|
-
border: "1px solid #3a3a3e",
|
|
1050
|
-
color: "#fff",
|
|
1051
|
-
borderRadius: "6px",
|
|
1052
|
-
padding: "6px 14px",
|
|
1053
|
-
cursor: "pointer",
|
|
1054
|
-
fontSize: "12px"
|
|
1055
|
-
}
|
|
1056
|
-
}, (0, react.createElement)(PlayIcon, { size: 14 }), " 启动"))));
|
|
1057
|
-
}
|
|
1058
|
-
//#endregion
|
|
1059
1083
|
//#region src/client/DirChooser.tsx
|
|
1060
1084
|
/**
|
|
1061
1085
|
* Shared directory chooser: a filesystem folder tree (backed by the sidebar
|
|
@@ -2021,6 +2045,13 @@ window.__ModuleLoader__.load({
|
|
|
2021
2045
|
background: rgba(97, 175, 239, 0.14);
|
|
2022
2046
|
border-bottom-color: #61afef;
|
|
2023
2047
|
}
|
|
2048
|
+
/* Clickable http(s) URLs inside the log (open in a new browser tab). */
|
|
2049
|
+
.sts-log-url {
|
|
2050
|
+
color: #61afef;
|
|
2051
|
+
}
|
|
2052
|
+
.sts-log-url:hover {
|
|
2053
|
+
background: rgba(97, 175, 239, 0.18);
|
|
2054
|
+
}
|
|
2024
2055
|
|
|
2025
2056
|
/* ===== Config detail ===== */
|
|
2026
2057
|
.sts-detail {
|
|
@@ -2646,7 +2677,6 @@ window.__ModuleLoader__.load({
|
|
|
2646
2677
|
const [splitRatio, setSplitRatio] = (0, react.useState)(.33);
|
|
2647
2678
|
const [dragging, setDragging] = (0, react.useState)(false);
|
|
2648
2679
|
const [isHorizontal, setIsHorizontal] = (0, react.useState)(true);
|
|
2649
|
-
const [historyOpen, setHistoryOpen] = (0, react.useState)(false);
|
|
2650
2680
|
const containerRef = (0, react.useRef)(null);
|
|
2651
2681
|
(0, react.useEffect)(() => {
|
|
2652
2682
|
const el = containerRef.current;
|
|
@@ -2821,8 +2851,7 @@ window.__ModuleLoader__.load({
|
|
|
2821
2851
|
}
|
|
2822
2852
|
} catch {}
|
|
2823
2853
|
}, [sessionQuery, fetchConfigs]);
|
|
2824
|
-
|
|
2825
|
-
const handleDeleteConfig = (0, react.useCallback)(async (configId) => {
|
|
2854
|
+
(0, react.useCallback)(async (configId) => {
|
|
2826
2855
|
for (const inst of instances) if (inst.configId === configId && inst.status === "running") await handleStop(inst.id);
|
|
2827
2856
|
try {
|
|
2828
2857
|
if ((await fetch(`${API_BASE}/configs?${sessionQuery()}&id=${encodeURIComponent(configId)}`, { method: "DELETE" })).ok) {
|
|
@@ -2883,14 +2912,7 @@ window.__ModuleLoader__.load({
|
|
|
2883
2912
|
}, (0, react.createElement)("div", { className: "sts-toolbar" }, (0, react.createElement)("div", { className: "sts-toolbar-title" }, (0, react.createElement)(RocketIcon, { size: 16 }), "服务"), (0, react.createElement)("button", {
|
|
2884
2913
|
className: "sts-toolbar-btn",
|
|
2885
2914
|
onClick: handleNewConfig
|
|
2886
|
-
}, (0, react.createElement)(PlusIcon, { size: 13 }), "新建配置"), (0, react.createElement)("
|
|
2887
|
-
className: `sts-toolbar-btn${historyOpen ? " active" : ""}`,
|
|
2888
|
-
title: "查看持久化历史日志(.dsh/logs,含启动失败记录)",
|
|
2889
|
-
onClick: () => {
|
|
2890
|
-
setHistoryOpen((v) => !v);
|
|
2891
|
-
if (historyOpen) {}
|
|
2892
|
-
}
|
|
2893
|
-
}, (0, react.createElement)(FileIcon, { size: 13 }), "历史日志")), (0, react.createElement)("div", { className: `sts-split${isHorizontal ? "" : " sts-split-vertical"}` }, (0, react.createElement)("div", {
|
|
2915
|
+
}, (0, react.createElement)(PlusIcon, { size: 13 }), "新建配置")), (0, react.createElement)("div", { className: `sts-split${isHorizontal ? "" : " sts-split-vertical"}` }, (0, react.createElement)("div", {
|
|
2894
2916
|
className: `sts-split-first${isHorizontal ? "" : " sts-split-first-v"}`,
|
|
2895
2917
|
style: isHorizontal ? { width: `${splitRatio * 100}%` } : { height: `${splitRatio * 100}%` }
|
|
2896
2918
|
}, configs.length === 0 ? (0, react.createElement)("div", { className: "sts-empty" }, "暂无运行配置,点击右上角 + 新建") : (0, react.createElement)(ConfigTree, {
|
|
@@ -2911,12 +2933,7 @@ window.__ModuleLoader__.load({
|
|
|
2911
2933
|
})), (0, react.createElement)("div", {
|
|
2912
2934
|
className: `sts-split-gutter${dragging ? " dragging" : ""}${isHorizontal ? "" : " sts-split-gutter-v"}`,
|
|
2913
2935
|
onMouseDown: handleMouseDown
|
|
2914
|
-
}), (0, react.createElement)("div", { className: `sts-split-second${isHorizontal ? "" : " sts-split-second-v"}` },
|
|
2915
|
-
ctx: props.ctx,
|
|
2916
|
-
sessionId: scope.sessionId ?? store.getSnapshot().sessionId ?? "",
|
|
2917
|
-
cwd: scope.cwd,
|
|
2918
|
-
onClose: () => setHistoryOpen(false)
|
|
2919
|
-
}) : selectedInstance !== null ? (0, react.createElement)(LogView, {
|
|
2936
|
+
}), (0, react.createElement)("div", { className: `sts-split-second${isHorizontal ? "" : " sts-split-second-v"}` }, selectedInstance !== null ? (0, react.createElement)(LogView, {
|
|
2920
2937
|
instance: selectedInstance,
|
|
2921
2938
|
ctx: props.ctx,
|
|
2922
2939
|
sessionId: scope.sessionId ?? store.getSnapshot().sessionId ?? "",
|
|
@@ -2927,17 +2944,15 @@ window.__ModuleLoader__.load({
|
|
|
2927
2944
|
onRestart: () => {
|
|
2928
2945
|
handleRestart(selectedInstance.id);
|
|
2929
2946
|
}
|
|
2930
|
-
}) : selectedConfig !== null ? (0, react.createElement)(
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
onDelete: () => {
|
|
2938
|
-
handleDeleteConfig(selectedConfig.id);
|
|
2947
|
+
}) : selectedConfig !== null ? (0, react.createElement)(LogHistoryView, {
|
|
2948
|
+
ctx: props.ctx,
|
|
2949
|
+
sessionId: scope.sessionId ?? store.getSnapshot().sessionId ?? "",
|
|
2950
|
+
cwd: scope.cwd,
|
|
2951
|
+
filter: selectedConfig.name,
|
|
2952
|
+
onClose: () => {
|
|
2953
|
+
setSelectedConfigId(null);
|
|
2939
2954
|
}
|
|
2940
|
-
}) : (0, react.createElement)("div", { className: "sts-empty" }, "
|
|
2955
|
+
}) : (0, react.createElement)("div", { className: "sts-empty" }, "选择左侧配置查看其历史日志,或选择运行中的服务查看实时日志"))), showModal ? (0, react.createElement)(ConfigEditorModal, {
|
|
2941
2956
|
config: editingConfig,
|
|
2942
2957
|
scope: {
|
|
2943
2958
|
sessionId: scope.sessionId ?? store.getSnapshot().sessionId ?? "",
|