From 24898439cb017e3c5f3ab576972cb3a69b3780b5 Mon Sep 17 00:00:00 2001 From: Chris Coutinho Date: Tue, 16 Dec 2025 00:40:01 +0100 Subject: [PATCH] fix: update unified search results to match chunk viz display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the unified search provider to show only chunk/page metadata in search results, consistent with the chunk visualization result list. Also fix news item URLs to link directly to the specific item. Changes to SemanticSearchProvider: 1. Result display improvements: - Remove excerpt text from search result subline - Show only chunk/page metadata (e.g., "Chunk 2/5 · Page 3/10") - Consistent with chunk visualization UI in App.vue 2. News item URL fix: - Change from generic news index to specific item URL - Format: /apps/news/item/{id} - Allows direct navigation to the news article 3. Code cleanup: - Remove unused $excerpt variable - Remove unused truncateExcerpt() method - Simplify transformResult() logic Benefits: - Cleaner, more scannable search results - Consistent UX between unified search and app UI - Functional links to news items instead of generic news page - Reduced code complexity --- .../lib/Search/SemanticSearchProvider.php | 43 +++++-------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/third_party/astroglobe/lib/Search/SemanticSearchProvider.php b/third_party/astroglobe/lib/Search/SemanticSearchProvider.php index 7734c57..06f2c41 100644 --- a/third_party/astroglobe/lib/Search/SemanticSearchProvider.php +++ b/third_party/astroglobe/lib/Search/SemanticSearchProvider.php @@ -177,7 +177,6 @@ class SemanticSearchProvider implements IProvider { private function transformResult(array $result): SearchResultEntry { $docType = $result['doc_type'] ?? 'unknown'; $title = $result['title'] ?? $this->l10n->t('Untitled'); - $excerpt = $result['excerpt'] ?? ''; $score = $result['score'] ?? 0; $id = isset($result['id']) ? (string)$result['id'] : null; $mimeType = $result['mime_type'] ?? null; @@ -205,17 +204,13 @@ class SemanticSearchProvider implements IProvider { // Combine metadata parts $metadata = !empty($metadataParts) ? implode(' · ', $metadataParts) : ''; - // Subline shows metadata + excerpt (or just metadata if no excerpt) - if (!empty($excerpt)) { - $subline = $metadata ? $metadata . "\n" . $excerpt : $excerpt; - } else { - $subline = $metadata ?: sprintf( - '%s · %d%% %s', - $this->getDocTypeLabel($docType), - (int)($score * 100), - $this->l10n->t('relevant') - ); - } + // Subline shows only chunk/page metadata (no excerpt, consistent with chunk viz) + $subline = $metadata ?: sprintf( + '%s · %d%% %s', + $this->getDocTypeLabel($docType), + (int)($score * 100), + $this->l10n->t('relevant') + ); return new SearchResultEntry( $thumbnailUrl, @@ -253,7 +248,9 @@ class SemanticSearchProvider implements IProvider { 'calendar', 'calendar_event' => $this->urlGenerator->linkToRoute('calendar.view.index'), - 'news_item' => $this->urlGenerator->linkToRoute('news.page.index'), + 'news_item' => $id + ? $this->urlGenerator->linkToRoute('news.page.index') . 'item/' . $id + : $this->urlGenerator->linkToRoute('news.page.index'), 'contact' => $this->urlGenerator->linkToRoute('contacts.page.index'), @@ -317,24 +314,4 @@ class SemanticSearchProvider implements IProvider { }; } - /** - * Truncate excerpt to a maximum length, breaking at word boundaries. - */ - private function truncateExcerpt(string $excerpt, int $maxLength): string { - $excerpt = trim($excerpt); - - if (mb_strlen($excerpt) <= $maxLength) { - return $excerpt; - } - - // Find last space before limit - $truncated = mb_substr($excerpt, 0, $maxLength); - $lastSpace = mb_strrpos($truncated, ' '); - - if ($lastSpace !== false && $lastSpace > $maxLength * 0.7) { - $truncated = mb_substr($truncated, 0, $lastSpace); - } - - return $truncated . '…'; - } }