diff --git a/public/js/admin/dashboard.js b/public/js/admin/dashboard.js index a45f67af..fa288935 100644 --- a/public/js/admin/dashboard.js +++ b/public/js/admin/dashboard.js @@ -225,22 +225,44 @@ async function loadDocuments() { return; } - container.innerHTML = response.documents.map(doc => ` -
+ container.innerHTML = response.documents.map(doc => { + const visibilityBadge = getVisibilityBadge(doc.visibility || 'internal'); + const statusBadge = getStatusBadge(doc.workflow_status || 'draft'); + const canPublish = doc.visibility === 'internal' && doc.workflow_status !== 'published'; + const canUnpublish = doc.visibility === 'public' && doc.workflow_status === 'published'; + + return ` +

${doc.title}

-

${doc.quadrant || 'No quadrant'} • ${formatDate(doc.created_at)}

+
+

${doc.quadrant || 'No quadrant'}

+ ${statusBadge} + ${visibilityBadge} + ${doc.category ? `Category: ${doc.category}` : ''} +
View + ${canPublish ? ` + + ` : ''} + ${canUnpublish ? ` + + ` : ''}
- `).join(''); + `; + }).join(''); } catch (error) { console.error('Failed to load documents:', error); container.innerHTML = '
Failed to load documents
'; @@ -350,7 +372,221 @@ async function deleteDocument(docId) { } } +// Open publish modal +async function openPublishModal(docId) { + try { + const response = await apiRequest(`/api/documents/${docId}`); + if (!response.success || !response.document) { + alert('Failed to load document'); + return; + } + + const doc = response.document; + const modalHTML = ` +
+
+

Publish Document

+ +
+

Title: ${doc.title}

+

Current Status: ${doc.workflow_status || 'draft'}

+
+ +
+
+ + +
+ +
+ + +

Higher numbers appear first

+
+ +
+ + +
+
+
+
+ `; + + document.body.insertAdjacentHTML('beforeend', modalHTML); + + // Store doc ID for later + document.getElementById('publish-form').dataset.docId = docId; + + // Handle form submission + document.getElementById('publish-form').addEventListener('submit', async (e) => { + e.preventDefault(); + const category = document.getElementById('publish-category').value; + const order = parseInt(document.getElementById('publish-order').value) || 0; + + await publishDocument(docId, category, order); + }); + } catch (error) { + console.error('Failed to open publish modal:', error); + alert('Failed to open publish modal'); + } +} + +// Publish document +async function publishDocument(docId, category, order) { + try { + const response = await apiRequest(`/api/documents/${docId}/publish`, { + method: 'POST', + body: JSON.stringify({ category, order }) + }); + + if (response.success) { + closePublishModal(); + loadDocuments(); + loadStatistics(); + alert('Document published successfully'); + } else { + alert(response.message || 'Failed to publish document'); + } + } catch (error) { + console.error('Publish error:', error); + alert('Failed to publish document'); + } +} + +// Close publish modal +function closePublishModal() { + document.getElementById('publish-modal')?.remove(); +} + +// Open unpublish modal +async function openUnpublishModal(docId) { + try { + const response = await apiRequest(`/api/documents/${docId}`); + if (!response.success || !response.document) { + alert('Failed to load document'); + return; + } + + const doc = response.document; + const modalHTML = ` +
+
+

Unpublish Document

+ +
+

Title: ${doc.title}

+

Current Visibility: ${doc.visibility}

+

Category: ${doc.category || 'None'}

+
+ +
+
+ + +

This will be recorded in the audit trail

+
+ +
+ + +
+
+
+
+ `; + + document.body.insertAdjacentHTML('beforeend', modalHTML); + + // Store doc ID for later + document.getElementById('unpublish-form').dataset.docId = docId; + + // Handle form submission + document.getElementById('unpublish-form').addEventListener('submit', async (e) => { + e.preventDefault(); + const reason = document.getElementById('unpublish-reason').value; + + await unpublishDocument(docId, reason); + }); + } catch (error) { + console.error('Failed to open unpublish modal:', error); + alert('Failed to open unpublish modal'); + } +} + +// Unpublish document +async function unpublishDocument(docId, reason) { + try { + const response = await apiRequest(`/api/documents/${docId}/unpublish`, { + method: 'POST', + body: JSON.stringify({ reason }) + }); + + if (response.success) { + closeUnpublishModal(); + loadDocuments(); + loadStatistics(); + alert('Document unpublished successfully'); + } else { + alert(response.message || 'Failed to unpublish document'); + } + } catch (error) { + console.error('Unpublish error:', error); + alert('Failed to unpublish document'); + } +} + +// Close unpublish modal +function closeUnpublishModal() { + document.getElementById('unpublish-modal')?.remove(); +} + // Utility functions +function getVisibilityBadge(visibility) { + const badges = { + 'public': 'Public', + 'internal': 'Internal', + 'confidential': 'Confidential', + 'archived': 'Archived' + }; + return badges[visibility] || badges['internal']; +} + +function getStatusBadge(status) { + const badges = { + 'draft': 'Draft', + 'review': 'Review', + 'published': 'Published' + }; + return badges[status] || badges['draft']; +} + function getActivityColor(type) { const colors = { 'create': 'bg-green-500', @@ -417,5 +653,17 @@ document.addEventListener('click', (e) => { case 'deleteDocument': deleteDocument(arg0); break; + case 'openPublishModal': + openPublishModal(arg0); + break; + case 'openUnpublishModal': + openUnpublishModal(arg0); + break; + case 'closePublishModal': + closePublishModal(); + break; + case 'closeUnpublishModal': + closeUnpublishModal(); + break; } });