diff --git a/ka-note/client/src/lib/components/JournalView.svelte b/ka-note/client/src/lib/components/JournalView.svelte
index ffe59b2..7f856dd 100644
--- a/ka-note/client/src/lib/components/JournalView.svelte
+++ b/ka-note/client/src/lib/components/JournalView.svelte
@@ -8,6 +8,7 @@
import RenderedMarkdown from './RenderedMarkdown.svelte';
import DateNavigator from './DateNavigator.svelte';
import ConfirmDialog from './ConfirmDialog.svelte';
+ import WiedervorlageSection from './WiedervorlageSection.svelte';
interface Props {
contextId: string;
@@ -22,6 +23,7 @@
let entryEditor: MarkdownEditor;
let selectedDate = $state(today());
let selectedLinkedContextId = $state('');
+ let wiedervorlageChecked = $state(false);
// All meeting contexts for the link dropdown
const meetingContexts = liveQuery(() =>
@@ -70,13 +72,14 @@
} else {
const text = body ? `${title}\n${body}` : title;
await getOrCreateJournalTopic();
- await createHistoryEntry(JOURNAL_TOPIC_ID, selectedDate, text);
+ await createHistoryEntry(JOURNAL_TOPIC_ID, selectedDate, text, null, wiedervorlageChecked);
}
entryTitle = '';
entryText = '';
entryEditor?.clear();
selectedLinkedContextId = '';
+ wiedervorlageChecked = false;
}
function handleTitleKeypress(e: KeyboardEvent) {
@@ -192,14 +195,24 @@
minHeight="60px"
onchange={(md) => entryText = md}
/>
-
+
{selectedDate}
diff --git a/ka-note/client/src/lib/components/WiedervorlageCard.svelte b/ka-note/client/src/lib/components/WiedervorlageCard.svelte
new file mode 100644
index 0000000..c2122db
--- /dev/null
+++ b/ka-note/client/src/lib/components/WiedervorlageCard.svelte
@@ -0,0 +1,110 @@
+
+
+
+
+ ⏰ Wiedervorlage {entry.wiedervorlageDate}
+
+
+
{title}
+ {#if body}
+
{body}
+ {/if}
+
+
+ {#if showVerschieben}
+
+
+
+
+
+ {:else if showConvert}
+
+
+
+
+
+ {:else}
+
+
+
+
+
+ {/if}
+
diff --git a/ka-note/client/src/lib/components/WiedervorlageSection.svelte b/ka-note/client/src/lib/components/WiedervorlageSection.svelte
new file mode 100644
index 0000000..c45a0e6
--- /dev/null
+++ b/ka-note/client/src/lib/components/WiedervorlageSection.svelte
@@ -0,0 +1,22 @@
+
+
+{#if ($pending ?? []).length > 0}
+
+
+ Wiedervorlage ({($pending ?? []).length})
+
+ {#each $pending ?? [] as entry (entry.id)}
+
+ {/each}
+
+{/if}
diff --git a/ka-note/client/src/lib/db/repositories.ts b/ka-note/client/src/lib/db/repositories.ts
index 40953ac..194dc7d 100644
--- a/ka-note/client/src/lib/db/repositories.ts
+++ b/ka-note/client/src/lib/db/repositories.ts
@@ -1,5 +1,5 @@
import { db } from './schema';
-import { newId, now } from './helpers';
+import { newId, now, today } from './helpers';
import type { AgendaContext, Topic, HistoryEntry, Rating, ContextType, TopicStatus, ProjectMeta, PersonMeta, CompanyMeta } from '@ka-note/shared';
// --- Contexts ---
@@ -203,8 +203,9 @@ export async function getAllHistoryByContext(contextId: string): Promise<(Histor
return allHistory;
}
-export async function createHistoryEntry(topicId: string, date: string, text: string, linkedContextId: string | null = null): Promise
{
+export async function createHistoryEntry(topicId: string, date: string, text: string, linkedContextId: string | null = null, wiedervorlage = false): Promise {
const existing = await getHistoryByTopic(topicId);
+ const autoWiedervorlage = date > today() || wiedervorlage;
const entry: HistoryEntry = {
id: newId(),
topicId,
@@ -213,6 +214,8 @@ export async function createHistoryEntry(topicId: string, date: string, text: st
sortOrder: existing.length,
linkedContextId,
doneAt: null,
+ wiedervorlageDate: autoWiedervorlage ? date : null,
+ wiedervorlageResolvedAt: null,
updatedAt: now(),
deletedAt: null,
version: 1
@@ -221,6 +224,30 @@ export async function createHistoryEntry(topicId: string, date: string, text: st
return entry;
}
+export async function setWiedervorlage(id: string, date: string): Promise {
+ const entry = await db.historyEntries.get(id);
+ if (entry) {
+ await db.historyEntries.update(id, { wiedervorlageDate: date, wiedervorlageResolvedAt: null, updatedAt: now(), version: entry.version + 1 });
+ }
+}
+
+export async function resolveWiedervorlage(id: string): Promise {
+ const entry = await db.historyEntries.get(id);
+ if (entry) {
+ await db.historyEntries.update(id, { wiedervorlageResolvedAt: now(), updatedAt: now(), version: entry.version + 1 });
+ }
+}
+
+export async function convertToTopic(entryId: string, contextId: string): Promise {
+ const entry = await db.historyEntries.get(entryId);
+ if (!entry) throw new Error('Entry not found');
+ const lines = entry.text.split('\n');
+ const title = lines[0].trim();
+ const topic = await createTopic(contextId, title);
+ await resolveWiedervorlage(entryId);
+ return topic;
+}
+
export async function updateHistoryEntry(id: string, text: string): Promise {
const entry = await db.historyEntries.get(id);
if (entry) {
diff --git a/ka-note/client/src/lib/db/schema.ts b/ka-note/client/src/lib/db/schema.ts
index 6299e06..b9aed6c 100644
--- a/ka-note/client/src/lib/db/schema.ts
+++ b/ka-note/client/src/lib/db/schema.ts
@@ -68,6 +68,15 @@ export class KaNoteDB extends Dexie {
if (ctx.isFavorite === undefined) ctx.isFavorite = false;
});
});
+
+ this.version(7).stores({
+ historyEntries: 'id, topicId, date, sortOrder, deletedAt, linkedContextId, doneAt, wiedervorlageDate, wiedervorlageResolvedAt'
+ }).upgrade(tx => {
+ return tx.table('historyEntries').toCollection().modify(entry => {
+ if (entry.wiedervorlageDate === undefined) entry.wiedervorlageDate = null;
+ if (entry.wiedervorlageResolvedAt === undefined) entry.wiedervorlageResolvedAt = null;
+ });
+ });
}
}
diff --git a/ka-note/client/src/lib/stores/agenda.ts b/ka-note/client/src/lib/stores/agenda.ts
index 9d40983..682af3d 100644
--- a/ka-note/client/src/lib/stores/agenda.ts
+++ b/ka-note/client/src/lib/stores/agenda.ts
@@ -118,3 +118,12 @@ export function ratingsForPerson(personName: string) {
.toArray()
);
}
+
+export function pendingWiedervorlage(date: string) {
+ return liveQuery(() =>
+ db.historyEntries
+ .where('wiedervorlageDate').belowOrEqual(date)
+ .filter(e => !e.wiedervorlageResolvedAt && !e.deletedAt)
+ .toArray()
+ );
+}
diff --git a/ka-note/server/src/lib/sync-service.ts b/ka-note/server/src/lib/sync-service.ts
index 6b57a56..a3079d6 100644
--- a/ka-note/server/src/lib/sync-service.ts
+++ b/ka-note/server/src/lib/sync-service.ts
@@ -52,6 +52,8 @@ function mapHistoryEntry(row: typeof historyEntries.$inferSelect): HistoryEntry
sortOrder: row.sortOrder,
linkedContextId: row.linkedContextId,
doneAt: row.doneAt,
+ wiedervorlageDate: (row as any).wiedervorlageDate ?? null,
+ wiedervorlageResolvedAt: (row as any).wiedervorlageResolvedAt ?? null,
updatedAt: row.updatedAt,
deletedAt: row.deletedAt,
version: row.version,
diff --git a/ka-note/shared/src/types.ts b/ka-note/shared/src/types.ts
index f9b4131..1bae3ad 100644
--- a/ka-note/shared/src/types.ts
+++ b/ka-note/shared/src/types.ts
@@ -57,6 +57,8 @@ export interface HistoryEntry extends SyncEntity {
sortOrder: number;
linkedContextId: string | null;
doneAt: string | null;
+ wiedervorlageDate: string | null; // YYYY-MM-DD
+ wiedervorlageResolvedAt: string | null; // ISO timestamp
}
export interface Rating extends SyncEntity {