mirror of
https://github.com/docmost/docmost.git
synced 2025-11-19 13:51:11 +10:00
feat: find and replace in editor (#689)
* feat: page find and replace * * Refactor search and replace directory * bugfix scroll * Fix search and replace functionality for macOS and improve UX - Fixed cmd+f shortcut to work on macOS (using 'Mod' key instead of 'Control') - Added search functionality to title editor - Fixed "Not found" message showing when search term is empty - Fixed tooltip error when clicking replace button - Changed replace button from icon to text for consistency - Reduced width of search input fields for better UI - Fixed result index after replace operation to prevent out-of-bounds error - Added missing translation strings for search and replace dialog - Updated tooltip to show platform-specific shortcuts (⌘F on Mac, Ctrl-F on others) * Hide replace functionality for users with view-only permissions - Added editable prop to SearchAndReplaceDialog component - Pass editable state from PageEditor to SearchAndReplaceDialog - Conditionally render replace button based on edit permissions - Hide replace input section for view-only users - Disable Alt+R shortcut when user lacks edit permissions * Fix search dialog not closing properly when navigating away - Clear all state (search text, replace text) when closing dialog - Reset replace button visibility state on close - Clear editor search term to remove highlights - Ensure dialog closes properly when route changes * fix: preserve text marks (comments, etc.) when replacing text in search and replace - Collect all marks that span the text being replaced using nodesBetween - Apply collected marks to the replacement text to maintain formatting - Fixes issue where comment marks were being removed during text replacement * ignore type error --------- Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
This commit is contained in:
@ -9,6 +9,7 @@ import {
|
||||
IconList,
|
||||
IconMessage,
|
||||
IconPrinter,
|
||||
IconSearch,
|
||||
IconTrash,
|
||||
IconWifiOff,
|
||||
} from "@tabler/icons-react";
|
||||
@ -16,7 +17,12 @@ import React from "react";
|
||||
import useToggleAside from "@/hooks/use-toggle-aside.tsx";
|
||||
import { useAtom } from "jotai";
|
||||
import { historyAtoms } from "@/features/page-history/atoms/history-atoms.ts";
|
||||
import { useClipboard, useDisclosure } from "@mantine/hooks";
|
||||
import {
|
||||
getHotkeyHandler,
|
||||
useClipboard,
|
||||
useDisclosure,
|
||||
useHotkeys,
|
||||
} from "@mantine/hooks";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { usePageQuery } from "@/features/page/queries/page-query.ts";
|
||||
import { buildPageUrl } from "@/features/page/page.utils.ts";
|
||||
@ -32,6 +38,7 @@ import {
|
||||
pageEditorAtom,
|
||||
yjsConnectionStatusAtom,
|
||||
} from "@/features/editor/atoms/editor-atoms.ts";
|
||||
import { searchAndReplaceStateAtom } from "@/features/editor/components/search-and-replace/atoms/search-and-replace-state-atom.ts";
|
||||
import { formattedDate, timeAgo } from "@/lib/time.ts";
|
||||
import { PageStateSegmentedControl } from "@/features/user/components/page-state-pref.tsx";
|
||||
import MovePageModal from "@/features/page/components/move-page-modal.tsx";
|
||||
@ -46,6 +53,26 @@ export default function PageHeaderMenu({ readOnly }: PageHeaderMenuProps) {
|
||||
const toggleAside = useToggleAside();
|
||||
const [yjsConnectionStatus] = useAtom(yjsConnectionStatusAtom);
|
||||
|
||||
useHotkeys(
|
||||
[
|
||||
[
|
||||
"mod+F",
|
||||
() => {
|
||||
const event = new CustomEvent("openFindDialogFromEditor", {});
|
||||
document.dispatchEvent(event);
|
||||
},
|
||||
],
|
||||
[
|
||||
"Escape",
|
||||
() => {
|
||||
const event = new CustomEvent("closeFindDialogFromEditor", {});
|
||||
document.dispatchEvent(event);
|
||||
},
|
||||
],
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{yjsConnectionStatus === "disconnected" && (
|
||||
|
||||
Reference in New Issue
Block a user