feat: add dynamic Mermaid diagram support and configuration and add diagrams for legacy staff application
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"path": "assets/diagrams/legacy/staff-mobile-application/overview.mermaid",
|
||||||
|
"title": "Overview"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "assets/diagrams/legacy/staff-mobile-application/use-case-flowchart.mermaid",
|
||||||
|
"title": "Use Case Flowchart"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
flowchart TD
|
||||||
|
A[main.dart] --> B{KrowApp};
|
||||||
|
B --> C{MaterialApp.router};
|
||||||
|
C --> D[SplashRoute];
|
||||||
|
D --> E{SplashRedirectGuard};
|
||||||
|
|
||||||
|
E -- Authenticated --> F[HomeRoute];
|
||||||
|
E -- Admin Validation --> G[WaitingValidationRoute];
|
||||||
|
E -- Prepare Profile --> H[CheckListFlowRoute];
|
||||||
|
E -- Unauthenticated/Error --> I[AuthFlowRoute];
|
||||||
|
|
||||||
|
F --> F1[ShiftsFlowRoute];
|
||||||
|
F --> F2[EarningsFlowRoute];
|
||||||
|
F --> F3[ProfileMainFlowRoute];
|
||||||
|
|
||||||
|
F1 --> F1a[ShiftsListMainRoute];
|
||||||
|
F1a --> F1b[ShiftDetailsRoute];
|
||||||
|
F1a --> F1c[QrScannerRoute];
|
||||||
|
|
||||||
|
F2 --> F2a[EarningsRoute];
|
||||||
|
F2a --> F2b[EarningsHistoryRoute];
|
||||||
|
|
||||||
|
F3 --> F3a[ProfileMainRoute];
|
||||||
|
F3a --> F3b[RoleKitFlowRoute];
|
||||||
|
F3a --> F3c[CertificatesRoute];
|
||||||
|
F3a --> F3d[ScheduleRoute];
|
||||||
|
F3a --> F3e[WorkingAreaRoute];
|
||||||
|
F3a --> F3f[LivePhotoRoute];
|
||||||
|
F3a --> F3g[ProfileSettingsFlowRoute];
|
||||||
|
F3a --> F3h[WagesFormsFlowRoute];
|
||||||
|
F3a --> F3i[BankAccountFlowRoute];
|
||||||
|
F3a --> F3j[BenefitsRoute];
|
||||||
|
F3a --> F3k[SupportRoute];
|
||||||
|
F3a --> F3l[FaqRoute];
|
||||||
|
|
||||||
|
F3g --> F3g1[ProfileSettingsMenuRoute];
|
||||||
|
F3g1 --> F3g2[RoleRoute];
|
||||||
|
F3g1 --> F3g3[PersonalInfoRoute];
|
||||||
|
F3g1 --> F3g4[EmailVerificationRoute];
|
||||||
|
F3g4 --> L1;
|
||||||
|
F3g1 --> F3g5[AddressRoute];
|
||||||
|
F3g1 --> F3g6[EmergencyContactsRoute];
|
||||||
|
F3g1 --> F3g7[MobilityRoute];
|
||||||
|
F3g1 --> F3g8[InclusiveRoute];
|
||||||
|
|
||||||
|
F3h --> F3h1[FormsListRoute];
|
||||||
|
F3h1 --> F3h2[OfferLetterFormRoute];
|
||||||
|
F3h1 --> F3h3[EddFormRoute];
|
||||||
|
F3h1 --> F3h4[INineFormRoute];
|
||||||
|
F3h1 --> F3h5[WFourFormRoute];
|
||||||
|
F3h2 --> F3h6[FormSignRoute];
|
||||||
|
F3h3 --> F3h6;
|
||||||
|
F3h4 --> F3h6;
|
||||||
|
F3h5 --> F3h6;
|
||||||
|
F3h6 --> F3h7[SignedFormRoute];
|
||||||
|
F3h6 --> F3h8[FormPreviewRoute];
|
||||||
|
|
||||||
|
F3i --> F3i1[BankAccountRoute];
|
||||||
|
F3i1 --> F3i2[BankAccountEditRoute];
|
||||||
|
|
||||||
|
F3b --> F3b1[RolesKitListRoute];
|
||||||
|
F3b1 --> F3b2[RoleKitRoute];
|
||||||
|
|
||||||
|
H --> H1[CheckListRoute];
|
||||||
|
H1 --> H2[PersonalInfoRoute];
|
||||||
|
H1 --> H3[EmailVerificationRoute];
|
||||||
|
H3 --> L1;
|
||||||
|
H1 --> H4[EmergencyContactsRoute];
|
||||||
|
H1 --> H5[AddressRoute];
|
||||||
|
H1 --> H6[WorkingAreaRoute];
|
||||||
|
H1 --> H7[RoleRoute];
|
||||||
|
H1 --> H8[CertificatesRoute];
|
||||||
|
H1 --> H9[ScheduleRoute];
|
||||||
|
H1 --> F3i;
|
||||||
|
H1 --> F3h;
|
||||||
|
H1 --> F3b;
|
||||||
|
|
||||||
|
I --> I1[WelcomeRoute];
|
||||||
|
I1 --> I2[PhoneVerificationRoute];
|
||||||
|
I2 --> I3[CodeVerificationRoute];
|
||||||
|
I3 --> J{SingUpRedirectGuard};
|
||||||
|
|
||||||
|
J -- Prepare Profile --> K[SignupFlowRoute];
|
||||||
|
J -- Authenticated --> F;
|
||||||
|
J -- Admin Validation --> G;
|
||||||
|
J -- Unauthenticated/Error --> I;
|
||||||
|
|
||||||
|
K --> K1[PersonalInfoRoute];
|
||||||
|
K1 --> K2[EmailVerificationRoute];
|
||||||
|
K2 --> K3[EmergencyContactsRoute];
|
||||||
|
K2 --> L1;
|
||||||
|
K3 --> K4[MobilityRoute];
|
||||||
|
K4 --> K5[InclusiveRoute];
|
||||||
|
K5 --> K6[AddressRoute];
|
||||||
|
K6 --> K7[WorkingAreaRoute];
|
||||||
|
K7 --> K8[RoleRoute];
|
||||||
|
|
||||||
|
subgraph PhoneReLoginFlow
|
||||||
|
L1[PhoneReLoginFlowRoute]
|
||||||
|
L1 --> L2[CodeVerificationRoute]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph CheckListFlow
|
||||||
|
H
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph AuthFlow
|
||||||
|
I
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph SignUpFlow
|
||||||
|
K
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph HomeFlow
|
||||||
|
F
|
||||||
|
end
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
flowchart TD
|
||||||
|
subgraph AppInitialization
|
||||||
|
A[Start App] --> B{Check Auth Status};
|
||||||
|
B -- Authenticated --> C[Go to Home];
|
||||||
|
B -- Unauthenticated --> D[Go to Auth];
|
||||||
|
B -- Admin Validation --> E[Go to Waiting Validation];
|
||||||
|
B -- Prepare Profile --> F[Go to Checklist];
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph UserAuthentication
|
||||||
|
D --> G[Welcome Screen];
|
||||||
|
G --> H{Select Sign In/Up};
|
||||||
|
H -- Sign In --> I[Sign In With Phone];
|
||||||
|
I --> J[Verify Phone Code];
|
||||||
|
J -- Success --> C;
|
||||||
|
H -- Sign Up --> K[Go to User Onboarding];
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph UserOnboarding
|
||||||
|
K --> L[Collect Personal Info];
|
||||||
|
L --> M[Verify Email];
|
||||||
|
M --> N[Add Emergency Contacts];
|
||||||
|
N --> O[Specify Mobility];
|
||||||
|
O --> P[Provide Inclusivity Info];
|
||||||
|
P --> Q[Enter Address];
|
||||||
|
Q --> R[Define Working Area];
|
||||||
|
R --> S[Select Role];
|
||||||
|
S -- Success --> F;
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph ProfileCompletion
|
||||||
|
F --> T[View Checklist];
|
||||||
|
T --> U[Complete Personal Info];
|
||||||
|
T --> V[Complete Email Verification];
|
||||||
|
T --> W[Complete Emergency Contacts];
|
||||||
|
T --> X[Manage Certificates];
|
||||||
|
T --> Y[Set Schedule];
|
||||||
|
T --> Z[Manage Bank Account];
|
||||||
|
T --> AA[Fill Out Wage Forms];
|
||||||
|
T --> AB[Manage Role Kit];
|
||||||
|
AB -- All Complete --> C;
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph MainApp
|
||||||
|
C --> AC[Home Screen];
|
||||||
|
AC --> AD{Navigate};
|
||||||
|
AD -- Shifts --> AE[Shift Management];
|
||||||
|
AD -- Earnings --> AF[Earnings Management];
|
||||||
|
AD -- Profile --> AG[Profile Management];
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph ShiftManagement
|
||||||
|
AE --> AH[View Shifts];
|
||||||
|
AH --> AI[View Shift Details];
|
||||||
|
AH --> AJ[Clock In/Out via QR];
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph EarningsManagement
|
||||||
|
AF --> AK[View Current Earnings];
|
||||||
|
AK --> AL[View Earnings History];
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph ProfileManagement
|
||||||
|
AG --> AM[View Profile];
|
||||||
|
AM --> AN[Manage Role Kit];
|
||||||
|
AM --> AO[Manage Certificates];
|
||||||
|
AM --> AP[Manage Schedule];
|
||||||
|
AM --> AQ[Manage Working Area];
|
||||||
|
AM --> AR[Update Live Photo];
|
||||||
|
AM --> AS[Manage Profile Settings];
|
||||||
|
AS --> AT[Update Personal Info];
|
||||||
|
AS --> AU[Update Email];
|
||||||
|
AU --> AV[Re-login with Phone];
|
||||||
|
AS --> AW[Update Address];
|
||||||
|
AM --> AX[Manage Wage Forms];
|
||||||
|
AM --> AY[Manage Bank Account];
|
||||||
|
AM --> AZ[View Benefits];
|
||||||
|
AM --> BA[Access Support];
|
||||||
|
BA --> BB[View FAQs];
|
||||||
|
BA --> BC[Contact Support];
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph QRScanning
|
||||||
|
AJ --> BD[Scan QR Code];
|
||||||
|
end
|
||||||
@@ -9,6 +9,8 @@
|
|||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<!-- Bootstrap Icons -->
|
<!-- Bootstrap Icons -->
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
|
||||||
|
<!-- Mermaid -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.6.1/mermaid.min.js"></script>
|
||||||
<!-- Custom CSS -->
|
<!-- Custom CSS -->
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
@@ -25,6 +27,7 @@
|
|||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border-right: 1px solid #dee2e6;
|
border-right: 1px solid #dee2e6;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar .nav-link {
|
.sidebar .nav-link {
|
||||||
@@ -54,14 +57,33 @@
|
|||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-subheading {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #868e96;
|
||||||
|
padding: 0 1rem 0 2rem;
|
||||||
|
margin-top: 0.75rem;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link.sub-item {
|
||||||
|
padding-left: 2.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link.sub-sub-item {
|
||||||
|
padding-left: 3.5rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
.content-area {
|
.content-area {
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#diagram-viewer {
|
#diagram-viewer {
|
||||||
display: none; /* Hidden by default */
|
display: none;
|
||||||
height: calc(100vh - 4rem); /* Full height minus padding */
|
height: calc(100vh - 4rem);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
@@ -74,9 +96,31 @@
|
|||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
border: 1px solid #dee2e6;
|
border: 1px solid #dee2e6;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 2rem;
|
||||||
}
|
}
|
||||||
#diagram-container:focus { outline: none; }
|
|
||||||
|
|
||||||
|
#diagram-container:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
|
||||||
|
#diagram-container:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#diagram-container svg {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@@ -85,27 +129,30 @@
|
|||||||
<!-- Sidebar -->
|
<!-- Sidebar -->
|
||||||
<nav class="sidebar">
|
<nav class="sidebar">
|
||||||
<div class="d-flex justify-content-center align-items-center mb-4">
|
<div class="d-flex justify-content-center align-items-center mb-4">
|
||||||
<img src="logo.svg" alt="Krow Logo" style="height: 60px;">
|
<img src="logo.svg" alt="Krow Logo" style="height: 60px;" onerror="this.style.display='none'">
|
||||||
</div>
|
</div>
|
||||||
<div class="nav flex-column nav-pills">
|
<div class="nav flex-column nav-pills" id="sidebar-nav">
|
||||||
<a class="nav-link active" href="#" id="nav-home" onclick="showView('home', this)">
|
<a class="nav-link active" href="#" id="nav-home" onclick="showView('home', this)">
|
||||||
<i class="bi bi-house-door"></i>Home
|
<i class="bi bi-house-door"></i>Home
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="sidebar-heading">Diagrams</div>
|
<div class="sidebar-heading">Static Diagrams</div>
|
||||||
|
|
||||||
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/high-level-overview.svg', 'Apps High-Level Overview')">
|
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/high-level-overview.svg', 'Apps High-Level Overview', 'svg')">
|
||||||
<i class="bi bi-diagram-3"></i>High-Level Overview
|
<i class="bi bi-diagram-3"></i>High-Level Overview
|
||||||
</a>
|
</a>
|
||||||
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/shift-lifecycle-workflow.svg', 'Core Workflow - Shift Lifecycle')">
|
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/shift-lifecycle-workflow.svg', 'Core Workflow - Shift Lifecycle', 'svg')">
|
||||||
<i class="bi bi-arrow-repeat"></i>Shift Lifecycle
|
<i class="bi bi-arrow-repeat"></i>Shift Lifecycle
|
||||||
</a>
|
</a>
|
||||||
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/invoice-workflow.svg', 'Invoice Workflow - Complete')">
|
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/invoice-workflow.svg', 'Invoice Workflow - Complete', 'svg')">
|
||||||
<i class="bi bi-receipt"></i>Invoice Workflow
|
<i class="bi bi-receipt"></i>Invoice Workflow
|
||||||
</a>
|
</a>
|
||||||
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/complete-workflow.svg', 'Complete Workflow')">
|
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/complete-workflow.svg', 'Complete Workflow', 'svg')">
|
||||||
<i class="bi bi-infinity"></i>Complete Workflow
|
<i class="bi bi-infinity"></i>Complete Workflow
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<!-- Dynamic Mermaid diagrams will be inserted here -->
|
||||||
|
<div id="dynamic-diagrams-section"></div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@@ -187,6 +234,8 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/@panzoom/panzoom@4.5.1/dist/panzoom.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@panzoom/panzoom@4.5.1/dist/panzoom.min.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
let mermaidDiagrams = [];
|
||||||
|
|
||||||
const homeView = document.getElementById('home-view');
|
const homeView = document.getElementById('home-view');
|
||||||
const diagramViewer = document.getElementById('diagram-viewer');
|
const diagramViewer = document.getElementById('diagram-viewer');
|
||||||
const diagramContainer = document.getElementById('diagram-container');
|
const diagramContainer = document.getElementById('diagram-container');
|
||||||
@@ -197,6 +246,123 @@
|
|||||||
const resetBtn = document.getElementById('resetBtn');
|
const resetBtn = document.getElementById('resetBtn');
|
||||||
|
|
||||||
let panzoomInstance = null;
|
let panzoomInstance = null;
|
||||||
|
let currentScale = 1;
|
||||||
|
|
||||||
|
// Initialize Mermaid
|
||||||
|
mermaid.initialize({
|
||||||
|
startOnLoad: false,
|
||||||
|
theme: 'default',
|
||||||
|
flowchart: {
|
||||||
|
useMaxWidth: false,
|
||||||
|
htmlLabels: true,
|
||||||
|
curve: 'basis'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Build hierarchical structure from paths
|
||||||
|
function buildDiagramHierarchy(diagrams) {
|
||||||
|
const hierarchy = {};
|
||||||
|
|
||||||
|
diagrams.forEach(diagram => {
|
||||||
|
const parts = diagram.path.split('/');
|
||||||
|
// Remove 'assets/diagrams/' prefix
|
||||||
|
const relevantParts = parts.slice(2, -1); // Everything except filename
|
||||||
|
const filename = parts[parts.length - 1].replace('.mermaid', '');
|
||||||
|
|
||||||
|
let current = hierarchy;
|
||||||
|
relevantParts.forEach(part => {
|
||||||
|
if (!current[part]) {
|
||||||
|
current[part] = { _items: [], _children: {} };
|
||||||
|
}
|
||||||
|
current = current[part]._children;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add the item to the last level
|
||||||
|
const lastLevel = relevantParts.length > 0 ?
|
||||||
|
relevantParts.reduce((acc, part) => acc[part]._children, hierarchy) :
|
||||||
|
hierarchy;
|
||||||
|
|
||||||
|
if (relevantParts.length > 0) {
|
||||||
|
const parentKey = relevantParts[relevantParts.length - 1];
|
||||||
|
if (!hierarchy[relevantParts[0]]) {
|
||||||
|
hierarchy[relevantParts[0]] = { _items: [], _children: {} };
|
||||||
|
}
|
||||||
|
let parent = hierarchy[relevantParts[0]];
|
||||||
|
for (let i = 1; i < relevantParts.length; i++) {
|
||||||
|
parent = parent._children[relevantParts[i]];
|
||||||
|
}
|
||||||
|
parent._items.push(diagram);
|
||||||
|
} else {
|
||||||
|
if (!hierarchy._root) {
|
||||||
|
hierarchy._root = { _items: [], _children: {} };
|
||||||
|
}
|
||||||
|
hierarchy._root._items.push(diagram);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return hierarchy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create navigation from hierarchy
|
||||||
|
function createNavigation(hierarchy, parentElement, level = 0) {
|
||||||
|
Object.keys(hierarchy).forEach(key => {
|
||||||
|
if (key === '_items' || key === '_children' || key === '_root') return;
|
||||||
|
|
||||||
|
const section = hierarchy[key];
|
||||||
|
const heading = document.createElement('div');
|
||||||
|
heading.className = level === 0 ? 'sidebar-heading' : 'sidebar-subheading';
|
||||||
|
heading.textContent = key.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
||||||
|
parentElement.appendChild(heading);
|
||||||
|
|
||||||
|
// Add items in this section
|
||||||
|
if (section._items && section._items.length > 0) {
|
||||||
|
section._items.forEach(diagram => {
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.className = `nav-link ${level > 0 ? 'sub-item' : ''}`;
|
||||||
|
link.href = '#';
|
||||||
|
link.onclick = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
showView('diagram', link, diagram.path, diagram.title, 'mermaid');
|
||||||
|
};
|
||||||
|
link.innerHTML = `<i class="bi bi-file-earmark-code"></i>${diagram.title}`;
|
||||||
|
parentElement.appendChild(link);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively add children
|
||||||
|
if (section._children && Object.keys(section._children).length > 0) {
|
||||||
|
createNavigation(section._children, parentElement, level + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load and render dynamic diagrams navigation
|
||||||
|
async function loadDynamicDiagrams() {
|
||||||
|
const dynamicSection = document.getElementById('dynamic-diagrams-section');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch the diagrams configuration from JSON file
|
||||||
|
const response = await fetch('./assets/diagrams/diagrams-config.json');
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to load diagrams config: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
mermaidDiagrams = await response.json();
|
||||||
|
|
||||||
|
if (mermaidDiagrams.length > 0) {
|
||||||
|
const mainHeading = document.createElement('div');
|
||||||
|
mainHeading.className = 'sidebar-heading';
|
||||||
|
mainHeading.textContent = 'Mermaid Diagrams';
|
||||||
|
dynamicSection.appendChild(mainHeading);
|
||||||
|
|
||||||
|
const hierarchy = buildDiagramHierarchy(mermaidDiagrams);
|
||||||
|
createNavigation(hierarchy, dynamicSection);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading diagrams configuration:', error);
|
||||||
|
dynamicSection.innerHTML = `<div class="alert alert-warning m-2 small">No Mermaid diagrams configuration found</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setActiveNav(activeLink) {
|
function setActiveNav(activeLink) {
|
||||||
document.querySelectorAll('.sidebar .nav-link').forEach(link => {
|
document.querySelectorAll('.sidebar .nav-link').forEach(link => {
|
||||||
@@ -205,10 +371,14 @@
|
|||||||
activeLink.classList.add('active');
|
activeLink.classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function showView(viewName, navLink, svgPath, title) {
|
async function showView(viewName, navLink, filePath, title, type = 'svg') {
|
||||||
setActiveNav(navLink);
|
setActiveNav(navLink);
|
||||||
if (panzoomInstance) panzoomInstance.destroy();
|
if (panzoomInstance) {
|
||||||
|
panzoomInstance.destroy();
|
||||||
|
panzoomInstance = null;
|
||||||
|
}
|
||||||
diagramContainer.innerHTML = '';
|
diagramContainer.innerHTML = '';
|
||||||
|
currentScale = 1;
|
||||||
|
|
||||||
if (viewName === 'home') {
|
if (viewName === 'home') {
|
||||||
homeView.style.display = 'block';
|
homeView.style.display = 'block';
|
||||||
@@ -217,30 +387,59 @@
|
|||||||
homeView.style.display = 'none';
|
homeView.style.display = 'none';
|
||||||
diagramViewer.style.display = 'flex';
|
diagramViewer.style.display = 'flex';
|
||||||
diagramTitle.textContent = title;
|
diagramTitle.textContent = title;
|
||||||
diagramContainer.innerHTML = '<div class="d-flex justify-content-center align-items-center h-100"><div class="spinner-border" role="status"><span class="visually-hidden">Loading...</span></div></div>';
|
diagramContainer.innerHTML = '<div class="loading-spinner"><div class="spinner-border" role="status"><span class="visually-hidden">Loading...</span></div></div>';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(svgPath);
|
if (type === 'svg') {
|
||||||
if (!response.ok) throw new Error(`Network error: ${response.status}`);
|
// Load static SVG files
|
||||||
const svgContent = await response.text();
|
const response = await fetch(filePath);
|
||||||
|
if (!response.ok) throw new Error(`Network error: ${response.status}`);
|
||||||
const parser = new DOMParser();
|
const svgContent = await response.text();
|
||||||
const svgDoc = parser.parseFromString(svgContent, "image/svg+xml");
|
|
||||||
const svgElement = svgDoc.querySelector('svg');
|
const parser = new DOMParser();
|
||||||
|
const svgDoc = parser.parseFromString(svgContent, "image/svg+xml");
|
||||||
|
const svgElement = svgDoc.querySelector('svg');
|
||||||
|
|
||||||
if (svgElement) {
|
if (svgElement) {
|
||||||
diagramContainer.innerHTML = '';
|
diagramContainer.innerHTML = '';
|
||||||
diagramContainer.appendChild(svgElement);
|
diagramContainer.appendChild(svgElement);
|
||||||
panzoomInstance = Panzoom(svgElement, {
|
panzoomInstance = Panzoom(svgElement, {
|
||||||
canvas: true,
|
canvas: true,
|
||||||
maxScale: 10,
|
maxScale: 10,
|
||||||
minScale: 0.3,
|
minScale: 0.3,
|
||||||
zoomOnDblClick: false
|
startScale: 1
|
||||||
});
|
});
|
||||||
diagramContainer.addEventListener('wheel', panzoomInstance.zoomWithWheel);
|
diagramContainer.addEventListener('wheel', panzoomInstance.zoomWithWheel);
|
||||||
diagramContainer.focus();
|
diagramContainer.focus();
|
||||||
} else {
|
} else {
|
||||||
throw new Error('No SVG element found.');
|
throw new Error('No SVG element found.');
|
||||||
|
}
|
||||||
|
} else if (type === 'mermaid') {
|
||||||
|
// Load and render Mermaid files
|
||||||
|
const response = await fetch(filePath);
|
||||||
|
if (!response.ok) throw new Error(`Network error: ${response.status}`);
|
||||||
|
const mermaidCode = await response.text();
|
||||||
|
|
||||||
|
const { svg } = await mermaid.render('mermaidDiagram_' + Date.now(), mermaidCode);
|
||||||
|
|
||||||
|
diagramContainer.innerHTML = svg;
|
||||||
|
const svgElement = diagramContainer.querySelector('svg');
|
||||||
|
|
||||||
|
if (svgElement) {
|
||||||
|
svgElement.style.maxWidth = 'none';
|
||||||
|
svgElement.style.height = 'auto';
|
||||||
|
|
||||||
|
panzoomInstance = Panzoom(svgElement, {
|
||||||
|
canvas: true,
|
||||||
|
maxScale: 10,
|
||||||
|
minScale: 0.3,
|
||||||
|
startScale: 1
|
||||||
|
});
|
||||||
|
diagramContainer.addEventListener('wheel', panzoomInstance.zoomWithWheel);
|
||||||
|
diagramContainer.focus();
|
||||||
|
} else {
|
||||||
|
throw new Error('Failed to render Mermaid diagram.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
diagramContainer.innerHTML = `<div class="alert alert-danger m-3">Failed to load diagram: ${error.message}</div>`;
|
diagramContainer.innerHTML = `<div class="alert alert-danger m-3">Failed to load diagram: ${error.message}</div>`;
|
||||||
@@ -248,11 +447,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
zoomInBtn.addEventListener('click', () => { panzoomInstance?.zoomIn(); diagramContainer.focus(); });
|
zoomInBtn.addEventListener('click', () => {
|
||||||
zoomOutBtn.addEventListener('click', () => { panzoomInstance?.zoomOut(); diagramContainer.focus(); });
|
if (panzoomInstance) {
|
||||||
resetBtn.addEventListener('click', () => { panzoomInstance?.reset(); diagramContainer.focus(); });
|
panzoomInstance.zoomIn();
|
||||||
|
diagramContainer.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
zoomOutBtn.addEventListener('click', () => {
|
||||||
|
if (panzoomInstance) {
|
||||||
|
panzoomInstance.zoomOut();
|
||||||
|
diagramContainer.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resetBtn.addEventListener('click', () => {
|
||||||
|
if (panzoomInstance) {
|
||||||
|
panzoomInstance.reset();
|
||||||
|
diagramContainer.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
loadDynamicDiagrams();
|
||||||
showView('home', document.getElementById('nav-home'));
|
showView('home', document.getElementById('nav-home'));
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user