feat(vocab): enrich core patterns with glosses in VocabService and VocabLessonView
All checks were successful
Deploy to production / deploy (push) Successful in 2m54s

- Implemented a new method in VocabService to enhance core patterns with glosses derived from extracted vocabulary, improving the clarity of vocabulary entries.
- Updated the VocabLessonView to utilize the enriched core patterns, ensuring that glosses are displayed alongside vocabulary targets for better user comprehension.
- Refactored vocabulary preparation logic to integrate glosses seamlessly, enhancing the overall user experience during vocabulary lessons.
This commit is contained in:
Torsten Schulz (local)
2026-04-01 09:40:33 +02:00
parent 02b3636e10
commit 1328e4983e
2 changed files with 47 additions and 3 deletions

View File

@@ -321,6 +321,32 @@ export default class VocabService {
return n ? n.target : '';
}
_enrichCorePatternsWithGloss(corePatterns = [], extractedVocabs = []) {
const glossByReference = new Map();
extractedVocabs.forEach((item) => {
const reference = this._normalizeLexeme(item?.reference);
const learning = String(item?.learning || '').trim();
if (!reference || !learning) {
return;
}
if (!glossByReference.has(reference)) {
glossByReference.set(reference, learning);
}
});
return corePatterns
.map((entry) => this._normalizeCorePatternEntry(entry))
.filter(Boolean)
.map((entry) => {
if (entry.gloss) {
return entry;
}
const gloss = glossByReference.get(this._normalizeLexeme(entry.target)) || '';
return gloss ? { ...entry, gloss } : entry;
});
}
_normalizeStructuredList(value, keys = ['title', 'text']) {
if (!value) return [];
if (Array.isArray(value)) {
@@ -533,7 +559,11 @@ export default class VocabService {
const uniquePatterns = [...new Set(patterns.map((item) => String(item || '').trim()).filter(Boolean))];
const learningGoals = this._normalizeStringList(plainLesson.learningGoals);
const corePatterns = this._normalizeCorePatternList(plainLesson.corePatterns);
const extractedTrainerVocabs = this._extractTrainerVocabsFromExercises(grammarExercises);
const corePatterns = this._enrichCorePatternsWithGloss(
this._normalizeCorePatternList(plainLesson.corePatterns),
extractedTrainerVocabs
);
const grammarFocus = this._normalizeStructuredList(plainLesson.grammarFocus, ['title', 'text', 'example']);
const explicitSpeakingPrompts = this._normalizeStructuredList(plainLesson.speakingPrompts, ['title', 'prompt', 'cue']);
const practicalTasks = this._normalizeStructuredList(plainLesson.practicalTasks, ['title', 'text']);
@@ -548,7 +578,10 @@ export default class VocabService {
],
corePatterns: corePatterns.length > 0
? corePatterns
: uniquePatterns.slice(0, 5).map((s) => ({ target: String(s || '').trim(), gloss: '' })).filter((p) => p.target),
: this._enrichCorePatternsWithGloss(
uniquePatterns.slice(0, 5).map((s) => ({ target: String(s || '').trim(), gloss: '' })).filter((p) => p.target),
extractedTrainerVocabs
),
grammarFocus: grammarFocus.length > 0 ? grammarFocus : uniqueGrammarExplanations.slice(0, 4),
speakingPrompts: explicitSpeakingPrompts.length > 0 ? explicitSpeakingPrompts : speakingPrompts.slice(0, 4),
practicalTasks: practicalTasks.length > 0

View File

@@ -948,7 +948,18 @@ export default {
},
prepItems() {
if (this.normalizedCorePatterns.length > 0) {
return this.normalizedCorePatterns;
const glossByReference = new Map(
(this.importantVocab || [])
.map((item) => [String(item?.reference || '').trim().toLowerCase(), String(item?.learning || '').trim()])
.filter(([reference, learning]) => reference && learning)
);
return this.normalizedCorePatterns.map((item) => {
if (item.gloss) {
return item;
}
const gloss = glossByReference.get(String(item.target || '').trim().toLowerCase()) || '';
return gloss ? { ...item, gloss } : item;
});
}
return (this.importantVocab || [])
.map((item) => ({