This commit is contained in:
@ -49,6 +49,22 @@ export function translationFor(entry, lang) {
|
||||
return normalizeTranslations(entry.translations)[lang] || '';
|
||||
}
|
||||
|
||||
export function isEntryMissing(entry, lang) {
|
||||
return !translationFor(entry, lang).trim();
|
||||
}
|
||||
|
||||
export function countMissing(entries, lang) {
|
||||
return entries.filter(e => isEntryMissing(e, lang)).length;
|
||||
}
|
||||
|
||||
export function sectionEntries(allEntries, section) {
|
||||
let entries = allEntries.slice(section.startIdx, section.startIdx + section.entryCount);
|
||||
if (section.isApp) {
|
||||
entries = entries.filter(e => e.type === 'app_string');
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
export function targetLanguages(languages) {
|
||||
return (languages || []).filter(l => l.languageCode !== SOURCE_LANG);
|
||||
}
|
||||
@ -197,11 +213,11 @@ export function sourceLanguageLabel(languages) {
|
||||
return row?.name ? `${row.name} (${SOURCE_LANG})` : 'German';
|
||||
}
|
||||
|
||||
/** Column headers: Key | main language (German) | target language */
|
||||
/** Column headers: label | main language (German) | target language */
|
||||
export function translationListHeaderHTML(targetLangLabel, sourceLabel = 'German') {
|
||||
return `
|
||||
<div class="trans-list-header">
|
||||
<span class="trans-col-key">Key</span>
|
||||
<div class="trans-list-header trans-list-header-sticky">
|
||||
<span class="trans-col-key">Label</span>
|
||||
<span class="trans-col-source">${escHtml(sourceLabel)}</span>
|
||||
<span class="trans-col-target">${escHtml(targetLangLabel)}</span>
|
||||
</div>`;
|
||||
@ -220,12 +236,17 @@ export function translationRowHTML(entry, idx, { targetLang, editable = true })
|
||||
value="${escHtml(german)}" placeholder="German text…" autocomplete="off">`
|
||||
: `<span class="trans-source-text" title="${escHtml(german)}">${escHtml(german)}</span>`;
|
||||
|
||||
const germanPreview = german.length > 72 ? `${german.slice(0, 72)}…` : german;
|
||||
|
||||
return `
|
||||
<div class="trans-list-item ${missing ? 'trans-list-item-missing' : ''}"
|
||||
data-idx="${idx}" data-type="${entry.type}" data-key="${escHtml(lookupKey)}" data-label="${escHtml(label)}" data-missing="${missing ? '1' : '0'}">
|
||||
<div class="trans-list-key">
|
||||
${typeBadge(entry.type)}
|
||||
<span class="trans-key-text" title="${escHtml(lookupKey)}">${escHtml(label)}</span>
|
||||
<div class="trans-key-labels">
|
||||
<span class="trans-key-primary" title="${escHtml(german)}">${escHtml(germanPreview || label)}</span>
|
||||
<span class="trans-key-secondary" title="${escHtml(lookupKey)}">${escHtml(lookupKey)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="trans-list-source">${sourceCell}</div>
|
||||
<input type="text" class="trans-cell-input ${missing ? 'trans-input-missing' : ''}"
|
||||
@ -233,3 +254,32 @@ export function translationRowHTML(entry, idx, { targetLang, editable = true })
|
||||
placeholder="Translation…" ${disabled} autocomplete="off">
|
||||
</div>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grouped rows with collapsible sections and missing counts in summaries.
|
||||
*/
|
||||
export function renderCollapsibleGroupedTranslationsHTML(groups, targetLang, sourceLabel, editable, options = {}) {
|
||||
const { openGroupsWithMissing = false } = options;
|
||||
if (!groups.length) return '';
|
||||
|
||||
const body = groups.map(g => {
|
||||
const missing = g.items.filter(({ entry }) => isEntryMissing(entry, targetLang)).length;
|
||||
const total = g.items.length;
|
||||
const open = openGroupsWithMissing && missing > 0;
|
||||
const summary = missing
|
||||
? `${g.title} · ${missing} missing`
|
||||
: `${g.title} · complete (${total})`;
|
||||
|
||||
return `
|
||||
<details class="trans-group-details"${open ? ' open' : ''}>
|
||||
<summary class="trans-group-summary">${escHtml(summary)}</summary>
|
||||
<div class="trans-group-rows">
|
||||
${g.items.map(({ entry, idx }) =>
|
||||
translationRowHTML(entry, idx, { targetLang, editable })
|
||||
).join('')}
|
||||
</div>
|
||||
</details>`;
|
||||
}).join('');
|
||||
|
||||
return `<div class="trans-groups-flat">${body}</div>`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user