fix: restore objectAssignments during load by fetching word IDs directly
Instead of waiting for the wordMap effect to reconcile, look up word IDs for each label→objectId pair immediately in load() so objectAssignments is set before the user sees the form. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -483,10 +483,6 @@ function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) {
|
||||
const [creatingWord, setCreatingWord] = useState(false);
|
||||
const [confirmDelete, setConfirmDelete] = 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]);
|
||||
|
||||
async function handleDelete() {
|
||||
@@ -499,16 +495,16 @@ function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) {
|
||||
}
|
||||
|
||||
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() {
|
||||
try {
|
||||
// Collect all label→objectId refs from raw placeholder text across all fields
|
||||
const labelToObjId = {};
|
||||
function extractObjectRefs(rawText) {
|
||||
const re = /\{\{([^.}]+)\.o:([0-9a-f-]{36})\}\}/gi;
|
||||
let m;
|
||||
while ((m = re.exec(rawText)) !== null) labelToObjId[m[1].toLowerCase()] = m[2];
|
||||
}
|
||||
|
||||
if (pair.question_id) {
|
||||
const q = await apiFetch(`/questions/${pair.question_id}`);
|
||||
const rawQ = q[`sentence_${lang}`] || q.sentence_de || '';
|
||||
@@ -534,6 +530,22 @@ function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) {
|
||||
setNegativeWords(words.filter(Boolean));
|
||||
}
|
||||
}
|
||||
|
||||
// Directly look up word IDs for each extracted label and set objectAssignments
|
||||
if (Object.keys(labelToObjId).length) {
|
||||
const assignments = {};
|
||||
await Promise.all(Object.entries(labelToObjId).map(async ([label, objId]) => {
|
||||
try {
|
||||
const words = await apiFetch(`/words?search=${encodeURIComponent(label)}&limit=5`);
|
||||
const word = Array.isArray(words) && words.find(w =>
|
||||
(w.titel_de || '').toLowerCase() === label ||
|
||||
(w.titel_en || '').toLowerCase() === label
|
||||
);
|
||||
if (word) assignments[word.id] = objId;
|
||||
} catch { /* ignore */ }
|
||||
}));
|
||||
if (Object.keys(assignments).length) setObjectAssignments(assignments);
|
||||
}
|
||||
} catch (e) { console.error(e); }
|
||||
finally { setLoading(false); }
|
||||
}
|
||||
@@ -564,17 +576,6 @@ function EditPairForm({ pair, allObjects, onSaved, onCancel, onDeleted }) {
|
||||
}
|
||||
});
|
||||
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 */ }
|
||||
}, 600);
|
||||
return () => clearTimeout(t);
|
||||
|
||||
Reference in New Issue
Block a user