From 27596568a841cbf01bf892d243242c065183c0e6 Mon Sep 17 00:00:00 2001 From: Tareq Kirresh Date: Fri, 25 Sep 2020 13:43:25 +0300 Subject: [PATCH] #73 Vue loading enabled, api.js and icpc.js moved to webjar-like location for access. --- core/pom.xml | 68 +----- .../java/org/openmymed/accessmd/app/App.java | 193 +++++++++--------- .../META-INF/resources/js/utils/api.js | 179 ++++++++++++++++ .../META-INF/resources/js/utils/icpc.js | 34 +++ core/src/main/resources/vue/layout.html | 17 ++ core/src/main/resources/vue/views/login.vue | 29 +++ .../main/resources/vue/views/second-view.vue | 18 ++ 7 files changed, 382 insertions(+), 156 deletions(-) create mode 100644 core/src/main/resources/META-INF/resources/js/utils/api.js create mode 100644 core/src/main/resources/META-INF/resources/js/utils/icpc.js create mode 100644 core/src/main/resources/vue/layout.html create mode 100644 core/src/main/resources/vue/views/login.vue create mode 100644 core/src/main/resources/vue/views/second-view.vue diff --git a/core/pom.xml b/core/pom.xml index a1f2ee8..bbf81db 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -103,7 +103,12 @@ org.slf4j slf4j-simple - 1.8.0-beta4 + 1.7.26 + + + org.webjars.npm + vue + 2.6.10 @@ -122,67 +127,6 @@ - - com.github.eirslett - frontend-maven-plugin - 1.6 - - ${node.version} - ${basedir}/src/main/webapp - - - - install node - - install-node-and-npm - - validate - - - npm install - - npm - - validate - - install - - - - npm run build - - npm - - generate-resources - - run build - - - - - - maven-resources-plugin - 3.1.0 - - - copy-resources - - process-resources - - copy-resources - - - ${basedir}/target/classes/webapp - - - src/main/webapp/dist - true - - - - - - org.apache.maven.plugins maven-dependency-plugin diff --git a/core/src/main/java/org/openmymed/accessmd/app/App.java b/core/src/main/java/org/openmymed/accessmd/app/App.java index 7cbd1a1..75877d6 100644 --- a/core/src/main/java/org/openmymed/accessmd/app/App.java +++ b/core/src/main/java/org/openmymed/accessmd/app/App.java @@ -14,6 +14,7 @@ import static io.javalin.core.security.SecurityUtil.roles; import io.javalin.http.Context; import io.javalin.http.staticfiles.Location; +import io.javalin.plugin.rendering.vue.VueComponent; import java.io.File; import java.sql.DriverManager; import java.sql.SQLException; @@ -105,7 +106,7 @@ public void run() { public static void startServer() { app = Javalin.create().start(7000); - + app.config.enableWebjars(); // Set the access-manager that Javalin should use app.config.accessManager((handler, ctx, permittedRoles) -> { if (!permittedRoles.contains(NONE)) { @@ -123,114 +124,123 @@ public static void startServer() { ICPCRestService icpcService = new ICPCRestService(); DoctorRestService doctorService = new DoctorRestService(); NotificationRestService notificationService = new NotificationRestService(); + app.get("/", new VueComponent(""), roles(NONE)); + app.get("/dashboard", new VueComponent(""), roles(ROLE_DOCTOR)); + app.get("/patient", new VueComponent(""), roles(ROLE_DOCTOR)); + app.get("/patient/:patientId", new VueComponent(""), roles(ROLE_DOCTOR)); + + app.get("/admin/dashboard", new VueComponent(""), roles(ROLE_ADMIN)); + app.routes(() -> { - path("login", () -> { - post(userService::signIn, roles(NONE)); - }); - path("symptom", () -> { - path("codes", () -> { - get(icpcService::getICPCSymptoms, roles(NONE)); - }); - }); - path("notification", () -> { - get(notificationService::getNotifications, roles(ROLE_PATIENT, ROLE_DOCTOR)); - }); - path("patient", () -> { - path("doctor", () -> { - get(patientService::getDoctor, roles(ROLE_PATIENT)); - }); - path("signup", () -> { - post(patientService::signUp, roles(NONE)); - }); - path("profile", () -> { - put(patientService::updateMedicalProfile, roles(ROLE_PATIENT)); - get(patientService::getMedicalProfile, roles(ROLE_PATIENT)); - }); - path("reccomendation", () -> { - get(patientService::getReccomendations, roles(ROLE_PATIENT)); - }); - path("question", () -> { - get(patientService::getUnansweredQuestions, roles(ROLE_PATIENT)); - path(":id", () -> { - path("answer", () -> { - put(patientService::answerQuestion, roles(ROLE_PATIENT)); - }); - }); - }); - path("code", () -> { - get(patientService::getSecurityCode, roles(ROLE_PATIENT)); + path("/api", () -> { + path("login", () -> { + post(userService::signIn, roles(NONE)); }); path("symptom", () -> { - post(patientService::addSymptom, roles(ROLE_PATIENT)); - }); - path("vitals", () -> { - post(patientService::addVitalsMeasurment, roles(ROLE_PATIENT)); + path("codes", () -> { + get(icpcService::getICPCSymptoms, roles(NONE)); + }); }); - }); - path("doctor", () -> { - path("feed", () -> { - get(doctorService::getPatientsFeed, roles(ROLE_DOCTOR)); + path("notification", () -> { + get(notificationService::getNotifications, roles(ROLE_PATIENT, ROLE_DOCTOR)); }); path("patient", () -> { - path("symptom", () -> { - path("count", () -> { - get(doctorService::getUnseenSymptomCount, roles(ROLE_DOCTOR)); - }); + path("doctor", () -> { + get(patientService::getDoctor, roles(ROLE_PATIENT)); }); - path("answer", () -> { - path("count", () -> { - get(doctorService::getUnseenAnswerCount, roles(ROLE_DOCTOR)); - }); + path("signup", () -> { + post(patientService::signUp, roles(NONE)); }); - - path("count", () -> { - get(doctorService::getPatientCount, roles(ROLE_DOCTOR)); + path("profile", () -> { + put(patientService::updateMedicalProfile, roles(ROLE_PATIENT)); + get(patientService::getMedicalProfile, roles(ROLE_PATIENT)); }); - get(doctorService::listPatients, roles(ROLE_DOCTOR)); - path("add", () -> { - post(doctorService::consumePatientCode, roles(ROLE_DOCTOR)); + path("reccomendation", () -> { + get(patientService::getReccomendations, roles(ROLE_PATIENT)); }); - path(":id", () -> { - get(doctorService::getPatient, roles(ROLE_DOCTOR)); - path("profile", () -> { - get(doctorService::getPatientProfile, roles(ROLE_DOCTOR)); - }); - path("vitals", () -> { - get(doctorService::getPatientVitalsMeasurments, roles(ROLE_DOCTOR)); + path("question", () -> { + get(patientService::getUnansweredQuestions, roles(ROLE_PATIENT)); + path(":id", () -> { + path("answer", () -> { + put(patientService::answerQuestion, roles(ROLE_PATIENT)); + }); }); + }); + path("code", () -> { + get(patientService::getSecurityCode, roles(ROLE_PATIENT)); + }); + path("symptom", () -> { + post(patientService::addSymptom, roles(ROLE_PATIENT)); + }); + path("vitals", () -> { + post(patientService::addVitalsMeasurment, roles(ROLE_PATIENT)); + }); + }); + path("doctor", () -> { + path("feed", () -> { + get(doctorService::getPatientsFeed, roles(ROLE_DOCTOR)); + }); + path("patient", () -> { path("symptom", () -> { - get(doctorService::listPatientSymptoms, roles(ROLE_DOCTOR)); - path(":symptom_id", () -> { - path("seen", () -> { - put(doctorService::markSymptomSeen, roles(ROLE_DOCTOR)); - }); + path("count", () -> { + get(doctorService::getUnseenSymptomCount, roles(ROLE_DOCTOR)); }); }); path("answer", () -> { - get(doctorService::listPatientAnswers, roles(ROLE_DOCTOR)); - path(":answer_id", () -> { - path("seen", () -> { - put(doctorService::markAnswerSeen, roles(ROLE_DOCTOR)); - }); + path("count", () -> { + get(doctorService::getUnseenAnswerCount, roles(ROLE_DOCTOR)); }); }); - path("question", () -> { - get(doctorService::listPatientQuestions, roles(ROLE_DOCTOR)); - post(doctorService::createPatientQuestion, roles(ROLE_DOCTOR)); - path(":question_id", () -> { - delete(doctorService::deletePatientQuestion, roles(ROLE_DOCTOR)); - put(doctorService::updatePatientQuestion, roles(ROLE_DOCTOR)); - get(doctorService::getPatientQuestion, roles(ROLE_DOCTOR)); + + path("count", () -> { + get(doctorService::getPatientCount, roles(ROLE_DOCTOR)); + }); + get(doctorService::listPatients, roles(ROLE_DOCTOR)); + path("add", () -> { + post(doctorService::consumePatientCode, roles(ROLE_DOCTOR)); + }); + path(":id", () -> { + get(doctorService::getPatient, roles(ROLE_DOCTOR)); + path("profile", () -> { + get(doctorService::getPatientProfile, roles(ROLE_DOCTOR)); + }); + path("vitals", () -> { + get(doctorService::getPatientVitalsMeasurments, roles(ROLE_DOCTOR)); + }); + path("symptom", () -> { + get(doctorService::listPatientSymptoms, roles(ROLE_DOCTOR)); + path(":symptom_id", () -> { + path("seen", () -> { + put(doctorService::markSymptomSeen, roles(ROLE_DOCTOR)); + }); + }); + }); + path("answer", () -> { + get(doctorService::listPatientAnswers, roles(ROLE_DOCTOR)); + path(":answer_id", () -> { + path("seen", () -> { + put(doctorService::markAnswerSeen, roles(ROLE_DOCTOR)); + }); + }); + }); + path("question", () -> { + get(doctorService::listPatientQuestions, roles(ROLE_DOCTOR)); + post(doctorService::createPatientQuestion, roles(ROLE_DOCTOR)); + path(":question_id", () -> { + delete(doctorService::deletePatientQuestion, roles(ROLE_DOCTOR)); + put(doctorService::updatePatientQuestion, roles(ROLE_DOCTOR)); + get(doctorService::getPatientQuestion, roles(ROLE_DOCTOR)); + }); }); }); }); - }); - }); - path("admin", () -> { - path("doctor", () -> { - post(doctorService::createDoctor, roles(ROLE_ADMIN)); - get(doctorService::getDoctors, roles(ROLE_ADMIN)); + }); + path("admin", () -> { + path("doctor", () -> { + post(doctorService::createDoctor, roles(ROLE_ADMIN)); + get(doctorService::getDoctors, roles(ROLE_ADMIN)); + }); }); }); }); @@ -240,11 +250,6 @@ public static void startServer() { ctx.result(e.getMessage()); }); app.config.sessionHandler(() -> fileSessionHandler()); - if (Boolean.valueOf(System.getProperty("app.production", "false"))) { - app.config.addStaticFiles("/webapp"); - } else { - app.config.addStaticFiles("./src/main/webapp/dist", Location.EXTERNAL); - } } @@ -277,7 +282,7 @@ public static void stopServer() { } private static void createAdminIfNotFound() { - try (UserRepository repo = UserRepositoryFactory.getInstance().get()) { + try ( UserRepository repo = UserRepositoryFactory.getInstance().get()) { if (repo.getUsersByRole(ROLE_ADMIN).isEmpty()) { log.info("No Admins Found; Creating one now"); String password = RandomStringUtils.random(16, true, true); diff --git a/core/src/main/resources/META-INF/resources/js/utils/api.js b/core/src/main/resources/META-INF/resources/js/utils/api.js new file mode 100644 index 0000000..e15e8ba --- /dev/null +++ b/core/src/main/resources/META-INF/resources/js/utils/api.js @@ -0,0 +1,179 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +var headers = { + "Content-Type": "application/json" +} + +window.api = {}; +const process = (res) => { + if (res.ok) { + return res.json(); + } else if (res.status == 401 || res.status == 403) { + window.location.path="/login" + } else { + throw new Error(res.status); + } +} + +window.api.getPatientVitals = (patientId) => { + return fetch("/api/doctor/patient/" + patientId + "/vitals", { + method: "GET", + headers: headers + }).then((res) => { + return process(res); + }) +} + + +window.api.addDoctor = (doctor) => { + return fetch("/api/admin/doctor", { + method: "POST", + headers: headers, + body: JSON.stringify(doctor) + }).then((res) => { + return process(res); + }) +} + +window.api.assignPatientToMyself = (code) => { + + return fetch("/api/doctor/patient/add", { + method: "POST", + headers: headers, + body: JSON.stringify({ + code: code + }) + }).then((res) => { + return process(res); + }); +} + +window.api.getPatientAnswers = (patientId) => { + return fetch("/api/doctor/patient/" + patientId + "/answer", { + method: "GET", + headers: headers, + }).then((res) => { + return process(res) + }) + +} + + +window.api.archiveAnswer = (patientId, answerId) => { + return fetch("/api/doctor/patient/" + patientId + "/answer/" + answerId + "/seen", { + method: "PUT", + headers: headers, + }).then((res) => { + return process(res); + }) +} + +window.api.getPatientMedicalProfile = (patientId) => { + return fetch("/api/doctor/patient/" + patientId, { + method: "GET", + headers: headers, + }).then((res) => { + return process(res); + }); + +} + +window.api.getPatientPersonalProfile = (patientId) => { + return fetch("/api/doctor/patient/" + patientId, { + method: "GET", + headers: headers, + }).then((res) => { + return process(res); + }); +} + + +window.api.getPatientsCount = () => { + fetch("/api/doctor/patient/count", { + method: "GET", + headers: headers + }).then((res) => { + return process(res); + }); +} + +window.api.getUarchivedSymptomsCount = () => { + fetch("/api/doctor/patient/symptom/count", { + method: "GET", + headers: headers + }).then((res) => { + return process(res); + }); +} + +window.api.getUnarchivedAnswersCount = () => { + fetch("/api/doctor/patient/answer/count", { + method: "GET", + headers: headers + }).then((res) => { + return process(res); + }); +} + +window.api.getDoctorFeed = () => { + fetch("/api/doctor/feed", { + method: "GET", + headers: headers + }).then((res) => { + return process(res); + }); +} + +window.api.getPatientSymptoms = (patientId) => { + return fetch("/api/doctor/patient/" + patientId + "/symptom", { + method: "GET", + headers: headers + }).then((res) => { + return process(res); + }); +} + +window.api.getPatients = () => { + return fetch("/api/doctor/patient", { + method: "GET", + headers: headers + }).then((res) => { + return process(res); + }); +} + +window.api.getPatientQuestions = (patientId) => { + return fetch("/api/doctor/patient/" + patientId + "/question", { + method: "GET", + headers: headers + }).then((res) => { + return process(res); + }); +} + +window.api.addQuestion = (patientId, question) => { + fetch("/api/doctor/patient/" + patientId + "/question", { + method: "POST", + headers: headers, + body: JSON.stringify(question) + }).then((res) => { + return process(res); + }); +} + +window.api.login = (username, password) => { + fetch("/api/login", { + method: "POST", + headers: headers, + body: JSON.stringify({ + username: username, + password: password + }), + }).then((res) => { + return process(res); + }) +} \ No newline at end of file diff --git a/core/src/main/resources/META-INF/resources/js/utils/icpc.js b/core/src/main/resources/META-INF/resources/js/utils/icpc.js new file mode 100644 index 0000000..c3b1e6b --- /dev/null +++ b/core/src/main/resources/META-INF/resources/js/utils/icpc.js @@ -0,0 +1,34 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +window.icpc = {}; +window.icpc.loadIcpc = () => { + return fetch("/symptom/codes", { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }).then((res) => { + if (res.ok) { + return res.json(); + } else { + alert("Wrong username or password"); + } + }).then(data => { + window.localStorage.setItem("icpc", JSON.stringify(data)) + }) +} + + +window.icpc.getTitle = (code) => { + let i = 0; + let codes = JSON.parse(window.localStorage.getItem("icpc")); + for (i; i < codes.length; i++) { + if (codes[i].code === code) { + return codes[i].title; + } + } + return "CODE " + code + " NOT FOUND"; +} diff --git a/core/src/main/resources/vue/layout.html b/core/src/main/resources/vue/layout.html new file mode 100644 index 0000000..812f1ea --- /dev/null +++ b/core/src/main/resources/vue/layout.html @@ -0,0 +1,17 @@ + + + + + + + + @componentRegistration + +
+ @routeComponent +
+ + + \ No newline at end of file diff --git a/core/src/main/resources/vue/views/login.vue b/core/src/main/resources/vue/views/login.vue new file mode 100644 index 0000000..3cb608d --- /dev/null +++ b/core/src/main/resources/vue/views/login.vue @@ -0,0 +1,29 @@ + + + + \ No newline at end of file diff --git a/core/src/main/resources/vue/views/second-view.vue b/core/src/main/resources/vue/views/second-view.vue new file mode 100644 index 0000000..fe0b282 --- /dev/null +++ b/core/src/main/resources/vue/views/second-view.vue @@ -0,0 +1,18 @@ + + +