Files
Huntarr.io/frontend/templates/components/apps_section.html
2026-02-14 23:22:47 -05:00

878 lines
28 KiB
HTML

<style>
/* Style for apps dropdown to ensure the text has proper padding */
#appsAppSelect option {
padding-left: 10px;
}
/* App Filter Styling - NO GLOWING RING */
.apps-app-filter {
display: flex;
align-items: center;
gap: 8px;
padding: 5px 10px;
border-radius: 8px;
background: linear-gradient(135deg, rgba(30, 39, 56, 0.6) 0%, rgba(14, 20, 32, 0.6) 100%);
border: 1px solid rgba(90, 109, 137, 0.3);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
position: relative;
}
.apps-app-filter:hover {
background: linear-gradient(135deg, rgba(40, 49, 66, 0.7) 0%, rgba(24, 30, 42, 0.7) 100%);
border-color: rgba(90, 109, 137, 0.5);
transform: translateY(-1px);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
}
.apps-app-filter label {
display: flex;
align-items: center;
gap: 5px;
color: rgba(255, 255, 255, 0.8);
font-size: 13px;
font-weight: 500;
cursor: pointer;
user-select: none;
}
.apps-app-filter label i {
color: rgba(99, 102, 241, 0.8);
font-size: 12px;
}
.apps-app-filter select {
background: linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(41, 128, 185, 0.9) 100%);
border: 1px solid rgba(99, 102, 241, 0.6);
border-radius: 4px;
color: rgba(255, 255, 255, 0.95);
padding: 4px 8px;
font-size: 12px;
font-weight: 500;
cursor: pointer;
outline: none;
transition: all 0.3s ease;
min-width: 120px;
/* Add dropdown arrow */
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 8px center;
background-size: 12px;
padding-right: 28px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
}
.apps-app-filter select:hover {
background: linear-gradient(135deg, rgba(99, 102, 241, 0.9) 0%, rgba(41, 128, 185, 1.0) 100%);
border-color: rgba(99, 102, 241, 0.8);
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);
/* Maintain dropdown arrow on hover */
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 8px center;
background-size: 12px;
}
.apps-app-filter select:focus {
border-color: rgba(99, 102, 241, 1.0);
box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.3);
/* Maintain dropdown arrow on focus */
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 8px center;
background-size: 12px;
}
.apps-app-filter select option {
background: #1a1e2a;
color: rgba(255, 255, 255, 0.9);
padding: 4px 8px;
}
/* DISABLE GLOWING RING ANIMATIONS - Apps Section */
#appsAppSelect.styled-select,
#appsSection .styled-select {
animation: none !important;
box-shadow: none !important;
}
#appsAppSelect.styled-select:focus,
#appsAppSelect.styled-select:hover,
#appsSection .styled-select:focus,
#appsSection .styled-select:hover {
animation: none !important;
box-shadow: 0 0 5px rgba(255, 255, 255, 0.2) !important;
transform: none !important;
}
</style>
<section id="appsSection" class="content-section">
<link rel="stylesheet" href="./static/css/instance-editor.css?v=1.0.2">
<div class="content-boundary-inner">
{% from 'components/page_header_partial.html' import page_header %}
{{ page_header(back_href='./#home', parent_icon='fas fa-th-large', parent_name='Apps', current_name='Dashboard', sponsor_section_id='apps') }}
<div class="apps-dashboard">
<div class="dashboard-header">
<div class="header-icon">
<i class="fas fa-tools"></i>
</div>
<h2>Apps Dashboard</h2>
<p>Monitor and manage your media server applications</p>
</div>
<div class="apps-stats-grid">
<!-- App Status Cards -->
<div class="stat-card app-status-card">
<div class="card-header">
<h3><i class="fas fa-server"></i> App Status</h3>
</div>
<div class="status-list" id="appsStatusList">
<div class="status-item" onclick="navigateToApp('sonarr')">
<img src="./static/images/app-icons/sonarr.png" alt="Sonarr" class="status-icon">
<div class="app-info">
<span class="app-name">Sonarr</span>
<span class="app-subtitle" id="sonarrSubtitle">TV Series Management</span>
</div>
<div class="status-info">
<span class="status-badge" id="sonarrStatus">Checking...</span>
<span class="instance-count" id="sonarrInstances">0 instances</span>
</div>
</div>
<div class="status-item" onclick="navigateToApp('radarr')">
<img src="./static/images/app-icons/radarr.png" alt="Radarr" class="status-icon">
<div class="app-info">
<span class="app-name">Radarr</span>
<span class="app-subtitle" id="radarrSubtitle">Movie Management</span>
</div>
<div class="status-info">
<span class="status-badge" id="radarrStatus">Checking...</span>
<span class="instance-count" id="radarrInstances">0 instances</span>
</div>
</div>
<div class="status-item" onclick="navigateToApp('lidarr')">
<img src="./static/images/app-icons/lidarr.png" alt="Lidarr" class="status-icon">
<div class="app-info">
<span class="app-name">Lidarr</span>
<span class="app-subtitle" id="lidarrSubtitle">Music Management</span>
</div>
<div class="status-info">
<span class="status-badge" id="lidarrStatus">Checking...</span>
<span class="instance-count" id="lidarrInstances">0 instances</span>
</div>
</div>
<div class="status-item" onclick="navigateToApp('readarr')">
<img src="./static/images/app-icons/readarr.png" alt="Readarr" class="status-icon">
<div class="app-info">
<span class="app-name">Readarr</span>
<span class="app-subtitle" id="readarrSubtitle">Book Management</span>
</div>
<div class="status-info">
<span class="status-badge" id="readarrStatus">Checking...</span>
<span class="instance-count" id="readarrInstances">0 instances</span>
</div>
</div>
<div class="status-item" onclick="navigateToApp('whisparr')">
<img src="./static/images/app-icons/whisparr.png" alt="Whisparr V2" class="status-icon">
<div class="app-info">
<span class="app-name">Whisparr V2</span>
<span class="app-subtitle" id="whisparrSubtitle">Adult Content Management</span>
</div>
<div class="status-info">
<span class="status-badge" id="whisparrStatus">Checking...</span>
<span class="instance-count" id="whisparrInstances">0 instances</span>
</div>
</div>
<div class="status-item" onclick="navigateToApp('eros')">
<img src="./static/images/app-icons/eros.png" alt="Whisparr V3" class="status-icon">
<div class="app-info">
<span class="app-name">Whisparr V3</span>
<span class="app-subtitle" id="erosSubtitle">Adult Content Management</span>
</div>
<div class="status-info">
<span class="status-badge" id="erosStatus">Checking...</span>
<span class="instance-count" id="erosInstances">0 instances</span>
</div>
</div>
<div class="status-item" onclick="navigateToApp('prowlarr')">
<img src="./static/images/app-icons/prowlarr.png" alt="Prowlarr" class="status-icon">
<div class="app-info">
<span class="app-name">Prowlarr</span>
<span class="app-subtitle" id="prowlarrSubtitle">Indexer Management</span>
</div>
<div class="status-info">
<span class="status-badge" id="prowlarrStatus">Checking...</span>
<span class="instance-count" id="prowlarrInstances">0 instances</span>
</div>
</div>
</div>
</div>
<!-- Configuration Summary -->
<div class="stat-card config-summary-card">
<div class="card-header">
<h3><i class="fas fa-cog"></i> Configuration Summary</h3>
</div>
<div class="config-stats" id="configStats">
<div class="config-item">
<span class="config-label">Configured Apps:</span>
<span class="config-value" id="configuredAppsCount">0</span>
</div>
<div class="config-item">
<span class="config-label">Total Instances:</span>
<span class="config-value" id="totalInstancesCount">0</span>
</div>
<div class="config-item">
<span class="config-label">Active Connections:</span>
<span class="config-value" id="activeConnectionsCount">0</span>
</div>
</div>
</div>
<!-- Recent Activity -->
<div class="stat-card activity-card">
<div class="card-header">
<h3><i class="fas fa-clock"></i> Recent Activity</h3>
</div>
<div class="activity-list" id="recentActivity">
<div class="activity-item loading">
<i class="fas fa-spinner fa-spin activity-icon"></i>
<span class="activity-text">Loading recent activity...</span>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="stat-card actions-card">
<div class="card-header">
<h3><i class="fas fa-bolt"></i> Quick Actions</h3>
</div>
<div class="actions-grid">
<button class="action-btn" onclick="window.location.hash = '#settings'">
<i class="fas fa-cog"></i>
<span>Global Settings</span>
</button>
<button class="action-btn" onclick="window.location.hash = '#logs'">
<i class="fas fa-list-alt"></i>
<span>View Logs</span>
</button>
<button class="action-btn" onclick="refreshAppStatus()">
<i class="fas fa-sync-alt"></i>
<span>Refresh Status</span>
</button>
<button class="action-btn" onclick="window.location.hash = '#hunt-manager'">
<i class="fas fa-crosshairs"></i>
<span>Hunt Manager</span>
</button>
</div>
</div>
</div>
</div>
</div>
</section>
<style>
#appsSection {
display: none;
width: 100%;
height: auto;
min-height: 100vh;
padding: 20px;
overflow-y: auto;
overflow-x: hidden;
}
#appsSection.active {
display: block;
}
.apps-dashboard {
max-width: 1200px;
margin: 0 auto;
width: 100%;
padding: 0 10px;
}
.dashboard-header {
text-align: center;
margin-bottom: 30px;
}
.header-icon {
width: 80px;
height: 80px;
margin: 0 auto 20px;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, rgba(99, 102, 241, 0.2) 0%, rgba(155, 89, 182, 0.2) 100%);
border-radius: 50%;
border: 2px solid rgba(99, 102, 241, 0.3);
}
.header-icon i {
font-size: 32px;
color: rgba(99, 102, 241, 0.9);
}
.dashboard-header h2 {
color: #fff;
font-size: 32px;
margin-bottom: 10px;
font-weight: 600;
}
.dashboard-header p {
color: rgba(255, 255, 255, 0.7);
font-size: 16px;
line-height: 1.5;
}
.apps-stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
width: 100%;
max-width: none;
}
@media (max-width: 1200px) {
.apps-stats-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 768px) {
.apps-stats-grid {
grid-template-columns: 1fr;
}
}
.stat-card {
background: linear-gradient(135deg, rgba(30, 39, 56, 0.8) 0%, rgba(14, 20, 32, 0.8) 100%);
border: 1px solid rgba(90, 109, 137, 0.3);
border-radius: 12px;
padding: 20px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
transition: all 0.3s ease;
}
.stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
border-color: rgba(99, 102, 241, 0.4);
}
.card-header {
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.card-header h3 {
color: #fff;
font-size: 18px;
font-weight: 600;
margin: 0;
display: flex;
align-items: center;
gap: 8px;
}
.card-header i {
color: rgba(99, 102, 241, 0.8);
}
/* App Status Styles */
.status-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.status-item {
display: flex;
align-items: center;
gap: 12px;
padding: 12px;
background: rgba(255, 255, 255, 0.05);
border-radius: 8px;
transition: all 0.3s ease;
cursor: pointer;
border: 1px solid transparent;
}
.status-item:hover {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(99, 102, 241, 0.3);
transform: translateY(-1px);
}
.app-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 2px;
}
.app-subtitle {
font-size: 11px;
color: rgba(255, 255, 255, 0.5);
font-weight: 400;
}
.status-info {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 2px;
}
.instance-count {
font-size: 11px;
color: rgba(255, 255, 255, 0.4);
font-weight: 400;
}
.status-icon {
width: 24px;
height: 24px;
border-radius: 4px;
flex-shrink: 0;
}
.app-name {
color: rgba(255, 255, 255, 0.9);
font-weight: 500;
flex: 1;
}
.status-badge {
padding: 4px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
background: rgba(108, 117, 125, 0.3);
color: rgba(255, 255, 255, 0.7);
}
.status-badge.online {
background: rgba(40, 167, 69, 0.3);
color: #28a745;
}
.status-badge.offline {
background: rgba(220, 53, 69, 0.3);
color: #dc3545;
}
.status-badge.checking {
background: rgba(255, 193, 7, 0.3);
color: #ffc107;
}
/* Configuration Summary Styles */
.config-stats {
display: flex;
flex-direction: column;
gap: 12px;
}
.config-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0;
}
.config-label {
color: rgba(255, 255, 255, 0.7);
font-size: 14px;
}
.config-value {
color: rgba(99, 102, 241, 0.9);
font-weight: 600;
font-size: 16px;
}
/* Activity Styles */
.activity-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.activity-item {
display: flex;
align-items: flex-start;
gap: 10px;
padding: 8px 0;
color: rgba(255, 255, 255, 0.7);
font-size: 14px;
line-height: 1.4;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.activity-item:last-child {
border-bottom: none;
}
.activity-item.loading {
justify-content: center;
border-bottom: none;
}
.activity-icon {
color: rgba(99, 102, 241, 0.6);
margin-top: 2px;
flex-shrink: 0;
width: 14px;
}
.activity-content {
flex: 1;
display: flex;
flex-direction: column;
gap: 2px;
}
.activity-time {
font-size: 11px;
color: rgba(255, 255, 255, 0.4);
}
.activity-item.success .activity-icon {
color: rgba(40, 167, 69, 0.8);
}
.activity-item.warning .activity-icon {
color: rgba(255, 193, 7, 0.8);
}
.activity-item.info .activity-icon {
color: rgba(23, 162, 184, 0.8);
}
/* Quick Actions Styles */
.actions-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.action-btn {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
padding: 12px 8px;
background: rgba(99, 102, 241, 0.1);
border: 1px solid rgba(99, 102, 241, 0.3);
border-radius: 8px;
color: rgba(255, 255, 255, 0.8);
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
}
.action-btn:hover {
background: rgba(99, 102, 241, 0.2);
border-color: rgba(99, 102, 241, 0.5);
color: #fff;
transform: translateY(-1px);
}
.action-btn i {
font-size: 16px;
color: rgba(99, 102, 241, 0.8);
}
.action-btn span {
font-size: 12px;
font-weight: 500;
text-align: center;
}
@media (max-width: 768px) {
.apps-placeholder {
padding: 20px;
}
.placeholder-icon {
width: 60px;
height: 60px;
margin-bottom: 15px;
}
.placeholder-icon i {
font-size: 24px;
}
.placeholder-content h2 {
font-size: 24px;
margin-bottom: 12px;
}
.placeholder-content p {
font-size: 14px;
}
}
@media (max-width: 480px) {
.apps-placeholder {
padding: 15px;
}
.placeholder-content h2 {
font-size: 22px;
}
.placeholder-content p {
font-size: 13px;
}
}
</style>
<style>
/* Apps Section Layout - Complete Redesign */
/* Remove unwanted background behind app headers */
#appsSection .app-content-panel, #appsSection .app-apps-panel {
background-color: transparent !important;
box-shadow: none !important;
border: none !important;
}
#appsSection {
display: none;
width: 100%;
height: auto;
overflow: hidden; /* Prevent double scrollbar */
padding-bottom: 60px; /* Clear space at the bottom */
}
#appsSection.active {
display: block;
}
/* Single scroll container - ONLY this element should scroll */
#appsSection .single-scroll-container {
display: block;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
padding-bottom: 100px; /* Significant padding to avoid content being cut off */
min-height: 100%;
height: auto;
max-height: unset; /* Remove any max-height restriction */
scrollbar-width: thin; /* Firefox */
position: relative;
}
/* Apps-only overflow controls (must not affect other sections) */
#appsSection .app-apps-panel, #appsSection .app-content-panel, #appsSection #appsContainer,
#appsSection .app-panels-container, #appsSection #appsStatus {
overflow: hidden !important;
scrollbar-width: none !important; /* Firefox */
-ms-overflow-style: none !important; /* IE/Edge */
}
/* Proper table positioning at bottom */
#appsSection .app-panels-container {
margin-top: auto;
padding: 10px 0 0;
width: 100%;
}
/* Ensure Additional Options section is fully visible */
#sonarrApps, #radarrApps, #lidarrApps, #readarrApps, #whisparrApps, #erosApps, #swaparrApps {
padding-bottom: 150px; /* Extra padding to ensure bottom content is visible */
margin-bottom: 50px;
}
/* Add explicit styling for the Additional Options section */
#appsSection .additional-options-section, #appsSection .additional-options {
margin-bottom: 100px;
padding-bottom: 100px;
}
/* Ensure Skip Series Refresh is visible */
#appsSection .skip-series-refresh {
margin-bottom: 50px;
padding-bottom: 50px;
}
/* Panel styling */
#appsSection .app-apps-panel {
padding-bottom: 10px;
min-height: 0;
height: auto;
}
/* Apps container styling */
#appsContainer {
height: auto;
flex: 1;
overflow: visible;
}
/* Prevent scrollbars on apps table elements only */
#appsSection table, #appsSection tbody, #appsSection tr, #appsSection td {
overflow: visible !important;
}
/* Hide scrollbars except the main content wrapper */
#appsSection ::-webkit-scrollbar {
width: 8px;
height: 8px;
}
/* Hide apps scrollbars except on .single-scroll-container */
#appsSection::-webkit-scrollbar,
#appsSection #appsContainer::-webkit-scrollbar,
#appsSection .app-panels-container::-webkit-scrollbar,
#appsSection .app-content-panel::-webkit-scrollbar,
#appsSection .app-apps-panel::-webkit-scrollbar,
#appsSection #sonarrApps::-webkit-scrollbar,
#appsSection #radarrApps::-webkit-scrollbar,
#appsSection #lidarrApps::-webkit-scrollbar,
#appsSection #readarrApps::-webkit-scrollbar,
#appsSection #whisparrApps::-webkit-scrollbar,
#appsSection #erosApps::-webkit-scrollbar,
#appsSection #swaparrApps::-webkit-scrollbar,
#appsSection table::-webkit-scrollbar,
#appsSection tr::-webkit-scrollbar,
#appsSection td::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
}
/* Complete overhaul for mobile and desktop visibility */
@media (max-width: 768px) {
/* Full display mode for mobile */
#appsSection, #appsSection.active {
display: block;
height: auto;
overflow-y: visible;
overflow-x: hidden;
padding-bottom: 150px;
}
/* Completely redesign scroll container for mobile */
#appsSection .single-scroll-container {
display: block;
position: relative;
overflow-y: visible;
height: auto;
min-height: 100%;
padding-bottom: 200px;
}
/* Ensure proper section isolation */
#appsSection, #appsSection .single-scroll-container {
overflow-y: auto !important;
height: auto !important;
}
/* Extra space for bottom content */
#appsSection .app-panels-container {
margin-bottom: 100px;
}
/* Force bottom option visibility */
#appsSection .additional-options, #appsSection .skip-series-refresh {
margin-bottom: 150px !important;
padding-bottom: 150px !important;
}
/* Apps section header mobile alignment - completely redone */
#appsSection .section-header {
display: grid;
grid-template-columns: auto auto;
width: 100%;
align-items: center;
padding: 10px 5px;
position: relative;
justify-content: flex-start; /* Align grid items to the left */
}
#appsSection .apps-app-filter {
justify-self: start;
margin: 0;
padding: 0;
width: auto;
position: absolute;
left: 5px;
top: 50%;
transform: translateY(-50%);
text-align: left !important;
}
#appsSection #saveAppsButton {
justify-self: end;
white-space: nowrap;
position: absolute;
right: 5px;
top: 50%;
transform: translateY(-50%);
}
/* Make the dropdown more aggressive with left alignment */
#appsSection .styled-select,
#appsSection select#appsAppSelect {
margin: 0 !important;
padding-left: 5px !important;
width: auto !important;
min-width: 120px !important;
text-align: left !important;
justify-content: flex-start !important;
float: left !important;
position: relative !important;
left: 0 !important;
font-size: 14px; /* Prevent zoom on iOS */
}
/* Reset any center alignment that might be applied */
#appsSection .section-header *,
#appsSection .apps-app-filter *,
#appsSection .apps-app-filter label {
text-align: left !important;
box-sizing: border-box !important;
}
/* Override any flex or space-between properties */
#appsSection .apps-app-filter,
#appsSection .apps-app-filter,
#appsSection .section-header > .apps-app-filter {
display: block !important;
justify-content: flex-start !important;
align-items: flex-start !important;
flex: initial !important;
text-align: left !important;
}
/* Fix specific dropdown menu positioning for mobile */
#appsSection .log-dropdown .log-dropdown-content {
left: 0 !important;
right: auto !important;
transform: none !important;
}
}
/* Default desktop padding */
#appsSection .single-scroll-container {
padding-bottom: 200px;
}
#appsSection .additional-options, #appsSection .skip-series-refresh {
margin-bottom: 150px;
padding-bottom: 150px;
}
</style>