diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d7c51d..595addb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,14 +3,6 @@ All notable changes to this project will be documented in this file. -## [v0.2.1](https://code.thetadev.de/HSA/Visitenbuch/compare/v0.2.0..v0.2.1) - 2024-05-07 - -### 🐛 Bug Fixes - -- Carta editor mobile context menu transparent - ([6bd7e15](https://code.thetadev.de/HSA/Visitenbuch/commit/6bd7e157eea6589be82692499cb956455386f7e5)) -- Dont output null age - ([c2c21d1](https://code.thetadev.de/HSA/Visitenbuch/commit/c2c21d1296c399324cdfa661c490cee79f7e16e1)) - - ## [v0.2.0](https://code.thetadev.de/HSA/Visitenbuch/compare/v0.1.0..v0.2.0) - 2024-05-06 ### 🚀 Features diff --git a/package.json b/package.json index 9ba37e9..fbb40e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "visitenbuch", - "version": "0.2.1", + "version": "0.2.0", "private": true, "license": "AGPL-3.0", "scripts": { @@ -21,7 +21,7 @@ "@floating-ui/core": "^1.6.1", "@mdi/js": "^7.4.47", "@prisma/client": "^5.13.0", - "@thetadev/carta-md": "^1.0.1", + "carta-md": "4.0.2", "diff": "^5.2.0", "isomorphic-dompurify": "^2.9.0", "prisma": "^5.13.0", @@ -71,5 +71,10 @@ "vite": "^5.2.11", "vitest": "^1.6.0" }, - "type": "module" + "type": "module", + "pnpm": { + "patchedDependencies": { + "carta-md@4.0.2": "patches/carta-md@4.0.2.patch" + } + } } diff --git a/patches/carta-md@4.0.2.patch b/patches/carta-md@4.0.2.patch new file mode 100644 index 0000000..2b8589e --- /dev/null +++ b/patches/carta-md@4.0.2.patch @@ -0,0 +1,27 @@ +# Change "markdown-body" css class to "prose" for Tailwind compatibility +diff --git a/dist/Markdown.svelte b/dist/Markdown.svelte +index 92b29fade303a14539720b9bc389e7a41202b1cf..cbdeede16d7af17a481bcac519aea92b8959803d 100644 +--- a/dist/Markdown.svelte ++++ b/dist/Markdown.svelte +@@ -15,7 +15,7 @@ onMount(async () => { + }); + + +-
++
+ + {@html rendered} + {#if mounted} +diff --git a/dist/internal/components/Renderer.svelte b/dist/internal/components/Renderer.svelte +index 1d2ff1a6937bc490ea1e6eb5c2ef9f3b33e4c326..6a95c154ea4ca7c4d19b20d02b3504fb2b65b7f7 100644 +--- a/dist/internal/components/Renderer.svelte ++++ b/dist/internal/components/Renderer.svelte +@@ -17,7 +17,7 @@ onMount(() => carta.$setRenderer(elem)); + onMount(() => mounted = true); + + +-
++
+ + {@html renderedHtml} + {#if mounted} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 23cae13..e5a6cc0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,11 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +patchedDependencies: + carta-md@4.0.2: + hash: i33ea43vfgrg3ziu25cfu7s2zq + path: patches/carta-md@4.0.2.patch + dependencies: '@auth/core': specifier: ^0.30.0 @@ -17,9 +22,9 @@ dependencies: '@prisma/client': specifier: ^5.13.0 version: 5.13.0(prisma@5.13.0) - '@thetadev/carta-md': - specifier: ^1.0.1 - version: 1.0.1(svelte@4.2.15) + carta-md: + specifier: 4.0.2 + version: 4.0.2(patch_hash=i33ea43vfgrg3ziu25cfu7s2zq)(svelte@4.2.15) diff: specifier: ^5.2.0 version: 5.2.0 @@ -884,6 +889,10 @@ packages: dev: true optional: true + /@shikijs/core@1.4.0: + resolution: {integrity: sha512-CxpKLntAi64h3j+TwWqVIQObPTED0FyXLHTTh3MKXtqiQNn2JGcMQQ362LftDbc9kYbDtrksNMNoVmVXzKFYUQ==} + dev: false + /@sideway/address@4.1.5: resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} requiresBuild: true @@ -1079,22 +1088,6 @@ packages: tailwindcss: 3.4.3 dev: true - /@thetadev/carta-md@1.0.1(svelte@4.2.15): - resolution: {integrity: sha512-B6TyB5gvrc1T5pEOM5nIZA+N6gG7EK7AJBrQCfokzrpNarq7CvgJEVaQoWh5oukB2MrRYSIQAYUNIoqEKzMSag==} - peerDependencies: - svelte: ^3.54.0 || ^4.0.0 - dependencies: - prismjs: 1.29.0 - rehype-stringify: 10.0.0 - remark-gfm: 4.0.0 - remark-parse: 11.0.0 - remark-rehype: 11.1.0 - svelte: 4.2.15 - unified: 11.0.4 - transitivePeerDependencies: - - supports-color - dev: false - /@trpc/client@10.45.2(@trpc/server@10.45.2): resolution: {integrity: sha512-ykALM5kYWTLn1zYuUOZ2cPWlVfrXhc18HzBDyRhoPYN0jey4iQHEFSEowfnhg1RvYnrAVjNBgHNeSAXjrDbGwg==} peerDependencies: @@ -1764,6 +1757,23 @@ packages: resolution: {integrity: sha512-RHVYKov7IcdNjVHJFNY/78RdG4oGVjbayxv8u5IO74Wv7Hlq4PnJE6mo/OjFijjVFNy5ijnCt6H3IIo4t+wfEw==} dev: true + /carta-md@4.0.2(patch_hash=i33ea43vfgrg3ziu25cfu7s2zq)(svelte@4.2.15): + resolution: {integrity: sha512-wMlw0r5RZiVwvF3dyxE/vHj9pXlXbzpijJ3m/o9zqZe7Cf6D96AjyBHBpa0A0OPj/uEJVF3k0R6ctopBJCpCQg==} + peerDependencies: + svelte: ^3.54.0 || ^4.0.0 + dependencies: + rehype-stringify: 10.0.0 + remark-gfm: 4.0.0 + remark-parse: 11.0.0 + remark-rehype: 11.1.0 + shiki: 1.4.0 + svelte: 4.2.15 + unified: 11.0.4 + transitivePeerDependencies: + - supports-color + dev: false + patched: true + /ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} dev: false @@ -4414,11 +4424,6 @@ packages: '@prisma/engines': 5.13.0 dev: false - /prismjs@1.29.0: - resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} - engines: {node: '>=6'} - dev: false - /property-expr@2.0.6: resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} requiresBuild: true @@ -4716,6 +4721,12 @@ packages: engines: {node: '>=8'} dev: true + /shiki@1.4.0: + resolution: {integrity: sha512-5WIn0OL8PWm7JhnTwRWXniy6eEDY234mRrERVlFa646V2ErQqwIFd2UML7e0Pq9eqSKLoMa3Ke+xbsF+DAuy+Q==} + dependencies: + '@shikijs/core': 1.4.0 + dev: false + /side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} diff --git a/prisma/migrations/20240509111910_execution_done/migration.sql b/prisma/migrations/20240509111910_execution_done/migration.sql deleted file mode 100644 index fc40831..0000000 --- a/prisma/migrations/20240509111910_execution_done/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "entry_executions" ADD COLUMN "done" BOOLEAN NOT NULL DEFAULT true; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 633705d..b626e89 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -142,7 +142,6 @@ model EntryExecution { entry_id Int text String - done Boolean @default(true) author User @relation(fields: [author_id], references: [id]) author_id Int diff --git a/src/lib/components/entry/EntryBody.svelte b/src/lib/components/entry/EntryBody.svelte index 48b5383..2dd3afc 100644 --- a/src/lib/components/entry/EntryBody.svelte +++ b/src/lib/components/entry/EntryBody.svelte @@ -39,7 +39,7 @@

Erstellt {humanDate(entry.created_at, true)} · - {#if entry.execution?.done} + {#if entry.execution} Erledigt {humanDate(entry.execution.created_at)} {:else} Zu erledigen {humanDate(entry.current_version.date)} @@ -53,7 +53,7 @@ Beschreibung

- +
@@ -69,12 +69,9 @@ {#if withExecution && entry.execution}
-
+

- {entry.execution.done ? "Erledigt am" : "Notiz von"} {formatDate(entry.execution.created_at, true)} von + Erledigt am {formatDate(entry.execution.created_at, true)} von

@@ -91,12 +88,3 @@ {/if}
{/if} - - diff --git a/src/lib/components/table/EntryTable.svelte b/src/lib/components/table/EntryTable.svelte index 6ea8b98..7143f49 100644 --- a/src/lib/components/table/EntryTable.svelte +++ b/src/lib/components/table/EntryTable.svelte @@ -1,4 +1,5 @@ @@ -37,7 +38,7 @@ {#each entries.items as entry (entry.id)} {entry.current_version.text} - {#if entry.execution?.done} + {#if entry.execution} {formatDate(entry.execution.created_at, true)} void = () => {}; + export let sortData: SortRequest | undefined; + export let sortUpdate: (sort: SortRequest | undefined) => void = () => {}; export let baseUrl: string; diff --git a/src/lib/components/table/SortHeader.svelte b/src/lib/components/table/SortHeader.svelte index c4007fe..40aab97 100644 --- a/src/lib/components/table/SortHeader.svelte +++ b/src/lib/components/table/SortHeader.svelte @@ -1,33 +1,29 @@ @@ -36,9 +32,6 @@ {#if sorting > 0} {/if} - {#if sortData && sortData.length > 1 && index !== -1} - ({index + 1}) - {/if} {title} diff --git a/src/lib/components/ui/EntryTodoButton.svelte b/src/lib/components/ui/EntryTodoButton.svelte deleted file mode 100644 index 6bedd3e..0000000 --- a/src/lib/components/ui/EntryTodoButton.svelte +++ /dev/null @@ -1,11 +0,0 @@ -
- {#each { length: 4 } as _, i} - - {/each} -
diff --git a/src/lib/components/ui/markdown/Markdown.svelte b/src/lib/components/ui/markdown/Markdown.svelte index d67cd3e..c43ffe0 100644 --- a/src/lib/components/ui/markdown/Markdown.svelte +++ b/src/lib/components/ui/markdown/Markdown.svelte @@ -1,15 +1,10 @@ -
- - {@html rendered} -
+ diff --git a/src/lib/components/ui/markdown/MarkdownInput.svelte b/src/lib/components/ui/markdown/MarkdownInput.svelte index 276904e..df91d0a 100644 --- a/src/lib/components/ui/markdown/MarkdownInput.svelte +++ b/src/lib/components/ui/markdown/MarkdownInput.svelte @@ -1,13 +1,11 @@ -{#if !data.entry.execution?.done} +{#if !data.entry.execution}
-
+
-
- {/if} diff --git a/src/routes/(app)/entry/[id]/+page.ts b/src/routes/(app)/entry/[id]/+page.ts index 3e48be4..e99bd7b 100644 --- a/src/routes/(app)/entry/[id]/+page.ts +++ b/src/routes/(app)/entry/[id]/+page.ts @@ -1,26 +1,14 @@ import type { PageLoad } from "./$types"; -import { superValidate } from "sveltekit-superforms"; - import { ZUrlEntityId } from "$lib/shared/model/validation"; import { trpc } from "$lib/shared/trpc"; import { loadWrap } from "$lib/shared/util"; -import { SchemaNewExecution } from "./editExecution/schema"; - export const load: PageLoad = async (event) => { const entry = await loadWrap(async () => { const id = ZUrlEntityId.parse(event.params.id); return trpc(event).entry.get.query(id); }); - const form = await superValidate( - { - old_execution_id: entry.execution?.id, - ...entry.execution, - }, - SchemaNewExecution, - ); - - return { entry, form }; + return { entry }; }; diff --git a/src/routes/(app)/entry/[id]/editExecution/+page.server.ts b/src/routes/(app)/entry/[id]/editExecution/+page.server.ts index 2fd0dbe..8a0cb57 100644 --- a/src/routes/(app)/entry/[id]/editExecution/+page.server.ts +++ b/src/routes/(app)/entry/[id]/editExecution/+page.server.ts @@ -5,33 +5,24 @@ import { superValidate } from "sveltekit-superforms"; import { ZUrlEntityId } from "$lib/shared/model/validation"; import { trpc } from "$lib/shared/trpc"; -import { loadWrap, moveEntryTodoDate } from "$lib/shared/util"; +import { loadWrap } from "$lib/shared/util"; import { SchemaNewExecution } from "./schema"; export const actions: Actions = { default: async (event) => loadWrap(async () => { - const formData = await event.request.formData(); - const form = await superValidate(formData, SchemaNewExecution); + const form = await superValidate(event.request, SchemaNewExecution); if (!form.valid) { return fail(400, { form }); } const id = ZUrlEntityId.parse(event.params.id); - const todoDays = formData.get("todo"); - await trpc(event).entry.newExecution.mutate({ id, - execution: { - text: form.data.text, - done: todoDays === null, - }, + execution: form.data, old_execution_id: form.data.old_execution_id, }); - const nTodoDays = todoDays ? parseInt(todoDays.toString()) : 0; - await moveEntryTodoDate(id, nTodoDays, event); - redirect(302, `/entry/${id}`); }), }; diff --git a/src/routes/(app)/entry/[id]/editExecution/+page.svelte b/src/routes/(app)/entry/[id]/editExecution/+page.svelte index 6815372..4e94ca4 100644 --- a/src/routes/(app)/entry/[id]/editExecution/+page.svelte +++ b/src/routes/(app)/entry/[id]/editExecution/+page.svelte @@ -2,19 +2,19 @@ import type { PageData } from "./$types"; - import { superForm } from "sveltekit-superforms"; + import { defaults, superForm } from "sveltekit-superforms"; import { superformConfig } from "$lib/shared/util"; import EntryBody from "$lib/components/entry/EntryBody.svelte"; - import EntryTodoButton from "$lib/components/ui/EntryTodoButton.svelte"; import MarkdownInput from "$lib/components/ui/markdown/MarkdownInput.svelte"; import { SchemaNewExecution } from "./schema"; export let data: PageData; - const { form, errors, enhance } = superForm(data.form, { + const formData = defaults(SchemaNewExecution); + const { form, errors, enhance } = superForm(formData, { validators: SchemaNewExecution, ...superformConfig("Eintrag"), }); @@ -30,10 +30,8 @@ label="Ausführungstext bearbeiten" bind:value={$form.text} > -
+
-
- diff --git a/src/routes/(app)/entry/[id]/executions/+page.svelte b/src/routes/(app)/entry/[id]/executions/+page.svelte index 9f39031..694c7f2 100644 --- a/src/routes/(app)/entry/[id]/executions/+page.svelte +++ b/src/routes/(app)/entry/[id]/executions/+page.svelte @@ -22,9 +22,6 @@
#{i + 1}  , {formatDate(version.created_at, true)} - {#if !version.done} -
Notiz
- {/if}
{#if version.text.length > 0}
diff --git a/src/routes/(app)/visit/+page.ts b/src/routes/(app)/visit/+page.ts index b3c727a..c6b99cc 100644 --- a/src/routes/(app)/visit/+page.ts +++ b/src/routes/(app)/visit/+page.ts @@ -22,7 +22,7 @@ export const load: PageLoad = async (event) => { // Sort entries by date if (!query.sort) { - query.sort = ["priority:dsc", "date"]; + query.sort = { field: "date" }; } const entries = await trpc(event).entry.list.query(query); diff --git a/tests/integration/query/entry.ts b/tests/integration/query/entry.ts index 78c87d4..226075d 100644 --- a/tests/integration/query/entry.ts +++ b/tests/integration/query/entry.ts @@ -57,8 +57,8 @@ async function insertTestEntries() { }); // Execute entries - await newEntryExecution(1, eId2, { text: "Some execution txt", done: true }); - await newEntryExecution(2, eId3, { text: "More execution txt", done: true }); + await newEntryExecution(1, eId2, { text: "Some execution txt" }); + await newEntryExecution(2, eId3, { text: "More execution txt" }); return { eId1, eId2, eId3 }; } @@ -166,7 +166,7 @@ test("create entry execution", async () => { }); const text = "Blutabnahme erledigt."; - const xId = await newEntryExecution(1, eId, { text, done: true }, null); + const xId = await newEntryExecution(1, eId, { text }, null); const entry = await getEntry(eId); expect(entry.execution?.id).toBe(xId); @@ -183,8 +183,8 @@ test("create entry execution (update)", async () => { version: TEST_VERSION, }); - const x1 = await newEntryExecution(1, eId, { text: "x1", done: true }, null); - const x2 = await newEntryExecution(2, eId, { text: "x2", done: true }, x1); + const x1 = await newEntryExecution(1, eId, { text: "x1" }, null); + const x2 = await newEntryExecution(2, eId, { text: "x2" }, x1); const entry = await getEntry(eId); expect(entry.execution?.id).toBe(x2); @@ -200,9 +200,9 @@ test("create entry execution (wrong old xid)", async () => { patient_id: 1, version: TEST_VERSION, }); - const x1 = await newEntryExecution(1, eId, { text: "x1", done: true }, null); + const x1 = await newEntryExecution(1, eId, { text: "x1" }, null); - expect(async () => newEntryExecution(1, eId, { text: "x2", done: true }, x1 + 1)).rejects.toThrowError(new ErrorConflict("old execution id does not match")); + expect(async () => newEntryExecution(1, eId, { text: "x2" }, x1 + 1)).rejects.toThrowError(new ErrorConflict("old execution id does not match")); }); test("get entries", async () => { @@ -246,8 +246,8 @@ test("get entries", async () => { const entriesPatient = await getEntries({ patient: 1 }, {}); expect(entriesPatient.items).length(2); expect(entriesPatient.total).toBe(2); - expect(entriesPatient.items[0].id).toBe(eId1); - expect(entriesPatient.items[1].id).toBe(eId3); + expect(entriesPatient.items[0].id).toBe(eId3); + expect(entriesPatient.items[1].id).toBe(eId1); // Filter by room const entriesRoom = await getEntries({ room: 1 }, {}); @@ -257,8 +257,8 @@ test("get entries", async () => { const entriesDone = await getEntries({ done: true }, {}); expect(entriesDone.items).length(2); expect(entriesDone.total).toBe(2); - expect(entriesDone.items[0].id).toBe(eId2); - expect(entriesDone.items[1].id).toBe(eId3); + expect(entriesDone.items[0].id).toBe(eId3); + expect(entriesDone.items[1].id).toBe(eId2); // Filter not done const entriesNotDone = await getEntries({ done: false }, {}); @@ -281,8 +281,8 @@ test("get entries", async () => { const entriesDateRange = await getEntries({ date: "2024-01-05..2024-01-06" }); expect(entriesDateRange.items).length(2); expect(entriesDateRange.total).toBe(2); - expect(entriesDateRange.items[0].id).toBe(eId2); - expect(entriesDateRange.items[1].id).toBe(eId3); + expect(entriesDateRange.items[0].id).toBe(eId3); + expect(entriesDateRange.items[1].id).toBe(eId2); // Search const entriesSearch = await getEntries({ search: "Blu" }, {}); @@ -293,30 +293,6 @@ test("get entries", async () => { // NTodo const n = await getNTodo(new Date("2024-01-05")); expect(n).toBe(1); - - // Sort by ID - const entriesSortedId = await getEntries({}, {}, ["id"]); - const entriesSortedIdDsc = await getEntries({}, {}, ["id:dsc"]); - expect(entriesSortedId.total).toBe(3); - expect(entriesSortedIdDsc.total).toBe(3); - for (let i = 0; i < 3; i++) { - expect(entriesSortedId.items[i]).toStrictEqual( - entriesSortedIdDsc.items[entriesSortedIdDsc.items.length - i - 1], - ); - } - - // Sort by patient and ID - const entriesSortedPatientId = await getEntries({}, {}, ["patient", "id"]); - expect(entriesSortedPatientId.items.length).toBe(3); - expect(entriesSortedPatientId.items[0].id).toBe(eId1); - expect(entriesSortedPatientId.items[1].id).toBe(eId3); - expect(entriesSortedPatientId.items[2].id).toBe(eId2); - - const entriesSortedPatientIdDsc = await getEntries({}, {}, ["patient:dsc", "id"]); - expect(entriesSortedPatientIdDsc.items.length).toBe(3); - expect(entriesSortedPatientIdDsc.items[0].id).toBe(eId2); - expect(entriesSortedPatientIdDsc.items[1].id).toBe(eId1); - expect(entriesSortedPatientIdDsc.items[2].id).toBe(eId3); }); test("get patient n entries", async () => { @@ -328,18 +304,3 @@ test("get category n entries", async () => { await insertTestEntries(); expect(await getCategoryNEntries(3)).toBe(1); }); - -test("todo execution", async () => { - const eId = await newEntry(1, { - patient_id: 1, - version: TEST_VERSION, - }); - - const n1 = await newEntryExecution(1, eId, { text: "note1", done: false }, null); - - const entry = await getEntry(eId); - expect(entry.execution?.id).toBe(n1); - expect(entry.execution?.text).toBe("note1"); - expect(entry.execution?.author.id).toBe(1); - expect(entry.execution?.done).toBe(false); -}); diff --git a/tests/integration/query/patient.ts b/tests/integration/query/patient.ts index f039870..e2633de 100644 --- a/tests/integration/query/patient.ts +++ b/tests/integration/query/patient.ts @@ -11,7 +11,7 @@ import { } from "$lib/server/query"; import { S1, S2 } from "$tests/helpers/testdata"; -const SORT_ID = ["id"]; +const SORT_ID = { field: "id" }; test("create patient", async () => { const pId = await newPatient({