Skip to content

Commit

Permalink
GDB-8054 Add cluster operations visualizations to the cluster view (#…
Browse files Browse the repository at this point in the history
…1019)

## What
Add visualizations and information about what cluster operations are undergoing on each node. The operation is shown with an icon and an info text message. The possible icons and messages can be seen in the legend.

## Why
With this change the user could have a visual hint on undergoing operations in the nodes when there is cluster

## How
- added a constant with all new possible states
- added icons for each new state
- added translations for each new state
- added a new info box under the hostname that displays text with the current operation
  • Loading branch information
yordanalexandrov authored Sep 15, 2023
1 parent f05818b commit 27b8b3c
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1 +1 @@
GDB_VERSION=10.3.0-TR14
GDB_VERSION=10.4.0-TR4
14 changes: 11 additions & 3 deletions src/css/bootstrap-graphdb-theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@
font-style: normal;
}

[class^="icon-"], [class*=" icon-"], .icon-any {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon', sans-serif !important;
[class^="icon-"], [class*=" icon-"], .icon-any, .fa-d3 {
speak: none;
font-style: normal;
font-weight: normal;
Expand All @@ -39,6 +37,16 @@
-moz-osx-font-smoothing: grayscale;
}

[class^="icon-"], [class*=" icon-"], .icon-any, .fa-d3 {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon', sans-serif !important;
}

.fa-d3 {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'FontAwesome', sans-serif !important;
}

.icon-arrow-up-off:before {
content: "\e948";
}
Expand Down
19 changes: 13 additions & 6 deletions src/css/clustermanagement.css
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,20 @@ path.link {
visibility: hidden;
}

.hidden {
display: none;
}

text.node-icon {
fill: rgba(255, 255, 255, 0.5);
font-size: 40px;
}

.id-host-background, .node-info-background {
fill: #EEEEEE;
}

text.node-icon {
text-anchor: middle;
dominant-baseline: central;
}
Expand All @@ -112,13 +123,9 @@ text {
pointer-events: none;
}

text.id {
text.id-host, text.node-info-text {
text-anchor: middle;
font-weight: 500;
}

text.id-host {
font-weight: 400;
font-weight: 400;
}

.text-btn {
Expand Down
10 changes: 9 additions & 1 deletion src/i18n/locale-en.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@
"node_state_restricted": "Restricted",
"link_state_in_sync": "In sync",
"link_state_syncing": "Syncing",
"link_state_out_of_sync": "Out of sync"
"link_state_out_of_sync": "Out of sync",
"recovery_state": {
"searching_for_node": "Searching for node",
"applying_snapshot": "Applying a snapshot",
"building_snapshot": "Building a snapshot for {{node}}",
"waiting_for_snapshot": "Waiting for snapshot from node {{node}}",
"sending_snapshot": "Sending a snapshot to node {{node}}",
"recording_snapshot": "Recording a snapshot from node {{node}}"
}
},
"cluster_configuration": {
"label": "Cluster configuration",
Expand Down
10 changes: 9 additions & 1 deletion src/i18n/locale-fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@
"node_state_restricted": "Restreint",
"link_state_in_sync": "En synchronisation",
"link_state_syncing": "Synchronisation",
"link_state_out_of_sync": "Désynchronisé"
"link_state_out_of_sync": "Désynchronisé",
"recovery_state": {
"searching_for_node": "Recherche de nœud",
"applying_snapshot": "Appliquer un instantané",
"building_snapshot": "Créer un instantané pour {{node}}",
"waiting_for_snapshot": "En attente d'un instantané du nœud {{node}}",
"sending_snapshot": "Envoi d'un instantané au nœud {{node}}",
"recording_snapshot": "Enregistrement d'un instantané du nœud {{node}}"
}
},
"cluster_configuration": {
"label": "Configuration des clusters",
Expand Down
99 changes: 87 additions & 12 deletions src/js/angular/clustermanagement/cluster-drawing.service.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {LinkState, NodeState} from "./controllers";
import {LinkState, NodeState, RecoveryState} from "./controllers";

export const clusterColors = {
ontoOrange: 'var(--primary-color)',
Expand Down Expand Up @@ -110,16 +110,26 @@ function addHostnameToNodes(nodeElements, nodeRadius, isLegend) {

nodeTextHost
.append('text')
.attr('y', nodeRadius + 10)
.attr('class', 'id id-host')
.style('text-anchor', 'middle');
.attr('y', nodeRadius + 15)
.attr('class', 'id id-host');

nodeTextHost
.append('rect')
.attr('class', 'node-info-background')
.attr('rx', 6);

nodeTextHost
.append('text')
.attr('y', nodeRadius + 45)
.attr('class', 'node-info-text');
}
}

export function updateNodes(nodes) {
updateNodesIcon(nodes);
updateNodesClasses(nodes);
updateNodesHostnameText(nodes);
updateNodesInfoText(nodes);
}

function updateNodesClasses(nodes) {
Expand All @@ -136,9 +146,45 @@ function updateNodesClasses(nodes) {
}

function updateNodesIcon(nodes) {
nodes
.select('.icon-any.node-icon')
.text(getNodeIconType);
nodes.select('.node-icon')
.classed('icon-any', function (d) {
return !hasRecoveryState(d);
})
.classed('fa-d3', hasRecoveryState)
.text(function (d) {
if (hasRecoveryState(d)) {
return getNodeInfoIconType(d);
} else {
return getNodeIconType(d);
}
});
}

function hasRecoveryState(node) {
return !!node.recoveryStatus;
}

function getNodeInfoIconType(node) {
if (!node.recoveryStatus) {
return '';
}

switch (node.recoveryStatus.state) {
case RecoveryState.SEARCHING_FOR_NODE:
return '\uf002';
case RecoveryState.WAITING_FOR_SNAPSHOT:
return '\uf017';
case RecoveryState.RECORDING_SNAPSHOT:
return '\uf0c7';
case RecoveryState.APPLYING_SNAPSHOT:
return '\uf110';
case RecoveryState.BUILDING_SNAPSHOT:
return '\uf085';
case RecoveryState.SENDING_SNAPSHOT:
return '\uf093';
default:
return '';
}
}

function getNodeIconType(node) {
Expand All @@ -160,6 +206,36 @@ function getNodeIconType(node) {
return '';
}

function updateNodesInfoText(nodes) {
nodes
.select('.node-info-text')
.each(function (d) {
d.infoNode = this;
})
.text(function (d) {
return d.recoveryStatus && d.recoveryStatus.message;
});

// Add padding styling to text background. left/right/top/bottom +5
nodes
.select('.node-info-background')
.attr('width', function (d) {
return d3.select(d.infoNode).node().getBBox().width + 10;
})
.attr('height', function (d) {
return d3.select(d.infoNode).node().getBBox().height + 10;
})
.attr('x', function (d) {
return d3.select(d.infoNode).node().getBBox().x - 5;
})
.attr('y', function (d) {
return d3.select(d.infoNode).node().getBBox().y - 5;
})
.classed('hidden', function (d) {
return !d.recoveryStatus;
});
}

function updateNodesHostnameText(nodes) {
nodes
.select('.id.id-host')
Expand All @@ -170,22 +246,21 @@ function updateNodesHostnameText(nodes) {
return d.hostname;
});

// Add padding styling to text background. left/right +5. top/bottom +1
// Add padding styling to text background. left/right/top/bottom +5
nodes
.select('.id-host-background')
.attr('width', function (d) {
return d3.select(d.labelNode).node().getBBox().width + 10;
})
.attr('height', function (d) {
return d3.select(d.labelNode).node().getBBox().height + 2;
return d3.select(d.labelNode).node().getBBox().height + 10;
})
.attr('x', function (d) {
return d3.select(d.labelNode).node().getBBox().x - 5;
})
.attr('y', function (d) {
return d3.select(d.labelNode).node().getBBox().y - 1;
})
.attr('fill', '#EEEEEE');
return d3.select(d.labelNode).node().getBBox().y - 5;
});
}

export function createLinks(linksDataBinding) {
Expand Down
10 changes: 10 additions & 0 deletions src/js/angular/clustermanagement/controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ export const NodeState = {
RESTRICTED: 'RESTRICTED',
NO_CLUSTER: 'NO_CLUSTER'
};

export const RecoveryState = {
SEARCHING_FOR_NODE: 'SEARCHING_FOR_NODE',
WAITING_FOR_SNAPSHOT: 'WAITING_FOR_SNAPSHOT',
RECORDING_SNAPSHOT: 'RECORDING_SNAPSHOT',
APPLYING_SNAPSHOT: 'APPLYING_SNAPSHOT',
BUILDING_SNAPSHOT: 'BUILDING_SNAPSHOT',
SENDING_SNAPSHOT: 'SENDING_SNAPSHOT'
};

export const LinkState = {
IN_SYNC: 'IN_SYNC',
OUT_OF_SYNC: 'OUT_OF_SYNC',
Expand Down
Loading

0 comments on commit 27b8b3c

Please sign in to comment.