Skip to content

Commit 8e017c6

Browse files
Status indicator and polling (#181)
* Minor fixes * Moved main padding into content * Fix Tests * Add status bar to Subscription page * Add status bar and status check to ei info page * Various changes to make status bar and polling work in subscription, testrules and info page * Back end select width adjusted * Fix button disable * Fix * Minor fix
1 parent 0269f82 commit 8e017c6

File tree

16 files changed

+583
-425
lines changed

16 files changed

+583
-425
lines changed

src/functionaltest/java/com/ericsson/ei/frontend/TestAlarm.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.apache.http.impl.client.CloseableHttpClient;
88
import org.junit.Test;
99
import org.openqa.selenium.By;
10+
import org.openqa.selenium.JavascriptExecutor;
1011
import org.springframework.boot.test.mock.mockito.MockBean;
1112

1213
import com.ericsson.ei.frontend.pageobjects.IndexPage;
@@ -20,13 +21,16 @@ public class TestAlarm extends SeleniumBaseClass {
2021
@Test
2122
public void testAlarm() throws IOException {
2223
initBaseMocks(mockedHttpClient);
24+
JavascriptExecutor js = (JavascriptExecutor) driver;
2325

2426
//Load index page
2527
IndexPage indexPageObject = new IndexPage(null, driver, baseUrl);
2628
indexPageObject.loadPage();
2729

2830
//Generate exception
2931
TestRulesPage testRulesPage = indexPageObject.clickTestRulesPage();
32+
//Enable buttons
33+
js.executeScript("$('button.btn').prop(\"disabled\", false);");
3034
testRulesPage.clickRemoveRuleNumber(0);
3135
testRulesPage.clickRemoveEventNumber(0);
3236

src/functionaltest/java/com/ericsson/ei/frontend/TestRulesFunctionality.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.junit.Test;
1717
import org.mockserver.client.MockServerClient;
1818
import org.mockserver.integration.ClientAndServer;
19+
import org.openqa.selenium.JavascriptExecutor;
1920
import org.openqa.selenium.support.ui.WebDriverWait;
2021
import org.springframework.boot.test.mock.mockito.MockBean;
2122

@@ -51,6 +52,7 @@ public void testJourneyToFindAggregatedObjectButton() throws Exception {
5152
int portServer = mockServer.getLocalPort();
5253
backEndInstancesUtils.setDefaultBackEndInstanceToNull();
5354
backEndInstancesUtils.setDefaultBackEndInstance("new_instance_default", "localhost", portServer, "", true);
55+
JavascriptExecutor js = (JavascriptExecutor) driver;
5456

5557
// Open indexpage and verify that it is opened
5658
IndexPage indexPageObject = new IndexPage(null, driver, baseUrl);
@@ -60,6 +62,9 @@ public void testJourneyToFindAggregatedObjectButton() throws Exception {
6062
TestRulesPage testRulesPage = indexPageObject.clickTestRulesPage();
6163
assert(new WebDriverWait(driver, 10).until((webdriver) -> testRulesPage.presenceOfTestRulesHeader()));
6264

65+
//Enable buttons
66+
js.executeScript("$('button.btn').prop(\"disabled\", false);");
67+
6368
// Verify that "download rules template" button works
6469
String downloadedRulesTemplate = "";
6570
String mockedResponse = getJSONStringFromFile(RULES_TEMPLATE_FILE_PATH);

src/functionaltest/java/com/ericsson/ei/frontend/pageobjects/TestRulesPage.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,12 @@ public void clickAddRuleButton() {
100100

101101
public void clickRemoveRuleNumber(int number) {
102102
new WebDriverWait(driver, TIMEOUT_TIMER).until(ExpectedConditions.presenceOfElementLocated(By.id("Rule" + number)));
103-
WebElement removeRuleButton = driver.findElement(By.id("Rule" + number)).findElement(By.className("fa-trash"));
103+
WebElement removeRuleButton = driver.findElement(By.id("Rule" + number)).findElement(By.className("remove-item"));
104+
105+
// We need the following two lines in order to be sure that the remove event button is not obscured...
106+
JavascriptExecutor jse2 = driver;
107+
jse2.executeScript("arguments[0].scrollIntoView()", removeRuleButton);
108+
104109
removeRuleButton.click();
105110
}
106111

@@ -112,7 +117,7 @@ public void clickAddEventButton() {
112117

113118
public void clickRemoveEventNumber(int number) {
114119
new WebDriverWait(driver, TIMEOUT_TIMER).until(ExpectedConditions.presenceOfElementLocated(By.id("Events" + number)));
115-
WebElement removeEventButton = driver.findElement(By.id("Events" + number)).findElement(By.className("fa-trash"));
120+
WebElement removeEventButton = driver.findElement(By.id("Events" + number)).findElement(By.className("remove-item"));
116121

117122
// We need the following two lines in order to be sure that the remove event button is not obscured...
118123
JavascriptExecutor jse2 = driver;

src/main/resources/static/css/style.css

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
.content-wrapper {
2-
height: 100%;
1+
.content {
2+
padding: 10px;
3+
}
4+
.subscription-alert {
5+
width: 100%;
6+
padding: 2px;
7+
margin-bottom: 0;
8+
border-radius:0px;
9+
text-align: center;
310
}
411
#table {
512
border-spacing: 0px;
@@ -31,8 +38,8 @@
3138
.display-inline-table {
3239
display: inline-table;
3340
}
34-
.split {
35-
max-width: 50%;
41+
.white-space-normal {
42+
white-space: normal;
3643
}
3744
.table-responsive>.table-bordered {
3845
border: 1px solid #dee2e6;
@@ -55,21 +62,6 @@
5562
width: 30%;
5663
}
5764
/* Information page stop */
58-
.testRulePage {
59-
position: fixed;
60-
top: 0px;
61-
left: 0px;
62-
width: 100%;
63-
height: 100%;
64-
background-color: rgba(0, 0, 0, .5);
65-
z-index: 999;
66-
vertical-align: middle;
67-
text-align: center;
68-
color: white;
69-
font-size: 25px;
70-
font-weight: bold;
71-
text-shadow: 1px 1px #525252;
72-
}
7365
.flexbox {
7466
display:flex;
7567
justify-content:center;
@@ -220,6 +212,13 @@ button.rules_info:focus {
220212
outline:0;
221213
outline:none;
222214
}
215+
button.remove-item {
216+
padding: 0 2px 0 2px;
217+
}
218+
.text-area {
219+
width: 100%;
220+
padding-right: 5px;
221+
}
223222
#infoContent{
224223
font-family: Calibri;
225224
}
@@ -239,6 +238,9 @@ table.dataTable.dtr-inline.collapsed > tbody > tr[role="row"] > td:first-child:b
239238
border: none;
240239
box-shadow: 0 0 0 transparent;
241240
}
241+
table.dataTable.dtr-inline.collapsed > tbody > tr > td > .dtr-details > li {
242+
word-break: break-word;
243+
}
242244
@media (max-width: 576px) {
243245
.container {
244246
max-width: 480px;

src/main/resources/static/css/ui.css

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ body {
2929
.main {
3030
height: calc(100vh - 55px);
3131
overflow-x: hidden;
32-
padding: 10px;
3332
margin-left: 200px;
3433
transition: all 1ms;
3534
}
@@ -49,7 +48,7 @@ body {
4948
}
5049
.app-header .header-bar {
5150
visibility: visible;
52-
max-width: 600px;
51+
max-width: 50%;
5352
min-width: 10%;
5453
outline: 0;
5554
}
@@ -84,6 +83,7 @@ body {
8483
white-space: nowrap;
8584
overflow: hidden;
8685
text-overflow: ellipsis;
86+
word-break: break-word;
8787
padding: 10px 5px 10px 10px;
8888
font-size: 80%;
8989
cursor: pointer;
@@ -402,6 +402,9 @@ body {
402402
}
403403

404404
@media (max-width: 767.98px) {
405+
.app-header .header-bar {
406+
max-width: 100%;
407+
}
405408
.app-body .sidebar {
406409
margin-left: -200px;
407410
}

src/main/resources/static/js/common.js

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,129 @@
1+
var router = new Navigo(null, true, '#');
12
var frontendServiceUrl = $('#frontendServiceUrl').text();
3+
var frontendServiceBackEndPath = "/backend";
4+
var timerInterval;
25

6+
// Start ## Routing ##
7+
var routes = {};
8+
routes["subscriptions"] = function () {
9+
updateBackEndInstanceList();
10+
$(".app-header").removeClass("header-bar-hidden");
11+
$(".main").load("subscriptionpage.html");
12+
};
13+
routes["test-rules"] = function () {
14+
updateBackEndInstanceList();
15+
$(".app-header").removeClass("header-bar-hidden");
16+
$(".main").load("testRules.html");
17+
};
18+
routes["ei-info"] = function () {
19+
updateBackEndInstanceList();
20+
$(".app-header").removeClass("header-bar-hidden");
21+
$(".main").load("eiInfo.html");
22+
};
23+
routes["switch-backend"] = function () {
24+
$(".app-header").addClass("header-bar-hidden");
25+
$(".main").load("switch-backend.html");
26+
};
27+
routes["add-backend"] = function () {
28+
$(".app-header").addClass("header-bar-hidden");
29+
$(".main").load("add-instances.html");
30+
};
31+
routes["login"] = function () {
32+
updateBackEndInstanceList();
33+
$(".app-header").removeClass("header-bar-hidden");
34+
$(".main").load("login.html");
35+
};
36+
37+
router.on({
38+
'subscriptions': routes["subscriptions"],
39+
'test-rules': routes["test-rules"],
40+
'ei-info': routes["ei-info"],
41+
'switch-backend': routes["switch-backend"],
42+
'add-backend': routes["add-backend"],
43+
'login': routes["login"],
44+
'*': function () {
45+
router.navigate('subscriptions');
46+
}
47+
}).resolve();
48+
49+
function reloadRoute() {
50+
const currentUrl = router._lastRouteResolved.url;
51+
routes[currentUrl]();
52+
}
53+
54+
function navigateRoute(route) {
55+
router.navigate(route);
56+
}
57+
// End ## Routing ##
58+
59+
// Start ## Load Back end list ##
60+
function updateBackEndInstanceList() {
61+
$.ajax({
62+
url: frontendServiceUrl + frontendServiceBackEndPath,
63+
type: "GET",
64+
contentType: 'application/json; charset=utf-8',
65+
cache: false,
66+
error: function (XMLHttpRequest, textStatus, errorThrown) {
67+
window.logMessages("Failure when trying to load backend instances");
68+
},
69+
success: function (responseData, XMLHttpRequest, textStatus) {
70+
var observableObject = $("#selectInstances")[0];
71+
ko.cleanNode(observableObject);
72+
ko.applyBindings(new viewModel(responseData), observableObject);
73+
}
74+
});
75+
}
76+
77+
function singleInstanceModel(name, host, port, contextPath, https, active) {
78+
this.name = ko.observable(name),
79+
this.host = ko.observable(host),
80+
this.port = ko.observable(port),
81+
this.contextPath = ko.observable(contextPath),
82+
this.https = ko.observable(https),
83+
this.active = ko.observable(active),
84+
this.information = name.toUpperCase() + " - " + host + " " + port + "/" + contextPath;
85+
}
86+
87+
function viewModel(data) {
88+
var self = this;
89+
var currentName;
90+
self.instances = ko.observableArray();
91+
var json = JSON.parse(ko.toJSON(data));
92+
var oldSelectedActive = self.selectedActive;
93+
for (var i = 0; i < json.length; i++) {
94+
var obj = json[i];
95+
var instance = new singleInstanceModel(obj.name, obj.host, obj.port, obj.contextPath, obj.https, obj.active);
96+
self.instances.push(instance);
97+
if (obj.active == true) {
98+
currentName = obj.name;
99+
}
100+
}
101+
self.selectedActive = ko.observable(currentName);
102+
self.onChange = function () {
103+
if (typeof self.selectedActive() !== "undefined") {
104+
$.ajax({
105+
url: frontendServiceUrl + frontendServiceBackEndPath,
106+
type: "PUT",
107+
data: self.selectedActive(),
108+
contentType: 'application/json; charset=utf-8',
109+
cache: false,
110+
error: function (XMLHttpRequest, textStatus, errorThrown) {
111+
self.selectedActive = oldSelectedActive;
112+
updateBackEndInstanceList();
113+
window.logMessages(XMLHttpRequest.responseText);
114+
},
115+
success: function (responseData, XMLHttpRequest, textStatus) {
116+
reloadRoute();
117+
}
118+
});
119+
} else {
120+
$.jGrowl("Please choose backend instance", { sticky: false, theme: 'Error' });
121+
}
122+
}
123+
}
124+
// End ## Load Back end list ##
125+
126+
// Start ## Login and Security ##
3127
function doIfUserLoggedIn(user) {
4128
localStorage.removeItem("currentUser");
5129
localStorage.setItem("currentUser", user);
@@ -60,4 +184,31 @@ function checkLoggedInUser() {
60184
doIfUserLoggedIn(user);
61185
}
62186
});
63-
}
187+
}
188+
// End ## Login and Security ##
189+
190+
// Start ## Status Indicator ##
191+
var statusType = {
192+
success: "alert-success",
193+
info: "alert-info",
194+
warning: "alert-warning",
195+
danger: "alert-danger"
196+
};
197+
198+
var statusText = {
199+
backend_down: "<strong>Back end is down!</strong> Wait for it go up or switch to another back end before continuing!",
200+
test_rules_disabled: "<strong>Test Rule service is disabled!</strong> To enable it set the backend property [testaggregated.enabled] as [true]"
201+
}
202+
203+
function addStatusIndicator(statusType, statusText) {
204+
var statusIndicator = $(".content")[0].previousElementSibling;
205+
if (statusIndicator != null) {
206+
$($(".content")[0].previousElementSibling).remove();
207+
}
208+
$(".content").before("<div class=\"subscription-alert alert " + statusType + "\">" + statusText + "</div>");
209+
}
210+
211+
function removeStatusIndicator() {
212+
$($(".content")[0].previousElementSibling).remove();
213+
}
214+
// End ## Status Indicator ##

0 commit comments

Comments
 (0)