This commit is contained in:
2025-12-07 01:20:22 +01:00
parent 5ffc000172
commit b18df2f206
2 changed files with 94 additions and 4 deletions

View File

@@ -1,5 +1,19 @@
import { apiList, apiGet, apiDelete, apiUpdate, toast } from './api.js'; import { apiList, apiGet, apiDelete, apiUpdate, toast } from './api.js';
function formatUsage(usage){
if (!usage || !usage.total) return '';
const parts=[];
if (usage.templates) parts.push(`${usage.templates} Template${usage.templates!==1?'s':''}`);
if (usage.sections) parts.push(`${usage.sections} Section${usage.sections!==1?'s':''}`);
if (usage.blocks) parts.push(`${usage.blocks} Block${usage.blocks!==1?'s':''}`);
if (usage.snippets) parts.push(`${usage.snippets} Snippet${usage.snippets!==1?'s':''}`);
if (!parts.length) return '';
return `<div class="mt-3 text-sm text-rose-600">
Dieses Element wird aktuell verwendet in: <strong>${parts.join(', ')}</strong>.<br>
Das Löschen entfernt diese Referenzen.
</div>`;
}
function esc(s=''){ function esc(s=''){
return String(s) return String(s)
.replace(/&/g,'&amp;') .replace(/&/g,'&amp;')
@@ -145,10 +159,16 @@ export async function loadList(resource){
let pending=null; let pending=null;
delCancel && (delCancel.onclick=()=>{pending=null;delDlg.close();}); delCancel && (delCancel.onclick=()=>{pending=null;delDlg.close();});
list.querySelectorAll('[data-del]').forEach(b=>b.addEventListener('click',()=>{ list.querySelectorAll('[data-del]').forEach(b=>b.addEventListener('click', async ()=>{
const [res,id]=b.dataset.del.split(':'); const nm=b.dataset.name||''; const [res,id]=b.dataset.del.split(':'); const nm=b.dataset.name||'';
pending={res,id,nm}; let usage = null;
delText && (delText.innerHTML=`Soll <strong>${nm || '(ohne Name)'} #${id}</strong> aus <strong>${res}</strong> wirklich gelöscht werden?<br><span class="text-rose-600">Achtung:</span> Kinder-Elemente werden <em>nicht</em> automatisch mit gelöscht.`); try {
const detail = await apiGet(res, id);
usage = detail?.usage || null;
} catch {}
pending={res,id,nm,usage};
const usageWarn = formatUsage(usage);
delText && (delText.innerHTML=`Soll <strong>${nm || '(ohne Name)'} #${id}</strong> aus <strong>${res}</strong> wirklich gelöscht werden?<br><span class="text-rose-600">Achtung:</span> Kinder-Elemente werden <em>nicht</em> automatisch mit gelöscht.${usageWarn}`);
delDlg.showModal(); delDlg.showModal();
})); }));

View File

@@ -392,6 +392,8 @@ class ApiKernel
$gjsComponents = $this->parseHtmlToGjsComponents($topHtml); $gjsComponents = $this->parseHtmlToGjsComponents($topHtml);
} }
$usage = $this->calculateUsage($kind, (int)$rowOut['id'], $auth);
$this->respond([ $this->respond([
'ok' => true, 'ok' => true,
'kind' => $kind, 'kind' => $kind,
@@ -400,7 +402,8 @@ class ApiKernel
'data' => $rowOut, 'data' => $rowOut,
'html' => $topHtml, 'html' => $topHtml,
'content' => $topContent, 'content' => $topContent,
'gjs_components' => $gjsComponents 'gjs_components' => $gjsComponents,
'usage' => $usage,
]); ]);
} }
@@ -680,3 +683,70 @@ class ApiKernel
} }
} }
} }
private function lookupTableName(string $key, string $default): string
{
$tables = $this->conf['tables'] ?? [];
if (!empty($tables[$key])) return $tables[$key];
$prefix = $this->conf['projectdb']['prefix'] ?? null;
if ($prefix && strpos($default, 'emailtemplate_') === 0) {
return $prefix . substr($default, strlen('emailtemplate_'));
}
return $default;
}
private function countRefsInTable(string $table, string $where, array $params, array $auth): int
{
try {
[$tw, $tp] = $this->tenantWhere($auth);
$sql = "SELECT COUNT(*) AS c FROM `$table` WHERE $where" . $tw;
$stmt = $this->pdo->prepare($sql);
foreach ($params as $k => $v) $stmt->bindValue($k, $v);
foreach ($tp as $k => $v) $stmt->bindValue($k, $v);
$stmt->execute();
$row = $stmt->fetch();
return (int)($row['c'] ?? 0);
} catch (Throwable $e) {
return 0;
}
}
private function calculateUsage(string $kind, int $id, array $auth): array
{
if ($id <= 0) return ['total' => 0];
$summary = [];
$templateItemsTable = $this->lookupTableName('template_items', 'emailtemplate_template_items');
$sectionItemsTable = $this->lookupTableName('section_items', 'emailtemplate_section_items');
if ($kind === 'sections') {
$summary['templates'] = $this->countRefsInTable(
$templateItemsTable,
"`ref_type` = :rt AND `ref_id` = :rid",
[':rt' => 'section', ':rid' => $id],
$auth
);
} elseif ($kind === 'blocks') {
$summary['templates'] = $this->countRefsInTable(
$templateItemsTable,
"`ref_type` = :rt AND `ref_id` = :rid",
[':rt' => 'block', ':rid' => $id],
$auth
);
$summary['sections'] = $this->countRefsInTable(
$sectionItemsTable,
"`ref_id` = :rid",
[':rid' => $id],
$auth
);
$summary['snippets'] = $this->countRefsInTable(
$this->tableMap['snippets'],
"`block_id` = :rid",
[':rid' => $id],
$auth
);
}
$summary = array_filter($summary, fn($v) => (int)$v > 0);
$summary['total'] = array_sum($summary);
return $summary;
}