@dong-victor/dsh-better-sidebar-starter 0.1.8 → 0.1.10

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 CHANGED
@@ -108,6 +108,14 @@ window.__ModuleLoader__.load({
108
108
  function FolderIcon({ size }) {
109
109
  return svg(size, `<path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z" fill="currentColor" opacity="0.7"/>`);
110
110
  }
111
+ /** 👁 Eye — hidden entries are shown (Material visibility). */
112
+ function EyeIcon({ size }) {
113
+ return svg(size, `<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="currentColor"/>`);
114
+ }
115
+ /** 🙈 Eye off — hidden entries are concealed (Material visibility_off). */
116
+ function EyeOffIcon({ size }) {
117
+ return svg(size, `<path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z" fill="currentColor"/>`);
118
+ }
111
119
  /** 📋 Clipboard — bulk paste env. */
112
120
  function ClipboardIcon({ size }) {
113
121
  return svg(size, `<path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm2 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z" fill="currentColor"/>`);
@@ -1089,29 +1097,34 @@ window.__ModuleLoader__.load({
1089
1097
  //#endregion
1090
1098
  //#region src/client/DirChooser.tsx
1091
1099
  /**
1092
- * Shared directory chooser: a filesystem folder tree (backed by the sidebar
1093
- * fs.tree API, which can list any absolute path) plus a browse button that
1094
- * opens a modal popup. Browsing starts at the user's home directory and can
1095
- * navigate up to any drive/root, so runtime tool paths (JDK/Maven/...) that
1096
- * live outside the workspace can be selected.
1100
+ * Shared directory chooser: a filesystem folder tree (backed by the starter
1101
+ * plugin's own fs-dirs host route) plus a browse button that opens a modal
1102
+ * popup. Browsing starts at the user's home directory and can navigate up to
1103
+ * any drive/root, so runtime tool paths (JDK/Maven/...) that live outside the
1104
+ * workspace can be selected. The sidebar fs.tree API cannot be used here — it
1105
+ * is workspace-confined since dsh-better-sidebar 0.16 (403 outside the
1106
+ * session workspace).
1097
1107
  * @module dsh-better-sidebar-starter/client/DirChooser
1098
1108
  */
1099
- /** Call the sidebar fs.tree API directly via fetch. Returns directories only. */
1100
- async function fsTree$1(scope, path) {
1101
- const payload = {
1102
- sessionId: scope.sessionId,
1103
- path
1104
- };
1105
- if (scope.cwd !== void 0 && scope.cwd !== "") payload.cwd = scope.cwd;
1106
- const resp = await fetch("/sidebar/api/fs.tree", {
1109
+ /** Call the starter fs-dirs host route via fetch. Returns directories only,
1110
+ * INCLUDING hidden ones (flagged via `hidden`) — visibility is decided at
1111
+ * render time so the show-hidden toggle works without refetching. */
1112
+ async function fsTree(scope, path) {
1113
+ const resp = await fetch("/api/dsh-better-sidebar-starter/fs-dirs", {
1107
1114
  method: "POST",
1108
1115
  headers: { "content-type": "application/json" },
1109
- body: JSON.stringify(payload)
1116
+ body: JSON.stringify({
1117
+ sessionId: scope.sessionId,
1118
+ path
1119
+ })
1110
1120
  });
1111
- if (!resp.ok) throw new Error(`fs.tree ${path}: ${resp.status}`);
1112
- const parsed = await resp.json();
1113
- if (!parsed.ok || parsed.value === void 0) throw new Error(`fs.tree ${path}: ${parsed.error?.message ?? "unknown error"}`);
1114
- return parsed.value.entries.filter((e) => e.isDir && !e.hidden);
1121
+ const parsed = await resp.json().catch(() => void 0);
1122
+ if (!resp.ok) throw new Error(`fs-dirs ${path}: ${parsed?.error ?? resp.status}`);
1123
+ return (parsed?.entries ?? []).filter((e) => e.isDir);
1124
+ }
1125
+ /** Render-time hidden-entry filter shared by the tree components. */
1126
+ function visibleDirs(entries, showHidden) {
1127
+ return showHidden ? entries : entries.filter((e) => !e.hidden);
1115
1128
  }
1116
1129
  /** Fetch the user's home directory from the host. Falls back to cwd. */
1117
1130
  async function fetchHomeDefault(scope) {
@@ -1139,6 +1152,7 @@ window.__ModuleLoader__.load({
1139
1152
  const [loading, setLoading] = (0, react.useState)(false);
1140
1153
  const [error, setError] = (0, react.useState)(null);
1141
1154
  const [expanded, setExpanded] = (0, react.useState)(/* @__PURE__ */ new Set());
1155
+ const [showHidden, setShowHidden] = (0, react.useState)(false);
1142
1156
  const scopeRef = (0, react.useRef)(scope);
1143
1157
  const initDoneRef = (0, react.useRef)(false);
1144
1158
  const initialValueRef = (0, react.useRef)(selectedPath);
@@ -1163,7 +1177,7 @@ window.__ModuleLoader__.load({
1163
1177
  const loadDir = (s, path) => {
1164
1178
  setLoading(true);
1165
1179
  setError(null);
1166
- fsTree$1(s, path).then((dirs) => {
1180
+ fsTree(s, path).then((dirs) => {
1167
1181
  setEntries(dirs);
1168
1182
  setLoading(false);
1169
1183
  }).catch((err) => {
@@ -1200,7 +1214,15 @@ window.__ModuleLoader__.load({
1200
1214
  className: "sts-dirtree-home",
1201
1215
  onClick: () => loadDir(scopeRef.current, cur),
1202
1216
  title: "刷新"
1203
- }, "↻"), (0, react.createElement)("span", {
1217
+ }, "↻"), (0, react.createElement)("button", {
1218
+ className: "sts-dirtree-home",
1219
+ onClick: () => setShowHidden(!showHidden),
1220
+ title: showHidden ? "隐藏隐藏目录" : "显示隐藏目录",
1221
+ style: showHidden ? {
1222
+ color: "#61afef",
1223
+ opacity: 1
1224
+ } : { opacity: .6 }
1225
+ }, (0, react.createElement)(showHidden ? EyeIcon : EyeOffIcon, { size: 13 })), (0, react.createElement)("span", {
1204
1226
  className: "sts-dirtree-cur",
1205
1227
  title: cur
1206
1228
  }, cur || "(.)")), (0, react.createElement)("div", {
@@ -1213,13 +1235,14 @@ window.__ModuleLoader__.load({
1213
1235
  }, "加载中...") : error !== null ? (0, react.createElement)("div", {
1214
1236
  className: "sts-tree-error",
1215
1237
  style: { paddingLeft: "16px" }
1216
- }, error) : entries !== null && entries.length > 0 ? (0, react.createElement)("div", { className: "sts-dirtree-sub" }, ...entries.map((entry) => (0, react.createElement)(DirRow, {
1238
+ }, error) : entries !== null && visibleDirs(entries, showHidden).length > 0 ? (0, react.createElement)("div", { className: "sts-dirtree-sub" }, ...visibleDirs(entries, showHidden).map((entry) => (0, react.createElement)(DirRow, {
1217
1239
  key: entry.path,
1218
1240
  scope,
1219
1241
  entry,
1220
1242
  depth: 1,
1221
1243
  selectedPath,
1222
1244
  expanded,
1245
+ showHidden,
1223
1246
  onToggleExpand: toggleExpand,
1224
1247
  onPick,
1225
1248
  onNavigate: navigateInto
@@ -1230,7 +1253,7 @@ window.__ModuleLoader__.load({
1230
1253
  }
1231
1254
  /** One directory row with recursive expansion + click into. */
1232
1255
  function DirRow(props) {
1233
- const { scope, entry, depth, selectedPath, expanded, onToggleExpand, onPick, onNavigate } = props;
1256
+ const { scope, entry, depth, selectedPath, expanded, showHidden, onToggleExpand, onPick, onNavigate } = props;
1234
1257
  const [children, setChildren] = (0, react.useState)(null);
1235
1258
  const [loading, setLoading] = (0, react.useState)(false);
1236
1259
  const isExpanded = expanded.has(entry.path);
@@ -1244,7 +1267,7 @@ window.__ModuleLoader__.load({
1244
1267
  onToggleExpand(entry.path);
1245
1268
  if (children === null) {
1246
1269
  setLoading(true);
1247
- fsTree$1(scope, entry.path).then((dirs) => {
1270
+ fsTree(scope, entry.path).then((dirs) => {
1248
1271
  setChildren(dirs);
1249
1272
  setLoading(false);
1250
1273
  }).catch(() => {
@@ -1260,13 +1283,14 @@ window.__ModuleLoader__.load({
1260
1283
  }, (0, react.createElement)("span", { className: `sts-tree-chevron${isExpanded ? " expanded" : ""}` }, (0, react.createElement)(isExpanded ? ChevronDownIcon : ChevronRightIcon, { size: 12 })), (0, react.createElement)("span", { className: "sts-tree-icon" }, (0, react.createElement)(FolderIcon, { size: 14 })), (0, react.createElement)("span", { className: "sts-tree-label" }, entry.name)), isExpanded ? loading ? (0, react.createElement)("div", {
1261
1284
  className: "sts-tree-loading",
1262
1285
  style: { paddingLeft: `${(depth + 1) * 16 + 8}px` }
1263
- }, "加载中...") : children !== null && children.length > 0 ? (0, react.createElement)("div", null, ...children.map((child) => (0, react.createElement)(DirRow, {
1286
+ }, "加载中...") : children !== null && visibleDirs(children, showHidden).length > 0 ? (0, react.createElement)("div", null, ...visibleDirs(children, showHidden).map((child) => (0, react.createElement)(DirRow, {
1264
1287
  key: child.path,
1265
1288
  scope,
1266
1289
  entry: child,
1267
1290
  depth: depth + 1,
1268
1291
  selectedPath,
1269
1292
  expanded,
1293
+ showHidden,
1270
1294
  onToggleExpand,
1271
1295
  onPick,
1272
1296
  onNavigate: props.onNavigate
@@ -1356,23 +1380,6 @@ window.__ModuleLoader__.load({
1356
1380
  * and environment variables.
1357
1381
  * @module dsh-better-sidebar-starter/client/ConfigEditorModal
1358
1382
  */
1359
- /** Call the sidebar fs.tree API directly via fetch. Returns directories only.
1360
- * If path is omitted, the server uses the session cwd (root listing).
1361
- * The sidebar API wraps responses in { ok: true, value: ... } envelope. */
1362
- async function fsTree(scope, path) {
1363
- const payload = { sessionId: scope.sessionId };
1364
- if (scope.cwd !== void 0 && scope.cwd !== "") payload.cwd = scope.cwd;
1365
- if (path !== void 0) payload.path = path;
1366
- const resp = await fetch("/sidebar/api/fs.tree", {
1367
- method: "POST",
1368
- headers: { "content-type": "application/json" },
1369
- body: JSON.stringify(payload)
1370
- });
1371
- if (!resp.ok) throw new Error(`fs.tree ${path ?? "(root)"}: ${resp.status}`);
1372
- const parsed = await resp.json();
1373
- if (!parsed.ok || parsed.value === void 0) throw new Error(`fs.tree ${path ?? "(root)"}: ${parsed.error?.message ?? "unknown error"}`);
1374
- return parsed.value.entries.filter((e) => e.isDir && !e.hidden);
1375
- }
1376
1383
  /** Recursive tree node: loads its own children on expand. */
1377
1384
  function TreeNode(props) {
1378
1385
  const { scope, entry, depth, selectedPath, onSelect } = props;
@@ -1383,7 +1390,7 @@ window.__ModuleLoader__.load({
1383
1390
  if (!expanded && children === null) {
1384
1391
  setLoading(true);
1385
1392
  fsTree(scope, entry.path).then((dirs) => {
1386
- setChildren(dirs);
1393
+ setChildren(dirs.filter((d) => !d.hidden));
1387
1394
  setLoading(false);
1388
1395
  }).catch(() => {
1389
1396
  setChildren([]);
@@ -1426,8 +1433,9 @@ window.__ModuleLoader__.load({
1426
1433
  if (!expanded && children === null) {
1427
1434
  setLoading(true);
1428
1435
  setError(null);
1429
- fsTree(scope).then((dirs) => {
1430
- setChildren(dirs);
1436
+ const root = scope.cwd ?? "";
1437
+ (root === "" ? Promise.reject(/* @__PURE__ */ new Error("fs-dirs: 会话工作目录不可用")) : fsTree(scope, root)).then((dirs) => {
1438
+ setChildren(dirs.filter((d) => !d.hidden));
1431
1439
  setLoading(false);
1432
1440
  }).catch((err) => {
1433
1441
  setError(err instanceof Error ? err.message : String(err));
@@ -3104,39 +3112,7 @@ window.__ModuleLoader__.load({
3104
3112
  icon: (size) => (0, react.createElement)(RocketIcon, { size }),
3105
3113
  order: 50,
3106
3114
  single: true,
3107
- settings: {
3108
- pluginToggles: [
3109
- {
3110
- key: "autoSelectOnStart",
3111
- type: "switch",
3112
- title: "启动后自动选中日志"
3113
- },
3114
- {
3115
- key: "autoScroll",
3116
- type: "switch",
3117
- title: "自动滚动到最新日志"
3118
- },
3119
- {
3120
- key: "javaHome",
3121
- type: "text",
3122
- title: "Java 主目录 (JAVA_HOME)",
3123
- desc: "Spring Boot 用的 JDK 路径,留空则自动查找"
3124
- },
3125
- {
3126
- key: "nodePath",
3127
- type: "text",
3128
- title: "Node.js 路径",
3129
- desc: "npm 命令用的 Node 路径,留空则用系统默认"
3130
- },
3131
- {
3132
- key: "pythonPath",
3133
- type: "text",
3134
- title: "Python 路径",
3135
- desc: "Python 命令用的解释器路径,留空则用系统默认"
3136
- }
3137
- ],
3138
- render: (props) => (0, react.createElement)(SettingsPanel, props)
3139
- },
3115
+ settings: { render: (props) => (0, react.createElement)(SettingsPanel, props) },
3140
3116
  component: (props) => (0, react.createElement)(ServicesTab, props)
3141
3117
  }), "dsh-better-sidebar-starter: services tab");
3142
3118
  }