Compare commits
2 commits
9e7aa15ced
...
16cd49456c
Author | SHA1 | Date | |
---|---|---|---|
16cd49456c | |||
80c8371253 |
19 changed files with 348 additions and 72 deletions
20
src/lib/components/entry/PatientCard.svelte
Normal file
20
src/lib/components/entry/PatientCard.svelte
Normal file
|
@ -0,0 +1,20 @@
|
|||
<script lang="ts">
|
||||
import type { RouterOutput } from "$lib/shared/trpc";
|
||||
import RoomField from "$lib/components/table/RoomField.svelte";
|
||||
|
||||
export let patient: RouterOutput["patient"]["list"]["items"][0];
|
||||
</script>
|
||||
|
||||
<div class="card2">
|
||||
<div class="row c-light text-sm">Patient</div>
|
||||
<div class="row items-center gap-2">
|
||||
{#if patient.room}
|
||||
<RoomField room={patient.room} />
|
||||
{/if}
|
||||
<a href="/patient/{patient.id}">
|
||||
{patient.first_name}
|
||||
{patient.last_name}
|
||||
({patient.age})
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
|
@ -92,10 +92,10 @@
|
|||
if (i !== -1) {
|
||||
highlightIndex = i;
|
||||
}
|
||||
if (asTextInput) setInputValue(selection.name || "");
|
||||
if (asTextInput) setInputValue(selection.name ?? "");
|
||||
} else {
|
||||
highlightIndex = 0;
|
||||
setInputValue(selection.name || "");
|
||||
setInputValue(selection.name ?? "");
|
||||
}
|
||||
} else {
|
||||
highlightIndex = 0;
|
||||
|
|
|
@ -72,7 +72,7 @@ gap-1 pl-1"
|
|||
{@const hids = hiddenIds()}
|
||||
<Autocomplete
|
||||
bind:this={autocomplete}
|
||||
items={filter.options || []}
|
||||
items={filter.options ?? []}
|
||||
hiddenIds={hids}
|
||||
{cache}
|
||||
cacheKey={filter.id}
|
||||
|
@ -84,7 +84,7 @@ gap-1 pl-1"
|
|||
fdata.selection = item;
|
||||
return { close: true, newValue: "" };
|
||||
} else {
|
||||
return { close: false, newValue: item.name || "" };
|
||||
return { close: false, newValue: item.name ?? "" };
|
||||
}
|
||||
}}
|
||||
{onClose}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
{/if}
|
||||
|
||||
<h1 class="heading">{title}</h1>
|
||||
|
||||
<slot />
|
||||
</div>
|
||||
<!-- Button on the right side (apply ml-auto) -->
|
||||
<slot name="rightBtn" />
|
||||
</div>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
export let errors: string[] | undefined = undefined;
|
||||
export let ariaInvalid: boolean | undefined = undefined;
|
||||
export let constraints: InputConstraint | undefined = undefined;
|
||||
export let marginTop = false;
|
||||
|
||||
let editMode = true;
|
||||
|
||||
|
@ -17,20 +18,17 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<FormField {label} {errors} fullWidth>
|
||||
<button
|
||||
type="button"
|
||||
slot="topLabel"
|
||||
class="label-text"
|
||||
on:click={toggle}
|
||||
tabindex="-1"
|
||||
>
|
||||
<div class="card2" class:mt-4={marginTop}>
|
||||
<div class="row c-light text-sm items-center justify-between">
|
||||
<span>{label}</span>
|
||||
<button type="button" class="label-text" on:click={toggle} tabindex="-1">
|
||||
{editMode ? "Vorschau" : "Bearbeiten"}
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div class="p-2">
|
||||
{#if editMode}
|
||||
<textarea
|
||||
class="textarea textarea-bordered w-full"
|
||||
class="textarea w-full h-48"
|
||||
{name}
|
||||
aria-invalid={ariaInvalid}
|
||||
bind:value
|
||||
|
@ -39,4 +37,14 @@
|
|||
{:else}
|
||||
<Markdown src={value} />
|
||||
{/if}
|
||||
</FormField>
|
||||
|
||||
{#if errors}
|
||||
<div class="label flex-col items-start">
|
||||
{#each errors as error}
|
||||
<span class="label-text-alt text-error">{error}</span>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
export let data: Pagination<unknown>;
|
||||
export let onUpdate: (pagination: PaginationRequest) => void = () => {};
|
||||
|
||||
$: limit = paginationData?.limit || PAGINATION_LIMIT;
|
||||
$: limit = paginationData?.limit ?? PAGINATION_LIMIT;
|
||||
$: thisPage = Math.floor(data.offset / limit) + 1; // current page number (starting from 1)
|
||||
$: nPages = Math.ceil(data.total / limit);
|
||||
let windowBottom: number;
|
||||
|
|
|
@ -105,16 +105,28 @@ export async function newEntryVersion(
|
|||
throw new ErrorConflict("old version id does not match");
|
||||
}
|
||||
|
||||
const created = await tx.entryVersion.create({
|
||||
data: {
|
||||
const updatedVersion = {
|
||||
// Old version
|
||||
entry_id,
|
||||
author_id,
|
||||
text: version.text || cver.text,
|
||||
date: new Date(version.date || cver.date),
|
||||
category_id: version.category_id || cver.category_id,
|
||||
priority: version.priority || cver.priority,
|
||||
},
|
||||
text: version.text ?? cver.text,
|
||||
date: new Date(version.date ?? cver.date),
|
||||
category_id: version.category_id ?? cver.category_id,
|
||||
priority: version.priority ?? cver.priority,
|
||||
};
|
||||
|
||||
// Check if there are any updates
|
||||
if (
|
||||
cver.text === updatedVersion.text &&
|
||||
cver.date.getTime() === updatedVersion.date.getTime() &&
|
||||
cver.category_id === updatedVersion.category_id &&
|
||||
cver.priority === updatedVersion.priority
|
||||
) {
|
||||
return cver.id;
|
||||
}
|
||||
|
||||
const created = await tx.entryVersion.create({
|
||||
data: updatedVersion,
|
||||
select: { id: true },
|
||||
});
|
||||
return created.id;
|
||||
|
@ -147,6 +159,11 @@ export async function newEntryExecution(
|
|||
throw new ErrorConflict("old execution id does not match");
|
||||
}
|
||||
|
||||
// Check if there are any updates
|
||||
if (execution.text === cex.text) {
|
||||
return cex.id;
|
||||
}
|
||||
|
||||
const created = await prisma.entryExecution.create({
|
||||
data: {
|
||||
entry_id,
|
||||
|
|
|
@ -16,12 +16,12 @@ export async function getUser(id: number): Promise<User> {
|
|||
export async function getUsers(
|
||||
pagination: PaginationRequest
|
||||
): Promise<Pagination<User>> {
|
||||
const offset = pagination.offset || 0;
|
||||
const offset = pagination.offset ?? 0;
|
||||
const [users, total] = await Promise.all([
|
||||
prisma.user.findMany({
|
||||
orderBy: { id: "asc" },
|
||||
skip: offset,
|
||||
take: pagination.limit || PAGINATION_LIMIT,
|
||||
take: pagination.limit ?? PAGINATION_LIMIT,
|
||||
}),
|
||||
prisma.user.count(),
|
||||
]);
|
||||
|
|
|
@ -26,6 +26,16 @@ export const fields = {
|
|||
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
||||
// @ts-expect-error check date for NaN is valid
|
||||
.refine((val) => !isNaN(new Date(val))),
|
||||
DateStringFuture: () =>
|
||||
fields.DateString().refine(
|
||||
(d) => {
|
||||
const inp = new Date(d);
|
||||
const now = new Date();
|
||||
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||
return inp >= today;
|
||||
},
|
||||
{ message: "Datum muss in der Zukunft liegen" }
|
||||
),
|
||||
};
|
||||
|
||||
export const ZUrlEntityId = z.coerce.number().int().nonnegative();
|
||||
|
|
|
@ -30,18 +30,23 @@ function newOrUndef<T>(o: T, n: T): T | undefined {
|
|||
return o === n ? undefined : n;
|
||||
}
|
||||
|
||||
function doDiffWords(s1: string, s2: string): Diff.Change[] {
|
||||
if (s1 === s2) return [];
|
||||
return diffWords(s1, s2);
|
||||
}
|
||||
|
||||
export function versionsDiff(versions: EntryVersion[]): EntryVersionChange[] {
|
||||
let prev = versions[versions.length - 1];
|
||||
const changes: EntryVersionChange[] = [
|
||||
{
|
||||
...prev,
|
||||
text: diffWords("", prev.text),
|
||||
text: [{ value: prev.text }],
|
||||
},
|
||||
];
|
||||
|
||||
for (let i = versions.length - 2; i >= 0; i--) {
|
||||
const v = versions[i];
|
||||
const text = diffWords(prev.text, v.text);
|
||||
const text = doDiffWords(prev.text, v.text);
|
||||
|
||||
changes.push({
|
||||
id: v.id,
|
||||
|
@ -64,13 +69,13 @@ export function executionsDiff(executions: EntryExecution[]): EntryExecutionChan
|
|||
const changes: EntryExecutionChange[] = [
|
||||
{
|
||||
...prev,
|
||||
text: diffWords("", prev.text),
|
||||
text: [{ value: prev.text }],
|
||||
},
|
||||
];
|
||||
|
||||
for (let i = executions.length - 2; i >= 0; i--) {
|
||||
const v = executions[i];
|
||||
const text = diffWords(prev.text, v.text);
|
||||
const text = doDiffWords(prev.text, v.text);
|
||||
|
||||
changes.push({
|
||||
id: v.id,
|
||||
|
|
25
src/routes/(app)/entry/[id]/+page.server.ts
Normal file
25
src/routes/(app)/entry/[id]/+page.server.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { superValidate } from "sveltekit-superforms";
|
||||
import type { Actions } from "./$types";
|
||||
import { SchemaEntryExecution } from "./schema";
|
||||
import { fail } from "@sveltejs/kit";
|
||||
import { loadWrap } from "$lib/shared/util";
|
||||
import { trpc } from "$lib/shared/trpc";
|
||||
import { ZUrlEntityId } from "$lib/shared/model/validation";
|
||||
|
||||
export const actions = {
|
||||
default: async (event) => {
|
||||
const form = await superValidate(event.request, SchemaEntryExecution);
|
||||
if (!form.valid) {
|
||||
return fail(400, { form });
|
||||
}
|
||||
|
||||
await loadWrap(async () => {
|
||||
const id = ZUrlEntityId.parse(event.params.id);
|
||||
await trpc(event).entry.newExecution.mutate({
|
||||
id,
|
||||
old_execution_id: null,
|
||||
execution: { text: form.data.text },
|
||||
});
|
||||
});
|
||||
},
|
||||
} satisfies Actions;
|
|
@ -2,17 +2,25 @@
|
|||
import type { PageData } from "./$types";
|
||||
import { formatDate, humanDate } from "$lib/shared/util";
|
||||
import UserField from "$lib/components/table/UserField.svelte";
|
||||
import RoomField from "$lib/components/table/RoomField.svelte";
|
||||
import CategoryField from "$lib/components/table/CategoryField.svelte";
|
||||
import Markdown from "$lib/components/ui/Markdown.svelte";
|
||||
import Header from "$lib/components/ui/Header.svelte";
|
||||
import Icon from "$lib/components/ui/Icon.svelte";
|
||||
import { mdiPencil } from "@mdi/js";
|
||||
import VersionsButton from "$lib/components/ui/VersionsButton.svelte";
|
||||
import MarkdownInput from "$lib/components/ui/MarkdownInput.svelte";
|
||||
import { SchemaEntryExecution } from "./schema";
|
||||
import { defaults, superForm } from "sveltekit-superforms";
|
||||
import PatientCard from "$lib/components/entry/PatientCard.svelte";
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
$: basePath = `/entry/${data.entry.id}`;
|
||||
|
||||
let formData = defaults(SchemaEntryExecution);
|
||||
const { form, errors, enhance } = superForm(formData, {
|
||||
validators: SchemaEntryExecution,
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
@ -26,6 +34,9 @@
|
|||
{#if data.entry.current_version.priority}
|
||||
<div class="badge ellipsis badge-warning">Priorität</div>
|
||||
{/if}
|
||||
<a slot="rightBtn" href="{basePath}/edit" class="btn btn-sm btn-primary ml-auto">
|
||||
Bearbeiten
|
||||
</a>
|
||||
</Header>
|
||||
|
||||
<p class="text-sm flex flex-row gap-2">
|
||||
|
@ -34,28 +45,16 @@
|
|||
<span>Zu erledigen {humanDate(data.entry.current_version.date)}</span>
|
||||
</p>
|
||||
|
||||
<div class="card2">
|
||||
<div class="row c-light text-sm">Patient</div>
|
||||
<div class="row items-center gap-2">
|
||||
{#if data.entry.patient.room}
|
||||
<RoomField room={data.entry.patient.room} />
|
||||
{/if}
|
||||
<a href="/patient/{data.entry.patient.id}">
|
||||
{data.entry.patient.first_name}
|
||||
{data.entry.patient.last_name}
|
||||
({data.entry.patient.age})
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<PatientCard patient={data.entry.patient} />
|
||||
|
||||
<div class="card2">
|
||||
<div class="row c-light text-sm items-center justify-between">
|
||||
Beschreibung
|
||||
<div>
|
||||
<VersionsButton href="{basePath}/versions" n={data.entry.n_versions} />
|
||||
<button class="btn btn-circle btn-sm btn-ghost">
|
||||
<a href="{basePath}/edit" class="btn btn-circle btn-sm btn-ghost">
|
||||
<Icon path={mdiPencil} size={1.2} />
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -64,8 +63,10 @@
|
|||
</p>
|
||||
</div>
|
||||
<div class="row c-vlight text-sm">
|
||||
Zuletzt bearbeitet am {formatDate(data.entry.current_version.created_at, true)} von
|
||||
<p>
|
||||
Zuletzt bearbeitet am {formatDate(data.entry.current_version.created_at, true)} von
|
||||
<UserField user={data.entry.current_version.author} filterName="author" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -74,19 +75,35 @@
|
|||
<div class="row c-light text-sm items-center justify-between">
|
||||
<p>
|
||||
Erledigt am {formatDate(data.entry.execution.created_at, true)} von
|
||||
<UserField user={data.entry.execution.author} filterName="executor" />:
|
||||
<UserField user={data.entry.execution.author} filterName="executor" />
|
||||
</p>
|
||||
<div>
|
||||
<VersionsButton href="{basePath}/executions" n={data.entry.n_executions} />
|
||||
<button class="btn btn-circle btn-xs btn-ghost">
|
||||
<a href="{basePath}/editExecution" class="btn btn-circle btn-xs btn-ghost">
|
||||
<Icon path={mdiPencil} size={1.2} />
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{#if data.entry.execution?.text}
|
||||
<div class="row">
|
||||
<p class="prose">
|
||||
<Markdown src={data.entry.execution?.text} />
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<form method="POST" use:enhance>
|
||||
<MarkdownInput
|
||||
label="Eintrag erledigen"
|
||||
name="text"
|
||||
ariaInvalid={Boolean($errors.text)}
|
||||
bind:value={$form.text}
|
||||
errors={$errors.text}
|
||||
>
|
||||
<div class="row c-vlight">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Erledigt</button>
|
||||
</div>
|
||||
</MarkdownInput>
|
||||
</form>
|
||||
{/if}
|
||||
|
|
28
src/routes/(app)/entry/[id]/edit/+page.server.ts
Normal file
28
src/routes/(app)/entry/[id]/edit/+page.server.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
import { superValidate } from "sveltekit-superforms";
|
||||
import type { Actions } from "./$types";
|
||||
import { SchemaNewEntryVersion } from "./schema";
|
||||
import { fail, redirect } from "@sveltejs/kit";
|
||||
import { loadWrap } from "$lib/shared/util";
|
||||
import { trpc } from "$lib/shared/trpc";
|
||||
import { ZUrlEntityId } from "$lib/shared/model/validation";
|
||||
|
||||
export const actions = {
|
||||
default: async (event) => {
|
||||
const form = await superValidate(event.request, SchemaNewEntryVersion);
|
||||
if (!form.valid) {
|
||||
return fail(400, { form });
|
||||
}
|
||||
|
||||
const entryId = await loadWrap(async () => {
|
||||
const id = ZUrlEntityId.parse(event.params.id);
|
||||
await trpc(event).entry.newVersion.mutate({
|
||||
id,
|
||||
version: form.data,
|
||||
old_version_id: form.data.old_version_id,
|
||||
});
|
||||
return id;
|
||||
});
|
||||
|
||||
throw redirect(302, `/entry/${entryId}`);
|
||||
},
|
||||
} satisfies Actions;
|
103
src/routes/(app)/entry/[id]/edit/+page.svelte
Normal file
103
src/routes/(app)/entry/[id]/edit/+page.svelte
Normal file
|
@ -0,0 +1,103 @@
|
|||
<script lang="ts">
|
||||
import type { PageData } from "./$types";
|
||||
|
||||
import Header from "$lib/components/ui/Header.svelte";
|
||||
import PatientCard from "$lib/components/entry/PatientCard.svelte";
|
||||
import { formatDate, humanDate } from "$lib/shared/util";
|
||||
import FormField from "$lib/components/ui/FormField.svelte";
|
||||
import Autocomplete from "$lib/components/filter/Autocomplete.svelte";
|
||||
import { trpc } from "$lib/shared/trpc";
|
||||
import { superForm } from "sveltekit-superforms";
|
||||
import { SchemaNewEntryVersion } from "./schema";
|
||||
import MarkdownInput from "$lib/components/ui/MarkdownInput.svelte";
|
||||
import UserField from "$lib/components/table/UserField.svelte";
|
||||
import { browser } from "$app/environment";
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
$: basePath = `/entry/${data.entry.id}`;
|
||||
|
||||
const { form, errors, constraints, enhance, tainted } = superForm(data.form, {
|
||||
validators: SchemaNewEntryVersion,
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Eintrag #{data.entry.id}</title>
|
||||
</svelte:head>
|
||||
|
||||
<Header title="Eintrag #{data.entry.id} bearbeiten" backHref={basePath}></Header>
|
||||
|
||||
<p class="text-sm flex flex-row gap-2">
|
||||
<span>Erstellt {humanDate(data.entry.created_at, true)}</span>
|
||||
<span>·</span>
|
||||
<span>
|
||||
Zuletzt bearbeitet am {formatDate(data.entry.current_version.created_at, true)} von
|
||||
<UserField user={data.entry.current_version.author} filterName="author" />
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<PatientCard patient={data.entry.patient} />
|
||||
|
||||
<form method="POST" use:enhance>
|
||||
<input type="hidden" name="old_version_id" value={$form.old_version_id} />
|
||||
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<FormField label="Kategorie" errors={$errors.category_id}>
|
||||
<Autocomplete
|
||||
inputCls="input input-bordered w-full max-w-xs"
|
||||
items={async () => {
|
||||
return await trpc().category.list.query();
|
||||
}}
|
||||
selection={data.entry.current_version.category}
|
||||
onSelect={(item) => {
|
||||
// @ts-expect-error ids are always numeric
|
||||
$form.category_id = item.id;
|
||||
return { newValue: item.name ?? "", close: true };
|
||||
}}
|
||||
onUnselect={() => {
|
||||
$form.category_id = null;
|
||||
}}
|
||||
asTextInput
|
||||
idInputName="category_id"
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<FormField label="Zu erledigen am" errors={$errors.date}>
|
||||
<input
|
||||
type="date"
|
||||
name="date"
|
||||
aria-invalid={Boolean($errors.date)}
|
||||
bind:value={$form.date}
|
||||
{...$constraints.date}
|
||||
/>
|
||||
</FormField>
|
||||
|
||||
<div class="form-control w-full max-w-xs">
|
||||
<label class="label cursor-pointer gap-2 justify-start">
|
||||
<span class="label-text text-right">Priorität</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="priority"
|
||||
class="checkbox checkbox-warning"
|
||||
bind:checked={$form.priority}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MarkdownInput
|
||||
label="Beschreibung"
|
||||
name="text"
|
||||
marginTop
|
||||
ariaInvalid={Boolean($errors.text)}
|
||||
bind:value={$form.text}
|
||||
errors={$errors.text}
|
||||
/>
|
||||
|
||||
<button
|
||||
class="btn btn-primary max-w-32 mt-4"
|
||||
type="submit"
|
||||
disabled={browser && $tainted === undefined}>Speichern</button
|
||||
>
|
||||
</form>
|
23
src/routes/(app)/entry/[id]/edit/+page.ts
Normal file
23
src/routes/(app)/entry/[id]/edit/+page.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { ZUrlEntityId } from "$lib/shared/model/validation";
|
||||
import { trpc } from "$lib/shared/trpc";
|
||||
import { loadWrap } from "$lib/shared/util";
|
||||
import { superValidate } from "sveltekit-superforms";
|
||||
import type { PageLoad } from "./$types";
|
||||
import { SchemaNewEntryVersion } from "./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_version_id: entry.current_version.id,
|
||||
...entry.current_version,
|
||||
},
|
||||
SchemaNewEntryVersion
|
||||
);
|
||||
|
||||
return { entry, form };
|
||||
};
|
11
src/routes/(app)/entry/[id]/edit/schema.ts
Normal file
11
src/routes/(app)/entry/[id]/edit/schema.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { ZEntryVersionNew, fields } from "$lib/shared/model/validation";
|
||||
import { zod } from "sveltekit-superforms/adapters";
|
||||
import { z } from "zod";
|
||||
|
||||
export const SchemaNewEntryVersion = zod(
|
||||
ZEntryVersionNew.extend({
|
||||
old_version_id: fields.EntityId(),
|
||||
// Override priority field so checkbox value is always true/false, not optional
|
||||
priority: z.boolean(),
|
||||
})
|
||||
);
|
9
src/routes/(app)/entry/[id]/schema.ts
Normal file
9
src/routes/(app)/entry/[id]/schema.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { fields } from "$lib/shared/model/validation";
|
||||
import { zod } from "sveltekit-superforms/adapters";
|
||||
import { z } from "zod";
|
||||
|
||||
const ZEntryDone = z.object({
|
||||
text: fields.TextString(),
|
||||
});
|
||||
|
||||
export const SchemaEntryExecution = zod(ZEntryDone);
|
|
@ -7,7 +7,6 @@
|
|||
import { SchemaNewEntryWithPatient } from "./schema";
|
||||
|
||||
let formData = defaults(SchemaNewEntryWithPatient);
|
||||
|
||||
const { form, errors, constraints, enhance } = superForm(formData, {
|
||||
validators: SchemaNewEntryWithPatient,
|
||||
});
|
||||
|
@ -158,6 +157,7 @@
|
|||
<MarkdownInput
|
||||
label="Beschreibung"
|
||||
name="text"
|
||||
marginTop
|
||||
ariaInvalid={Boolean($errors.text)}
|
||||
bind:value={$form.text}
|
||||
errors={$errors.text}
|
||||
|
|
|
@ -5,7 +5,7 @@ import { dateToYMD } from "$lib/shared/util";
|
|||
|
||||
const emsg = "Erforderlich für einen neuen Patienten";
|
||||
|
||||
export const ZNewEntryWithPatient = z
|
||||
const ZNewEntryWithPatient = z
|
||||
.object({
|
||||
room_id: fields.EntityId().nullable(),
|
||||
patient_id: fields.EntityId().nullable(),
|
||||
|
@ -13,7 +13,7 @@ export const ZNewEntryWithPatient = z
|
|||
patient_last_name: fields.NameString().nullable(),
|
||||
patient_age: fields.Age().nullable(),
|
||||
category_id: fields.EntityId().nullable(),
|
||||
date: fields.DateString().default(() => dateToYMD(new Date())),
|
||||
date: fields.DateStringFuture().default(() => dateToYMD(new Date())),
|
||||
priority: z.boolean(),
|
||||
text: fields.TextString(),
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue