diff --git a/apps/client/src/stylesheets/theme-next/dialogs.css b/apps/client/src/stylesheets/theme-next/dialogs.css index 985239d49..357a541ff 100644 --- a/apps/client/src/stylesheets/theme-next/dialogs.css +++ b/apps/client/src/stylesheets/theme-next/dialogs.css @@ -233,11 +233,11 @@ div.tn-tool-dialog { /* Item title link */ -.recent-changes-content ul li .note-title a { +.recent-changes-content ul li a { color: currentColor; } -.recent-changes-content ul li .note-title a:hover { +.recent-changes-content ul li a:hover { text-decoration: underline; } diff --git a/apps/client/src/widgets/dialogs/recent_changes.tsx b/apps/client/src/widgets/dialogs/recent_changes.tsx index ec93da186..b5ce10c0e 100644 --- a/apps/client/src/widgets/dialogs/recent_changes.tsx +++ b/apps/client/src/widgets/dialogs/recent_changes.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "preact/hooks"; -import { EventData } from "../../components/app_context"; -import { openDialog } from "../../services/dialog"; +import appContext, { EventData } from "../../components/app_context"; +import dialog, { closeActiveDialog, openDialog } from "../../services/dialog"; import { t } from "../../services/i18n"; import server from "../../services/server"; import toast from "../../services/toast"; @@ -8,11 +8,12 @@ import Button from "../react/Button"; import Modal from "../react/Modal"; import ReactBasicWidget from "../react/ReactBasicWidget"; import hoisted_note from "../../services/hoisted_note"; -import { RecentChangesRow } from "@triliumnext/commons"; +import type { RecentChangesRow } from "@triliumnext/commons"; import froca from "../../services/froca"; import { formatDateTime } from "../../utils/formatters"; import link from "../../services/link"; import RawHtml from "../react/RawHtml"; +import ws from "../../services/ws"; interface RecentChangesDialogProps { ancestorNoteId?: string; @@ -90,9 +91,9 @@ function RecentChangesTimeline({ groupedByDate }: { groupedByDate: Map {formattedTime} - { !isDeleted && notePath + { !isDeleted ? - : {change.current_title} } + : } ); })} @@ -117,7 +118,35 @@ function NoteLink({ notePath, title }: { notePath: string, title: string }) { }).then(setNoteLink); }, [notePath, title]); return ( - noteLink ? : Foo {title} + noteLink ? : {title} + ); +} + +function DeletedNoteLink({ change }: { change: RecentChangesRow }) { + return ( + <> + {change.current_title} +   + ( { + async () => { + const text = t("recent_changes.confirm_undelete"); + + if (await dialog.confirm(text)) { + await server.put(`notes/${change.noteId}/undelete`); + closeActiveDialog(); + await ws.waitForMaxKnownEntityChangeId(); + + const activeContext = appContext.tabManager.getActiveContext(); + if (activeContext) { + activeContext.setNote(change.noteId); + } + } + } + }}> + {t("recent_changes.undelete_link")}) + + ); } diff --git a/apps/server/src/routes/api/recent_changes.ts b/apps/server/src/routes/api/recent_changes.ts index 1e539710e..9dd246588 100644 --- a/apps/server/src/routes/api/recent_changes.ts +++ b/apps/server/src/routes/api/recent_changes.ts @@ -5,18 +5,7 @@ import protectedSessionService from "../../services/protected_session.js"; import noteService from "../../services/notes.js"; import becca from "../../becca/becca.js"; import type { Request } from "express"; - -interface RecentChangeRow { - noteId: string; - current_isDeleted: boolean; - current_deleteId: string; - current_title: string; - current_isProtected: boolean; - title: string; - utcDate: string; - date: string; - canBeUndeleted?: boolean; -} +import type { RecentChangeRow } from "@triliumnext/commons"; function getRecentChanges(req: Request) { const { ancestorNoteId } = req.params; diff --git a/packages/commons/src/lib/server_api.ts b/packages/commons/src/lib/server_api.ts index f4645e0c5..7f0e30d67 100644 --- a/packages/commons/src/lib/server_api.ts +++ b/packages/commons/src/lib/server_api.ts @@ -46,9 +46,16 @@ export interface RevisionPojo { contentLength?: number; } -export interface RecentChangesRow { +export interface RecentChangeRow { noteId: string; + current_isDeleted: boolean; + current_deleteId: string; + current_title: string; + current_isProtected: boolean; + title: string; + utcDate: string; date: string; + canBeUndeleted?: boolean; } export interface BulkActionAffectedNotes {