globular_admin
Version:
Administration panel for a Globular server.
579 lines (520 loc) • 19.1 kB
text/typescript
/**
* This class is use to manage file on the server.
*/
import { Panel } from "./panel";
import * as M from "materialize-css";
import "materialize-css/sass/materialize.scss";
import { eventHub, updateAccountEmail, updateAccountPassword, getErrorMessage } from './backend';
import {
getAllRoles,
GetAllAccountsInfo,
DeleteAccount,
AppendRoleToAccount,
RemoveRoleFromAccount,
registerAccount
} from "./backend";
import { randomUUID } from "./utility";
/**
* This class is use to manage file on the server.
*/
export class AccountManager extends Panel {
private editable: boolean;
private roles: any; // contain the list of roles.
// File panel constructor.
constructor(id: string) {
super(id);
this.roles = {}
getAllRoles((roles: any) => {
for (var i = 0; i < roles.length; i++) {
this.roles[roles[i]._id] = roles[i]
}
this.displayAccounts();
}, (err: any) => {
console.log(err)
})
// Emit when user click on the path
eventHub.subscribe(
"update_role_event",
(uuid: string) => { },
(evt: any) => {
// Set the dir to display.
// Here I must retreive the directory from the given path.
getAllRoles((roles: any) => {
for (var i = 0; i < roles.length; i++) {
this.roles[roles[i]._id] = roles[i]
}
this.displayAccounts();
}, (err: any) => {
console.log(err)
})
},
true
);
}
// Here I will react to login information...
onlogin(data: any) {
// overide...
this.editable = true;
this.displayAccounts();
}
onlogout() {
// overide...
this.editable = false;
this.displayAccounts();
}
/**
* Display the account.
* @param content
* @param account
*/
displayAccount(content: any, account: any) {
// reset the interface.
content.removeAllChilds();
// The start and end time.
content
.appendElement({ tag: "div", class: "row" }).down()
.appendElement({ tag: "div", class: "col s2", innerHtml: "email" })
.appendElement({ tag: "div", class: "col s10", id: "email_div", innerHtml: account.email }).up()
.appendElement({ tag: "div", id: "password_div" })
.appendElement({ tag: "div", id: "new_password_div" })
.appendElement({ tag: "div", id: "confirm_password_div" })
.appendElement({ tag: "div", class: "row" })
.down()
.appendElement({ tag: "div", class: "col s2", innerHtml: "roles" })
.appendElement({ tag: "div", id: "roles_div", class: "col s10" })
.down()
.appendElement({ tag: "div", class: "row" })
.down()
.appendElement({
tag: "div",
id: "roles_ul",
class: "collection col s12"
});
let email_div = content.getChildById("email_div");
let password_div = content.getChildById("password_div");
let new_password_div = content.getChildById("new_password_div");
let confirm_password_div = content.getChildById("confirm_password_div");
let roles_div = content.getChildById("roles_div");
let roles_ul = content.getChildById("roles_ul");
if (this.editable) {
// Here i will set the email input...
email_div.removeAllChilds()
email_div.element.innerHTML = ""
let email_input_id = randomUUID()
email_div.appendElement({ tag: "input-field" }).down()
.appendElement({ tag: "input", id: email_input_id, value: account.email, type: "email", class: "validate" })
.appendElement({ tag: "span" })
// Set the password change button.
new_password_div.element.className = confirm_password_div.element.className = password_div.element.className = "row"
let password_input_id = randomUUID();
// The password div
password_div.appendElement({ tag: "input-field" }).down()
.appendElement({ tag: "div", class: "col s2", innerHtml: "password" })
.appendElement({ tag: "div", class: "col s10" }).down()
.appendElement({ tag: "input", type: "password", id: password_input_id, class: "validate" })
.appendElement({ tag: "span" })
let new_password_input_id = randomUUID()
new_password_div.appendElement({ tag: "input-field" }).down()
.appendElement({ tag: "div", class: "col s2", innerHtml: "new password" })
.appendElement({ tag: "div", class: "col s10" }).down()
.appendElement({ tag: "input", type: "password", id: new_password_input_id, class: "validate" })
.appendElement({ tag: "span" })
// The confirmation password
let confirm_password_input_id = randomUUID()
confirm_password_div
.appendElement({ tag: "div", class: "col s2", innerHtml: "confirm password" })
.appendElement({ tag: "div", class: "col s10" }).down()
.appendElement({ tag: "input-field" }).down()
.appendElement({ tag: "input", type: "password", id: confirm_password_input_id, class: "validate" })
.appendElement({ tag: "span" })
// Now i will set the action.
email_div.getChildById(email_input_id).element.onkeyup = (evt: any) => {
if (evt.keyCode == 13) {
// here the user want to change it email.
updateAccountEmail(account._id, account.email, email_div.getChildById(email_input_id).element.value,
() => {
// keep the email in the account!
account.email = email_div.getChildById(email_input_id).element.value
M.toast({ html: "your email was updated!", displayLength: 2000 });
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
}
);
}
}
// Now the update password...
confirm_password_div.getChildById(confirm_password_input_id).element.onkeyup = (evt: any) => {
if (evt.keyCode == 13) {
// here the user want to change it email.
let confirm_pwd = confirm_password_div.getChildById(confirm_password_input_id).element.value
let old_pwd = password_div.getChildById(password_input_id).element.value
let new_pwd = new_password_div.getChildById(new_password_input_id).element.value
// Update the account password.
updateAccountPassword(account._id, old_pwd, new_pwd, confirm_pwd,
() => {
// keep the email in the account!
M.toast({ html: "your password was updated!", displayLength: 2000 });
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
}
);
}
}
}
// append the roles list.
if (!this.editable) {
// Now the roles...
if (account.roles != undefined) {
for (var j = 0; j < account.roles.length; j++) {
if (this.roles[account.roles[j].$id] != undefined) {
roles_ul.appendElement({
tag: "li",
class: "collection-item",
innerHtml: this.roles[account.roles[j].$id].name
});
}
}
}
} else {
// generate an id for the autocomplete
// Here I will append the roles list.
let role_input = roles_div
.prependElement({ tag: "div", class: "row" })
.down()
.appendElement({ tag: "div", class: "input-field col s12" })
.down()
.appendElement({
tag: "input",
class: "autocomplete",
placeholder: "Append Role",
id: randomUUID()
})
.down();
getAllRoles(
(roles: any) => {
let data: any;
data = {};
if (account.roles != undefined) {
for (var i = 0; i < roles.length; i++) {
let exist = false;
for (var j = 0; j < account.roles.length; j++) {
if (account.roles[j].$id == roles[i]._id) {
exist = true;
break;
}
}
if (!exist) {
data[roles[i]._id] = null;
}
}
} else {
for (var i = 0; i < roles.length; i++) {
data[roles[i]._id] = null;
}
}
// The action call on auto complete...
let onAutocomplete = () => {
let role = role_input.element.value;
let accountId = account._id;
// save the action in the role.
AppendRoleToAccount(
accountId,
role,
() => {
M.toast({
html: "Role " + role + " has been added!",
displayLength: 2000
});
// re-init the display.
content.removeAllChilds();
if (account.roles == null) {
account.roles = [];
}
account.roles.push({
$id: role,
$db: "local_ressource",
$ref: "local_ressource"
});
this.displayAccount(content, account);
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
}
);
};
M.Autocomplete.init(document.getElementById(role_input.element.id), {
data: data,
onAutocomplete: onAutocomplete
});
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
}
);
// Now the roles...
if (account.roles != undefined) {
for (var j = 0; j < account.roles.length; j++) {
let role = account.roles[j];
if (this.roles[role.$id] != undefined) {
let deleteBtn = roles_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: this.roles[role.$id].name
})
.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 role from the account.
deleteBtn.element.onclick = () => {
RemoveRoleFromAccount(
account._id,
role.$id,
() => {
M.toast({
html: "Role " + this.roles[role.$id].name + " has been remove!",
displayLength: 2000
});
// remove the role from the roles list
let roles = new Array<any>();
for (var i = 0; i < account.roles.length; i++) {
if (account.roles[i].$id != role.$id) {
roles.push(account.roles[i]);
}
}
// set back the roles.
account.roles = roles;
// refresh the panel.
this.displayAccount(content, account);
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
}
);
};
}
}
}
}
}
/**
*
*/
refresh(){
this.displayAccounts()
}
displayAccounts() {
// clear the panel before recreate information inside it.
this.div.removeAllChilds();
let div = this.div.appendElement({ tag: "div", class: "row", id:"accounts_content_div" }).down();
let newAccountBtn = div
.appendElement({ tag: "a", class: "modal-trigger", href: "#modal1" })
.down()
.appendElement({
tag: "i",
id: "append_role_btn",
class: "material-icons col s1",
title: "Create new account",
innerHtml: "person_add",
style: "margin-top: 10px; text-align: end;"
})
.down();
newAccountBtn.element.onmouseenter = function () {
this.style.cursor = "pointer";
};
newAccountBtn.element.onmouseout = function () {
this.style.cursor = "default";
};
// Append a new role.
newAccountBtn.element.onclick = () => {
// Here I will create a modal dialog where the user will create a new account.
let modal = this.div
.appendElement({ tag: "div", class: "modal", id: "modal1" })
.down();
modal
.appendElement({ tag: "div", class: "modal-content" })
.down()
.appendElement({ tag: "h5", innerHtml: "Create Account" })
.appendElement({ tag: "div", id: "content" })
.up()
.appendElement({ tag: "div", class: "modal-footer" })
.down()
.appendElement({
tag: "a",
class: "modal-close waves-effect waves-green btn-flat",
id: "create_account_btn",
innerHtml: "Save"
});
let content = modal.getChildById("content");
let user_name_id = randomUUID();
let user_email_id = randomUUID();
let user_password_id = randomUUID();
let user_password_validate_id = randomUUID();
// Here I will set the account values.
content
.appendElement({ tag: "div", class: "row" })
.down()
.appendElement({ tag: "div", class: "input-field col s12" })
.down()
.appendElement({
tag: "input",
placeholder: "",
id: user_name_id,
type: "text",
class: "validate"
})
.appendElement({
tag: "label",
for: user_name_id,
innerHtml: "Username"
})
.up()
.appendElement({ tag: "div", class: "input-field col s12" })
.down()
.appendElement({
tag: "input",
placeholder: "",
id: user_email_id,
type: "email",
class: "validate"
})
.appendElement({ tag: "label", for: "user_email", innerHtml: "Email" })
.up()
.appendElement({ tag: "div", class: "input-field col s12" })
.down()
.appendElement({
tag: "input",
placeholder: "",
id: user_password_id,
type: "password"
})
.appendElement({
tag: "label",
for: user_password_id,
innerHtml: "Password"
})
.up()
.appendElement({ tag: "div", class: "input-field col s12" })
.down()
.appendElement({
tag: "input",
placeholder: "",
id: user_password_validate_id,
type: "password"
})
.appendElement({
tag: "label",
for: user_password_validate_id,
innerHtml: "Password validate"
})
.up();
let createAccountBtn = modal.getChildById("create_account_btn");
createAccountBtn.element.onclick = () => {
let username = modal.getChildById(user_name_id).element.value;
let email = modal.getChildById(user_email_id).element.value;
let pwd = modal.getChildById(user_password_id).element.value;
let pwd_ = modal.getChildById(user_password_validate_id).element.value;
// Here I will register the account.
registerAccount(
username,
email,
pwd,
pwd_,
(result: any) => {
this.displayAccounts();
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
}
);
};
M.Modal.init(modal.element, {});
};
GetAllAccountsInfo(
(accounts: Array<any>) => {
// Here I will get the list of all accounts.
let ul = div
.appendElement({ tag: "div", class: "col s11", style: "padding: 0px;" })
.down()
.appendElement({ tag: "ul", class: "collapsible" })
.down();
for (var i = 0; i < accounts.length; i++) {
let li = ul.appendElement({ tag: "li" }).down();
let header = li
.appendElement({ tag: "div", class: "collapsible-header" })
.down();
let content = li
.appendElement({ tag: "div", class: "collapsible-body" })
.down();
let account = accounts[i];
if (this.editable) {
// Here I will display button to edit accounts...
// The delete icon.
// the account header.
header.appendElement({
tag: "span",
class: "col s11",
innerHtml: account.name
});
let deleteBtn = header
.appendElement({
tag: "i",
class: "material-icons col s1",
innerHtml: "delete"
})
.down();
// Now the remove account action.
deleteBtn.element.onclick = () => {
DeleteAccount(
account._id,
() => {
M.toast({
html: "account " + account._id + " have been removed!",
displayLength: 2000
});
// refresh the interface.
this.displayAccounts();
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
}
);
};
} else {
header.appendElement({
tag: "span",
class: "col s12",
innerHtml: account.name
});
}
// Display the account.
this.displayAccount(content, account);
}
// init all collapsible panels...
M.Collapsible.init(ul.element);
},
(err: any) => {
M.toast({ html: getErrorMessage(err.message), displayLength: 2000 });
}
);
}
}