Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(ui): Replace base64 assets by image #47

Merged
merged 3 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.4.2 / 2024-07-05

* [CHANGE] Replaced base64 encoded files in web assets (HTML, CSS) with common images and added a new route for images.

## 0.4.1 / 2024-06-30

* [ENHANCEMENT] Added a new web page for reports. This page allows exporting Prometheus data in various formats directly from the web UI. #43
Expand Down
26 changes: 22 additions & 4 deletions src/api/v1/endpoints/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,38 @@
from src.utils.log import logger
from fastapi import APIRouter
from fastapi import Request
from os.path import exists

router = APIRouter()

if arg_parser().get("web.enable_ui") == "true":
rules_management = "ui/rules-management"
metrics_management = "ui/metrics-management"
reports = "ui/reports"
rules_management = "ui/pages/rules-management"
metrics_management = "ui/pages/metrics-management"
reports = "ui/pages/reports"
logger.info("Starting web management UI")

@router.get("/", response_class=HTMLResponse,
description="Renders home page of this application",
include_in_schema=False)
async def homepage():
return FileResponse("ui/homepage/index.html")
return FileResponse("ui/pages/homepage/index.html")

@router.get(
"/images/{path}",
description="Returns common image resources for web UI",
include_in_schema=False)
async def images(path, request: Request):
assets_images = "ui/assets/images"
if exists(f"{assets_images}/{path}"):
return FileResponse(f"{assets_images}/{path}")
sts, msg = "404", "Not Found"
logger.info(
msg=msg,
extra={
"status": sts,
"method": request.method,
"request_path": request.url.path})
return f"{sts} {msg}"

@router.get("/rules-management",
description="Renders rules management HTML page of this application",
Expand Down
2 changes: 1 addition & 1 deletion src/utils/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def openapi(app: FastAPI):
"providing additional features and addressing its limitations. "
"Running as a sidecar alongside the Prometheus server enables "
"users to extend the capabilities of the API.",
version="0.4.1",
version="0.4.2",
contact={
"name": "Hayk Davtyan",
"url": "https://hayk96.github.io",
Expand Down
Binary file added ui/assets/images/icon-edit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/assets/images/icon-home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/assets/images/icon-metrics-management.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/assets/images/icon-moon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/assets/images/icon-remove.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/assets/images/icon-reports.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/assets/images/icon-rules-management.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/assets/images/icon-sun.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/assets/images/icon-web-code.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/assets/images/logo-github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/assets/images/logo-prometheus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
194 changes: 0 additions & 194 deletions ui/homepage/index.html

This file was deleted.

72 changes: 0 additions & 72 deletions ui/metrics-management/index.html

This file was deleted.

194 changes: 194 additions & 0 deletions ui/pages/homepage/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Extended HTTP API service for Prometheus</title>
<link rel="icon" type="image/png" href="https://raw.githubusercontent.com/hayk96/prometheus-api/main/docs/images/logo.png">
<style>
body, h1, ul, li, a {
margin: 0;
padding: 0;
}
body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
background-size: 200% 200%;
animation: backgroundShift 10s ease infinite;
}

@keyframes backgroundShift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}

a {
color: white;
text-decoration: none;
}

nav {
position: fixed;
top: 0;
left: 0;
right: 0;
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
background: #30354b;
box-shadow: 0 2px 5px rgba(40, 14, 14, 0.3);
z-index: 1000;
}
.navbar-logo {
height: 50px;
animation: enterLogo 1s ease-out forwards;
}

@keyframes enterLogo {
0% { transform: scale(0); }
80% { transform: scale(1.1); }
100% { transform: scale(1); }
}

.nav-title {
margin-left: 10px;
font-size: 20px;
font-weight: 500;
}
.nav-menu {
display: flex;
align-items: center;
list-style: none;
}
.nav-item:not(:last-child) {
margin-right: 20px;
}
.nav-link {
display: flex;
align-items: center;
}
.nav-link img {
height: 20px;
margin-right: 8px;
}

.nav-link:hover {
animation: linkPulse 1s infinite;
}

@keyframes linkPulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}

.container {
text-align: center;
max-width: 400px;
width: 90%;
padding: 2rem;
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
position: relative;
top: 60px;
}
h1 {
font-size: 2rem;
margin-bottom: 1rem;
}
button {
font-size: 1rem;
padding: 0.75rem 1.5rem;
margin: 0.5rem;
border: none;
border-radius: 20px;
cursor: pointer;
transition: all 0.3s ease;
color: #ffffff;
background-image: linear-gradient(45deg, #f6d365, #fda085);
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16);
width: 200px;
}
button:hover {
animation: buttonPulse 0.5s ease;
}

@keyframes buttonPulse {
from { transform: translateY(0); }
50% { transform: translateY(-5px); }
to { transform: translateY(0); }
}

@media (max-width: 768px) {
.nav-title {
display: none;
}
.nav-link img {
margin-right: 5px;
}
.container {
padding: 1.5rem;
top: 30px;
width: 95%;
}
button {
padding: 0.5rem 1rem;
}
}
</style>
</head>
<body>
<nav>
<div style="display: flex; align-items: center;">
<img src="https://raw.githubusercontent.com/hayk96/prometheus-api/main/docs/images/logo.png" alt="Prometheus API" class="navbar-logo">
<span class="nav-title">Prometheus API</span>
</div>
<ul class="nav-menu">
<li class="nav-item">
<a href="https://github.com/hayk96/prometheus-api" class="nav-link">
<img src="/images/logo-github.png" alt="GitHub Logo">GitHub
</a>
</li>
<li class="nav-item">
<a href="#" id="apiDocumentationLink" class="nav-link">
<img src="/images/icon-web-code.png" alt="Prometheus Docs Logo">API Documentation
</a>
</li>
</ul>
</nav>
<div class="container">
<h1>The easiest Prometheus management interface</h1>
<button id="openPrometheusButton">Open Prometheus</button>
<button id="rulesManagementButton">Rules Management</button>
<button id="metricsManagementButton">Metrics Management</button>
<button id="reportsButton">Reports</button>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('apiDocumentationLink').href = window.location.origin + '/redoc';
document.getElementById('openPrometheusButton').onclick = function() {
window.location.href = window.location.origin + '/graph';
};
document.getElementById('rulesManagementButton').onclick = function() {
window.location.href = window.location.origin + '/rules-management';
};
document.getElementById('metricsManagementButton').onclick = function() {
window.location.href = window.location.origin + '/metrics-management';
};
document.getElementById('reportsButton').onclick = function() {
window.location.href = window.location.origin + '/reports';
};
});
</script>
</body>
</html>
72 changes: 72 additions & 0 deletions ui/pages/metrics-management/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Metrics Management</title>
<link rel="stylesheet" href="/metrics-management/style.css">
<link rel="icon" type="image/png" href="https://raw.githubusercontent.com/hayk96/prometheus-api/main/docs/images/logo.png">
</head>
<body>
<div id="sidebar" class="sidebar">
<a href="#" class="sidebar-icon" id="homeBtn">
<img src="/images/icon-home.png" alt="Home"/>
<span class="icon-label">Home</span>
</a>
<a href="#" class="sidebar-icon" id="prometheusBtn">
<img src="/images/logo-prometheus.png" alt="Prometheus"/>
<span class="icon-label">Prometheus</span>
</a>
<a href="/rules-management" class="sidebar-icon" id="rulesManagement">
<img src="/images/icon-rules-management.png" alt="Rules Management"/>
<span class="icon-label">Rules Management</span>
</a>
<a href="/reports" class="sidebar-icon" id="reportsPage">
<img src="/images/icon-reports.png" alt="Reports"/>
<span class="icon-label">Reports</span>
</a>
</div>
<div class="main-content">
<div class="toolbar">
<button id="createPolicyBtn" class="action-btn create-btn">Create</button>
<input type="text" id="searchInput" placeholder="Search by pattern..." class="search-bar">
</div>
<div id="policiesList" class="policies-list"></div>
<div id="createPolicyModal" class="modal">
<div class="modal-content">
<h2>Create New Policy</h2>
<input type="text" id="newPolicyName" placeholder="Kubernetes policy" class="modal-input" />
<input type="text" id="newPolicyMatch" placeholder="{job='kubernetes-pods'}" class="modal-input" />
<input type="text" id="newPolicyKeepFor" placeholder="7d" class="modal-input" />
<textarea id="newPolicyDescription" placeholder="Keeps Kubernetes pod metrics for 7 days" class="modal-input"></textarea>
<div id="createPolicyError" class="modal-error-message"></div>
<button id="submitNewPolicy" class="modal-btn modal-btn-create">Create</button>
<button id="cancelCreatePolicyBtn" class="modal-btn modal-btn-cancel-create">Cancel</button>
</div>
</div>

<div id="editPolicyModal" class="modal">
<div class="modal-content">
<h2>Edit Policy</h2>
<input type="text" id="editPolicyName" class="modal-input" disabled />
<textarea type="text" id="editPolicyMatch" class="modal-input"></textarea>
<input type="text" id="editPolicyKeepFor" class="modal-input" />
<textarea id="editPolicyDescription" class="modal-input"></textarea>
<div id="editPolicyError" class="modal-error-message"></div>
<button id="submitEditPolicy" class="modal-btn modal-btn-confirm">Save</button>
<button id="cancelEditPolicyBtn" class="modal-btn modal-btn-cancel">Cancel</button>
</div>
</div>

<div id="deletePolicyModal" class="modal">
<div class="modal-content">
<h2>Delete Policy</h2>
<p id="deletePolicyMessage">Are you sure you want to delete this policy?</p>
<button id="confirmDeletePolicyBtn" class="modal-btn modal-btn-confirm delete-btn">Delete</button>
<button id="cancelDeletePolicyBtn" class="modal-btn modal-btn-cancel">Cancel</button>
</div>
</div>
</div>
<script src="/metrics-management/script.js"></script>
</body>
</html>
Loading
Loading