aktive/inaktiv list templates
This commit is contained in:
@@ -1 +1 @@
|
|||||||
1.2.28
|
1.2.29
|
||||||
@@ -107,10 +107,16 @@ export function initEditor() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return async ({ title, text, confirmLabel = 'Bestätigen', cancelLabel = 'Abbrechen' }) => {
|
return async ({ title, text, html = false, confirmLabel = 'Bestätigen', cancelLabel = 'Abbrechen' }) => {
|
||||||
ensure();
|
ensure();
|
||||||
if (titleEl) titleEl.textContent = title || 'Bestätigung';
|
if (titleEl) titleEl.textContent = title || 'Bestätigung';
|
||||||
if (textEl) textEl.textContent = text || '';
|
if (textEl) {
|
||||||
|
if (html) {
|
||||||
|
textEl.innerHTML = text || '';
|
||||||
|
} else {
|
||||||
|
textEl.textContent = text || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
if (btnOk) btnOk.textContent = confirmLabel;
|
if (btnOk) btnOk.textContent = confirmLabel;
|
||||||
if (btnCancel) btnCancel.textContent = cancelLabel;
|
if (btnCancel) btnCancel.textContent = cancelLabel;
|
||||||
if (!dialog.open) dialog.showModal();
|
if (!dialog.open) dialog.showModal();
|
||||||
@@ -120,6 +126,24 @@ export function initEditor() {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
function formatReferencesHtml(refs = []) {
|
||||||
|
if (!refs.length) return '';
|
||||||
|
const lines = refs.map(ref => {
|
||||||
|
const name = String(ref.name || 'Template')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
|
const id = Number(ref.id || 0);
|
||||||
|
const versions = Array.isArray(ref.versions) && ref.versions.length
|
||||||
|
? ` – Versionen: ${ref.versions.join(', ')}`
|
||||||
|
: '';
|
||||||
|
return `• ${name} #${id}${versions}`;
|
||||||
|
});
|
||||||
|
return lines.join('<br>');
|
||||||
|
}
|
||||||
|
|
||||||
// ---------- Hilfen ----------
|
// ---------- Hilfen ----------
|
||||||
function activeMode() {
|
function activeMode() {
|
||||||
const activeSection = window.__activeSection || current?.section || null;
|
const activeSection = window.__activeSection || current?.section || null;
|
||||||
@@ -1174,9 +1198,22 @@ export function initEditor() {
|
|||||||
if (!refs.length) return true;
|
if (!refs.length) return true;
|
||||||
const preview = refs.slice(0, 6).map(r => `${r.name || 'Template'} #${r.id}`).join(', ');
|
const preview = refs.slice(0, 6).map(r => `${r.name || 'Template'} #${r.id}`).join(', ');
|
||||||
const more = refs.length > 6 ? ` und ${refs.length - 6} weitere` : '';
|
const more = refs.length > 6 ? ` und ${refs.length - 6} weitere` : '';
|
||||||
|
const escPreview = preview
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
|
const escMore = more
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
return await showConfirmDialog({
|
return await showConfirmDialog({
|
||||||
title: 'Template wird verwendet',
|
title: 'Template wird verwendet',
|
||||||
text: `Dieses Template wird in ${refs.length} anderen Template(s) verwendet (${preview}${more}). ${actionLabel} trotzdem?`,
|
html: true,
|
||||||
|
text: `Dieses Template wird in ${refs.length} anderen Template(s) verwendet (${escPreview}${escMore}).<br>${formatReferencesHtml(refs)}<br>${actionLabel} trotzdem?`,
|
||||||
confirmLabel: actionLabel,
|
confirmLabel: actionLabel,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1211,9 +1248,11 @@ export function initEditor() {
|
|||||||
if (!okRefs) return;
|
if (!okRefs) return;
|
||||||
let res = await apiAction('content_versions.deactivate', { method: 'POST', data: { content_id: current.id } });
|
let res = await apiAction('content_versions.deactivate', { method: 'POST', data: { content_id: current.id } });
|
||||||
if (res && res.ok === false && Array.isArray(res.references) && res.references.length) {
|
if (res && res.ok === false && Array.isArray(res.references) && res.references.length) {
|
||||||
|
const refs = res.references || [];
|
||||||
const ok = await showConfirmDialog({
|
const ok = await showConfirmDialog({
|
||||||
title: 'Template wird verwendet',
|
title: 'Template wird verwendet',
|
||||||
text: 'Dieses Template wird in anderen Templates verwendet. Trotzdem deaktivieren?',
|
html: true,
|
||||||
|
text: `Dieses Template wird in anderen Templates verwendet.<br>${formatReferencesHtml(refs)}<br>Deaktivieren trotzdem?`,
|
||||||
confirmLabel: 'Deaktivieren',
|
confirmLabel: 'Deaktivieren',
|
||||||
});
|
});
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
|
|||||||
@@ -53,10 +53,16 @@ const showConfirmDialog = (() => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return async ({ title, text, confirmLabel = 'Bestätigen', cancelLabel = 'Abbrechen' }) => {
|
return async ({ title, text, html = false, confirmLabel = 'Bestätigen', cancelLabel = 'Abbrechen' }) => {
|
||||||
ensure();
|
ensure();
|
||||||
if (titleEl) titleEl.textContent = title || 'Bestätigung';
|
if (titleEl) titleEl.textContent = title || 'Bestätigung';
|
||||||
if (textEl) textEl.textContent = text || '';
|
if (textEl) {
|
||||||
|
if (html) {
|
||||||
|
textEl.innerHTML = text || '';
|
||||||
|
} else {
|
||||||
|
textEl.textContent = text || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
if (btnOk) btnOk.textContent = confirmLabel;
|
if (btnOk) btnOk.textContent = confirmLabel;
|
||||||
if (btnCancel) btnCancel.textContent = cancelLabel;
|
if (btnCancel) btnCancel.textContent = cancelLabel;
|
||||||
if (!dialog.open) dialog.showModal();
|
if (!dialog.open) dialog.showModal();
|
||||||
@@ -66,6 +72,19 @@ const showConfirmDialog = (() => {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
function formatReferencesHtml(refs = []) {
|
||||||
|
if (!refs.length) return '';
|
||||||
|
const lines = refs.map(ref => {
|
||||||
|
const name = esc(ref.name || 'Template');
|
||||||
|
const id = Number(ref.id || 0);
|
||||||
|
const versions = Array.isArray(ref.versions) && ref.versions.length
|
||||||
|
? ` – Versionen: ${ref.versions.join(', ')}`
|
||||||
|
: '';
|
||||||
|
return `• ${name} #${id}${versions}`;
|
||||||
|
});
|
||||||
|
return lines.join('<br>');
|
||||||
|
}
|
||||||
|
|
||||||
function formatVersionDate(value) {
|
function formatVersionDate(value) {
|
||||||
if (!value) return '';
|
if (!value) return '';
|
||||||
try {
|
try {
|
||||||
@@ -173,7 +192,8 @@ async function openTemplateManager(item, section) {
|
|||||||
const more = refs.length > 6 ? ` und ${refs.length - 6} weitere` : '';
|
const more = refs.length > 6 ? ` und ${refs.length - 6} weitere` : '';
|
||||||
return await showConfirmDialog({
|
return await showConfirmDialog({
|
||||||
title: 'Template wird verwendet',
|
title: 'Template wird verwendet',
|
||||||
text: `Dieses Template wird in ${refs.length} anderen Template(s) verwendet (${preview}${more}). ${actionLabel} trotzdem?`,
|
html: true,
|
||||||
|
text: `Dieses Template wird in ${refs.length} anderen Template(s) verwendet (${esc(preview)}${esc(more)}).<br>${formatReferencesHtml(refs)}<br>${esc(actionLabel)} trotzdem?`,
|
||||||
confirmLabel: actionLabel,
|
confirmLabel: actionLabel,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -327,9 +347,11 @@ async function openTemplateManager(item, section) {
|
|||||||
}
|
}
|
||||||
let res = await apiAction('content_versions.deactivate', { method: 'POST', data: { content_id: item.id } });
|
let res = await apiAction('content_versions.deactivate', { method: 'POST', data: { content_id: item.id } });
|
||||||
if (res && res.ok === false && Array.isArray(res.references) && res.references.length) {
|
if (res && res.ok === false && Array.isArray(res.references) && res.references.length) {
|
||||||
|
const refs = res.references || [];
|
||||||
const ok = await showConfirmDialog({
|
const ok = await showConfirmDialog({
|
||||||
title: 'Template wird verwendet',
|
title: 'Template wird verwendet',
|
||||||
text: 'Dieses Template wird in anderen Templates verwendet. Trotzdem deaktivieren?',
|
html: true,
|
||||||
|
text: `Dieses Template wird in anderen Templates verwendet.<br>${formatReferencesHtml(refs)}<br>Deaktivieren trotzdem?`,
|
||||||
confirmLabel: 'Deaktivieren',
|
confirmLabel: 'Deaktivieren',
|
||||||
});
|
});
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
@@ -346,9 +368,11 @@ async function openTemplateManager(item, section) {
|
|||||||
if (!confirm('Version wirklich löschen?')) return;
|
if (!confirm('Version wirklich löschen?')) return;
|
||||||
let res = await apiAction('content_versions.delete', { method: 'POST', data: { id: vid, content_id: item.id } });
|
let res = await apiAction('content_versions.delete', { method: 'POST', data: { id: vid, content_id: item.id } });
|
||||||
if (res && res.ok === false && Array.isArray(res.references) && res.references.length) {
|
if (res && res.ok === false && Array.isArray(res.references) && res.references.length) {
|
||||||
|
const refs = res.references || [];
|
||||||
const ok = await showConfirmDialog({
|
const ok = await showConfirmDialog({
|
||||||
title: 'Template wird verwendet',
|
title: 'Template wird verwendet',
|
||||||
text: 'Dieses Template wird in anderen Templates verwendet. Trotzdem löschen?',
|
html: true,
|
||||||
|
text: `Dieses Template wird in anderen Templates verwendet.<br>${formatReferencesHtml(refs)}<br>Löschen trotzdem?`,
|
||||||
confirmLabel: 'Löschen',
|
confirmLabel: 'Löschen',
|
||||||
});
|
});
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
|
|||||||
@@ -2337,7 +2337,7 @@ class ApiKernel
|
|||||||
private function findTemplateReferences(int $customerId, int $templateId, array &$debug = []): array
|
private function findTemplateReferences(int $customerId, int $templateId, array &$debug = []): array
|
||||||
{
|
{
|
||||||
$out = [];
|
$out = [];
|
||||||
$seen = [];
|
$byId = [];
|
||||||
$debug = [
|
$debug = [
|
||||||
'time' => date(DATE_ATOM),
|
'time' => date(DATE_ATOM),
|
||||||
'customer_id' => $customerId,
|
'customer_id' => $customerId,
|
||||||
@@ -2347,6 +2347,31 @@ class ApiKernel
|
|||||||
'matched_rows' => [],
|
'matched_rows' => [],
|
||||||
'template_items_matches' => [],
|
'template_items_matches' => [],
|
||||||
];
|
];
|
||||||
|
$addRef = function (int $id, string $name) use (&$out, &$byId) {
|
||||||
|
if ($id <= 0) return;
|
||||||
|
if (!isset($byId[$id])) {
|
||||||
|
$entry = [
|
||||||
|
'id' => $id,
|
||||||
|
'name' => $name,
|
||||||
|
'versions' => [],
|
||||||
|
];
|
||||||
|
$byId[$id] = count($out);
|
||||||
|
$out[] = $entry;
|
||||||
|
} elseif ($name !== '') {
|
||||||
|
$out[$byId[$id]]['name'] = $name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$addVersion = function (int $id, ?int $ver) use (&$out, &$byId) {
|
||||||
|
if ($id <= 0 || $ver === null || $ver <= 0) return;
|
||||||
|
if (!isset($byId[$id])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$idx = $byId[$id];
|
||||||
|
if (!in_array($ver, $out[$idx]['versions'], true)) {
|
||||||
|
$out[$idx]['versions'][] = $ver;
|
||||||
|
sort($out[$idx]['versions']);
|
||||||
|
}
|
||||||
|
};
|
||||||
$matches = function (?string $html, array $libKinds = []) use ($templateId): bool {
|
$matches = function (?string $html, array $libKinds = []) use ($templateId): bool {
|
||||||
if (!$html) return false;
|
if (!$html) return false;
|
||||||
$id = preg_quote((string)$templateId, '/');
|
$id = preg_quote((string)$templateId, '/');
|
||||||
@@ -2463,12 +2488,8 @@ class ApiKernel
|
|||||||
}
|
}
|
||||||
if ($found) {
|
if ($found) {
|
||||||
$id = (int)($row['id'] ?? 0);
|
$id = (int)($row['id'] ?? 0);
|
||||||
if ($id <= 0 || isset($seen[$id])) continue;
|
if ($id <= 0) continue;
|
||||||
$seen[$id] = true;
|
$addRef($id, (string)($row['name'] ?? ''));
|
||||||
$out[] = [
|
|
||||||
'id' => $id,
|
|
||||||
'name' => (string)($row['name'] ?? ''),
|
|
||||||
];
|
|
||||||
if (count($debug['matched_rows']) < 50) {
|
if (count($debug['matched_rows']) < 50) {
|
||||||
$debug['matched_rows'][] = [
|
$debug['matched_rows'][] = [
|
||||||
'id' => $id,
|
'id' => $id,
|
||||||
@@ -2478,6 +2499,62 @@ class ApiKernel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->tableExists($versionsTable)) {
|
||||||
|
$vCols = $this->tableColumns($versionsTable);
|
||||||
|
$vHtml = $versionHtmlCol;
|
||||||
|
$vJson = $versionJsonCol;
|
||||||
|
$vCraft = $versionCraftCol;
|
||||||
|
$vSettings = $versionSettingsCol;
|
||||||
|
$vNo = $this->firstExisting($vCols, ['version_no', 'version', 'ver', 'version_nr']);
|
||||||
|
$vContentId = $this->firstExisting($vCols, ['content_id', 'content']);
|
||||||
|
$vCustomerId = $this->firstExisting($vCols, ['customer_id', 'customer']);
|
||||||
|
$vSectionId = $this->firstExisting($vCols, ['section_id', 'section']);
|
||||||
|
if ($vContentId && $vNo) {
|
||||||
|
$select = "v.`$vContentId` AS content_id, v.`$vNo` AS version_no, i.`name` AS name";
|
||||||
|
if ($vHtml) $select .= ", v.`$vHtml` AS version_html";
|
||||||
|
if ($vJson) $select .= ", v.`$vJson` AS version_json";
|
||||||
|
if ($vCraft) $select .= ", v.`$vCraft` AS version_craft";
|
||||||
|
if ($vSettings) $select .= ", v.`$vSettings` AS version_settings";
|
||||||
|
$join = "LEFT JOIN `$itemsTable` i ON i.`id` = v.`$vContentId`";
|
||||||
|
$where = [];
|
||||||
|
$params = [];
|
||||||
|
if ($vCustomerId) {
|
||||||
|
$where[] = "v.`$vCustomerId` = :cid";
|
||||||
|
$params[':cid'] = $customerId;
|
||||||
|
}
|
||||||
|
if ($vSectionId) {
|
||||||
|
$where[] = "v.`$vSectionId` = :sid";
|
||||||
|
$params[':sid'] = (int)$section['id'];
|
||||||
|
}
|
||||||
|
$where[] = "v.`$vContentId` <> :id";
|
||||||
|
$params[':id'] = $templateId;
|
||||||
|
$sql = "SELECT $select FROM `$versionsTable` v $join WHERE " . implode(' AND ', $where);
|
||||||
|
$stmt = $this->pdo->prepare($sql);
|
||||||
|
$stmt->execute($params);
|
||||||
|
$rows = $stmt->fetchAll() ?: [];
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$blobs = [
|
||||||
|
(string)($row['version_html'] ?? ''),
|
||||||
|
(string)($row['version_json'] ?? ''),
|
||||||
|
(string)($row['version_craft'] ?? ''),
|
||||||
|
(string)($row['version_settings'] ?? ''),
|
||||||
|
];
|
||||||
|
$found = false;
|
||||||
|
foreach ($blobs as $blob) {
|
||||||
|
if ($matches($blob, $libKinds)) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($found) {
|
||||||
|
$cid = (int)($row['content_id'] ?? 0);
|
||||||
|
$addRef($cid, (string)($row['name'] ?? ''));
|
||||||
|
$addVersion($cid, (int)($row['version_no'] ?? 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!$this->useUnifiedContent()) {
|
if (!$this->useUnifiedContent()) {
|
||||||
$table = $this->tableMap['templates'] ?? null;
|
$table = $this->tableMap['templates'] ?? null;
|
||||||
@@ -2520,12 +2597,8 @@ class ApiKernel
|
|||||||
}
|
}
|
||||||
if ($found) {
|
if ($found) {
|
||||||
$id = (int)($row['id'] ?? 0);
|
$id = (int)($row['id'] ?? 0);
|
||||||
if ($id <= 0 || isset($seen[$id])) continue;
|
if ($id <= 0) continue;
|
||||||
$seen[$id] = true;
|
$addRef($id, (string)($row['name'] ?? ''));
|
||||||
$out[] = [
|
|
||||||
'id' => $id,
|
|
||||||
'name' => (string)($row['name'] ?? ''),
|
|
||||||
];
|
|
||||||
if (count($debug['matched_rows']) < 50) {
|
if (count($debug['matched_rows']) < 50) {
|
||||||
$debug['matched_rows'][] = [
|
$debug['matched_rows'][] = [
|
||||||
'id' => $id,
|
'id' => $id,
|
||||||
@@ -2559,12 +2632,8 @@ class ApiKernel
|
|||||||
$rows = $stmt->fetchAll() ?: [];
|
$rows = $stmt->fetchAll() ?: [];
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$id = (int)($row['id'] ?? 0);
|
$id = (int)($row['id'] ?? 0);
|
||||||
if ($id <= 0 || isset($seen[$id])) continue;
|
if ($id <= 0) continue;
|
||||||
$seen[$id] = true;
|
$addRef($id, (string)($row['name'] ?? ''));
|
||||||
$out[] = [
|
|
||||||
'id' => $id,
|
|
||||||
'name' => (string)($row['name'] ?? ''),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2588,12 +2657,8 @@ class ApiKernel
|
|||||||
$rows = $stmt->fetchAll() ?: [];
|
$rows = $stmt->fetchAll() ?: [];
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$id = (int)($row['id'] ?? 0);
|
$id = (int)($row['id'] ?? 0);
|
||||||
if ($id <= 0 || isset($seen[$id])) continue;
|
if ($id <= 0) continue;
|
||||||
$seen[$id] = true;
|
$addRef($id, (string)($row['name'] ?? ''));
|
||||||
$out[] = [
|
|
||||||
'id' => $id,
|
|
||||||
'name' => (string)($row['name'] ?? ''),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user