feat(docs): integrate LikeC4 interactive diagrams into Hugo/Docsy
Implement complete integration of LikeC4 interactive architecture
diagrams into the Hugo/Docsy documentation system, enabling embedded
web components for exploring C4 models directly in documentation pages.
Integration Components:
Static Assets:
- static/js/likec4-webcomponent.js (3.1 MB) - Generated web component
containing all 54 C4 views as interactive embeddable elements
- static/js/likec4-loader.js - Dynamic ES6 module loader with fallback
paths for robust component loading across different page depths
- static/css/likec4-styles.css - Styling for diagram containers with
dark mode support for Docsy theme compatibility
Hugo Configuration:
- hugo.toml - Added params.likec4.enable configuration flag
- layouts/partials/hooks/head-end.html - Hook to inject CSS and JS
when LikeC4 is enabled site-wide
Documentation:
- content/en/docs/architecture/_index.md - Architecture section index
- content/en/docs/architecture/highlevelarch.md - Example page with
interactive OTC FaaS deployment diagram demonstrating integration
- content/en/docs/architecture/setup.md - Comprehensive setup guide
covering installation, usage, workflow, and troubleshooting
- resources/likec4/INTEGRATION.md - Technical integration details
- LIKEC4-QUICKSTART.md - Quick start guide for developers
Features:
- Interactive diagram exploration (click components for details)
- Automatic loading indicators with timeout fallback
- Graceful degradation for non-JS environments
- Dark mode support matching Docsy theme
- Multiple diagrams per page support
- Browser compatibility detection
Usage Pattern:
```html
<div class="likec4-container">
<div class="likec4-header">Diagram Title</div>
<likec4-view view-id="otc-faas" browser="true"></likec4-view>
<div class="likec4-loading">Loading...</div>
</div>
```
Workflow:
1. Edit .c4 files in resources/likec4/
2. Run: npx likec4 gen webcomponent --webcomponent-prefix likec4
--outfile ../../static/js/likec4-webcomponent.js
3. Commit both model changes and regenerated webcomponent
Available Views:
- otc-faas, edp, landscape, edpbuilderworkflow
- keycloak, forgejo, argocd, crossplane, monitoring
- And 40+ more component and deployment views
The integration preserves the MkDocs-style embedding approach from
edp-doc while adapting it to Hugo's static site generation model.
This completes the migration making this repository the central hub
for both C4 architecture models and their rendered documentation.
This commit is contained in:
parent
286b427ed8
commit
8785b327dd
9 changed files with 1465 additions and 1 deletions
70
static/css/likec4-styles.css
Normal file
70
static/css/likec4-styles.css
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* LikeC4 Component Styles for Hugo/Docsy */
|
||||
likec4-view {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.likec4-container {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
background: #f9f9f9;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.likec4-loading {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
font-family: system-ui, sans-serif;
|
||||
}
|
||||
|
||||
.likec4-loading::after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-left: 8px;
|
||||
border: 2px solid #dee2e6;
|
||||
border-top: 2px solid #007bff;
|
||||
border-radius: 50%;
|
||||
animation: likec4-spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes likec4-spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.likec4-header {
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
padding: 8px 16px;
|
||||
font-size: 12px;
|
||||
color: #495057;
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
/* Dark mode support for Docsy */
|
||||
body[data-dark-mode] .likec4-container {
|
||||
background: #1e1e1e;
|
||||
border-color: #444;
|
||||
}
|
||||
|
||||
body[data-dark-mode] .likec4-header {
|
||||
background: #2d2d2d;
|
||||
border-bottom-color: #444;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
body[data-dark-mode] .likec4-loading {
|
||||
color: #ccc;
|
||||
}
|
||||
86
static/js/likec4-loader.js
Normal file
86
static/js/likec4-loader.js
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/* LikeC4 Webcomponent Loader for Hugo/Docsy */
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// Check if the component is already loaded
|
||||
if (customElements.get('likec4-view')) {
|
||||
console.log('LikeC4 component already loaded');
|
||||
return;
|
||||
}
|
||||
|
||||
// Function to dynamically import the ES6 module
|
||||
function loadLikeC4Module() {
|
||||
// Try different possible paths for the webcomponent
|
||||
const possiblePaths = [
|
||||
// Absolute Hugo paths (most likely to work)
|
||||
'/js/likec4-webcomponent.js',
|
||||
// Relative paths from current page
|
||||
'../js/likec4-webcomponent.js',
|
||||
'../../js/likec4-webcomponent.js',
|
||||
'../../../js/likec4-webcomponent.js',
|
||||
// Fallback paths
|
||||
'./js/likec4-webcomponent.js',
|
||||
'js/likec4-webcomponent.js'
|
||||
];
|
||||
|
||||
let pathIndex = 0;
|
||||
|
||||
function tryNextPath() {
|
||||
if (pathIndex >= possiblePaths.length) {
|
||||
console.error('All module paths failed');
|
||||
showErrorMessage('Failed to load interactive diagram module');
|
||||
return;
|
||||
}
|
||||
|
||||
const modulePath = possiblePaths[pathIndex];
|
||||
console.log(`Trying to load LikeC4 module from: ${modulePath}`);
|
||||
|
||||
// Dynamic import with error handling
|
||||
try {
|
||||
const importFunction = new Function('specifier', 'return import(specifier)');
|
||||
importFunction(modulePath)
|
||||
.then(function(module) {
|
||||
console.log('LikeC4 webcomponent loaded successfully');
|
||||
// Hide any loading indicators
|
||||
hideLoadingIndicators();
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.warn(`Failed to load from ${modulePath}:`, error.message);
|
||||
pathIndex++;
|
||||
tryNextPath();
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(`Dynamic import failed for ${modulePath}:`, error.message);
|
||||
pathIndex++;
|
||||
tryNextPath();
|
||||
}
|
||||
}
|
||||
|
||||
tryNextPath();
|
||||
}
|
||||
|
||||
function hideLoadingIndicators() {
|
||||
const loadingElements = document.querySelectorAll('.likec4-loading, #likec4-loading');
|
||||
loadingElements.forEach(function(el) {
|
||||
el.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
function showErrorMessage(message) {
|
||||
const containers = document.querySelectorAll('.likec4-container');
|
||||
containers.forEach(function(container) {
|
||||
const errorDiv = document.createElement('div');
|
||||
errorDiv.style.cssText = 'position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #dc3545; text-align: center; font-size: 14px; max-width: 300px;';
|
||||
errorDiv.textContent = message;
|
||||
container.appendChild(errorDiv);
|
||||
});
|
||||
hideLoadingIndicators();
|
||||
}
|
||||
|
||||
// Check if DOM is ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', loadLikeC4Module);
|
||||
} else {
|
||||
loadLikeC4Module();
|
||||
}
|
||||
})();
|
||||
760
static/js/likec4-webcomponent.js
Normal file
760
static/js/likec4-webcomponent.js
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue