globular-mvc
Version:
Generic template to create web-application that made use of globular as backend and materialize as css (wrap in web-component's)
1,101 lines (926 loc) • 38 kB
JavaScript
// I will made use of polymer instead of materialyze for the main
// layout because materialyse dosen't react to well with the shadow doom.
import "@polymer/iron-icon/iron-icon.js";
import "@polymer/iron-icons/social-icons";
import "@polymer/iron-icons/iron-icons.js";
import "@polymer/paper-icon-button/paper-icon-button.js";
import "@polymer/paper-ripple/paper-ripple.js";
import "@polymer/paper-input/paper-input.js";
import "@polymer/paper-card/paper-card.js";
import "@polymer/paper-button/paper-button.js";
import "@polymer/paper-checkbox/paper-checkbox.js";
import "./Session"
import "./DiskSpace.js"
import { PasswordInput } from "./Password"
import { Menu } from "./Menu";
import { generatePeerToken, Model } from "../Model";
import { Account, AddAccountRoleRqst, AddGroupMemberAccountRqst, AddOrganizationAccountRqst, DeleteAccountRqst, GetAccountsRqst, RegisterAccountRqst, RemoveAccountRoleRqst, RemoveGroupMemberAccountRqst, RemoveOrganizationAccountRqst } from "globular-web-client/resource/resource_pb";
import { getAllGroups, getAllRoles } from 'globular-web-client/api';
import { getAllOrganizations } from "./Organization";
import { SearchableGroupList, SearchableOrganizationList, SearchableRoleList } from "./List";
import { ApplicationView } from "../ApplicationView";
import { localToGlobal } from "./utility";
import { Picker } from "emoji-picker-element";
import { Application } from "../Application";
import { Connection } from "globular-web-client/persistence/persistence_pb";
import { SetPasswordRequest } from "globular-web-client/authentication/authentication_pb";
function getAllAccountsInfo_(globule, callback, errorCallback) {
let rqst = new GetAccountsRqst
rqst.setQuery("{}")
let accounts = [];
let stream = globule.resourceService.getAccounts(rqst,
{
domain: Model.domain,
address: Model.address,
application:
Model.application,
token: localStorage.getItem("user_token")
});
// Get the stream and set event on it...
stream.on("data", (rsp) => {
rsp.getAccountsList().forEach(a => {
// the data will be keep in the local storage if the user was once log on that computer.
if (localStorage.getItem(a.getId()) != undefined) {
let data = JSON.parse(localStorage.getItem(a.getId()))
a.profilePicture_ = data.profilePicture_
a.firstName_ = data.firstName_
a.lastName_ = data.lastName_
a.globule = globule // keep reference to the parent globule.
}
accounts.push(a)
})
});
stream.on("status", (status) => {
if (status.code == 0) {
callback(accounts);
} else {
errorCallback({ message: status.details });
}
});
}
/**
* return the all account information.
*/
export function getAllAccountsInfo(callback, errorCallback, external) {
if (external == undefined) {
external = false;
}
// Connections can contain many time the same address....
let globules = Model.getGlobules()
let index = 0
let accounts_ = []
let _getAllAccountsInfo_ = (globule) => {
getAllAccountsInfo_(globule,
(accounts) => {
if (external) {
if (globules[index].config.Mac != Model.globular.config.Mac) {
accounts_ = accounts_.concat(accounts)
}
} else {
accounts_ = accounts_.concat(accounts)
}
// move to the next globule.
index++
if (index < globules.length) {
_getAllAccountsInfo_(globules[index])
} else {
// return the list of all accounts.
callback(accounts_)
}
}, errorCallback)
}
// retreive the list of accounts.
if (globules.length > 0) {
// call onces
_getAllAccountsInfo_(globules[0])
}
}
/**
* Login/Register functionality.
*/
export class AccountMenu extends Menu {
// attributes.
// Create the applicaiton view.
constructor() {
super("account", "account-circle", "session");
this.ico = null;
this.img = null;
this.accountUpdateListener = null;
}
init() {
//super.init()
this.account = null;
// Reset the account.
Model.eventHub.subscribe("logout_event_",
(uuid) => { },
(dataUrl) => {
this.account = null;
this.resetProfilePicture()
},
true, this)
// Refresh account event.
}
// Set the account information.
setAccount(account) {
this.account = account;
// Set the data url.
Model.globular.eventHub.subscribe(`__update_account_${account._id + "@" + account.domain}_data_evt__`,
(uuid) => {
this.accountUpdateListener = uuid;
},
(data) => {
this.setProfilePicture(data.profilePicture_)
},
true, this)
let html = `
<style>
#accout-menu-header{
display: flex;
font-size: 12pt;
line-height: 1.6rem;
align-items: center;
margin-bottom: 16px;
}
#account-header-id{
font-weight: 500;
}
#title{
display: none;
justify-content: center;
}
#account_menu_div{
min-width: 300px;
}
(max-width: 700px) {
#account_menu_div{
margin-top: 25px;
height: 100%;
}
#title{
display: flex;
}
}
#account-header-id{
}
#icon-div iron-icon{
padding-right: 10px;
}
#profile-picture{
width: 64px;
height: 64px;
padding-right: 10px;
border-radius: 20px;
border: 1px solid transparent;
display: none;
}
#profile-picture:hover{
cursor: pointer;
}
#icon-div iron-icon:hover{
cursor: pointer;
}
#profile-icon {
fill: var(--palette-text-primary);
}
.card-actions{
display: flex;
justify-content: flex-end;
background-color: var(--palette-background-paper);
color: var(--palette-text-primary);
}
paper-card{
background-color: var(--palette-background-paper);
color: var(--palette-text-primary);
}
paper-button {
font-size: 1rem;
}
.card-content{
display: flex;
flex-direction: column;
background-color: var(--palette-background-paper);
color: var(--palette-text-primary);
}
#header h1 {
font-size: 1.65rem;
margin: 0px;
margin-bottom: 10px;
}
</style>
<div class="card-content">
<div id="header" style="width: 100%;">
<div id="title">
<h1 style="flex-grow: 1;">Session</h1>
<paper-icon-button id="close-btn" icon="icons:close" role="button" tabindex="0" aria-disabled="false"></paper-icon-button>
</div>
</div>
<div id="accout-menu-header">
<div id="icon-div" title="click here to change profile picture">
<iron-icon id="profile-icon" icon="account-circle"></iron-icon>
<img id="profile-picture"></img>
</div>
<div>
<span id="account-header-id">
${account.name}
</span>
<span id="account-header-email">
${account.email}
</span>
</div>
</div>
<globular-session-state account="${account.id + "@" + account.domain}" editable state="online"></globular-session-state>
</div>
<div class="card-actions">
<paper-button id="settings_btn" >settings
<iron-icon style="padding-left: 5px;" icon="settings"></iron-icon>
</paper-button>
<paper-button id="logout_btn" >logout
<iron-icon style="padding-left: 5px;" icon="exit-to-app"></iron-icon>
</paper-button>
</div>
`;
let range = document.createRange();
this.getMenuDiv().innerHTML = ""; // remove existing elements.
this.getMenuDiv().appendChild(range.createContextualFragment(html));
this.getMenuDiv().querySelector("#close-btn").onclick = () => {
this.getMenuDiv().parentNode.removeChild(this.getMenuDiv())
}
// Set the account.
this.getMenuDiv().querySelector("globular-session-state").account = account
this.getMenuDiv().querySelector("globular-session-state").init()
// Action's
this.shadowRoot.appendChild(this.getMenuDiv());
// The Settings event.
this.shadowRoot.getElementById("settings_btn").onclick = () => {
Model.eventHub.publish("settings_event_", {}, true);
};
// The logout event.
this.shadowRoot.getElementById("logout_btn").onclick = () => {
Model.eventHub.publish("logout_event_", {}, true);
};
this.img = this.shadowRoot.getElementById("profile-picture");
this.ico = this.shadowRoot.getElementById("profile-icon");
if (account.profilePicture_ != undefined) {
this.setProfilePicture(account.profilePicture_);
}
this.shadowRoot.removeChild(this.getMenuDiv());
}
resetProfilePicture() {
// reset the display
this.getIcon().style.display = "block";
this.getImage().style.display = "none";
this.getImage().src = "";
if (this.img != undefined) {
this.img.src = "";
this.img.style.display = "none";
}
if (this.ico != undefined) {
this.ico.style.display = "block";
}
}
/**
* Set the profile picture with the given data url.
* @param {*} dataUrl
*/
setProfilePicture(dataUrl) {
// The account, and data url must be valid.
if (this.account == null) {
this.resetProfilePicture()
return;
}
if (dataUrl == undefined) {
this.resetProfilePicture()
return
}
if (dataUrl.length == 0) {
this.resetProfilePicture()
return;
}
// Here the account has a profile picture.
this.getIcon().style.display = "none";
this.getImage().style.display = "block";
this.getImage().src = dataUrl;
// The profile in the menu.
let isClose =
this.shadowRoot.getElementById("profile-picture") == undefined;
if (isClose) {
this.shadowRoot.appendChild(this.getMenuDiv());
}
if (this.img != undefined) {
this.img.src = dataUrl;
this.img.style.display = "block";
}
if (this.ico != undefined) {
this.ico.style.display = "none";
}
if (isClose) {
this.shadowRoot.removeChild(this.getMenuDiv());
}
}
}
customElements.define("globular-account-menu", AccountMenu);
/**
* The way to manage account informations.
*/
export class AccountManager extends HTMLElement {
// attributes.
// Create the applicaiton view.
constructor() {
super()
// Set the shadow dom.
this.attachShadow({ mode: 'open' });
// Innitialisation of the layout.
this.shadowRoot.innerHTML = `
<style>
#create-account-btn{
top: -42px;
right: 0px;
position: absolute;
}
#container{
display: flex;
flex-direction: column;
position: relative;
}
.card-content {
min-width: 728px;
padding: 0px;
font-size: 1rem;
}
(max-width: 800px) {
.card-content{
min-width: 580px;
}
}
(max-width: 600px) {
.card-content{
min-width: 380px;
}
}
paper-card{
background-color: var(--palette-background-paper);
color: var(--palette-text-primary);
}
</style>
<div id="container">
<paper-card>
<div class="card-content">
</div>
</paper-card>
<paper-icon-button icon="add" id="create-account-btn"></paper-icon-button>
</div>
`
// give the focus to the input.
let content = this.shadowRoot.querySelector(".card-content")
// give the focus to the input.
let container = this.shadowRoot.querySelector("#container")
let displayAccounts = () => {
content.innerHTML = ""
// Here I will get the list of all accounts.
getAllAccountsInfo_(
Model.globular,
(accounts) => {
accounts.forEach(a => {
if (a.getId() != "admin" && a.getId() != "guest") {
let panel = new AccountPanel(a)
content.appendChild(panel)
}
})
}, err => { ApplicationView.displayMessage(err, 3000) })
}
// call once
displayAccounts()
Model.globular.eventHub.subscribe("refresh_account_evt", uuid => { }, evt => {
displayAccounts()
}, true)
let createAccountBtn = this.shadowRoot.querySelector("#create-account-btn")
createAccountBtn.onclick = () => {
let html = `
<style>
#create-account-panel{
position: absolute;
right: 0px;
top: 0px;
z-index: 1;
background-color: var(--palette-background-paper);
}
#create-account-panel .card-content{
min-width: 200px;
padding: 0px 10px 0px 10px;
display: flex;
flex-direction: column;
}
paper-card{
background-color: var(--palette-background-paper);
color: var(--palette-text-primary);
}
</style>
<paper-card id="create-account-panel">
<div style="display: flex; align-items: center;">
<div style="flex-grow: 1; padding: 5px;">
Create account
</div>
<paper-icon-button id="cancel-btn" icon="close"></paper-icon-button>
</div>
<div class="card-content">
<paper-input></paper-input>
<paper-button style="align-self: end;">Create</paper-button>
</div>
</paper-card>
`
let panel = container.querySelector("#create-account-panel")
let input = null
if (panel == undefined) {
container.appendChild(document.createRange().createContextualFragment(html))
panel = container.querySelector("#create-account-panel")
let closeBtn = panel.querySelector("#cancel-btn")
closeBtn.onclick = () => {
panel.parentNode.removeChild(panel)
}
input = panel.querySelector("paper-input")
let createAccountButton = panel.querySelector("paper-button")
// Create a new account.
createAccountButton.onclick = () => {
let accountId = input.value;
if (accountId.length == 0) {
ApplicationView.displayMessage("No account name was given!", 3000)
setTimeout(() => {
input.focus()
}, 100)
return
}
let rqst = new RegisterAccountRqst()
let account = new Account()
account.setId(accountId)
account.setName(accountId)
account.setPassword("1234")
rqst.setConfirmPassword("1234")
rqst.setAccount(account)
Model.globular.resourceService.registerAccount(rqst,
{
domain: Model.domain,
address: Model.address,
application: Model.application,
token: localStorage.getItem("user_token")
})
.then(rsp => {
ApplicationView.displayMessage("account " + accountId + " was created!", 3000)
panel.parentNode.removeChild(panel)
displayAccounts()
}).catch(err => {
ApplicationView.displayMessage(err, 3000)
setTimeout(() => {
input.focus()
}, 100)
})
}
} else {
input = panel.querySelector("paper-input")
}
setTimeout(() => {
input.focus()
}, 100)
}
}
// The connection callback.
connectedCallback() {
}
}
customElements.define('globular-account-manager', AccountManager)
/**
* Display account informations in the manager panel.
*/
export class AccountPanel extends HTMLElement {
// attributes.
// Create the applicaiton view.
constructor(a) {
super()
// Set the shadow dom.
this.attachShadow({ mode: 'open' });
// Keep account informations.
this.account = a;
let profilePicture = this.account.getProfilepicture()
if (!profilePicture) {
profilePicture = ""
}
// Innitialisation of the layout.
this.shadowRoot.innerHTML = `
<style>
#container{
display: flex;
flex-direction: column;
align-items: center;
border-bottom: 1px solid var(--palette-background-default);
background-color: var(--palette-background-paper);
}
#content{
padding: 0px;
padding-top: 16px;
min-width: 728px;
font-size: 1rem;
}
(max-width: 800px) {
.card-content{
min-width: 580px;
}
}
(max-width: 600px) {
.card-content{
min-width: 380px;
}
}
.header{
display: flex;
align-items: center;
width: 100%;
transition: background 0.2s ease,padding 0.8s linear;
background-color: var(--palette-background-paper);
}
.header:hover{
-webkit-filter: invert(10%);
filter: invert(10%);
}
.title{
flex-grow: 1;
margin: 8px;
font-size: 1.1rem;
}
img, iron-icon{
margin: 8px;
}
#collapse-panel{
display: flex;
flex-direction: column;
width: 100%;
}
#delete-account-btn{
font-size: .85rem;
max-height: 32px;
}
paper-tabs {
/* custom CSS property */
--paper-tabs-selection-bar-color: var(--palette-primary-main);
color: var(--palette-text-primary);
--paper-tab-ink: var(--palette-action-disabled);
}
.password-div{
display: flex;
flex-direction: column;
padding: 0px 20px
}
</style>
<div id="container">
<div class="header">
<img style="width: 32px; height: 32px; display: ${profilePicture.length == 0 ? "none" : "block"};" src="${profilePicture}"></img>
<iron-icon icon="account-circle" style="width: 32px; height: 32px; --iron-icon-fill-color:var(--palette-action-disabled); display: ${profilePicture.length > 0 ? "none" : "block"};"></iron-icon>
<span class="title">${this.account.getName() + "@" + this.account.getDomain()}</span>
<globular-disk-space-manager editable="true" account="${this.account.getId() + "@" + this.account.getDomain()}"></globular-disk-space-manager>
<div style="display: flex; width: 32px; height: 32px; justify-content: center; align-items: center;position: relative;">
<iron-icon id="hide-btn" icon="unfold-less" style="flex-grow: 1; --iron-icon-fill-color:var(--palette-text-primary);" icon="add"></iron-icon>
<paper-ripple class="circle" recenters=""></paper-ripple>
</div>
</div>
<iron-collapse id="collapse-panel" >
<div class="password-div" style="display:${this.account.getDomain() == Model.domain && Application.account.id == "sa" && this.account.getId() != "sa" ? 'block' : 'none'};">
<span>set password</span>
<globular-password-input id="new-password" label="new password"></globular-password-input>
<globular-password-input id="confirm-new-password" label="confirm new password"></globular-password-input>
<div style="display: flex;">
<span style="flex-grow: 1;"></span>
<paper-button id="submit-btn" disabled>Submit</paper-button>
</div>
</div>
<paper-tabs selected="0">
<paper-tab id="account-organizations-tab">Organizations</paper-tab>
<paper-tab id="account-roles-tab">Roles</paper-tab>
<paper-tab id="account-groups-tab">Groups</paper-tab>
</paper-tabs>
<div id="content">
</div>
<div style="display: flex; padding-bottom: 10px;">
<span style="flex-grow: 1;"></span>
<paper-button id="delete-account-btn" style="display:${this.account.getDomain() == Model.domain && this.account.getId() != "sa" ? 'block' : 'none'};">Delete</paper-button>
</div>
</iron-collapse>
</div>
`
let togglePanel = this.shadowRoot.querySelector("#collapse-panel")
let content = this.shadowRoot.querySelector("#content")
this.hideBtn = this.shadowRoot.querySelector("#hide-btn")
// The password change
this.newPasswordInput = this.shadowRoot.getElementById("new-password");
this.confirmNewPassword = this.shadowRoot.getElementById("confirm-new-password");
this.submitBtn = this.shadowRoot.querySelector("#submit-btn")
// test if the password match...
this.newPasswordInput.onkeyup = this.confirmNewPassword.onkeyup = () => {
// disabled the submit button
this.submitBtn.setAttribute("disabled", "")
if (this.newPasswordInput.getPassword().length > 0 &&
this.confirmNewPassword.getPassword().length > 0 && this.confirmNewPassword.getPassword() == this.newPasswordInput.getPassword()) {
this.submitBtn.removeAttribute("disabled")
}
}
this.submitBtn.onclick = () => {
let globule = Model.getGlobule(this.account.getDomain())
generatePeerToken(globule, token => {
let rqst = new SetPasswordRequest
rqst.setOldpassword("")
rqst.setNewpassword(this.newPasswordInput.getPassword())
rqst.setAccountid(this.account.getId() + "@" + this.account.getDomain())
globule.authenticationService.setPassword(rqst, { token: token, application: Model.application, domain: globule.domain })
.then(rsp => {
ApplicationView.displayMessage(this.account.getName() + " password was updated!", 3000)
ApplicationView.resume()
}).catch(err => { ApplicationView.displayMessage(err, 3000); ApplicationView.resume() })
})
}
this.shadowRoot.querySelector("globular-disk-space-manager").account = this.account;
// Aggregations
this.organizationsList = null
this.rolesList = null
this.groupsList = null
this.shadowRoot.querySelector("#account-organizations-tab").onclick = () => {
if (this.organizationsList != undefined)
this.organizationsList.style.display = ""
if (this.rolesList != undefined)
this.rolesList.style.display = "none"
if (this.groupsList != undefined)
this.groupsList.style.display = "none"
}
this.shadowRoot.querySelector("#account-groups-tab").onclick = () => {
if (this.organizationsList != undefined)
this.organizationsList.style.display = "none"
if (this.rolesList != undefined)
this.rolesList.style.display = "none"
if (this.groupsList != undefined)
this.groupsList.style.display = ""
}
this.shadowRoot.querySelector("#account-roles-tab").onclick = () => {
if (this.organizationsList != undefined)
this.organizationsList.style.display = "none"
if (this.rolesList != undefined)
this.rolesList.style.display = ""
if (this.groupsList != undefined)
this.groupsList.style.display = "none"
}
let deleteBtn = this.shadowRoot.querySelector("#delete-account-btn")
deleteBtn.onclick = () => {
this.onDeleteaccount(a)
}
// Organization list.
getAllOrganizations(
organizations => {
// I will get the account object whit the given id.
let list = []
this.account.getOrganizationsList().forEach(organizationId => {
let o_ = organizations.find(o => o.getId() + "@" + o.getDomain() === organizationId);
if (o_ != undefined) {
list.push(o_)
}
})
this.organizationsList = new SearchableOrganizationList("Organizations", list,
o => {
let rqst = new RemoveOrganizationAccountRqst
rqst.setOrganizationid(o.getId() + "@" + o.getDomain())
rqst.setAccountid(a.getId() + "@" + a.getDomain())
Model.globular.resourceService.removeOrganizationAccount(rqst, { domain: Model.domain, address: Model.address, application: Model.application, token: localStorage.getItem("user_token") })
.then(rsp => {
this.organizationsList.removeItem(o)
ApplicationView.displayMessage("Account " + a.getId() + "@" + a.getDomain() + " was removed from account " + o.getName() + "@" + o.getDomain(), 3000)
}).catch(err => {
this.organizationsList.appendItem(o) // set it back
ApplicationView.displayMessage(err, 3000)
})
},
o => {
let rqst = new AddOrganizationAccountRqst
rqst.setOrganizationid(o.getId() + "@" + o.getDomain())
rqst.setAccountid(a.getId() + "@" + a.getDomain())
Model.globular.resourceService.addOrganizationAccount(rqst, { domain: Model.domain, address: Model.address, application: Model.application, token: localStorage.getItem("user_token") })
.then(rsp => {
this.organizationsList.appendItem(o)
ApplicationView.displayMessage("Account " + a.getId() + "@" + a.getDomain() + " has now organization " + o.getName() + "@" + o.getDomain(), 3000)
}).catch(err => {
this.organizationsList.removeItem(o)
ApplicationView.displayMessage(err, 3000)
})
})
content.appendChild(this.organizationsList)
}, err => {
ApplicationView.displayMessage(err, 3000)
})
// The role list.
getAllRoles(Model.globular,
roles => {
// I will get the account object whit the given id.
let list = []
this.account.getRolesList().forEach(roleId => {
let r_ = roles.find(r => r.getId() + "@" + r.getDomain() === roleId);
if (r_ != undefined) {
list.push(r_)
}
})
this.rolesList = new SearchableRoleList("Roles", list,
r => {
this.rolesList.removeItem(r)
let rqst = new RemoveAccountRoleRqst
rqst.setAccountid(a.getId() + "@" + a.getDomain())
rqst.setRoleid(r.getId() + "@" + r.getDomain())
Model.globular.resourceService.removeAccountRole(rqst, { domain: Model.domain, address: Model.address, application: Model.application, token: localStorage.getItem("user_token") })
.then(rsp => {
this.rolesList.removeItem(r)
ApplicationView.displayMessage("Role " + r.getName() + "@" + r.getDomain() + " was removed from account " + a.getName() + "@" + a.getDomain(), 3000)
}).catch(err => {
this.rolesList.appendItem(r) // set it back
ApplicationView.displayMessage(err, 3000)
})
},
r => {
let rqst = new AddAccountRoleRqst
rqst.setAccountid(a.getId() + "@" + a.getDomain())
rqst.setRoleid(r.getId() + "@" + r.getDomain())
Model.globular.resourceService.addAccountRole(rqst, { domain: Model.domain, address: Model.address, application: Model.application, token: localStorage.getItem("user_token") })
.then(rsp => {
this.rolesList.appendItem(r)
ApplicationView.displayMessage("Role " + r.getName() + "@" + r.getDomain() + " has now account " + a.getName() + "@" + a.getDomain(), 3000)
}).catch(err => {
this.rolesList.removeItem(r)
ApplicationView.displayMessage(err, 3000)
})
})
content.appendChild(this.rolesList)
}, err => {
ApplicationView.displayMessage(err, 3000)
})
// The applications list.
getAllGroups(Model.globular,
groups => {
// I will get the account object whit the given id.
let list = []
this.account.getGroupsList().forEach(groupId => {
let g_ = groups.find(g => g.getId() + "@" + g.getDomain() === groupId);
if (g_ != undefined) {
list.push(g_)
}
})
this.groupsList = new SearchableGroupList("Groups", list,
g => {
this.groupsList.removeItem(g)
let rqst = new RemoveGroupMemberAccountRqst
rqst.setAccountid(a.getId() + "@" + a.getDomain())
rqst.setGroupid(g.getId() + "@" + g.getDomain())
Model.globular.resourceService.removeGroupMemberAccount(rqst, { domain: Model.domain, address: Model.address, application: Model.application, token: localStorage.getItem("user_token") })
.then(rsp => {
this.groupsList.removeItem(g)
ApplicationView.displayMessage("Group " + g.getName() + "@" + g.getDomain() + " was removed from account " + a.getName() + "@" + a.getDomain(), 3000)
}).catch(err => {
this.groupsList.appendItem(g) // set it back
ApplicationView.displayMessage(err, 3000)
})
},
g => {
let rqst = new AddGroupMemberAccountRqst
rqst.setAccountid(a.getId() + "@" + a.getDomain())
rqst.setGroupid(g.getId() + "@" + g.getDomain())
Model.globular.resourceService.addGroupMemberAccount(rqst, { domain: Model.domain, address: Model.address, application: Model.application, token: localStorage.getItem("user_token") })
.then(rsp => {
this.groupsList.appendItem(g)
ApplicationView.displayMessage("Group " + g.getName() + "@" + g.getDomain() + " has now account " + a.getName() + "@" + a.getDomain(), 3000)
}).catch(err => {
this.groupsList.removeItem(g)
ApplicationView.displayMessage(err, 3000)
})
})
content.appendChild(this.groupsList)
}, err => {
ApplicationView.displayMessage(err, 3000)
})
// give the focus to the input.
this.hideBtn.onclick = () => {
let button = this.shadowRoot.querySelector("#hide-btn")
if (button && togglePanel) {
if (!togglePanel.opened) {
button.icon = "unfold-more"
} else {
button.icon = "unfold-less"
}
togglePanel.toggle();
}
}
}
onDeleteaccount(a) {
let toast = ApplicationView.displayMessage(
`
<style>
#yes-no-contact-delete-box{
display: flex;
flex-direction: column;
}
#yes-no-contact-delete-box globular-contact-card{
padding-bottom: 10px;
}
#yes-no-contact-delete-box div{
display: flex;
padding-bottom: 10px;
}
paper-button{
font-size: .85rem;
height: 32px;
}
</style>
<div id="yes-no-account-delete-box">
<div>Your about to delete the account ${a.getName() + "@" + a.getDomain()}</div>
<div>Is it what you want to do? </div>
<div style="justify-content: flex-end;">
<paper-button id="yes-delete-account">Yes</paper-button>
<paper-button id="no-delete-account">No</paper-button>
</div>
</div>
`,
15000 // 15 sec...
);
let yesBtn = document.querySelector("#yes-delete-account")
let noBtn = document.querySelector("#no-delete-account")
// On yes
yesBtn.onclick = () => {
let rqst = new DeleteAccountRqst
rqst.setId(a.getId())
Model.globular.resourceService.deleteAccount(rqst, { domain: Model.domain, address: Model.address, application: Model.application, token: localStorage.getItem("user_token") }).then((rsp) => {
ApplicationView.displayMessage(
"<iron-icon icon='communication:message' style='margin-right: 10px;'></iron-icon><div>account named " +
a.getName() + "@" + a.getDomain() +
" was deleted!</div>",
3000
);
Model.globular.eventHub.publish("refresh_account_evt", {}, true)
toast.dismiss();
}).catch(e => {
ApplicationView.displayMessage(e, 3000)
toast.dismiss();
})
}
noBtn.onclick = () => {
toast.dismiss();
}
}
connectedCallback() {
this.shadowRoot.querySelector("#account-organizations-tab").click()
}
}
customElements.define('globular-account-panel', AccountPanel)
/**
* Display list of account not manage by this peer...
*/
export class ExternalAccountManager extends HTMLElement {
// attributes.
// Create the applicaiton view.
constructor() {
super()
// Set the shadow dom.
this.attachShadow({ mode: 'open' });
// Innitialisation of the layout.
this.shadowRoot.innerHTML = `
<style>
#container{
display: flex;
flex-direction: column;
margin-top: 64px;
}
.title{
font-size: 1rem;
color: var(--cr-primary-text-color);
padding-left: 8px;
padding-bottom: 35px;
}
paper-card{
background-color: var(--palette-background-paper);
color: var(--palette-text-primary);
}
.card-content{
padding: 0px;
}
</style>
<div id="container">
<div class="title">Manage external accounts</div>
<paper-card>
<div class="card-content">
<slot>
</slot>
<div>
</paper-card>
</div>
`
// give the focus to the input.
let container = this.shadowRoot.querySelector("#container")
getAllAccountsInfo(accounts => {
accounts.forEach(a => {
// I will manage only regular user account
if (a.getId() != "sa") {
let panel = new AccountPanel(a)
this.appendChild(panel)
}
})
}, err => ApplicationView.displayMessage(err, 3000), true)
}
}
customElements.define('globular-external-account-manager', ExternalAccountManager)