Skip to content

Commit 4635248

Browse files
committed
changes in the ui
1 parent c5c8bf7 commit 4635248

1 file changed

Lines changed: 152 additions & 29 deletions

File tree

api/ui.py

Lines changed: 152 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,12 @@ async def serve_ui():
359359
font-size:10px;font-weight:600;margin-right:6px;
360360
background:rgba(159,122,234,0.15);color:var(--accent-purple);
361361
}
362+
.title-lang-item{
363+
margin-bottom:4px;
364+
}
365+
.title-lang-item:last-child{
366+
margin-bottom:0;
367+
}
362368
.ctx-search-no-results{
363369
padding:12px;text-align:center;font-size:12px;color:var(--text-muted);
364370
}
@@ -854,7 +860,12 @@ async def serve_ui():
854860
let type = 'content';
855861
if (c.pecha_text_id) type = 'search';
856862
else if (c.file_url) type = 'file';
857-
addContextEntry(type, {content: c.content, file_url: c.file_url, pecha_title: c.pecha_title, pecha_text_id: c.pecha_text_id});
863+
addContextEntry(type, {
864+
content: c.content,
865+
file_url: c.file_url,
866+
pecha_title: c.pecha_title,
867+
pecha_text_id: c.pecha_text_id
868+
});
858869
});
859870
}
860871
document.getElementById('modalOverlay').classList.add('active');
@@ -920,6 +931,20 @@ async def serve_ui():
920931
renderFileField(fieldArea, data.file_url || '');
921932
} else if (selectedType === 'search') {
922933
renderSearchField(fieldArea, data.pecha_title || '', data.pecha_text_id || '');
934+
// If editing and has content, create a mock search result with the content
935+
if (data.content && data.pecha_title && data.pecha_text_id) {
936+
const contentDataScript = document.createElement('script');
937+
contentDataScript.type = 'application/json';
938+
contentDataScript.className = 'ctx-pecha-content-data';
939+
// Create a single item array with the content
940+
contentDataScript.textContent = JSON.stringify([{
941+
id: data.pecha_text_id,
942+
content: data.content,
943+
type: 'text',
944+
source: 'pecha'
945+
}]);
946+
fieldArea.appendChild(contentDataScript);
947+
}
923948
}
924949
}
925950
@@ -1026,7 +1051,7 @@ async def serve_ui():
10261051
`;
10271052
if (title && textId) {
10281053
const tagsDiv = container.querySelector('.pecha-tags');
1029-
addPechaTag(tagsDiv, container, title, textId);
1054+
addPechaTag(tagsDiv, container, title, textId, null);
10301055
}
10311056
}
10321057
@@ -1044,24 +1069,19 @@ async def serve_ui():
10441069
resultsDiv.innerHTML = '<div class="ctx-search-no-results"><span class="spinner"></span> Searching...</div>';
10451070
10461071
try {
1047-
const r = await fetch('https://search.buddhistai.tools/search', {
1048-
method: 'POST',
1049-
headers: {'Content-Type':'application/json'},
1050-
body: JSON.stringify({limit:10, query:query, return_text:true, search_type:'exact'})
1051-
});
1072+
const r = await fetch('https://api-aq25662yyq-uc.a.run.app/v2/texts?limit=20&offset=0&title=' + encodeURIComponent(query));
10521073
if (!r.ok) throw new Error('Search failed');
1053-
const data = await r.json();
1054-
const results = data.results || [];
1074+
const results = await r.json();
10551075
if (!results.length) {
10561076
resultsDiv.innerHTML = '<div class="ctx-search-no-results">No results found</div>';
10571077
} else {
1058-
results.forEach(item => { _searchResultsCache[item.id] = item.entity?.text || ''; });
10591078
resultsDiv.innerHTML = results.map(item => {
1060-
const text = item.entity?.text || '';
1061-
const lang = item.entity?.language || '';
1062-
const displayText = text.length > 150 ? text.slice(0,150) + '...' : text;
1079+
const title = item.title || {};
1080+
const titleTexts = Object.entries(title).map(([lang, text]) =>
1081+
'<div class="title-lang-item"><span class="result-lang">' + esc(lang) + '</span>: ' + esc(text.length > 100 ? text.slice(0,100) + '...' : text) + '</div>'
1082+
).join('');
10631083
return '<div class="ctx-search-result-item" data-result-id="' + esc(item.id) + '" onclick="selectSearchResult(this)">'
1064-
+ '<span class="result-lang">' + esc(lang) + '</span>' + esc(displayText)
1084+
+ titleTexts
10651085
+ '</div>';
10661086
}).join('');
10671087
}
@@ -1073,29 +1093,89 @@ async def serve_ui():
10731093
}
10741094
}
10751095
1076-
function selectSearchResult(el) {
1096+
async function selectSearchResult(el) {
10771097
const id = el.getAttribute('data-result-id');
1078-
const fullText = _searchResultsCache[id] || '';
10791098
const entry = el.closest('.context-entry');
10801099
const fieldArea = entry.querySelector('.ctx-field-area');
10811100
const tagsDiv = fieldArea.querySelector('.pecha-tags');
10821101
const titleInput = fieldArea.querySelector('.ctx-pecha-title');
10831102
const idInput = fieldArea.querySelector('.ctx-pecha-text-id');
10841103
const resultsDiv = entry.querySelector('.ctx-search-results');
10851104
1086-
const displayTitle = fullText.length > 80 ? fullText.slice(0,80) + '...' : fullText;
1087-
titleInput.value = displayTitle;
1088-
idInput.value = id;
1089-
resultsDiv.style.display = 'none';
1090-
1091-
tagsDiv.innerHTML = '';
1092-
addPechaTag(tagsDiv, fieldArea, displayTitle, id);
1105+
const titleText = el.textContent.trim();
1106+
const displayTitle = titleText.length > 80 ? titleText.slice(0,80) + '...' : titleText;
1107+
1108+
// Show loading state
1109+
el.innerHTML = '<span class="spinner" style="width:12px;height:12px;border-width:2px"></span> Loading content...';
1110+
el.style.pointerEvents = 'none';
1111+
1112+
try {
1113+
// Call the search endpoint to fetch content
1114+
const r = await fetch(API_BASE + '/search/' + encodeURIComponent(id));
1115+
if (!r.ok) throw new Error('Failed to fetch content');
1116+
const searchData = await r.json();
1117+
1118+
// Store both the title and the fetched content
1119+
titleInput.value = displayTitle;
1120+
idInput.value = id;
1121+
1122+
// Store content data as JSON in a script tag to avoid HTML escaping issues
1123+
let contentScript = fieldArea.querySelector('.ctx-pecha-content-data');
1124+
if (!contentScript) {
1125+
contentScript = document.createElement('script');
1126+
contentScript.type = 'application/json';
1127+
contentScript.className = 'ctx-pecha-content-data';
1128+
fieldArea.appendChild(contentScript);
1129+
}
1130+
contentScript.textContent = JSON.stringify(searchData || []);
1131+
1132+
resultsDiv.style.display = 'none';
1133+
tagsDiv.innerHTML = '';
1134+
addPechaTag(tagsDiv, fieldArea, displayTitle, id, searchData);
1135+
1136+
toast('Content loaded successfully! (' + (searchData?.length || 0) + ' items)', 'success');
1137+
} catch(e) {
1138+
toast('Error loading content: ' + e.message, 'error');
1139+
el.innerHTML = displayTitle;
1140+
el.style.pointerEvents = '';
1141+
}
10931142
}
10941143
1095-
function addPechaTag(tagsDiv, fieldArea, title, id) {
1096-
const tag = document.createElement('span');
1097-
tag.className = 'pecha-tag';
1098-
tag.innerHTML = `<span class="pecha-tag-text">${esc(title)}</span><button class="pecha-tag-remove" onclick="removePechaTag(this)">&times;</button>`;
1144+
function addPechaTag(tagsDiv, fieldArea, title, id, searchData) {
1145+
const tag = document.createElement('div');
1146+
tag.style.cssText = 'margin-top:8px';
1147+
1148+
// Add main tag
1149+
tag.innerHTML = `
1150+
<div class="pecha-tag">
1151+
<span class="pecha-tag-text">${esc(title)}</span>
1152+
<button class="pecha-tag-remove" onclick="removePechaTag(this)">&times;</button>
1153+
</div>
1154+
`;
1155+
1156+
// If we have search data, show the content items
1157+
if (searchData && searchData.length > 0) {
1158+
const contentList = document.createElement('div');
1159+
contentList.style.cssText = 'margin-top:8px;display:flex;flex-direction:column;gap:8px';
1160+
1161+
searchData.forEach((item, idx) => {
1162+
const contentPreview = (item.content || '').substring(0, 150);
1163+
const itemDiv = document.createElement('div');
1164+
itemDiv.style.cssText = 'padding:8px 10px;background:var(--bg-input);border:1px solid var(--border);border-radius:var(--radius-xs);font-size:12px';
1165+
itemDiv.innerHTML = `
1166+
<div style="font-weight:600;color:var(--accent-purple);margin-bottom:4px">
1167+
${esc(item.type || 'Content')} - ${esc(item.source || 'Unknown')}
1168+
</div>
1169+
<div style="color:var(--text-secondary);line-height:1.5">
1170+
${esc(contentPreview)}${contentPreview.length >= 150 ? '...' : ''}
1171+
</div>
1172+
`;
1173+
contentList.appendChild(itemDiv);
1174+
});
1175+
1176+
tag.appendChild(contentList);
1177+
}
1178+
10991179
tagsDiv.appendChild(tag);
11001180
}
11011181
@@ -1104,7 +1184,18 @@ async def serve_ui():
11041184
const fieldArea = entry.querySelector('.ctx-field-area');
11051185
fieldArea.querySelector('.ctx-pecha-title').value = '';
11061186
fieldArea.querySelector('.ctx-pecha-text-id').value = '';
1107-
btn.closest('.pecha-tag').remove();
1187+
1188+
// Remove the content data script if it exists
1189+
const contentDataScript = fieldArea.querySelector('.ctx-pecha-content-data');
1190+
if (contentDataScript) {
1191+
contentDataScript.remove();
1192+
}
1193+
1194+
// Clear the pecha tags div
1195+
const tagsDiv = fieldArea.querySelector('.pecha-tags');
1196+
if (tagsDiv) {
1197+
tagsDiv.innerHTML = '';
1198+
}
11081199
}
11091200
11101201
function getContextsFromForm() {
@@ -1121,7 +1212,39 @@ async def serve_ui():
11211212
} else if (type === 'search') {
11221213
const pecha_title = e.querySelector('.ctx-pecha-title')?.value.trim();
11231214
const pecha_text_id = e.querySelector('.ctx-pecha-text-id')?.value.trim();
1124-
if (pecha_title && pecha_text_id) contexts.push({content:null, file_url:null, pecha_title, pecha_text_id});
1215+
const contentDataScript = e.querySelector('.ctx-pecha-content-data');
1216+
1217+
if (pecha_title && pecha_text_id) {
1218+
// Parse the stored JSON data
1219+
let searchData = [];
1220+
if (contentDataScript) {
1221+
try {
1222+
searchData = JSON.parse(contentDataScript.textContent || '[]');
1223+
} catch(err) {
1224+
console.error('Failed to parse search data', err);
1225+
}
1226+
}
1227+
1228+
// Create separate context entries for each search result
1229+
if (searchData.length > 0) {
1230+
searchData.forEach(item => {
1231+
contexts.push({
1232+
content: item.content || null,
1233+
file_url: null,
1234+
pecha_title: pecha_title,
1235+
pecha_text_id: pecha_text_id
1236+
});
1237+
});
1238+
} else {
1239+
// No content loaded yet, just store the metadata
1240+
contexts.push({
1241+
content: null,
1242+
file_url: null,
1243+
pecha_title: pecha_title,
1244+
pecha_text_id: pecha_text_id
1245+
});
1246+
}
1247+
}
11251248
}
11261249
});
11271250
return contexts;

0 commit comments

Comments
 (0)