Skip to content

Commit a1d38b6

Browse files
committed
add 'Open note on server' menu item to NoteActions drop-down
1 parent c781eab commit a1d38b6

File tree

5 files changed

+30
-1
lines changed

5 files changed

+30
-1
lines changed

apps/client/src/components/app_context.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ export type CommandMappings = {
329329
exportAsPdf: CommandData;
330330
openNoteExternally: CommandData;
331331
openNoteCustom: CommandData;
332+
openNoteOnServer: CommandData;
332333
renderActiveNote: CommandData;
333334
unhoist: CommandData;
334335
reloadFrontendApp: CommandData;

apps/client/src/components/root_command_executor.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ export default class RootCommandExecutor extends Component {
6666
}
6767
}
6868

69+
openNoteOnServerCommand() {
70+
const noteId = appContext.tabManager.getActiveContextNoteId();
71+
if (noteId) {
72+
openService.openNoteOnServer(noteId);
73+
}
74+
}
75+
6976
enterProtectedSessionCommand() {
7077
protectedSessionService.enterProtectedSession();
7178
}

apps/client/src/services/open.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import utils from "./utils.js";
2+
import options from "./options.js";
23
import server from "./server.js";
34

45
type ExecFunction = (command: string, cb: (err: string, stdout: string, stderror: string) => void) => void;
@@ -171,6 +172,21 @@ function getHost() {
171172
return `${url.protocol}//${url.hostname}:${url.port}`;
172173
}
173174

175+
async function openNoteOnServer(noteId: string) {
176+
// Get the sync server host from options
177+
const syncServerHost = options.get("syncServerHost");
178+
179+
if (!syncServerHost) {
180+
console.error("No sync server host configured");
181+
return;
182+
}
183+
184+
const url = new URL(`#root/${noteId}`, syncServerHost).toString();
185+
186+
// Use window.open to ensure link opens in external browser in Electron
187+
window.open(url, '_blank', 'noopener,noreferrer');
188+
}
189+
174190
async function openDirectory(directory: string) {
175191
try {
176192
if (utils.isElectron()) {
@@ -198,5 +214,6 @@ export default {
198214
openAttachmentExternally,
199215
openNoteCustom,
200216
openAttachmentCustom,
217+
openNoteOnServer,
201218
openDirectory
202219
};

apps/client/src/translations/en/translation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@
682682
"open_note_externally": "Open note externally",
683683
"open_note_externally_title": "File will be open in an external application and watched for changes. You'll then be able to upload the modified version back to Trilium.",
684684
"open_note_custom": "Open note custom",
685+
"open_note_on_server": "Open note on server",
685686
"import_files": "Import files",
686687
"export_note": "Export note",
687688
"delete_note": "Delete note",

apps/client/src/widgets/ribbon/NoteActions.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ParentComponent } from "../react/react_utils";
55
import { t } from "../../services/i18n"
66
import { useContext } from "preact/hooks";
77
import { useIsNoteReadOnly } from "../react/hooks";
8+
import { useTriliumOption } from "../react/hooks";
89
import ActionButton from "../react/ActionButton"
910
import appContext, { CommandNames } from "../../components/app_context";
1011
import branches from "../../services/branches";
@@ -53,6 +54,7 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
5354
const isMac = getIsMac();
5455
const hasSource = ["text", "code", "relationMap", "mermaid", "canvas", "mindMap", "aiChat"].includes(note.type);
5556
const isSearchOrBook = ["search", "book"].includes(note.type);
57+
const [ syncServerHost ] = useTriliumOption("syncServerHost");
5658
const {isReadOnly, enableEditing} = useIsNoteReadOnly(note, noteContext);
5759

5860
return (
@@ -68,7 +70,7 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
6870
command={() => enableEditing()} />
6971
<FormDropdownDivider />
7072
</>}
71-
73+
7274
{canBeConvertedToAttachment && <ConvertToAttachment note={note} /> }
7375
{note.type === "render" && <CommandItem command="renderActiveNote" icon="bx bx-extension" text={t("note_actions.re_render_note")} />}
7476
<CommandItem command="findInText" icon="bx bx-search" disabled={!isSearchable} text={t("note_actions.search_in_note")} />
@@ -90,6 +92,7 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
9092
<CommandItem command="openNoteExternally" icon="bx bx-file-find" disabled={isSearchOrBook || !isElectron} text={t("note_actions.open_note_externally")} title={t("note_actions.open_note_externally_title")} />
9193
<CommandItem command="openNoteCustom" icon="bx bx-customize" disabled={isSearchOrBook || isMac || !isElectron} text={t("note_actions.open_note_custom")} />
9294
<CommandItem command="showNoteSource" icon="bx bx-code" disabled={!hasSource} text={t("note_actions.note_source")} />
95+
<CommandItem command="openNoteOnServer" icon="bx bx-world" disabled={!syncServerHost} text={t("note_actions.open_note_on_server")} />
9396
<FormDropdownDivider />
9497

9598
<CommandItem command="forceSaveRevision" icon="bx bx-save" disabled={isInOptionsOrHelp} text={t("note_actions.save_revision")} />

0 commit comments

Comments
 (0)