diff --git a/js/apps/system/aardvark/frontend/css/clusterDashboardView.css b/js/apps/system/aardvark/frontend/css/clusterDashboardView.css
index fb62f9d025..1de6983ca3 100644
--- a/js/apps/system/aardvark/frontend/css/clusterDashboardView.css
+++ b/js/apps/system/aardvark/frontend/css/clusterDashboardView.css
@@ -1,13 +1,75 @@
div.clusterColumn {
- width: 18%;
- padding-left: 1%;
- padding-right: 1%;
+ padding-right: 5px;
float: left;
}
+div.clusterColumnMax {
+ float: none;
+ min-height: 255px;
+}
+
div.clusterColumn li {
background: none;
}
h3.clusterColumnHeader {
text-align: center;
}
+
+div.clusterAmounts {
+ position: absolute;
+ left: 0px;
+ right: 0px;
+ bottom: 0px;
+}
+
+span.cluster_icon_large {
+ font-size: 120px;
+}
+
+span.cluster_icon_small {
+ font-size: 25px;
+}
+
+div.tile {
+ width: 200px;
+ height: 200px;
+ position: absolute;
+ text-align: center;
+ font-weight: 700;
+ font-size: 20px;
+ cursor: pointer;
+}
+
+div.tile-left {
+ right: 50%;
+ margin-right: 20px;
+}
+
+div.tile-right {
+ left: 50%;
+ margin-left: 20px;
+}
+
+.btn-success {
+ background: #8AA051;
+}
+
+.btn-success:hover {
+ background: #788F3D;
+}
+
+.btn-danger {
+ background-color: #DA4F49;
+}
+
+.btn-danger:hover {
+ background-color: #BE342E;
+}
+
+.btn-warning {
+ background-color: #FAA732;
+}
+
+.btn-warning:hover {
+ background-color: #F89406;
+}
diff --git a/js/apps/system/aardvark/frontend/js/templates/clusterOverviewView.ejs b/js/apps/system/aardvark/frontend/js/templates/clusterOverviewView.ejs
index 678377f867..633c9dc265 100644
--- a/js/apps/system/aardvark/frontend/js/templates/clusterOverviewView.ejs
+++ b/js/apps/system/aardvark/frontend/js/templates/clusterOverviewView.ejs
@@ -1,14 +1,43 @@
+<% var statusClass = function(s) {
+ switch (s) {
+ case "ok":
+ return "success";
+ case "warning":
+ return "warning";
+ case "critical":
+ return "danger";
+ }
+ };
+%>
+<% if(minify) { %>
+
-
-
+
-
-
-
- -
-
+
+<% } else { %>
+
+
Data Servers
+
+
+
+
+ <%=dbservers.having %>/<%=dbservers.plan %>
+
+
+
+
Coordinators
+
+
+
+
+ <%=coordinators.having %>/<%=coordinators.plan %>
+
+
+<% } %>
diff --git a/js/apps/system/aardvark/frontend/js/views/clusterOverviewView.js b/js/apps/system/aardvark/frontend/js/views/clusterOverviewView.js
index 63ebe13ef2..8df5652fec 100644
--- a/js/apps/system/aardvark/frontend/js/views/clusterOverviewView.js
+++ b/js/apps/system/aardvark/frontend/js/views/clusterOverviewView.js
@@ -11,35 +11,48 @@
template: templateEngine.createTemplate("clusterOverviewView.ejs"),
events: {
- "click #primary": "loadPrimaries",
- "click #secondary": "loadSecondaries",
+ "click #dbserver": "loadDBServers",
"click #coordinator": "loadCoordinators"
},
initialize: function() {
+ this.fakeData = {
+ dbservers: {
+ plan: 3,
+ having: 3,
+ status: "warning"
+ },
+ coordinators: {
+ plan: 3,
+ having: 2,
+ status: "critical"
+ }
+ };
+
this.serverView = new window.ClusterServerView();
},
- loadPrimaries: function() {
+ loadDBServers: function() {
this.serverView.render({
- type: "primary"
- });
- },
-
- loadSecondaries: function() {
- this.serverView.render({
- type: "secondary"
+ type: "dbservers"
});
+ this.render(true);
},
loadCoordinators: function() {
this.serverView.render({
type: "coordinator"
});
+ this.render(true);
},
- render: function(info){
- $(this.el).html(this.template.render({}));
+ render: function(minify){
+ $(this.el).html(this.template.render({
+ minify: minify,
+ dbservers: this.fakeData.dbservers,
+ coordinators: this.fakeData.coordinators
+ }));
+ $(this.el).toggleClass("clusterColumnMax", !minify);
return this;
}
diff --git a/js/apps/system/aardvark/test/specs/views/clusterOverviewViewSpec.js b/js/apps/system/aardvark/test/specs/views/clusterOverviewViewSpec.js
index 04393e52b2..d748a1228f 100644
--- a/js/apps/system/aardvark/test/specs/views/clusterOverviewViewSpec.js
+++ b/js/apps/system/aardvark/test/specs/views/clusterOverviewViewSpec.js
@@ -1,7 +1,7 @@
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true, browser: true*/
/*global describe, beforeEach, afterEach, it, */
/*global spyOn, expect*/
-/*global templateEngine, $*/
+/*global templateEngine, $, _*/
(function() {
"use strict";
@@ -16,6 +16,33 @@
render: function(){}
};
spyOn(window, "ClusterServerView").andReturn(serverView);
+ this.addMatchers({
+
+ toBeTag: function(name) {
+ var el = this.actual;
+ this.message = function() {
+ return "Expected " + el.tagName.toLowerCase() + " to be a " + name;
+ };
+ return el.tagName.toLowerCase() === name;
+ },
+
+ toBeOfClass: function(name) {
+ var el = $(this.actual);
+ this.message = function() {
+ return "Expected \"" + el.attr("class") + "\" to contain " + name;
+ };
+ return el.hasClass(name);
+ },
+
+ toNotHaveClass: function(name) {
+ var el = $(this.actual);
+ this.message = function() {
+ return "Expected \"" + el.attr("class") + "\" to not contain " + name;
+ };
+ return !el.hasClass(name);
+ }
+
+ });
});
afterEach(function() {
@@ -33,100 +60,292 @@
describe("rendering", function() {
+ var checkUserActions = function() {
+ describe("user actions", function() {
+ var info;
+
+ beforeEach(function() {
+ serverView.render.reset();
+ view.render();
+ spyOn(view, "render");
+ });
+
+ it("should be able to navigate to db servers", function() {
+ info = {
+ type: "dbservers"
+ };
+ $("#dbserver").click();
+ expect(serverView.render).toHaveBeenCalledWith(info);
+ expect(view.render).toHaveBeenCalledWith(true);
+ });
+
+ it("should be able to navigate to primary servers", function() {
+ info = {
+ type: "coordinator"
+ };
+ $("#coordinator").click();
+ expect(serverView.render).toHaveBeenCalledWith(info);
+ expect(view.render).toHaveBeenCalledWith(true);
+ });
+
+ });
+ },
+
+ checkShowStatus = function (btn, status) {
+ var classNames = {
+ ok: "btn-success",
+ warning: "btn-warning",
+ critical: "btn-danger"
+ };
+ expect(btn).toBeOfClass(classNames[status]);
+ delete classNames[status];
+ _.each(classNames, function(v) {
+ expect(btn).toNotHaveClass(v);
+ });
+ };
+
beforeEach(function() {
spyOn(serverView, "render");
view = new window.ClusterOverviewView();
// Fake Data Injection to be removed
view.fakeData = {
- primaries: {
+ dbservers: {
plan: 3,
- having: 2,
+ having: 3,
status: "warning"
},
- secondaries: {
- plan: 3,
- having: 1,
- status: "critical"
- },
coordinators: {
plan: 3,
- having: 3,
- status: "ok"
+ having: 2,
+ status: "critical"
}
};
});
- it("should not render the Server view", function() {
- view.render();
- expect(serverView.render).not.toHaveBeenCalled();
+ describe("minified version", function() {
+
+ beforeEach(function() {
+ view.render(true);
+ });
+
+ it("should not render the Server view", function() {
+ expect(serverView.render).not.toHaveBeenCalled();
+ });
+
+ it("should render in minified version", function() {
+ expect($(div).hasClass("clusterColumnMax")).toBeFalsy();
+ });
+
+ describe("dbservers" , function() {
+
+ var getButton = function() {
+ return document.getElementById("dbserver");
+ };
+
+ it("should render the amounts", function() {
+ view.fakeData.dbservers.plan = 5;
+ view.fakeData.dbservers.having = 4;
+ view.render(true);
+ var btn = getButton(),
+ span = btn.firstChild,
+ txt = $(span).text();
+ expect(btn).toBeDefined();
+ expect(span).toBeDefined();
+ expect(span).toBeOfClass("arangoicon");
+ expect(span).toBeOfClass("icon_arangodb_database1");
+ expect(span).toBeOfClass("cluster_icon_small");
+ expect(txt.trim()).toEqual("4/5");
+ });
+
+ it("should render the status ok", function() {
+ var status = "ok";
+ view.fakeData.dbservers.status = status;
+ view.render(true);
+ checkShowStatus(getButton(), status);
+ });
+
+ it("should render the status warning", function() {
+ var status = "warning";
+ view.fakeData.dbservers.status = status;
+ view.render(true);
+ checkShowStatus(getButton(), status);
+ });
+
+ it("should render the status critical", function() {
+ var status = "critical";
+ view.fakeData.dbservers.status = status;
+ view.render(true);
+ checkShowStatus(getButton(), status);
+ });
+
+ });
+
+ describe("coordinators" , function() {
+
+ var getButton = function() {
+ return document.getElementById("coordinator");
+ };
+
+ it("should render the amounts", function() {
+ view.fakeData.coordinators.plan = 5;
+ view.fakeData.coordinators.having = 4;
+ view.render(true);
+ var btn = getButton(),
+ span = btn.firstChild,
+ txt = $(span).text();
+ expect(btn).toBeDefined();
+ expect(span).toBeDefined();
+ expect(span).toBeOfClass("arangoicon");
+ expect(span).toBeOfClass("icon_arangodb_compass");
+ expect(span).toBeOfClass("cluster_icon_small");
+ expect(txt.trim()).toEqual("4/5");
+ });
+
+ it("should render the status ok", function() {
+ var status = "ok";
+ view.fakeData.coordinators.status = status;
+ view.render(true);
+ checkShowStatus(getButton(), status);
+ });
+
+ it("should render the status warning", function() {
+ var status = "warning";
+ view.fakeData.coordinators.status = status;
+ view.render(true);
+ checkShowStatus(getButton(), status);
+ });
+
+ it("should render the status critical", function() {
+ var status = "critical";
+ view.fakeData.coordinators.status = status;
+ view.render(true);
+ checkShowStatus(getButton(), status);
+ });
+
+ });
+
+ checkUserActions();
+
});
- it("should render the amounts and status of primaries", function() {
- view.render();
- var btn = document.getElementById("primary"),
- txt = $(btn).text();
- expect(btn).toBeDefined();
- expect(txt.trim()).toEqual("Primaries 2/3");
- expect($(btn).hasClass("btn-success")).toBeFalsy();
- expect($(btn).hasClass("btn-warning")).toBeTruthy();
- expect($(btn).hasClass("btn-danger")).toBeFalsy();
- });
+ describe("maximised version", function() {
- it("should render the amounts and status of secondaries", function() {
- view.render();
- var btn = document.getElementById("secondary"),
- txt = $(btn).text();
- expect(btn).toBeDefined();
- expect(txt.trim()).toEqual("Secondaries 1/3");
- expect($(btn).hasClass("btn-success")).toBeFalsy();
- expect($(btn).hasClass("btn-warning")).toBeFalsy();
- expect($(btn).hasClass("btn-danger")).toBeTruthy();
- });
+ beforeEach(function() {
+ view.render();
+ });
- it("should render the amounts and status of coordinators", function() {
- view.render();
- var btn = document.getElementById("coordinator"),
- txt = $(btn).text();
- expect(btn).toBeDefined();
- expect(txt.trim()).toEqual("Coordinators 3/3");
- expect($(btn).hasClass("btn-success")).toBeTruthy();
- expect($(btn).hasClass("btn-warning")).toBeFalsy();
- expect($(btn).hasClass("btn-danger")).toBeFalsy();
- });
+ it("should not render the Server view", function() {
+ expect(serverView.render).not.toHaveBeenCalled();
+ });
- });
+ it("should increase the size of the column to maximum", function() {
+ expect($(div).hasClass("clusterColumnMax")).toBeTruthy();
+ });
- describe("user actions", function() {
- var info;
+ describe("dbservers" , function() {
- beforeEach(function() {
- spyOn(serverView, "render");
- view = new window.ClusterOverviewView();
- view.render();
- });
+ var getTile = function() {
+ return document.getElementById("dbserver");
+ };
- it("should be able to navigate to primary servers", function() {
- info = {
- type: "primary"
- };
- $("#primary").click();
- expect(serverView.render).toHaveBeenCalledWith(info);
- });
+ it("should render the tile", function() {
+ view.fakeData.dbservers.plan = 5;
+ view.fakeData.dbservers.having = 4;
+ view.render();
+ var tile = getTile(),
+ spans = $("> span", $(tile)),
+ header = spans[0],
+ icon = spans[1],
+ footer = $("> div", $(tile)),
+ htxt = $(header).text(),
+ ftxt = $(footer).text();
+ expect(tile).toBeDefined();
+ expect(tile).toBeOfClass("tile");
+ expect(tile).toBeOfClass("tile-left");
+ expect(icon).toBeDefined();
+ expect(icon).toBeOfClass("arangoicon");
+ expect(icon).toBeOfClass("icon_arangodb_database1");
+ expect(icon).toBeOfClass("cluster_icon_large");
+ expect(htxt.trim()).toEqual("Data Servers");
+ expect(ftxt.trim()).toEqual("4/5");
+ });
- it("should be able to navigate to primary servers", function() {
- info = {
- type: "secondary"
- };
- $("#secondary").click();
- expect(serverView.render).toHaveBeenCalledWith(info);
- });
+ it("should render the status ok", function() {
+ var status = "ok";
+ view.fakeData.dbservers.status = status;
+ view.render();
+ checkShowStatus(getTile(), status);
+ });
+
+ it("should render the status warning", function() {
+ var status = "warning";
+ view.fakeData.dbservers.status = status;
+ view.render();
+ checkShowStatus(getTile(), status);
+ });
+
+ it("should render the status critical", function() {
+ var status = "critical";
+ view.fakeData.dbservers.status = status;
+ view.render();
+ checkShowStatus(getTile(), status);
+ });
+
+ });
+
+ describe("coordinators" , function() {
+
+ var getTile = function() {
+ return document.getElementById("coordinator");
+ };
+
+ it("should render the tile", function() {
+ view.fakeData.coordinators.plan = 5;
+ view.fakeData.coordinators.having = 4;
+ view.render();
+ var tile = getTile(),
+ spans = $("> span", $(tile)),
+ header = spans[0],
+ icon = spans[1],
+ footer = $("> div", $(tile)),
+ htxt = $(header).text(),
+ ftxt = $(footer).text();
+ expect(tile).toBeDefined();
+ expect(tile).toBeOfClass("tile");
+ expect(tile).toBeOfClass("tile-right");
+ expect(icon).toBeDefined();
+ expect(icon).toBeOfClass("arangoicon");
+ expect(icon).toBeOfClass("icon_arangodb_compass");
+ expect(icon).toBeOfClass("cluster_icon_large");
+ expect(htxt.trim()).toEqual("Coordinators");
+ expect(ftxt.trim()).toEqual("4/5");
+ });
+
+ it("should render the status ok", function() {
+ var status = "ok";
+ view.fakeData.coordinators.status = status;
+ view.render();
+ checkShowStatus(getTile(), status);
+ });
+
+ it("should render the status warning", function() {
+ var status = "warning";
+ view.fakeData.coordinators.status = status;
+ view.render();
+ checkShowStatus(getTile(), status);
+ });
+
+ it("should render the status critical", function() {
+ var status = "critical";
+ view.fakeData.coordinators.status = status;
+ view.render();
+ checkShowStatus(getTile(), status);
+ });
+
+ });
+
+ checkUserActions();
- it("should be able to navigate to primary servers", function() {
- info = {
- type: "coordinator"
- };
- $("#coordinator").click();
- expect(serverView.render).toHaveBeenCalledWith(info);
});
});