diff --git a/basics/async-javascript/promise.html b/basics/async-javascript/promise.html new file mode 100644 index 0000000..271cbbd --- /dev/null +++ b/basics/async-javascript/promise.html @@ -0,0 +1,24 @@ + + + + +Insert title here + + + + + + + + \ No newline at end of file diff --git a/notebook/author/author.html b/notebook/author/author.html index e3cfcd7..c976d78 100644 --- a/notebook/author/author.html +++ b/notebook/author/author.html @@ -10,6 +10,7 @@ + @@ -31,23 +32,24 @@ +
-
-
+
+
-
+
-
+
diff --git a/notebook/author/images/1.png b/notebook/author/images/1.png deleted file mode 100644 index 4d7b41d..0000000 Binary files a/notebook/author/images/1.png and /dev/null differ diff --git a/notebook/author/images/10.png b/notebook/author/images/10.png deleted file mode 100644 index 7f278a1..0000000 Binary files a/notebook/author/images/10.png and /dev/null differ diff --git a/notebook/author/images/11.png b/notebook/author/images/11.png deleted file mode 100644 index ede092d..0000000 Binary files a/notebook/author/images/11.png and /dev/null differ diff --git a/notebook/author/images/12.png b/notebook/author/images/12.png deleted file mode 100644 index 880c623..0000000 Binary files a/notebook/author/images/12.png and /dev/null differ diff --git a/notebook/author/images/13.png b/notebook/author/images/13.png deleted file mode 100644 index 23d1abf..0000000 Binary files a/notebook/author/images/13.png and /dev/null differ diff --git a/notebook/author/images/14.png b/notebook/author/images/14.png deleted file mode 100644 index b96ed98..0000000 Binary files a/notebook/author/images/14.png and /dev/null differ diff --git a/notebook/author/images/15.png b/notebook/author/images/15.png deleted file mode 100644 index 90d1711..0000000 Binary files a/notebook/author/images/15.png and /dev/null differ diff --git a/notebook/author/images/16.png b/notebook/author/images/16.png deleted file mode 100644 index 8306e3d..0000000 Binary files a/notebook/author/images/16.png and /dev/null differ diff --git a/notebook/author/images/17.png b/notebook/author/images/17.png deleted file mode 100644 index 5adb1ff..0000000 Binary files a/notebook/author/images/17.png and /dev/null differ diff --git a/notebook/author/images/18.png b/notebook/author/images/18.png deleted file mode 100644 index a84d08e..0000000 Binary files a/notebook/author/images/18.png and /dev/null differ diff --git a/notebook/author/images/19.png b/notebook/author/images/19.png deleted file mode 100644 index 79f1888..0000000 Binary files a/notebook/author/images/19.png and /dev/null differ diff --git a/notebook/author/images/2.png b/notebook/author/images/2.png deleted file mode 100644 index 2fc8065..0000000 Binary files a/notebook/author/images/2.png and /dev/null differ diff --git a/notebook/author/images/20.png b/notebook/author/images/20.png deleted file mode 100644 index dd90020..0000000 Binary files a/notebook/author/images/20.png and /dev/null differ diff --git a/notebook/author/images/21.png b/notebook/author/images/21.png deleted file mode 100644 index 320b426..0000000 Binary files a/notebook/author/images/21.png and /dev/null differ diff --git a/notebook/author/images/22.png b/notebook/author/images/22.png deleted file mode 100644 index 2c6d8af..0000000 Binary files a/notebook/author/images/22.png and /dev/null differ diff --git a/notebook/author/images/23.png b/notebook/author/images/23.png deleted file mode 100644 index 792ee18..0000000 Binary files a/notebook/author/images/23.png and /dev/null differ diff --git a/notebook/author/images/3.png b/notebook/author/images/3.png deleted file mode 100644 index dac91e6..0000000 Binary files a/notebook/author/images/3.png and /dev/null differ diff --git a/notebook/author/images/4.png b/notebook/author/images/4.png deleted file mode 100644 index 99b2fb8..0000000 Binary files a/notebook/author/images/4.png and /dev/null differ diff --git a/notebook/author/images/5.png b/notebook/author/images/5.png deleted file mode 100644 index be8c3f3..0000000 Binary files a/notebook/author/images/5.png and /dev/null differ diff --git a/notebook/author/images/6.png b/notebook/author/images/6.png deleted file mode 100644 index be31fe1..0000000 Binary files a/notebook/author/images/6.png and /dev/null differ diff --git a/notebook/author/images/7.png b/notebook/author/images/7.png deleted file mode 100644 index c56ecbf..0000000 Binary files a/notebook/author/images/7.png and /dev/null differ diff --git a/notebook/author/images/8.png b/notebook/author/images/8.png deleted file mode 100644 index 1ae02ff..0000000 Binary files a/notebook/author/images/8.png and /dev/null differ diff --git a/notebook/author/images/9.png b/notebook/author/images/9.png deleted file mode 100644 index 3dc31b9..0000000 Binary files a/notebook/author/images/9.png and /dev/null differ diff --git a/notebook/author/images/ampliacao-eletro.gif b/notebook/author/images/ampliacao-eletro.gif new file mode 100644 index 0000000..d1e8a47 Binary files /dev/null and b/notebook/author/images/ampliacao-eletro.gif differ diff --git a/notebook/author/images/anger-no.png b/notebook/author/images/anger-no.png deleted file mode 100644 index 9e55ced..0000000 Binary files a/notebook/author/images/anger-no.png and /dev/null differ diff --git a/notebook/author/images/anger.png b/notebook/author/images/anger.png deleted file mode 100644 index 8981000..0000000 Binary files a/notebook/author/images/anger.png and /dev/null differ diff --git a/notebook/author/images/bacteria.gif b/notebook/author/images/bacteria.gif deleted file mode 100644 index 2778a53..0000000 Binary files a/notebook/author/images/bacteria.gif and /dev/null differ diff --git a/notebook/author/images/case-forklift.png b/notebook/author/images/case-forklift.png new file mode 100644 index 0000000..4dc882a Binary files /dev/null and b/notebook/author/images/case-forklift.png differ diff --git a/notebook/author/images/ebm-clinical-history-aortic-dissection.png b/notebook/author/images/ebm-clinical-history-aortic-dissection.png new file mode 100644 index 0000000..8b6771e Binary files /dev/null and b/notebook/author/images/ebm-clinical-history-aortic-dissection.png differ diff --git a/notebook/author/images/ebm-clinical-history-myocardial-infarction.png b/notebook/author/images/ebm-clinical-history-myocardial-infarction.png new file mode 100644 index 0000000..8fc3727 Binary files /dev/null and b/notebook/author/images/ebm-clinical-history-myocardial-infarction.png differ diff --git a/notebook/author/images/ebm-physical-examination-aortic-dissection.png b/notebook/author/images/ebm-physical-examination-aortic-dissection.png new file mode 100644 index 0000000..1d05f5e Binary files /dev/null and b/notebook/author/images/ebm-physical-examination-aortic-dissection.png differ diff --git a/notebook/author/images/ebm-physical-examination-myocardial-infarction.png b/notebook/author/images/ebm-physical-examination-myocardial-infarction.png new file mode 100644 index 0000000..a75ec55 Binary files /dev/null and b/notebook/author/images/ebm-physical-examination-myocardial-infarction.png differ diff --git a/notebook/author/images/ebm-pulmonary-embolism-wells-criteria.png b/notebook/author/images/ebm-pulmonary-embolism-wells-criteria.png new file mode 100644 index 0000000..f076c09 Binary files /dev/null and b/notebook/author/images/ebm-pulmonary-embolism-wells-criteria.png differ diff --git a/notebook/author/images/ekg-description.png b/notebook/author/images/ekg-description.png new file mode 100644 index 0000000..60941ed Binary files /dev/null and b/notebook/author/images/ekg-description.png differ diff --git a/notebook/author/images/ekg-detail-01.png b/notebook/author/images/ekg-detail-01.png new file mode 100644 index 0000000..4286bcc Binary files /dev/null and b/notebook/author/images/ekg-detail-01.png differ diff --git a/notebook/author/images/ekg-detail-02.png b/notebook/author/images/ekg-detail-02.png new file mode 100644 index 0000000..d5ae3b7 Binary files /dev/null and b/notebook/author/images/ekg-detail-02.png differ diff --git a/notebook/author/images/ekg-original.png b/notebook/author/images/ekg-original.png new file mode 100644 index 0000000..2953a82 Binary files /dev/null and b/notebook/author/images/ekg-original.png differ diff --git a/notebook/author/images/end.jpg b/notebook/author/images/end.jpg deleted file mode 100644 index 9b8b264..0000000 Binary files a/notebook/author/images/end.jpg and /dev/null differ diff --git a/notebook/author/images/fight.gif b/notebook/author/images/fight.gif deleted file mode 100644 index 0594cb1..0000000 Binary files a/notebook/author/images/fight.gif and /dev/null differ diff --git a/notebook/author/images/fingers-ok.png b/notebook/author/images/fingers-ok.png deleted file mode 100644 index 3ad8ba7..0000000 Binary files a/notebook/author/images/fingers-ok.png and /dev/null differ diff --git a/notebook/author/images/fingers-shaking.png b/notebook/author/images/fingers-shaking.png deleted file mode 100644 index 64cf59a..0000000 Binary files a/notebook/author/images/fingers-shaking.png and /dev/null differ diff --git a/notebook/author/images/hospital-background.png b/notebook/author/images/hospital-background.png new file mode 100644 index 0000000..7f64e05 Binary files /dev/null and b/notebook/author/images/hospital-background.png differ diff --git a/notebook/author/images/lumbriga.gif b/notebook/author/images/lumbriga.gif deleted file mode 100644 index 305fe1a..0000000 Binary files a/notebook/author/images/lumbriga.gif and /dev/null differ diff --git a/notebook/author/images/members-loss.png b/notebook/author/images/members-loss.png deleted file mode 100644 index 835037e..0000000 Binary files a/notebook/author/images/members-loss.png and /dev/null differ diff --git a/notebook/author/images/members-ok.png b/notebook/author/images/members-ok.png deleted file mode 100644 index ca7b895..0000000 Binary files a/notebook/author/images/members-ok.png and /dev/null differ diff --git a/notebook/author/images/nurse_agnes.png b/notebook/author/images/nurse_agnes.png new file mode 100644 index 0000000..f4ab542 Binary files /dev/null and b/notebook/author/images/nurse_agnes.png differ diff --git a/notebook/author/images/pain-chest.png b/notebook/author/images/pain-chest.png deleted file mode 100644 index 2c78102..0000000 Binary files a/notebook/author/images/pain-chest.png and /dev/null differ diff --git a/notebook/author/images/pain-no.png b/notebook/author/images/pain-no.png deleted file mode 100644 index 57a200a..0000000 Binary files a/notebook/author/images/pain-no.png and /dev/null differ diff --git a/notebook/author/images/paralysis-no.png b/notebook/author/images/paralysis-no.png deleted file mode 100644 index e8dadeb..0000000 Binary files a/notebook/author/images/paralysis-no.png and /dev/null differ diff --git a/notebook/author/images/paralysis.png b/notebook/author/images/paralysis.png deleted file mode 100644 index 63289f2..0000000 Binary files a/notebook/author/images/paralysis.png and /dev/null differ diff --git a/notebook/author/images/patient-icon.png b/notebook/author/images/patient-icon.png new file mode 100644 index 0000000..920ac87 Binary files /dev/null and b/notebook/author/images/patient-icon.png differ diff --git a/notebook/author/images/patient-in-bed.svg b/notebook/author/images/patient-in-bed.svg new file mode 100644 index 0000000..2074402 --- /dev/null +++ b/notebook/author/images/patient-in-bed.svg @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/notebook/author/images/patient.png b/notebook/author/images/patient.png new file mode 100644 index 0000000..899415e Binary files /dev/null and b/notebook/author/images/patient.png differ diff --git a/notebook/author/images/patient_jakob.png b/notebook/author/images/patient_jakob.png new file mode 100644 index 0000000..4e49da7 Binary files /dev/null and b/notebook/author/images/patient_jakob.png differ diff --git a/notebook/author/images/presentation.png b/notebook/author/images/presentation.png deleted file mode 100644 index 8859d84..0000000 Binary files a/notebook/author/images/presentation.png and /dev/null differ diff --git a/notebook/author/images/supervisor_harry.png b/notebook/author/images/supervisor_harry.png new file mode 100644 index 0000000..ce0c3dc Binary files /dev/null and b/notebook/author/images/supervisor_harry.png differ diff --git a/notebook/author/images/tongue-red.png b/notebook/author/images/tongue-red.png deleted file mode 100644 index 926563f..0000000 Binary files a/notebook/author/images/tongue-red.png and /dev/null differ diff --git a/notebook/author/images/tongue-yellow.png b/notebook/author/images/tongue-yellow.png deleted file mode 100644 index 8611eaf..0000000 Binary files a/notebook/author/images/tongue-yellow.png and /dev/null differ diff --git a/notebook/author/images/treatment-right.png b/notebook/author/images/treatment-right.png deleted file mode 100644 index fa74ab9..0000000 Binary files a/notebook/author/images/treatment-right.png and /dev/null differ diff --git a/notebook/author/images/treatment-wrong.png b/notebook/author/images/treatment-wrong.png deleted file mode 100644 index d7e6b5d..0000000 Binary files a/notebook/author/images/treatment-wrong.png and /dev/null differ diff --git a/notebook/author/images/virus.gif b/notebook/author/images/virus.gif deleted file mode 100644 index b36ca55..0000000 Binary files a/notebook/author/images/virus.gif and /dev/null differ diff --git a/notebook/author/js/author.js b/notebook/author/js/author.js index 632feff..ddf0d67 100644 --- a/notebook/author/js/author.js +++ b/notebook/author/js/author.js @@ -21,25 +21,40 @@ class AuthorManager { this.controlEvent = this.controlEvent.bind(this); window.messageBus.ext.subscribe("control/#", this.controlEvent); + + this.selectKnot = this.selectKnot.bind(this); + window.messageBus.ext.subscribe("knot/+/selected", this.selectKnot); this._caseLoadSelected = this._caseLoadSelected.bind(this); this._templateFamilySelected = this._templateFamilySelected.bind(this); } + /* + * `control/case/load` + * `control/case/save` + * `control/case/play` + * `control/knot/edit` + * `control/config/edit` + + * `knot//selected` + + */ controlEvent(topic, message) { switch (topic) { - case "control/load": this.selectCase(); - break; - case "control/save": this.saveCase(); - break; + case "control/case/load": this.selectCase(); + break; + case "control/case/save": this.saveCase(); + break; case "control/knot/edit": this.editKnot(); - break; - case "control/play": this.playCase(); - break; - case "control/config": this.config(); - break; - case "control/knot/selected": this.knotSelected(message); - break; + break; + case "control/case/play": this.playCase(); + break; + case "control/config/edit": this.config(); + break; + /* + case "control/knot/selected": this.selectKnot(message); + break; + */ } } @@ -48,11 +63,13 @@ class AuthorManager { */ async selectCase() { this._resourcePicker = new DCCResourcePicker(); + this._resourcePicker.resource = "case"; - window.messageBus.ext.subscribe("dcc/resource-picker/selected", this._caseLoadSelected); + window.messageBus.ext.subscribe("control/case/selected", this._caseLoadSelected); - const cases = await this._server.casesList(this._resourcePicker); - this._resourcePicker.addSelectList(cases); + // const cases = await this._server.casesList(this._resourcePicker); + const cases = await window.messageBus.ext.request("case/*/get", "", "case/*"); + this._resourcePicker.addSelectList(cases.message); let knotPanel = document.querySelector("#knot-panel"); knotPanel.appendChild(this._resourcePicker); } @@ -61,14 +78,16 @@ class AuthorManager { * ACTION: control-load (2) */ async _caseLoadSelected(topic, message) { - window.messageBus.ext.unsubscribe("dcc/resource-picker/selected", this._caseLoadSelected); - this._currentCaseName = message; - let caseMd = await this._server.loadCase(this._currentCaseName); + window.messageBus.ext.unsubscribe("control/case/selected", this._caseLoadSelected); + this._currentCaseName = message.selected; + // let caseMd = await this._server.loadCase(this._currentCaseName); + const caseMd = await window.messageBus.ext.request("case/" + this._currentCaseName + "/get", "", + "case/" + this._currentCaseName); let navigationPanel = document.querySelector("#navigation-panel"); let knotPanel = document.querySelector("#knot-panel"); knotPanel.removeChild(this._resourcePicker); - this._compiledCase = this._translator.compileMarkdown(this._currentCaseName, caseMd); + this._compiledCase = this._translator.compileMarkdown(this._currentCaseName, caseMd.message); this._knots = this._compiledCase.knots; for (let kn in this._knots) { @@ -76,13 +95,19 @@ class AuthorManager { let miniature = document.createElement("div"); miniature.classList.add("navigation-knot"); miniature.classList.add("std-border"); - miniature.innerHTML = "

" - "

"; + const dot = this._knots[kn].title.lastIndexOf("."); + const title = (dot == -1) ? this._knots[kn].title : this._knots[kn].title.substring(dot); + if (this._knots[kn].render) + miniature.innerHTML = "

" + + "

"; + else + miniature.innerHTML = "

" + title + "

"; navigationPanel.appendChild(miniature); } } + console.log(this._knots); } /* @@ -104,9 +129,12 @@ class AuthorManager { async saveCase() { if (this._currentCaseName != null && this._compiledCase != null) { let md =this._translator.assembleMarkdown(this._compiledCase); - const versionFile = await this._server.saveCase(this._currentCaseName, md); + // const versionFile = await this._server.saveCase(this._currentCaseName, md); + const versionFile = await window.messageBus.ext.request("case/" + this._currentCaseName + "/set", + {format: "markdown", source: md}, + "case/" + this._currentCaseName + "/version"); - console.log("Case saved! Previous version: " + versionFile); + console.log("Case saved! Previous version: " + versionFile.message); document.querySelector("#message-space").innerHTML = "Saved"; setTimeout(this._clearMessage, 2000); @@ -124,7 +152,10 @@ class AuthorManager { async playCase() { let message = document.querySelector("#message-space"); message.innerHTML = "Preparing..."; - await this._server.prepareCaseHTML(this._currentTemplateFamily, this._currentCaseName); + // await this._server.prepareCaseHTML(this._currentTemplateFamily, this._currentCaseName); + await window.messageBus.ext.request("case/" + this._currentCaseName + "/prepare", + this._currentTemplateFamily, + "case/" + this._currentCaseName + "/prepare/status"); this._templateSet = {}; /* @@ -134,31 +165,44 @@ class AuthorManager { */ const htmlSet = Object.assign( - {"entry": "", - "signin": "", - "register": "", - "report": ""}, + {"entry": {render: true}, + "signin": {render: true}, + "register": {render: true}, + "report": {render: true}}, this._knots); const total = Object.keys(htmlSet).length; let processing = 0; for (let kn in htmlSet) { processing++; - message.innerHTML = "Processed: " + processing + "/" + total; - let htmlName = kn.replace(/ /igm, "_"); - let finalHTML = ""; - if (processing > 4) - finalHTML = await this._generateHTMLBuffer(kn); - else - finalHTML = await this._server.loadTemplate(this._currentTemplateFamily, kn); - // finalHTML = this._templateSet.player.replace("{knot}", finalHTML); - finalHTML = AuthorManager.jsonKnot.replace("{knot}", finalHTML); - await this._server.saveKnotHTML(this._currentCaseName, - htmlName + ".js", finalHTML); + message.innerHTML = "Processed: " + processing + "/" + total; + if (htmlSet[kn].render) { + // let htmlName = kn.replace(/ /igm, "_"); + let finalHTML = ""; + if (processing > 4) + finalHTML = await this._generateHTMLBuffer(kn); + else + finalHTML = await this._loadTemplate(this._currentTemplateFamily, kn); + // finalHTML = this._templateSet.player.replace("{knot}", finalHTML); + finalHTML = AuthorManager.jsonKnot.replace("{knot}", finalHTML); + + await window.messageBus.ext.request("knot/" + kn + "/set", + {caseId: this._currentCaseName, + format: "html", + source: finalHTML}, + "knot/" + kn + "/set/status"); + /* + await this._server.saveKnotHTML(this._currentCaseName, + kn + ".js", finalHTML); + */ + } } message.innerHTML = "Finalizing..."; let caseJSON = this._translator.generateCompiledJSON(this._compiledCase); - await this._server.saveCaseScript(this._currentCaseName, "case.js", caseJSON); + // await this._server.saveCaseScript(this._currentCaseName, "case.js", caseJSON); + await window.messageBus.ext.request("case/" + this._currentCaseName + "/set", + {format: "json", source: caseJSON}, + "case/" + this._currentCaseName + "/set/status"); message.innerHTML = ""; @@ -171,11 +215,14 @@ class AuthorManager { */ async config() { this._resourcePicker = new DCCResourcePicker(); + this._resourcePicker.resource = "template"; + + window.messageBus.ext.subscribe("control/template_family/selected", this._templateFamilySelected); - window.messageBus.ext.subscribe("dcc/resource-picker/selected", this._templateFamilySelected); + // const families = await this._server.templateFamiliesList(this._resourcePicker); + const families = await window.messageBus.ext.request("template_family/*/get", "", "template_family/*"); - const families = await this._server.templateFamiliesList(this._resourcePicker); - this._resourcePicker.addSelectList(families); + this._resourcePicker.addSelectList(families.message); document.querySelector("#knot-panel").appendChild(this._resourcePicker); } @@ -183,18 +230,20 @@ class AuthorManager { * ACTION: config (2) */ async _templateFamilySelected(topic, message) { - window.messageBus.ext.unsubscribe("dcc/resource-picker/selected", this._templateFamilySelected); - this._currentTemplateFamily = message; + window.messageBus.ext.unsubscribe("control/template/selected", this._templateFamilySelected); + this._currentTemplateFamily = message.selected; document.querySelector("#knot-panel").removeChild(this._resourcePicker); } /* * ACTION: knot-selected */ - async knotSelected(knotTitle) { - if (this._knots[knotTitle]) { + async selectKnot(topic, message) { + // console.log("selected - topic: " + topic + "; message: " + message); + const knotId = MessageBus.extractLevel(topic, 2); + if (knotId != null) { this._checkKnotModification(); - this._knotSelected = knotTitle; + this._knotSelected = knotId; this._htmlKnot = await this._generateHTML(this._knotSelected); this._renderKnot(); } @@ -231,13 +280,13 @@ class AuthorManager { for (let tp in templates) if (!this._templateSet[templates[tp]]) { const templ = await - this._server.loadTemplate(this._currentTemplateFamily, templates[tp]); + this._loadTemplate(this._currentTemplateFamily, templates[tp]); if (templ != "") this._templateSet[templates[tp]] = templ; else { if (!this._templateSet["knot"]) this._templateSet["knot"] = await - this._server.loadTemplate(this._currentTemplateFamily, "knot"); + this._loadTemplate(this._currentTemplateFamily, "knot"); this._templateSet[templates[tp]] = this._templateSet["knot"]; } } @@ -248,6 +297,13 @@ class AuthorManager { return finalHTML; } + async _loadTemplate(templateFamily, templateName) { + const templateObj = await window.messageBus.ext.request( + "template/" + templateFamily + "." + templateName + "/get", "", + "template/" + templateFamily + "." + templateName); + return templateObj.message; + } + _renderKnot() { let knotPanel = document.querySelector("#knot-panel"); diff --git a/notebook/author/js/dcc-author-server-address.js b/notebook/author/js/dcc-author-server-address.js new file mode 100644 index 0000000..69ad2fc --- /dev/null +++ b/notebook/author/js/dcc-author-server-address.js @@ -0,0 +1,4 @@ +(function() { + DCCAuthorServer.serverAddress = "http://cloud.lis.ic.unicamp.br/case-notebook/v1/server/"; + // DCCAuthorServer.serverAddress = "http://127.0.0.1:8888/"; +})(); \ No newline at end of file diff --git a/notebook/author/js/dcc-author-server-proxy.js b/notebook/author/js/dcc-author-server-proxy.js index 22bc146..6ced514 100644 --- a/notebook/author/js/dcc-author-server-proxy.js +++ b/notebook/author/js/dcc-author-server-proxy.js @@ -3,6 +3,27 @@ */ class DCCAuthorServer { + constructor() { + this.templateFamiliesList = this.templateFamiliesList.bind(this); + window.messageBus.ext.subscribe("template_family/*/get", this.templateFamiliesList); + this.casesList = this.casesList.bind(this); + window.messageBus.ext.subscribe("case/*/get", this.casesList); + this.loadCase = this.loadCase.bind(this); + window.messageBus.ext.subscribe("case/+/get", this.loadCase); + this.saveCase = this.saveCase.bind(this); + window.messageBus.ext.subscribe("case/+/set", this.saveCase); + this.loadTemplate = this.loadTemplate.bind(this); + window.messageBus.ext.subscribe("template/+/get", this.loadTemplate); + this.prepareCaseHTML = this.prepareCaseHTML.bind(this); + window.messageBus.ext.subscribe("case/+/prepare", this.prepareCaseHTML); + this.saveKnotHTML = this.saveKnotHTML.bind(this); + window.messageBus.ext.subscribe("knot/+/set", this.saveKnotHTML); + this.saveCaseObject = this.saveCaseObject.bind(this); + window.messageBus.ext.subscribe("case/+/set", this.saveCaseObject); + } + + // wrapper of the services + async templateFamiliesList() { const response = await fetch(DCCAuthorServer.serverAddress + "template-families-list", { method: "POST", @@ -15,7 +36,7 @@ class DCCAuthorServer { let finalFamiliesList = {}; for (var f in families) finalFamiliesList[families[f]] = "icons/mono-slide.svg"; - return finalFamiliesList; + window.messageBus.ext.publish("template_family/*", finalFamiliesList); } async casesList() { @@ -30,34 +51,41 @@ class DCCAuthorServer { let finalCasesList = {}; for (var c in cases) finalCasesList[cases[c]] = "icons/mono-slide.svg"; - return finalCasesList; + window.messageBus.ext.publish("case/*", finalCasesList); } - async loadCase(caseName) { - const response = await fetch(DCCAuthorServer.serverAddress + "load-case", { - method: "POST", - body: JSON.stringify({"caseName": caseName}), - headers:{ - "Content-Type": "application/json" - } - }); - const jsonResponse = await response.json(); - return jsonResponse.caseMd; + async loadCase(topic) { + const caseName = MessageBus.extractLevel(topic, 2); + if (caseName != "*") { + const response = await fetch(DCCAuthorServer.serverAddress + "load-case", { + method: "POST", + body: JSON.stringify({"caseName": caseName}), + headers:{ + "Content-Type": "application/json" + } + }); + const jsonResponse = await response.json(); + window.messageBus.ext.publish("case/" + caseName, jsonResponse.caseMd); + } } - async saveCase(caseName, caseText) { - const response = await fetch(DCCAuthorServer.serverAddress + "save-case", { - method: "POST", - body: JSON.stringify({"caseName": caseName, - "caseText": caseText}), - headers:{ - "Content-Type": "application/json" - } - }); - const jsonResponse = await response.json(); - return jsonResponse.versionFile; + async saveCase(topic, message) { + if (message.format == "markdown") { + const caseName = MessageBus.extractLevel(topic, 2); + const response = await fetch(DCCAuthorServer.serverAddress + "save-case", { + method: "POST", + body: JSON.stringify({"caseName": caseName, + "caseText": message.source}), + headers:{ + "Content-Type": "application/json" + } + }); + const jsonResponse = await response.json(); + window.messageBus.ext.publish("case/" + caseName + "/version", jsonResponse.versionFile); + } } + /* async loadPlayer() { const response = await fetch(DCCAuthorServer.serverAddress + "load-player", { method: "POST", @@ -68,8 +96,13 @@ class DCCAuthorServer { const jsonResponse = await response.json(); return jsonResponse.player; } + */ - async loadTemplate(templateFamily, templateName) { + async loadTemplate(topic) { + const templateCompleteName = MessageBus.extractLevel(topic, 2); + const separator = templateCompleteName.indexOf("."); + const templateFamily = templateCompleteName.substring(0, separator); + const templateName = templateCompleteName.substring(separator+1); const response = await fetch(DCCAuthorServer.serverAddress + "load-template", { method: "POST", body: JSON.stringify({"templateFamily": templateFamily, @@ -79,10 +112,11 @@ class DCCAuthorServer { } }); const jsonResponse = await response.json(); - return jsonResponse.template; + window.messageBus.ext.publish("template/" + templateCompleteName, jsonResponse.template); } - async prepareCaseHTML(templateFamily, caseName) { + async prepareCaseHTML(topic, templateFamily) { + const caseName = MessageBus.extractLevel(topic, 2); const response = await fetch(DCCAuthorServer.serverAddress + "prepare-case-html", { method: "POST", body: JSON.stringify({"templateFamily": templateFamily, @@ -92,39 +126,41 @@ class DCCAuthorServer { } }); const jsonResponse = await response.json(); - return jsonResponse.status; + window.messageBus.ext.publish("case/" + caseName + "/prepare/status", jsonResponse.status); } - async saveKnotHTML(caseName, knotFile, knotHTML) { + async saveKnotHTML(topic, message) { + const knotId = MessageBus.extractLevel(topic, 2); + const response = await fetch(DCCAuthorServer.serverAddress + "save-knot-html", { method: "POST", - body: JSON.stringify({"caseName": caseName, - "knotFile": knotFile, - "knotHTML": knotHTML}), + body: JSON.stringify({"caseName": message.caseId, + "knotFile": knotId + ".js", + "knotHTML": message.source}), headers:{ "Content-Type": "application/json" } }); const jsonResponse = await response.json(); - return jsonResponse.status; + window.messageBus.ext.publish("knot/" + knotId + "/set/status", jsonResponse.status); } - async saveCaseScript(caseName, scriptFile, scriptJS) { - const response = await fetch(DCCAuthorServer.serverAddress + "save-case-script", { - method: "POST", - body: JSON.stringify({"caseName": caseName, - "scriptFile": scriptFile, - "scriptJS": scriptJS}), - headers:{ - "Content-Type": "application/json" - } - }); - const jsonResponse = await response.json(); - return jsonResponse.status; + async saveCaseObject(topic, message) { + if (message.format == "json") { + const caseId = MessageBus.extractLevel(topic, 2); + + // change the name of the service + const response = await fetch(DCCAuthorServer.serverAddress + "save-case-script", { + method: "POST", + body: JSON.stringify({"caseName": caseId, + "scriptFile": "case.js", + "scriptJS": message.source}), + headers:{ + "Content-Type": "application/json" + } + }); + const jsonResponse = await response.json(); + window.messageBus.ext.publish("case/" + caseId + "/set/status", jsonResponse.status); + } } } - -(function() { - DCCAuthorServer.serverAddress = "http://cloud.lis.ic.unicamp.br/case-notebook/v1/server/"; - //DCCAuthorServer.serverAddress = "http://127.0.0.1:8888/"; -})(); diff --git a/notebook/bus/README.md b/notebook/bus/README.md index 0540e45..1dd3966 100644 --- a/notebook/bus/README.md +++ b/notebook/bus/README.md @@ -1,11 +1,149 @@ +# Harena Message Protocol +## Topic Structure and Wildcards +The wildcards standard is based in the MQTT 3.1.1, as specified in the document: [MQTT Version 3.1.1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html), Section 4.7.1 Topic wildcards. + +Extra information is based on: +The HiveMQ Team. MQTT Essentials Part 5: MQTT Topics & Best Practices. February 9, 2015. online: https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/. +## Topic Name Structure + +Whenever a message is published or subscribed a **Topic Name** is specified. It is a hierarchical structure composed by one or more **Topic Levels** separated by slashes `/` (the **Topic Level Separators**). + +* **Topic Level** - Is a label formed with alphanumeric characters, and can also have: white space, underscore and minus. + +## Best Practices +The following best practices have been adopted in the Harena project and must be followed by all developers. They are derived from [MQTT Essentials Part 5: MQTT Topics & Best Practices](https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/). + +* **Never use a leading forward slash** - A Topic Name can optionally start and/or end by a slash `/`, but it adds an extra unnecessary level, therefore they are not adopted in Harena. + +* **Never use spaces in a topic** - Even though MQTT supports spaces, they are not used in Harena. + +## Topic Filters and Wildcards + +In the subscription process, it is possible to specify a specific Topic Name or a Topic Filter, which works as a regular expression representing a set of possible Topic Names. + +Wildcards are represented by the special `#` and/or `+` characters, appearing inside a Topic Name in the subscription process. They enable the subscription of a set of topics, since they generically represent one or more Topic Levels, according to the following rules: +### Multilevel Wildcard `#` +The wildcard `#` can be used only in two positions in the Topic Filter: +* alone (the filter is only a `#`) - matches any Topic Name with any number of levels; +* end of the Topic Name (always preceded by a `/ `) - matches any number of Topic Levels with the prefix specified before the wildcard. + +### Single Level Wildcard `+` +Only a single Topic Level can be matched by the wildcard `+`, which represents any possible complete Topic Level Label. The `+` wildcard can appear only in four positions: +* alone (the filter is only a `+`) - matches any Topic Label in a single level (without slashes); +* beginning of the Topic Filter, always followed by a slash; +* end of the Topic Filter, always preceded by a slash; +* middle of the Topic Filter, always between two slashes. # Message Paths in the Bus +## Control Actions + +General protocol: `control//`. + +Most of the control actions trigger the final action, for example, the `control/case/load` control action is the start of the process to trigger the `case//load` action. + +* `control/case/load` +* `control/case/selected` +* `control/case/save` +* `control/case/play` +* `control/knot/edit` +* `control/config/edit` + ## Persisted Messages All the internal paths are mapped to the external paths prefixing the path by: `/execution/`, where `` is the id of the case instance that is being executed. -### Entity: `dcc-input` -* `set ` \[`/dcc-input/set/`\] - Notifies the input of a value by the user related to a ``. +### Entity: `template_family` +* `template_family/*/get` - Returns the list of the available template families. + + response topic: `template_family/*` + message: {: } + +### Entity: `template` +* `template/.