diff --git a/app/static/js/CorpusList.js b/app/static/js/CorpusList.js new file mode 100644 index 00000000..2ef523c9 --- /dev/null +++ b/app/static/js/CorpusList.js @@ -0,0 +1,79 @@ +class CorpusList extends List { + constructor(idOrElement, options, live=false) { + super(idOrElement, options); + this.createCorpusElements(corpora); + if (live) { + subscribers.corpora.push(this); + } + } + + + createCorpusElement(corpus) { + var corpusDescriptionElement, corpusElement, corpusIconElement, + corpusTitleElement; + + corpusDescriptionElement = document.createElement("p"); + corpusDescriptionElement.dataset.key = "description"; + corpusDescriptionElement.innerText = corpus.description; + corpusElement = document.createElement("a"); + corpusElement.classList.add("avatar", "collection-item"); + corpusElement.dataset.key = "id"; + corpusElement.dataset.value = corpus.id; + corpusElement.href = `/corpora/${corpus.id}`; + corpusIconElement = document.createElement("i"); + corpusIconElement.classList.add("circle", "material-icons"); + corpusIconElement.innerText = "book"; + corpusTitleElement = document.createElement("span"); + corpusTitleElement.classList.add("title"); + corpusTitleElement.dataset.key = "title"; + corpusTitleElement.innerText = corpus.title; + + corpusElement.appendChild(corpusIconElement); + corpusElement.appendChild(corpusTitleElement); + corpusElement.appendChild(corpusDescriptionElement); + + return corpusElement; + } + + + createCorpusElements(corpora) { + var corpus; + + for (corpus of corpora) { + this.list.appendChild(this.createCorpusElement(corpus)); + } + + this.reIndex(); + this.update(); + List.updatePagination(this); + } + + + corporaUpdateHandler(delta) { + var corpusElement, key, listItem; + + for (key in delta) { + if (key === "_t") {continue;} + if (key.startsWith("_")) { + this.remove("id", delta[key][0].id); + } else if (Array.isArray(delta[key])) { + corpusElement = this.createCorpusElement(delta[key][0]); + listItem = this.add({"description": delta[key][0].description, + "title": delta[key][0].title, + "id": delta[key][0].id})[0]; + if (listItem.elm) { + listItem.elm.replaceWith(corpusElement); + } + listItem.elm = corpusElement; + } else { + listItem = this.get("id", corpora[parseInt(key)].id)[0]; + if (delta[key]["description"]) { + listItem.values({"description": delta[key]["description"][1]}); + } + if (delta[key]["title"]) { + listItem.values({"title": delta[key]["title"][1]}); + } + } + } + } +} diff --git a/app/static/js/JobList.js b/app/static/js/JobList.js new file mode 100644 index 00000000..f4d3ee24 --- /dev/null +++ b/app/static/js/JobList.js @@ -0,0 +1,99 @@ +class JobList extends List { + constructor(idOrElement, options, live=false) { + super(idOrElement, options); + this.createJobElements(jobs); + if (live) { + subscribers.jobs.push(this); + } + } + + + createJobElement(job) { + var jobDescriptionElement, jobElement, jobServiceElement, jobStatusElement, + jobTitleElement; + + jobDescriptionElement = document.createElement("p"); + jobDescriptionElement.classList.add("description"); + jobDescriptionElement.innerText = job.description; + jobElement = document.createElement("a"); + jobElement.classList.add("avatar", "collection-item"); + jobElement.dataset.id = job.id; + jobElement.href = `/jobs/${job.id}`; + jobServiceElement = document.createElement("i"); + jobServiceElement.classList.add("circle", "material-icons", "service-icon", JobList.SERVICE_COLORS[job.service]); + jobServiceElement.innerText = JobList.SERVICE_ICONS[job.service]; + jobStatusElement = document.createElement("span"); + jobStatusElement.classList.add("badge", "new", "status", JobList.STATUS_COLORS[job.status]); + jobStatusElement.dataset.badgeCaption = ""; + jobStatusElement.innerText = job.status; + jobTitleElement = document.createElement("span"); + jobTitleElement.classList.add("title"); + jobTitleElement.innerText = job.title; + + jobElement.appendChild(jobServiceElement); + jobElement.appendChild(jobStatusElement); + jobElement.appendChild(jobTitleElement); + jobElement.appendChild(jobDescriptionElement); + + return jobElement; + } + + + createJobElements(jobs) { + var job; + + for (job of jobs) { + this.list.appendChild(this.createJobElement(job)); + } + + this.reIndex(); + this.update(); + List.updatePagination(this); + } + + + jobsUpdateHandler(delta) { + var jobElement, jobStatusElement, key, listItem; + + for (key in delta) { + if (key === "_t") {continue;} + if (key.startsWith("_")) { + this.remove("id", delta[key][0].id); + } else if (Array.isArray(delta[key])) { + jobElement = this.createJobElement(delta[key][0]); + listItem = this.add({"description": delta[key][0].description, + "title": delta[key][0].title, + "id": delta[key][0].id})[0]; + if (listItem.elm) { + listItem.elm.replaceWith(jobElement); + } + listItem.elm = jobElement; + } else { + listItem = this.get("id", jobs[parseInt(key)].id)[0]; + if (delta[key]["status"]) { + jobStatusElement = listItem.elm.querySelector(".status"); + jobStatusElement.classList.remove(JobList.STATUS_COLORS[delta[key]["status"][0]]); + jobStatusElement.classList.add(JobList.STATUS_COLORS[delta[key]["status"][1]]); + jobStatusElement.innerHTML = delta[key]["status"][1]; + } + if (delta[key]["description"]) { + listItem.values({"description": delta[key]["description"][1]}); + } + if (delta[key]["title"]) { + listItem.values({"title": delta[key]["title"][1]}); + } + } + } + } +} + +JobList.SERVICE_COLORS = {"nlp": "blue", + "ocr": "green", + "default": "red"}; +JobList.SERVICE_ICONS = {"nlp": "format_textdirection_l_to_r", + "ocr": "find_in_page", + "default": "help"}; +JobList.STATUS_COLORS = {"pending": "amber", + "running": "indigo", + "complete": "teal", + "default": "red"}; diff --git a/app/static/js/corpora.js b/app/static/js/corpora.js deleted file mode 100644 index 6922adec..00000000 --- a/app/static/js/corpora.js +++ /dev/null @@ -1,33 +0,0 @@ -function createCorpusElement(corpus) { - corpusElement = document.createElement("a"); - corpusElement.classList.add("avatar", "collection-item"); - corpusElement.dataset.key = "id"; - corpusElement.dataset.value = corpus.id; - corpusElement.href = `/corpora/${corpus.id}`; - corpusDescriptionElement = document.createElement("p"); - corpusDescriptionElement.dataset.key = "description"; - corpusDescriptionElement.innerText = corpus.description; - corpusIconElement = document.createElement("i"); - corpusIconElement.classList.add("circle", "material-icons"); - corpusIconElement.innerText = "book"; - corpusTitleElement = document.createElement("span"); - corpusTitleElement.classList.add("title"); - corpusTitleElement.dataset.key = "title"; - corpusTitleElement.innerText = corpus.title; - - corpusElement.appendChild(corpusIconElement); - corpusElement.appendChild(corpusTitleElement); - corpusElement.appendChild(corpusDescriptionElement); - - return corpusElement; -} - - -function createCorpusElements(corpusList) { - for (corpus of corpora) { - corpusList.list.appendChild(createCorpusElement(corpus)); - } - corpusList.reIndex(); - corpusList.update(); - updatePagination(corpusList); -} diff --git a/app/static/js/jobs.js b/app/static/js/jobs.js deleted file mode 100644 index fbdb993e..00000000 --- a/app/static/js/jobs.js +++ /dev/null @@ -1,49 +0,0 @@ -// Job list code -const SERVICE_COLORS = {"nlp": "blue", - "ocr": "green", - "default": "red"}; -const SERVICE_ICONS = {"nlp": "format_textdirection_l_to_r", - "ocr": "find_in_page", - "default": "help"}; -const STATUS_COLORS = {"pending": "amber", - "running": "indigo", - "complete": "teal", - "default": "red"}; - - -function createJobElement(job) { - jobElement = document.createElement("a"); - jobElement.classList.add("avatar", "collection-item"); - jobElement.dataset.id = job.id; - jobElement.href = `/jobs/${job.id}`; - jobDescriptionElement = document.createElement("p"); - jobDescriptionElement.classList.add("description"); - jobDescriptionElement.innerText = job.description; - jobServiceElement = document.createElement("i"); - jobServiceElement.classList.add("circle", "material-icons", "service-icon", SERVICE_COLORS[job.service]); - jobServiceElement.innerText = SERVICE_ICONS[job.service]; - jobStatusElement = document.createElement("span"); - jobStatusElement.classList.add("badge", "new", "status", STATUS_COLORS[job.status]); - jobStatusElement.dataset.badgeCaption = ""; - jobStatusElement.innerText = job.status; - jobTitleElement = document.createElement("span"); - jobTitleElement.classList.add("title"); - jobTitleElement.innerText = job.title; - - jobElement.appendChild(jobServiceElement); - jobElement.appendChild(jobStatusElement); - jobElement.appendChild(jobTitleElement); - jobElement.appendChild(jobDescriptionElement); - - return jobElement; -} - - -function createJobElements(jobList) { - for (job of jobs) { - jobList.list.appendChild(createJobElement(job)); - } - jobList.reIndex(); - jobList.update(); - updatePagination(jobList); -} diff --git a/app/static/js/polls.js b/app/static/js/polls.js index a4ae2c00..fdd332dd 100644 --- a/app/static/js/polls.js +++ b/app/static/js/polls.js @@ -17,7 +17,7 @@ function getCorpora() { if (JSON.stringify(corpora) != JSON.stringify(data)) { corpora = data; for (subscriber of subscribers.corpora) { - subscriber(); + subscriber.corporaUpdateHandler(); } } }) @@ -44,7 +44,7 @@ function getJobs() { if (delta) { jobs = json; for (subscriber of subscribers.jobs) { - subscriber(delta); + subscriber.jobsUpdateHandler(delta); } } }) diff --git a/app/static/js/utils.js b/app/static/js/utils.js index 91e3a66c..35c023ef 100644 --- a/app/static/js/utils.js +++ b/app/static/js/utils.js @@ -1,5 +1,4 @@ -// List.js utils -var updatePagination = function(list) { +List.updatePagination = function(list) { pagination = list.listContainer.querySelector(".pagination"); if (pagination.childElementCount <= 1) { pagination.classList.add("hide"); diff --git a/app/templates/base.html.j2 b/app/templates/base.html.j2 index ce571e90..f9ee2094 100644 --- a/app/templates/base.html.j2 +++ b/app/templates/base.html.j2 @@ -29,8 +29,8 @@ {% endif %} - - + +
diff --git a/app/templates/main/dashboard.html.j2 b/app/templates/main/dashboard.html.j2 index d77865ff..08fcd063 100644 --- a/app/templates/main/dashboard.html.j2 +++ b/app/templates/main/dashboard.html.j2 @@ -31,15 +31,13 @@