v9.14: instance graph uses rawDetail deps; age day declension

This commit is contained in:
Naeel
2026-04-16 16:10:03 +03:00
parent a662be9c12
commit 23f09556f9
2 changed files with 46 additions and 7 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ spec:
spec:
containers:
- name: cloud-dashboard
image: naeel/cloud-dashboard:v9.13
image: naeel/cloud-dashboard:v9.14
imagePullPolicy: Always
ports:
- containerPort: 8080
+45 -6
View File
@@ -452,7 +452,11 @@ function humanAge(dtStr){
var days = Math.floor(hrs / 24);
var months = Math.floor(days / 30);
var years = Math.floor(days / 365);
if(days >= 1) return days + " д";
if(days >= 1){
var d10 = days % 10, d100 = days % 100;
var w = (d100 >= 11 && d100 <= 19) ? "дней" : d10 === 1 ? "день" : (d10 >= 2 && d10 <= 4) ? "дня" : "дней";
return days + " " + w;
}
if(hrs >= 1) return hrs + " ч";
return mins + " мин";
}
@@ -614,11 +618,7 @@ function renderInstanceGraph(uid){
if(holder) holder.innerHTML = '<div class="graph-loading">Строю граф зависимостей...</div>';
var run = function(){
ensureFullGraphLoaded().then(function(){
var g = buildClientSubgraph(graphFullData || {nodes:[], edges:[]}, uid, 3);
if((g.nodes || []).length <= 1 && graphFullData){
var near = buildClientSubgraph(graphFullData, uid, 1);
if((near.nodes || []).length > (g.nodes || []).length) g = near;
}
var g = buildDepSubgraphFromDetail(uid);
if((g.nodes || []).length > 2){
if(holder) holder.innerHTML = '<div class="graph-inline-note">Граф открыт почти на весь экран для удобства чтения.</div>';
showGraphModal("Граф зависимостей: " + escHtml(instanceName(uid)), g, uid, true);
@@ -1217,6 +1217,45 @@ if(getToken()) initApp();
window.navigateToDep = navigateToDep;
window.navBack = navBack;
// Build instance subgraph using rawDetail dependencies (no edges needed)
function buildDepSubgraphFromDetail(rootUid){
var seen = new Set([rootUid]);
var frontier = new Set([rootUid]);
for(var i=0;i<3;i++){
var nxt = new Set();
frontier.forEach(function(u){
var det = rawDetail[u];
if(!det) return;
(det.dependencies || []).forEach(function(dep){
var duid = depUid(dep);
if(duid && !seen.has(duid)) nxt.add(duid);
});
(det.dependentInstances || []).forEach(function(dep){
var duid = depUid(dep);
if(duid && !seen.has(duid)) nxt.add(duid);
});
});
if(nxt.size === 0) break;
nxt.forEach(function(x){ seen.add(x); });
frontier = nxt;
}
var allNodes = (graphFullData && graphFullData.nodes) || [];
var filtered = allNodes.filter(function(n){ return seen.has(n.id); });
// Ensure root is present even if not in graphFullData
if(!filtered.some(function(n){ return n.id === rootUid; })){
var inst = null;
for(var j=0;j<allInstances.length;j++){
if(allInstances[j].instanceUid === rootUid){ inst = allInstances[j]; break; }
}
if(inst) filtered.push({
id: rootUid, label: inst.displayName || rootUid,
status: inst.explainedStatus || "unknown", svc: inst.svc || "",
lane: "regular", created: inst.instanceConfigDtCreated || inst.dtCreated || ""
});
}
return { nodes: filtered, edges: [] };
}
})();
</script>
</body>