updates
This commit is contained in:
parent
341a794ffb
commit
973cd977ba
21
app.py
21
app.py
@ -11,6 +11,7 @@ DEFAULT_GROUP_PRIORITY = 100
|
|||||||
DEFAULT_GROUP = 'Applications'
|
DEFAULT_GROUP = 'Applications'
|
||||||
DEFAULT_GROUP_ICON = 'fas fa-box'
|
DEFAULT_GROUP_ICON = 'fas fa-box'
|
||||||
DEFAULT_TITLE = 'Traefik Routers'
|
DEFAULT_TITLE = 'Traefik Routers'
|
||||||
|
DEFAULT_ICON = 'fas fa-bars'
|
||||||
|
|
||||||
client = docker.from_env()
|
client = docker.from_env()
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ def filter_routers(routers, containers):
|
|||||||
if not is_router_hidden(router['name'], containers):
|
if not is_router_hidden(router['name'], containers):
|
||||||
router['description'] = get_router_description(router['name'], containers)
|
router['description'] = get_router_description(router['name'], containers)
|
||||||
router['display_name'] = get_router_display_name(router['name'], containers)
|
router['display_name'] = get_router_display_name(router['name'], containers)
|
||||||
|
router['icon'] = get_router_icon(router['name'], containers)
|
||||||
router['group'] = get_router_group(router['name'], containers)
|
router['group'] = get_router_group(router['name'], containers)
|
||||||
filtered_routers.append(router)
|
filtered_routers.append(router)
|
||||||
break
|
break
|
||||||
@ -71,16 +73,17 @@ def get_router_group(router_name, containers):
|
|||||||
return labels[group_label]
|
return labels[group_label]
|
||||||
return DEFAULT_GROUP
|
return DEFAULT_GROUP
|
||||||
|
|
||||||
def get_groups(containers):
|
def get_router_icon(router_name, containers):
|
||||||
groups = {
|
service_name = router_name.split('@')[0]
|
||||||
DEFAULT_GROUP: {
|
for container in containers:
|
||||||
'priority': DEFAULT_GROUP_PRIORITY,
|
labels = container.attrs.get('Config', {}).get('Labels', {})
|
||||||
'collapsed': False,
|
icon_label = f'traefik-frontend.http.routers.{service_name}.icon'
|
||||||
'routers': [],
|
if icon_label in labels:
|
||||||
'icon': DEFAULT_GROUP_ICON
|
return labels[icon_label]
|
||||||
}
|
return DEFAULT_ICON
|
||||||
}
|
|
||||||
|
|
||||||
|
def get_groups(containers):
|
||||||
|
groups = {DEFAULT_GROUP: {'priority': DEFAULT_GROUP_PRIORITY, 'collapsed': False, 'routers': [], 'icon': DEFAULT_GROUP_ICON}}
|
||||||
for container in containers:
|
for container in containers:
|
||||||
labels = container.attrs.get('Config', {}).get('Labels', {})
|
labels = container.attrs.get('Config', {}).get('Labels', {})
|
||||||
for label, value in labels.items():
|
for label, value in labels.items():
|
||||||
|
@ -30,6 +30,7 @@ services:
|
|||||||
- "traefik-frontend.http.routers.connpy.group=Development"
|
- "traefik-frontend.http.routers.connpy.group=Development"
|
||||||
- "traefik-frontend.http.routers.nginx.hidden=true"
|
- "traefik-frontend.http.routers.nginx.hidden=true"
|
||||||
- "traefik-frontend.groups.Management.priority=1"
|
- "traefik-frontend.groups.Management.priority=1"
|
||||||
|
- "traefik-frontend.groups.Management.collapsed=false"
|
||||||
- "traefik-frontend.groups.Management.icon=fas fa-tools"
|
- "traefik-frontend.groups.Management.icon=fas fa-tools"
|
||||||
- "traefik-frontend.groups.Networking.priority=2"
|
- "traefik-frontend.groups.Networking.priority=2"
|
||||||
- "traefik-frontend.groups.Networking.icon=fas fa-network-wired"
|
- "traefik-frontend.groups.Networking.icon=fas fa-network-wired"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:root {
|
:root {
|
||||||
--light-background: #f9f9f9;
|
--light-background: #f0f0f0;
|
||||||
--dark-background: #121212;
|
--dark-background: #121212;
|
||||||
--light-title-text: #e0e0e0;
|
--light-title-text: #e0e0e0;
|
||||||
--light-icons: #333;
|
--light-icons: #333;
|
||||||
@ -112,4 +112,11 @@ body {
|
|||||||
.dark-mode .settings-menu .fa {
|
.dark-mode .settings-menu .fa {
|
||||||
color: var(--dark-icons);
|
color: var(--dark-icons);
|
||||||
}
|
}
|
||||||
|
.router svg {
|
||||||
|
font-size: 26px;
|
||||||
|
color: var(--light-router-title);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-mode .router svg {
|
||||||
|
color: var(--dark-router-title);
|
||||||
|
}
|
||||||
|
@ -41,30 +41,75 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.group {
|
.group {
|
||||||
margin-bottom: 40px;
|
margin-bottom: 20px; /* Reduced margin between groups */
|
||||||
}
|
}
|
||||||
|
|
||||||
.group-title {
|
.group-title {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
margin-top: 10px; /* Reduced margin above group title */
|
||||||
}
|
}
|
||||||
|
|
||||||
.group-icon {
|
.group-icon {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.router-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.router {
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
padding: 20px 15px; /* Added padding top and bottom */
|
||||||
|
margin: 15px; /* Added margin between boxes */
|
||||||
|
flex: 1 1 calc(33.333% - 40px); /* Adjusted for new margin */
|
||||||
|
max-width: calc(33.333% - 40px); /* Adjusted for new margin */
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: box-shadow 0.3s ease;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.router svg {
|
||||||
|
font-size: 32px; /* Made the icon bigger */
|
||||||
|
margin-right: 15px; /* Added padding between icon and text */
|
||||||
|
}
|
||||||
|
|
||||||
|
.router:hover {
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.router h2 {
|
||||||
|
font-size: 18px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.router p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 5px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 20px; /* Added padding to the left and right of the webpage */
|
||||||
|
}
|
||||||
|
|
||||||
/* Responsive Design */
|
/* Responsive Design */
|
||||||
@media (max-width: 1024px) {
|
@media (max-width: 1024px) {
|
||||||
.router {
|
.router {
|
||||||
flex: 1 1 calc(50% - 20px);
|
flex: 1 1 calc(50% - 40px); /* Adjusted for new margin */
|
||||||
max-width: calc(50% - 20px);
|
max-width: calc(50% - 40px); /* Adjusted for new margin */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.router {
|
.router {
|
||||||
flex: 1 1 calc(50% - 20px);
|
flex: 1 1 calc(50% - 40px); /* Adjusted for new margin */
|
||||||
max-width: calc(50% - 20px);
|
max-width: calc(50% - 40px); /* Adjusted for new margin */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6044
static/js/fontawesome.js
Normal file
6044
static/js/fontawesome.js
Normal file
File diff suppressed because one or more lines are too long
@ -8,6 +8,16 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||||||
document.getElementById('theme-icon').classList.add('fa-moon');
|
document.getElementById('theme-icon').classList.add('fa-moon');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.group').forEach(group => {
|
||||||
|
const groupName = group.id;
|
||||||
|
const collapsed = group.dataset.collapsed === 'true';
|
||||||
|
if (collapsed) {
|
||||||
|
group.classList.add('collapsed');
|
||||||
|
} else if (localStorage.getItem(`collapsed-${groupName}`) === 'true') {
|
||||||
|
group.classList.add('collapsed');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener("click", function(event) {
|
document.addEventListener("click", function(event) {
|
||||||
const settingsMenu = document.getElementById('settings-menu');
|
const settingsMenu = document.getElementById('settings-menu');
|
||||||
if (!settingsMenu.contains(event.target) && !event.target.closest('.icon-button')) {
|
if (!settingsMenu.contains(event.target) && !event.target.closest('.icon-button')) {
|
||||||
@ -33,6 +43,8 @@ function toggleDarkMode() {
|
|||||||
function toggleGroup(group) {
|
function toggleGroup(group) {
|
||||||
const groupElement = document.getElementById(group);
|
const groupElement = document.getElementById(group);
|
||||||
groupElement.classList.toggle("collapsed");
|
groupElement.classList.toggle("collapsed");
|
||||||
|
const isCollapsed = groupElement.classList.contains("collapsed");
|
||||||
|
localStorage.setItem(`collapsed-${group}`, isCollapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleSettings() {
|
function toggleSettings() {
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{ title }}</title>
|
<title>{{ title }}</title>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/colors.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/colors.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/components.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/components.css') }}">
|
||||||
|
<script src="{{ url_for('static', filename='js/fontawesome.js') }}" defer></script>
|
||||||
<script src="{{ url_for('static', filename='js/scripts.js') }}" defer></script>
|
<script src="{{ url_for('static', filename='js/scripts.js') }}" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -23,14 +23,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{% for group, data in groups.items() %}
|
{% for group, data in groups.items() %}
|
||||||
<div class="group {% if data.collapsed %}collapsed{% endif %}" id="{{ group }}">
|
<div class="group {% if data.collapsed %}collapsed{% endif %}" id="{{ group }}" data-collapsed="{{ data.collapsed }}">
|
||||||
<h2 class="group-title" onclick="toggleGroup('{{ group }}')"><i class="{{ data.icon }}"></i> {{ group }}</h2>
|
<h2 class="group-title" onclick="toggleGroup('{{ group }}')"><i class="{{ data.icon }}"></i> {{ group }}</h2>
|
||||||
<div class="router-container">
|
<div class="router-container">
|
||||||
{% for router in data.routers %}
|
{% for router in data.routers %}
|
||||||
<div class="router" onclick="location.href='http://{{ router['rule'].split('`')[1] }}'">
|
<div class="router" onclick="window.open('http://{{ router['rule'].split('`')[1] }}', '_blank')">
|
||||||
|
<i class="{{ router['icon'] }}"></i>
|
||||||
|
<div>
|
||||||
<h2>{{ router['display_name'] }}</h2>
|
<h2>{{ router['display_name'] }}</h2>
|
||||||
<p>{{ router['description'] }}</p>
|
<p>{{ router['description'] }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user