fresh-main #9
			
				
			
		
		
		
	
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -1,166 +0,0 @@ | ||||||
| --- |  | ||||||
| // Digital Garden Graph Visualization |  | ||||||
| // This component creates a network graph visualization of content relationships |  | ||||||
| --- |  | ||||||
| 
 |  | ||||||
| <div class="digital-garden-graph"> |  | ||||||
|     <div class="graph-container"> |  | ||||||
|         <svg id="digital-garden-svg" width="100%" height="400"></svg> |  | ||||||
|     </div> |  | ||||||
|     <div class="graph-legend"> |  | ||||||
|         <span class="legend-item"> |  | ||||||
|             <span class="dot post-dot"></span> |  | ||||||
|             <span>Blog Posts</span> |  | ||||||
|         </span> |  | ||||||
|         <span class="legend-item"> |  | ||||||
|             <span class="dot config-dot"></span> |  | ||||||
|             <span>Configurations</span> |  | ||||||
|         </span> |  | ||||||
|         <span class="legend-item"> |  | ||||||
|             <span class="dot project-dot"></span> |  | ||||||
|             <span>Projects</span> |  | ||||||
|         </span> |  | ||||||
|     </div> |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <style> |  | ||||||
|     .digital-garden-graph { |  | ||||||
|         margin: 2rem 0; |  | ||||||
|         border-radius: 1rem; |  | ||||||
|         border: 1px solid var(--card-border); |  | ||||||
|         background-color: var(--card-bg); |  | ||||||
|         overflow: hidden; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     .graph-container { |  | ||||||
|         width: 100%; |  | ||||||
|         height: 400px; |  | ||||||
|         position: relative; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     .graph-legend { |  | ||||||
|         display: flex; |  | ||||||
|         justify-content: center; |  | ||||||
|         gap: 2rem; |  | ||||||
|         padding: 1rem; |  | ||||||
|         border-top: 1px solid var(--card-border); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     .legend-item { |  | ||||||
|         display: flex; |  | ||||||
|         align-items: center; |  | ||||||
|         gap: 0.5rem; |  | ||||||
|         color: var(--text-secondary); |  | ||||||
|         font-size: 0.85rem; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     .dot { |  | ||||||
|         display: inline-block; |  | ||||||
|         width: 12px; |  | ||||||
|         height: 12px; |  | ||||||
|         border-radius: 50%; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     .post-dot { |  | ||||||
|         background-color: var(--accent-primary); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     .config-dot { |  | ||||||
|         background-color: var(--accent-secondary); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     .project-dot { |  | ||||||
|         background-color: var(--accent-tertiary); |  | ||||||
|     } |  | ||||||
| </style> |  | ||||||
| 
 |  | ||||||
| <script> |  | ||||||
|     document.addEventListener('DOMContentLoaded', () => { |  | ||||||
|         const svg = document.getElementById('digital-garden-svg'); |  | ||||||
|         if (!svg) return; |  | ||||||
|          |  | ||||||
|         // Set up the SVG dimensions |  | ||||||
|         const width = svg.clientWidth; |  | ||||||
|         const height = 400; |  | ||||||
|          |  | ||||||
|         // Define nodes - this would typically come from your content metadata |  | ||||||
|         // For this demo, we'll create a sample dataset |  | ||||||
|         const nodes = [ |  | ||||||
|             { id: 'k3s-cluster', type: 'post', x: width * 0.2, y: height * 0.3 }, |  | ||||||
|             { id: 'prometheus', type: 'post', x: width * 0.4, y: height * 0.5 }, |  | ||||||
|             { id: 'cloudflare-tunnel', type: 'post', x: width * 0.6, y: height * 0.3 }, |  | ||||||
|             { id: 'gitops-flux', type: 'post', x: width * 0.5, y: height * 0.7 }, |  | ||||||
|             { id: 'longhorn-storage', type: 'config', x: width * 0.3, y: height * 0.6 }, |  | ||||||
|             { id: 'metallb', type: 'config', x: width * 0.7, y: height * 0.5 }, |  | ||||||
|             { id: 'argobox', type: 'project', x: width * 0.5, y: height * 0.2 }, |  | ||||||
|         ]; |  | ||||||
|          |  | ||||||
|         // Define links between nodes |  | ||||||
|         const links = [ |  | ||||||
|             { source: 'k3s-cluster', target: 'prometheus' }, |  | ||||||
|             { source: 'k3s-cluster', target: 'longhorn-storage' }, |  | ||||||
|             { source: 'k3s-cluster', target: 'argobox' }, |  | ||||||
|             { source: 'prometheus', target: 'gitops-flux' }, |  | ||||||
|             { source: 'cloudflare-tunnel', target: 'argobox' }, |  | ||||||
|             { source: 'longhorn-storage', target: 'prometheus' }, |  | ||||||
|             { source: 'argobox', target: 'metallb' }, |  | ||||||
|             { source: 'metallb', target: 'cloudflare-tunnel' }, |  | ||||||
|         ]; |  | ||||||
|          |  | ||||||
|         // Create SVG elements |  | ||||||
|         // First the links |  | ||||||
|         links.forEach(link => { |  | ||||||
|             const sourceNode = nodes.find(n => n.id === link.source); |  | ||||||
|             const targetNode = nodes.find(n => n.id === link.target); |  | ||||||
|              |  | ||||||
|             if (sourceNode && targetNode) { |  | ||||||
|                 const line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); |  | ||||||
|                 line.setAttribute('x1', sourceNode.x); |  | ||||||
|                 line.setAttribute('y1', sourceNode.y); |  | ||||||
|                 line.setAttribute('x2', targetNode.x); |  | ||||||
|                 line.setAttribute('y2', targetNode.y); |  | ||||||
|                 line.setAttribute('stroke', 'rgba(226, 232, 240, 0.1)'); |  | ||||||
|                 line.setAttribute('stroke-width', '2'); |  | ||||||
|                 svg.appendChild(line); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|          |  | ||||||
|         // Then the nodes |  | ||||||
|         nodes.forEach(node => { |  | ||||||
|             const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); |  | ||||||
|             circle.setAttribute('cx', node.x); |  | ||||||
|             circle.setAttribute('cy', node.y); |  | ||||||
|             circle.setAttribute('r', '8'); |  | ||||||
|              |  | ||||||
|             // Assign color based on node type |  | ||||||
|             if (node.type === 'post') { |  | ||||||
|                 circle.setAttribute('fill', 'var(--accent-primary)'); |  | ||||||
|             } else if (node.type === 'config') { |  | ||||||
|                 circle.setAttribute('fill', 'var(--accent-secondary)'); |  | ||||||
|             } else { |  | ||||||
|                 circle.setAttribute('fill', 'var(--accent-tertiary)'); |  | ||||||
|             } |  | ||||||
|              |  | ||||||
|             // Add hover effect |  | ||||||
|             circle.onmouseover = () => { |  | ||||||
|                 circle.setAttribute('r', '12'); |  | ||||||
|                 circle.style.cursor = 'pointer'; |  | ||||||
|             }; |  | ||||||
|             circle.onmouseout = () => { |  | ||||||
|                 circle.setAttribute('r', '8'); |  | ||||||
|             }; |  | ||||||
|              |  | ||||||
|             // Add node label |  | ||||||
|             const text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); |  | ||||||
|             text.setAttribute('x', node.x); |  | ||||||
|             text.setAttribute('y', node.y + 20); |  | ||||||
|             text.setAttribute('font-size', '12'); |  | ||||||
|             text.setAttribute('fill', 'var(--text-secondary)'); |  | ||||||
|             text.setAttribute('text-anchor', 'middle'); |  | ||||||
|             text.textContent = node.id.replace(/-/g, ' '); |  | ||||||
|              |  | ||||||
|             svg.appendChild(circle); |  | ||||||
|             svg.appendChild(text); |  | ||||||
|         }); |  | ||||||
|     }); |  | ||||||
| </script>  |  | ||||||
|  | @ -5,7 +5,6 @@ | ||||||
| import BaseLayout from '../layouts/BaseLayout.astro'; | import BaseLayout from '../layouts/BaseLayout.astro'; | ||||||
| import Header from '../components/Header.astro'; | import Header from '../components/Header.astro'; | ||||||
| import Footer from '../components/Footer.astro'; | import Footer from '../components/Footer.astro'; | ||||||
| import Newsletter from '../components/Newsletter.astro'; |  | ||||||
| import MiniKnowledgeGraph from '../components/MiniKnowledgeGraph.astro'; | import MiniKnowledgeGraph from '../components/MiniKnowledgeGraph.astro'; | ||||||
| import { getCollection } from 'astro:content'; | import { getCollection } from 'astro:content'; | ||||||
| 
 | 
 | ||||||
|  | @ -235,7 +234,6 @@ const fallbackCurrentPost = currentPost || { | ||||||
|     </aside> |     </aside> | ||||||
|   </div> |   </div> | ||||||
| 
 | 
 | ||||||
|   <Newsletter /> |  | ||||||
|   <Footer slot="footer" /> |   <Footer slot="footer" /> | ||||||
| </BaseLayout> | </BaseLayout> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,179 +0,0 @@ | ||||||
| --- |  | ||||||
| import BaseLayout from '../layouts/BaseLayout.astro'; |  | ||||||
| import Header from '../components/Header.astro'; |  | ||||||
| import Footer from '../components/Footer.astro'; |  | ||||||
| import MiniKnowledgeGraph from '../components/MiniKnowledgeGraph.astro'; |  | ||||||
| import { getCollection } from 'astro:content'; |  | ||||||
| 
 |  | ||||||
| // Get all posts |  | ||||||
| const allPosts = await getCollection('posts').catch(error => { |  | ||||||
|   console.error('Error fetching posts collection:', error); |  | ||||||
|   return []; |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| // Try blog collection if posts doesn't exist |  | ||||||
| const blogPosts = allPosts.length === 0 ? await getCollection('blog').catch(() => []) : []; |  | ||||||
| const combinedPosts = [...allPosts, ...blogPosts]; |  | ||||||
| 
 |  | ||||||
| // Use the first post as a test post |  | ||||||
| const testPost = combinedPosts.length > 0 ? combinedPosts[0] : { |  | ||||||
|   slug: 'test-post', |  | ||||||
|   data: { |  | ||||||
|     title: 'Test Post', |  | ||||||
|     tags: ['test', 'graph'], |  | ||||||
|     category: 'Test' |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| // Create related posts - use the next 3 posts in the collection or create test posts |  | ||||||
| const relatedPosts = combinedPosts.length > 1  |  | ||||||
|   ? combinedPosts.slice(1, 4)  |  | ||||||
|   : [ |  | ||||||
|     { |  | ||||||
|       slug: 'related-1', |  | ||||||
|       data: { |  | ||||||
|         title: 'Related Post 1', |  | ||||||
|         tags: ['test', 'graph'], |  | ||||||
|         category: 'Test' |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       slug: 'related-2', |  | ||||||
|       data: { |  | ||||||
|         title: 'Related Post 2', |  | ||||||
|         tags: ['test'], |  | ||||||
|         category: 'Test' |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   ]; |  | ||||||
| --- |  | ||||||
| 
 |  | ||||||
| <BaseLayout title="Test MiniKnowledgeGraph"> |  | ||||||
|   <Header slot="header" /> |  | ||||||
|    |  | ||||||
|   <div class="container mx-auto px-4 py-8"> |  | ||||||
|     <h1 class="text-3xl font-bold mb-6">MiniKnowledgeGraph Test Page</h1> |  | ||||||
|      |  | ||||||
|     <div class="bg-slate-800 rounded-lg p-6 mb-8"> |  | ||||||
|       <p class="mb-4">This is a test page to ensure the MiniKnowledgeGraph component is working properly.</p> |  | ||||||
|        |  | ||||||
|       <div class="border border-slate-700 rounded-lg p-4 mb-6"> |  | ||||||
|         <h2 class="text-xl font-bold mb-4">Test Post Details:</h2> |  | ||||||
|         <p><strong>Title:</strong> {testPost.data.title}</p> |  | ||||||
|         <p><strong>Slug:</strong> {testPost.slug}</p> |  | ||||||
|         <p><strong>Tags:</strong> {testPost.data.tags?.join(', ') || 'None'}</p> |  | ||||||
|         <p><strong>Category:</strong> {testPost.data.category || 'None'}</p> |  | ||||||
|         <p><strong>Related Posts:</strong> {relatedPosts.length}</p> |  | ||||||
|       </div> |  | ||||||
|        |  | ||||||
|       <div class="mini-knowledge-graph-area"> |  | ||||||
|         <h2 class="text-xl font-bold mb-4">MiniKnowledgeGraph Component:</h2> |  | ||||||
|          |  | ||||||
|         <div class="mini-knowledge-graph-wrapper"> |  | ||||||
|           <MiniKnowledgeGraph |  | ||||||
|             currentPost={testPost} |  | ||||||
|             relatedPosts={relatedPosts} |  | ||||||
|             height="300px" |  | ||||||
|             title="Test Graph" |  | ||||||
|           /> |  | ||||||
|         </div> |  | ||||||
|          |  | ||||||
|         <!-- Debug Information Display --> |  | ||||||
|         <div class="debug-info mt-4 p-4 bg-gray-900 rounded-lg"> |  | ||||||
|           <h3 class="text-lg font-bold mb-2">Debug Info</h3> |  | ||||||
|           <div id="debug-container">Loading debug info...</div> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|   </div> |  | ||||||
|    |  | ||||||
|   <Footer slot="footer" /> |  | ||||||
| </BaseLayout> |  | ||||||
| 
 |  | ||||||
| <style> |  | ||||||
|   .mini-knowledge-graph-area { |  | ||||||
|     margin-top: 2rem; |  | ||||||
|   } |  | ||||||
|    |  | ||||||
|   .mini-knowledge-graph-wrapper { |  | ||||||
|     width: 100%; |  | ||||||
|     border-radius: 10px; |  | ||||||
|     overflow: hidden; |  | ||||||
|     display: block !important; |  | ||||||
|     position: relative; |  | ||||||
|     min-height: 300px; |  | ||||||
|     height: 300px; |  | ||||||
|     background: var(--card-bg, #1e293b); |  | ||||||
|     border: 1px solid var(--card-border, #334155); |  | ||||||
|     visibility: visible !important; |  | ||||||
|   } |  | ||||||
|    |  | ||||||
|   .debug-info { |  | ||||||
|     font-family: monospace; |  | ||||||
|     font-size: 0.8rem; |  | ||||||
|     line-height: 1.4; |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| 
 |  | ||||||
| <script> |  | ||||||
|   // Debug utility for testing the knowledge graph |  | ||||||
|   document.addEventListener('DOMContentLoaded', function() { |  | ||||||
|     setTimeout(checkGraphStatus, 500); |  | ||||||
|      |  | ||||||
|     // Also check after window load |  | ||||||
|     window.addEventListener('load', function() { |  | ||||||
|       setTimeout(checkGraphStatus, 1000); |  | ||||||
|     }); |  | ||||||
|   }); |  | ||||||
|    |  | ||||||
|   function checkGraphStatus() { |  | ||||||
|     const debugContainer = document.getElementById('debug-container'); |  | ||||||
|     if (!debugContainer) return; |  | ||||||
|      |  | ||||||
|     // Get container info |  | ||||||
|     const container = document.querySelector('.mini-knowledge-graph-wrapper'); |  | ||||||
|     const cyContainer = document.getElementById('mini-cy'); |  | ||||||
|      |  | ||||||
|     // Check for cytoscape instance |  | ||||||
|     const cyInstance = window.miniCy; |  | ||||||
|      |  | ||||||
|     let html = '<ul>'; |  | ||||||
|      |  | ||||||
|     // Container dimensions |  | ||||||
|     if (container) { |  | ||||||
|       html += `<li>Container: ${container.offsetWidth}x${container.offsetHeight}px</li>`; |  | ||||||
|       html += `<li>Display: ${getComputedStyle(container).display}</li>`; |  | ||||||
|       html += `<li>Visibility: ${getComputedStyle(container).visibility}</li>`; |  | ||||||
|     } else { |  | ||||||
|       html += '<li>Container: Not found</li>'; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     // Cytoscape container |  | ||||||
|     if (cyContainer) { |  | ||||||
|       html += `<li>Cy Container: ${cyContainer.offsetWidth}x${cyContainer.offsetHeight}px</li>`; |  | ||||||
|     } else { |  | ||||||
|       html += '<li>Cy Container: Not found</li>'; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     // Cytoscape instance |  | ||||||
|     html += `<li>Cytoscape object: ${typeof cytoscape !== 'undefined' ? 'Available' : 'Not available'}</li>`; |  | ||||||
|     html += `<li>Cytoscape instance: ${cyInstance ? 'Initialized' : 'Not initialized'}</li>`; |  | ||||||
|      |  | ||||||
|     // If instance exists, get more details |  | ||||||
|     if (cyInstance) { |  | ||||||
|       html += `<li>Nodes: ${cyInstance.nodes().length}</li>`; |  | ||||||
|       html += `<li>Edges: ${cyInstance.edges().length}</li>`; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     html += '</ul>'; |  | ||||||
|      |  | ||||||
|     // Add refresh button |  | ||||||
|     html += '<button id="refresh-debug" class="mt-2 px-3 py-1 bg-blue-700 text-white rounded hover:bg-blue-600">' +  |  | ||||||
|             'Refresh Debug Info</button>'; |  | ||||||
|      |  | ||||||
|     debugContainer.innerHTML = html; |  | ||||||
|      |  | ||||||
|     // Add event listener to refresh button |  | ||||||
|     document.getElementById('refresh-debug')?.addEventListener('click', checkGraphStatus); |  | ||||||
|   } |  | ||||||
| </script>  |  | ||||||
		Loading…
	
		Reference in New Issue