Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit 20900d9

Browse files
authored
refactor: Replace base64 assets by images #patch (#49)
Signed-off-by: hayk96 <hayko5999@gmail.com>
1 parent c9c082f commit 20900d9

29 files changed

+1160
-1138
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.4.2 / 2024-07-05
4+
5+
* [CHANGE] Replaced base64 encoded files in web assets (HTML, CSS) with common images and added a new route for images.
6+
37
## 0.4.1 / 2024-06-30
48

59
* [ENHANCEMENT] Added a new web page for reports. This page allows exporting Prometheus data in various formats directly from the web UI. #43

src/api/v1/endpoints/web.py

+22-4
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,38 @@
44
from src.utils.log import logger
55
from fastapi import APIRouter
66
from fastapi import Request
7+
from os.path import exists
78

89
router = APIRouter()
910

1011
if arg_parser().get("web.enable_ui") == "true":
11-
rules_management = "ui/rules-management"
12-
metrics_management = "ui/metrics-management"
13-
reports = "ui/reports"
12+
rules_management = "ui/pages/rules-management"
13+
metrics_management = "ui/pages/metrics-management"
14+
reports = "ui/pages/reports"
1415
logger.info("Starting web management UI")
1516

1617
@router.get("/", response_class=HTMLResponse,
1718
description="Renders home page of this application",
1819
include_in_schema=False)
1920
async def homepage():
20-
return FileResponse("ui/homepage/index.html")
21+
return FileResponse("ui/pages/homepage/index.html")
22+
23+
@router.get(
24+
"/images/{path}",
25+
description="Returns common image resources for web UI",
26+
include_in_schema=False)
27+
async def images(path, request: Request):
28+
assets_images = "ui/assets/images"
29+
if exists(f"{assets_images}/{path}"):
30+
return FileResponse(f"{assets_images}/{path}")
31+
sts, msg = "404", "Not Found"
32+
logger.info(
33+
msg=msg,
34+
extra={
35+
"status": sts,
36+
"method": request.method,
37+
"request_path": request.url.path})
38+
return f"{sts} {msg}"
2139

2240
@router.get("/rules-management",
2341
description="Renders rules management HTML page of this application",

src/utils/openapi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def openapi(app: FastAPI):
1616
"providing additional features and addressing its limitations. "
1717
"Running as a sidecar alongside the Prometheus server enables "
1818
"users to extend the capabilities of the API.",
19-
version="0.4.1",
19+
version="0.4.2",
2020
contact={
2121
"name": "Hayk Davtyan",
2222
"url": "https://hayk96.github.io",

ui/assets/images/icon-edit.png

4.08 KB
Loading

ui/assets/images/icon-home.png

5.17 KB
Loading
6.22 KB
Loading

ui/assets/images/icon-moon.png

7.75 KB
Loading

ui/assets/images/icon-remove.png

5.64 KB
Loading

ui/assets/images/icon-reports.png

14.6 KB
Loading
6.55 KB
Loading

ui/assets/images/icon-sun.png

3.27 KB
Loading

ui/assets/images/icon-web-code.png

7.28 KB
Loading

ui/assets/images/logo-github.png

7.43 KB
Loading

ui/assets/images/logo-prometheus.png

2.96 KB
Loading

ui/homepage/index.html

-194
This file was deleted.

ui/metrics-management/index.html

-72
This file was deleted.

ui/pages/homepage/index.html

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Extended HTTP API service for Prometheus</title>
7+
<link rel="icon" type="image/png" href="https://raw.githubusercontent.com/hayk96/prometheus-api/main/docs/images/logo.png">
8+
<style>
9+
body, h1, ul, li, a {
10+
margin: 0;
11+
padding: 0;
12+
}
13+
body {
14+
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
15+
background: linear-gradient(135deg, #667eea, #764ba2);
16+
color: white;
17+
display: flex;
18+
flex-direction: column;
19+
align-items: center;
20+
justify-content: center;
21+
height: 100vh;
22+
background-size: 200% 200%;
23+
animation: backgroundShift 10s ease infinite;
24+
}
25+
26+
@keyframes backgroundShift {
27+
0% { background-position: 0% 50%; }
28+
50% { background-position: 100% 50%; }
29+
100% { background-position: 0% 50%; }
30+
}
31+
32+
a {
33+
color: white;
34+
text-decoration: none;
35+
}
36+
37+
nav {
38+
position: fixed;
39+
top: 0;
40+
left: 0;
41+
right: 0;
42+
display: flex;
43+
justify-content: space-between;
44+
align-items: center;
45+
padding: 10px 20px;
46+
background: #30354b;
47+
box-shadow: 0 2px 5px rgba(40, 14, 14, 0.3);
48+
z-index: 1000;
49+
}
50+
.navbar-logo {
51+
height: 50px;
52+
animation: enterLogo 1s ease-out forwards;
53+
}
54+
55+
@keyframes enterLogo {
56+
0% { transform: scale(0); }
57+
80% { transform: scale(1.1); }
58+
100% { transform: scale(1); }
59+
}
60+
61+
.nav-title {
62+
margin-left: 10px;
63+
font-size: 20px;
64+
font-weight: 500;
65+
}
66+
.nav-menu {
67+
display: flex;
68+
align-items: center;
69+
list-style: none;
70+
}
71+
.nav-item:not(:last-child) {
72+
margin-right: 20px;
73+
}
74+
.nav-link {
75+
display: flex;
76+
align-items: center;
77+
}
78+
.nav-link img {
79+
height: 20px;
80+
margin-right: 8px;
81+
}
82+
83+
.nav-link:hover {
84+
animation: linkPulse 1s infinite;
85+
}
86+
87+
@keyframes linkPulse {
88+
0% { transform: scale(1); }
89+
50% { transform: scale(1.05); }
90+
100% { transform: scale(1); }
91+
}
92+
93+
.container {
94+
text-align: center;
95+
max-width: 400px;
96+
width: 90%;
97+
padding: 2rem;
98+
background: rgba(255, 255, 255, 0.1);
99+
border-radius: 10px;
100+
backdrop-filter: blur(10px);
101+
border: 1px solid rgba(255, 255, 255, 0.3);
102+
position: relative;
103+
top: 60px;
104+
}
105+
h1 {
106+
font-size: 2rem;
107+
margin-bottom: 1rem;
108+
}
109+
button {
110+
font-size: 1rem;
111+
padding: 0.75rem 1.5rem;
112+
margin: 0.5rem;
113+
border: none;
114+
border-radius: 20px;
115+
cursor: pointer;
116+
transition: all 0.3s ease;
117+
color: #ffffff;
118+
background-image: linear-gradient(45deg, #f6d365, #fda085);
119+
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16);
120+
width: 200px;
121+
}
122+
button:hover {
123+
animation: buttonPulse 0.5s ease;
124+
}
125+
126+
@keyframes buttonPulse {
127+
from { transform: translateY(0); }
128+
50% { transform: translateY(-5px); }
129+
to { transform: translateY(0); }
130+
}
131+
132+
@media (max-width: 768px) {
133+
.nav-title {
134+
display: none;
135+
}
136+
.nav-link img {
137+
margin-right: 5px;
138+
}
139+
.container {
140+
padding: 1.5rem;
141+
top: 30px;
142+
width: 95%;
143+
}
144+
button {
145+
padding: 0.5rem 1rem;
146+
}
147+
}
148+
</style>
149+
</head>
150+
<body>
151+
<nav>
152+
<div style="display: flex; align-items: center;">
153+
<img src="https://raw.githubusercontent.com/hayk96/prometheus-api/main/docs/images/logo.png" alt="Prometheus API" class="navbar-logo">
154+
<span class="nav-title">Prometheus API</span>
155+
</div>
156+
<ul class="nav-menu">
157+
<li class="nav-item">
158+
<a href="https://github.com/hayk96/prometheus-api" class="nav-link">
159+
<img src="/images/logo-github.png" alt="GitHub Logo">GitHub
160+
</a>
161+
</li>
162+
<li class="nav-item">
163+
<a href="#" id="apiDocumentationLink" class="nav-link">
164+
<img src="/images/icon-web-code.png" alt="Prometheus Docs Logo">API Documentation
165+
</a>
166+
</li>
167+
</ul>
168+
</nav>
169+
<div class="container">
170+
<h1>The easiest Prometheus management interface</h1>
171+
<button id="openPrometheusButton">Open Prometheus</button>
172+
<button id="rulesManagementButton">Rules Management</button>
173+
<button id="metricsManagementButton">Metrics Management</button>
174+
<button id="reportsButton">Reports</button>
175+
</div>
176+
<script>
177+
document.addEventListener('DOMContentLoaded', function() {
178+
document.getElementById('apiDocumentationLink').href = window.location.origin + '/redoc';
179+
document.getElementById('openPrometheusButton').onclick = function() {
180+
window.location.href = window.location.origin + '/graph';
181+
};
182+
document.getElementById('rulesManagementButton').onclick = function() {
183+
window.location.href = window.location.origin + '/rules-management';
184+
};
185+
document.getElementById('metricsManagementButton').onclick = function() {
186+
window.location.href = window.location.origin + '/metrics-management';
187+
};
188+
document.getElementById('reportsButton').onclick = function() {
189+
window.location.href = window.location.origin + '/reports';
190+
};
191+
});
192+
</script>
193+
</body>
194+
</html>
+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Metrics Management</title>
7+
<link rel="stylesheet" href="/metrics-management/style.css">
8+
<link rel="icon" type="image/png" href="https://raw.githubusercontent.com/hayk96/prometheus-api/main/docs/images/logo.png">
9+
</head>
10+
<body>
11+
<div id="sidebar" class="sidebar">
12+
<a href="#" class="sidebar-icon" id="homeBtn">
13+
<img src="/images/icon-home.png" alt="Home"/>
14+
<span class="icon-label">Home</span>
15+
</a>
16+
<a href="#" class="sidebar-icon" id="prometheusBtn">
17+
<img src="/images/logo-prometheus.png" alt="Prometheus"/>
18+
<span class="icon-label">Prometheus</span>
19+
</a>
20+
<a href="/rules-management" class="sidebar-icon" id="rulesManagement">
21+
<img src="/images/icon-rules-management.png" alt="Rules Management"/>
22+
<span class="icon-label">Rules Management</span>
23+
</a>
24+
<a href="/reports" class="sidebar-icon" id="reportsPage">
25+
<img src="/images/icon-reports.png" alt="Reports"/>
26+
<span class="icon-label">Reports</span>
27+
</a>
28+
</div>
29+
<div class="main-content">
30+
<div class="toolbar">
31+
<button id="createPolicyBtn" class="action-btn create-btn">Create</button>
32+
<input type="text" id="searchInput" placeholder="Search by pattern..." class="search-bar">
33+
</div>
34+
<div id="policiesList" class="policies-list"></div>
35+
<div id="createPolicyModal" class="modal">
36+
<div class="modal-content">
37+
<h2>Create New Policy</h2>
38+
<input type="text" id="newPolicyName" placeholder="Kubernetes policy" class="modal-input" />
39+
<input type="text" id="newPolicyMatch" placeholder="{job='kubernetes-pods'}" class="modal-input" />
40+
<input type="text" id="newPolicyKeepFor" placeholder="7d" class="modal-input" />
41+
<textarea id="newPolicyDescription" placeholder="Keeps Kubernetes pod metrics for 7 days" class="modal-input"></textarea>
42+
<div id="createPolicyError" class="modal-error-message"></div>
43+
<button id="submitNewPolicy" class="modal-btn modal-btn-create">Create</button>
44+
<button id="cancelCreatePolicyBtn" class="modal-btn modal-btn-cancel-create">Cancel</button>
45+
</div>
46+
</div>
47+
48+
<div id="editPolicyModal" class="modal">
49+
<div class="modal-content">
50+
<h2>Edit Policy</h2>
51+
<input type="text" id="editPolicyName" class="modal-input" disabled />
52+
<textarea type="text" id="editPolicyMatch" class="modal-input"></textarea>
53+
<input type="text" id="editPolicyKeepFor" class="modal-input" />
54+
<textarea id="editPolicyDescription" class="modal-input"></textarea>
55+
<div id="editPolicyError" class="modal-error-message"></div>
56+
<button id="submitEditPolicy" class="modal-btn modal-btn-confirm">Save</button>
57+
<button id="cancelEditPolicyBtn" class="modal-btn modal-btn-cancel">Cancel</button>
58+
</div>
59+
</div>
60+
61+
<div id="deletePolicyModal" class="modal">
62+
<div class="modal-content">
63+
<h2>Delete Policy</h2>
64+
<p id="deletePolicyMessage">Are you sure you want to delete this policy?</p>
65+
<button id="confirmDeletePolicyBtn" class="modal-btn modal-btn-confirm delete-btn">Delete</button>
66+
<button id="cancelDeletePolicyBtn" class="modal-btn modal-btn-cancel">Cancel</button>
67+
</div>
68+
</div>
69+
</div>
70+
<script src="/metrics-management/script.js"></script>
71+
</body>
72+
</html>
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)