diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml
index 6e52db6..cc8e814 100644
--- a/k8s/deployment.yaml
+++ b/k8s/deployment.yaml
@@ -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
diff --git a/static/index.html b/static/index.html
index 8f83616..d5d0653 100644
--- a/static/index.html
+++ b/static/index.html
@@ -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 = '
Строю граф зависимостей...
';
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 = 'Граф открыт почти на весь экран для удобства чтения.
';
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