mirror of
https://github.com/ashwin271/obsidian-vector-search.git
synced 2026-07-22 05:35:32 +00:00
feat: improve search modal UI
This commit is contained in:
parent
8425ba055e
commit
b709e3ca9f
2 changed files with 79 additions and 8 deletions
47
main.ts
47
main.ts
|
|
@ -618,6 +618,7 @@ export default class VectorSearchPlugin extends Plugin {
|
|||
class SearchModal extends Modal {
|
||||
private plugin: VectorSearchPlugin;
|
||||
private searchInput: HTMLInputElement;
|
||||
private statusDiv: HTMLDivElement;
|
||||
private resultsDiv: HTMLDivElement;
|
||||
|
||||
constructor(app: App, plugin: VectorSearchPlugin) {
|
||||
|
|
@ -635,6 +636,12 @@ class SearchModal extends Modal {
|
|||
type: 'text',
|
||||
placeholder: 'Type to search similar notes...'
|
||||
});
|
||||
|
||||
const actions = searchContainer.createDiv('search-actions');
|
||||
const searchButton = actions.createEl('button', { text: 'Search' });
|
||||
const selectionButton = actions.createEl('button', { text: 'Use selection' });
|
||||
|
||||
this.statusDiv = contentEl.createDiv('search-status');
|
||||
|
||||
// Create results container
|
||||
this.resultsDiv = contentEl.createDiv('search-results');
|
||||
|
|
@ -644,31 +651,61 @@ class SearchModal extends Modal {
|
|||
const query = this.searchInput.value;
|
||||
if (query.length < 3) {
|
||||
this.resultsDiv.empty();
|
||||
this.statusDiv.empty();
|
||||
return;
|
||||
}
|
||||
await this.performSearch(query);
|
||||
}, this.plugin.settings.debounceTime, true);
|
||||
|
||||
this.searchInput.addEventListener('input', debouncedSearch);
|
||||
|
||||
searchButton.addEventListener('click', async () => {
|
||||
await this.performSearch(this.searchInput.value);
|
||||
});
|
||||
selectionButton.addEventListener('click', async () => {
|
||||
const selection = this.getActiveSelection();
|
||||
if (selection.length < 3) {
|
||||
new Notice('Select at least 3 characters to search.');
|
||||
return;
|
||||
}
|
||||
this.searchInput.value = selection;
|
||||
await this.performSearch(selection);
|
||||
});
|
||||
|
||||
// Focus input
|
||||
this.searchInput.focus();
|
||||
}
|
||||
|
||||
private getActiveSelection(): string {
|
||||
const editor = this.app.workspace.activeEditor?.editor;
|
||||
return editor?.getSelection().trim() ?? '';
|
||||
}
|
||||
|
||||
async performSearch(query: string) {
|
||||
if (query.length < 3) {
|
||||
this.resultsDiv.setText('Type at least 3 characters to search.');
|
||||
this.statusDiv.empty();
|
||||
return;
|
||||
}
|
||||
this.statusDiv.setText('Searching...');
|
||||
if (this.plugin.vectorStore.size === 0) {
|
||||
this.resultsDiv.setText('Vector index is empty. Please rebuild the index first.');
|
||||
this.statusDiv.empty();
|
||||
return;
|
||||
}
|
||||
|
||||
const isReady = await this.plugin.ensureRequirements(true);
|
||||
if (!isReady) {
|
||||
this.resultsDiv.setText('Ollama is unavailable. Check the plugin settings and try again.');
|
||||
this.statusDiv.empty();
|
||||
return;
|
||||
}
|
||||
|
||||
const queryEmbedding = await this.plugin.getEmbedding(query);
|
||||
if (queryEmbedding.length === 0) {
|
||||
this.resultsDiv.setText('Failed to generate an embedding for the query.');
|
||||
this.statusDiv.empty();
|
||||
return;
|
||||
}
|
||||
const results: Array<{vectorData: VectorData, similarity: number}> = [];
|
||||
|
||||
for (const vectorData of this.plugin.vectorStore.values()) {
|
||||
|
|
@ -680,6 +717,7 @@ class SearchModal extends Modal {
|
|||
|
||||
results.sort((a, b) => b.similarity - a.similarity);
|
||||
this.displayResults(results.slice(0, this.plugin.settings.maxResults));
|
||||
this.statusDiv.empty();
|
||||
}
|
||||
|
||||
displayResults(results: Array<{vectorData: VectorData, similarity: number}>) {
|
||||
|
|
@ -693,9 +731,10 @@ class SearchModal extends Modal {
|
|||
const list = this.resultsDiv.createEl('ul');
|
||||
for (const result of results) {
|
||||
const item = list.createEl('li');
|
||||
const link = item.createEl('a', {
|
||||
text: `${result.vectorData.title} (${(result.similarity * 100).toFixed(2)}%)`,
|
||||
href: '#'
|
||||
const link = item.createEl('a', { text: result.vectorData.title, href: '#' });
|
||||
item.createEl('span', {
|
||||
text: `${(result.similarity * 100).toFixed(2)}%`,
|
||||
cls: 'similarity-score'
|
||||
});
|
||||
|
||||
// Add line numbers info
|
||||
|
|
|
|||
40
styles.css
40
styles.css
|
|
@ -38,6 +38,30 @@
|
|||
box-shadow: 0 0 0 2px var(--interactive-accent-hover);
|
||||
}
|
||||
|
||||
.search-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.search-actions button {
|
||||
padding: 6px 10px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
background-color: var(--background-secondary);
|
||||
color: var(--text-normal);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.search-actions button:hover {
|
||||
background-color: var(--background-modifier-hover);
|
||||
}
|
||||
|
||||
.search-status {
|
||||
padding: 6px 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.search-results {
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
|
|
@ -56,6 +80,9 @@
|
|||
border-radius: 6px;
|
||||
background-color: var(--background-secondary);
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-results li:hover {
|
||||
|
|
@ -66,9 +93,7 @@
|
|||
.search-results a {
|
||||
text-decoration: none;
|
||||
color: var(--text-normal);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.search-results .similarity-score {
|
||||
|
|
@ -79,6 +104,13 @@
|
|||
background-color: var(--background-modifier-border);
|
||||
}
|
||||
|
||||
.search-result-lines {
|
||||
width: 100%;
|
||||
margin-top: 6px;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
/* Progress Bar Styles */
|
||||
.vector-search-progress {
|
||||
width: 100%;
|
||||
|
|
@ -93,4 +125,4 @@
|
|||
height: 100%;
|
||||
background-color: var(--interactive-accent);
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue