From d9316aa8da33e831a8abf2b4e0f3fea361dd3ed8 Mon Sep 17 00:00:00 2001 From: Kristina Date: Tue, 25 Mar 2025 16:51:38 +0400 Subject: [PATCH] Add search for meetings (#8341) Signed-off-by: Kristina Fefelova Signed-off-by: Andrey Sobolev Co-authored-by: Andrey Sobolev --- models/love/src/index.ts | 31 +++++++++++++++- models/love/src/plugin.ts | 5 +++ models/server-love/src/index.ts | 5 +++ plugins/love-assets/assets/icons.svg | 14 ++++++++ plugins/love-assets/lang/cs.json | 3 +- plugins/love-assets/lang/de.json | 3 +- plugins/love-assets/lang/en.json | 3 +- plugins/love-assets/lang/es.json | 3 +- plugins/love-assets/lang/fr.json | 3 +- plugins/love-assets/lang/it.json | 3 +- plugins/love-assets/lang/pt.json | 3 +- plugins/love-assets/lang/ru.json | 3 +- plugins/love-assets/lang/zh.json | 3 +- plugins/love-assets/src/index.ts | 3 +- .../components/MeetingMinutesPresenter.svelte | 2 +- .../MeetingMinutesSearchItem.svelte | 31 ++++++++++++++++ plugins/love-resources/src/index.ts | 6 +++- plugins/love-resources/src/utils.ts | 35 +++++++++++++++++-- plugins/love/src/index.ts | 6 ++-- 19 files changed, 148 insertions(+), 17 deletions(-) create mode 100644 plugins/love-resources/src/components/MeetingMinutesSearchItem.svelte diff --git a/models/love/src/index.ts b/models/love/src/index.ts index 3aaafeaa03..319c0e51f0 100644 --- a/models/love/src/index.ts +++ b/models/love/src/index.ts @@ -201,7 +201,14 @@ export class TMeeting extends TEvent implements Meeting { } @Model(love.class.MeetingMinutes, core.class.Doc, DOMAIN_MEETING_MINUTES) -@UX(love.string.MeetingMinutes, love.icon.Cam, undefined, 'createdOn', undefined, love.string.MeetingsMinutes) +@UX( + love.string.MeetingMinutes, + love.icon.MeetingMinutes, + undefined, + 'createdOn', + undefined, + love.string.MeetingsMinutes +) export class TMeetingMinutes extends TAttachedDoc implements MeetingMinutes, Todoable { @Prop(TypeRef(core.class.Doc), love.string.Room, { editor: love.component.MeetingMinutesDocEditor }) @Index(IndexKind.Indexed) @@ -644,6 +651,28 @@ export function createModel (builder: Builder): void { editor: love.component.PanelControlBar }) + builder.createDoc(core.class.FullTextSearchContext, core.space.Model, { + toClass: love.class.MeetingMinutes, + fullTextSummary: true, + forceIndex: true, + propagate: [] + }) + + builder.createDoc( + presentation.class.ObjectSearchCategory, + core.space.Model, + { + icon: love.icon.MeetingMinutes, + label: love.string.SearchMeetingMinutes, + title: love.string.MeetingMinutes, + query: love.completion.MeetingMinutesQuery, + context: ['search', 'mention', 'spotlight'], + classToSearch: love.class.MeetingMinutes, + priority: 600 + }, + love.completion.MeetingMinutesCategory + ) + createAttributePresenter( builder, view.component.DateTimePresenter, diff --git a/models/love/src/plugin.ts b/models/love/src/plugin.ts index f8819f6ed0..fe617ab048 100644 --- a/models/love/src/plugin.ts +++ b/models/love/src/plugin.ts @@ -20,6 +20,7 @@ import { type AnyComponent } from '@hcengineering/ui/src/types' import { type ActionCategory, type ViewAction } from '@hcengineering/view' import { loveId } from '@hcengineering/love' import love from '@hcengineering/love-resources/src/plugin' +import { type ObjectSearchCategory, type ObjectSearchFactory } from '@hcengineering/model-presentation' export default mergeIds(loveId, love, { component: { @@ -50,5 +51,9 @@ export default mergeIds(loveId, love, { }, function: { MeetingMinutesTitleProvider: '' as Resource<(client: Client, ref: Ref, doc?: Doc) => Promise> + }, + completion: { + MeetingMinutesQuery: '' as Resource, + MeetingMinutesCategory: '' as Ref } }) diff --git a/models/server-love/src/index.ts b/models/server-love/src/index.ts index 3d3bbb3a68..c2984c8088 100644 --- a/models/server-love/src/index.ts +++ b/models/server-love/src/index.ts @@ -79,4 +79,9 @@ export function createModel (builder: Builder): void { _class: core.class.TxCreateDoc } }) + + builder.mixin(love.class.MeetingMinutes, core.class.Class, serverCore.mixin.SearchPresenter, { + searchIcon: love.icon.MeetingMinutes, + title: [['title']] + }) } diff --git a/plugins/love-assets/assets/icons.svg b/plugins/love-assets/assets/icons.svg index 4e7d4cc5b3..15e8e852c9 100644 --- a/plugins/love-assets/assets/icons.svg +++ b/plugins/love-assets/assets/icons.svg @@ -94,4 +94,18 @@ + + + + + + diff --git a/plugins/love-assets/lang/cs.json b/plugins/love-assets/lang/cs.json index 7d3340b1b1..a52eb64b82 100644 --- a/plugins/love-assets/lang/cs.json +++ b/plugins/love-assets/lang/cs.json @@ -85,6 +85,7 @@ "WithAudio": "Zahrnout systémový zvuk", "ShareWithAudioTooltip": "Sdílejte obrazovku se systémovým zvukem. Restartujte sdílení obrazovky, aby se změny projevily.", "MicPermission": "Mikrofon nebyl nalezen, zkontrolujte oprávnění prohlížeče", - "CamPermission": "Kamera nebyla nalezena, zkontrolujte oprávnění prohlížeče" + "CamPermission": "Kamera nebyla nalezena, zkontrolujte oprávnění prohlížeče", + "SearchMeetingMinutes": "Vyhledat minuty schůzky..." } } \ No newline at end of file diff --git a/plugins/love-assets/lang/de.json b/plugins/love-assets/lang/de.json index 402810eadd..4caef78740 100644 --- a/plugins/love-assets/lang/de.json +++ b/plugins/love-assets/lang/de.json @@ -83,6 +83,7 @@ "WithAudio": "Systemaudio einschließen", "ShareWithAudioTooltip": "Teile deinen Bildschirm mit Systemaudio. Starte die Bildschirmfreigabe neu, um Änderungen anzuwenden.", "MicPermission": "Mikrofon nicht gefunden, überprüfen Sie die Browserberechtigungen", - "CamPermission": "Kamera nicht gefunden, überprüfen Sie die Browserberechtigungen" + "CamPermission": "Kamera nicht gefunden, überprüfen Sie die Browserberechtigungen", + "SearchMeetingMinutes": "Meetingprotokoll suchen..." } } diff --git a/plugins/love-assets/lang/en.json b/plugins/love-assets/lang/en.json index bc60f1472a..fe4755282c 100644 --- a/plugins/love-assets/lang/en.json +++ b/plugins/love-assets/lang/en.json @@ -85,6 +85,7 @@ "WithAudio": "Include system audio", "ShareWithAudioTooltip": "Share your screen with system audio. Restart screen share to apply changes.", "MicPermission": "Microphone not found, check browser permissions", - "CamPermission": "Camera not found, check browser permissions" + "CamPermission": "Camera not found, check browser permissions", + "SearchMeetingMinutes": "Search meeting minutes..." } } diff --git a/plugins/love-assets/lang/es.json b/plugins/love-assets/lang/es.json index ecdcb4ce17..b120dec1db 100644 --- a/plugins/love-assets/lang/es.json +++ b/plugins/love-assets/lang/es.json @@ -85,6 +85,7 @@ "WithAudio": "Incluir audio del sistema", "ShareWithAudioTooltip": "Comparte tu pantalla con el audio del sistema. Reinicia la pantalla compartida para aplicar los cambios.", "MicPermission": "Micrófono no encontrado, comprueba los permisos del navegador", - "CamPermission": "Cámara no encontrada, comprueba los permisos del navegador" + "CamPermission": "Cámara no encontrada, comprueba los permisos del navegador", + "SearchMeetingMinutes": "Buscar minutos de reunión..." } } diff --git a/plugins/love-assets/lang/fr.json b/plugins/love-assets/lang/fr.json index d4e4c7af87..7e6369b4ee 100644 --- a/plugins/love-assets/lang/fr.json +++ b/plugins/love-assets/lang/fr.json @@ -85,6 +85,7 @@ "WithAudio": "Inclure l'audio du système", "ShareWithAudioTooltip": "Partagez votre écran avec l'audio du système. Redémarrez le partage d’écran pour appliquer les modifications.", "MicPermission": "Microphone non trouvé, vérifiez les autorisations du navigateur", - "CamPermission": "Caméra non trouvée, vérifiez les autorisations du navigateur" + "CamPermission": "Caméra non trouvée, vérifiez les autorisations du navigateur", + "SearchMeetingMinutes": "Rechercher des minutes de réunion..." } } \ No newline at end of file diff --git a/plugins/love-assets/lang/it.json b/plugins/love-assets/lang/it.json index e06c19dc5b..ed024eb787 100644 --- a/plugins/love-assets/lang/it.json +++ b/plugins/love-assets/lang/it.json @@ -85,6 +85,7 @@ "WithAudio": "Includi l'audio di sistema", "ShareWithAudioTooltip": "Condividi lo schermo con l'audio di sistema. Riavvia la condivisione dello schermo per applicare le modifiche.", "MicPermission": "Microfono non trovato, controlla le autorizzazioni del browser", - "CamPermission": "Camera non trovata, controlla le autorizzazioni del browser" + "CamPermission": "Camera non trovata, controlla le autorizzazioni del browser", + "SearchMeetingMinutes": "Cerca i minuti della riunione..." } } diff --git a/plugins/love-assets/lang/pt.json b/plugins/love-assets/lang/pt.json index 820fb40bbe..26f979ce56 100644 --- a/plugins/love-assets/lang/pt.json +++ b/plugins/love-assets/lang/pt.json @@ -85,6 +85,7 @@ "WithAudio": "Incluir áudio do sistema", "ShareWithAudioTooltip": "Compartilhe sua tela com o áudio do sistema. Reinicie o compartilhamento de tela para aplicar as alterações.", "MicPermission": "Microfone não encontrado, verifique as permissões do navegador", - "CamPermission": "Câmera não encontrada, verifique as permissões do navegador" + "CamPermission": "Câmera não encontrada, verifique as permissões do navegador", + "SearchMeetingMinutes": "Procurar minutos de reunião..." } } diff --git a/plugins/love-assets/lang/ru.json b/plugins/love-assets/lang/ru.json index 54542ff5ad..1400afe7ef 100644 --- a/plugins/love-assets/lang/ru.json +++ b/plugins/love-assets/lang/ru.json @@ -85,6 +85,7 @@ "WithAudio": "С системным звуком", "ShareWithAudioTooltip": "Делитесь экраном с системным звуком. Перезапустите трансляцию, чтобы применить изменения.", "MicPermission": "Микрофон не найден, проверьте разрешения браузера", - "CamPermission": "Камера не найдена, проверьте разрешения браузера" + "CamPermission": "Камера не найдена, проверьте разрешения браузера", + "SearchMeetingMinutes": "Поиск протоколов встреч..." } } diff --git a/plugins/love-assets/lang/zh.json b/plugins/love-assets/lang/zh.json index 2914adca2f..1e9964757f 100644 --- a/plugins/love-assets/lang/zh.json +++ b/plugins/love-assets/lang/zh.json @@ -85,6 +85,7 @@ "WithAudio": "包含系统音频", "ShareWithAudioTooltip": "与系统音频一起共享屏幕。重新启动屏幕共享以应用更改。", "MicPermission": "未找到麦克风,请检查浏览器权限", - "CamPermission": "未找到摄像头,请检查浏览器权限" + "CamPermission": "未找到摄像头,请检查浏览器权限", + "SearchMeetingMinutes": "搜索会议分钟..." } } diff --git a/plugins/love-assets/src/index.ts b/plugins/love-assets/src/index.ts index 6ff830192f..e3b12e355e 100644 --- a/plugins/love-assets/src/index.ts +++ b/plugins/love-assets/src/index.ts @@ -37,7 +37,8 @@ loadMetadata(love.icon, { FullScreen: `${icons}#fullscreen`, ExitFullScreen: `${icons}#exitfullscreen`, Invite: `${icons}#invite`, - Kick: `${icons}#kick` + Kick: `${icons}#kick`, + MeetingMinutes: `${icons}#meeting-minutes` }) loadMetadata(love.sound, { Knock: require('../assets/knock.wav') diff --git a/plugins/love-resources/src/components/MeetingMinutesPresenter.svelte b/plugins/love-resources/src/components/MeetingMinutesPresenter.svelte index f7a8c56298..503b77a29d 100644 --- a/plugins/love-resources/src/components/MeetingMinutesPresenter.svelte +++ b/plugins/love-resources/src/components/MeetingMinutesPresenter.svelte @@ -37,7 +37,7 @@
{#if shouldShowAvatar}
- +
{/if}
diff --git a/plugins/love-resources/src/components/MeetingMinutesSearchItem.svelte b/plugins/love-resources/src/components/MeetingMinutesSearchItem.svelte new file mode 100644 index 0000000000..6a35f2c3c2 --- /dev/null +++ b/plugins/love-resources/src/components/MeetingMinutesSearchItem.svelte @@ -0,0 +1,31 @@ + + + +
+
+ +
+ + {value.title} + +
diff --git a/plugins/love-resources/src/index.ts b/plugins/love-resources/src/index.ts index fd308ddb50..411c4f773b 100644 --- a/plugins/love-resources/src/index.ts +++ b/plugins/love-resources/src/index.ts @@ -33,7 +33,8 @@ import { stopTranscription, toggleMic, toggleVideo, - getMeetingMinutesTitle + getMeetingMinutesTitle, + queryMeetingMinutes } from './utils' export { setCustomCreateScreenTracks } from './utils' @@ -85,5 +86,8 @@ export default async (): Promise => ({ StopTranscribing: stopTranscription, ShowRoomSettings: showRoomSettings, CopyGuestLink: copyGuestLink + }, + completion: { + MeetingMinutesQuery: queryMeetingMinutes } }) diff --git a/plugins/love-resources/src/utils.ts b/plugins/love-resources/src/utils.ts index 9d6babff07..93ed656a94 100644 --- a/plugins/love-resources/src/utils.ts +++ b/plugins/love-resources/src/utils.ts @@ -7,16 +7,20 @@ import contact, { getCurrentEmployee, getName, type Person } from '@hcengineerin import { personByIdStore } from '@hcengineering/contact-resources' import core, { AccountRole, + type Client, concatLink, type Data, type Doc, + type DocumentQuery, generateId, getCurrentAccount, type Hierarchy, type IdMap, type Ref, + type RelatedDocument, type Space, - type TxOperations + type TxOperations, + type WithLookup } from '@hcengineering/core' import login from '@hcengineering/login' import { @@ -43,7 +47,8 @@ import presentation, { copyTextToClipboard, createQuery, type DocCreatePhase, - getClient + getClient, + type ObjectSearchResult } from '@hcengineering/presentation' import { closePanel, @@ -87,6 +92,7 @@ import { sendMessage } from './broadcast' import RoomSettingsPopup from './components/RoomSettingsPopup.svelte' import love from './plugin' import { $myPreferences, currentMeetingMinutes, currentRoom, myOffice, selectedRoomPlace } from './stores' +import MeetingMinutesSearchItem from './components/MeetingMinutesSearchItem.svelte' export const selectedCamId = 'selectedDevice_cam' export const selectedMicId = 'selectedDevice_mic' @@ -1161,3 +1167,28 @@ export async function getMeetingMinutesTitle ( return meeting?.title ?? '' } + +export async function queryMeetingMinutes ( + client: Client, + search: string, + filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] } +): Promise { + const q: DocumentQuery = { title: { $like: `%${search}%` } } + if (filter?.in !== undefined || filter?.nin !== undefined) { + q._id = {} + if (filter.in !== undefined) { + q._id.$in = filter.in?.map((it) => it._id as Ref) + } + if (filter.nin !== undefined) { + q._id.$nin = filter.nin?.map((it) => it._id as Ref) + } + } + return (await client.findAll(love.class.MeetingMinutes, q, { limit: 200 })).map(toMeetingMinutesObjectSearchResult) +} + +const toMeetingMinutesObjectSearchResult = (e: WithLookup): ObjectSearchResult => ({ + doc: e, + title: e.title, + icon: love.icon.MeetingMinutes, + component: MeetingMinutesSearchItem +}) diff --git a/plugins/love/src/index.ts b/plugins/love/src/index.ts index de107b2ca9..7ff86bd70d 100644 --- a/plugins/love/src/index.ts +++ b/plugins/love/src/index.ts @@ -228,7 +228,8 @@ const love = plugin(loveId, { Finished: '' as IntlString, StartWithRecording: '' as IntlString, Kick: '' as IntlString, - EndMeeting: '' as IntlString + EndMeeting: '' as IntlString, + SearchMeetingMinutes: '' as IntlString }, ids: { MainFloor: '' as Ref, @@ -258,7 +259,8 @@ const love = plugin(loveId, { FullScreen: '' as Asset, ExitFullScreen: '' as Asset, Invite: '' as Asset, - Kick: '' as Asset + Kick: '' as Asset, + MeetingMinutes: '' as Asset }, sound: { Knock: '' as Asset