class RolesViewController extends OnTimeViewController { constructor(element) { super(element); this.roleCells = { }; this.resourceDependencies = { user: { user_role: "r" }, user_samerole: { user: "r", project_user: "r" }, user_all: { user_samerole: "r" }, card: { project: "r", card_category: "r" }, project_user: { project: "r" }, report_project: { project: "r" }, period: { card: "r" } }; OnTime.userManager.addEventListener("roleadded", this.onRoleAdded.bind(this)); OnTime.userManager.addEventListener("rolechanged", this.onRoleChanged.bind(this)); OnTime.userManager.addEventListener("roleremoved", this.onRoleRemoved.bind(this)); } viewDidLoad() { this.rolesTableController.addEventListener("cellselected", this.onCellSelected.bind(this)); this.newRoleCell = new TableViewCell(); this.newRoleCell.titleLabel.innerText = "New Role"; //Index the permissions table. var permissionSelects = this.permissionsTable.querySelectorAll("input[type=\"radio\"].permission-radio"); this.resourceKeys = [ ]; for (var i = 0; i < permissionSelects.length; i++) { if (this.resourceKeys.indexOf(permissionSelects[i].name) == -1) { this.resourceKeys.push(permissionSelects[i].name); } } } onRoleAdded(event) { var roleCell = new TableViewCell(); roleCell.titleLabel.innerText = event.role.name; roleCell.role = event.role; this.rolesTableController.addCell(roleCell); this.roleCells[event.role.role_key] = roleCell; if (this.waitingForRoleCreation) { this.waitingForRoleCreation = false; this.rolesTableController.selectCell(roleCell); } } onRoleChanged(event) { if (!(event.role.role_key in this.roleCells)) { return; } var roleCell = this.roleCells[event.role.role_key]; roleCell.titleLabel = event.role.name; roleCell.role = event.role; } onRoleRemoved(event) { if (!(event.role.role_key in this.roleCells)) { return; } var roleCell = this.roleCells[event.role.role_key]; this.rolesTableController.removeCell(roleCell); delete this.roleCells[event.role.role_key]; } onCellSelected(event) { if (!event.cell) { this.roleSettingsSheet.style.display = "none"; this.selectedRole = null; } else { //Hide the new project cell if another cell was selected. if (this.isNewRole && event.cell != this.newRoleCell) { this.onDeleteButtonPressed(event); } this.setRoleData(event.cell.role); this.roleSettingsSheet.style.display = ""; } } /** * Reads the permission radio buttons and assembles them into an object. */ gatherPermissionData() { var permissions = { }; for (var i = 0; i < this.resourceKeys.length; i++) { var resourceKey = this.resourceKeys[i]; var noRightsRadio = this.permissionsTable.querySelector("input[type=\"radio\"].permission-radio[name=\"" + resourceKey + "\"].no-rights"); var readRadio = this.permissionsTable.querySelector("input[type=\"radio\"].permission-radio[name=\"" + resourceKey + "\"].read"); var writeRadio = this.permissionsTable.querySelector("input[type=\"radio\"].permission-radio[name=\"" + resourceKey + "\"].write"); var permission = (writeRadio.checked ? "w" : (readRadio.checked ? "r" : null)); if (permission) { permissions[resourceKey] = permission; } } return permissions; } setRoleData(role) { this.selectedRole = role; this.roleNameField.value = role.name; //Populate the permissions table. for (var i = 0; i < this.resourceKeys.length; i++) { if (this.resourceKeys[i] in role.permissions) { this.setPermission(this.resourceKeys[i], role.permissions[this.resourceKeys[i]]); } else { this.setPermission(this.resourceKeys[i], false); } } //Hide the delete button if this is the session user's role. //If this is the case, also disable the radio buttons. var radioButtons = this.permissionsTable.querySelectorAll("input[type=\"radio\"].permission-radio"); for (var i = 0; i < radioButtons.length; i++) { radioButtons[i].disabled = (OnTime.userManager.sessionUser.role_key == role.role_key); } if (OnTime.userManager.sessionUser.role_key == role.role_key) { this.deleteRoleButton.disabled = true; this.ownRoleInformation.style.display = ""; } else { this.deleteRoleButton.disabled = false; this.ownRoleInformation.style.display = "none"; } this.updatePermissions(); } respectDependencies(resource) { //Just return if there are no dependencies. if (!(resource in this.resourceDependencies)) { return; } var dependencies = this.resourceDependencies[resource]; for (var dependency in dependencies) { var type = dependencies[dependency]; var dependencyRadio = this.permissionsTable.querySelector("input[type=\"radio\"].permission-radio[name=\"" + dependency + "\"]." + (type == "w" ? "write" : "read")); var noRightsRadio = this.permissionsTable.querySelector("input[type=\"radio\"].permission-radio[name=\"" + dependency + "\"].no-rights"); var readRadio = this.permissionsTable.querySelector("input[type=\"radio\"].permission-radio[name=\"" + dependency + "\"].read"); //Check if the dependency is not already met. if (!(dependency in this.selectedRole.permissions) || (type == "w" && this.selectedRole.permissions[dependency] == "r")) { if (this.selectedRole.permissions[resource]) { this.setPermission(dependency, type); } } if (resource in this.selectedRole.permissions) { noRightsRadio.disabled = true; if (type == "w") { readRadio.disabled = true; } } else { noRightsRadio.disabled = false; if (type == "w") { readRadio.disabled = false; } } } } setPermission(resource, type = false) { var noRightsRadio = this.permissionsTable.querySelector("input[type=\"radio\"].permission-radio[name=\"" + resource + "\"].no-rights"); var readRadio = this.permissionsTable.querySelector("input[type=\"radio\"].permission-radio[name=\"" + resource + "\"].read"); var writeRadio = this.permissionsTable.querySelector("input[type=\"radio\"].permission-radio[name=\"" + resource + "\"].write"); noRightsRadio.checked = false; readRadio.checked = false; writeRadio.checked = false; if (!type) { noRightsRadio.checked = true; } else if (type == "r") { readRadio.checked = true; } else if (type == "w") { writeRadio.checked = true; } if (type) { this.selectedRole.permissions[resource] = type; } else { delete this.selectedRole.permissions[resource]; } //Only check the dependencies when the type is "r" or "w". this.respectDependencies(resource); } /** * Takes the input and puts it into an object which will then be sent to the server. */ saveRole() { if (this.roleNameField.value && this.roleNameField.value.length > 0) { var role = { name: this.roleNameField.value, permissions: this.gatherPermissionData() }; if (this.isNewRole) { if (!this.waitingForRoleCreation) { OnTime.userManager.createRole(role); this.waitingForRoleCreation = true; } } else { role.role_key = this.selectedRole.role_key; OnTime.userManager.updateRole(role); } } } onFieldChanged(event) { this.saveRole(); } onPermissionRadioChanged(event) { this.setPermission(event.currentTarget.name, (event.currentTarget.className.indexOf("no-rights") != -1 ? false : (event.currentTarget.className.indexOf("read") != -1 ? "r" : (event.currentTarget.className.indexOf("write") != -1 ? "w" : false)))); this.saveRole(); } onDeleteButtonPressed(event) { if (this.isNewRole) { this.isNewRole = false; this.rolesTableController.removeCell(this.newRoleCell); } else { OnTime.userManager.deleteRole(this.selectedRole); } } onCreateButtonPressed(event) { this.isNewRole = true; this.newRoleCell.role = { name: "", permissions: { } }; this.rolesTableController.addCell(this.newRoleCell); this.rolesTableController.selectCell(this.newRoleCell); this.roleNameField.focus(); } } UIKit.registerViewControllerType(RolesViewController);