Merge pull request #25808 from overleaf/mj-ide-full-project-search
[web] Editor redesign: Add full project search GitOrigin-RevId: b4327c4ba0ddd7387ec8d6640e31200ca0fe4a6e
This commit is contained in:
committed by
Copybot
parent
3a96df4623
commit
48337b2e2c
@@ -1292,6 +1292,7 @@
|
||||
"project_ownership_transfer_confirmation_2": "",
|
||||
"project_renamed_or_deleted": "",
|
||||
"project_renamed_or_deleted_detail": "",
|
||||
"project_search": "",
|
||||
"project_search_file_count": "",
|
||||
"project_search_file_count_plural": "",
|
||||
"project_search_result_count": "",
|
||||
|
||||
BIN
Binary file not shown.
@@ -10,6 +10,7 @@ export default /** @type {const} */ ([
|
||||
'create_new_folder',
|
||||
'delete',
|
||||
'description',
|
||||
'error',
|
||||
'experiment',
|
||||
'forum',
|
||||
'help',
|
||||
@@ -20,10 +21,10 @@ export default /** @type {const} */ ([
|
||||
'picture_as_pdf',
|
||||
'rate_review',
|
||||
'report',
|
||||
'search',
|
||||
'settings',
|
||||
'space_dashboard',
|
||||
'table_chart',
|
||||
'upload_file',
|
||||
'web_asset',
|
||||
'error',
|
||||
])
|
||||
|
||||
@@ -6,7 +6,7 @@ type SearchEventSegmentation = {
|
||||
searchType: 'full-project'
|
||||
} & (
|
||||
| { method: 'keyboard' }
|
||||
| { method: 'button'; location: 'toolbar' | 'search-form' }
|
||||
| { method: 'button'; location: 'toolbar' | 'search-form' | 'rail' }
|
||||
))
|
||||
| ({
|
||||
searchType: 'document'
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import { ElementType } from 'react'
|
||||
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
|
||||
|
||||
const componentModule = importOverleafModules('fullProjectSearchPanel')[0] as
|
||||
| {
|
||||
import: { default: ElementType }
|
||||
path: string
|
||||
}
|
||||
| undefined
|
||||
|
||||
export const FullProjectSearchPanel = () => {
|
||||
if (!componentModule) {
|
||||
return null
|
||||
}
|
||||
const FullProjectSearch = componentModule.import.default
|
||||
return <FullProjectSearch />
|
||||
}
|
||||
|
||||
export const hasFullProjectSearch = Boolean(componentModule)
|
||||
@@ -34,6 +34,11 @@ import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
|
||||
import OLIconButton from '@/features/ui/components/ol/ol-icon-button'
|
||||
import { useChatContext } from '@/features/chat/context/chat-context'
|
||||
import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
|
||||
import {
|
||||
FullProjectSearchPanel,
|
||||
hasFullProjectSearch,
|
||||
} from './full-project-search-panel'
|
||||
import { sendSearchEvent } from '@/features/event-tracking/search-events'
|
||||
|
||||
type RailElement = {
|
||||
icon: AvailableUnfilledIcon
|
||||
@@ -106,6 +111,13 @@ export const RailLayout = () => {
|
||||
title: t('file_tree'),
|
||||
component: <FileTreeOutlinePanel />,
|
||||
},
|
||||
{
|
||||
key: 'full-project-search',
|
||||
icon: 'search',
|
||||
title: t('project_search'),
|
||||
component: <FullProjectSearchPanel />,
|
||||
hide: !hasFullProjectSearch,
|
||||
},
|
||||
{
|
||||
key: 'integrations',
|
||||
icon: 'integration_instructions',
|
||||
@@ -170,10 +182,17 @@ export const RailLayout = () => {
|
||||
// Attempting to open a non-existent tab
|
||||
return
|
||||
}
|
||||
const keyOrDefault = key ?? 'file-tree'
|
||||
const keyOrDefault = (key ?? 'file-tree') as RailTabKey
|
||||
// Change the selected tab and make sure it's open
|
||||
openTab(keyOrDefault as RailTabKey)
|
||||
openTab(keyOrDefault)
|
||||
sendEvent('rail-click', { tab: keyOrDefault })
|
||||
if (keyOrDefault === 'full-project-search') {
|
||||
sendSearchEvent('search-open', {
|
||||
searchType: 'full-project',
|
||||
method: 'button',
|
||||
location: 'rail',
|
||||
})
|
||||
}
|
||||
|
||||
if (key === 'chat') {
|
||||
markMessagesAsRead()
|
||||
|
||||
@@ -19,6 +19,7 @@ export type RailTabKey =
|
||||
| 'review-panel'
|
||||
| 'chat'
|
||||
| 'errors'
|
||||
| 'full-project-search'
|
||||
|
||||
export type RailModalKey = 'keyboard-shortcuts' | 'contact-us' | 'dictionary'
|
||||
|
||||
|
||||
+1
-4
@@ -36,7 +36,6 @@ import { getStoredSelection, setStoredSelection } from '../extensions/search'
|
||||
import { debounce } from 'lodash'
|
||||
import { EditorSelection, EditorState } from '@codemirror/state'
|
||||
import { sendSearchEvent } from '@/features/event-tracking/search-events'
|
||||
import { useIsNewEditorEnabled } from '@/features/ide-redesign/utils/new-editor-utils'
|
||||
import { FullProjectSearchButton } from './full-project-search-button'
|
||||
|
||||
const MATCH_COUNT_DEBOUNCE_WAIT = 100 // the amount of ms to wait before counting matches
|
||||
@@ -82,8 +81,6 @@ const CodeMirrorSearchForm: FC<React.PropsWithChildren> = () => {
|
||||
const inputRef = useRef<HTMLInputElement | null>(null)
|
||||
const replaceRef = useRef<HTMLInputElement | null>(null)
|
||||
|
||||
const newEditor = useIsNewEditorEnabled()
|
||||
|
||||
const handleInputRef = useCallback((node: HTMLInputElement) => {
|
||||
inputRef.current = node
|
||||
|
||||
@@ -443,7 +440,7 @@ const CodeMirrorSearchForm: FC<React.PropsWithChildren> = () => {
|
||||
</OLButton>
|
||||
</OLButtonGroup>
|
||||
|
||||
{!newEditor && <FullProjectSearchButton query={query} />}
|
||||
<FullProjectSearchButton query={query} />
|
||||
|
||||
{position !== null && (
|
||||
<div className="ol-cm-search-form-position">
|
||||
|
||||
+10
-2
@@ -12,6 +12,8 @@ import Close from '@/shared/components/close'
|
||||
import useTutorial from '@/shared/hooks/promotions/use-tutorial'
|
||||
import { useEditorContext } from '@/shared/context/editor-context'
|
||||
import getMeta from '@/utils/meta'
|
||||
import { useIsNewEditorEnabled } from '@/features/ide-redesign/utils/new-editor-utils'
|
||||
import { useRailContext } from '@/features/ide-redesign/contexts/rail-context'
|
||||
|
||||
const PROMOTION_SIGNUP_CUT_OFF_DATE = new Date('2025-04-22T00:00:00Z')
|
||||
|
||||
@@ -19,6 +21,8 @@ export const FullProjectSearchButton = ({ query }: { query: SearchQuery }) => {
|
||||
const view = useCodeMirrorViewContext()
|
||||
const { t } = useTranslation()
|
||||
const { setProjectSearchIsOpen } = useLayoutContext()
|
||||
const newEditor = useIsNewEditorEnabled()
|
||||
const { openTab } = useRailContext()
|
||||
const ref = useRef<HTMLButtonElement>(null)
|
||||
|
||||
const { inactiveTutorials } = useEditorContext()
|
||||
@@ -44,14 +48,18 @@ export const FullProjectSearchButton = ({ query }: { query: SearchQuery }) => {
|
||||
}
|
||||
|
||||
const openFullProjectSearch = useCallback(() => {
|
||||
setProjectSearchIsOpen(true)
|
||||
if (newEditor) {
|
||||
openTab('full-project-search')
|
||||
} else {
|
||||
setProjectSearchIsOpen(true)
|
||||
}
|
||||
closeSearchPanel(view)
|
||||
window.setTimeout(() => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('editor:full-project-search', { detail: query })
|
||||
)
|
||||
}, 200)
|
||||
}, [setProjectSearchIsOpen, query, view])
|
||||
}, [setProjectSearchIsOpen, query, view, newEditor, openTab])
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
sendSearchEvent('search-open', {
|
||||
|
||||
Reference in New Issue
Block a user