diff --git a/frontend/src/light-app/index.css b/frontend/src/light-app/index.css
index 7608589e..a6de4849 100644
--- a/frontend/src/light-app/index.css
+++ b/frontend/src/light-app/index.css
@@ -9,6 +9,39 @@ body {
text-align: center;
}
+.hide {
+ display: none;
+}
+
+.power-off-container {
+ position: absolute;
+ margin: 0;
+ padding: 0;
+}
+
+#power-on {
+ cursor: pointer;
+ fill: #6dbdb9;
+ color: #6dbdb9;
+}
+
+.power-on-text {
+ font-size: xx-small;
+ text-align: center;
+ margin: 0;
+ padding: 0;
+}
+
+#power-off {
+ fill: #737471;
+ color: #737471;
+}
+
+#power-sync {
+ fill: #737471;
+ color: #737471;
+}
+
.dashboard-link {
color: rgb(155, 155, 232);
font-family: helvetica;
diff --git a/frontend/src/light-app/index.html b/frontend/src/light-app/index.html
index 949c88fb..bc6befbe 100644
--- a/frontend/src/light-app/index.html
+++ b/frontend/src/light-app/index.html
@@ -9,8 +9,35 @@
+
+
Welcome To Casanet Lite Dashboard
diff --git a/frontend/src/light-app/index.js b/frontend/src/light-app/index.js
index 3289c2e7..3a2a9948 100644
--- a/frontend/src/light-app/index.js
+++ b/frontend/src/light-app/index.js
@@ -1,16 +1,19 @@
/** Get the environments */
let environments = {
- API_URL: "http://127.0.0.1:3000/API",
- DASHBOARD_DOMAIN: ""
+ API_URL: 'http://127.0.0.1:3000/API',
+ DASHBOARD_DOMAIN: '',
};
+/** Flag to know if the 'power off' syncing */
+let isSync = false;
+
let domainAlert = () => {
if (document.baseURI.includes(environments.DASHBOARD_DOMAIN)) {
return;
}
const result = confirm(
- `The address of the service has changed and you will soon get off the air, please move to our new address!\n\n${environments.DASHBOARD_DOMAIN}\n\nPress 'OK' to move the new home`
+ `The address of the service has changed and you will soon get off the air, please move to our new address!\n\n${environments.DASHBOARD_DOMAIN}\n\nPress 'OK' to move the new home`,
);
if (!result) {
return;
@@ -28,13 +31,13 @@ let fetchEnvironments = () => {
}
if (xmlhttp.status === 401 || xmlhttp.status === 403) {
- alert("GET ENVIRONMENTS FAIL");
+ alert('GET ENVIRONMENTS FAIL');
return;
}
getMinionsFail(xmlhttp.responseText);
};
- xmlhttp.open("GET", "/light-app/environments.json", false);
+ xmlhttp.open('GET', '/light-app/environments.json', false);
xmlhttp.send();
};
@@ -45,40 +48,43 @@ fetchEnvironments();
* Redirect to auth page.
*/
let accessFail = () => {
- alert("ACCESS FORBIDDEN, redirecting to auth page...");
- window.location.href = "/#/login";
+ alert('ACCESS FORBIDDEN, redirecting to auth page...');
+ window.location.href = '/#/login';
};
let getMinionsFail = msg => {
if (confirm(`GET MINIONS FAIL: \n${msg},\n\n\nPress "OK" to retry`)) {
- patchMinions();
+ petchMinions();
}
};
/**
* Generate HTML button for given minion
* @param {*} minion A minion
- * @returns A DOM button object for the given minion
+ * @returns A DOM button object for the given minion
*/
let generateMinionButton = minion => {
/** Create button element */
- const minionButton = document.createElement("a");
+ const minionButton = document.createElement('a');
/** Insert name */
minionButton.innerText = minion.name;
try {
/** Set correct class for current status */
- minionButton.className = `button button--ghost button--ghost--${
- minion.minionStatus[minion.minionType].status
- }`;
+ minionButton.className = `button button--ghost button--ghost--${minion.minionStatus[minion.minionType].status}`;
+
+ if (!isSync && minion.minionStatus[minion.minionType].status === 'on') {
+ // In case the minion status are 'on' allow 'power-all-off' button
+ setViewPowerOn();
+ }
if (!minion.isProperlyCommunicated) {
minionButton.className = `button button--ghost button--ghost--err`;
}
} catch (error) {
minion.minionStatus[minion.minionType] = {
- status: "off"
+ status: 'off',
};
minionButton.className = `button button--ghost button--ghost--err`;
}
@@ -104,28 +110,34 @@ let generateMinions = minions => {
});
const rooms = minions.reduce((rooms, minion) => {
- minion.room = minion.room ? minion.room : "";
+ minion.room = minion.room ? minion.room : '';
rooms[minion.room] = rooms[minion.room] ? rooms[minion.room] : [];
rooms[minion.room].push(minion);
return rooms;
}, {});
/** Get the list holder element */
- const welcomeElement = document.getElementById("welcome-message");
- welcomeElement.innerHTML = "";
+ const welcomeElement = document.getElementById('welcome-message');
+ welcomeElement.innerHTML = '';
/** Get the list holder element */
- const listElement = document.getElementById("minions-container");
+ const listElement = document.getElementById('minions-container');
/** Set list empty */
- listElement.innerHTML = "";
+ listElement.innerHTML = '';
+
+ if (!isSync) {
+ // If the power off not currently sync, set power off,
+ // and in case any of the minion status are 'on' then call to 'setViewPowerOn()'
+ setViewPowerOff();
+ }
for (const [roomName, roomMinions] of Object.entries(rooms)) {
- const roomDiv = document.createElement("div");
- roomDiv.className = "room";
+ const roomDiv = document.createElement('div');
+ roomDiv.className = 'room';
- const roomTitle = document.createElement("h3");
- roomTitle.className = "room-name";
+ const roomTitle = document.createElement('h3');
+ roomTitle.className = 'room-name';
roomTitle.innerText = roomName;
roomDiv.appendChild(roomTitle);
@@ -140,7 +152,7 @@ let generateMinions = minions => {
};
/** Get minions from server */
-let patchMinions = () => {
+let petchMinions = () => {
// compatible with IE7+, Firefox, Chrome, Opera, Safari
const xmlhttp = new XMLHttpRequest();
xmlhttp.withCredentials = true;
@@ -157,21 +169,21 @@ let patchMinions = () => {
getMinionsFail(xmlhttp.responseText);
};
- xmlhttp.open("GET", `${environments.API_URL}/minions`, true);
+ xmlhttp.open('GET', `${environments.API_URL}/minions`, true);
xmlhttp.send();
};
/** Toggle minion status on click */
let buttonClicked = (element, minion) => {
- if (minion.sync) {
+ if (minion.sync || isSync) {
return;
}
+
minion.sync = true;
- element.className = element.className + " button--slicein--sync";
+ element.className = element.className + ' button--slicein--sync';
const setStatus = JSON.parse(JSON.stringify(minion.minionStatus));
- setStatus[minion.minionType].status =
- setStatus[minion.minionType].status === "on" ? "off" : "on";
+ setStatus[minion.minionType].status = setStatus[minion.minionType].status === 'on' ? 'off' : 'on';
// compatible with IE7+, Firefox, Chrome, Opera, Safari
const xmlhttp = new XMLHttpRequest();
@@ -183,51 +195,95 @@ let buttonClicked = (element, minion) => {
}
if (xmlhttp.status === 204) {
- patchMinions();
+ petchMinions();
return;
}
- element.className = `button button--ghost button--ghost--${
- minion.minionStatus[minion.minionType].status
- }`;
+ element.className = `button button--ghost button--ghost--${minion.minionStatus[minion.minionType].status}`;
if (xmlhttp.status === 401 || xmlhttp.status === 403) {
accessFail();
}
};
- xmlhttp.open(
- "PUT",
- `${environments.API_URL}/minions/${minion.minionId}`,
- true
- );
- xmlhttp.setRequestHeader("Content-type", "application/json; charset=utf-8");
+ xmlhttp.open('PUT', `${environments.API_URL}/minions/${minion.minionId}`, true);
+ xmlhttp.setRequestHeader('Content-type', 'application/json; charset=utf-8');
xmlhttp.send(JSON.stringify(setStatus));
};
+let setViewPowerOn = () => {
+ const powerOnContainer = document.getElementById('power-on');
+ const powerOffContainer = document.getElementById('power-off');
+ const powerSyncContainer = document.getElementById('power-sync');
+
+ powerOnContainer.className = '';
+ powerOffContainer.className = 'hide';
+ powerSyncContainer.className = 'hide';
+};
+
+let setViewPowerOff = () => {
+ const powerOnContainer = document.getElementById('power-on');
+ const powerOffContainer = document.getElementById('power-off');
+ const powerSyncContainer = document.getElementById('power-sync');
+
+ powerOnContainer.className = 'hide';
+ powerOffContainer.className = '';
+ powerSyncContainer.className = 'hide';
+};
+
+let setViewPowerSync = () => {
+ const powerOnContainer = document.getElementById('power-on');
+ const powerOffContainer = document.getElementById('power-off');
+ const powerSyncContainer = document.getElementById('power-sync');
+
+ powerOnContainer.className = 'hide';
+ powerOffContainer.className = 'hide';
+ powerSyncContainer.className = '';
+};
+
+let powerAllOff = () => {
+ isSync = true;
+
+ // Mark view as sync
+ setViewPowerSync();
+
+ const xmlhttp = new XMLHttpRequest();
+ xmlhttp.onload = () => {
+ if (xmlhttp.readyState === 4 && xmlhttp.status == 204) {
+ isSync = false;
+ petchMinions();
+ return;
+ }
+
+ alert('POWER OFF FAIL');
+ };
+ xmlhttp.open('PUT', `${environments.API_URL}/minions/power-off`, true);
+ xmlhttp.send();
+};
+
/** On start. get and generate minions */
-patchMinions();
+petchMinions();
/** SSE */
var evtSource = new EventSource(`${environments.API_URL}/feed/minions`, {
- withCredentials: true
+ withCredentials: true,
});
evtSource.onmessage = e => {
if (e.data === '"init"') {
return;
}
- patchMinions();
+ petchMinions();
};
/** PWA */
-if (localStorage.getItem("use-sw") === "true" && "serviceWorker" in navigator) {
+if (localStorage.getItem('use-sw') === 'true' && 'serviceWorker' in navigator) {
navigator.serviceWorker
- .register("/light-app/service-worker.js")
+ .register('/light-app/service-worker.js')
.then(function(registration) {
- console.log("Registration successful, scope is:", registration.scope);
+ console.log('Registration successful, scope is:', registration.scope);
})
.catch(function(error) {
- console.warn("Service worker registration failed, error:", error);
+ console.warn('Service worker registration failed, error:', error);
});
}