class JobList extends List { constructor(idOrElement, subscriberList, options={}) { super(idOrElement, {...JobList.DEFAULT_OPTIONS, ...options}); subscriberList.push(this); } _init(jobs) { for (let [id, job] of Object.entries(jobs)) { this.addJob(job); } this.update(); } _update(patch) { let item, jobStatusElement, operation, pathArray; for (operation of patch) { /* "/jobId/valueName" -> ["jobId", "valueName"] */ pathArray = operation.path.split("/").slice(1); switch(operation.op) { case "add": if (pathArray.includes("results")) {break;} this.addJob(operation.value); this.update(); break; case "remove": this.remove("id", pathArray[0]); break; case "replace": item = this.get("id", pathArray[0])[0]; switch(pathArray[1]) { case "status": jobStatusElement = item.elm.querySelector(".status"); jobStatusElement.classList.remove(...Object.values(JobList.STATUS_COLORS)); jobStatusElement.classList.add(JobList.STATUS_COLORS[operation.value] || JobList.STATUS_COLORS['default']); jobStatusElement.innerHTML = operation.value; item.values({status: operation.value}); break; default: break; } default: break; } } } addJob(job) { let rowElement, columnElement, serviceElement, serviceIconElement, titleElement, descriptionElement, statusElement, viewElement, viewIconElement; // Create a row elment, where all related information get stored rowElement = document.createElement("tr"); rowElement.dataset.id = job.id; // Create a column containing a service type identifying icon columnElement = document.createElement("td"); serviceElement = document.createElement("a"); serviceElement.classList.add("btn-floating", "disabled"); serviceIconElement = document.createElement("i"); serviceIconElement.classList.add("material-icons"); serviceIconElement.innerText = JobList.SERVICE_ICONS[job.service] || JobList.SERVICE_ICONS['default']; serviceElement.appendChild(serviceIconElement); columnElement.appendChild(serviceElement); rowElement.appendChild(columnElement); // Create a column containing the title and description columnElement = document.createElement("td"); titleElement = document.createElement("b"); titleElement.classList.add("title"); titleElement.innerText = job.title; descriptionElement = document.createElement("i"); descriptionElement.classList.add("description"); descriptionElement.innerText = job.description; columnElement.appendChild(titleElement); columnElement.appendChild(document.createElement("br")); columnElement.appendChild(descriptionElement); rowElement.appendChild(columnElement); // Create a column containing the current status columnElement = document.createElement("td"); statusElement = document.createElement("span"); statusElement.classList.add("badge", "new", "status", JobList.STATUS_COLORS[job.status] || JobList.STATUS_COLORS['default']); statusElement.dataset.badgeCaption = ""; statusElement.innerText = job.status; columnElement.appendChild(statusElement); rowElement.appendChild(columnElement); // Create a column containing a button leading to a details page columnElement = document.createElement("td"); columnElement.classList.add("right-align"); viewElement = document.createElement("a"); viewElement.classList.add("waves-effect", "waves-light", "btn-small"); viewElement.href = `/jobs/${job.id}`; viewElement.innerText = "View "; viewIconElement = document.createElement("i"); viewIconElement.classList.add("material-icons", "right"); viewIconElement.innerText = "send"; viewElement.appendChild(viewIconElement); columnElement.appendChild(viewElement); rowElement.appendChild(columnElement); /* * Add an entry to the List.js datastructure and immediatly replace the * generic DOM element with our own one created above. */ this.add([{description: job.description, id: job.id, service: `/service=${job.service}`, status: job.status, title: job.title}], function(items) {items[0].elm = rowElement;}); } } JobList.DEFAULT_OPTIONS = {item: `