docs: remove deprecated integration checklists and documentation files
This commit is contained in:
@@ -5,12 +5,14 @@ import {
|
||||
EventEmitter,
|
||||
signal,
|
||||
computed,
|
||||
effect,
|
||||
ChangeDetectionStrategy,
|
||||
inject
|
||||
} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { SearchResult, SearchMatch } from '../../core/search/search-evaluator.service';
|
||||
import { SearchResult, SearchMatch } from '../../core/search/search-orchestrator.service';
|
||||
import { SearchHighlighterService } from '../../core/search/search-highlighter.service';
|
||||
import { VaultService } from '../../services/vault.service';
|
||||
|
||||
/**
|
||||
@@ -24,6 +26,7 @@ interface ResultGroup {
|
||||
matchCount: number;
|
||||
isExpanded: boolean;
|
||||
score: number;
|
||||
allRanges: any[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,15 +70,6 @@ type SortOption = 'relevance' | 'name' | 'modified';
|
||||
<option value="name">Name</option>
|
||||
<option value="modified">Modified</option>
|
||||
</select>
|
||||
|
||||
<!-- Expand/Collapse all -->
|
||||
<button
|
||||
(click)="toggleAllGroups()"
|
||||
class="btn-standard-xs"
|
||||
title="Expand/Collapse all"
|
||||
>
|
||||
{{ allExpanded() ? 'Collapse all' : 'Expand all' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -164,8 +158,8 @@ type SortOption = 'relevance' | 'name' | 'modified';
|
||||
</div>
|
||||
|
||||
<!-- Match context with highlighting -->
|
||||
<div class="text-sm text-text-main dark:text-gray-200 font-mono leading-relaxed">
|
||||
<span [innerHTML]="highlightMatch(match.context, match.text)"></span>
|
||||
<div class="text-sm text-text-main dark:text-gray-200 font-mono leading-relaxed whitespace-pre-wrap">
|
||||
<span [innerHTML]="highlightMatch(match)"></span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -205,16 +199,32 @@ type SortOption = 'relevance' | 'name' | 'modified';
|
||||
})
|
||||
export class SearchResultsComponent {
|
||||
@Input() set results(value: SearchResult[]) {
|
||||
this._results.set(value);
|
||||
this.buildGroups(value);
|
||||
}
|
||||
|
||||
@Input() collapseAll: boolean = false;
|
||||
@Input() showMoreContext: boolean = false;
|
||||
@Input() contextLines: number = 2;
|
||||
|
||||
@Output() noteOpen = new EventEmitter<{ noteId: string; line?: number }>();
|
||||
|
||||
private vaultService = inject(VaultService);
|
||||
private highlighter = inject(SearchHighlighterService);
|
||||
|
||||
private _results = signal<SearchResult[]>([]);
|
||||
private groups = signal<ResultGroup[]>([]);
|
||||
sortBy: SortOption = 'relevance';
|
||||
|
||||
constructor() {
|
||||
// Watch for collapseAll changes
|
||||
effect(() => {
|
||||
if (this.collapseAll !== undefined) {
|
||||
this.applyCollapseAll(this.collapseAll);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Total number of result files
|
||||
*/
|
||||
@@ -273,14 +283,24 @@ export class SearchResultsComponent {
|
||||
filePath,
|
||||
matches: result.matches,
|
||||
matchCount: result.matches.length,
|
||||
isExpanded: true, // Expand by default
|
||||
score: result.score
|
||||
isExpanded: !this.collapseAll, // Respect collapseAll setting
|
||||
score: result.score,
|
||||
allRanges: result.allRanges || []
|
||||
};
|
||||
});
|
||||
|
||||
this.groups.set(groups);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply collapse all setting to all groups
|
||||
*/
|
||||
private applyCollapseAll(collapse: boolean): void {
|
||||
this.groups.update(groups => {
|
||||
return groups.map(g => ({ ...g, isExpanded: !collapse }));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle a result group
|
||||
*/
|
||||
@@ -295,7 +315,7 @@ export class SearchResultsComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle all groups
|
||||
* Toggle all groups (not used when controlled by parent)
|
||||
*/
|
||||
toggleAllGroups(): void {
|
||||
const shouldExpand = !this.allExpanded();
|
||||
@@ -320,30 +340,24 @@ export class SearchResultsComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight matched text in context
|
||||
* Highlight matched text in context using ranges
|
||||
*/
|
||||
highlightMatch(context: string, matchText: string): string {
|
||||
if (!matchText || !context) {
|
||||
return this.escapeHtml(context);
|
||||
highlightMatch(match: SearchMatch): string {
|
||||
if (!match || !match.context) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const escapedContext = this.escapeHtml(context);
|
||||
const escapedMatch = this.escapeHtml(matchText);
|
||||
|
||||
// Case-insensitive replacement with highlighting
|
||||
const regex = new RegExp(`(${escapedMatch})`, 'gi');
|
||||
return escapedContext.replace(
|
||||
regex,
|
||||
'<mark class="bg-yellow-200 dark:bg-yellow-600 text-text-main dark:text-gray-900 px-0.5 rounded">$1</mark>'
|
||||
);
|
||||
}
|
||||
// If we have ranges, use them for precise highlighting
|
||||
if (match.ranges && match.ranges.length > 0) {
|
||||
return this.highlighter.highlightWithRanges(match.context, match.ranges);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape HTML to prevent XSS
|
||||
*/
|
||||
private escapeHtml(text: string): string {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
// Fallback to simple text-based highlighting
|
||||
if (match.text) {
|
||||
return this.highlighter.highlightMatches(match.context, [match.text], false);
|
||||
}
|
||||
|
||||
// No highlighting needed
|
||||
return this.highlighter.highlightMatches(match.context, [], false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user