Upload folder using huggingface_hub
Browse files
client/src/components/Refinity.tsx
CHANGED
|
@@ -1096,7 +1096,7 @@ const Refinity: React.FC = () => {
|
|
| 1096 |
initialTranslation={taskVersions.find(v => v.id === currentVersionId)?.content || ''}
|
| 1097 |
onBack={()=>setStage('flow')}
|
| 1098 |
onSave={handleSaveRevision}
|
| 1099 |
-
onSaveEdit={(text)=>
|
| 1100 |
taskTitle={task?.title || 'Task'}
|
| 1101 |
username={username}
|
| 1102 |
nextVersionNumber={((versions.filter(v=>v.taskId===(task?.id||'')).slice(-1)[0]?.versionNumber) || 0) + 1}
|
|
@@ -1214,7 +1214,7 @@ const EditorPane: React.FC<{ source: string; initialTranslation: string; onBack:
|
|
| 1214 |
if (pos < start) html += escapeHtml(textValue.slice(pos, start));
|
| 1215 |
const cls = CATEGORY_CLASS[a.category] || 'bg-gray-100';
|
| 1216 |
const span = escapeHtml(textValue.slice(start, end)) || ' ';
|
| 1217 |
-
html += `<span data-anno-id="${a.id}" class="inline rounded-[4px] ${cls}
|
| 1218 |
pos = end;
|
| 1219 |
}
|
| 1220 |
if (pos < textValue.length) html += escapeHtml(textValue.slice(pos));
|
|
@@ -1288,6 +1288,14 @@ const EditorPane: React.FC<{ source: string; initialTranslation: string; onBack:
|
|
| 1288 |
return () => window.removeEventListener('resize', onResize);
|
| 1289 |
}, []);
|
| 1290 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1291 |
const save = async ()=>{
|
| 1292 |
setSaving(true);
|
| 1293 |
try {
|
|
@@ -1366,8 +1374,8 @@ const EditorPane: React.FC<{ source: string; initialTranslation: string; onBack:
|
|
| 1366 |
{/* Overlay highlights rendered above, but non-interactive; textarea handles selection */}
|
| 1367 |
<div
|
| 1368 |
ref={overlayRef}
|
| 1369 |
-
className="pointer-events-none absolute inset-0 rounded-lg px-4 py-3 whitespace-pre-wrap
|
| 1370 |
-
style={{ minHeight: textareaHeight, height: textareaHeight, maxHeight: textareaHeight,
|
| 1371 |
dangerouslySetInnerHTML={{ __html: renderAnnotatedHtml(text) }}
|
| 1372 |
/>
|
| 1373 |
<textarea
|
|
@@ -1391,7 +1399,7 @@ const EditorPane: React.FC<{ source: string; initialTranslation: string; onBack:
|
|
| 1391 |
}}
|
| 1392 |
onScroll={(e)=>{ const el = e.currentTarget; if (overlayRef.current) { overlayRef.current.style.transform = `translateY(-${el.scrollTop}px)`; } }}
|
| 1393 |
onKeyUp={updateSelectionPopover}
|
| 1394 |
-
className="relative z-
|
| 1395 |
style={{
|
| 1396 |
minHeight: textareaHeight,
|
| 1397 |
height: textareaHeight,
|
|
@@ -1399,7 +1407,7 @@ const EditorPane: React.FC<{ source: string; initialTranslation: string; onBack:
|
|
| 1399 |
resize: 'none',
|
| 1400 |
overflowY: 'auto',
|
| 1401 |
background: 'transparent',
|
| 1402 |
-
color: '
|
| 1403 |
caretColor: '#111827'
|
| 1404 |
}}
|
| 1405 |
/>
|
|
|
|
| 1096 |
initialTranslation={taskVersions.find(v => v.id === currentVersionId)?.content || ''}
|
| 1097 |
onBack={()=>setStage('flow')}
|
| 1098 |
onSave={handleSaveRevision}
|
| 1099 |
+
onSaveEdit={editingVersionId ? ((text)=>saveEditedVersion(editingVersionId, text)) : undefined}
|
| 1100 |
taskTitle={task?.title || 'Task'}
|
| 1101 |
username={username}
|
| 1102 |
nextVersionNumber={((versions.filter(v=>v.taskId===(task?.id||'')).slice(-1)[0]?.versionNumber) || 0) + 1}
|
|
|
|
| 1214 |
if (pos < start) html += escapeHtml(textValue.slice(pos, start));
|
| 1215 |
const cls = CATEGORY_CLASS[a.category] || 'bg-gray-100';
|
| 1216 |
const span = escapeHtml(textValue.slice(start, end)) || ' ';
|
| 1217 |
+
html += `<span data-anno-id="${a.id}" class="inline rounded-[4px] ${cls}" title="${a.category}${a.comment ? ': '+escapeHtml(a.comment) : ''}">${span}</span>`;
|
| 1218 |
pos = end;
|
| 1219 |
}
|
| 1220 |
if (pos < textValue.length) html += escapeHtml(textValue.slice(pos));
|
|
|
|
| 1288 |
return () => window.removeEventListener('resize', onResize);
|
| 1289 |
}, []);
|
| 1290 |
|
| 1291 |
+
// Keep overlay aligned with textarea scroll position across renders/toggles
|
| 1292 |
+
React.useLayoutEffect(() => {
|
| 1293 |
+
const ta = taRef.current;
|
| 1294 |
+
const ov = overlayRef.current;
|
| 1295 |
+
if (!ta || !ov) return;
|
| 1296 |
+
ov.style.transform = `translateY(-${ta.scrollTop}px)`;
|
| 1297 |
+
}, [showAnnotations, text, textareaHeight, isFullscreen]);
|
| 1298 |
+
|
| 1299 |
const save = async ()=>{
|
| 1300 |
setSaving(true);
|
| 1301 |
try {
|
|
|
|
| 1374 |
{/* Overlay highlights rendered above, but non-interactive; textarea handles selection */}
|
| 1375 |
<div
|
| 1376 |
ref={overlayRef}
|
| 1377 |
+
className="pointer-events-none select-none absolute inset-0 rounded-lg px-4 py-3 whitespace-pre-wrap overflow-visible z-10 text-base leading-relaxed will-change-transform font-sans tracking-normal"
|
| 1378 |
+
style={{ minHeight: textareaHeight, height: textareaHeight, maxHeight: textareaHeight, opacity: showAnnotations ? 1 : 0, color: 'transparent' }}
|
| 1379 |
dangerouslySetInnerHTML={{ __html: renderAnnotatedHtml(text) }}
|
| 1380 |
/>
|
| 1381 |
<textarea
|
|
|
|
| 1399 |
}}
|
| 1400 |
onScroll={(e)=>{ const el = e.currentTarget; if (overlayRef.current) { overlayRef.current.style.transform = `translateY(-${el.scrollTop}px)`; } }}
|
| 1401 |
onKeyUp={updateSelectionPopover}
|
| 1402 |
+
className="relative z-0 w-full px-4 py-3 border border-ui-border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white text-base leading-relaxed font-sans tracking-normal"
|
| 1403 |
style={{
|
| 1404 |
minHeight: textareaHeight,
|
| 1405 |
height: textareaHeight,
|
|
|
|
| 1407 |
resize: 'none',
|
| 1408 |
overflowY: 'auto',
|
| 1409 |
background: 'transparent',
|
| 1410 |
+
color: '#111827' as any,
|
| 1411 |
caretColor: '#111827'
|
| 1412 |
}}
|
| 1413 |
/>
|