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);