mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-09 11:17:43 +02:00
UBERF-4446: Move search from text editor (#4093)
Signed-off-by: Maxim Karmatskikh <mkarmatskih@gmail.com>
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user