globular_admin
Version:
Administration panel for a Globular server.
316 lines (269 loc) • 12.4 kB
text/typescript
import { Panel } from "./panel";
import { GetAllApplicationsInfo, getAllActions, getErrorMessage, AppendActionToApplication, RemoveActionFromApplication, DeleteApplication, eventHub, SaveApplication } from './backend';
import * as M from "materialize-css";
import "materialize-css/sass/materialize.scss";
import { randomUUID } from "./utility";
import { IConfig } from 'globular-web-client';
/**
* This class is use to manage file on the server.
*/
export class ApplicationManager extends Panel {
private editable: boolean;
// File panel constructor.
constructor(id: string) {
super(id);
this.displayApplications()
}
// Here I will react to login information...
onlogin(data: any) {
// overide...
this.editable = true;
this.displayApplications()
}
onlogout() {
// overide...
this.editable = false;
this.displayApplications()
}
/**
* Display the application.
* @param content
* @param application
*/
displayApplication(content: any, application: any) {
// reset the interface.
content.removeAllChilds();
// The start and end time.
let startTime = new Date(application.creation_date * 1000)
let releasedTime = new Date(application.last_deployed * 1000)
let path: string = application.path
let url: string = window.location.protocol + "//" + window.location.hostname + ":" + window.location.port + path
content.appendElement({ tag: "div", class: "row" }).down()
.appendElement({ tag: "div", class: "col s2", innerHtml: "path" })
.appendElement({ tag: "div", class: "col s10", innerHtml: path }).up()
.appendElement({ tag: "div", class: "row" }).down()
.appendElement({ tag: "div", class: "col s2", innerHtml: "created the" })
.appendElement({ tag: "div", class: "col s10", innerHtml: startTime.toLocaleDateString() + " " + startTime.toLocaleTimeString() }).up()
.appendElement({ tag: "div", class: "row" }).down()
.appendElement({ tag: "div", class: "col s2", innerHtml: "released the" })
.appendElement({ tag: "div", class: "col s10", innerHtml: releasedTime.toLocaleDateString() + " " + releasedTime.toLocaleTimeString() }).up()
.appendElement({ tag: "div", class: "row" }).down()
.appendElement({ tag: "div", class: "col s2", innerHtml: "link" })
.appendElement({ tag: "a", class: "col s10", href: url, innerHtml: url }).up()
.appendElement({ tag: "div", class: "row" }).down()
.appendElement({ tag: "input", id: "icon_selector", type: "file", style: "display: none;" })
.appendElement({ tag: "div", class: "col s2", innerHtml: "icon" })
.appendElement({ tag: "div", id: "icon_div", class: "col s10" }).down()
.appendElement({ tag: "i", id: "icon_lnk", class: "material-icons", innerHtml: "image" })
.appendElement({ tag: "img", id: "icon_img", style: "display: none;" }).up().up()
.appendElement({ tag: "div", class: "row" }).down()
.appendElement({ tag: "div", class: "col s2", innerHtml: "actions" })
.appendElement({ tag: "div", id: "actions_div", class: "col s10" }).down()
.appendElement({ tag: "div", class: "row" }).down()
.appendElement({ tag: "div", id: "actions_ul", class: "collection col s12" })
let imageBtn = content.getChildById("icon_img")
if (application.icon != undefined) {
imageBtn.element.src = application.icon
imageBtn.element.style.display = "";
content.getChildById("icon_lnk").element.style.display = "none"
}
// So here I will
let actions_div = content.getChildById("actions_div")
let actions_ul = content.getChildById("actions_ul")
// append the actions list.
if (!this.editable) {
// Now the actions...
if (application.actions != undefined) {
for (var j = 0; j < application.actions.length; j++) {
actions_ul.appendElement({ tag: "li", class: "collection-item", innerHtml: application.actions[j] })
}
}
} else {
// Display the file selection window.
imageBtn.element.onclick = content.getChildById("icon_lnk").element.onclick = (evt: any) => {
evt.stopPropagation()
content.getChildById("icon_selector").element.click()
}
imageBtn.element.onmouseover = content.getChildById("icon_lnk").element.onmouseover = (evt: any) => {
content.getChildById("icon_lnk").element.style.cursor = "pointer"
imageBtn.element.style.cursor = "pointer"
}
imageBtn.element.onmouseleave = content.getChildById("icon_lnk").element.onmouseleave = (evt: any) => {
content.getChildById("icon_lnk").element.style.cursor = "default"
imageBtn.element.style.cursor = "default"
}
// The profile image selection.
content.getChildById("icon_selector").element.onchange = (evt: any) => {
var r = new FileReader();
var file = evt.target.files[0];
r.onload = () => {
// Here I will set the image to a size of 64x64 pixel instead of keep the original size.
var img = new Image();
img.onload = () => {
var thumbSize = 64;
var canvas = document.createElement("canvas");
canvas.width = thumbSize;
canvas.height = thumbSize;
var c = canvas.getContext("2d");
c.drawImage(img, 0, 0, thumbSize, thumbSize);
application.icon = canvas.toDataURL("image/png");
imageBtn.element.src = application.icon;
imageBtn.element.style.display = "";
content.getChildById("icon_lnk").element.style.display = "none"
SaveApplication(application,
() => {
M.toast({ html: "applicaition ico was saved!", displayLength: 2000 });
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
})
};
img.src = r.result.toString();
};
try {
r.readAsDataURL(file); // read as BASE64 format
} catch (err) {
console.log(err)
}
};
// Here I will append the actions list.
let action_input = actions_div.prependElement({ tag: "div", class: "row" }).down()
.appendElement({ tag: "div", class: "input-field col s12" }).down()
.appendElement({ tag: "input", id: randomUUID(), class: "autocomplete", placeholder: "New Action" }).down()
getAllActions(
(actions: any) => {
// console.log(actions)
let data: any;
data = {};
if (application.actions != undefined) {
for (var i = 0; i < actions.length; i++) {
if (application.actions.indexOf(actions[i]) == -1) {
data[actions[i]] = null
}
}
} else {
for (var i = 0; i < actions.length; i++) {
data[actions[i]] = null
}
}
// The action call on auto complete...
let onAutocomplete = () => {
let action = action_input.element.value;
let applicationId = application._id;
// save the action in the role.
AppendActionToApplication(
applicationId,
action,
() => {
M.toast({
html: "Action " + action + "has been added!",
displayLength: 2000
});
// re-init the display.
content.removeAllChilds()
if (application.actions == null) {
application.actions = []
}
application.actions.push(action)
this.displayApplication(content, application)
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
}
);
}
M.Autocomplete.init(document.getElementById(action_input.element.id), { data: data, onAutocomplete: onAutocomplete })
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
})
// Now the actions...
if (application.actions != undefined) {
for (var j = 0; j < application.actions.length; j++) {
let action = application.actions[j]
let deleteBtn = actions_ul.appendElement({ tag: "li", class: "collection-item" }).down()
.appendElement({ tag: "div", class: "row", style: "margin-bottom: 0px;" }).down()
.appendElement({ tag: "div", class: "col s11", innerHtml: action })
.appendElement({ tag: "i", class: "tiny material-icons col s1", innerHtml: "remove" }).down()
deleteBtn.element.onmouseenter = function () {
this.style.cursor = "pointer"
}
deleteBtn.element.onmouseleave = function () {
this.style.cursor = "default"
}
// Here I will remove the action from the application.
deleteBtn.element.onclick = () => {
RemoveActionFromApplication(application._id, action,
() => {
M.toast({
html: "Action " + action + "has been remove!",
displayLength: 2000
});
// remove the action from the actions list
application.actions.splice(application.actions.indexOf(action), 1);
// refresh the panel.
this.displayApplication(content, application)
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
})
}
}
}
}
}
// Redisplay the roles.
refresh() {
this.displayApplications()
}
displayApplications() {
// clear the panel before recreate information inside it.
this.div.removeAllChilds()
this.div.element.className = "row"
GetAllApplicationsInfo((applications: Array<any>) => {
// must be one in the page.
if (document.getElementById("applications_content_div") != undefined) {
return
}
let ul = this.div
.appendElement({ tag: "div", class: "col s12 /*m10 offset-m1*/", id: "applications_content_div" }).down()
.appendElement({ tag: "ul", class: "collapsible" }).down()
for (var i = 0; i < applications.length; i++) {
let application = applications[i]
if (document.getElementById(application._id + "_li") == undefined) {
let li = ul.appendElement({ tag: "li", id: application._id + "_li" }).down()
let header = li.appendElement({ tag: "div", class: "collapsible-header" }).down()
let content = li.appendElement({ tag: "div", class: "collapsible-body" }).down()
if (this.editable) {
// Here I will display button to edit applications...
// The delete icon.
// the application header.
header.appendElement({ tag: "span", class: "col s11", innerHtml: application._id })
let deleteBtn = header.appendElement({ tag: "i", class: "material-icons col s1", innerHtml: "delete" }).down()
// Now the remove application action.
deleteBtn.element.onclick = () => {
DeleteApplication(application._id,
() => {
M.toast({ html: "Application " + application._id + " have been removed!", displayLength: 2000 });
// refresh the interface.
this.displayApplications()
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
})
}
} else {
header.appendElement({ tag: "span", class: "col s12", innerHtml: application._id })
}
// Display the application.
this.displayApplication(content, application)
}
}
// init all collapsible panels...
M.Collapsible.init(ul.element)
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
});
}
}