UBERF-4446: Move search from text editor (#4093)

Signed-off-by: Maxim Karmatskikh <mkarmatskih@gmail.com>
This commit is contained in:
Maksim Karmatskikh
2023-11-29 14:37:12 +07:00
committed by GitHub
parent 58a004e53f
commit cd68dd7d10
7 changed files with 51 additions and 76 deletions
+2
View File
@@ -43,6 +43,7 @@ export { default as Breadcrumbs } from './components/breadcrumbs/Breadcrumbs.sve
export { default as BreadcrumbsElement } from './components/breadcrumbs/BreadcrumbsElement.svelte'
export { default as ComponentExtensions } from './components/extensions/ComponentExtensions.svelte'
export { default as DocCreateExtComponent } from './components/extensions/DocCreateExtComponent.svelte'
export { default as SearchResult } from './components/SearchResult.svelte'
export { default } from './plugin'
export * from './types'
export * from './utils'
@@ -53,3 +54,4 @@ export * from './context'
export * from './pipeline'
export * from './components/extensions/manager'
export * from './rules'
export * from './search'
@@ -14,12 +14,11 @@
//
import type { Class, Ref, Doc, SearchResultDoc, TxOperations } from '@hcengineering/core'
import { type ObjectSearchCategory } from '@hcengineering/presentation'
import { type ObjectSearchCategory } from './types'
import plugin from './plugin'
import { getClient } from './utils'
/**
* @public
*/
export interface SearchSection {
interface SearchSection {
category: ObjectSearchCategory
items: SearchResultDoc[]
}
@@ -33,7 +32,7 @@ export interface SearchItem {
category: ObjectSearchCategory
}
export function findCategoryByClass (
function findCategoryByClass (
categories: ObjectSearchCategory[],
_class: Ref<Class<Doc>>
): ObjectSearchCategory | undefined {
@@ -45,7 +44,7 @@ export function findCategoryByClass (
return undefined
}
export function packSearchResultsForListView (sections: SearchSection[]): SearchItem[] {
function packSearchResultsForListView (sections: SearchSection[]): SearchItem[] {
let results: SearchItem[] = []
for (const section of sections) {
const category = section.category
@@ -62,7 +61,7 @@ export function packSearchResultsForListView (sections: SearchSection[]): Search
return results
}
export async function doFulltextSearch (
async function doFulltextSearch (
client: TxOperations,
classes: Array<Ref<Class<Doc>>>,
query: string,
@@ -98,3 +97,27 @@ export async function doFulltextSearch (
return sections
}
const categoriesByContext = new Map<string, ObjectSearchCategory[]>()
export async function searchFor (context: 'mention' | 'spotlight', query: string): Promise<SearchItem[]> {
const client = getClient()
let categories
if (categoriesByContext.get(context) === undefined) {
categories = await client.findAll(plugin.class.ObjectSearchCategory, { context })
categoriesByContext.set(context, categories)
}
if (categories === undefined) {
return []
}
const classesToSearch: Array<Ref<Class<Doc>>> = []
for (const cat of categories) {
if (cat.classToSearch !== undefined) {
classesToSearch.push(cat.classToSearch)
}
}
const sections = await doFulltextSearch(client, classesToSearch, query, categories)
return packSearchResultsForListView(sections)
}
@@ -59,7 +59,7 @@
return searchPopup?.onKeyDown(ev)
}
export function done () {}
export function done (): void {}
function updateStyle (): void {
const rect = clientRect()
@@ -84,7 +84,10 @@
}
let style = 'visibility: hidden'
$: if (popup) updateStyle()
$: if (popup !== undefined && popup !== null) {
updateStyle()
}
let wPopup: number = 0
</script>
@@ -16,30 +16,12 @@
<script lang="ts">
import { Label, ListView, resizeObserver } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import presentation, { getClient, type ObjectSearchCategory } from '@hcengineering/presentation'
import { Class, Ref, Doc, SearchResultDoc } from '@hcengineering/core'
import { type SearchItem, packSearchResultsForListView, doFulltextSearch } from '../search'
import MentionResult from './MentionResult.svelte'
import presentation, { type SearchItem, SearchResult, searchFor } from '@hcengineering/presentation'
import { SearchResultDoc } from '@hcengineering/core'
export let query: string = ''
let items: SearchItem[] = []
let categories: ObjectSearchCategory[] = []
const client = getClient()
client
.findAll(presentation.class.ObjectSearchCategory, { context: 'mention' })
.then(async (results) => {
categories = results
await updateItems(query)
})
.catch((e) => {
console.error(e)
})
const dispatch = createEventDispatcher()
@@ -86,15 +68,7 @@
}
async function updateItems (query: string): Promise<void> {
const classesToSearch: Array<Ref<Class<Doc>>> = []
for (const cat of categories) {
if (cat.classToSearch !== undefined) {
classesToSearch.push(cat.classToSearch)
}
}
const sections = await doFulltextSearch(client, classesToSearch, query, categories)
items = packSearchResultsForListView(sections)
items = await searchFor('mention', query)
}
$: void updateItems(query)
</script>
@@ -128,7 +102,7 @@
dispatchItem(doc)
}}
>
<MentionResult value={doc} />
<SearchResult value={doc} />
</div>
</svelte:fragment>
</ListView>
-2
View File
@@ -32,12 +32,10 @@ export { default as TextEditor } from './components/TextEditor.svelte'
export { default as TextEditorStyleToolbar } from './components/TextEditorStyleToolbar.svelte'
export { default as AttachIcon } from './components/icons/Attach.svelte'
export { default as TableOfContents } from './components/toc/TableOfContents.svelte'
export { default as MentionResult } from './components/MentionResult.svelte'
export * from './components/node-view'
export { default } from './plugin'
export * from './types'
export * from './utils'
export * from './search'
export { FocusExtension, type FocusOptions, type FocusStorage } from './components/extension/focus'
export { HeadingsExtension, type HeadingsOptions, type HeadingsStorage } from './components/extension/headings'
@@ -13,13 +13,16 @@
// limitations under the License.
-->
<script lang="ts">
import { WithLookup, Doc, Ref, Class, SearchResultDoc } from '@hcengineering/core'
import { WithLookup, Doc, Ref, SearchResultDoc } from '@hcengineering/core'
import { getResource, translate } from '@hcengineering/platform'
import presentation, {
import {
type SearchItem,
type ObjectSearchCategory,
SearchResult,
createQuery,
getClient,
ActionContext,
ObjectSearchCategory
searchFor
} from '@hcengineering/presentation'
import ui, {
Button,
@@ -42,14 +45,6 @@
import ObjectPresenter from './ObjectPresenter.svelte'
import { createEventDispatcher, tick } from 'svelte'
import {
type SearchSection,
type SearchItem,
packSearchResultsForListView,
doFulltextSearch,
MentionResult
} from '@hcengineering/text-editor'
import ChevronDown from './icons/ChevronDown.svelte'
import ChevronUp from './icons/ChevronUp.svelte'
@@ -241,32 +236,12 @@
}
let items: SearchActionItem[] = []
let categories: ObjectSearchCategory[] = []
client
.findAll(presentation.class.ObjectSearchCategory, { context: 'spotlight' })
.then(async (results) => {
categories = results
await updateItems(search, filteredActions)
})
.catch((e) => {
console.error(e)
})
async function updateItems (query: string, filteredActions: Array<WithLookup<Action>>): Promise<void> {
const classesToSearch: Array<Ref<Class<Doc>>> = []
for (const cat of categories) {
if (cat.classToSearch !== undefined) {
classesToSearch.push(cat.classToSearch)
}
}
let sections: SearchSection[] = []
let searchItems: SearchItem[] = []
if (query !== '' && query.indexOf('/') !== 0) {
sections = await doFulltextSearch(client, classesToSearch, query, categories)
searchItems = await searchFor('spotlight', query)
}
const searchItems = packSearchResultsForListView(sections)
items = packSearchAndActions(searchItems, filteredActions)
}
@@ -393,7 +368,7 @@
{#if item.item !== undefined}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="ap-menuItem withComp actionsSearchItem">
<MentionResult value={item.item} />
<SearchResult value={item.item} />
</div>
{/if}
{#if item.action !== undefined}