fix: restore objectAssignments in EditPairForm on load
Extract {{label.o:objectId}} refs from raw sentence text before resolving
placeholders, then reconcile with wordMap once it's built so the object
assignment dropdown reflects the saved state on re-open.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -483,6 +483,9 @@ function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) {
|
|||||||
const [creatingWord, setCreatingWord] = useState(false);
|
const [creatingWord, setCreatingWord] = useState(false);
|
||||||
const [confirmDelete, setConfirmDelete] = useState(false);
|
const [confirmDelete, setConfirmDelete] = useState(false);
|
||||||
const [deleting, setDeleting] = useState(false);
|
const [deleting, setDeleting] = useState(false);
|
||||||
|
// Stores label→objectId extracted from raw placeholder text during load,
|
||||||
|
// used to restore objectAssignments once wordMap is built.
|
||||||
|
const labelToObjectId = useRef({});
|
||||||
|
|
||||||
useEffect(() => { setWordInput(selection); }, [selection]);
|
useEffect(() => { setWordInput(selection); }, [selection]);
|
||||||
|
|
||||||
@@ -496,16 +499,26 @@ function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
labelToObjectId.current = {};
|
||||||
|
function extractObjectRefs(rawText) {
|
||||||
|
const re = /\{\{([^.}]+)\.o:([0-9a-f-]{36})\}\}/gi;
|
||||||
|
let m;
|
||||||
|
while ((m = re.exec(rawText)) !== null) {
|
||||||
|
labelToObjectId.current[m[1].toLowerCase()] = m[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
async function load() {
|
async function load() {
|
||||||
try {
|
try {
|
||||||
if (pair.question_id) {
|
if (pair.question_id) {
|
||||||
const q = await apiFetch(`/questions/${pair.question_id}`);
|
const q = await apiFetch(`/questions/${pair.question_id}`);
|
||||||
setQuestion(await resolvePlaceholders(q[`sentence_${lang}`] || q.sentence_de || '', allObjects));
|
const rawQ = q[`sentence_${lang}`] || q.sentence_de || '';
|
||||||
|
extractObjectRefs(rawQ);
|
||||||
|
setQuestion(await resolvePlaceholders(rawQ, allObjects));
|
||||||
}
|
}
|
||||||
if (pair.positive_statement_id) {
|
if (pair.positive_statement_id) {
|
||||||
const s = await apiFetch(`/statements/${pair.positive_statement_id}`);
|
const s = await apiFetch(`/statements/${pair.positive_statement_id}`);
|
||||||
const raw = s[`positive_sentence_${lang}`] || s.positive_sentence_de || '';
|
const raw = s[`positive_sentence_${lang}`] || s.positive_sentence_de || '';
|
||||||
if (raw) setPositive(await resolvePlaceholders(raw, allObjects));
|
if (raw) { extractObjectRefs(raw); setPositive(await resolvePlaceholders(raw, allObjects)); }
|
||||||
if (s.answer !== null && s.answer !== undefined) setYesNoAnswer(s.answer);
|
if (s.answer !== null && s.answer !== undefined) setYesNoAnswer(s.answer);
|
||||||
if (s.positive_word_ids?.length) {
|
if (s.positive_word_ids?.length) {
|
||||||
const words = await Promise.all(s.positive_word_ids.map(id => apiFetch(`/words/${id}`).catch(() => null)));
|
const words = await Promise.all(s.positive_word_ids.map(id => apiFetch(`/words/${id}`).catch(() => null)));
|
||||||
@@ -515,7 +528,7 @@ function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) {
|
|||||||
if (pair.negative_statement_id) {
|
if (pair.negative_statement_id) {
|
||||||
const s = await apiFetch(`/statements/${pair.negative_statement_id}`);
|
const s = await apiFetch(`/statements/${pair.negative_statement_id}`);
|
||||||
const raw = s[`negative_sentence_${lang}`] || s.negative_sentence_de || '';
|
const raw = s[`negative_sentence_${lang}`] || s.negative_sentence_de || '';
|
||||||
if (raw) setNegative(await resolvePlaceholders(raw, allObjects));
|
if (raw) { extractObjectRefs(raw); setNegative(await resolvePlaceholders(raw, allObjects)); }
|
||||||
if (s.negative_word_ids?.length) {
|
if (s.negative_word_ids?.length) {
|
||||||
const words = await Promise.all(s.negative_word_ids.map(id => apiFetch(`/words/${id}`).catch(() => null)));
|
const words = await Promise.all(s.negative_word_ids.map(id => apiFetch(`/words/${id}`).catch(() => null)));
|
||||||
setNegativeWords(words.filter(Boolean));
|
setNegativeWords(words.filter(Boolean));
|
||||||
@@ -551,6 +564,17 @@ function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
setWordMap(map);
|
setWordMap(map);
|
||||||
|
// Restore objectAssignments from placeholders extracted during load
|
||||||
|
if (Object.keys(labelToObjectId.current).length) {
|
||||||
|
setObjectAssignments(prev => {
|
||||||
|
const restored = {};
|
||||||
|
Object.entries(map).forEach(([label, w]) => {
|
||||||
|
const objId = labelToObjectId.current[label.toLowerCase()];
|
||||||
|
if (objId) restored[w.id] = objId;
|
||||||
|
});
|
||||||
|
return Object.keys(restored).length ? { ...restored, ...prev } : prev;
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch { /* ignore word detection errors */ }
|
} catch { /* ignore word detection errors */ }
|
||||||
}, 600);
|
}, 600);
|
||||||
return () => clearTimeout(t);
|
return () => clearTimeout(t);
|
||||||
|
|||||||
Reference in New Issue
Block a user