working preview.. for view
This commit is contained in:
parent
9e2d3c9707
commit
17885b005c
4 changed files with 652 additions and 241 deletions
|
@ -5,42 +5,55 @@
|
|||
{% block header_title %}{{ document.title }}{% endblock %}
|
||||
|
||||
{% block header_actions %}
|
||||
<a href="{{ url_for('main.edit_document', doc_id=document.id) }}" class="button primary">
|
||||
<i class="mdi mdi-pencil"></i> Edit
|
||||
<a href="{{ url_for('main.edit_document', doc_id=document.id) }}" class="inline-flex items-center px-4 py-2 bg-primary text-black rounded-md hover:bg-primary-dark transition-colors">
|
||||
<i class="mdi mdi-pencil mr-2"></i> Edit
|
||||
</a>
|
||||
<a href="{{ url_for('main.export_document', doc_id=document.id) }}" class="button">
|
||||
<i class="mdi mdi-download"></i> Export
|
||||
<a href="{{ url_for('main.export_document', doc_id=document.id) }}" class="inline-flex items-center px-4 py-2 bg-gray-700 text-white rounded-md hover:bg-gray-600 transition-colors ml-2">
|
||||
<i class="mdi mdi-download mr-2"></i> Export
|
||||
</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<!-- GitHub Markdown CSS -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.2.0/github-markdown-dark.min.css">
|
||||
<!-- Highlight.js for syntax highlighting -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/github-dark.min.css">
|
||||
|
||||
<style>
|
||||
.document-view {
|
||||
padding: 20px;
|
||||
.document-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: calc(100vh - 64px);
|
||||
background-color: #0d1117;
|
||||
}
|
||||
|
||||
.document-metadata {
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
.document-header {
|
||||
padding: 20px 30px;
|
||||
border-bottom: 1px solid #30363d;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.document-metadata {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.metadata-item {
|
||||
margin-right: 15px;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.9em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.875rem;
|
||||
color: #8b949e;
|
||||
}
|
||||
|
||||
.metadata-item i {
|
||||
margin-right: 5px;
|
||||
color: #6e7681;
|
||||
}
|
||||
|
||||
.document-tags {
|
||||
|
@ -50,16 +63,23 @@
|
|||
}
|
||||
|
||||
.document-tag {
|
||||
background: var(--accent-color);
|
||||
color: var(--bg-color);
|
||||
background-color: rgba(80, 250, 123, 0.1);
|
||||
color: #50fa7b;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
transition: transform 0.2s ease;
|
||||
border-radius: 12px;
|
||||
font-size: 0.75rem;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.document-tag:hover {
|
||||
transform: translateY(-2px);
|
||||
background-color: rgba(80, 250, 123, 0.2);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.document-body {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
|
@ -68,7 +88,6 @@
|
|||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
padding: 45px;
|
||||
color: #c9d1d9;
|
||||
}
|
||||
|
||||
/* GitHub-style admonitions/alerts */
|
||||
|
@ -130,45 +149,59 @@
|
|||
color: #f85149;
|
||||
}
|
||||
|
||||
/* Regular blockquotes */
|
||||
.markdown-body blockquote {
|
||||
padding: 0.5rem 1rem;
|
||||
color: #8b949e;
|
||||
border-left: 0.25em solid #30363d;
|
||||
margin: 1em 0;
|
||||
background-color: rgba(55, 65, 81, 0.1);
|
||||
.markdown-body .admonition-danger {
|
||||
border-color: #cf222e;
|
||||
background-color: rgba(207, 34, 46, 0.1);
|
||||
}
|
||||
|
||||
.markdown-body blockquote > :first-child {
|
||||
margin-top: 0;
|
||||
.markdown-body .admonition-danger .admonition-title {
|
||||
color: #cf222e;
|
||||
}
|
||||
|
||||
.markdown-body blockquote > :last-child {
|
||||
margin-bottom: 0;
|
||||
/* Animation for fade-in */
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn 0.5s ease-in;
|
||||
}
|
||||
|
||||
/* Mobile adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.document-header {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
padding: 25px 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="document-view">
|
||||
<div class="document-metadata">
|
||||
<div class="metadata-item">
|
||||
<i class="mdi mdi-calendar"></i>
|
||||
Created: {{ document.created_date.strftime('%b %d, %Y') }}
|
||||
<div class="document-container">
|
||||
<div class="document-header">
|
||||
<div class="document-metadata">
|
||||
<div class="metadata-item">
|
||||
<i class="mdi mdi-clock-outline"></i>
|
||||
Updated {{ document.updated_date.strftime('%b %d, %Y') }}
|
||||
</div>
|
||||
|
||||
{% if document.category %}
|
||||
<div class="metadata-item">
|
||||
<i class="mdi {{ document.category.icon }}"></i>
|
||||
<a href="{{ url_for('main.view_category', category_id=document.category.id) }}" class="hover:text-primary transition-colors">
|
||||
{{ document.category.name }}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="metadata-item">
|
||||
<i class="mdi mdi-update"></i>
|
||||
Updated: {{ document.updated_date.strftime('%b %d, %Y') }}
|
||||
</div>
|
||||
{% if document.category %}
|
||||
<div class="metadata-item">
|
||||
<i class="mdi {{ document.category.icon }}"></i>
|
||||
{{ document.category.name }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if document.tags %}
|
||||
<div class="metadata-item document-tags">
|
||||
<i class="mdi mdi-tag-multiple"></i>
|
||||
<div class="document-tags">
|
||||
{% for tag in document.tags %}
|
||||
<span class="document-tag">{{ tag.name }}</span>
|
||||
{% endfor %}
|
||||
|
@ -176,8 +209,10 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="markdown-body" id="document-content" data-content="{{ document.content|tojson|safe }}">
|
||||
<!-- Content will be rendered here -->
|
||||
<div class="document-body">
|
||||
<div id="document-content" class="markdown-body fade-in">
|
||||
<!-- Content will be rendered here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -185,6 +220,8 @@
|
|||
{% block extra_js %}
|
||||
<!-- Marked.js for Markdown parsing -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<!-- Highlight.js for syntax highlighting -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
@ -197,7 +234,13 @@
|
|||
pedantic: false,
|
||||
sanitize: false,
|
||||
smartLists: true,
|
||||
smartypants: false
|
||||
smartypants: false,
|
||||
highlight: function(code, lang) {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
return hljs.highlight(code, { language: lang }).value;
|
||||
}
|
||||
return hljs.highlightAuto(code).value;
|
||||
}
|
||||
});
|
||||
|
||||
// Custom renderer for GitHub-style alert blocks
|
||||
|
@ -239,21 +282,10 @@
|
|||
|
||||
// Render markdown content
|
||||
const documentContent = document.getElementById('document-content');
|
||||
const markdownContent = documentContent.getAttribute('data-content');
|
||||
const markdownContent = `{{ document.content|replace("\n", "\\n")|replace("'", "\\'")|safe }}`;
|
||||
|
||||
console.log("Raw content attribute:", markdownContent);
|
||||
|
||||
try {
|
||||
// Parse the JSON-encoded content (Flask's tojson filter wraps content in quotes)
|
||||
const decodedContent = JSON.parse(markdownContent);
|
||||
console.log("Content length:", decodedContent.length);
|
||||
|
||||
// Render the markdown directly without additional checks
|
||||
documentContent.innerHTML = marked.parse(decodedContent);
|
||||
} catch (e) {
|
||||
console.error("Error rendering document:", e);
|
||||
documentContent.innerHTML = '<div class="text-center p-8 text-red-500">Error displaying document content.</div>';
|
||||
}
|
||||
// Render directly without JSON parsing
|
||||
documentContent.innerHTML = marked.parse(markdownContent);
|
||||
|
||||
// Add linkification for dynamic links
|
||||
document.querySelectorAll('#document-content a[href^="#doc:"]').forEach(link => {
|
||||
|
@ -264,15 +296,40 @@
|
|||
link.removeAttribute('rel');
|
||||
});
|
||||
|
||||
// Highlight active document in sidebar
|
||||
highlightActiveDocument();
|
||||
|
||||
// Add keyboard shortcuts
|
||||
document.addEventListener('keydown', function(e) {
|
||||
// 'e' to edit the current document
|
||||
if (e.key === 'e' && !e.ctrlKey && !e.metaKey && !e.altKey &&
|
||||
if (e.key === 'e' && !e.ctrlKey && !e.metaKey && !e.altKey &&
|
||||
!(e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA')) {
|
||||
e.preventDefault();
|
||||
window.location.href = "{{ url_for('main.edit_document', doc_id=document.id) }}";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function highlightActiveDocument() {
|
||||
// Find the current document in the sidebar and highlight it
|
||||
const currentDocId = "{{ document.id }}";
|
||||
const sidebarItems = document.querySelectorAll('.document-item a');
|
||||
|
||||
sidebarItems.forEach(item => {
|
||||
const href = item.getAttribute('href');
|
||||
if (href && href.includes(`/document/${currentDocId}`)) {
|
||||
item.classList.add('text-primary');
|
||||
|
||||
// Expand parent category if collapsed
|
||||
const parentContainer = item.closest('.category-children');
|
||||
if (parentContainer && parentContainer.style.display === 'none') {
|
||||
const toggleBtn = parentContainer.parentElement.querySelector('.toggle-btn');
|
||||
if (toggleBtn) {
|
||||
toggleBtn.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
Loading…
Add table
Add a link
Reference in a new issue