mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-12 20:02:28 +08:00
correctly style the failed embeddings section
This commit is contained in:
parent
c914aaa4a8
commit
ee7b2283de
@ -42,6 +42,7 @@ interface FailedEmbeddingNotes {
|
|||||||
error: string;
|
error: string;
|
||||||
failureType: string;
|
failureType: string;
|
||||||
chunks: number;
|
chunks: number;
|
||||||
|
isPermanent: boolean;
|
||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -847,34 +848,61 @@ export default class AiSettingsWidget extends OptionsWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const $failedHeader = $(`
|
// Create header with count and retry all button
|
||||||
|
const $header = $(`
|
||||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||||
<h6>Failed Embeddings (${failedResult.failedNotes.length})</h6>
|
<h6 class="mb-0">Failed Embeddings (${failedResult.failedNotes.length})</h6>
|
||||||
<button class="btn btn-sm btn-outline-primary retry-all-btn">Retry All Failed</button>
|
<button class="btn btn-sm btn-primary retry-all-btn">Retry All</button>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const $failedList = $('<div class="list-group failed-list mb-3">');
|
// Create list container using the application's native note-list class
|
||||||
|
const $failedList = $('<div class="note-list mb-3">');
|
||||||
|
|
||||||
for (const note of failedResult.failedNotes) {
|
for (const note of failedResult.failedNotes) {
|
||||||
// Determine if this is a full note failure or just failed chunks
|
// Determine if this is a full note failure or just failed chunks
|
||||||
const isFullFailure = note.failureType === 'full';
|
const isFullFailure = note.failureType === 'full';
|
||||||
const badgeClass = isFullFailure ? 'badge-danger' : 'badge-warning';
|
const isPermanentlyFailed = note.isPermanent === true;
|
||||||
const badgeText = isFullFailure ? 'Full Note' : `${note.chunks} Chunks`;
|
|
||||||
|
|
||||||
|
// Use Bootstrap 4 badge classes
|
||||||
|
let badgeText = isFullFailure ? 'Full Note' : `Chunks Failed`;
|
||||||
|
let badgeClass = 'badge-warning';
|
||||||
|
|
||||||
|
if (isPermanentlyFailed) {
|
||||||
|
badgeClass = 'badge-danger';
|
||||||
|
if (isFullFailure) {
|
||||||
|
badgeText = 'Permanently Failed';
|
||||||
|
} else {
|
||||||
|
badgeText = 'Partially Failed';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the application's note-list-item styling
|
||||||
const $item = $(`
|
const $item = $(`
|
||||||
<div class="list-group-item list-group-item-action flex-column align-items-start p-2">
|
<div class="note-list-item">
|
||||||
<div class="d-flex justify-content-between">
|
<div class="note-book-card p-2">
|
||||||
<div>
|
<div class="d-flex w-100 justify-content-between">
|
||||||
<h6 class="mb-1">${note.title || note.noteId}</h6>
|
<div>
|
||||||
<span class="badge ${badgeClass} mb-1">${badgeText}</span>
|
<div class="d-flex align-items-center">
|
||||||
|
<h6 class="mb-1">${note.title || note.noteId}</h6>
|
||||||
|
<span class="badge ${badgeClass} ml-2">${badgeText}</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-muted mb-1 small">
|
||||||
|
${isPermanentlyFailed ?
|
||||||
|
`<strong>Status:</strong> Permanently failed` :
|
||||||
|
`<strong>Attempts:</strong> ${note.attempts}`}
|
||||||
|
<br>
|
||||||
|
<strong>Last attempt:</strong> ${note.lastAttempt.substring(0, 19)}
|
||||||
|
<br>
|
||||||
|
<strong>Error:</strong> ${(note.error || 'Unknown error').substring(0, 100)}${(note.error && note.error.length > 100) ? '...' : ''}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="ml-2 align-self-center">
|
||||||
|
<button class="btn btn-sm btn-outline-secondary retry-btn" data-note-id="${note.noteId}">
|
||||||
|
<i class="fas fa-redo-alt"></i> Retry
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-sm btn-outline-secondary retry-btn" data-note-id="${note.noteId}">Retry</button>
|
|
||||||
</div>
|
|
||||||
<div class="small text-muted">
|
|
||||||
<div>Attempts: ${note.attempts}</div>
|
|
||||||
<div>Last attempt: ${note.lastAttempt}</div>
|
|
||||||
<div>Error: ${note.error}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
@ -882,38 +910,67 @@ export default class AiSettingsWidget extends OptionsWidget {
|
|||||||
$failedList.append($item);
|
$failedList.append($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$widget.find('.embedding-failed-notes-list').empty().append($failedHeader, $failedList);
|
// Add the header and list to the DOM (no card structure)
|
||||||
|
this.$widget.find('.embedding-failed-notes-list').empty().append($header, $failedList);
|
||||||
|
|
||||||
// Add event handlers using local variables to avoid 'this' issues
|
// Add event handlers using local variables to avoid 'this' issues
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
this.$widget.find('.retry-btn').on('click', async function() {
|
this.$widget.find('.retry-btn').on('click', async function(e) {
|
||||||
const noteId = $(this).data('note-id');
|
// Prevent default behavior
|
||||||
$(this).prop('disabled', true).text('Retrying...');
|
e.preventDefault();
|
||||||
|
|
||||||
|
const $button = $(this);
|
||||||
|
const noteId = $button.data('note-id');
|
||||||
|
|
||||||
|
// Show loading state
|
||||||
|
$button.prop('disabled', true)
|
||||||
|
.removeClass('btn-outline-secondary')
|
||||||
|
.addClass('btn-outline-secondary')
|
||||||
|
.html('<span class="fa fa-spin fa-spinner mr-1"></span>Retrying');
|
||||||
|
|
||||||
const success = await self.retryFailedEmbedding(noteId);
|
const success = await self.retryFailedEmbedding(noteId);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
toastService.showMessage("Note queued for retry");
|
toastService.showMessage(t("ai_llm.note_queued_for_retry"));
|
||||||
await self.refreshEmbeddingStats();
|
await self.refreshEmbeddingStats();
|
||||||
} else {
|
} else {
|
||||||
toastService.showError("Failed to retry note");
|
toastService.showError(t("ai_llm.failed_to_retry_note"));
|
||||||
$(this).prop('disabled', false).text('Retry');
|
$button.prop('disabled', false)
|
||||||
|
.html('<i class="fas fa-redo-alt"></i> Retry');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$widget.find('.retry-all-btn').on('click', async function() {
|
this.$widget.find('.retry-all-btn').on('click', async function(e) {
|
||||||
$(this).prop('disabled', true).text('Retrying All...');
|
const $button = $(this);
|
||||||
|
|
||||||
|
// Show loading state
|
||||||
|
$button.prop('disabled', true)
|
||||||
|
.removeClass('btn-primary')
|
||||||
|
.addClass('btn-secondary')
|
||||||
|
.html('<span class="fa fa-spin fa-spinner mr-1"></span>Retrying All');
|
||||||
|
|
||||||
const success = await self.retryAllFailedEmbeddings();
|
const success = await self.retryAllFailedEmbeddings();
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
toastService.showMessage("All failed notes queued for retry");
|
toastService.showMessage(t("ai_llm.all_notes_queued_for_retry"));
|
||||||
await self.refreshEmbeddingStats();
|
await self.refreshEmbeddingStats();
|
||||||
|
|
||||||
|
// Return button to original state after successful refresh
|
||||||
|
if (!$button.is(':disabled')) { // Check if button still exists
|
||||||
|
$button.prop('disabled', false)
|
||||||
|
.removeClass('btn-secondary')
|
||||||
|
.addClass('btn-primary')
|
||||||
|
.html('Retry All');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
toastService.showError("Failed to retry notes");
|
toastService.showError(t("ai_llm.failed_to_retry_all"));
|
||||||
$(this).prop('disabled', false).text('Retry All Failed');
|
$button.prop('disabled', false)
|
||||||
|
.removeClass('btn-secondary')
|
||||||
|
.addClass('btn-primary')
|
||||||
|
.html('Retry All');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1209,7 +1209,11 @@
|
|||||||
"refresh_stats": "Refresh Stats",
|
"refresh_stats": "Refresh Stats",
|
||||||
"refreshing": "Refreshing...",
|
"refreshing": "Refreshing...",
|
||||||
"stats_error": "Error fetching embedding statistics",
|
"stats_error": "Error fetching embedding statistics",
|
||||||
"auto_refresh_notice": "Auto-refreshes every {{seconds}} seconds"
|
"auto_refresh_notice": "Auto-refreshes every {{seconds}} seconds",
|
||||||
|
"note_queued_for_retry": "Note queued for retry",
|
||||||
|
"failed_to_retry_note": "Failed to retry note",
|
||||||
|
"all_notes_queued_for_retry": "All failed notes queued for retry",
|
||||||
|
"failed_to_retry_all": "Failed to retry notes"
|
||||||
},
|
},
|
||||||
"zoom_factor": {
|
"zoom_factor": {
|
||||||
"title": "Zoom Factor (desktop build only)",
|
"title": "Zoom Factor (desktop build only)",
|
||||||
|
@ -286,10 +286,10 @@ export async function processEmbeddingQueue() {
|
|||||||
if (noteData.attempts + 1 >= 3) {
|
if (noteData.attempts + 1 >= 3) {
|
||||||
log.error(`Marked note ${noteData.noteId} as permanently failed after multiple embedding attempts`);
|
log.error(`Marked note ${noteData.noteId} as permanently failed after multiple embedding attempts`);
|
||||||
|
|
||||||
// Set the failed flag and update the attempts
|
// Set the failed flag but keep the actual attempts count
|
||||||
await sql.execute(`
|
await sql.execute(`
|
||||||
UPDATE embedding_queue
|
UPDATE embedding_queue
|
||||||
SET attempts = 999, failed = 1
|
SET failed = 1
|
||||||
WHERE noteId = ?
|
WHERE noteId = ?
|
||||||
`, [noteData.noteId]);
|
`, [noteData.noteId]);
|
||||||
}
|
}
|
||||||
@ -313,10 +313,10 @@ export async function processEmbeddingQueue() {
|
|||||||
if (noteData.attempts + 1 >= 3) {
|
if (noteData.attempts + 1 >= 3) {
|
||||||
log.error(`Marked note ${noteData.noteId} as permanently failed after multiple embedding attempts`);
|
log.error(`Marked note ${noteData.noteId} as permanently failed after multiple embedding attempts`);
|
||||||
|
|
||||||
// Set the failed flag and update the attempts
|
// Set the failed flag but keep the actual attempts count
|
||||||
await sql.execute(`
|
await sql.execute(`
|
||||||
UPDATE embedding_queue
|
UPDATE embedding_queue
|
||||||
SET attempts = 999, failed = 1
|
SET failed = 1
|
||||||
WHERE noteId = ?
|
WHERE noteId = ?
|
||||||
`, [noteData.noteId]);
|
`, [noteData.noteId]);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user