322 lines
9.6 KiB
JavaScript
322 lines
9.6 KiB
JavaScript
/**
|
|
* DNS Template Selector
|
|
* Presents DNS server template options when user chooses to set up DNS
|
|
*/
|
|
|
|
(function(window) {
|
|
'use strict';
|
|
|
|
class DnsTemplateSelector {
|
|
constructor(progressTracker) {
|
|
this.progressTracker = progressTracker;
|
|
this.modal = null;
|
|
this.onTemplateSelected = null;
|
|
console.log('[DnsTemplateSelector] Module loaded');
|
|
}
|
|
|
|
/**
|
|
* Get available DNS server templates from app templates
|
|
* @returns {Array} Array of DNS template objects
|
|
*/
|
|
getDnsTemplates() {
|
|
// In a real implementation, this would fetch from app-templates.js
|
|
// For now, return hardcoded templates matching what we added
|
|
return [
|
|
{
|
|
id: 'technitium',
|
|
name: 'Technitium DNS Server',
|
|
description: 'Modern DNS server with web UI for managing private zones',
|
|
icon: '🌐',
|
|
difficulty: 'Easy',
|
|
features: [
|
|
'Web-based management interface',
|
|
'Private zone management for .sami domain',
|
|
'DHCP server integration',
|
|
'DNS-over-HTTPS and DNS-over-TLS support'
|
|
],
|
|
recommended: true
|
|
},
|
|
{
|
|
id: 'bind9',
|
|
name: 'BIND9 DNS Server',
|
|
description: 'Industry-standard DNS server - powerful and flexible',
|
|
icon: '🔧',
|
|
difficulty: 'Advanced',
|
|
features: [
|
|
'Industry standard DNS server',
|
|
'Full RFC compliance',
|
|
'Advanced zone management',
|
|
'DNSSEC support'
|
|
],
|
|
recommended: false
|
|
},
|
|
{
|
|
id: 'pihole',
|
|
name: 'Pi-hole',
|
|
description: 'Network-wide ad blocker with DNS capabilities',
|
|
icon: '🛡️',
|
|
difficulty: 'Intermediate',
|
|
features: [
|
|
'Ad blocking at DNS level',
|
|
'Web interface for management',
|
|
'DHCP server included',
|
|
'Query logging and statistics'
|
|
],
|
|
recommended: false
|
|
},
|
|
{
|
|
id: 'powerdns',
|
|
name: 'PowerDNS',
|
|
description: 'High-performance DNS server with SQL backend',
|
|
icon: '⚡',
|
|
difficulty: 'Intermediate',
|
|
features: [
|
|
'SQL database backend',
|
|
'RESTful API for automation',
|
|
'Geographic load balancing',
|
|
'DNSSEC support'
|
|
],
|
|
recommended: false
|
|
},
|
|
{
|
|
id: 'coredns',
|
|
name: 'CoreDNS',
|
|
description: 'Cloud-native DNS server - lightweight and flexible',
|
|
icon: '☁️',
|
|
difficulty: 'Intermediate',
|
|
features: [
|
|
'Plugin-based architecture',
|
|
'Kubernetes-native',
|
|
'Lightweight and fast',
|
|
'Prometheus metrics'
|
|
],
|
|
recommended: false
|
|
}
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Show DNS template selection modal
|
|
*/
|
|
showTemplateSelector() {
|
|
// Create modal if it doesn't exist
|
|
if (!this.modal) {
|
|
this.createModal();
|
|
}
|
|
|
|
// Populate with templates
|
|
this.populateTemplates();
|
|
|
|
// Show modal
|
|
this.modal.style.display = 'flex';
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
|
|
/**
|
|
* Create the modal HTML structure
|
|
* @private
|
|
*/
|
|
createModal() {
|
|
const modal = document.createElement('div');
|
|
modal.id = 'dns-template-modal';
|
|
modal.className = 'dns-template-modal';
|
|
modal.innerHTML = `
|
|
<div class="dns-template-modal-content">
|
|
<div class="dns-template-header">
|
|
<h2>🌐 Choose a DNS Server</h2>
|
|
<p>Setting up a DNS server is essential for managing your private .sami domain</p>
|
|
<button class="dns-template-close" aria-label="Close">×</button>
|
|
</div>
|
|
<div class="dns-template-grid" id="dns-template-grid">
|
|
<!-- Templates will be inserted here -->
|
|
</div>
|
|
<div class="dns-template-footer">
|
|
<button class="dns-template-later-btn" id="dns-setup-later">Set up later</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
document.body.appendChild(modal);
|
|
this.modal = modal;
|
|
|
|
// Add event listeners
|
|
modal.querySelector('.dns-template-close').addEventListener('click', () => this.close());
|
|
modal.querySelector('#dns-setup-later').addEventListener('click', () => this.handleSetupLater());
|
|
|
|
// Close on overlay click
|
|
modal.addEventListener('click', (e) => {
|
|
if (e.target === modal) {
|
|
this.close();
|
|
}
|
|
});
|
|
|
|
// Close on Escape key
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape' && modal.style.display === 'flex') {
|
|
this.close();
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Populate modal with DNS templates
|
|
* @private
|
|
*/
|
|
populateTemplates() {
|
|
const grid = document.getElementById('dns-template-grid');
|
|
if (!grid) return;
|
|
|
|
const templates = this.getDnsTemplates();
|
|
grid.innerHTML = '';
|
|
|
|
templates.forEach(template => {
|
|
const card = this.createTemplateCard(template);
|
|
grid.appendChild(card);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Create a template card element
|
|
* @private
|
|
*/
|
|
createTemplateCard(template) {
|
|
const card = document.createElement('div');
|
|
card.className = 'dns-template-card';
|
|
if (template.recommended) {
|
|
card.classList.add('recommended');
|
|
}
|
|
|
|
const difficultyClass = template.difficulty.toLowerCase();
|
|
|
|
card.innerHTML = `
|
|
${template.recommended ? '<div class="recommended-badge">Recommended</div>' : ''}
|
|
<div class="dns-template-icon">${template.icon}</div>
|
|
<h3>${template.name}</h3>
|
|
<p class="dns-template-description">${template.description}</p>
|
|
<div class="dns-template-difficulty difficulty-${difficultyClass}">
|
|
${template.difficulty}
|
|
</div>
|
|
<ul class="dns-template-features">
|
|
${template.features.slice(0, 3).map(f => `<li>${f}</li>`).join('')}
|
|
</ul>
|
|
<button class="dns-template-select-btn" data-template-id="${template.id}">
|
|
Select ${template.name}
|
|
</button>
|
|
`;
|
|
|
|
// Add click handler to select button
|
|
const selectBtn = card.querySelector('.dns-template-select-btn');
|
|
selectBtn.addEventListener('click', () => this.handleTemplateSelection(template));
|
|
|
|
return card;
|
|
}
|
|
|
|
/**
|
|
* Handle template selection
|
|
* @private
|
|
*/
|
|
handleTemplateSelection(template) {
|
|
console.log(`[DnsTemplateSelector] Template selected: ${template.id}`);
|
|
|
|
// Close modal
|
|
this.close();
|
|
|
|
// Trigger callback if set
|
|
if (this.onTemplateSelected) {
|
|
this.onTemplateSelected(template);
|
|
} else {
|
|
// Default behavior: open app selector with DNS filter
|
|
this.openAppSelector(template.id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle "Set up later" button
|
|
* @private
|
|
*/
|
|
handleSetupLater() {
|
|
console.log('[DnsTemplateSelector] DNS setup deferred');
|
|
|
|
// Mark as deferred in progress tracker
|
|
if (this.progressTracker) {
|
|
this.progressTracker.markDnsSetupDeferred();
|
|
}
|
|
|
|
// Close modal
|
|
this.close();
|
|
|
|
// Show notification
|
|
this.showNotification('DNS setup deferred. You can set it up later from the App Selector.');
|
|
}
|
|
|
|
/**
|
|
* Open app selector with specific template
|
|
* @private
|
|
*/
|
|
openAppSelector(templateId) {
|
|
// Try to open the app selector modal if it exists
|
|
const appSelectorBtn = document.querySelector('[onclick*="showAppSelector"]');
|
|
if (appSelectorBtn) {
|
|
appSelectorBtn.click();
|
|
|
|
// Wait a bit then filter to the selected template
|
|
setTimeout(() => {
|
|
const searchInput = document.querySelector('#app-search');
|
|
if (searchInput) {
|
|
searchInput.value = templateId;
|
|
searchInput.dispatchEvent(new Event('input', { bubbles: true }));
|
|
}
|
|
}, 300);
|
|
} else {
|
|
// Fallback: show instructions
|
|
this.showNotification(`To deploy ${templateId}, use the App Selector and search for "${templateId}"`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show notification message
|
|
* @private
|
|
*/
|
|
showNotification(message) {
|
|
// Simple notification - could be enhanced
|
|
const notification = document.createElement('div');
|
|
notification.className = 'dns-template-notification';
|
|
notification.textContent = message;
|
|
notification.style.cssText = `
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
background: var(--card-base);
|
|
color: var(--fg);
|
|
padding: 15px 20px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
|
z-index: 10001;
|
|
max-width: 300px;
|
|
`;
|
|
|
|
document.body.appendChild(notification);
|
|
|
|
setTimeout(() => {
|
|
notification.style.opacity = '0';
|
|
notification.style.transition = 'opacity 0.3s';
|
|
setTimeout(() => notification.remove(), 300);
|
|
}, 3000);
|
|
}
|
|
|
|
/**
|
|
* Close the modal
|
|
*/
|
|
close() {
|
|
if (this.modal) {
|
|
this.modal.style.display = 'none';
|
|
document.body.style.overflow = '';
|
|
}
|
|
}
|
|
}
|
|
|
|
window.DnsTemplateSelector = DnsTemplateSelector;
|
|
console.log('[DnsTemplateSelector] Module loaded');
|
|
|
|
})(window);
|