fix: update unified search results to match chunk viz display
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
This commit is contained in:
+10
-33
@@ -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 . '…';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user