mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-25 19:58:30 +03:00
UBERF-5018: search improvements/Indexing fix (#4403)
Signed-off-by: Vyacheslav Tumanov <me@slavatumanov.me>
This commit is contained in:
parent
27c428602a
commit
28dca6632c
@ -55,7 +55,9 @@ export function createModel (builder: Builder): void {
|
||||
}
|
||||
]
|
||||
},
|
||||
getSearchTitle: serverContact.function.ContactNameProvider
|
||||
getSearchTitle: {
|
||||
name: serverContact.function.ContactNameProvider
|
||||
}
|
||||
})
|
||||
|
||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||
|
@ -45,8 +45,8 @@ export class TObjectDDParticipant extends TClass implements ObjectDDParticipant
|
||||
@Mixin(serverCore.mixin.SearchPresenter, core.class.Class)
|
||||
export class TSearchPresenter extends TClass implements SearchPresenter {
|
||||
searchConfig!: ClassSearchConfig
|
||||
getSearchShortTitle!: Resource<SearchPresenterFunc>
|
||||
getSearchTitle!: Resource<SearchPresenterFunc>
|
||||
getSearchShortTitle!: SearchPresenterFunc
|
||||
getSearchTitle!: SearchPresenterFunc
|
||||
}
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
|
@ -65,10 +65,13 @@ export function createModel (builder: Builder): void {
|
||||
props: ['number']
|
||||
},
|
||||
title: {
|
||||
props: [{ _class: ['attachedTo', '_class'] }, { name: ['attachedTo', 'name'] }]
|
||||
tmpl: '{name} - {vacName}',
|
||||
props: [{ _class: ['attachedTo', '_class'] }, { name: ['attachedTo', 'name'] }, { vacName: ['space', 'name'] }]
|
||||
}
|
||||
},
|
||||
getSearchTitle: serverContact.function.ContactNameProvider
|
||||
getSearchTitle: {
|
||||
name: serverContact.function.ContactNameProvider
|
||||
}
|
||||
})
|
||||
|
||||
builder.mixin(
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import type { Plugin, Resource } from '@hcengineering/platform'
|
||||
import { plugin } from '@hcengineering/platform'
|
||||
import type { TriggerFunc, SearchPresenterFunc } from '@hcengineering/server-core'
|
||||
import type { TriggerFunc, SearchPresenterProvider } from '@hcengineering/server-core'
|
||||
import { Presenter } from '@hcengineering/server-notification'
|
||||
|
||||
/**
|
||||
@ -38,6 +38,6 @@ export default plugin(serverContactId, {
|
||||
OrganizationHTMLPresenter: '' as Resource<Presenter>,
|
||||
OrganizationTextPresenter: '' as Resource<Presenter>,
|
||||
|
||||
ContactNameProvider: '' as Resource<SearchPresenterFunc>
|
||||
ContactNameProvider: '' as Resource<SearchPresenterProvider>
|
||||
}
|
||||
})
|
||||
|
@ -178,12 +178,12 @@ export class FullTextPushStage implements FullTextPipelineStage {
|
||||
}
|
||||
}
|
||||
}
|
||||
const parentDoc: DocIndexState | undefined = undefined
|
||||
let parentDoc: DocIndexState | undefined
|
||||
if (doc.attachedToClass != null && doc.attachedTo != null) {
|
||||
const propagate: Ref<Class<Doc>>[] = collectPropagate(pipeline, doc.attachedToClass)
|
||||
if (propagate.some((it) => pipeline.hierarchy.isDerived(doc.objectClass, it))) {
|
||||
// We need to include all parent content into this one.
|
||||
const [parentDoc] = await metrics.with(
|
||||
;[parentDoc] = await metrics.with(
|
||||
'find-parent',
|
||||
{},
|
||||
async (ctx) =>
|
||||
|
@ -107,4 +107,4 @@ export const fieldStateId = 'fld-v11'
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const fullTextPushStageId = 'fts-v9'
|
||||
export const fullTextPushStageId = 'fts-v9bc'
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Class, Doc, DocIndexState, docKey, Hierarchy, Ref, RefTo, SearchResultDoc } from '@hcengineering/core'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
import { getResource, Resource } from '@hcengineering/platform'
|
||||
|
||||
import plugin from './plugin'
|
||||
import { ClassSearchConfigProps, IndexedDoc, SearchPresenter, SearchScoring } from './types'
|
||||
import { ClassSearchConfigProps, IndexedDoc, SearchPresenter, SearchPresenterFunc, SearchScoring } from './types'
|
||||
|
||||
interface IndexedReader {
|
||||
get: (attribute: string) => any
|
||||
@ -39,7 +39,14 @@ function createIndexedReader (
|
||||
}
|
||||
}
|
||||
|
||||
function readAndMapProps (reader: IndexedReader, props: ClassSearchConfigProps[]): Record<string, any> {
|
||||
async function readAndMapProps (
|
||||
reader: IndexedReader,
|
||||
props: ClassSearchConfigProps[],
|
||||
searchProvider?: {
|
||||
hierarchy: Hierarchy
|
||||
providers: SearchPresenterFunc
|
||||
}
|
||||
): Promise<Record<string, any>> {
|
||||
const res: Record<string, any> = {}
|
||||
for (const prop of props) {
|
||||
if (typeof prop === 'string') {
|
||||
@ -48,7 +55,18 @@ function readAndMapProps (reader: IndexedReader, props: ClassSearchConfigProps[]
|
||||
for (const [propName, rest] of Object.entries(prop)) {
|
||||
if (rest.length > 1) {
|
||||
const val = reader.getDoc(rest[0])?.get(rest[1])
|
||||
res[propName] = Array.isArray(val) ? val[0] : val
|
||||
const v = Array.isArray(val) ? val[0] : val
|
||||
if (searchProvider !== undefined) {
|
||||
const func =
|
||||
searchProvider.providers !== undefined && Object.keys(searchProvider.providers).includes(propName)
|
||||
? ((await getResource(searchProvider.providers[propName])) as any)
|
||||
: undefined
|
||||
if (func !== undefined) {
|
||||
res[propName] = func(searchProvider.hierarchy, { _class: res?._class, [propName]: v })
|
||||
continue
|
||||
}
|
||||
}
|
||||
res[propName] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,16 +134,16 @@ export async function updateDocWithPresenter (
|
||||
let value
|
||||
if (prop.config.tmpl !== undefined) {
|
||||
const tmpl = prop.config.tmpl
|
||||
const renderProps = readAndMapProps(reader, prop.config.props)
|
||||
const renderProps = await readAndMapProps(reader, prop.config.props, { hierarchy, providers: prop.provider })
|
||||
value = fillTemplate(tmpl, renderProps)
|
||||
} else if (typeof prop.config === 'string') {
|
||||
value = reader.get(prop.config)
|
||||
} else if (prop.provider !== undefined) {
|
||||
const func = (await getResource(prop.provider)) as any
|
||||
const renderProps = readAndMapProps(reader, prop.config.props)
|
||||
const func = await getResource(Object.values(prop.provider)[0] as Resource<any>)
|
||||
const renderProps = await readAndMapProps(reader, prop.config.props)
|
||||
value = func(hierarchy, { _class: elasticDoc._class, ...renderProps })
|
||||
} else if (prop.name === 'searchIcon') {
|
||||
value = readAndMapProps(reader, prop.config.props)
|
||||
value = await readAndMapProps(reader, prop.config.props)
|
||||
}
|
||||
elasticDoc[prop.name] = value
|
||||
}
|
||||
|
@ -349,7 +349,11 @@ export type SearchProps = Record<string, string>
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type SearchPresenterFunc = (hierarchy: Hierarchy, props: SearchProps) => string
|
||||
export type SearchPresenterProvider = (hierarchy: Hierarchy, props: SearchProps) => string
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type SearchPresenterFunc = Record<string, Resource<SearchPresenterProvider>>
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -386,6 +390,6 @@ export interface ClassSearchConfig {
|
||||
*/
|
||||
export interface SearchPresenter extends Class<Doc> {
|
||||
searchConfig: ClassSearchConfig
|
||||
getSearchShortTitle?: Resource<SearchPresenterFunc>
|
||||
getSearchTitle?: Resource<SearchPresenterFunc>
|
||||
getSearchShortTitle?: SearchPresenterFunc
|
||||
getSearchTitle?: SearchPresenterFunc
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user