Allow crew to read AI summaries without losing them on save.

Preserve existing summaries when crew edits entries and show a read-only hint in the editor.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-03 12:42:17 +02:00
parent dd111ce01f
commit d654aad937
6 changed files with 28 additions and 2 deletions
+23 -2
View File
@@ -43,6 +43,7 @@ import {
generateTravelDaySummary,
TravelDaySummaryApiError
} from '../services/aiSummary.js'
import { tryDecryptEntryPayload } from '../services/quickEventLog.js'
import {
getDecryptedTrack,
saveUploadedTrack,
@@ -457,13 +458,28 @@ export default function LogEntryEditor({
const eventsOverride = normalized.eventsOverride
const skipperToSave = normalized.signSkipper !== undefined ? normalized.signSkipper : signSkipper
const crewToSave = normalized.signCrew !== undefined ? normalized.signCrew : signCrew
const summaryToSave = normalized.aiSummary !== undefined ? normalized.aiSummary : aiSummary
const summaryAtToSave =
let summaryToSave = normalized.aiSummary !== undefined ? normalized.aiSummary : aiSummary
let summaryAtToSave =
normalized.aiSummaryGeneratedAt !== undefined ? normalized.aiSummaryGeneratedAt : aiSummaryGeneratedAt
const masterKey = await getLogbookKey(logbookId) || getActiveMasterKey()
if (!masterKey) throw new Error('Encryption key not found. Please log in.')
// Crew edits must not drop the skipper's AI summary when it is not loaded into editor state.
if (!summaryToSave.trim()) {
const local = await db.entries.get(entryId)
if (local) {
const decrypted = await tryDecryptEntryPayload(local, masterKey)
const existing =
decrypted && typeof decrypted.aiSummary === 'string' ? decrypted.aiSummary.trim() : ''
if (existing) {
summaryToSave = existing
summaryAtToSave =
typeof decrypted.aiSummaryGeneratedAt === 'string' ? decrypted.aiSummaryGeneratedAt : ''
}
}
}
const entryData: Record<string, unknown> = {
...buildPayloadForSigning(eventsOverride),
signSkipper: normalizedSerializedSignature(skipperToSave),
@@ -1551,6 +1567,11 @@ export default function LogEntryEditor({
<Sparkles size={20} className="form-icon" />
<h3>{t('logs.ai_summary_title')}</h3>
</div>
{aiSummary.trim() && !canSignSkipper && (
<p style={{ margin: '0 0 12px', fontSize: '0.9rem', opacity: 0.8 }}>
{t('logs.ai_summary_read_only')}
</p>
)}
{aiSummary.trim() ? (
<p style={{ whiteSpace: 'pre-wrap', margin: '0 0 16px', lineHeight: 1.5 }}>{aiSummary}</p>
) : (
+1
View File
@@ -373,6 +373,7 @@
"export_pdf": "Download PDF.",
"exporting_pdf": "PDF er genereret...",
"ai_summary_title": "AI-resumé",
"ai_summary_read_only": "Oprettet af skipperen — kun læsning for besætningen.",
"ai_summary_empty": "Intet resumé endnu.",
"ai_summary_generate": "Generér resumé",
"ai_summary_regenerate": "Generér igen",
+1
View File
@@ -373,6 +373,7 @@
"export_pdf": "PDF herunterladen",
"exporting_pdf": "PDF wird generiert...",
"ai_summary_title": "KI-Zusammenfassung",
"ai_summary_read_only": "Vom Skipper erstellt — nur lesbar für die Crew.",
"ai_summary_empty": "Noch keine Zusammenfassung vorhanden.",
"ai_summary_generate": "Zusammenfassung generieren",
"ai_summary_regenerate": "Neu generieren",
+1
View File
@@ -373,6 +373,7 @@
"export_pdf": "Download PDF",
"exporting_pdf": "Generating PDF...",
"ai_summary_title": "AI Summary",
"ai_summary_read_only": "Created by the skipper — read-only for crew.",
"ai_summary_empty": "No summary yet.",
"ai_summary_generate": "Generate summary",
"ai_summary_regenerate": "Regenerate",
+1
View File
@@ -373,6 +373,7 @@
"export_pdf": "Last ned PDF",
"exporting_pdf": "PDF genereres...",
"ai_summary_title": "AI-sammendrag",
"ai_summary_read_only": "Opprettet av skipperen — kun lesbar for mannskapet.",
"ai_summary_empty": "Ingen sammendrag ennå.",
"ai_summary_generate": "Generer sammendrag",
"ai_summary_regenerate": "Generer på nytt",
+1
View File
@@ -373,6 +373,7 @@
"export_pdf": "Hämta PDF.",
"exporting_pdf": "PDF genereras...",
"ai_summary_title": "AI-sammanfattning",
"ai_summary_read_only": "Skapad av skepparen — endast läsning för besättningen.",
"ai_summary_empty": "Ingen sammanfattning ännu.",
"ai_summary_generate": "Generera sammanfattning",
"ai_summary_regenerate": "Generera igen",