dsh-db-tool 1.5.2 → 1.5.3
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/client/client.js +45 -4
- package/package.json +3 -2
package/client/client.js
CHANGED
|
@@ -463,10 +463,37 @@ window.__ModuleLoader__.load({
|
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
// --- 弹窗挂载:优先 createPortal 挂 document.body(避免侧栏容器裁剪);宿主未提供 react-dom 时回退 Panel 内 fixed overlay(DangerDialog 同模式) ---
|
|
466
|
-
|
|
467
|
-
|
|
466
|
+
// 三重降级解析(模块级缓存,全模块一次):①模块加载时同步 require(dsh.client.inject 声明 react-dom 后应成功)
|
|
467
|
+
// ②宿主模块系统异步 import(ctx.modules,宿主 rc.8+ 提供)③均不可用则保持 Panel 内回退渲染。
|
|
468
|
+
let portalImpl = null; // 解析成功的 createPortal(缓存,全模块一次)
|
|
469
|
+
let portalTried = false; // 是否已尝试解析(异步 import 只发起一次)
|
|
470
|
+
let portalPending = null; // 订阅解析成功的回调列表
|
|
471
|
+
try {
|
|
472
|
+
var rd = require("react-dom");
|
|
473
|
+
if (rd && typeof rd.createPortal === "function") { portalImpl = rd.createPortal.bind(rd); portalTried = true; }
|
|
474
|
+
} catch (e) { /* 留 null,等异步解析 */ }
|
|
475
|
+
function resolvePortalAsync(ctx) {
|
|
476
|
+
if (portalTried) return;
|
|
477
|
+
portalTried = true;
|
|
478
|
+
if (portalImpl) return;
|
|
479
|
+
var mods = ctx && ctx.modules;
|
|
480
|
+
var p = mods && typeof mods.import === "function" ? mods.import("react-dom") : null;
|
|
481
|
+
if (p && typeof p.then === "function") {
|
|
482
|
+
p.then(function (m) {
|
|
483
|
+
if (m && typeof m.createPortal === "function") {
|
|
484
|
+
portalImpl = m.createPortal.bind(m);
|
|
485
|
+
var waiters = portalPending || []; portalPending = null;
|
|
486
|
+
for (var i = 0; i < waiters.length; i++) waiters[i]();
|
|
487
|
+
}
|
|
488
|
+
}).catch(function () { /* 解析失败保持回退渲染 */ });
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
function onPortalReady(cb) {
|
|
492
|
+
if (portalImpl) { cb(); return; }
|
|
493
|
+
(portalPending = portalPending || []).push(cb);
|
|
494
|
+
}
|
|
468
495
|
function mountDialog(children) {
|
|
469
|
-
return
|
|
496
|
+
return portalImpl ? portalImpl(children, document.body) : children;
|
|
470
497
|
}
|
|
471
498
|
|
|
472
499
|
/* ---------------- 连接管理 ---------------- */
|
|
@@ -1306,8 +1333,20 @@ window.__ModuleLoader__.load({
|
|
|
1306
1333
|
}
|
|
1307
1334
|
|
|
1308
1335
|
function BrowseDialog(props) {
|
|
1309
|
-
const { conns, projectPath, grants, askConfirm, onClose } = props;
|
|
1336
|
+
const { conns, projectPath, grants, askConfirm, onClose, ctx } = props;
|
|
1310
1337
|
// grants / askConfirm:预留给后续单元格编辑的危险操作确认通道,本任务先接住不使用
|
|
1338
|
+
// portal 异步解析接入:portalReady 仅用于触发重渲染(mountDialog 内部读 portalImpl)。
|
|
1339
|
+
// createPortal 不换组件实例——portalReady 切换前后是同一 DOM 节点,pos state 保持,居中定位不受 portal 重挂影响。
|
|
1340
|
+
const [portalReady, setPortalReady] = React.useState(!!portalImpl);
|
|
1341
|
+
React.useEffect(() => {
|
|
1342
|
+
resolvePortalAsync(ctx);
|
|
1343
|
+
onPortalReady(function () { setPortalReady(true); });
|
|
1344
|
+
// 诊断:一次性输出(帮助真机排查 iframe 隔离与 portal 解析结果)
|
|
1345
|
+
if (!window.__dbtPortalDiag) {
|
|
1346
|
+
window.__dbtPortalDiag = true;
|
|
1347
|
+
console.info("[dbt] portal:", portalImpl ? "sync/async ok" : "unavailable", "sameDoc:", window.top === window.self);
|
|
1348
|
+
}
|
|
1349
|
+
}, []);
|
|
1311
1350
|
const [sel, setSel] = React.useState(null); // 弹窗内当前选中(null=未选表,右栏显示引导空态)
|
|
1312
1351
|
const [view, setView] = React.useState("structure"); // structure | preview(纯视图切换,不影响数据加载)
|
|
1313
1352
|
const [schema, setSchema] = React.useState([]);
|
|
@@ -1742,6 +1781,7 @@ window.__ModuleLoader__.load({
|
|
|
1742
1781
|
// 浮窗常驻:portal 到 body 且在 dbt-view 外,切 tab 时不消失
|
|
1743
1782
|
browseOpen ? React.createElement(BrowseDialog, {
|
|
1744
1783
|
conns, projectPath, grants, askConfirm,
|
|
1784
|
+
ctx: props.ctx, // 宿主 ctx 透传给浮窗,供 portal 异步解析(ctx.modules.import)
|
|
1745
1785
|
onClose: () => setBrowseOpen(false),
|
|
1746
1786
|
}) : null,
|
|
1747
1787
|
);
|
|
@@ -1766,6 +1806,7 @@ window.__ModuleLoader__.load({
|
|
|
1766
1806
|
key: "db-tool-" + String(localeKey || "zh"),
|
|
1767
1807
|
visible: props.visible,
|
|
1768
1808
|
scope: props.scope,
|
|
1809
|
+
ctx: ctx, // 宿主 ctx 下传,Panel 透传给 BrowseDialog 供 portal 解析
|
|
1769
1810
|
});
|
|
1770
1811
|
}
|
|
1771
1812
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-db-tool",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "DSH community plugin: chat-operated multi-database admin tool with sidebar management, project-scoped grants, ro/rw modes and dangerous-operation confirmation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
},
|
|
39
39
|
"client": {
|
|
40
40
|
"inject": [
|
|
41
|
-
"@deepseek-ai/dsh-client-locale"
|
|
41
|
+
"@deepseek-ai/dsh-client-locale",
|
|
42
|
+
"react-dom"
|
|
42
43
|
],
|
|
43
44
|
"platform": "web"
|
|
44
45
|
}
|