forked from vganshin/aidbox-ui-projects
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
433 additions
and
231 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,30 @@ | ||
import { describe, expect, test } from 'vitest' | ||
import { describe, expect, test, beforeAll } from 'vitest' | ||
|
||
beforeAll(async () => { | ||
await http({method: "POST", | ||
url: "/$sql", | ||
body: ["truncate patient"]}); | ||
}); | ||
|
||
describe('Patient', async () => { | ||
test('Create /Patient', async () => { | ||
test('Create /Patient', async () => { | ||
|
||
let resp; | ||
let resp; | ||
|
||
resp = await http({method: "POST", | ||
url: "/$sql", | ||
body: ["truncate patient"]}) | ||
resp = await http({method: "POST", | ||
url: "/$sql", | ||
body: ["truncate patient"]}) | ||
|
||
resp = await http({method: "GET", | ||
url: "/Patient"}); | ||
resp = await http({method: "GET", | ||
url: "/Patient"}); | ||
|
||
expect(resp.total).toBe(0); | ||
|
||
resp = await http({method: "POST", | ||
url: "/Patient", | ||
body: {name: [{given: ["John"]}]}}); | ||
resp = await http({method: "POST", | ||
url: "/Patient", | ||
body: {name: [{given: ["John"]}]}}); | ||
|
||
resp = await http({method: "GET", | ||
url: "/Patient"}); | ||
resp = await http({method: "GET", | ||
url: "/Patient"}); | ||
|
||
expect(resp.total).toBe(1); | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,88 @@ | ||
(box/set-header! "Content-Type" "text/vnd.turbo-stream.html; charset=utf-8") | ||
|
||
(let [params (box/url-params) | ||
_ (m/set :params params) | ||
patients (->> (box/sql ["select resource || jsonb_build_object('id', id) resource from Patient | ||
where resource::text ilike ?" (str "%" (:query params) "%")]) | ||
(mapv :resource)) | ||
_ (m/set :patients patients) | ||
] | ||
|
||
[:turbo-stream {:target "patients" | ||
:action "update"} | ||
(into [:template] | ||
(map (fn [p] | ||
[:div {:class "contents" | ||
:id (str "patient-" (:id p))} | ||
[:div | ||
{:class "px-4 py-4 text-sm font-medium whitespace-nowrap flex items-center border-b"} | ||
[:h2 | ||
{:class "font-medium text-gray-800 dark:text-white"} | ||
(str (get-in p [:name 0 :given 0]) ", " | ||
(get-in p [:name 0 :family]))]] | ||
[:div | ||
{:class "px-12 py-4 text-sm font-medium whitespace-nowrap flex items-center border-b"} | ||
(when-let [birth-date (get-in p [:birthDate])] | ||
[:div | ||
{:class | ||
"inline px-3 py-1 text-sm font-normal rounded-full text-emerald-500 gap-x-2 bg-emerald-100/60 dark:bg-gray-800"} | ||
birth-date])] | ||
[:div | ||
{:class "px-4 py-4 text-sm whitespace-nowrap flex items-center border-b"} | ||
|
||
patients* (cond->> patients | ||
(not-empty (:gender params)) | ||
(filter (fn [p] (= (:gender params) (:gender p))))) | ||
_ (m/set :patients patients*) | ||
encode-params (fn [qparams] | ||
(->> qparams | ||
(map (fn [[k v]] (str (name k) "=" v))) | ||
(clojure.string/join "&")))] | ||
[:<> | ||
(when (:gender params) | ||
(let [inactive-class "px-5 py-2 text-xs font-medium text-gray-600 transition-colors duration-200 sm:text-sm dark:bg-gray-800 dark:text-gray-300" | ||
active-class (str inactive-class " bg-gray-100") | ||
|
||
status-button (fn [gender] | ||
[:a | ||
{:class (if (= (:gender params) (not-empty gender)) active-class inactive-class) | ||
:data-turbo-action "advance" | ||
:href (str "/ui/patients?" (cond-> params | ||
(not-empty gender) | ||
(assoc :gender gender) | ||
|
||
(empty? gender) | ||
(dissoc :gender) | ||
|
||
:true | ||
encode-params))} | ||
(or (some-> gender not-empty clojure.string/capitalize) "View all")])] | ||
[:turbo-stream {:target "gender-filter" | ||
:action "update"} | ||
[:template | ||
(status-button "") | ||
(status-button "male") | ||
(status-button "female")]]) | ||
) | ||
|
||
[:turbo-stream {:target "patients" | ||
:action "update"} | ||
(into [:template] | ||
(map (fn [p] | ||
[:div {:class "contents" | ||
:id (str "patient-" (:id p))} | ||
[:div | ||
{:class "px-4 py-4 text-sm font-medium whitespace-nowrap flex items-center border-b"} | ||
[:h2 | ||
{:class "font-medium text-gray-800 dark:text-white"} | ||
(str (get-in p [:name 0 :given 0]) ", " | ||
(get-in p [:name 0 :family]))]] | ||
[:div | ||
{:class "px-12 py-4 text-sm font-medium whitespace-nowrap flex items-center border-b"} | ||
(when-let [birth-date (get-in p [:birthDate])] | ||
[:div | ||
[:h4 {:class "text-gray-700 dark:text-gray-200"} (get-in p [:gender])]]] | ||
[:div | ||
{:class "px-4 py-4 text-sm whitespace-nowrap flex items-center border-b"} | ||
[:form {:action "/ui/patients/edit" | ||
:class "mb-0"} | ||
[:input {:type "hidden" | ||
:name "patient-id" | ||
:value (:id p)}] | ||
[:button | ||
{:class | ||
"px-3 py-2 text-gray-500 transition-colors duration-200 rounded-lg dark:text-gray-300 hover:bg-gray-100"} | ||
[:i.fas.fa-pencil]]] | ||
[:a | ||
{:class | ||
"px-3 py-2 text-gray-500 transition-colors duration-200 rounded-lg dark:text-gray-300 hover:bg-gray-100" | ||
:href (str "/ui/patients/" (str (:id p))) | ||
:data-turbo-method "DELETE" | ||
:data-turbo-confirm "Do you want to delete patient?"} | ||
[:i.fas.fa-trash]]]]) patients)) | ||
"inline px-3 py-1 text-sm font-normal rounded-full text-emerald-500 gap-x-2 bg-emerald-100/60 dark:bg-gray-800"} | ||
birth-date])] | ||
[:div | ||
{:class "px-4 py-4 text-sm whitespace-nowrap flex items-center border-b"} | ||
[:div | ||
[:h4 {:class "text-gray-700 dark:text-gray-200"} (get-in p [:gender])]]] | ||
[:div | ||
{:class "px-4 py-4 text-sm whitespace-nowrap flex items-center border-b"} | ||
[:form {:action "/ui/patients/edit" | ||
:class "mb-0"} | ||
[:input {:type "hidden" | ||
:name "patient-id" | ||
:value (:id p)}] | ||
[:button | ||
{:class | ||
"px-3 py-2 text-gray-500 transition-colors duration-200 rounded-lg dark:text-gray-300 hover:bg-gray-100"} | ||
[:i.fas.fa-pencil]]] | ||
[:a | ||
{:class | ||
"px-3 py-2 text-gray-500 transition-colors duration-200 rounded-lg dark:text-gray-300 hover:bg-gray-100" | ||
:href (str "/ui/patients/" (str (:id p))) | ||
:data-turbo-method "DELETE" | ||
:data-turbo-confirm "Do you want to delete patient?"} | ||
[:i.fas.fa-trash]]]]) patients*)) | ||
|
||
|
||
] | ||
]] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import { describe, expect, test, afterAll, beforeAll } from 'vitest' | ||
|
||
beforeAll(async () => { | ||
console.log("Delete all: "); | ||
|
||
await http({method: "POST", | ||
url: "/$sql", | ||
body: ["truncate patient"]}); | ||
|
||
await http({method: "POST", | ||
url: "/Patient", | ||
body: {id: "pt-1", | ||
name: [{given: ["Paul"], family: "Mask"}]}}) | ||
|
||
}); | ||
|
||
afterAll(async () => { | ||
await http({method: "POST", | ||
url: "/$sql", | ||
body: ["truncate patient"]}); | ||
}); | ||
|
||
describe('Patient grid', async () => { | ||
let resp; | ||
test("patient grid", async () => { | ||
resp = await http({method: "GET", | ||
url: "/ui/patients/search", | ||
headers: {"X-Aidbox-Dev": "model"} | ||
}); | ||
|
||
console.log(resp); | ||
|
||
expect(resp).toEqual({ | ||
params: {}, | ||
patients: expect.arrayContaining( | ||
[{id: "pt-1", | ||
name: [{family: "Mask", given: ["Paul"]}]}] | ||
)}); | ||
}); | ||
|
||
test("search should return empty list", async () => { | ||
resp = await http({method: "GET", | ||
url: "/ui/patients/search?query=tahto", | ||
headers: {"X-Aidbox-Dev": "model"}}); | ||
expect(resp).toEqual({ | ||
params: {query: "tahto"}, | ||
patients: [], | ||
}); | ||
|
||
}); | ||
|
||
test("search should return one patient", async () => { | ||
resp = await http({method: "GET", | ||
url: "/ui/patients/search?query=paul", | ||
headers: {"X-Aidbox-Dev": "model"}}); | ||
expect(resp).toEqual({ | ||
params: {query: "paul"}, | ||
patients: [{id: "pt-1", | ||
name: [{family: "Mask", given: ["Paul"]}]}], | ||
}); | ||
}) | ||
|
||
}); | ||
|
||
describe('patient form', async () => { | ||
let resp; | ||
|
||
test("add patient should open empty form", async () => { | ||
resp = await http({method: "GET", | ||
url: "/ui/patients/edit", | ||
headers: {"X-Aidbox-Dev": "model"}}); | ||
|
||
expect(resp.patient).toBeNull(); | ||
}); | ||
|
||
test("edit patient should open filled form", async () => { | ||
resp = await http({method: "GET", | ||
url: "/ui/patients/edit?patient-id=pt-1", | ||
headers: {"X-Aidbox-Dev": "model"}}); | ||
|
||
expect(resp.patient).toMatchObject({ | ||
id: "pt-1", | ||
name: [{given: ["Paul"], family: "Mask"}] | ||
}); | ||
}); | ||
|
||
test("save patient should return new patient", async () => { | ||
var formData = new FormData(); | ||
formData.append("id", "pt-1"); | ||
formData.append("given", "Pasha"), | ||
formData.append("family", "Mask"); | ||
formData.append("gender", "male"); | ||
|
||
resp = await http({method: "POST", | ||
url: "/ui/patients/save", | ||
body: formData, | ||
headers: { | ||
"content-type": "multipart/form-data", | ||
"x-aidbox-dev": "model", | ||
}}); | ||
|
||
expect(resp).toMatchObject({ | ||
"saved-patient": { | ||
id: "pt-1", | ||
name: [{given: ["Pasha"], family: "Mask"}], | ||
gender: "male", | ||
|
||
}}); | ||
|
||
}); | ||
}); | ||
|
||
describe("delete patient", async () => { | ||
let resp; | ||
|
||
test("delete patient", async () => { | ||
resp = await http({method: "DELETE", | ||
url: "/ui/patients/pt-1", | ||
headers: {"x-aidbox-dev": "model"}}); | ||
|
||
expect(resp.result).toMatchObject({ | ||
id: "pt-1", | ||
}); | ||
}); | ||
|
||
test("patient grid should not include deleted patient", async () => { | ||
resp = await http({method: "GET", | ||
url: "/ui/patients/search?query=Mask", | ||
headers: {"x-aidbox-dev": "model"}}); | ||
|
||
expect(resp.patients).toEqual([]); | ||
|
||
}); | ||
}); |
Oops, something went wrong.