forked from seokho-son/cb-mapui
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add integrated API dashboard redoc swagger
- Loading branch information
1 parent
6e54e9a
commit b1500c4
Showing
4 changed files
with
227 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>CB-Tumblebug API Dashboard</title> | ||
<style> | ||
body { | ||
font-family: Arial, sans-serif; | ||
margin: 0; | ||
padding: 0; | ||
display: flex; | ||
flex-direction: column; | ||
height: 100vh; | ||
width: 100vw; | ||
overflow: hidden; | ||
} | ||
|
||
#title-bar { | ||
height: 50px; /* Height for the title bar */ | ||
background-color: #262626; | ||
color: #fcfcfc; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
font-size: 20px; | ||
font-weight: bold; | ||
} | ||
|
||
#content-container { | ||
display: flex; | ||
height: calc(100vh - 50px); /* Remaining height after title bar */ | ||
width: 100%; | ||
} | ||
|
||
#redoc-container { | ||
width: 65%; /* Redoc is now on the left side */ | ||
height: 100%; | ||
overflow-y: scroll; | ||
border-right: 1px solid #ddd; | ||
} | ||
|
||
|
||
#swagger-container { | ||
width: 35%; /* Swagger UI is now on the right side */ | ||
height: 100%; | ||
display: flex; | ||
flex-direction: column; | ||
} | ||
#swagger-header { | ||
height: 40px; | ||
background-color: #ffffff; | ||
color: rgb(0, 0, 0); | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
z-index: 1000; | ||
position: sticky; /* Make header stick to the top */ | ||
top: 0; | ||
} | ||
#swagger-ui-container { | ||
height: calc(100% - 40px); /* Adjust height based on header */ | ||
overflow-y: scroll; | ||
} | ||
</style> | ||
|
||
<!-- Load Swagger UI styles --> | ||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.14/swagger-ui.css"> | ||
</head> | ||
<body> | ||
<div id="title-bar"> CB-Tumblebug API Dashboard</div> | ||
|
||
<div id="content-container"> | ||
<div id="redoc-container"></div> | ||
<div id="swagger-container"> | ||
<div id="swagger-header">Try out API with Swagger UI</div> | ||
<div id="swagger-ui-container"></div> | ||
</div> | ||
|
||
</div> | ||
|
||
<!-- Load the latest Redoc and Swagger UI scripts --> | ||
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.14/swagger-ui-bundle.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.14/swagger-ui-standalone-preset.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js-yaml.min.js"></script> | ||
|
||
<script> | ||
// Basic authentication details | ||
const username = 'default'; | ||
const password = 'default'; | ||
const credentials = btoa(username + ':' + password); | ||
const authHeader = 'Basic ' + credentials; | ||
|
||
console.log('Starting to fetch YAML'); | ||
|
||
// Fetch the YAML file with authentication | ||
fetch('http://localhost:1323/tumblebug/api/doc.yaml', { | ||
headers: { | ||
'Authorization': authHeader | ||
} | ||
}) | ||
.then(response => { | ||
console.log('Fetch response:', response); | ||
if (!response.ok) { | ||
throw new Error('Authentication failed: ' + response.statusText); | ||
} | ||
return response.text(); | ||
}) | ||
.then(yamlText => { | ||
console.log('YAML fetched successfully'); | ||
const spec = jsyaml.load(yamlText); | ||
|
||
console.log('YAML parsed successfully'); | ||
|
||
// Initialize Swagger UI (placed on the right side) | ||
const ui = SwaggerUIBundle({ | ||
url: 'http://localhost:1323/tumblebug/api/doc.yaml', | ||
dom_id: '#swagger-ui-container', | ||
presets: [ | ||
SwaggerUIBundle.presets.apis, | ||
SwaggerUIStandalonePreset | ||
], | ||
layout: "BaseLayout", | ||
deepLinking: true, // Enable deep linking | ||
displayOperationId: true, // Display operationId in Swagger UI | ||
requestInterceptor: (request) => { | ||
request.headers['Authorization'] = authHeader; | ||
return request; | ||
}, | ||
validatorUrl: null, | ||
onComplete: () => { | ||
console.log('Swagger UI loaded'); | ||
} | ||
}); | ||
|
||
console.log('Swagger UI initialized'); | ||
|
||
// Initialize Redoc (placed on the left side) | ||
Redoc.init(spec, { | ||
scrollYOffset: 50, | ||
hideLoading: true, | ||
theme: { | ||
colors: { | ||
primary: { | ||
main: '#dd5522' | ||
} | ||
}, | ||
typography: { | ||
fontFamily: 'Arial, sans-serif', | ||
fontSize: '18px', | ||
headings: { | ||
fontFamily: 'Arial, sans-serif' | ||
} | ||
}, | ||
} | ||
}, document.getElementById('redoc-container')); | ||
|
||
console.log('Redoc initialized'); | ||
|
||
// Function to remove special characters from a string | ||
function removeSpecialCharacters(str) { | ||
return str.replace(/[^a-zA-Z0-9]/g, ''); | ||
} | ||
|
||
// Use MutationObserver to detect URL hash changes | ||
const observer = new MutationObserver(() => { | ||
const hash = window.location.hash; | ||
if (hash.startsWith('#tag')) { // Only proceed if the hash starts with #tag | ||
const operationId = hash.split('/').pop(); | ||
|
||
// Find the corresponding operation in Swagger UI based on the operationId | ||
const allOperations = document.querySelectorAll('#swagger-ui-container [id]'); | ||
let targetOperation = null; | ||
|
||
allOperations.forEach(op => { | ||
const idAttribute = op.getAttribute('id'); | ||
const idParts = idAttribute.split('-'); | ||
const lastIdPart = idParts.pop(); | ||
|
||
// Check if the last part of the id matches the operationId | ||
if (lastIdPart === operationId) { | ||
targetOperation = op; | ||
} | ||
|
||
if (idAttribute.includes('operations-tag-')) { | ||
const idWithoutPrefix = idAttribute.replace('operations-tag-', ''); | ||
const idWithoutSpecialChars = removeSpecialCharacters(idWithoutPrefix); | ||
const operationIdWithoutSpecialChars = removeSpecialCharacters(operationId); | ||
if (!targetOperation && idWithoutSpecialChars === operationIdWithoutSpecialChars) { | ||
targetOperation = op; | ||
} | ||
} | ||
}); | ||
|
||
if (targetOperation) { | ||
console.log('Target found for operationId:', operationId); | ||
targetOperation.scrollIntoView({ behavior: 'smooth' }); | ||
} else { | ||
console.log('Target not found for operationId:', operationId); | ||
} | ||
} | ||
}); | ||
|
||
// Observe changes to the URL hash | ||
observer.observe(document.querySelector('body'), { | ||
attributes: true, | ||
childList: true, | ||
subtree: true | ||
}); | ||
|
||
}) | ||
.catch(error => { | ||
console.error('Failed to load API specification:', error); | ||
alert('Failed to load API specification: ' + error.message); | ||
}); | ||
</script> | ||
</body> | ||
</html> | ||
|
||
|