class ProjectManager extends Listenable { constructor() { super(); this.projectListeners = { }; this.projects = { }; this.loadProjectsRequest = new Request(TimeCards.REQUEST_URI + "Projects", Request.GET, this.loadedProjects.bind(this), this.projectLoadingError.bind(this)); this.loadProjectsInterval = setInterval(this.loadProjects.bind(this), 60000); this.loadProjects(); this.deleteProjectRequest = new Request(TimeCards.REQUEST_URI + "Project/Delete", Request.POST, this.deletedProject.bind(this), this.projectDeletionError.bind(this)); this.createProjectRequest = new Request(TimeCards.REQUEST_URI + "Project/Create", Request.POST, this.createdProject.bind(this), this.projectCreationError.bind(this)); this.updateProjectRequest = new Request(TimeCards.REQUEST_URI + "Project", Request.POST, this.updatedProject.bind(this), this.projectUpdatingError.bind(this)); } performInitialCalls(eventType, callback) { if (eventType == "projectadded") { for (var projectId in this.projects) { var addedProject = this.projects[projectId]; var projectAddedEvent = new Event("projectadded"); projectAddedEvent.project = addedProject; callback(projectAddedEvent); } } } loadProjects() { if (this.loadProjectsRequest.ready) { this.loadProjectsRequest.send(); } } loadedProjects(projects) { //Check for deleted and updated projects. for (var projectId in this.projects) { var localProject = this.projects[projectId]; if (!(projectId in projects)) { this.callProjectListeners(projectId, null); var projectDeletedEvent = new Event("projectremoved"); projectDeletedEvent.project = localProject; this.dispatchEvent(projectDeletedEvent); continue; } var remoteProject = projects[projectId]; if (!Object.equals(localProject, remoteProject)) { this.callProjectListeners(projectId, remoteProject); var projectChangedEvent = new Event("projectchanged"); projectChangedEvent.project = remoteProject; this.dispatchEvent(projectChangedEvent); } } //Check for new projects. for (var projectId in projects) { if (!(projectId in this.projects)) { this.callProjectListeners(projectId, projects[projectId]); var projectAddedEvent = new Event("projectadded"); projectAddedEvent.project = projects[projectId]; this.dispatchEvent(projectAddedEvent); } } this.projects = projects; } projectLoadingError(request, status, error) { alert("Error during the loading of the projects:\r\n\r\n" + JSON.stringify(error, true)); } /** * Attempts to delete the given project on the server side. */ deleteProject(project) { this.deleteProjectRequest.send(project); } deletedProject(response) { this.callProjectListeners(response.project_id, null); var projectDeletedEvent = new Event("projectremoved"); projectDeletedEvent.project = this.projects[response.project_id]; this.dispatchEvent(projectDeletedEvent); delete this.projects[response.project_id]; //Remove the project from all users locally. var roles = TimeCards.userManager.roles; for (var roleId in roles) { for (var userId in roles[roleId].users) { var user = roles[roleId].users[userId]; if (user.projects && (response.project_id in user.projects)) { delete roles[roleId].users[userId].projects[response.project_id]; } } } TimeCards.userManager.loadedUsers(roles); } projectDeletionError(request, status, error) { alert("Error during the deletion of the project:\r\n\r\n" + JSON.stringify(error, true)); } /** * Attempts to create a project with the given data on the server side. */ createProject(project) { this.createProjectRequest.send(project); } createdProject(response) { this.projects[response.project_id] = response; var projectAddedEvent = new Event("projectadded"); projectAddedEvent.project = response; this.dispatchEvent(projectAddedEvent); } projectCreationError(request, status, error) { alert("Error during the creation of the project:\r\n\r\n" + JSON.stringify(error, true)); } /** * Attempts to save the given project data on the server. */ updateProject(project) { this.updateProjectRequest.send(project); } updatedProject(response) { this.projects[response.project_id] = response; this.callProjectListeners(response.project_id, response); var projectChangedEvent = new Event("projectchanged"); projectChangedEvent.project = response; this.dispatchEvent(projectChangedEvent); } projectUpdatingError(request, status, error) { alert("Error while updating the project:\r\n\r\n" + JSON.stringify(error, true)); } /** * The project listeners are called when a specific project is loaded initially or when it has changed. * The listeners are also called when the project was deleted, but with null instead of the project as a parameter. */ addProjectListener(projectId, callback) { if (!(projectId in this.projectListeners)) { this.projectListeners[projectId] = [ ]; } if (this.projectListeners[projectId].indexOf(callback) == -1) { this.projectListeners[projectId].push(callback); if (projectId in this.projects) { callback(this.projects[projectId]); } } } removeProjectListener(projectId, callback) { if (!(projectId in this.projectListeners)) { return; } var index = this.projectListeners[projectId].indexOf(callback); if (index != -1) { this.projectListeners[projectId].splice(index, 1); } } callProjectListeners(projectId, projectData) { if (!(projectId in this.projectListeners)) { return; } var listeners = this.projectListeners[projectId]; for (var i = 0; i < listeners.length; i++) { listeners[i](projectData); } } getProjectByKey(projectId) { if (projectId in this.projects) { return this.projects[projectId]; } return null; } }