class UsersViewController extends OnTimeViewController {
constructor(element) {
super(element);
this.userCells = { };
OnTime.userManager.addEventListener("useradded", this.onUserAdded.bind(this));
OnTime.userManager.addEventListener("userchanged", this.onUserChanged.bind(this));
OnTime.userManager.addEventListener("userremoved", this.onUserRemoved.bind(this));
OnTime.projectManager.addEventListener("projectchanged", this.onProjectChanged.bind(this));
this.deleteUserDialog = new Dialog("Are you sure you want to delete this employee?
They will no longer be able to log in. The recorded time periods will not be deleted.", this.onDeleteDialogReturned.bind(this), Dialog.BUTTONS_DESTRUCTIVE);
}
viewDidLoad() {
this.usersTableController.addEventListener("cellselected", this.onCellSelected.bind(this));
this.newUserCell = new TableViewCell();
this.newUserCell.titleLabel.innerText = "New Employee";
}
onUserAdded(event) {
var userCell = new TableViewCell();
userCell.titleLabel.innerText = event.user.full_name;
userCell.subtitleLabel.innerText = OnTime.userManager.roles[event.user.role_key].name;
userCell.user = event.user;
this.usersTableController.addCell(userCell, (event.user == OnTime.userManager.sessionUser ? 0 : 1));
this.userCells[event.user.email] = userCell;
if (this.waitingForUserCreation) {
this.waitingForUserCreation = false;
this.usersTableController.selectCell(userCell);
}
}
onUserChanged(event) {
if (!(event.user.email in this.userCells)) {
return;
}
var userCell = this.userCells[event.user.email];
userCell.titleLabel.innerText = event.user.full_name;
userCell.subtitleLabel.innerText = OnTime.userManager.roles[event.user.role_key].name;
userCell.user = event.user;
if (this.selectedUser && event.user.email == this.selectedUser.email) {
this.selectedUser = event.user;
}
}
onUserRemoved(event) {
if (!(event.user.email in this.userCells)) {
return;
}
var userCell = this.userCells[event.user.email];
this.usersTableController.removeCell(userCell);
delete this.userCells[event.user.email];
}
onCellSelected(event) {
if (!event.cell) {
this.userSettingsSheet.style.display = "none";
this.selectedUser = null;
}
else {
//Hide the new user cell if another cell was selected.
if (this.isNewUser && event.cell != this.newUserCell) {
this.onDeleteButtonPressed(event);
}
this.setUserData(event.cell.user);
this.userSettingsSheet.style.display = "";
}
}
onFieldChanged(event) {
//Return if the field values are not properly given.
if (!this.fullNameField.value || !this.usernameField.value || !this.emailField.value || (!this.defaultTariffField.value && this.defaultTariffField.value !== 0) || !this.roleSelect.value) {
return;
}
var user = {
full_name: this.fullNameField.value,
username: this.usernameField.value,
role_key: this.roleSelect.value,
default_tariff: this.defaultTariffField.value,
projects: this.gatherProjectAssociations()
};
if (this.isNewUser) {
if (!this.waitingForUserCreation) {
user.email = this.emailField.value;
OnTime.userManager.createUser(user);
this.waitingForUserCreation = true;
}
}
else {
user.email = this.selectedUser.email;
user.new_email = this.emailField.value;
OnTime.userManager.updateUser(user);
}
//Update the project tariff field placeholders.
for (var projectKey in this.tariffFields) {
this.tariffFields[projectKey].placeholder = user.default_tariff;
}
//Refresh the projects if the "All projects" radio button was selected.
if (event.currentTarget == this.allProjectsRadio) {
OnTime.projectManager.loadProjects();
}
}
/**
* Returns an array of all the projects currently in the projects table.
*/
gatherProjectAssociations() {
//If the "All" radio button is selected, return an array containing an asterisk string.
if (this.allProjectsRadio.checked) {
return { "*": null };
}
var buttons = this.projectsTableBody.querySelectorAll("button");
var projects = { };
for (var i = 0; i < buttons.length; i++) {
var tariff = this.tariffFields[buttons[i].value].value;
projects[buttons[i].value] = tariff == "" ? null : tariff;
}
return projects;
}
setUserData(user) {
this.selectedUser = user;
this.fullNameField.value = user.full_name;
this.usernameField.value = user.username;
this.emailField.value = user.email;
this.roleSelect.value = user.role_key;
this.defaultTariffField.value = user.default_tariff;
//Clear the project association table.
while (this.projectsTableBody.children.length > 0) {
this.projectsTableBody.removeChild(this.projectsTableBody.firstChild);
}
//Enable all options in the select.
for (var i = 0; i < this.projectSelect.options.length; i++) {
this.projectSelect.options[i].disabled = false;
}
this.projectSelect.value = "";
//Add the new project associations.
for (var projectKey in user.projects) {
if (projectKey == "*") {
this.allProjectsRadio.checked = true;
}
else {
this.customProjectsRadio.checked = true;
this.addProjectAssociation(projectKey, user.projects[projectKey]);
}
}
if ((Array.isArray(user.projects) && user.projects.length == 0) || Object.keys(user.projects).length == 0) {
this.customProjectsRadio.checked = true;
}
//Show or hide the own user notification and prevent the editing of the own user and projects settings.
this.ownRoleInformation.style.display = user.email == OnTime.userManager.sessionUser.email ? "" : "none";
//this.allProjectsRadio.disabled = user.email == OnTime.userManager.sessionUser.email; //Removed because a user may always edit its own project associations if the user has the permission to do so in general.
//this.customProjectsRadio.disabled = user.email == OnTime.userManager.sessionUser.email;
//this.assignProjectButton.disabled = user.email == OnTime.userManager.sessionUser.email;
//this.projectSelect.disabled = user.email == OnTime.userManager.sessionUser.email;
this.deleteButton.disabled = user.email == OnTime.userManager.sessionUser.email;
this.ownUserDeletionInformation.style.display = user.email == OnTime.userManager.sessionUser.email ? "" : "none";
this.roleSelect.disabled = user.email == OnTime.userManager.sessionUser.email;
this.updatePermissions();
}
addProjectAssociation(projectKey, tariff = null) {
var associationRow = document.createElement("TR");
associationRow.id = "project-association__" + projectKey;
//The left cell.
var projectNameCell = document.createElement("TD");
projectNameCell.innerText = OnTime.projectManager.getProjectByKey(projectKey).name;
projectNameCell.style.paddingLeft = "0.25em";
projectNameCell.className = "project-name-cell";
associationRow.appendChild(projectNameCell);
//The right cell.
var rightCell = document.createElement("TD");
rightCell.style.textAlign = "right";
associationRow.appendChild(rightCell);
var tariffField = document.createElement("INPUT");
tariffField.type = "number";
tariffField.value = tariff;
tariffField.id = "project-tariff-field__" + projectKey;
tariffField.placeholder = this.selectedUser.default_tariff;
tariffField.className = "tariff-field available__multiuser available_w__project_user";
tariffField.addEventListener("change", this.onFieldChanged.bind(this));
//tariffField.disabled = (this.selectedUser.email == OnTime.userManager.sessionUser.email) && ("multiuser" in OnTime.userManager.permissions);
rightCell.appendChild(tariffField);
if (!this.tariffFields) {
this.tariffFields = { };
}
this.tariffFields[projectKey] = tariffField;
var perHourLabel = document.createElement("LABEL");
perHourLabel.setAttribute("for", "project-tariff-field__" + projectKey);
perHourLabel.innerText = "/ h";
rightCell.appendChild(perHourLabel);
var removeButton = document.createElement("BUTTON");
removeButton.innerText = "Remove";
removeButton.value = projectKey;
removeButton.addEventListener("click", this.onRemoveProjectButtonPressed.bind(this));
//removeButton.disabled = this.selectedUser.email == OnTime.userManager.sessionUser.email;
removeButton.className = "require__multiuser available_w__project_user";
rightCell.appendChild(removeButton);
this.projectsTableBody.appendChild(associationRow);
//Disable this option in the select.
for (var i = 0; i < this.projectSelect.options.length; i++) {
if (this.projectSelect.options[i].value == projectKey) {
this.projectSelect.options[i].disabled = true;
break;
}
}
}
onDeleteButtonPressed(event) {
if (this.isNewUser) {
this.isNewUser = false;
this.usersTableController.removeCell(this.newUserCell);
}
else {
this.deleteUserDialog.show();
}
}
onDeleteDialogReturned(buttonId) {
if (buttonId == "delete") {
OnTime.userManager.deleteUser(this.selectedUser);
}
}
onCreateButtonPressed(event) {
this.isNewUser = true;
this.newUserCell.user = {
full_name: "",
email: "",
username: "",
role_key: "",
default_tariff: 0,
projects: { }
};
this.usersTableController.addCell(this.newUserCell, 1);
this.usersTableController.selectCell(this.newUserCell);
this.fullNameField.focus();
}
onAssignProjectButtonPressed(event) {
if (!this.projectSelect.value) {
return;
}
this.addProjectAssociation(this.projectSelect.value);
//Update the user.
this.onFieldChanged(event);
this.projectSelect.value = "";
/*this.addProjectButtonRow.style.display = "";
this.addProjectRow.style.display = "none";*/
}
onAssignNewProjectButtonPressed(event) {
/*this.addProjectButtonRow.style.display = "none";
this.addProjectRow.style.display = "";*/
}
onRemoveProjectButtonPressed(event) {
if (event.currentTarget.value in this.selectedUser.projects) {
//Rwmove the row from the table.
for (var i = 0; i < this.projectsTableBody.children.length; i++) {
if (this.projectsTableBody.children[i].id == "project-association__" + event.currentTarget.value) {
this.projectsTableBody.removeChild(this.projectsTableBody.children[i]);
break;
}
}
//Delete the tariff field reference.
delete this.tariffFields[event.currentTarget.value];
//Update the user.
this.onFieldChanged(event);
//Re-enable this option in the select.
for (var i = 0; i < this.projectSelect.options.length; i++) {
if (this.projectSelect.options[i].value == event.currentTarget.value) {
this.projectSelect.options[i].disabled = false;
break;
}
}
}
}
onProjectChanged(event) {
//Update the changed project in the associations list.
if (event.project.project_key in this.selectedUser.projects) {
for (var i = 0; i < this.projectsTableBody.children.length; i++) {
if (this.projectsTableBody.children[i].id == "project-association__" + event.project.project_key) {
this.projectsTableBody.children[i].querySelector(".project-name-cell").innerText = event.project.name;
break;
}
}
}
}
}
UIKit.registerViewControllerType(UsersViewController);