142 lines
4.8 KiB
JavaScript
142 lines
4.8 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
|
console.log('App script loaded.');
|
|
|
|
// Initialize Tiptap editor if element exists
|
|
const editorElement = document.getElementById('editor');
|
|
if (editorElement) {
|
|
initTiptapEditor(editorElement);
|
|
}
|
|
|
|
// Add Bootstrap tooltips
|
|
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
|
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
|
return new bootstrap.Tooltip(tooltipTriggerEl);
|
|
});
|
|
|
|
// Close flash messages after 5 seconds
|
|
setTimeout(function () {
|
|
var alerts = document.querySelectorAll('.alert:not(.alert-persistent)');
|
|
alerts.forEach(function (alert) {
|
|
var bsAlert = bootstrap.Alert.getInstance(alert);
|
|
if (bsAlert) {
|
|
bsAlert.close();
|
|
} else {
|
|
alert.classList.add('fade');
|
|
setTimeout(function () {
|
|
alert.remove();
|
|
}, 150);
|
|
}
|
|
});
|
|
}, 5000);
|
|
|
|
// Add event listener for subnet scan buttons with HTMX
|
|
document.body.addEventListener('htmx:afterOnLoad', function (event) {
|
|
if (event.detail.xhr.status === 200) {
|
|
showNotification('Subnet scan started successfully', 'success');
|
|
}
|
|
});
|
|
|
|
// Add markdown preview for documentation fields
|
|
const docTextareas = document.querySelectorAll('textarea[name="documentation"]');
|
|
docTextareas.forEach(function (textarea) {
|
|
// Only if preview container exists
|
|
const previewContainer = document.getElementById('markdown-preview');
|
|
if (previewContainer && textarea) {
|
|
textarea.addEventListener('input', function () {
|
|
// Use the server to render the markdown (safer)
|
|
fetch('/api/markdown-preview', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ content: textarea.value })
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
previewContainer.innerHTML = data.html;
|
|
});
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
function initTiptapEditor(element) {
|
|
// Load required Tiptap scripts
|
|
const editorContainer = document.getElementById('editor-container');
|
|
const preview = document.getElementById('markdown-preview');
|
|
|
|
// Initialize the Tiptap editor
|
|
const { Editor } = window.tiptap;
|
|
const { StarterKit } = window.tiptapExtensions;
|
|
|
|
const editor = new Editor({
|
|
element: element,
|
|
extensions: [
|
|
StarterKit
|
|
],
|
|
content: element.getAttribute('data-content') || '',
|
|
onUpdate: ({ editor }) => {
|
|
// Update preview with current content
|
|
if (preview) {
|
|
const markdown = editor.getHTML();
|
|
fetch('/api/markdown-preview', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ markdown: markdown })
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
preview.innerHTML = data.html;
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
// Store editor reference
|
|
window.editor = editor;
|
|
|
|
// Form submission handling
|
|
const form = element.closest('form');
|
|
if (form) {
|
|
form.addEventListener('submit', () => {
|
|
const contentInput = form.querySelector('input[name="content"]');
|
|
if (contentInput) {
|
|
contentInput.value = editor.getHTML();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// Copy to clipboard function
|
|
function copyToClipboard(text) {
|
|
navigator.clipboard.writeText(text).then(function () {
|
|
// Success notification
|
|
showNotification('Copied to clipboard!', 'success');
|
|
}, function (err) {
|
|
// Error notification
|
|
showNotification('Could not copy text', 'danger');
|
|
});
|
|
}
|
|
|
|
// Show notification
|
|
function showNotification(message, type = 'info') {
|
|
const notificationArea = document.getElementById('notification-area');
|
|
if (!notificationArea) return;
|
|
|
|
const notification = document.createElement('div');
|
|
notification.className = `alert alert-${type} alert-dismissible fade show`;
|
|
notification.innerHTML = `
|
|
${message}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
`;
|
|
|
|
notificationArea.appendChild(notification);
|
|
|
|
// Remove notification after 3 seconds
|
|
setTimeout(() => {
|
|
notification.classList.remove('show');
|
|
setTimeout(() => notification.remove(), 150);
|
|
}, 3000);
|
|
}
|