qbit_manage/web-ui/css/components/_scheduler-control.css
bobokun 5a4ddf0112
4.6.0 (#931)
# Requirements Updated
- "humanize==4.13.0"
- "ruff==0.12.11"

# Breaking Changes
- **DEPRECATE `QBT_CONFIG` / `--config-file` OPTION**
- No longer supporting `QBT_CONFIG` / `--config-file`. Instead please
switch over to **`QBT_CONFIG_DIR` / `--config-dir`**.
- `QBT_CONFIG` / `--config-file` option will still work for now but is
now considered legacy and will be removed in a future release.
- **Note**: All yml/yaml files will be treated as valid configuration
files and loaded in the `QBT_CONFIG_DIR` path. Please ensure you
**remove** any old/unused configurations that you don't want to be
loaded prior to using this path.

# Improvements
- Adds docker support for PUID/PGID environment variables
- Dockerfile copies the latest `config.yml.sample` in the config folder
- Add `QBT_HOST` / `--host` option to specify webUI host address (#929
Thanks to @QuixThe2nd)
- WebUI: Quick action settings persist now

# Bug Fixes
- WebUI: Fix loading spinner to be centered in the webUI

**Full Changelog**:
https://github.com/StuffAnThings/qbit_manage/compare/v4.5.5...v4.6.0

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Fabricio Silva <hi@fabricio.dev>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Parsa Yazdani <parsa@yazdani.au>
Co-authored-by: Actionbot <actions@github.com>
2025-08-30 14:54:13 -04:00

521 lines
11 KiB
CSS

/* Scheduler Control Component Styles */
/* Add spacing between scheduler sections */
.scheduler-section {
margin-bottom: 2rem;
padding-bottom: 1.5rem;
border-bottom: 1px solid var(--border-color);
}
.scheduler-section:last-child {
border-bottom: none;
margin-bottom: 2rem;
padding-bottom: 1.5rem;
}
.scheduler-control {
background: var(--card-bg);
border: 1px solid var(--border-color);
border-radius: var(--border-radius);
padding: var(--spacing-lg);
margin-bottom: var(--spacing-lg);
box-shadow: var(--shadow-sm);
}
.scheduler-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: var(--spacing-lg);
padding-bottom: var(--spacing-md);
border-bottom: 1px solid var(--border-color);
}
.scheduler-header h3 {
margin: 0;
color: var(--text-primary);
font-size: var(--font-size-lg);
font-weight: 600;
}
.scheduler-status {
display: flex;
flex-direction: column;
gap: var(--spacing-xs);
align-items: flex-end;
}
/* Status Indicators */
.status-indicator,
.connection-status {
display: flex;
align-items: center;
gap: var(--spacing-xs);
font-size: var(--font-size-sm);
}
.status-dot,
.connection-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.status-dot.status-running {
background-color: var(--success-color);
box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.2);
animation: pulse-success 2s infinite;
}
.status-dot.status-stopped {
background-color: var(--error-color);
}
.connection-dot.connection-connected {
background-color: var(--success-color);
}
.connection-dot.connection-disconnected {
background-color: var(--warning-color);
animation: pulse-warning 2s infinite;
}
@keyframes pulse-success {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
@keyframes pulse-warning {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
.status-text,
.connection-text {
font-weight: 500;
color: var(--text-secondary);
}
/* Content Sections */
.scheduler-content {
display: flex;
flex-direction: column;
gap: var(--spacing-xl);
}
.current-schedule-section,
.schedule-form-section,
.schedule-presets-section {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: var(--border-radius);
padding: var(--spacing-lg);
}
.current-schedule-section h4,
.schedule-form-section h4,
.schedule-presets-section h4 {
margin: 0 0 var(--spacing-md) 0;
color: var(--text-primary);
font-size: var(--font-size-md);
font-weight: 600;
}
/* Current Schedule Info */
.schedule-info {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: var(--spacing-md);
}
.schedule-type,
.schedule-value,
.schedule-source,
.next-run {
display: flex;
flex-direction: column;
gap: var(--spacing-xs);
}
/* Persistence Status Badge */
.persistence-badge {
display: inline-flex;
align-items: center;
padding: 2px 8px;
border-radius: 12px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-left: var(--spacing-xs);
}
.persistence-badge.persistent {
background-color: rgba(34, 197, 94, 0.15);
color: #166534;
border: 1px solid rgba(34, 197, 94, 0.3);
}
.persistence-badge.env {
background-color: rgba(59, 130, 246, 0.15);
color: #1e40af;
border: 1px solid rgba(59, 130, 246, 0.3);
}
.persistence-badge.temporary {
background-color: rgba(245, 158, 11, 0.15);
color: #92400e;
border: 1px solid rgba(245, 158, 11, 0.3);
}
.schedule-info label {
font-size: var(--font-size-sm);
font-weight: 500;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.schedule-info span {
font-size: var(--font-size-md);
color: var(--text-primary);
font-family: var(--font-mono, 'Courier New', monospace);
background: var(--input-bg);
padding: var(--spacing-xs) var(--spacing-sm);
border-radius: var(--border-radius-sm);
border: 1px solid var(--border-color);
}
/* Schedule Form */
.schedule-form {
display: flex;
flex-direction: column;
gap: var(--spacing-lg);
}
/* Input Group for schedule input and validate button */
.input-group {
display: flex;
gap: var(--spacing-md);
align-items: stretch;
}
.input-group .form-input {
flex: 1;
min-width: 0; /* Prevents flex item from overflowing */
padding: var(--spacing-sm) var(--spacing-md);
border: 1px solid var(--border-color);
border-radius: var(--border-radius);
/* Ensure the input maintains its rounded corners */
border-top-right-radius: var(--border-radius);
border-bottom-right-radius: var(--border-radius);
height: auto; /* Let height be determined by padding and content */
box-sizing: border-box;
}
.input-group .btn {
flex-shrink: 0;
white-space: nowrap;
border: 1px solid var(--border-color);
border-radius: var(--border-radius);
padding: var(--spacing-sm) var(--spacing-md);
height: auto; /* Match input height */
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
}
/* Validate button styling - light green */
#validate-schedule-btn {
background-color: #dcfce7; /* Light green background */
border: 1px solid #86efac; /* Slightly darker green border */
color: #166534; /* Dark green text */
}
#validate-schedule-btn:hover {
background-color: #bbf7d0; /* Slightly darker on hover */
border: 1px solid #4ade80;
color: #14532d;
}
#validate-schedule-btn:focus {
box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.2);
}
.schedule-type-selector {
display: flex;
gap: var(--spacing-lg);
margin-top: var(--spacing-xs);
}
.radio-label {
display: flex;
align-items: center;
gap: var(--spacing-sm);
cursor: pointer;
font-size: var(--font-size-sm);
color: var(--text-primary);
user-select: none;
}
.radio-label input[type="radio"] {
display: none;
}
.radio-mark {
width: 16px;
height: 16px;
border: 2px solid var(--border-color);
border-radius: 50%;
position: relative;
transition: all var(--transition-fast);
}
.radio-label input[type="radio"]:checked + .radio-mark {
border-color: var(--primary-color);
background-color: var(--primary-color);
}
.radio-label input[type="radio"]:checked + .radio-mark::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 6px;
height: 6px;
background-color: white;
border-radius: 50%;
}
.radio-label:hover .radio-mark {
border-color: var(--primary-hover);
}
/* Form Validation States */
.form-error,
.form-success {
display: flex;
align-items: center;
gap: var(--spacing-xs);
margin-top: var(--spacing-xs);
font-size: var(--font-size-sm);
padding: var(--spacing-xs) var(--spacing-sm);
border-radius: var(--border-radius-sm);
}
.form-error {
color: var(--error-color);
background-color: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.2);
}
.form-success {
color: var(--success-color);
background-color: rgba(34, 197, 94, 0.1);
border: 1px solid rgba(34, 197, 94, 0.2);
}
.error-icon,
.success-icon {
font-weight: bold;
flex-shrink: 0;
}
/* Form Actions */
.form-actions {
display: flex;
gap: var(--spacing-md);
justify-content: flex-start;
margin-top: var(--spacing-md);
}
.btn-loading {
display: inline-flex;
align-items: center;
gap: var(--spacing-sm);
}
/* Loading spinner now uses unified system from main.css */
/* Preset Buttons */
.preset-buttons {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: var(--spacing-sm);
}
.preset-btn {
font-size: var(--font-size-sm);
padding: var(--spacing-sm) var(--spacing-md);
text-align: center;
transition: all var(--transition-fast);
}
.preset-btn:hover {
background-color: var(--primary-color);
border-color: var(--primary-color);
color: var(--text-inverse);
transform: translateY(-1px);
box-shadow: var(--shadow-md);
}
/* Responsive Design */
@media (max-width: 768px) {
.scheduler-header {
flex-direction: column;
gap: var(--spacing-md);
align-items: flex-start;
}
.scheduler-status {
align-items: flex-start;
}
.schedule-info {
grid-template-columns: 1fr;
}
.schedule-type-selector {
flex-direction: column;
gap: var(--spacing-md);
}
.form-actions {
flex-direction: column;
}
.preset-buttons {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.scheduler-control {
padding: var(--spacing-md);
}
.current-schedule-section,
.schedule-form-section,
.schedule-presets-section {
padding: var(--spacing-md);
}
.preset-buttons {
grid-template-columns: 1fr;
}
}
/* Focus and Accessibility */
.radio-label:focus-within .radio-mark {
box-shadow: 0 0 0 3px var(--input-focus-ring);
}
.preset-btn:focus {
outline: none;
box-shadow: 0 0 0 3px var(--input-focus-ring);
}
/* High contrast mode support */
@media (prefers-contrast: high) {
.status-dot,
.connection-dot {
border: 1px solid currentColor;
}
.schedule-info span {
border-width: 2px;
}
.radio-mark {
border-width: 3px;
}
}
/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
.status-dot.status-running,
.connection-dot.connection-disconnected {
animation: none;
}
.loading-spinner {
animation: none;
}
.preset-btn:hover {
transform: none;
}
}
/* Screen reader only content */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Fieldset and legend styling */
fieldset {
border: none;
padding: 0;
margin: 0;
}
legend {
padding: 0;
margin-bottom: var(--spacing-xs);
font-size: var(--font-size-sm);
font-weight: 500;
color: var(--text-primary);
}
/* Enhanced focus indicators for better accessibility */
.schedule-form input[type="radio"]:focus + .radio-mark {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
.schedule-form input[type="text"]:focus {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Ensure sufficient color contrast for status indicators */
.status-dot.status-running {
background-color: #16a34a; /* Darker green for better contrast */
}
.status-dot.status-stopped {
background-color: #dc2626; /* Ensure good contrast */
}
.connection-dot.connection-connected {
background-color: #16a34a; /* Darker green for better contrast */
}
.connection-dot.connection-disconnected {
background-color: #ea580c; /* Orange with good contrast */
}
/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
.status-dot.status-running,
.connection-dot.connection-disconnected {
animation: none;
}
.loading-spinner {
animation: none;
}
.preset-btn:hover {
transform: none;
}
}