OfficeServer/public/templates.html
dgsoft a01423321b Complete migration from docx-templates to docxtemplater
 Migration completed:
- server.js: Complete rewrite using docxtemplater + pizzip
- server-old.js: Backup of original docx-templates implementation
- package.json: Added docxtemplater and pizzip dependencies
- Removed docx-templates dependency

🚀 New features:
- True dynamic tables with {#array}{field}{/array} syntax
- Unlimited table rows (no more fixed array indices)
- New API endpoints: /analyze, /generate, /demo
- Simplified template creation scripts

🎯 Template improvements:
- Updated template syntax examples
- Added dynamic-template.docx with loop syntax
- Enhanced template analysis functionality

📊 Benefits:
- Real dynamic table generation
- Better template flexibility
- Cleaner API design
- Preserved SSL and WebDAV functionality
2025-10-01 22:14:19 +02:00

334 lines
11 KiB
HTML
Raw Blame History

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>📄 Template Management - DOCX Server</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
margin: 0;
font-size: 2.5em;
}
.header p {
margin: 10px 0 0 0;
opacity: 0.9;
}
.content {
padding: 30px;
}
.templates-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 20px;
margin-top: 20px;
}
.template-card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
background: #fafafa;
transition: transform 0.2s, box-shadow 0.2s;
}
.template-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
.template-name {
font-size: 1.2em;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.template-info {
color: #666;
font-size: 0.9em;
margin-bottom: 15px;
}
.action-buttons {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
text-decoration: none;
font-size: 0.9em;
transition: background-color 0.2s;
}
.btn-analyze {
background-color: #17a2b8;
color: white;
}
.btn-analyze:hover {
background-color: #138496;
}
.btn-test {
background-color: #28a745;
color: white;
}
.btn-test:hover {
background-color: #218838;
}
.btn-demo {
background-color: #ff6b35;
color: white;
font-weight: bold;
}
.btn-demo:hover {
background-color: #e55a2b;
}
.btn-word {
background-color: #0066cc;
color: white;
}
.btn-word:hover {
background-color: #0052a3;
}
.btn-webdav {
background-color: #6c757d;
color: white;
}
.btn-webdav:hover {
background-color: #5a6268;
}
.loading {
text-align: center;
padding: 40px;
color: #666;
}
.info-section {
background-color: #e3f2fd;
border-left: 4px solid #2196f3;
padding: 15px;
margin: 20px 0;
border-radius: 4px;
}
.refresh-btn {
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
margin-bottom: 20px;
}
.refresh-btn:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>📄 Template Management</h1>
<p>DOCX Template Server - Analyse, Test und Verwaltung</p>
</div>
<div class="content">
<button class="refresh-btn" onclick="loadTemplates()">🔄 Templates neu laden</button>
<div class="info-section">
<h3>🚀 Neue Features:</h3>
<ul>
<li><strong><EFBFBD> One-Click Demo:</strong> Analyse + Demo-Dokument in einem Schritt</li>
<li><strong><EFBFBD>📊 Analysieren:</strong> Alle Template-Tags automatisch erkennen</li>
<li><strong>🎲 Testen:</strong> Test-Dokument mit Zufallsdaten erstellen</li>
<li><strong>📝 MS Word:</strong> Direkt in Word öffnen und bearbeiten</li>
<li><strong>🌐 WebDAV:</strong> Browser-basierte Dateiverwaltung</li>
</ul>
</div>
<div id="loading" class="loading">
🔄 Lade Templates...
</div>
<div id="templates-container" style="display: none;">
<h2>📁 Verfügbare Templates (<span id="template-count">0</span>)</h2>
<div id="templates-grid" class="templates-grid">
</div>
</div>
</div>
</div>
<script>
async function loadTemplates() {
document.getElementById('loading').style.display = 'block';
document.getElementById('templates-container').style.display = 'none';
try {
const response = await fetch('/templates');
const data = await response.json();
document.getElementById('template-count').textContent = data.count;
const templatesGrid = document.getElementById('templates-grid');
templatesGrid.innerHTML = '';
data.templates.forEach(template => {
const card = createTemplateCard(template);
templatesGrid.appendChild(card);
});
document.getElementById('loading').style.display = 'none';
document.getElementById('templates-container').style.display = 'block';
} catch (error) {
document.getElementById('loading').innerHTML = '❌ Fehler beim Laden der Templates: ' + error.message;
}
}
function createTemplateCard(template) {
const card = document.createElement('div');
card.className = 'template-card';
const sizeKB = Math.round(template.size / 1024);
const modifiedDate = new Date(template.modified).toLocaleDateString('de-DE');
card.innerHTML = `
<div class="template-name">📄 ${template.name}</div>
<div class="template-info">
📊 Größe: ${sizeKB} KB<br>
📅 Geändert: ${modifiedDate}
</div>
<div class="action-buttons">
<button onclick="demoTemplate('${template.name}')" class="btn btn-demo">
🚀 Demo
</button>
<a href="${template.analyzeUrl}" target="_blank" class="btn btn-analyze">
📊 Analysieren
</a>
<button onclick="testTemplate('${template.name}')" class="btn btn-test">
🎲 Testen
</button>
<a href="${template.msWordUrl}" class="btn btn-word">
📝 In Word öffnen
</a>
<a href="${template.webdavUrl}" target="_blank" class="btn btn-webdav">
🌐 WebDAV
</a>
</div>
`;
return card;
}
async function demoTemplate(templateName) {
const rowCount = prompt('Anzahl Tabellenzeilen für Demo:', '3');
if (!rowCount) return;
try {
const response = await fetch(`/demo-template/${templateName}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ rowCount: parseInt(rowCount) })
});
const result = await response.json();
if (result.success) {
const message = `🚀 One-Click Demo erfolgreich erstellt!
📄 Template: ${result.templateInfo.name}
📊 Analyse-Ergebnis:
• Tags gefunden: ${result.tagAnalysis.totalTags}
• Einfache Tags: ${result.tagAnalysis.tagBreakdown.simple}
• Tabellen: ${result.tagAnalysis.tagBreakdown.tables}
📝 Demo-Dokument erstellt:
• Datei: ${result.demoDocument.filename}
• Tabellenzeilen: ${rowCount} pro Tabelle
🔗 Aktionen:
• Herunterladen: ${window.location.origin}${result.demoDocument.downloadUrl}
• In Word öffnen: ${result.demoDocument.msWordUrl}
• WebDAV: ${window.location.origin}${result.demoDocument.webdavUrl}
📋 Gefundene Tags: ${result.tagAnalysis.foundTags.join(', ')}`;
alert(message);
// Optional: Demo-Dokument direkt öffnen
if (confirm('Demo-Dokument jetzt in Word öffnen?')) {
window.location.href = result.demoDocument.msWordUrl;
}
} else {
alert('❌ Fehler: ' + result.error);
}
} catch (error) {
alert('❌ Fehler beim Erstellen der Demo: ' + error.message);
}
}
async function testTemplate(templateName) {
const rowCount = prompt('Anzahl Tabellenzeilen für Test:', '3');
if (!rowCount) return;
try {
const response = await fetch(`/test-template/${templateName}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ rowCount: parseInt(rowCount) })
});
const result = await response.json();
if (result.success) {
const message = `✅ Test-Dokument erstellt!
📄 Datei: ${result.templateName}
🏷️ Tags gefunden: ${result.foundTags.length}
📊 Tabellen: ${result.tableNames.length}
🔗 Aktionen:
• Herunterladen: ${window.location.origin}${result.downloadUrl}
• In Word öffnen: ${result.msWordUrl}
• WebDAV: ${window.location.origin}${result.webdavUrl}`;
alert(message);
// Optional: Test-Dokument direkt öffnen
if (confirm('Test-Dokument jetzt in Word öffnen?')) {
window.location.href = result.msWordUrl;
}
} else {
alert('❌ Fehler: ' + result.error);
}
} catch (error) {
alert('❌ Fehler beim Erstellen des Test-Dokuments: ' + error.message);
}
}
// Templates beim Laden der Seite laden
document.addEventListener('DOMContentLoaded', loadTemplates);
</script>
</body>
</html>