406 lines
9.9 KiB
PHP
406 lines
9.9 KiB
PHP
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>API Documentation - CLQMS</title>
|
||
|
|
|
||
|
|
<!-- Swagger UI CSS -->
|
||
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css">
|
||
|
|
|
||
|
|
<style>
|
||
|
|
html {
|
||
|
|
box-sizing: border-box;
|
||
|
|
overflow: -moz-scrollbars-vertical;
|
||
|
|
overflow-y: scroll;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Custom Scrollbar for Webkit */
|
||
|
|
::-webkit-scrollbar {
|
||
|
|
width: 8px;
|
||
|
|
height: 8px;
|
||
|
|
}
|
||
|
|
::-webkit-scrollbar-track {
|
||
|
|
background: transparent;
|
||
|
|
}
|
||
|
|
::-webkit-scrollbar-thumb {
|
||
|
|
background: #888;
|
||
|
|
border-radius: 4px;
|
||
|
|
}
|
||
|
|
::-webkit-scrollbar-thumb:hover {
|
||
|
|
background: #555;
|
||
|
|
}
|
||
|
|
|
||
|
|
*,
|
||
|
|
*:before,
|
||
|
|
*:after {
|
||
|
|
box-sizing: inherit;
|
||
|
|
}
|
||
|
|
|
||
|
|
body {
|
||
|
|
margin: 0;
|
||
|
|
padding: 0;
|
||
|
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||
|
|
display: flex; /* Sidebar layout */
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Sidebar Styles */
|
||
|
|
#custom-sidebar {
|
||
|
|
width: 280px;
|
||
|
|
height: 100vh;
|
||
|
|
position: fixed;
|
||
|
|
left: 0;
|
||
|
|
top: 0;
|
||
|
|
overflow-y: auto;
|
||
|
|
background: #fafafa;
|
||
|
|
border-right: 1px solid #ddd;
|
||
|
|
padding: 20px 0;
|
||
|
|
z-index: 1000;
|
||
|
|
transition: background 0.3s, border-color 0.3s;
|
||
|
|
}
|
||
|
|
|
||
|
|
#custom-sidebar h2 {
|
||
|
|
padding: 0 20px;
|
||
|
|
font-size: 1.2rem;
|
||
|
|
margin-bottom: 1rem;
|
||
|
|
color: #3b4151;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-link {
|
||
|
|
display: block;
|
||
|
|
padding: 8px 20px;
|
||
|
|
color: #3b4151;
|
||
|
|
text-decoration: none;
|
||
|
|
font-size: 0.9rem;
|
||
|
|
border-left: 3px solid transparent;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: all 0.2s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-link:hover {
|
||
|
|
background: rgba(0,0,0,0.05);
|
||
|
|
color: #000;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-link.active {
|
||
|
|
border-left-color: #49cc90; /* Swagger Green */
|
||
|
|
background: rgba(73, 204, 144, 0.1);
|
||
|
|
font-weight: 600;
|
||
|
|
color: #49cc90;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Main Content Adjustments */
|
||
|
|
#swagger-ui {
|
||
|
|
margin-left: 280px; /* Width of sidebar */
|
||
|
|
width: calc(100% - 280px);
|
||
|
|
height: 100vh;
|
||
|
|
}
|
||
|
|
|
||
|
|
#swagger-ui .information-container {
|
||
|
|
margin: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Dark theme support */
|
||
|
|
[data-theme="dark"] body {
|
||
|
|
background: #0d1117;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] #custom-sidebar {
|
||
|
|
background: #161b22;
|
||
|
|
border-right: 1px solid #30363d;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] #custom-sidebar h2 {
|
||
|
|
color: #c9d1d9;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .sidebar-link {
|
||
|
|
color: #8b949e;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .sidebar-link:hover {
|
||
|
|
background: rgba(255,255,255,0.05);
|
||
|
|
color: #c9d1d9;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .sidebar-link.active {
|
||
|
|
border-left-color: #58a6ff;
|
||
|
|
background: rgba(88, 166, 255, 0.1);
|
||
|
|
color: #58a6ff;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] #swagger-ui {
|
||
|
|
--swagger-ui-color: #8b949e;
|
||
|
|
--swagger-ui-bg: #0d1117;
|
||
|
|
--swagger-ui-primary: #58a6ff;
|
||
|
|
--swagger-ui-text: #c9d1d9;
|
||
|
|
--swagger-ui-border: #30363d;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui {
|
||
|
|
color-scheme: dark;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .info {
|
||
|
|
margin: 20px 0;
|
||
|
|
background: #161b22;
|
||
|
|
box-shadow: 0 1px 3px 0 rgba(0,0,0,0.3);
|
||
|
|
border: 1px solid #30363d;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .info .title {
|
||
|
|
color: #58a6ff;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .info .description {
|
||
|
|
color: #8b949e;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .opblock {
|
||
|
|
background: #0d1117;
|
||
|
|
border: 1px solid #30363d;
|
||
|
|
box-shadow: 0 1px 3px 0 rgba(0,0,0,0.3);
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .opblock .opblock-summary {
|
||
|
|
border-color: #30363d;
|
||
|
|
background: #161b22;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .opblock .opblock-summary-description {
|
||
|
|
color: #8b949e;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .opblock.opblock-get {
|
||
|
|
border-color: #3fb950;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .opblock.opblock-post {
|
||
|
|
border-color: #58a6ff;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .opblock.opblock-put {
|
||
|
|
border-color: #d29922;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .opblock.opblock-delete {
|
||
|
|
border-color: #f85149;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .opblock.opblock-patch {
|
||
|
|
border-color: #a371f7;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .scheme-container {
|
||
|
|
background: #161b22;
|
||
|
|
box-shadow: 0 1px 3px 0 rgba(0,0,0,0.3);
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .loading-container {
|
||
|
|
background: #0d1117;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .btn {
|
||
|
|
background: #21262d;
|
||
|
|
border-color: #30363d;
|
||
|
|
color: #c9d1d9;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .btn:hover {
|
||
|
|
background: #30363d;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui input[type="text"],
|
||
|
|
[data-theme="dark"] .swagger-ui textarea {
|
||
|
|
background: #0d1117;
|
||
|
|
border-color: #30363d;
|
||
|
|
color: #c9d1d9;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui select {
|
||
|
|
background: #0d1117;
|
||
|
|
border-color: #30363d;
|
||
|
|
color: #c9d1d9;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .model-title {
|
||
|
|
color: #58a6ff;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .property-name {
|
||
|
|
color: #8b949e;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .tab li {
|
||
|
|
color: #8b949e;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .tab li.active {
|
||
|
|
color: #58a6ff;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .responses-inner h4,
|
||
|
|
[data-theme="dark"] .swagger-ui .responses-inner h5 {
|
||
|
|
color: #c9d1d9;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .response-col_status {
|
||
|
|
color: #8b949e;
|
||
|
|
}
|
||
|
|
|
||
|
|
[data-theme="dark"] .swagger-ui .response-col_description {
|
||
|
|
color: #8b949e;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Responsive adjustments */
|
||
|
|
@media (max-width: 768px) {
|
||
|
|
body {
|
||
|
|
display: block; /* Stack on mobile */
|
||
|
|
}
|
||
|
|
|
||
|
|
#custom-sidebar {
|
||
|
|
width: 100%;
|
||
|
|
height: auto;
|
||
|
|
max-height: 200px;
|
||
|
|
position: relative;
|
||
|
|
border-right: none;
|
||
|
|
border-bottom: 1px solid #ddd;
|
||
|
|
}
|
||
|
|
|
||
|
|
#swagger-ui {
|
||
|
|
margin-left: 0;
|
||
|
|
width: 100%;
|
||
|
|
}
|
||
|
|
|
||
|
|
#swagger-ui .information-container {
|
||
|
|
padding: 10px;
|
||
|
|
}
|
||
|
|
|
||
|
|
#swagger-ui .info {
|
||
|
|
margin: 10px 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<div id="custom-sidebar">
|
||
|
|
<h2>Resources</h2>
|
||
|
|
<div id="sidebar-links"></div>
|
||
|
|
</div>
|
||
|
|
<div id="swagger-ui"></div>
|
||
|
|
|
||
|
|
<!-- Swagger UI Bundle -->
|
||
|
|
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
||
|
|
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-standalone-preset.js"></script>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
// Custom Sidebar Logic
|
||
|
|
function initCustomSidebar(ui) {
|
||
|
|
const sidebarLinks = document.getElementById('sidebar-links');
|
||
|
|
|
||
|
|
// Wait for Swagger UI to render tags
|
||
|
|
// We'll poll every 100ms for up to 5 seconds
|
||
|
|
let attempts = 0;
|
||
|
|
const maxAttempts = 50;
|
||
|
|
|
||
|
|
const interval = setInterval(() => {
|
||
|
|
attempts++;
|
||
|
|
const tags = document.querySelectorAll('.opblock-tag-section');
|
||
|
|
|
||
|
|
if (tags.length > 0 || attempts >= maxAttempts) {
|
||
|
|
clearInterval(interval);
|
||
|
|
buildSidebar(tags);
|
||
|
|
}
|
||
|
|
}, 100);
|
||
|
|
}
|
||
|
|
|
||
|
|
function buildSidebar(tags) {
|
||
|
|
const sidebarLinksContainer = document.getElementById('sidebar-links');
|
||
|
|
sidebarLinksContainer.innerHTML = ''; // Clear existing
|
||
|
|
|
||
|
|
if (tags.length === 0) {
|
||
|
|
sidebarLinksContainer.innerHTML = '<div style="padding:0 20px;color:#888;">No resources found</div>';
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
tags.forEach(tagSection => {
|
||
|
|
const tagHeader = tagSection.querySelector('.opblock-tag');
|
||
|
|
if (!tagHeader) return;
|
||
|
|
|
||
|
|
const tagName = tagHeader.getAttribute('data-tag');
|
||
|
|
const tagText = tagHeader.querySelector('a span') ? tagHeader.querySelector('a span').innerText : tagName;
|
||
|
|
const tagId = tagHeader.id; // e.g., operations-tag-Auth
|
||
|
|
|
||
|
|
const link = document.createElement('a');
|
||
|
|
link.className = 'sidebar-link';
|
||
|
|
link.textContent = tagText;
|
||
|
|
link.href = '#' + tagId;
|
||
|
|
|
||
|
|
link.onclick = (e) => {
|
||
|
|
e.preventDefault();
|
||
|
|
const target = document.getElementById(tagId);
|
||
|
|
if (target) {
|
||
|
|
target.scrollIntoView({ behavior: 'smooth' });
|
||
|
|
// Update active state
|
||
|
|
document.querySelectorAll('.sidebar-link').forEach(l => l.classList.remove('active'));
|
||
|
|
link.classList.add('active');
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
sidebarLinksContainer.appendChild(link);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
window.onload = function() {
|
||
|
|
// Get JWT token from localStorage
|
||
|
|
// JWT token handled via HttpOnly cookie automatically
|
||
|
|
|
||
|
|
// Initialize Swagger UI
|
||
|
|
const ui = SwaggerUIBundle({
|
||
|
|
url: "<?= base_url('api-docs.yaml') ?>",
|
||
|
|
dom_id: '#swagger-ui',
|
||
|
|
deepLinking: true,
|
||
|
|
presets: [
|
||
|
|
SwaggerUIBundle.presets.apis,
|
||
|
|
SwaggerUIStandalonePreset
|
||
|
|
],
|
||
|
|
plugins: [
|
||
|
|
SwaggerUIBundle.plugins.DownloadUrl
|
||
|
|
],
|
||
|
|
layout: "StandaloneLayout",
|
||
|
|
defaultModelsExpandDepth: 1,
|
||
|
|
defaultModelExpandDepth: 1,
|
||
|
|
displayOperationId: false,
|
||
|
|
displayRequestDuration: true,
|
||
|
|
docExpansion: "list",
|
||
|
|
filter: true,
|
||
|
|
showRequestHeaders: true,
|
||
|
|
showCommonExtensions: true,
|
||
|
|
tryItOutEnabled: true,
|
||
|
|
persistAuthorization: true,
|
||
|
|
withCredentials: true, // Enable cookies
|
||
|
|
syntaxHighlight: {
|
||
|
|
activate: true,
|
||
|
|
theme: "monokai"
|
||
|
|
},
|
||
|
|
validatorUrl: null,
|
||
|
|
|
||
|
|
onComplete: () => {
|
||
|
|
// Initialize Custom Sidebar
|
||
|
|
initCustomSidebar(ui);
|
||
|
|
},
|
||
|
|
|
||
|
|
// Request interceptor to ensure cookies are sent
|
||
|
|
requestInterceptor: (request) => {
|
||
|
|
// Ensure credentials (cookies) are included in the request
|
||
|
|
request.credentials = 'include';
|
||
|
|
return request;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
window.ui = ui;
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|